Skip to content

Commit 1cc2ad8

Browse files
committed
CVC5: fix repeated usage of non-incremental mode in solver, i.e., just create a new solver whenever needed.
The previous mode either crashed when using a CVC5-solver again or kept the previous assertions when solving new asertions. The issue only affects SL, other theories use the CVC5-solver in incremental mode, which works as expected. SL was never properly tested here.
1 parent de5bb91 commit 1cc2ad8

File tree

4 files changed

+56
-69
lines changed

4 files changed

+56
-69
lines changed

src/org/sosy_lab/java_smt/solvers/cvc5/CVC5AbstractProver.java

Lines changed: 42 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
import io.github.cvc5.Solver;
2727
import io.github.cvc5.Sort;
2828
import io.github.cvc5.Term;
29-
import io.github.cvc5.TermManager;
3029
import io.github.cvc5.UnknownExplanation;
3130
import java.util.ArrayDeque;
3231
import java.util.ArrayList;
@@ -55,75 +54,81 @@ abstract class CVC5AbstractProver<T> extends AbstractProverWithAllSat<T> {
5554

5655
private final FormulaManager mgr;
5756
protected final CVC5FormulaCreator creator;
58-
protected final Solver solver;
57+
private final int randomSeed;
58+
private final ImmutableSet<ProverOptions> options;
59+
private final ImmutableMap<String, String> furtherOptionsMap;
60+
protected Solver solver; // final in incremental mode, non-final in non-incremental mode
5961
private boolean changedSinceLastSatQuery = false;
6062
protected final Deque<PersistentMap<String, Term>> assertedTerms = new ArrayDeque<>();
6163

6264
// TODO: does CVC5 support separation logic in incremental mode?
63-
// --> No, CVC5 aborts on addConstraint.
65+
// --> No. In incremental mode, CVC5 aborts when calling addConstraint(...).
66+
// This means, we have to use non-incremental mode when SL is enabled.
67+
// This also means, that push/pop are not supported when SL is enabled and we implement
68+
// our own stack for asserted terms, and use a different solver instance for each sat check.
6469
protected final boolean incremental;
6570

66-
// Separation Logic supports only one heap with one sort. Let's store them here.
67-
private Sort heapSort = null;
68-
private Sort elementSort = null;
69-
7071
protected CVC5AbstractProver(
7172
CVC5FormulaCreator pFormulaCreator,
7273
ShutdownNotifier pShutdownNotifier,
73-
@SuppressWarnings("unused") int randomSeed,
74-
Set<ProverOptions> pOptions,
74+
int pRandomSeed,
75+
ImmutableSet<ProverOptions> pOptions,
7576
FormulaManager pMgr,
7677
ImmutableMap<String, String> pFurtherOptionsMap) {
7778
super(pOptions, pMgr.getBooleanFormulaManager(), pShutdownNotifier);
7879

7980
mgr = pMgr;
8081
creator = pFormulaCreator;
82+
options = ImmutableSet.copyOf(pOptions);
83+
furtherOptionsMap = pFurtherOptionsMap;
84+
randomSeed = pRandomSeed;
8185
incremental = !enableSL;
8286
assertedTerms.add(PathCopyingPersistentTreeMap.of());
8387

84-
TermManager termManager = creator.getEnv();
85-
solver = new Solver(termManager);
86-
87-
setSolverOptions(randomSeed, pOptions, pFurtherOptionsMap, solver);
88+
if (incremental) {
89+
solver = getNewSolver(randomSeed, options, furtherOptionsMap);
90+
}
8891
}
8992

90-
protected void setSolverOptions(
93+
protected Solver getNewSolver(
9194
int randomSeed,
9295
Set<ProverOptions> pOptions,
93-
ImmutableMap<String, String> pFurtherOptionsMap,
94-
Solver pSolver) {
96+
ImmutableMap<String, String> pFurtherOptionsMap) {
97+
Solver newSolver = new Solver(creator.getEnv());
9598
try {
96-
CVC5SolverContext.setSolverOptions(pSolver, randomSeed, pFurtherOptionsMap);
99+
CVC5SolverContext.setSolverOptions(newSolver, randomSeed, pFurtherOptionsMap);
97100
} catch (CVC5ApiRecoverableException e) {
98101
// We've already used these options in CVC5SolverContext, so there should be no exception
99102
throw new AssertionError("Unexpected exception", e);
100103
}
101104

102-
pSolver.setOption("incremental", incremental ? "true" : "false");
103-
pSolver.setOption("produce-models", generateModels ? "true" : "false");
104-
pSolver.setOption("produce-unsat-cores", generateUnsatCores ? "true" : "false");
105+
newSolver.setOption("incremental", incremental ? "true" : "false");
106+
newSolver.setOption("produce-models", generateModels ? "true" : "false");
107+
newSolver.setOption("produce-unsat-cores", generateUnsatCores ? "true" : "false");
105108

106-
pSolver.setOption("produce-assertions", "true");
107-
pSolver.setOption("dump-models", "true");
109+
newSolver.setOption("produce-assertions", "true");
110+
newSolver.setOption("dump-models", "true");
108111

109112
// Set Strings option to enable all String features (such as lessOrEquals)
110-
pSolver.setOption("strings-exp", "true");
113+
newSolver.setOption("strings-exp", "true");
111114

112115
// Enable experimental array features
113116
// Needed when array constants (= with default element) are used
114-
pSolver.setOption("arrays-exp", "true");
117+
newSolver.setOption("arrays-exp", "true");
115118

116119
// Enable more complete quantifier solving (for more info see CVC5QuantifiedFormulaManager)
117-
pSolver.setOption("full-saturate-quant", "true");
120+
newSolver.setOption("full-saturate-quant", "true");
118121

119122
// if no logic is set in CVC5, select the broadest logic available: "ALL"
120-
if (!solver.isLogicSet()) {
123+
if (!newSolver.isLogicSet()) {
121124
try {
122-
solver.setLogic("ALL");
125+
newSolver.setLogic("ALL");
123126
} catch (CVC5ApiException e) {
124127
throw new AssertionError("Unexpected exception", e);
125128
}
126129
}
130+
131+
return newSolver;
127132
}
128133

129134
@Override
@@ -217,6 +222,12 @@ public boolean isUnsat() throws InterruptedException, SolverException {
217222
closeAllEvaluators();
218223
changedSinceLastSatQuery = false;
219224
if (!incremental) {
225+
// in non-incremental mode, we need to create a new solver instance for each sat check
226+
if (solver != null) {
227+
solver.deletePointer(); // cleanup
228+
}
229+
solver = getNewSolver(randomSeed, options, furtherOptionsMap);
230+
220231
ImmutableSet<BooleanFormula> assertedFormulas = getAssertedFormulas();
221232
if (enableSL) {
222233
declareHeap(assertedFormulas);
@@ -261,33 +272,10 @@ private void declareHeap(ImmutableSet<BooleanFormula> pAssertedFormulas) throws
261272
+ heapSorts);
262273
}
263274

264-
// get the (only) heap sort
265-
final Sort newHeapSort = checkNotNull(Iterables.getOnlyElement(heapSorts.keySet()));
266-
final Sort newElementSort = checkNotNull(Iterables.getOnlyElement(heapSorts.get(newHeapSort)));
267-
268-
// if we already have a heap, check that the sorts are the same
269-
if (heapSort != null) {
270-
checkState(elementSort != null, "Heap sort and element sort must both be defined.");
271-
if (!heapSort.equals(newHeapSort) || !elementSort.equals(newElementSort)) {
272-
throw new SolverException(
273-
"CVC5 SL support is limited to one heap with one sort. Already declared heap with"
274-
+ " sorts: "
275-
+ heapSort
276-
+ "->"
277-
+ elementSort
278-
+ ", but found heap with sorts: "
279-
+ newHeapSort
280-
+ "->"
281-
+ newElementSort);
282-
}
283-
} else {
284-
checkState(elementSort == null, "Heap sort and element sort must both be undefined.");
285-
heapSort = newHeapSort;
286-
elementSort = newElementSort;
287-
288-
// then declare the heap in the solver, once before the first sat check
289-
solver.declareSepHeap(heapSort, elementSort);
290-
}
275+
// get the (only) heap sort, and declare it in the solver, once before the first sat check
276+
final Sort heapSort = checkNotNull(Iterables.getOnlyElement(heapSorts.keySet()));
277+
final Sort elementSort = checkNotNull(Iterables.getOnlyElement(heapSorts.get(heapSort)));
278+
solver.declareSepHeap(heapSort, elementSort);
291279
}
292280

293281
@Nonnull

src/org/sosy_lab/java_smt/solvers/cvc5/CVC5InterpolatingProver.java

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public class CVC5InterpolatingProver extends CVC5AbstractProver<String>
4848
CVC5FormulaCreator pFormulaCreator,
4949
ShutdownNotifier pShutdownNotifier,
5050
int randomSeed,
51-
Set<ProverOptions> pOptions,
51+
ImmutableSet<ProverOptions> pOptions,
5252
FormulaManager pMgr,
5353
ImmutableMap<String, String> pFurtherOptionsMap,
5454
boolean pValidateInterpolants) {
@@ -66,13 +66,13 @@ public class CVC5InterpolatingProver extends CVC5AbstractProver<String>
6666
* produce-interpolants which is set here. From CVC5AbstractProver Line 66
6767
*/
6868
@Override
69-
protected void setSolverOptions(
69+
protected Solver getNewSolver(
7070
int randomSeed,
7171
Set<ProverOptions> pOptions,
72-
ImmutableMap<String, String> pFurtherOptionsMap,
73-
Solver pSolver) {
74-
super.setSolverOptions(randomSeed, pOptions, pFurtherOptionsMap, pSolver);
75-
pSolver.setOption("produce-interpolants", "true");
72+
ImmutableMap<String, String> pFurtherOptionsMap) {
73+
Solver newSolver = super.getNewSolver(randomSeed, pOptions, pFurtherOptionsMap);
74+
newSolver.setOption("produce-interpolants", "true");
75+
return newSolver;
7676
}
7777

7878
@Override
@@ -184,8 +184,7 @@ private Term getCVC5Interpolation(Collection<Term> formulasA, Collection<Term> f
184184
Term phiMinus = bmgr.andImpl(formulasB);
185185

186186
// Uses a separate Solver instance to leave the original solver-context unmodified
187-
Solver itpSolver = new Solver(termManager);
188-
setSolverOptions(seed, solverOptions, furtherOptionsMap, itpSolver);
187+
Solver itpSolver = getNewSolver(seed, solverOptions, furtherOptionsMap);
189188

190189
Term interpolant;
191190
try {
@@ -225,9 +224,8 @@ private void checkInterpolationCriteria(Term interpolant, Term phiPlus, Term phi
225224
Sets.difference(interpolantSymbols, intersection));
226225

227226
// build and check both Craig interpolation formulas with the generated interpolant.
228-
Solver validationSolver = new Solver(termManager);
229227
// interpolation option is not required for validation
230-
super.setSolverOptions(seed, solverOptions, furtherOptionsMap, validationSolver);
228+
Solver validationSolver = getNewSolver(seed, solverOptions, furtherOptionsMap);
231229
try {
232230
validationSolver.push();
233231
validationSolver.assertFormula(termManager.mkTerm(Kind.IMPLIES, phiPlus, interpolant));

src/org/sosy_lab/java_smt/solvers/cvc5/CVC5SolverContext.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import com.google.common.base.Splitter.MapSplitter;
1515
import com.google.common.collect.ImmutableList;
1616
import com.google.common.collect.ImmutableMap;
17+
import com.google.common.collect.ImmutableSet;
1718
import io.github.cvc5.CVC5ApiRecoverableException;
1819
import io.github.cvc5.Solver;
1920
import io.github.cvc5.TermManager;
@@ -221,7 +222,7 @@ public ProverEnvironment newProverEnvironment0(Set<ProverOptions> pOptions) {
221222
creator,
222223
shutdownNotifier,
223224
randomSeed,
224-
pOptions,
225+
ImmutableSet.copyOf(pOptions),
225226
getFormulaManager(),
226227
settings.furtherOptionsMap);
227228
}
@@ -239,7 +240,7 @@ protected InterpolatingProverEnvironment<?> newProverEnvironmentWithInterpolatio
239240
creator,
240241
shutdownNotifier,
241242
randomSeed,
242-
pOptions,
243+
ImmutableSet.copyOf(pOptions),
243244
getFormulaManager(),
244245
settings.furtherOptionsMap,
245246
settings.validateInterpolants);

src/org/sosy_lab/java_smt/solvers/cvc5/CVC5TheoremProver.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
package org.sosy_lab.java_smt.solvers.cvc5;
1010

1111
import com.google.common.collect.ImmutableMap;
12-
import java.util.Set;
12+
import com.google.common.collect.ImmutableSet;
1313
import org.checkerframework.checker.nullness.qual.Nullable;
1414
import org.sosy_lab.common.ShutdownNotifier;
1515
import org.sosy_lab.java_smt.api.BasicProverEnvironment;
@@ -24,8 +24,8 @@ class CVC5TheoremProver extends CVC5AbstractProver<Void>
2424
protected CVC5TheoremProver(
2525
CVC5FormulaCreator pFormulaCreator,
2626
ShutdownNotifier pShutdownNotifier,
27-
@SuppressWarnings("unused") int randomSeed,
28-
Set<ProverOptions> pOptions,
27+
int randomSeed,
28+
ImmutableSet<ProverOptions> pOptions,
2929
FormulaManager pMgr,
3030
ImmutableMap<String, String> pFurtherOptionsMap) {
3131
super(pFormulaCreator, pShutdownNotifier, randomSeed, pOptions, pMgr, pFurtherOptionsMap);

0 commit comments

Comments
 (0)