@@ -40,6 +40,7 @@ class CVC4TheoremProver extends AbstractProverWithAllSat<Void>
4040 implements ProverEnvironment , BasicProverEnvironment <Void > {
4141
4242 private final CVC4FormulaCreator creator ;
43+ private final int randomSeed ;
4344 SmtEngine smtEngine ; // final except for SL theory
4445 private boolean changedSinceLastSatQuery = false ;
4546
@@ -50,37 +51,45 @@ class CVC4TheoremProver extends AbstractProverWithAllSat<Void>
5051 * <p>TODO If the overhead of importing/exporting the expressions is too expensive, we can disable
5152 * this behavior. This change would cost us the flexibility of setting options per Prover.
5253 */
53- private final ExprManager exprManager = new ExprManager ();
54+ private ExprManager exprManager ; // final except for SL theory
5455
5556 /** We copy expression between different ExprManagers. The map serves as cache. */
56- private final ExprManagerMapCollection exportMapping = new ExprManagerMapCollection ();
57+ private ExprManagerMapCollection exportMapping ; // final except for SL theory
5758
5859 // CVC4 does not support separation logic in incremental mode.
5960 private final boolean incremental ;
6061
6162 protected CVC4TheoremProver (
6263 CVC4FormulaCreator pFormulaCreator ,
6364 ShutdownNotifier pShutdownNotifier ,
64- int randomSeed ,
65+ int pRandomSeed ,
6566 Set <ProverOptions > pOptions ,
6667 BooleanFormulaManager pBmgr ) {
6768 super (pOptions , pBmgr , pShutdownNotifier );
6869
6970 creator = pFormulaCreator ;
70- smtEngine = new SmtEngine ( exprManager ) ;
71+ randomSeed = pRandomSeed ;
7172 incremental = !enableSL ;
7273
73- setOptions ( randomSeed , pOptions );
74+ createNewEngine ( );
7475 }
7576
76- private void setOptions (int randomSeed , Set <ProverOptions > pOptions ) {
77- smtEngine .setOption ("incremental" , new SExpr (incremental ));
78- if (pOptions .contains (ProverOptions .GENERATE_MODELS )) {
79- smtEngine .setOption ("produce-models" , new SExpr (true ));
77+ private void createNewEngine () {
78+ if (smtEngine != null ) {
79+ smtEngine .delete (); // cleanup
80+ }
81+ if (exportMapping != null ) {
82+ exportMapping .delete ();
8083 }
81- if (pOptions . contains ( ProverOptions . GENERATE_UNSAT_CORE ) ) {
82- smtEngine . setOption ( "produce-unsat-cores" , new SExpr ( true ));
84+ if (exprManager != null ) {
85+ exprManager . delete (); // cleanup
8386 }
87+ exprManager = new ExprManager ();
88+ smtEngine = new SmtEngine (exprManager );
89+ exportMapping = new ExprManagerMapCollection ();
90+ smtEngine .setOption ("incremental" , new SExpr (incremental ));
91+ smtEngine .setOption ("produce-models" , new SExpr (generateModels ));
92+ smtEngine .setOption ("produce-unsat-cores" , new SExpr (generateUnsatCores ));
8493 smtEngine .setOption ("produce-assertions" , new SExpr (true ));
8594 smtEngine .setOption ("dump-models" , new SExpr (true ));
8695 // smtEngine.setOption("produce-unsat-cores", new SExpr(true));
@@ -93,10 +102,6 @@ private void setOptions(int randomSeed, Set<ProverOptions> pOptions) {
93102 smtEngine .setOption ("full-saturate-quant" , new SExpr (true ));
94103 }
95104
96- protected void setOptionForIncremental () {
97- smtEngine .setOption ("incremental" , new SExpr (true ));
98- }
99-
100105 /** import an expression from global context into this prover's context. */
101106 protected Expr importExpr (Expr expr ) {
102107 return expr .exportTo (exprManager , exportMapping );
@@ -172,13 +177,9 @@ protected Evaluator getEvaluatorWithoutChecks() {
172177 }
173178
174179 private void setChanged () {
175- closeAllEvaluators ();
176180 if (!changedSinceLastSatQuery ) {
177181 changedSinceLastSatQuery = true ;
178- if (!incremental ) {
179- // create a new clean smtEngine
180- smtEngine = new SmtEngine (exprManager );
181- }
182+ closeAllEvaluators ();
182183 }
183184 }
184185
@@ -196,17 +197,20 @@ public boolean isUnsat() throws InterruptedException, SolverException {
196197 closeAllEvaluators ();
197198 changedSinceLastSatQuery = false ;
198199 if (!incremental ) {
199- for ( BooleanFormula f : getAssertedFormulas ()) {
200- assertFormula ( f );
201- }
200+ // in non-incremental mode, we need to create a new solver instance for each sat check
201+ createNewEngine ( );
202+ getAssertedFormulas (). forEach ( this :: assertFormula );
202203 }
203204
204205 Result result ;
205206 try (ShutdownHook hook = new ShutdownHook (shutdownNotifier , smtEngine ::interrupt )) {
206207 shutdownNotifier .shutdownIfNecessary ();
207208 result = smtEngine .checkSat ();
209+ } catch (Exception e ) {
210+ throw new SolverException ("CVC4 failed during satisfiability check" , e );
211+ } finally {
212+ shutdownNotifier .shutdownIfNecessary ();
208213 }
209- shutdownNotifier .shutdownIfNecessary ();
210214 return convertSatResult (result );
211215 }
212216
0 commit comments