Skip to content

Commit ea7ad09

Browse files
committed
Track Simplification Origins by Full VC Implication
1 parent 8932b49 commit ea7ad09

18 files changed

Lines changed: 182 additions & 182 deletions

liquidjava-verifier/src/main/java/liquidjava/diagnostics/errors/RefinementError.java

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import liquidjava.rj_language.Predicate;
1010
import liquidjava.rj_language.ast.Expression;
1111
import liquidjava.rj_language.ast.formatter.VariableFormatter;
12+
import liquidjava.rj_language.opt.VCSimplificationResult;
1213
import liquidjava.smt.Counterexample;
1314
import spoon.reflect.cu.SourcePosition;
1415

@@ -20,13 +21,15 @@
2021
public class RefinementError extends LJError {
2122

2223
private final Predicate expected;
23-
private final VCImplication found;
24+
private final VCSimplificationResult found;
2425
private final Counterexample counterexample;
2526

26-
public RefinementError(SourcePosition position, Predicate expected, VCImplication found,
27+
public RefinementError(SourcePosition position, Predicate expected, VCSimplificationResult found,
2728
TranslationTable translationTable, Counterexample counterexample, String customMessage) {
28-
super("Refinement Error", String.format("%s is not a subtype of %s",
29-
found.toPredicate().getExpression().toDisplayString(), expected.getExpression().toDisplayString()),
29+
super("Refinement Error",
30+
String.format("%s is not a subtype of %s",
31+
found.getImplication().toPredicate().getExpression().toDisplayString(),
32+
expected.getExpression().toDisplayString()),
3033
position, translationTable, customMessage);
3134
this.expected = expected;
3235
this.found = found;
@@ -46,7 +49,7 @@ public String getCounterExampleString() {
4649
return null;
4750

4851
List<String> foundVarNames = new ArrayList<>();
49-
Expression foundExpression = found.toPredicate().getExpression();
52+
Expression foundExpression = getFound().getImplication().toPredicate().getExpression();
5053
Expression expectedExpression = expected.getExpression();
5154
foundExpression.getVariableNames(foundVarNames);
5255
// also keep resolved static-final constants (e.g. Integer.MAX_VALUE) referenced by either side of the
@@ -77,7 +80,7 @@ public Predicate getExpected() {
7780
return expected;
7881
}
7982

80-
public VCImplication getFound() {
83+
public VCSimplificationResult getFound() {
8184
return found;
8285
}
8386
}

liquidjava-verifier/src/main/java/liquidjava/diagnostics/errors/StateRefinementError.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import liquidjava.diagnostics.TranslationTable;
44
import liquidjava.processor.VCImplication;
55
import liquidjava.rj_language.Predicate;
6+
import liquidjava.rj_language.opt.VCSimplificationResult;
67
import spoon.reflect.cu.SourcePosition;
78

89
/**
@@ -13,13 +14,13 @@
1314
public class StateRefinementError extends LJError {
1415

1516
private final Predicate expected;
16-
private final VCImplication found;
17+
private final VCSimplificationResult found;
1718

18-
public StateRefinementError(SourcePosition position, Predicate expected, VCImplication found,
19+
public StateRefinementError(SourcePosition position, Predicate expected, VCSimplificationResult found,
1920
TranslationTable translationTable, String customMessage) {
2021
super("State Refinement Error",
2122
String.format("Expected state %s but found %s", expected.getExpression().toDisplayString(),
22-
found.toPredicate().getExpression().toDisplayString()),
23+
found.getImplication().toPredicate().getExpression().toDisplayString()),
2324
position, translationTable, customMessage);
2425
this.expected = expected;
2526
this.found = found;
@@ -30,6 +31,10 @@ public Predicate getExpected() {
3031
}
3132

3233
public VCImplication getFound() {
34+
return found.getImplication();
35+
}
36+
37+
public VCSimplificationResult getFoundSimplification() {
3338
return found;
3439
}
3540
}

liquidjava-verifier/src/main/java/liquidjava/processor/SimplifiedVCImplication.java

Lines changed: 0 additions & 53 deletions
This file was deleted.

liquidjava-verifier/src/main/java/liquidjava/processor/VCImplication.java

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import liquidjava.rj_language.Predicate;
66
import liquidjava.rj_language.opt.VCSimplification;
7+
import liquidjava.rj_language.opt.VCSimplificationResult;
78
import liquidjava.utils.Utils;
89
import spoon.reflect.reference.CtTypeReference;
910

@@ -32,21 +33,6 @@ public VCImplication(VCImplication implication, Predicate ref) {
3233
this.refinement = ref;
3334
}
3435

35-
public VCImplication getOrigin() {
36-
return null;
37-
}
38-
39-
public Predicate getOriginRefinement() {
40-
VCImplication origin = getOrigin();
41-
if (origin == null)
42-
return refinement.clone();
43-
return origin.getRefinement().clone();
44-
}
45-
46-
public VCImplication copyWithRefinement(Predicate refinement) {
47-
return new VCImplication(this, refinement);
48-
}
49-
5036
public void setNext(VCImplication c) {
5137
next = c;
5238
}
@@ -89,7 +75,7 @@ public String toString() {
8975
return String.format("%-20s %s", "", refinement.toString());
9076
}
9177

92-
public VCImplication simplify() {
78+
public VCSimplificationResult simplify() {
9379
return VCSimplification.simplifyToFixedPoint(this);
9480
}
9581

liquidjava-verifier/src/main/java/liquidjava/rj_language/Predicate.java

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import liquidjava.diagnostics.errors.LJError;
1111
import liquidjava.diagnostics.errors.NotFoundError;
1212
import liquidjava.processor.VCImplication;
13+
import liquidjava.rj_language.opt.VCSimplificationResult;
1314
import liquidjava.processor.context.AliasWrapper;
1415
import liquidjava.processor.context.Context;
1516
import liquidjava.processor.context.GhostFunction;
@@ -259,12 +260,6 @@ public Predicate getOrigin() {
259260
return this;
260261
}
261262

262-
public VCImplication simplify() {
263-
VCImplication result = new VCImplication(clone()).simplify();
264-
DebugLog.simplification(this.getExpression(), result.getRefinement().getExpression());
265-
return result;
266-
}
267-
268263
private static boolean isBooleanLiteral(Expression expr, boolean value) {
269264
return expr instanceof LiteralBoolean && expr.isBooleanTrue() == value;
270265
}

liquidjava-verifier/src/main/java/liquidjava/rj_language/opt/VCBinderSimplification.java

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
package liquidjava.rj_language.opt;
22

33
import static liquidjava.rj_language.opt.VCSimplificationUtils.containsVar;
4+
import static liquidjava.rj_language.opt.VCSimplificationUtils.copyWithRefinement;
45
import static liquidjava.rj_language.opt.VCSimplificationUtils.isFalse;
56
import static liquidjava.rj_language.opt.VCSimplificationUtils.isTrue;
67

7-
import liquidjava.processor.SimplifiedVCImplication;
88
import liquidjava.processor.VCImplication;
99
import liquidjava.rj_language.Predicate;
1010
import liquidjava.rj_language.ast.LiteralBoolean;
@@ -41,7 +41,7 @@ private VCImplication simplify(VCImplication implication) {
4141
if (next == null)
4242
return null;
4343

44-
VCImplication result = implication.copyWithRefinement(implication.getRefinement().clone());
44+
VCImplication result = copyWithRefinement(implication, implication.getRefinement().clone());
4545
result.setNext(next);
4646
return result;
4747
}
@@ -53,17 +53,12 @@ private VCImplication removeTrueBinder(VCImplication implication) {
5353
VCImplication next = implication.getNext();
5454

5555
// ∀x. true => P -> P
56-
if (next != null) {
57-
VCImplication origin = new VCImplication(implication.getName(), implication.getType(),
58-
next.getOriginRefinement());
59-
VCImplication result = new SimplifiedVCImplication(next, next.getRefinement().clone(), origin);
60-
result.setNext(next.getNext() == null ? null : next.getNext().clone());
61-
return result;
62-
}
56+
if (next != null)
57+
return next.clone();
6358

6459
// ∀x. true -> true
6560
Predicate truePredicate = new Predicate(new LiteralBoolean(true));
66-
return new SimplifiedVCImplication(new VCImplication(truePredicate), truePredicate, implication);
61+
return new VCImplication(truePredicate);
6762
}
6863

6964
/**
@@ -72,7 +67,7 @@ private VCImplication removeTrueBinder(VCImplication implication) {
7267
private VCImplication collapseFalseBinder(VCImplication implication) {
7368
// ∀x. false => P -> true
7469
Predicate truePredicate = new Predicate(new LiteralBoolean(true));
75-
return new SimplifiedVCImplication(new VCImplication(truePredicate), truePredicate, implication);
70+
return new VCImplication(truePredicate);
7671
}
7772

7873
/**

liquidjava-verifier/src/main/java/liquidjava/rj_language/opt/VCExpressionSimplificationPass.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package liquidjava.rj_language.opt;
22

3-
import liquidjava.processor.SimplifiedVCImplication;
3+
import static liquidjava.rj_language.opt.VCSimplificationUtils.copyWithRefinement;
4+
45
import liquidjava.processor.VCImplication;
56
import liquidjava.rj_language.Predicate;
67
import liquidjava.rj_language.ast.Expression;
@@ -32,7 +33,7 @@ private VCImplication apply(VCImplication implication, C context) {
3233
Expression expression = implication.getRefinement().getExpression();
3334
Expression simplified = simplify(expression, context);
3435
if (!expression.equals(simplified)) {
35-
VCImplication result = new SimplifiedVCImplication(implication, new Predicate(simplified), implication);
36+
VCImplication result = copyWithRefinement(implication, new Predicate(simplified));
3637
result.setNext(implication.getNext() == null ? null : implication.getNext().clone());
3738
return result;
3839
}
@@ -41,7 +42,7 @@ private VCImplication apply(VCImplication implication, C context) {
4142
if (implication.getNext() == null || implication.getNext().equals(next))
4243
return implication;
4344

44-
VCImplication result = implication.copyWithRefinement(implication.getRefinement().clone());
45+
VCImplication result = copyWithRefinement(implication, implication.getRefinement().clone());
4546
result.setNext(next);
4647
return result;
4748
}

liquidjava-verifier/src/main/java/liquidjava/rj_language/opt/VCSimplification.java

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,32 +15,38 @@ public class VCSimplification {
1515
/**
1616
* Applies all available simplification steps to a VC chain until a fixed point is reached
1717
*/
18-
public static VCImplication simplifyToFixedPoint(VCImplication implication) {
18+
public static VCSimplificationResult simplifyToFixedPoint(VCImplication implication) {
1919
if (implication == null)
2020
return null;
2121

22-
// keep applying simplification steps until a fixed point is reached
23-
VCImplication current = implication.clone();
22+
VCSimplificationResult current = new VCSimplificationResult(implication);
2423
while (true) {
25-
VCImplication simplified = simplifyOnce(current);
26-
if (current.equals(simplified))
27-
return simplified; // fixed point reached
24+
VCSimplificationResult simplified = simplifyOnce(current.getImplication(), current);
25+
if (simplified.getOrigin() == null)
26+
return current; // fixed point reached
2827
current = simplified;
2928
}
3029
}
3130

3231
/**
3332
* Applies one simplification step to a VC chain
3433
*/
35-
public static VCImplication simplifyOnce(VCImplication implication) {
34+
public static VCSimplificationResult simplifyOnce(VCImplication implication) {
3635
if (implication == null)
3736
return null;
3837

38+
return simplifyOnce(implication, new VCSimplificationResult(implication));
39+
}
40+
41+
/**
42+
* Applies one simplification step to a VC chain, keeping track of the origin of the simplification
43+
*/
44+
private static VCSimplificationResult simplifyOnce(VCImplication implication, VCSimplificationResult origin) {
3945
for (VCSimplificationPass pass : PASSES) {
4046
VCImplication simplified = pass.apply(implication);
4147
if (!implication.equals(simplified))
42-
return simplified;
48+
return new VCSimplificationResult(simplified, origin);
4349
}
44-
return implication;
50+
return new VCSimplificationResult(implication);
4551
}
4652
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package liquidjava.rj_language.opt;
2+
3+
import java.util.Objects;
4+
5+
import liquidjava.processor.VCImplication;
6+
7+
/**
8+
* Result of simplifying VC implication chain
9+
*/
10+
public final class VCSimplificationResult {
11+
12+
private final VCImplication implication;
13+
private final VCSimplificationResult origin;
14+
15+
public VCSimplificationResult(VCImplication implication) {
16+
this(implication, null);
17+
}
18+
19+
public VCSimplificationResult(VCImplication implication, VCSimplificationResult origin) {
20+
this.implication = Objects.requireNonNull(implication).clone();
21+
this.origin = origin;
22+
}
23+
24+
/**
25+
* Returns the simplified VC chain represented by this result
26+
*/
27+
public VCImplication getImplication() {
28+
return implication;
29+
}
30+
31+
/**
32+
* Returns the origin of this simplification result or null if this result is the original VC chain
33+
*/
34+
public VCSimplificationResult getOrigin() {
35+
return origin;
36+
}
37+
38+
@Override
39+
public String toString() {
40+
if (origin == null)
41+
return "\n" + implication;
42+
return "\n" + implication + "\n" + origin.toString().indent(2).stripTrailing();
43+
}
44+
}

liquidjava-verifier/src/main/java/liquidjava/rj_language/opt/VCSimplificationUtils.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,16 @@
44
import java.util.List;
55

66
import liquidjava.processor.VCImplication;
7+
import liquidjava.rj_language.Predicate;
78
import liquidjava.rj_language.ast.Expression;
89
import liquidjava.rj_language.ast.LiteralBoolean;
910

1011
public final class VCSimplificationUtils {
1112

13+
public static VCImplication copyWithRefinement(VCImplication implication, Predicate refinement) {
14+
return new VCImplication(implication, refinement);
15+
}
16+
1217
public static boolean containsVar(Expression expression, String name) {
1318
List<String> names = new ArrayList<>();
1419
expression.getVariableNames(names);

0 commit comments

Comments
 (0)