-
Notifications
You must be signed in to change notification settings - Fork 35
Expand file tree
/
Copy pathSMTEvaluator.java
More file actions
51 lines (46 loc) · 1.94 KB
/
SMTEvaluator.java
File metadata and controls
51 lines (46 loc) · 1.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
package liquidjava.smt;
import com.martiansoftware.jsap.SyntaxException;
import com.microsoft.z3.Expr;
import com.microsoft.z3.Model;
import com.microsoft.z3.Solver;
import com.microsoft.z3.Status;
import com.microsoft.z3.Z3Exception;
import liquidjava.processor.context.Context;
import liquidjava.rj_language.Predicate;
import liquidjava.rj_language.ast.Expression;
public class SMTEvaluator {
/**
* Verifies that subRef is a subtype of supRef by checking the satisfiability of subRef && !supRef. Creates a parser
* for our SMT-ready refinement language and discharges the verification to Z3
*
* @param subRef
* @param supRef
* @param context
*
* @return the result of the verification, containing a counterexample if the verification fails
*/
public SMTResult verifySubtype(Predicate subRef, Predicate supRef, Context context) throws Exception {
Predicate toVerify = Predicate.createConjunction(subRef, supRef.negate());
try {
Expression exp = toVerify.getExpression();
try (TranslatorToZ3 tz3 = new TranslatorToZ3(context)) {
ExpressionToZ3Visitor visitor = new ExpressionToZ3Visitor(tz3);
Expr<?> e = exp.accept(visitor);
Solver solver = tz3.makeSolverForExpression(e);
Status result = solver.check();
// subRef is not a subtype of supRef
if (result.equals(Status.SATISFIABLE)) {
Model model = solver.getModel();
Counterexample counterexample = tz3.getCounterexample(model);
return SMTResult.error(counterexample);
}
}
} catch (SyntaxException e) {
System.out.println("Could not parse: " + toVerify);
e.printStackTrace();
} catch (Z3Exception e) {
throw new Z3Exception(e.getLocalizedMessage());
}
return SMTResult.ok();
}
}