|
26 | 26 | import io.github.cvc5.Solver; |
27 | 27 | import io.github.cvc5.Sort; |
28 | 28 | import io.github.cvc5.Term; |
29 | | -import io.github.cvc5.TermManager; |
30 | 29 | import io.github.cvc5.UnknownExplanation; |
31 | 30 | import java.util.ArrayDeque; |
32 | 31 | import java.util.ArrayList; |
@@ -55,75 +54,81 @@ abstract class CVC5AbstractProver<T> extends AbstractProverWithAllSat<T> { |
55 | 54 |
|
56 | 55 | private final FormulaManager mgr; |
57 | 56 | 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 |
59 | 61 | private boolean changedSinceLastSatQuery = false; |
60 | 62 | protected final Deque<PersistentMap<String, Term>> assertedTerms = new ArrayDeque<>(); |
61 | 63 |
|
62 | 64 | // 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. |
64 | 69 | protected final boolean incremental; |
65 | 70 |
|
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 | | - |
70 | 71 | protected CVC5AbstractProver( |
71 | 72 | CVC5FormulaCreator pFormulaCreator, |
72 | 73 | ShutdownNotifier pShutdownNotifier, |
73 | | - @SuppressWarnings("unused") int randomSeed, |
74 | | - Set<ProverOptions> pOptions, |
| 74 | + int pRandomSeed, |
| 75 | + ImmutableSet<ProverOptions> pOptions, |
75 | 76 | FormulaManager pMgr, |
76 | 77 | ImmutableMap<String, String> pFurtherOptionsMap) { |
77 | 78 | super(pOptions, pMgr.getBooleanFormulaManager(), pShutdownNotifier); |
78 | 79 |
|
79 | 80 | mgr = pMgr; |
80 | 81 | creator = pFormulaCreator; |
| 82 | + options = ImmutableSet.copyOf(pOptions); |
| 83 | + furtherOptionsMap = pFurtherOptionsMap; |
| 84 | + randomSeed = pRandomSeed; |
81 | 85 | incremental = !enableSL; |
82 | 86 | assertedTerms.add(PathCopyingPersistentTreeMap.of()); |
83 | 87 |
|
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 | + } |
88 | 91 | } |
89 | 92 |
|
90 | | - protected void setSolverOptions( |
| 93 | + protected Solver getNewSolver( |
91 | 94 | int randomSeed, |
92 | 95 | Set<ProverOptions> pOptions, |
93 | | - ImmutableMap<String, String> pFurtherOptionsMap, |
94 | | - Solver pSolver) { |
| 96 | + ImmutableMap<String, String> pFurtherOptionsMap) { |
| 97 | + Solver newSolver = new Solver(creator.getEnv()); |
95 | 98 | try { |
96 | | - CVC5SolverContext.setSolverOptions(pSolver, randomSeed, pFurtherOptionsMap); |
| 99 | + CVC5SolverContext.setSolverOptions(newSolver, randomSeed, pFurtherOptionsMap); |
97 | 100 | } catch (CVC5ApiRecoverableException e) { |
98 | 101 | // We've already used these options in CVC5SolverContext, so there should be no exception |
99 | 102 | throw new AssertionError("Unexpected exception", e); |
100 | 103 | } |
101 | 104 |
|
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"); |
105 | 108 |
|
106 | | - pSolver.setOption("produce-assertions", "true"); |
107 | | - pSolver.setOption("dump-models", "true"); |
| 109 | + newSolver.setOption("produce-assertions", "true"); |
| 110 | + newSolver.setOption("dump-models", "true"); |
108 | 111 |
|
109 | 112 | // Set Strings option to enable all String features (such as lessOrEquals) |
110 | | - pSolver.setOption("strings-exp", "true"); |
| 113 | + newSolver.setOption("strings-exp", "true"); |
111 | 114 |
|
112 | 115 | // Enable experimental array features |
113 | 116 | // Needed when array constants (= with default element) are used |
114 | | - pSolver.setOption("arrays-exp", "true"); |
| 117 | + newSolver.setOption("arrays-exp", "true"); |
115 | 118 |
|
116 | 119 | // Enable more complete quantifier solving (for more info see CVC5QuantifiedFormulaManager) |
117 | | - pSolver.setOption("full-saturate-quant", "true"); |
| 120 | + newSolver.setOption("full-saturate-quant", "true"); |
118 | 121 |
|
119 | 122 | // if no logic is set in CVC5, select the broadest logic available: "ALL" |
120 | | - if (!solver.isLogicSet()) { |
| 123 | + if (!newSolver.isLogicSet()) { |
121 | 124 | try { |
122 | | - solver.setLogic("ALL"); |
| 125 | + newSolver.setLogic("ALL"); |
123 | 126 | } catch (CVC5ApiException e) { |
124 | 127 | throw new AssertionError("Unexpected exception", e); |
125 | 128 | } |
126 | 129 | } |
| 130 | + |
| 131 | + return newSolver; |
127 | 132 | } |
128 | 133 |
|
129 | 134 | @Override |
@@ -217,6 +222,12 @@ public boolean isUnsat() throws InterruptedException, SolverException { |
217 | 222 | closeAllEvaluators(); |
218 | 223 | changedSinceLastSatQuery = false; |
219 | 224 | 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 | + |
220 | 231 | ImmutableSet<BooleanFormula> assertedFormulas = getAssertedFormulas(); |
221 | 232 | if (enableSL) { |
222 | 233 | declareHeap(assertedFormulas); |
@@ -261,33 +272,10 @@ private void declareHeap(ImmutableSet<BooleanFormula> pAssertedFormulas) throws |
261 | 272 | + heapSorts); |
262 | 273 | } |
263 | 274 |
|
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); |
291 | 279 | } |
292 | 280 |
|
293 | 281 | @Nonnull |
|
0 commit comments