@@ -96,15 +96,18 @@ public Optional<Predicate> getRefinementFromAnnotation(CtElement element) throws
9696 return constr ;
9797 }
9898
99- private void checkRefinementSatisfiability (Predicate refinement , CtElement element , String refinementString )
99+ private void checkRefinementSatisfiability (Predicate predicate , CtElement element , String refinementString )
100100 throws LJError {
101101
102102 // skip if trivially true
103- if (refinement .isBooleanTrue ()) {
103+ if (predicate .isBooleanTrue ())
104104 return ;
105- }
106105
107- // normalize refinement for caching x > 0 and y > 0 hit same cache
106+ // replace _ with variable name
107+ String name = element instanceof CtNamedElement named ? named .getSimpleName () : Keys .WILDCARD ;
108+ Predicate refinement = predicate .clone ().substituteVariable (Keys .WILDCARD , name );
109+
110+ // normalize refinement so that equivalent refinements hit the same cache entry
108111 String pattern = getRefinementPattern (refinement );
109112
110113 // if we already checked this refinement pattern, use cached result
@@ -114,49 +117,39 @@ private void checkRefinementSatisfiability(Predicate refinement, CtElement eleme
114117 SourcePosition pos = Utils .getAnnotationPosition (element , refinementString );
115118 throw new UnsatisfiableRefinementError (pos , refinementString );
116119 }
117- return ; // skip
120+ return ; // skip check
118121 }
119122
123+ // check if false is a subtype of the refinement (the refinement is unsatisfiable)
120124 context .enterContext ();
121125 try {
122- Predicate pred = refinement .clone ();
123- CtTypeReference <?> elementType = element instanceof CtTypedElement <?> typedElement ? typedElement .getType ()
126+ CtTypeReference <?> elementType = element instanceof CtTypedElement typedElement ? typedElement .getType ()
124127 : null ;
125- if (elementType == null )
126- return ;
127-
128- String oldName = element instanceof CtNamedElement named ? named .getSimpleName () : Keys .WILDCARD ;
129- String newName = String .format (Formats .REF , context .getCounter ());
128+ if (elementType != null )
129+ context .addVarToContext (name , elementType , new Predicate (), element );
130130
131- // add var to context
132- context .addVarToContext (newName , elementType , new Predicate (), element );
133- pred = pred .substituteVariable (oldName , newName );
134-
135- // check if false is a subtype of the refinement (the refinement is unsatisfiable)
136131 Predicate falsePred = Predicate .createLit ("false" , Types .BOOLEAN );
137- boolean isUnsatisfiable = vcChecker .smtChecks (falsePred , pred , element .getPosition ());
132+ boolean isUnsatisfiable = vcChecker .smtChecks (falsePred , refinement , element .getPosition ());
138133 refinementSatisfiabilityCache .put (pattern , !isUnsatisfiable );
139134 if (isUnsatisfiable ) {
140135 SourcePosition pos = Utils .getAnnotationPosition (element , refinementString );
141136 throw new UnsatisfiableRefinementError (pos , refinementString );
142137 }
143- } catch (UnsatisfiableRefinementError e ) {
144- throw e ;
145138 } catch (LJError e ) {
146- // ignore other errors
139+ // ignore errors
147140 } finally {
148141 context .exitContext ();
149142 }
150143 }
151144
152145 private String getRefinementPattern (Predicate refinement ) {
153- Predicate pattern = refinement .clone (). substituteVariable ( Keys . WILDCARD , "$" ) ;
146+ Predicate pattern = refinement .clone ();
154147 List <String > varNames = pattern .getVariableNames ();
155148 HashSet <String > uniqueVars = new HashSet <>();
156149 uniqueVars .addAll (varNames );
157150 int i = 1 ;
158151 for (String var : uniqueVars ) {
159- pattern = pattern .substituteVariable (var , "x " + i );
152+ pattern = pattern .substituteVariable (var , "# " + i );
160153 i ++;
161154 }
162155 return pattern .toString ();
0 commit comments