Skip to content

Commit e78891c

Browse files
authored
Simplification Migration (#261)
1 parent 3b957de commit e78891c

21 files changed

Lines changed: 46 additions & 2221 deletions

CONTRIBUTING.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,8 @@ To run specific tests, run:
3737

3838
```bash
3939
mvn -pl liquidjava-verifier -Dtest=ExpressionFormatterTest test
40-
mvn -pl liquidjava-verifier -Dtest=ExpressionSimplifierTest test
4140
mvn -pl liquidjava-verifier -Dtest=RefinementsParserTest test
42-
mvn -pl liquidjava-verifier -Dtest=VariableResolverTest test
41+
mvn -pl liquidjava-verifier -Dtest=VCSimplificationTest test
4342
```
4443

4544
## Release

liquidjava-verifier/src/main/java/liquidjava/diagnostics/DebugLog.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public static void smtVerifying(SourcePosition position) {
5656

5757
/**
5858
* Flat-predicate fallback: prints top-level conjuncts in order with no per-variable grouping. Used by SMT entry
59-
* points that don't carry the structured per-variable {@link VCImplication} chain (e.g. ExpressionSimplifier).
59+
* points that don't carry the structured per-variable {@link VCImplication} chain.
6060
*/
6161
public static void smtStart(Predicate premises, Predicate conclusion) {
6262
if (!enabled()) {

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

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@
55
import java.util.stream.Collectors;
66

77
import liquidjava.diagnostics.TranslationTable;
8+
import liquidjava.processor.VCImplication;
9+
import liquidjava.rj_language.Predicate;
810
import liquidjava.rj_language.ast.Expression;
911
import liquidjava.rj_language.ast.formatter.VariableFormatter;
10-
import liquidjava.rj_language.opt.derivation_node.ValDerivationNode;
1112
import liquidjava.smt.Counterexample;
1213
import spoon.reflect.cu.SourcePosition;
1314

@@ -18,14 +19,15 @@
1819
*/
1920
public class RefinementError extends LJError {
2021

21-
private final ValDerivationNode expected;
22-
private final ValDerivationNode found;
22+
private final Predicate expected;
23+
private final VCImplication found;
2324
private final Counterexample counterexample;
2425

25-
public RefinementError(SourcePosition position, ValDerivationNode expected, ValDerivationNode found,
26+
public RefinementError(SourcePosition position, Predicate expected, VCImplication found,
2627
TranslationTable translationTable, Counterexample counterexample, String customMessage) {
27-
super("Refinement Error", String.format("%s is not a subtype of %s", found.getValue().toDisplayString(),
28-
expected.getValue().toDisplayString()), position, translationTable, customMessage);
28+
super("Refinement Error", String.format("%s is not a subtype of %s",
29+
found.toPredicate().getExpression().toDisplayString(), expected.getExpression().toDisplayString()),
30+
position, translationTable, customMessage);
2931
this.expected = expected;
3032
this.found = found;
3133
this.counterexample = counterexample;
@@ -44,12 +46,14 @@ public String getCounterExampleString() {
4446
return null;
4547

4648
List<String> foundVarNames = new ArrayList<>();
47-
found.getValue().getVariableNames(foundVarNames);
49+
Expression foundExpression = found.toPredicate().getExpression();
50+
Expression expectedExpression = expected.getExpression();
51+
foundExpression.getVariableNames(foundVarNames);
4852
// also keep resolved static-final constants (e.g. Integer.MAX_VALUE) referenced by either side of the
4953
// subtyping check, so the counterexample maps the symbolic name back to its compile-time value
50-
found.getValue().getResolvedConstantNames(foundVarNames);
51-
expected.getValue().getResolvedConstantNames(foundVarNames);
52-
List<String> foundAssignments = found.getValue().getConjuncts().stream().map(Expression::toString).toList();
54+
foundExpression.getResolvedConstantNames(foundVarNames);
55+
expectedExpression.getResolvedConstantNames(foundVarNames);
56+
List<String> foundAssignments = foundExpression.getConjuncts().stream().map(Expression::toString).toList();
5357
String counterexampleString = counterexample.assignments().stream()
5458
// only include variables that appear in the found value and are not already fixed there
5559
.filter(a -> foundVarNames.contains(a.first())
@@ -69,11 +73,11 @@ public Counterexample getCounterexample() {
6973
return counterexample;
7074
}
7175

72-
public ValDerivationNode getExpected() {
76+
public Predicate getExpected() {
7377
return expected;
7478
}
7579

76-
public ValDerivationNode getFound() {
80+
public VCImplication getFound() {
7781
return found;
7882
}
7983
}
Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
package liquidjava.diagnostics.errors;
22

33
import liquidjava.diagnostics.TranslationTable;
4-
import liquidjava.rj_language.opt.derivation_node.ValDerivationNode;
4+
import liquidjava.processor.VCImplication;
5+
import liquidjava.rj_language.Predicate;
56
import spoon.reflect.cu.SourcePosition;
67

78
/**
@@ -11,23 +12,24 @@
1112
*/
1213
public class StateRefinementError extends LJError {
1314

14-
private final ValDerivationNode expected;
15-
private final ValDerivationNode found;
15+
private final Predicate expected;
16+
private final VCImplication found;
1617

17-
public StateRefinementError(SourcePosition position, ValDerivationNode expected, ValDerivationNode found,
18+
public StateRefinementError(SourcePosition position, Predicate expected, VCImplication found,
1819
TranslationTable translationTable, String customMessage) {
19-
super("State Refinement Error", String.format("Expected state %s but found %s",
20-
expected.getValue().toDisplayString(), found.getValue().toDisplayString()), position, translationTable,
21-
customMessage);
20+
super("State Refinement Error",
21+
String.format("Expected state %s but found %s", expected.getExpression().toDisplayString(),
22+
found.toPredicate().getExpression().toDisplayString()),
23+
position, translationTable, customMessage);
2224
this.expected = expected;
2325
this.found = found;
2426
}
2527

26-
public ValDerivationNode getExpected() {
28+
public Predicate getExpected() {
2729
return expected;
2830
}
2931

30-
public ValDerivationNode getFound() {
32+
public VCImplication getFound() {
3133
return found;
3234
}
3335
}

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@ public VCImplication simplify() {
9393
return VCSimplification.simplifyToFixedPoint(this);
9494
}
9595

96+
public Predicate toPredicate() {
97+
return hasBinder() || hasNext() ? toConjunctions() : refinement;
98+
}
99+
96100
public Predicate toConjunctions() {
97101
Predicate c = new Predicate();
98102
if (name == null && type == null && next == null)

liquidjava-verifier/src/main/java/liquidjava/processor/refinement_checker/VCChecker.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ public void processSubtyping(Predicate expectedType, List<GhostState> list, CtEl
5353
TranslationTable map = new TranslationTable();
5454
String[] s = { Keys.WILDCARD, Keys.THIS };
5555
VCImplication impl = joinPredicates(expectedType, mainVars, lrv, map);
56+
VCImplication implBeforeChange = impl.clone();
5657
Predicate premisesBeforeChange = impl.toConjunctions();
5758
Predicate premises;
5859
Predicate expected;
@@ -81,8 +82,8 @@ public void processSubtyping(Predicate expectedType, List<GhostState> list, CtEl
8182
}
8283
DebugLog.smtResult(result);
8384
if (result.isError()) {
84-
throw new RefinementError(element.getPosition(), expectedType.simplify(context),
85-
premisesBeforeChange.simplify(context), map, result.getCounterexample(), customMessage);
85+
throw new RefinementError(element.getPosition(), expectedType, implBeforeChange.simplify(), map,
86+
result.getCounterexample(), customMessage);
8687
}
8788
}
8889

@@ -405,17 +406,15 @@ private VCImplication buildPremiseChain(TranslationTable map, Predicate... predi
405406
protected void throwRefinementError(SourcePosition position, Predicate expected, Predicate found,
406407
Counterexample counterexample, String customMessage) throws RefinementError {
407408
TranslationTable map = new TranslationTable();
408-
Predicate premises = buildPremiseChain(map, expected, found).toConjunctions();
409-
throw new RefinementError(position, expected.simplify(context), premises.simplify(context), map, counterexample,
410-
customMessage);
409+
VCImplication premises = buildPremiseChain(map, expected, found);
410+
throw new RefinementError(position, expected, premises.simplify(), map, counterexample, customMessage);
411411
}
412412

413413
protected void throwStateRefinementError(SourcePosition position, Predicate found, Predicate expected,
414414
String customMessage) throws StateRefinementError {
415415
TranslationTable map = new TranslationTable();
416416
VCImplication foundState = buildPremiseChain(map, expected, found);
417-
throw new StateRefinementError(position, expected.simplify(context),
418-
foundState.toConjunctions().simplify(context), map, customMessage);
417+
throw new StateRefinementError(position, expected, foundState.simplify(), map, customMessage);
419418
}
420419

421420
protected void throwStateConflictError(SourcePosition position, Predicate expected) throws StateConflictError {

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

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import liquidjava.diagnostics.DebugLog;
1010
import liquidjava.diagnostics.errors.LJError;
1111
import liquidjava.diagnostics.errors.NotFoundError;
12+
import liquidjava.processor.VCImplication;
1213
import liquidjava.processor.context.AliasWrapper;
1314
import liquidjava.processor.context.Context;
1415
import liquidjava.processor.context.GhostFunction;
@@ -27,10 +28,8 @@
2728
import liquidjava.rj_language.ast.LiteralReal;
2829
import liquidjava.rj_language.ast.UnaryExpression;
2930
import liquidjava.rj_language.ast.Var;
30-
import liquidjava.utils.StaticConstants;
31-
import liquidjava.rj_language.opt.derivation_node.ValDerivationNode;
32-
import liquidjava.rj_language.opt.ExpressionSimplifier;
3331
import liquidjava.rj_language.parsing.RefinementsParser;
32+
import liquidjava.utils.StaticConstants;
3433
import liquidjava.utils.Utils;
3534
import liquidjava.utils.constants.Keys;
3635
import liquidjava.utils.constants.Ops;
@@ -260,15 +259,9 @@ public Predicate getOrigin() {
260259
return this;
261260
}
262261

263-
public ValDerivationNode simplify(Context context) {
264-
// collect aliases from context
265-
Map<String, AliasDTO> aliases = new HashMap<>();
266-
for (AliasWrapper aw : context.getAliases()) {
267-
aliases.put(aw.getName(), aw.createAliasDTO());
268-
}
269-
// simplify expression
270-
ValDerivationNode result = ExpressionSimplifier.simplify(exp.clone(), aliases);
271-
DebugLog.simplification(this.getExpression(), result.getValue());
262+
public VCImplication simplify() {
263+
VCImplication result = new VCImplication(clone()).simplify();
264+
DebugLog.simplification(this.getExpression(), result.getRefinement().getExpression());
272265
return result;
273266
}
274267

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

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

0 commit comments

Comments
 (0)