From b8ccbe03efc126de4b3ba95243f266fea0f170d6 Mon Sep 17 00:00:00 2001 From: BaierD Date: Fri, 30 May 2025 20:58:07 +0200 Subject: [PATCH 01/87] Revert "Revert changes supposed to be on a feature branch" This reverts commit 3a6285330cf9f2d3d8c9284e30eccdb8e4669db2. --- .../java_smt/api/BasicProverEnvironment.java | 16 ++++ .../java_smt/basicimpl/AbstractProver.java | 24 ++++- .../basicimpl/AbstractProverWithAllSat.java | 12 ++- .../BasicProverWithAssumptionsWrapper.java | 6 ++ .../DebuggingBasicProverEnvironment.java | 6 ++ ...ebuggingOptimizationProverEnvironment.java | 6 ++ .../LoggingBasicProverEnvironment.java | 6 ++ .../StatisticsBasicProverEnvironment.java | 6 ++ .../SynchronizedBasicProverEnvironment.java | 6 ++ ...izedBasicProverEnvironmentWithContext.java | 6 ++ ...rpolatingProverEnvironmentWithContext.java | 6 ++ .../bitwuzla/BitwuzlaTheoremProver.java | 14 ++- .../boolector/BoolectorAbstractProver.java | 2 +- .../solvers/cvc4/CVC4TheoremProver.java | 13 ++- .../solvers/cvc5/CVC5AbstractProver.java | 8 +- .../mathsat5/Mathsat5AbstractProver.java | 33 +++++-- .../mathsat5/Mathsat5SolverContext.java | 17 ---- .../opensmt/OpenSmtAbstractProver.java | 13 ++- .../SmtInterpolAbstractProver.java | 19 ++-- .../SmtInterpolInterpolatingProver.java | 2 +- .../solvers/yices2/Yices2TheoremProver.java | 20 ++++- .../java_smt/solvers/z3/Z3AbstractProver.java | 6 ++ .../java_smt/solvers/z3/Z3TheoremProver.java | 4 +- .../java_smt/test/SolverBasedTest0.java | 11 +++ .../sosy_lab/java_smt/test/TimeoutTest.java | 89 +++++++++++++++++-- 25 files changed, 289 insertions(+), 62 deletions(-) diff --git a/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java b/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java index b5ac3b1455..34b3ae4bff 100644 --- a/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java +++ b/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java @@ -15,6 +15,8 @@ import java.util.List; import java.util.Optional; import org.checkerframework.checker.nullness.qual.Nullable; +import org.sosy_lab.common.ShutdownManager; +import org.sosy_lab.common.ShutdownNotifier; import org.sosy_lab.java_smt.api.SolverContext.ProverOptions; /** @@ -202,4 +204,18 @@ interface AllSatCallback { default boolean registerUserPropagator(UserPropagator propagator) { return false; } + + /** + * Returns the {@link ShutdownManager} registered for this {@link ProverEnvironment}. It is + * guaranteed to be a child of the {@link ShutdownNotifier} given to the creating {@link + * SolverContext}, resulting in shutdown when the {@link SolverContext}s notifier is shutting + * down. The notifier returned here can be shut down independently of the creating contexts + * notifier. + * + * @return a {@link ShutdownManager} who is the child of the {@link ShutdownNotifier} used in the + * creating {@link SolverContext}, that can be used to shut down only this {@link + * ProverEnvironment}. + * @throws UnsupportedOperationException if the solver does not support prover specific shutdown. + */ + ShutdownManager getShutdownManagerForProver() throws UnsupportedOperationException; } diff --git a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java index 07dbbbb5d6..4e02ea576c 100644 --- a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java +++ b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java @@ -22,6 +22,8 @@ import java.util.List; import java.util.Set; import org.checkerframework.checker.nullness.qual.Nullable; +import org.sosy_lab.common.ShutdownManager; +import org.sosy_lab.common.ShutdownNotifier; import org.sosy_lab.java_smt.api.BasicProverEnvironment; import org.sosy_lab.java_smt.api.BooleanFormula; import org.sosy_lab.java_smt.api.Evaluator; @@ -47,7 +49,11 @@ public abstract class AbstractProver implements BasicProverEnvironment { private static final String TEMPLATE = "Please set the prover option %s."; - protected AbstractProver(Set pOptions) { + // Do we even need this? + private final ShutdownNotifier contextShutdownNotifier; + protected final ShutdownManager proverShutdownManager; + + protected AbstractProver(ShutdownNotifier pShutdownNotifier, Set pOptions) { generateModels = pOptions.contains(ProverOptions.GENERATE_MODELS); generateAllSat = pOptions.contains(ProverOptions.GENERATE_ALL_SAT); generateUnsatCores = pOptions.contains(ProverOptions.GENERATE_UNSAT_CORE); @@ -56,6 +62,9 @@ protected AbstractProver(Set pOptions) { enableSL = pOptions.contains(ProverOptions.ENABLE_SEPARATION_LOGIC); assertedFormulas.add(LinkedHashMultimap.create()); + + contextShutdownNotifier = pShutdownNotifier; + proverShutdownManager = ShutdownManager.createWithParent(contextShutdownNotifier); } protected final void checkGenerateModels() { @@ -158,4 +167,17 @@ public void close() { closeAllEvaluators(); closed = true; } + + @Override + public ShutdownManager getShutdownManagerForProver() throws UnsupportedOperationException { + return getShutdownManagerForProverImpl(); + } + + protected ShutdownManager getShutdownManagerForProverImpl() throws UnsupportedOperationException { + // Override this with the prover specific ShutdownManagers notifier for supporting solvers. + // The solver should then use the prover specific ShutdownManagers notifier for stopping + // instead of the contexts' notifier! + throw new UnsupportedOperationException( + "The chosen solver does not support isolated prover " + "shutdown"); + } } diff --git a/src/org/sosy_lab/java_smt/basicimpl/AbstractProverWithAllSat.java b/src/org/sosy_lab/java_smt/basicimpl/AbstractProverWithAllSat.java index 8e78b2848f..947505ac44 100644 --- a/src/org/sosy_lab/java_smt/basicimpl/AbstractProverWithAllSat.java +++ b/src/org/sosy_lab/java_smt/basicimpl/AbstractProverWithAllSat.java @@ -28,16 +28,14 @@ */ public abstract class AbstractProverWithAllSat extends AbstractProver { - protected final ShutdownNotifier shutdownNotifier; private final BooleanFormulaManager bmgr; protected AbstractProverWithAllSat( Set pOptions, BooleanFormulaManager pBmgr, ShutdownNotifier pShutdownNotifier) { - super(pOptions); + super(pShutdownNotifier, pOptions); bmgr = pBmgr; - shutdownNotifier = pShutdownNotifier; } @Override @@ -68,7 +66,7 @@ private void iterateOverAllModels( AllSatCallback callback, List importantPredicates) throws SolverException, InterruptedException { while (!isUnsat()) { - shutdownNotifier.shutdownIfNecessary(); + proverShutdownManager.getNotifier().shutdownIfNecessary(); ImmutableList.Builder valuesOfModel = ImmutableList.builder(); try (Evaluator evaluator = getEvaluatorWithoutChecks()) { @@ -88,11 +86,11 @@ private void iterateOverAllModels( final ImmutableList values = valuesOfModel.build(); callback.apply(values); - shutdownNotifier.shutdownIfNecessary(); + proverShutdownManager.getNotifier().shutdownIfNecessary(); BooleanFormula negatedModel = bmgr.not(bmgr.and(values)); addConstraint(negatedModel); - shutdownNotifier.shutdownIfNecessary(); + proverShutdownManager.getNotifier().shutdownIfNecessary(); } } @@ -113,7 +111,7 @@ private void iterateOverAllPredicateCombinations( Deque valuesOfModel) throws SolverException, InterruptedException { - shutdownNotifier.shutdownIfNecessary(); + proverShutdownManager.getNotifier().shutdownIfNecessary(); if (isUnsat()) { return; diff --git a/src/org/sosy_lab/java_smt/basicimpl/withAssumptionsWrapper/BasicProverWithAssumptionsWrapper.java b/src/org/sosy_lab/java_smt/basicimpl/withAssumptionsWrapper/BasicProverWithAssumptionsWrapper.java index f2bf7435fe..4cb6dc051f 100644 --- a/src/org/sosy_lab/java_smt/basicimpl/withAssumptionsWrapper/BasicProverWithAssumptionsWrapper.java +++ b/src/org/sosy_lab/java_smt/basicimpl/withAssumptionsWrapper/BasicProverWithAssumptionsWrapper.java @@ -14,6 +14,7 @@ import java.util.Collection; import java.util.List; import java.util.Optional; +import org.sosy_lab.common.ShutdownManager; import org.sosy_lab.java_smt.api.BasicProverEnvironment; import org.sosy_lab.java_smt.api.BooleanFormula; import org.sosy_lab.java_smt.api.Model; @@ -128,4 +129,9 @@ public R allSat(AllSatCallback pCallback, List pImportant clearAssumptions(); return delegate.allSat(pCallback, pImportant); } + + @Override + public ShutdownManager getShutdownManagerForProver() throws UnsupportedOperationException { + return delegate.getShutdownManagerForProver(); + } } diff --git a/src/org/sosy_lab/java_smt/delegate/debugging/DebuggingBasicProverEnvironment.java b/src/org/sosy_lab/java_smt/delegate/debugging/DebuggingBasicProverEnvironment.java index c548d30384..45155f5eb3 100644 --- a/src/org/sosy_lab/java_smt/delegate/debugging/DebuggingBasicProverEnvironment.java +++ b/src/org/sosy_lab/java_smt/delegate/debugging/DebuggingBasicProverEnvironment.java @@ -14,6 +14,7 @@ import java.util.List; import java.util.Optional; import org.checkerframework.checker.nullness.qual.Nullable; +import org.sosy_lab.common.ShutdownManager; import org.sosy_lab.java_smt.api.BasicProverEnvironment; import org.sosy_lab.java_smt.api.BooleanFormula; import org.sosy_lab.java_smt.api.Model; @@ -29,6 +30,11 @@ class DebuggingBasicProverEnvironment implements BasicProverEnvironment { debugging = pDebugging; } + @Override + public ShutdownManager getShutdownManagerForProver() throws UnsupportedOperationException { + return delegate.getShutdownManagerForProver(); + } + @Override public void pop() { debugging.assertThreadLocal(); diff --git a/src/org/sosy_lab/java_smt/delegate/debugging/DebuggingOptimizationProverEnvironment.java b/src/org/sosy_lab/java_smt/delegate/debugging/DebuggingOptimizationProverEnvironment.java index 9c178112f6..a41c30e364 100644 --- a/src/org/sosy_lab/java_smt/delegate/debugging/DebuggingOptimizationProverEnvironment.java +++ b/src/org/sosy_lab/java_smt/delegate/debugging/DebuggingOptimizationProverEnvironment.java @@ -9,6 +9,7 @@ package org.sosy_lab.java_smt.delegate.debugging; import java.util.Optional; +import org.sosy_lab.common.ShutdownManager; import org.sosy_lab.common.rationals.Rational; import org.sosy_lab.java_smt.api.Formula; import org.sosy_lab.java_smt.api.OptimizationProverEnvironment; @@ -26,6 +27,11 @@ public DebuggingOptimizationProverEnvironment( debugging = pDebugging; } + @Override + public ShutdownManager getShutdownManagerForProver() throws UnsupportedOperationException { + return delegate.getShutdownManagerForProver(); + } + @Override public int maximize(Formula objective) { debugging.assertThreadLocal(); diff --git a/src/org/sosy_lab/java_smt/delegate/logging/LoggingBasicProverEnvironment.java b/src/org/sosy_lab/java_smt/delegate/logging/LoggingBasicProverEnvironment.java index 2f194c6125..6776639382 100644 --- a/src/org/sosy_lab/java_smt/delegate/logging/LoggingBasicProverEnvironment.java +++ b/src/org/sosy_lab/java_smt/delegate/logging/LoggingBasicProverEnvironment.java @@ -18,6 +18,7 @@ import java.util.Optional; import java.util.logging.Level; import org.checkerframework.checker.nullness.qual.Nullable; +import org.sosy_lab.common.ShutdownManager; import org.sosy_lab.common.log.LogManager; import org.sosy_lab.java_smt.api.BasicProverEnvironment; import org.sosy_lab.java_smt.api.BooleanFormula; @@ -38,6 +39,11 @@ class LoggingBasicProverEnvironment implements BasicProverEnvironment { logger = checkNotNull(pLogger); } + @Override + public ShutdownManager getShutdownManagerForProver() throws UnsupportedOperationException { + return wrapped.getShutdownManagerForProver(); + } + @Override public @Nullable T push(BooleanFormula f) throws InterruptedException { logger.log(Level.FINE, "up to level " + level++); diff --git a/src/org/sosy_lab/java_smt/delegate/statistics/StatisticsBasicProverEnvironment.java b/src/org/sosy_lab/java_smt/delegate/statistics/StatisticsBasicProverEnvironment.java index 49106d6324..84a5109b0d 100644 --- a/src/org/sosy_lab/java_smt/delegate/statistics/StatisticsBasicProverEnvironment.java +++ b/src/org/sosy_lab/java_smt/delegate/statistics/StatisticsBasicProverEnvironment.java @@ -14,6 +14,7 @@ import java.util.List; import java.util.Optional; import org.checkerframework.checker.nullness.qual.Nullable; +import org.sosy_lab.common.ShutdownManager; import org.sosy_lab.java_smt.api.BasicProverEnvironment; import org.sosy_lab.java_smt.api.BooleanFormula; import org.sosy_lab.java_smt.api.Model; @@ -35,6 +36,11 @@ class StatisticsBasicProverEnvironment implements BasicProverEnvironment { stats.provers.getAndIncrement(); } + @Override + public ShutdownManager getShutdownManagerForProver() throws UnsupportedOperationException { + return delegate.getShutdownManagerForProver(); + } + @Override public void pop() { stats.pop.getAndIncrement(); diff --git a/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedBasicProverEnvironment.java b/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedBasicProverEnvironment.java index f0401c6db2..17497f0540 100644 --- a/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedBasicProverEnvironment.java +++ b/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedBasicProverEnvironment.java @@ -15,6 +15,7 @@ import java.util.List; import java.util.Optional; import org.checkerframework.checker.nullness.qual.Nullable; +import org.sosy_lab.common.ShutdownManager; import org.sosy_lab.java_smt.api.BasicProverEnvironment; import org.sosy_lab.java_smt.api.BooleanFormula; import org.sosy_lab.java_smt.api.Model; @@ -31,6 +32,11 @@ class SynchronizedBasicProverEnvironment implements BasicProverEnvironment sync = checkNotNull(pSync); } + @Override + public ShutdownManager getShutdownManagerForProver() throws UnsupportedOperationException { + return delegate.getShutdownManagerForProver(); + } + @Override public void pop() { synchronized (sync) { diff --git a/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedBasicProverEnvironmentWithContext.java b/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedBasicProverEnvironmentWithContext.java index 43922ccc25..9b7fda176b 100644 --- a/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedBasicProverEnvironmentWithContext.java +++ b/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedBasicProverEnvironmentWithContext.java @@ -16,6 +16,7 @@ import java.util.List; import java.util.Optional; import org.checkerframework.checker.nullness.qual.Nullable; +import org.sosy_lab.common.ShutdownManager; import org.sosy_lab.java_smt.api.BasicProverEnvironment; import org.sosy_lab.java_smt.api.BooleanFormula; import org.sosy_lab.java_smt.api.FormulaManager; @@ -144,6 +145,11 @@ public R allSat(AllSatCallback pCallback, List pImportant } } + @Override + public ShutdownManager getShutdownManagerForProver() throws UnsupportedOperationException { + return delegate.getShutdownManagerForProver(); + } + private class AllSatCallbackWithContext implements AllSatCallback { private final AllSatCallback delegateCallback; diff --git a/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedInterpolatingProverEnvironmentWithContext.java b/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedInterpolatingProverEnvironmentWithContext.java index 52e99c1e90..d365ffad46 100644 --- a/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedInterpolatingProverEnvironmentWithContext.java +++ b/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedInterpolatingProverEnvironmentWithContext.java @@ -12,6 +12,7 @@ import java.util.Collection; import java.util.List; +import org.sosy_lab.common.ShutdownManager; import org.sosy_lab.java_smt.api.BooleanFormula; import org.sosy_lab.java_smt.api.FormulaManager; import org.sosy_lab.java_smt.api.InterpolatingProverEnvironment; @@ -33,6 +34,11 @@ class SynchronizedInterpolatingProverEnvironmentWithContext delegate = checkNotNull(pDelegate); } + @Override + public ShutdownManager getShutdownManagerForProver() throws UnsupportedOperationException { + return delegate.getShutdownManagerForProver(); + } + @Override public BooleanFormula getInterpolant(Collection pFormulasOfA) throws SolverException, InterruptedException { diff --git a/src/org/sosy_lab/java_smt/solvers/bitwuzla/BitwuzlaTheoremProver.java b/src/org/sosy_lab/java_smt/solvers/bitwuzla/BitwuzlaTheoremProver.java index 5cd0448c2a..0087f16132 100644 --- a/src/org/sosy_lab/java_smt/solvers/bitwuzla/BitwuzlaTheoremProver.java +++ b/src/org/sosy_lab/java_smt/solvers/bitwuzla/BitwuzlaTheoremProver.java @@ -17,6 +17,7 @@ import java.util.Optional; import java.util.Set; import org.checkerframework.checker.nullness.qual.Nullable; +import org.sosy_lab.common.ShutdownManager; import org.sosy_lab.common.ShutdownNotifier; import org.sosy_lab.java_smt.api.BooleanFormula; import org.sosy_lab.java_smt.api.Model; @@ -38,7 +39,10 @@ class BitwuzlaTheoremProver extends AbstractProverWithAllSat implements Pr new Terminator() { @Override public boolean terminate() { - return shutdownNotifier.shouldShutdown(); // shutdownNotifer is defined in the superclass + return proverShutdownManager + .getNotifier() + .shouldShutdown(); // shutdownNotifer is defined in the + // superclass } }; private final Bitwuzla env; @@ -119,7 +123,8 @@ private boolean readSATResult(Result resultValue) throws SolverException, Interr return false; } else if (resultValue == Result.UNSAT) { return true; - } else if (resultValue == Result.UNKNOWN && shutdownNotifier.shouldShutdown()) { + } else if (resultValue == Result.UNKNOWN + && proverShutdownManager.getNotifier().shouldShutdown()) { throw new InterruptedException(); } else { throw new SolverException("Bitwuzla returned UNKNOWN."); @@ -246,6 +251,11 @@ protected BitwuzlaModel getEvaluatorWithoutChecks() { Collections2.transform(getAssertedFormulas(), creator::extractInfo))); } + @Override + protected ShutdownManager getShutdownManagerForProverImpl() throws UnsupportedOperationException { + return proverShutdownManager; + } + public boolean isClosed() { return closed; } diff --git a/src/org/sosy_lab/java_smt/solvers/boolector/BoolectorAbstractProver.java b/src/org/sosy_lab/java_smt/solvers/boolector/BoolectorAbstractProver.java index 1608cc098c..f2ca23ea78 100644 --- a/src/org/sosy_lab/java_smt/solvers/boolector/BoolectorAbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/boolector/BoolectorAbstractProver.java @@ -49,7 +49,7 @@ protected BoolectorAbstractProver( this.manager = manager; this.creator = creator; this.btor = btor; - terminationCallback = shutdownNotifier::shouldShutdown; + terminationCallback = proverShutdownManager.getNotifier()::shouldShutdown; terminationCallbackHelper = addTerminationCallback(); isAnyStackAlive = pIsAnyStackAlive; diff --git a/src/org/sosy_lab/java_smt/solvers/cvc4/CVC4TheoremProver.java b/src/org/sosy_lab/java_smt/solvers/cvc4/CVC4TheoremProver.java index 3998fc59ff..33ac359f0a 100644 --- a/src/org/sosy_lab/java_smt/solvers/cvc4/CVC4TheoremProver.java +++ b/src/org/sosy_lab/java_smt/solvers/cvc4/CVC4TheoremProver.java @@ -24,6 +24,7 @@ import java.util.Optional; import java.util.Set; import org.checkerframework.checker.nullness.qual.Nullable; +import org.sosy_lab.common.ShutdownManager; import org.sosy_lab.common.ShutdownNotifier; import org.sosy_lab.java_smt.api.BasicProverEnvironment; import org.sosy_lab.java_smt.api.BooleanFormula; @@ -202,11 +203,12 @@ public boolean isUnsat() throws InterruptedException, SolverException { } Result result; - try (ShutdownHook hook = new ShutdownHook(shutdownNotifier, smtEngine::interrupt)) { - shutdownNotifier.shutdownIfNecessary(); + try (ShutdownHook hook = + new ShutdownHook(proverShutdownManager.getNotifier(), smtEngine::interrupt)) { + proverShutdownManager.getNotifier().shutdownIfNecessary(); result = smtEngine.checkSat(); } - shutdownNotifier.shutdownIfNecessary(); + proverShutdownManager.getNotifier().shutdownIfNecessary(); return convertSatResult(result); } @@ -260,4 +262,9 @@ public void close() { } super.close(); } + + @Override + protected ShutdownManager getShutdownManagerForProverImpl() throws UnsupportedOperationException { + return proverShutdownManager; + } } diff --git a/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5AbstractProver.java b/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5AbstractProver.java index 85cfb0a23c..a4519534a1 100644 --- a/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5AbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5AbstractProver.java @@ -203,7 +203,7 @@ public boolean isUnsat() throws InterruptedException, SolverException { /* Shutdown currently not possible in CVC5. */ Result result = solver.checkSat(); - shutdownNotifier.shutdownIfNecessary(); + proverShutdownManager.getNotifier().shutdownIfNecessary(); return convertSatResult(result); } @@ -251,4 +251,10 @@ public void close() { } super.close(); } + + /* TODO: revisit once CVC5 supports interruption + @Override + protected ShutdownManager getShutdownManagerForProverImpl() throws UnsupportedOperationException { + return proverShutdownManager; + }*/ } diff --git a/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5AbstractProver.java b/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5AbstractProver.java index 39ace99503..3ab242ea5b 100644 --- a/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5AbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5AbstractProver.java @@ -42,6 +42,7 @@ import java.util.Map; import java.util.Optional; import java.util.Set; +import org.sosy_lab.common.ShutdownManager; import org.sosy_lab.common.ShutdownNotifier; import org.sosy_lab.java_smt.api.BooleanFormula; import org.sosy_lab.java_smt.api.Evaluator; @@ -51,27 +52,24 @@ import org.sosy_lab.java_smt.basicimpl.AbstractProver; import org.sosy_lab.java_smt.basicimpl.CachingModel; import org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.AllSatModelCallback; +import org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.TerminationCallback; /** Common base class for {@link Mathsat5TheoremProver} and {@link Mathsat5InterpolatingProver}. */ abstract class Mathsat5AbstractProver extends AbstractProver { - protected final Mathsat5SolverContext context; protected final long curEnv; private final long curConfig; protected final Mathsat5FormulaCreator creator; - private final ShutdownNotifier shutdownNotifier; protected Mathsat5AbstractProver( Mathsat5SolverContext pContext, Set pOptions, Mathsat5FormulaCreator pCreator, ShutdownNotifier pShutdownNotifier) { - super(pOptions); - context = pContext; + super(pShutdownNotifier, pOptions); creator = pCreator; curConfig = buildConfig(pOptions); - curEnv = context.createEnvironment(curConfig); - shutdownNotifier = pShutdownNotifier; + curEnv = pContext.createEnvironment(curConfig); } private long buildConfig(Set opts) { @@ -100,7 +98,7 @@ private long buildConfig(Set opts) { public boolean isUnsat() throws InterruptedException, SolverException { Preconditions.checkState(!closed); - final long hook = msat_set_termination_callback(curEnv, context.getTerminationTest()); + final long hook = msat_set_termination_callback(curEnv, getTerminationTest()); try { return !msat_check_sat(curEnv); } finally { @@ -108,13 +106,25 @@ public boolean isUnsat() throws InterruptedException, SolverException { } } + /** + * Get a termination callback for the current prover (who's parent is the contexts callback). The + * callback can be registered upfront, i.e., before calling a possibly expensive computation in + * the solver to allow a proper shutdown. + */ + private TerminationCallback getTerminationTest() { + return () -> { + proverShutdownManager.getNotifier().shutdownIfNecessary(); + return false; + }; + } + @Override public boolean isUnsatWithAssumptions(Collection pAssumptions) throws SolverException, InterruptedException { Preconditions.checkState(!closed); checkForLiterals(pAssumptions); - final long hook = msat_set_termination_callback(curEnv, context.getTerminationTest()); + final long hook = msat_set_termination_callback(curEnv, getTerminationTest()); try { return !msat_check_sat_with_assumptions(curEnv, getMsatTerm(pAssumptions)); } finally { @@ -273,10 +283,15 @@ class MathsatAllSatCallback implements AllSatModelCallback { @Override public void callback(long[] model) throws InterruptedException { - shutdownNotifier.shutdownIfNecessary(); + proverShutdownManager.getNotifier().shutdownIfNecessary(); clientCallback.apply( Collections.unmodifiableList( Lists.transform(Longs.asList(model), creator::encapsulateBoolean))); } } + + @Override + protected ShutdownManager getShutdownManagerForProverImpl() throws UnsupportedOperationException { + return proverShutdownManager; + } } diff --git a/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5SolverContext.java b/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5SolverContext.java index 8ca17b8a2a..4e107395e5 100644 --- a/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5SolverContext.java +++ b/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5SolverContext.java @@ -46,7 +46,6 @@ import org.sosy_lab.java_smt.api.ProverEnvironment; import org.sosy_lab.java_smt.basicimpl.AbstractNumeralFormulaManager.NonLinearArithmetic; import org.sosy_lab.java_smt.basicimpl.AbstractSolverContext; -import org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.TerminationCallback; public final class Mathsat5SolverContext extends AbstractSolverContext { @@ -96,7 +95,6 @@ private Mathsat5Settings(Configuration config, @Nullable PathCounterTemplate pLo private final long randomSeed; private final ShutdownNotifier shutdownNotifier; - private final TerminationCallback terminationTest; private final Mathsat5FormulaCreator creator; private boolean closed = false; @@ -120,12 +118,6 @@ private Mathsat5SolverContext( this.randomSeed = randomSeed; this.shutdownNotifier = shutdownNotifier; this.creator = creator; - - terminationTest = - () -> { - shutdownNotifier.shutdownIfNecessary(); - return false; - }; } private static void logLicenseInfo(LogManager logger) { @@ -299,15 +291,6 @@ public void close() { } } - /** - * Get a termination callback for the current context. The callback can be registered upfront, - * i.e., before calling a possibly expensive computation in the solver to allow a proper shutdown. - */ - TerminationCallback getTerminationTest() { - Preconditions.checkState(!closed, "solver context is already closed"); - return terminationTest; - } - @Override protected boolean supportsAssumptionSolving() { return true; diff --git a/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtAbstractProver.java b/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtAbstractProver.java index 6678fb9b1c..8f711f8ace 100644 --- a/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtAbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtAbstractProver.java @@ -20,6 +20,7 @@ import java.util.Optional; import java.util.Set; import org.checkerframework.checker.nullness.qual.Nullable; +import org.sosy_lab.common.ShutdownManager; import org.sosy_lab.common.ShutdownNotifier; import org.sosy_lab.java_smt.api.BooleanFormula; import org.sosy_lab.java_smt.api.Evaluator; @@ -230,8 +231,9 @@ public boolean isUnsat() throws InterruptedException, SolverException { changedSinceLastSatQuery = false; sstat result; - try (ShutdownHook listener = new ShutdownHook(shutdownNotifier, osmtSolver::stop)) { - shutdownNotifier.shutdownIfNecessary(); + try (ShutdownHook listener = + new ShutdownHook(proverShutdownManager.getNotifier(), osmtSolver::stop)) { + proverShutdownManager.getNotifier().shutdownIfNecessary(); try { result = osmtSolver.check(); } catch (Exception e) { @@ -250,7 +252,7 @@ public boolean isUnsat() throws InterruptedException, SolverException { throw new SolverException("OpenSMT crashed while checking satisfiability.", e); } } - shutdownNotifier.shutdownIfNecessary(); + proverShutdownManager.getNotifier().shutdownIfNecessary(); } if (result.equals(sstat.Error())) { @@ -289,4 +291,9 @@ public void close() { } super.close(); } + + @Override + protected ShutdownManager getShutdownManagerForProverImpl() throws UnsupportedOperationException { + return proverShutdownManager; + } } diff --git a/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolAbstractProver.java b/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolAbstractProver.java index 97c185ba00..4b2fc684c1 100644 --- a/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolAbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolAbstractProver.java @@ -52,7 +52,6 @@ abstract class SmtInterpolAbstractProver extends AbstractProver { protected final FormulaCreator creator; protected final SmtInterpolFormulaManager mgr; protected final Deque> annotatedTerms = new ArrayDeque<>(); - protected final ShutdownNotifier shutdownNotifier; private static final String PREFIX = "term_"; // for termnames private static final UniqueIdGenerator termIdGenerator = @@ -63,11 +62,10 @@ abstract class SmtInterpolAbstractProver extends AbstractProver { Script pEnv, Set options, ShutdownNotifier pShutdownNotifier) { - super(options); + super(pShutdownNotifier, options); mgr = pMgr; creator = pMgr.getFormulaCreator(); env = pEnv; - shutdownNotifier = pShutdownNotifier; annotatedTerms.add(PathCopyingPersistentTreeMap.of()); } @@ -109,7 +107,7 @@ public boolean isUnsat() throws InterruptedException { // by using a shutdown listener. However, SmtInterpol resets the // mStopEngine flag in DPLLEngine before starting to solve, // so we check here, too. - shutdownNotifier.shutdownIfNecessary(); + proverShutdownManager.getNotifier().shutdownIfNecessary(); LBool result = env.checkSat(); switch (result) { @@ -127,7 +125,9 @@ public boolean isUnsat() throws InterruptedException { // SMTInterpol catches OOM, but we want to have it thrown. throw new OutOfMemoryError("Out of memory during SMTInterpol operation"); case CANCELLED: - shutdownNotifier.shutdownIfNecessary(); // expected if we requested termination + proverShutdownManager + .getNotifier() + .shutdownIfNecessary(); // expected if we requested termination throw new SMTLIBException("checkSat returned UNKNOWN with unexpected reason " + reason); default: throw new SMTLIBException("checkSat returned UNKNOWN with unexpected reason " + reason); @@ -244,10 +244,17 @@ public R allSat(AllSatCallback callback, List important) // by using a shutdown listener. However, SmtInterpol resets the // mStopEngine flag in DPLLEngine before starting to solve, // so we check here, too. - shutdownNotifier.shutdownIfNecessary(); + proverShutdownManager.getNotifier().shutdownIfNecessary(); for (Term[] model : env.checkAllsat(importantTerms)) { callback.apply(Collections3.transformedImmutableListCopy(model, creator::encapsulateBoolean)); } return callback.getResult(); } + + /* TODO: the shutdownNotifier is bound to the Script. But this is done in the context. It seems + like it might be re-usable after a shutdown. + @Override + protected ShutdownManager getShutdownManagerForProverImpl() throws UnsupportedOperationException { + return proverShutdownManager; + }*/ } diff --git a/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolInterpolatingProver.java b/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolInterpolatingProver.java index 37b86aabf4..98ce562a70 100644 --- a/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolInterpolatingProver.java +++ b/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolInterpolatingProver.java @@ -100,7 +100,7 @@ public List getTreeInterpolants( } } catch (SMTLIBException e) { if ("Timeout exceeded".equals(e.getMessage())) { - shutdownNotifier.shutdownIfNecessary(); + proverShutdownManager.getNotifier().shutdownIfNecessary(); } throw new AssertionError(e); } diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2TheoremProver.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2TheoremProver.java index 30b6eda2a5..dd7406dd6b 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2TheoremProver.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2TheoremProver.java @@ -32,6 +32,7 @@ import java.util.Set; import java.util.stream.Collectors; import org.checkerframework.checker.nullness.qual.Nullable; +import org.sosy_lab.common.ShutdownManager; import org.sosy_lab.common.ShutdownNotifier; import org.sosy_lab.java_smt.api.BooleanFormula; import org.sosy_lab.java_smt.api.BooleanFormulaManager; @@ -124,9 +125,13 @@ public boolean isUnsat() throws SolverException, InterruptedException { int[] allConstraints = getAllConstraints(); unsat = !yices_check_sat_with_assumptions( - curEnv, DEFAULT_PARAMS, allConstraints.length, allConstraints, shutdownNotifier); + curEnv, + DEFAULT_PARAMS, + allConstraints.length, + allConstraints, + proverShutdownManager.getNotifier()); } else { - unsat = !yices_check_sat(curEnv, DEFAULT_PARAMS, shutdownNotifier); + unsat = !yices_check_sat(curEnv, DEFAULT_PARAMS, proverShutdownManager.getNotifier()); if (unsat && stackSizeToUnsat == Integer.MAX_VALUE) { stackSizeToUnsat = size(); // If sat check is UNSAT and stackSizeToUnsat waS not already set, @@ -147,7 +152,11 @@ public boolean isUnsatWithAssumptions(Collection pAssumptions) Preconditions.checkState(!closed); // TODO handle BooleanFormulaCollection / check for literals return !yices_check_sat_with_assumptions( - curEnv, DEFAULT_PARAMS, pAssumptions.size(), uncapsulate(pAssumptions), shutdownNotifier); + curEnv, + DEFAULT_PARAMS, + pAssumptions.size(), + uncapsulate(pAssumptions), + proverShutdownManager.getNotifier()); } @SuppressWarnings("resource") @@ -209,4 +218,9 @@ public void close() { } super.close(); } + + @Override + protected ShutdownManager getShutdownManagerForProverImpl() throws UnsupportedOperationException { + return proverShutdownManager; + } } diff --git a/src/org/sosy_lab/java_smt/solvers/z3/Z3AbstractProver.java b/src/org/sosy_lab/java_smt/solvers/z3/Z3AbstractProver.java index 7da2fbdbf5..c148102902 100644 --- a/src/org/sosy_lab/java_smt/solvers/z3/Z3AbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/z3/Z3AbstractProver.java @@ -25,6 +25,7 @@ import java.util.Optional; import java.util.Set; import org.checkerframework.checker.nullness.qual.Nullable; +import org.sosy_lab.common.ShutdownManager; import org.sosy_lab.common.ShutdownNotifier; import org.sosy_lab.common.UniqueIdGenerator; import org.sosy_lab.common.collect.PathCopyingPersistentTreeMap; @@ -261,4 +262,9 @@ public R allSat(AllSatCallback callback, List important) throw creator.handleZ3Exception(e); } } + + @Override + protected ShutdownManager getShutdownManagerForProverImpl() throws UnsupportedOperationException { + return proverShutdownManager; + } } diff --git a/src/org/sosy_lab/java_smt/solvers/z3/Z3TheoremProver.java b/src/org/sosy_lab/java_smt/solvers/z3/Z3TheoremProver.java index 5ec0eae466..2f967b4fe0 100644 --- a/src/org/sosy_lab/java_smt/solvers/z3/Z3TheoremProver.java +++ b/src/org/sosy_lab/java_smt/solvers/z3/Z3TheoremProver.java @@ -45,7 +45,7 @@ class Z3TheoremProver extends Z3AbstractProver implements ProverEnvironment { Native.solverIncRef(z3context, z3solver); interruptListener = reason -> Native.solverInterrupt(z3context, z3solver); - shutdownNotifier.register(interruptListener); + proverShutdownManager.getNotifier().register(interruptListener); long z3params = Native.mkParams(z3context); Native.paramsIncRef(z3context, z3params); @@ -192,7 +192,7 @@ public void close() { propagator.close(); propagator = null; } - shutdownNotifier.unregister(interruptListener); + proverShutdownManager.getNotifier().unregister(interruptListener); } super.close(); } diff --git a/src/org/sosy_lab/java_smt/test/SolverBasedTest0.java b/src/org/sosy_lab/java_smt/test/SolverBasedTest0.java index e96c7b39f1..6e2b81dc5b 100644 --- a/src/org/sosy_lab/java_smt/test/SolverBasedTest0.java +++ b/src/org/sosy_lab/java_smt/test/SolverBasedTest0.java @@ -386,6 +386,17 @@ protected void requireUserPropagators() { .isEqualTo(Solvers.Z3); } + /** Skip test if the solvers prover can not be shut down without also stopping the context. */ + protected final void requireIsolatedProverShutdown() { + assume() + .withMessage( + "Solver %s does not support shutdown of provers without shutting down the " + + "context as well", + solverToUse()) + .that(solverToUse()) + .isNoneOf(Solvers.CVC5, Solvers.BOOLECTOR, Solvers.SMTINTERPOL); + } + /** * Use this for checking assertions about BooleanFormulas with Truth: * assertThatFormula(formula).is...(). diff --git a/src/org/sosy_lab/java_smt/test/TimeoutTest.java b/src/org/sosy_lab/java_smt/test/TimeoutTest.java index 59d6d6a0c3..aa9d9cdf92 100644 --- a/src/org/sosy_lab/java_smt/test/TimeoutTest.java +++ b/src/org/sosy_lab/java_smt/test/TimeoutTest.java @@ -8,6 +8,7 @@ package org.sosy_lab.java_smt.test; +import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.TruthJUnit.assume; import static org.junit.Assert.assertThrows; @@ -24,6 +25,7 @@ import org.sosy_lab.java_smt.SolverContextFactory.Solvers; import org.sosy_lab.java_smt.api.BasicProverEnvironment; import org.sosy_lab.java_smt.api.BooleanFormula; +import org.sosy_lab.java_smt.api.SolverException; import org.sosy_lab.java_smt.api.Tactic; import org.sosy_lab.java_smt.solvers.opensmt.Logics; @@ -90,43 +92,97 @@ public void testTacticTimeout() { @Test(timeout = TIMEOUT_MILLISECONDS) public void testProverTimeoutInt() throws InterruptedException { requireIntegers(); - testBasicProverTimeoutInt(() -> context.newProverEnvironment()); + testBasicContextTimeoutInt(() -> context.newProverEnvironment()); } @Test(timeout = TIMEOUT_MILLISECONDS) public void testProverTimeoutBv() throws InterruptedException { requireBitvectors(); + testBasicContextTimeoutBv(() -> context.newProverEnvironment()); + } + + // Test shutdown of prover specific shutdown manager. The context should still be usable! + @Test(timeout = TIMEOUT_MILLISECONDS) + public void testProverInterruptWithSubsequentNewProverUsageBv() + throws InterruptedException, SolverException { + requireBitvectors(); + requireIsolatedProverShutdown(); + testBasicProverTimeoutBv(() -> context.newProverEnvironment()); + assertThat(shutdownManager.getNotifier().shouldShutdown()).isFalse(); + + HardBitvectorFormulaGenerator gen = new HardBitvectorFormulaGenerator(bvmgr, bmgr); + try (BasicProverEnvironment pe = context.newProverEnvironment()) { + pe.push(gen.generate(8)); + assertThat(pe.isUnsat()).isTrue(); + } + } + + // Test shutdown of prover specific shutdown manager. The context should still be usable! + @Test(timeout = TIMEOUT_MILLISECONDS) + public void testProverInterruptWithSubsequentNewProverUsageInt() + throws InterruptedException, SolverException { + requireIntegers(); + requireIsolatedProverShutdown(); + + testBasicProverTimeoutInt(() -> context.newProverEnvironment()); + assertThat(shutdownManager.getNotifier().shouldShutdown()).isFalse(); + + HardIntegerFormulaGenerator gen = new HardIntegerFormulaGenerator(imgr, bmgr); + try (BasicProverEnvironment pe = context.newProverEnvironment()) { + pe.push(gen.generate(8)); + assertThat(pe.isUnsat()).isTrue(); + } } @Test(timeout = TIMEOUT_MILLISECONDS) public void testInterpolationProverTimeout() throws InterruptedException { requireInterpolation(); requireIntegers(); - testBasicProverTimeoutInt(() -> context.newProverEnvironmentWithInterpolation()); + testBasicContextTimeoutInt(() -> context.newProverEnvironmentWithInterpolation()); } @Test(timeout = TIMEOUT_MILLISECONDS) public void testOptimizationProverTimeout() throws InterruptedException { requireOptimization(); requireIntegers(); - testBasicProverTimeoutInt(() -> context.newOptimizationProverEnvironment()); + testBasicContextTimeoutInt(() -> context.newOptimizationProverEnvironment()); } + /** Shuts down the shutdown manager of the context. */ + private void testBasicContextTimeoutInt(Supplier> proverConstructor) + throws InterruptedException { + HardIntegerFormulaGenerator gen = new HardIntegerFormulaGenerator(imgr, bmgr); + testBasicContextBasedTimeout(proverConstructor, gen.generate(200)); + } + + /** Shuts down the shutdown manager of the context. */ + private void testBasicContextTimeoutBv(Supplier> proverConstructor) + throws InterruptedException { + HardBitvectorFormulaGenerator gen = new HardBitvectorFormulaGenerator(bvmgr, bmgr); + testBasicContextBasedTimeout(proverConstructor, gen.generate(200)); + } + + /** + * Shuts down the shutdown manager of the prover. Throws an exception for non-supporting solvers. + */ private void testBasicProverTimeoutInt(Supplier> proverConstructor) throws InterruptedException { HardIntegerFormulaGenerator gen = new HardIntegerFormulaGenerator(imgr, bmgr); - testBasicProverTimeout(proverConstructor, gen.generate(200)); + testBasicProverBasedTimeout(proverConstructor, gen.generate(200)); } + /** + * Shuts down the shutdown manager of the prover. Throws an exception for non-supporting solvers. + */ private void testBasicProverTimeoutBv(Supplier> proverConstructor) throws InterruptedException { HardBitvectorFormulaGenerator gen = new HardBitvectorFormulaGenerator(bvmgr, bmgr); - testBasicProverTimeout(proverConstructor, gen.generate(200)); + testBasicProverBasedTimeout(proverConstructor, gen.generate(200)); } @SuppressWarnings("CheckReturnValue") - private void testBasicProverTimeout( + private void testBasicContextBasedTimeout( Supplier> proverConstructor, BooleanFormula instance) throws InterruptedException { Thread t = @@ -146,4 +202,25 @@ private void testBasicProverTimeout( assertThrows(InterruptedException.class, pe::isUnsat); } } + + private void testBasicProverBasedTimeout( + Supplier> proverConstructor, BooleanFormula instance) + throws InterruptedException { + + try (BasicProverEnvironment pe = proverConstructor.get()) { + Thread t = + new Thread( + () -> { + try { + Thread.sleep(delay); + pe.getShutdownManagerForProver().requestShutdown("Shutdown Request"); + } catch (InterruptedException exception) { + throw new UnsupportedOperationException("Unexpected interrupt", exception); + } + }); + pe.push(instance); + t.start(); + assertThrows(InterruptedException.class, pe::isUnsat); + } + } } From 7422f4c19ecae338579edf6219df7b4de6865948 Mon Sep 17 00:00:00 2001 From: BaierD Date: Mon, 2 Jun 2025 12:07:36 +0200 Subject: [PATCH 02/87] Reduce complexity of prover based shutdown getter --- src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java | 8 ++------ .../java_smt/solvers/bitwuzla/BitwuzlaTheoremProver.java | 2 +- .../sosy_lab/java_smt/solvers/cvc4/CVC4TheoremProver.java | 2 +- .../java_smt/solvers/mathsat5/Mathsat5AbstractProver.java | 2 +- .../java_smt/solvers/opensmt/OpenSmtAbstractProver.java | 2 +- .../java_smt/solvers/yices2/Yices2TheoremProver.java | 2 +- .../sosy_lab/java_smt/solvers/z3/Z3AbstractProver.java | 2 +- 7 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java index 4e02ea576c..ad8e9af26b 100644 --- a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java +++ b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java @@ -169,15 +169,11 @@ public void close() { } @Override - public ShutdownManager getShutdownManagerForProver() throws UnsupportedOperationException { - return getShutdownManagerForProverImpl(); - } - - protected ShutdownManager getShutdownManagerForProverImpl() throws UnsupportedOperationException { + public ShutdownManager getShutdownManagerForProver() { // Override this with the prover specific ShutdownManagers notifier for supporting solvers. // The solver should then use the prover specific ShutdownManagers notifier for stopping // instead of the contexts' notifier! throw new UnsupportedOperationException( - "The chosen solver does not support isolated prover " + "shutdown"); + "The chosen solver does not support isolated prover shutdown"); } } diff --git a/src/org/sosy_lab/java_smt/solvers/bitwuzla/BitwuzlaTheoremProver.java b/src/org/sosy_lab/java_smt/solvers/bitwuzla/BitwuzlaTheoremProver.java index 0087f16132..ede6324f12 100644 --- a/src/org/sosy_lab/java_smt/solvers/bitwuzla/BitwuzlaTheoremProver.java +++ b/src/org/sosy_lab/java_smt/solvers/bitwuzla/BitwuzlaTheoremProver.java @@ -252,7 +252,7 @@ protected BitwuzlaModel getEvaluatorWithoutChecks() { } @Override - protected ShutdownManager getShutdownManagerForProverImpl() throws UnsupportedOperationException { + public ShutdownManager getShutdownManagerForProver() throws UnsupportedOperationException { return proverShutdownManager; } diff --git a/src/org/sosy_lab/java_smt/solvers/cvc4/CVC4TheoremProver.java b/src/org/sosy_lab/java_smt/solvers/cvc4/CVC4TheoremProver.java index 33ac359f0a..4fcc55e3b6 100644 --- a/src/org/sosy_lab/java_smt/solvers/cvc4/CVC4TheoremProver.java +++ b/src/org/sosy_lab/java_smt/solvers/cvc4/CVC4TheoremProver.java @@ -264,7 +264,7 @@ public void close() { } @Override - protected ShutdownManager getShutdownManagerForProverImpl() throws UnsupportedOperationException { + public ShutdownManager getShutdownManagerForProver() throws UnsupportedOperationException { return proverShutdownManager; } } diff --git a/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5AbstractProver.java b/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5AbstractProver.java index 3ab242ea5b..53442210f5 100644 --- a/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5AbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5AbstractProver.java @@ -291,7 +291,7 @@ public void callback(long[] model) throws InterruptedException { } @Override - protected ShutdownManager getShutdownManagerForProverImpl() throws UnsupportedOperationException { + public ShutdownManager getShutdownManagerForProver() throws UnsupportedOperationException { return proverShutdownManager; } } diff --git a/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtAbstractProver.java b/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtAbstractProver.java index 8f711f8ace..317257e520 100644 --- a/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtAbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtAbstractProver.java @@ -293,7 +293,7 @@ public void close() { } @Override - protected ShutdownManager getShutdownManagerForProverImpl() throws UnsupportedOperationException { + public ShutdownManager getShutdownManagerForProver() throws UnsupportedOperationException { return proverShutdownManager; } } diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2TheoremProver.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2TheoremProver.java index dd7406dd6b..1f17a187be 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2TheoremProver.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2TheoremProver.java @@ -220,7 +220,7 @@ public void close() { } @Override - protected ShutdownManager getShutdownManagerForProverImpl() throws UnsupportedOperationException { + public ShutdownManager getShutdownManagerForProver() throws UnsupportedOperationException { return proverShutdownManager; } } diff --git a/src/org/sosy_lab/java_smt/solvers/z3/Z3AbstractProver.java b/src/org/sosy_lab/java_smt/solvers/z3/Z3AbstractProver.java index c148102902..678dcd9438 100644 --- a/src/org/sosy_lab/java_smt/solvers/z3/Z3AbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/z3/Z3AbstractProver.java @@ -264,7 +264,7 @@ public R allSat(AllSatCallback callback, List important) } @Override - protected ShutdownManager getShutdownManagerForProverImpl() throws UnsupportedOperationException { + public ShutdownManager getShutdownManagerForProver() throws UnsupportedOperationException { return proverShutdownManager; } } From a43d1838b549be05ebdb1f06de6faf6f7855102d Mon Sep 17 00:00:00 2001 From: BaierD Date: Mon, 2 Jun 2025 12:11:23 +0200 Subject: [PATCH 03/87] Reduce complexity of prover based shutdown getter even more --- .../sosy_lab/java_smt/api/BasicProverEnvironment.java | 8 +++++++- src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java | 9 --------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java b/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java index 34b3ae4bff..69a331cf16 100644 --- a/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java +++ b/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java @@ -217,5 +217,11 @@ default boolean registerUserPropagator(UserPropagator propagator) { * ProverEnvironment}. * @throws UnsupportedOperationException if the solver does not support prover specific shutdown. */ - ShutdownManager getShutdownManagerForProver() throws UnsupportedOperationException; + default ShutdownManager getShutdownManagerForProver() { + // Override this with the prover specific ShutdownManagers notifier for supporting solvers. + // The solver should then use the prover specific ShutdownManagers notifier for stopping + // instead of the contexts' notifier! + throw new UnsupportedOperationException( + "The chosen solver does not support isolated prover shutdown"); + } } diff --git a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java index ad8e9af26b..01fcd2906f 100644 --- a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java +++ b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java @@ -167,13 +167,4 @@ public void close() { closeAllEvaluators(); closed = true; } - - @Override - public ShutdownManager getShutdownManagerForProver() { - // Override this with the prover specific ShutdownManagers notifier for supporting solvers. - // The solver should then use the prover specific ShutdownManagers notifier for stopping - // instead of the contexts' notifier! - throw new UnsupportedOperationException( - "The chosen solver does not support isolated prover shutdown"); - } } From 5af69e680f538770890028198679c2d1e1853e24 Mon Sep 17 00:00:00 2001 From: BaierD Date: Mon, 2 Jun 2025 12:13:51 +0200 Subject: [PATCH 04/87] Remove unnecessary comment in BitwuzlaTheoremProver --- .../java_smt/solvers/bitwuzla/BitwuzlaTheoremProver.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/org/sosy_lab/java_smt/solvers/bitwuzla/BitwuzlaTheoremProver.java b/src/org/sosy_lab/java_smt/solvers/bitwuzla/BitwuzlaTheoremProver.java index ede6324f12..70371a7f17 100644 --- a/src/org/sosy_lab/java_smt/solvers/bitwuzla/BitwuzlaTheoremProver.java +++ b/src/org/sosy_lab/java_smt/solvers/bitwuzla/BitwuzlaTheoremProver.java @@ -41,8 +41,7 @@ class BitwuzlaTheoremProver extends AbstractProverWithAllSat implements Pr public boolean terminate() { return proverShutdownManager .getNotifier() - .shouldShutdown(); // shutdownNotifer is defined in the - // superclass + .shouldShutdown(); } }; private final Bitwuzla env; From 2b81ac8c42e01cbafdd8ebfc9765bc66d5b704ca Mon Sep 17 00:00:00 2001 From: BaierD Date: Mon, 2 Jun 2025 12:44:20 +0200 Subject: [PATCH 05/87] Allow and use direct access to prover specific ShutdownNotifier --- src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java | 7 +++---- .../java_smt/basicimpl/AbstractProverWithAllSat.java | 8 ++++---- .../java_smt/solvers/bitwuzla/BitwuzlaTheoremProver.java | 7 ++----- .../solvers/boolector/BoolectorAbstractProver.java | 2 +- .../sosy_lab/java_smt/solvers/cvc4/CVC4TheoremProver.java | 7 +++---- .../java_smt/solvers/cvc5/CVC5AbstractProver.java | 2 +- .../java_smt/solvers/mathsat5/Mathsat5AbstractProver.java | 4 ++-- .../java_smt/solvers/opensmt/OpenSmtAbstractProver.java | 7 +++---- .../solvers/smtinterpol/SmtInterpolAbstractProver.java | 4 ++-- .../smtinterpol/SmtInterpolInterpolatingProver.java | 2 +- .../java_smt/solvers/yices2/Yices2TheoremProver.java | 6 +++--- src/org/sosy_lab/java_smt/solvers/z3/Z3TheoremProver.java | 4 ++-- 12 files changed, 27 insertions(+), 33 deletions(-) diff --git a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java index 01fcd2906f..b6f0e9d441 100644 --- a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java +++ b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java @@ -49,8 +49,7 @@ public abstract class AbstractProver implements BasicProverEnvironment { private static final String TEMPLATE = "Please set the prover option %s."; - // Do we even need this? - private final ShutdownNotifier contextShutdownNotifier; + protected final ShutdownNotifier proverShutdownNotifier; protected final ShutdownManager proverShutdownManager; protected AbstractProver(ShutdownNotifier pShutdownNotifier, Set pOptions) { @@ -63,8 +62,8 @@ protected AbstractProver(ShutdownNotifier pShutdownNotifier, Set assertedFormulas.add(LinkedHashMultimap.create()); - contextShutdownNotifier = pShutdownNotifier; - proverShutdownManager = ShutdownManager.createWithParent(contextShutdownNotifier); + proverShutdownManager = ShutdownManager.createWithParent(pShutdownNotifier); + proverShutdownNotifier = proverShutdownManager.getNotifier(); } protected final void checkGenerateModels() { diff --git a/src/org/sosy_lab/java_smt/basicimpl/AbstractProverWithAllSat.java b/src/org/sosy_lab/java_smt/basicimpl/AbstractProverWithAllSat.java index 947505ac44..d178188c1d 100644 --- a/src/org/sosy_lab/java_smt/basicimpl/AbstractProverWithAllSat.java +++ b/src/org/sosy_lab/java_smt/basicimpl/AbstractProverWithAllSat.java @@ -66,7 +66,7 @@ private void iterateOverAllModels( AllSatCallback callback, List importantPredicates) throws SolverException, InterruptedException { while (!isUnsat()) { - proverShutdownManager.getNotifier().shutdownIfNecessary(); + proverShutdownNotifier.shutdownIfNecessary(); ImmutableList.Builder valuesOfModel = ImmutableList.builder(); try (Evaluator evaluator = getEvaluatorWithoutChecks()) { @@ -86,11 +86,11 @@ private void iterateOverAllModels( final ImmutableList values = valuesOfModel.build(); callback.apply(values); - proverShutdownManager.getNotifier().shutdownIfNecessary(); + proverShutdownNotifier.shutdownIfNecessary(); BooleanFormula negatedModel = bmgr.not(bmgr.and(values)); addConstraint(negatedModel); - proverShutdownManager.getNotifier().shutdownIfNecessary(); + proverShutdownNotifier.shutdownIfNecessary(); } } @@ -111,7 +111,7 @@ private void iterateOverAllPredicateCombinations( Deque valuesOfModel) throws SolverException, InterruptedException { - proverShutdownManager.getNotifier().shutdownIfNecessary(); + proverShutdownNotifier.shutdownIfNecessary(); if (isUnsat()) { return; diff --git a/src/org/sosy_lab/java_smt/solvers/bitwuzla/BitwuzlaTheoremProver.java b/src/org/sosy_lab/java_smt/solvers/bitwuzla/BitwuzlaTheoremProver.java index 70371a7f17..b5d29d1307 100644 --- a/src/org/sosy_lab/java_smt/solvers/bitwuzla/BitwuzlaTheoremProver.java +++ b/src/org/sosy_lab/java_smt/solvers/bitwuzla/BitwuzlaTheoremProver.java @@ -39,9 +39,7 @@ class BitwuzlaTheoremProver extends AbstractProverWithAllSat implements Pr new Terminator() { @Override public boolean terminate() { - return proverShutdownManager - .getNotifier() - .shouldShutdown(); + return proverShutdownNotifier.shouldShutdown(); } }; private final Bitwuzla env; @@ -122,8 +120,7 @@ private boolean readSATResult(Result resultValue) throws SolverException, Interr return false; } else if (resultValue == Result.UNSAT) { return true; - } else if (resultValue == Result.UNKNOWN - && proverShutdownManager.getNotifier().shouldShutdown()) { + } else if (resultValue == Result.UNKNOWN && proverShutdownNotifier.shouldShutdown()) { throw new InterruptedException(); } else { throw new SolverException("Bitwuzla returned UNKNOWN."); diff --git a/src/org/sosy_lab/java_smt/solvers/boolector/BoolectorAbstractProver.java b/src/org/sosy_lab/java_smt/solvers/boolector/BoolectorAbstractProver.java index f2ca23ea78..c4a99af3d4 100644 --- a/src/org/sosy_lab/java_smt/solvers/boolector/BoolectorAbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/boolector/BoolectorAbstractProver.java @@ -49,7 +49,7 @@ protected BoolectorAbstractProver( this.manager = manager; this.creator = creator; this.btor = btor; - terminationCallback = proverShutdownManager.getNotifier()::shouldShutdown; + terminationCallback = proverShutdownNotifier::shouldShutdown; terminationCallbackHelper = addTerminationCallback(); isAnyStackAlive = pIsAnyStackAlive; diff --git a/src/org/sosy_lab/java_smt/solvers/cvc4/CVC4TheoremProver.java b/src/org/sosy_lab/java_smt/solvers/cvc4/CVC4TheoremProver.java index 4fcc55e3b6..56b9149209 100644 --- a/src/org/sosy_lab/java_smt/solvers/cvc4/CVC4TheoremProver.java +++ b/src/org/sosy_lab/java_smt/solvers/cvc4/CVC4TheoremProver.java @@ -203,12 +203,11 @@ public boolean isUnsat() throws InterruptedException, SolverException { } Result result; - try (ShutdownHook hook = - new ShutdownHook(proverShutdownManager.getNotifier(), smtEngine::interrupt)) { - proverShutdownManager.getNotifier().shutdownIfNecessary(); + try (ShutdownHook hook = new ShutdownHook(proverShutdownNotifier, smtEngine::interrupt)) { + proverShutdownNotifier.shutdownIfNecessary(); result = smtEngine.checkSat(); } - proverShutdownManager.getNotifier().shutdownIfNecessary(); + proverShutdownNotifier.shutdownIfNecessary(); return convertSatResult(result); } diff --git a/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5AbstractProver.java b/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5AbstractProver.java index a4519534a1..252bba0237 100644 --- a/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5AbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5AbstractProver.java @@ -203,7 +203,7 @@ public boolean isUnsat() throws InterruptedException, SolverException { /* Shutdown currently not possible in CVC5. */ Result result = solver.checkSat(); - proverShutdownManager.getNotifier().shutdownIfNecessary(); + proverShutdownNotifier.shutdownIfNecessary(); return convertSatResult(result); } diff --git a/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5AbstractProver.java b/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5AbstractProver.java index 53442210f5..1879af3d5e 100644 --- a/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5AbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5AbstractProver.java @@ -113,7 +113,7 @@ public boolean isUnsat() throws InterruptedException, SolverException { */ private TerminationCallback getTerminationTest() { return () -> { - proverShutdownManager.getNotifier().shutdownIfNecessary(); + proverShutdownNotifier.shutdownIfNecessary(); return false; }; } @@ -283,7 +283,7 @@ class MathsatAllSatCallback implements AllSatModelCallback { @Override public void callback(long[] model) throws InterruptedException { - proverShutdownManager.getNotifier().shutdownIfNecessary(); + proverShutdownNotifier.shutdownIfNecessary(); clientCallback.apply( Collections.unmodifiableList( Lists.transform(Longs.asList(model), creator::encapsulateBoolean))); diff --git a/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtAbstractProver.java b/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtAbstractProver.java index 317257e520..58b864529b 100644 --- a/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtAbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtAbstractProver.java @@ -231,9 +231,8 @@ public boolean isUnsat() throws InterruptedException, SolverException { changedSinceLastSatQuery = false; sstat result; - try (ShutdownHook listener = - new ShutdownHook(proverShutdownManager.getNotifier(), osmtSolver::stop)) { - proverShutdownManager.getNotifier().shutdownIfNecessary(); + try (ShutdownHook listener = new ShutdownHook(proverShutdownNotifier, osmtSolver::stop)) { + proverShutdownNotifier.shutdownIfNecessary(); try { result = osmtSolver.check(); } catch (Exception e) { @@ -252,7 +251,7 @@ public boolean isUnsat() throws InterruptedException, SolverException { throw new SolverException("OpenSMT crashed while checking satisfiability.", e); } } - proverShutdownManager.getNotifier().shutdownIfNecessary(); + proverShutdownNotifier.shutdownIfNecessary(); } if (result.equals(sstat.Error())) { diff --git a/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolAbstractProver.java b/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolAbstractProver.java index 4b2fc684c1..420fe58fcd 100644 --- a/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolAbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolAbstractProver.java @@ -107,7 +107,7 @@ public boolean isUnsat() throws InterruptedException { // by using a shutdown listener. However, SmtInterpol resets the // mStopEngine flag in DPLLEngine before starting to solve, // so we check here, too. - proverShutdownManager.getNotifier().shutdownIfNecessary(); + proverShutdownNotifier.shutdownIfNecessary(); LBool result = env.checkSat(); switch (result) { @@ -244,7 +244,7 @@ public R allSat(AllSatCallback callback, List important) // by using a shutdown listener. However, SmtInterpol resets the // mStopEngine flag in DPLLEngine before starting to solve, // so we check here, too. - proverShutdownManager.getNotifier().shutdownIfNecessary(); + proverShutdownNotifier.shutdownIfNecessary(); for (Term[] model : env.checkAllsat(importantTerms)) { callback.apply(Collections3.transformedImmutableListCopy(model, creator::encapsulateBoolean)); } diff --git a/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolInterpolatingProver.java b/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolInterpolatingProver.java index 98ce562a70..8507444c22 100644 --- a/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolInterpolatingProver.java +++ b/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolInterpolatingProver.java @@ -100,7 +100,7 @@ public List getTreeInterpolants( } } catch (SMTLIBException e) { if ("Timeout exceeded".equals(e.getMessage())) { - proverShutdownManager.getNotifier().shutdownIfNecessary(); + proverShutdownNotifier.shutdownIfNecessary(); } throw new AssertionError(e); } diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2TheoremProver.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2TheoremProver.java index 1f17a187be..ec21759699 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2TheoremProver.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2TheoremProver.java @@ -129,9 +129,9 @@ public boolean isUnsat() throws SolverException, InterruptedException { DEFAULT_PARAMS, allConstraints.length, allConstraints, - proverShutdownManager.getNotifier()); + proverShutdownNotifier); } else { - unsat = !yices_check_sat(curEnv, DEFAULT_PARAMS, proverShutdownManager.getNotifier()); + unsat = !yices_check_sat(curEnv, DEFAULT_PARAMS, proverShutdownNotifier); if (unsat && stackSizeToUnsat == Integer.MAX_VALUE) { stackSizeToUnsat = size(); // If sat check is UNSAT and stackSizeToUnsat waS not already set, @@ -156,7 +156,7 @@ public boolean isUnsatWithAssumptions(Collection pAssumptions) DEFAULT_PARAMS, pAssumptions.size(), uncapsulate(pAssumptions), - proverShutdownManager.getNotifier()); + proverShutdownNotifier); } @SuppressWarnings("resource") diff --git a/src/org/sosy_lab/java_smt/solvers/z3/Z3TheoremProver.java b/src/org/sosy_lab/java_smt/solvers/z3/Z3TheoremProver.java index 2f967b4fe0..66038fa11d 100644 --- a/src/org/sosy_lab/java_smt/solvers/z3/Z3TheoremProver.java +++ b/src/org/sosy_lab/java_smt/solvers/z3/Z3TheoremProver.java @@ -45,7 +45,7 @@ class Z3TheoremProver extends Z3AbstractProver implements ProverEnvironment { Native.solverIncRef(z3context, z3solver); interruptListener = reason -> Native.solverInterrupt(z3context, z3solver); - proverShutdownManager.getNotifier().register(interruptListener); + proverShutdownNotifier.register(interruptListener); long z3params = Native.mkParams(z3context); Native.paramsIncRef(z3context, z3params); @@ -192,7 +192,7 @@ public void close() { propagator.close(); propagator = null; } - proverShutdownManager.getNotifier().unregister(interruptListener); + proverShutdownNotifier.unregister(interruptListener); } super.close(); } From 92f2f60dd72a6741928cdb370af34dff73cc1ee4 Mon Sep 17 00:00:00 2001 From: BaierD Date: Mon, 2 Jun 2025 12:44:47 +0200 Subject: [PATCH 06/87] Add Int and BV test for context shutdown and prover reuse afterward --- .../sosy_lab/java_smt/test/TimeoutTest.java | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/src/org/sosy_lab/java_smt/test/TimeoutTest.java b/src/org/sosy_lab/java_smt/test/TimeoutTest.java index aa9d9cdf92..b0e92d9adb 100644 --- a/src/org/sosy_lab/java_smt/test/TimeoutTest.java +++ b/src/org/sosy_lab/java_smt/test/TimeoutTest.java @@ -135,6 +135,52 @@ public void testProverInterruptWithSubsequentNewProverUsageInt() } } + // Test shutdown of context-wide shutdown manager. No prover should be usable afterward! + @Test(timeout = TIMEOUT_MILLISECONDS) + public void testContextInterruptWithSubsequentNewProverUsageBv() + throws InterruptedException, SolverException { + requireBitvectors(); + requireIsolatedProverShutdown(); + + testBasicContextTimeoutBv(() -> context.newProverEnvironment()); + assertThat(shutdownManager.getNotifier().shouldShutdown()).isTrue(); + + HardBitvectorFormulaGenerator gen = new HardBitvectorFormulaGenerator(bvmgr, bmgr); + try (BasicProverEnvironment pe = context.newProverEnvironment()) { + pe.push(gen.generate(8)); + assertThrows(InterruptedException.class, pe::isUnsat); + + } catch (InterruptedException expected) { + // We don't really know where an exception is coming from currently. + // TODO: define where and how exceptions are thrown if we build a new prover but shutdown + // has been requested. + assertThat(expected).isNotNull(); + } + } + + // Test shutdown of context-wide shutdown manager. No prover should be usable afterward! + @Test(timeout = TIMEOUT_MILLISECONDS) + public void testContextInterruptWithSubsequentNewProverUsageInt() + throws InterruptedException, SolverException { + requireIntegers(); + requireIsolatedProverShutdown(); + + testBasicContextTimeoutInt(() -> context.newProverEnvironment()); + assertThat(shutdownManager.getNotifier().shouldShutdown()).isTrue(); + + HardIntegerFormulaGenerator gen = new HardIntegerFormulaGenerator(imgr, bmgr); + try (BasicProverEnvironment pe = context.newProverEnvironment()) { + pe.push(gen.generate(8)); + assertThrows(InterruptedException.class, pe::isUnsat); + + } catch (InterruptedException expected) { + // We don't really know where an exception is coming from currently. + // TODO: define where and how exceptions are thrown if we build a new prover but shutdown + // has been requested. + assertThat(expected).isNotNull(); + } + } + @Test(timeout = TIMEOUT_MILLISECONDS) public void testInterpolationProverTimeout() throws InterruptedException { requireInterpolation(); From b048f56d9f7f0c16f9deeb27a71d497c6b7cdb62 Mon Sep 17 00:00:00 2001 From: BaierD Date: Mon, 2 Jun 2025 13:03:01 +0200 Subject: [PATCH 07/87] Add default implementation of isUnsat() to centralize checks (closed, shut-down etc.) and add more shutdown checks in the abstract prover --- .../sosy_lab/java_smt/basicimpl/AbstractProver.java | 13 +++++++++++++ .../solvers/bitwuzla/BitwuzlaTheoremProver.java | 2 +- .../solvers/boolector/BoolectorAbstractProver.java | 2 +- .../java_smt/solvers/cvc4/CVC4TheoremProver.java | 4 +--- .../java_smt/solvers/cvc5/CVC5AbstractProver.java | 4 +--- .../solvers/mathsat5/Mathsat5AbstractProver.java | 2 +- .../solvers/opensmt/OpenSmtAbstractProver.java | 4 +--- .../solvers/princess/PrincessAbstractProver.java | 2 +- .../LoggingSmtInterpolInterpolatingProver.java | 4 ++-- .../smtinterpol/SmtInterpolAbstractProver.java | 2 +- .../solvers/yices2/Yices2TheoremProver.java | 2 +- .../java_smt/solvers/z3/Z3OptimizationProver.java | 2 +- .../java_smt/solvers/z3/Z3TheoremProver.java | 2 +- 13 files changed, 26 insertions(+), 19 deletions(-) diff --git a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java index b6f0e9d441..2608d11f47 100644 --- a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java +++ b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java @@ -28,6 +28,7 @@ import org.sosy_lab.java_smt.api.BooleanFormula; import org.sosy_lab.java_smt.api.Evaluator; import org.sosy_lab.java_smt.api.SolverContext.ProverOptions; +import org.sosy_lab.java_smt.api.SolverException; public abstract class AbstractProver implements BasicProverEnvironment { @@ -95,9 +96,20 @@ public int size() { return assertedFormulas.size() - 1; } + @Override + public final boolean isUnsat() throws SolverException, InterruptedException { + checkState(!closed); + closeAllEvaluators(); // TODO: needed? + proverShutdownNotifier.shutdownIfNecessary(); + return isUnsatImpl(); + } + + protected abstract boolean isUnsatImpl() throws SolverException, InterruptedException; + @Override public final void push() throws InterruptedException { checkState(!closed); + proverShutdownNotifier.shutdownIfNecessary(); pushImpl(); assertedFormulas.add(LinkedHashMultimap.create()); } @@ -118,6 +130,7 @@ public final void pop() { @CanIgnoreReturnValue public final @Nullable T addConstraint(BooleanFormula constraint) throws InterruptedException { checkState(!closed); + proverShutdownNotifier.shutdownIfNecessary(); T t = addConstraintImpl(constraint); Iterables.getLast(assertedFormulas).put(constraint, t); return t; diff --git a/src/org/sosy_lab/java_smt/solvers/bitwuzla/BitwuzlaTheoremProver.java b/src/org/sosy_lab/java_smt/solvers/bitwuzla/BitwuzlaTheoremProver.java index b5d29d1307..6e555476a8 100644 --- a/src/org/sosy_lab/java_smt/solvers/bitwuzla/BitwuzlaTheoremProver.java +++ b/src/org/sosy_lab/java_smt/solvers/bitwuzla/BitwuzlaTheoremProver.java @@ -129,7 +129,7 @@ private boolean readSATResult(Result resultValue) throws SolverException, Interr /** Check whether the conjunction of all formulas on the stack is unsatisfiable. */ @Override - public boolean isUnsat() throws SolverException, InterruptedException { + protected boolean isUnsatImpl() throws SolverException, InterruptedException { Preconditions.checkState(!closed); wasLastSatCheckSat = false; final Result result = env.check_sat(); diff --git a/src/org/sosy_lab/java_smt/solvers/boolector/BoolectorAbstractProver.java b/src/org/sosy_lab/java_smt/solvers/boolector/BoolectorAbstractProver.java index c4a99af3d4..864bc3b85b 100644 --- a/src/org/sosy_lab/java_smt/solvers/boolector/BoolectorAbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/boolector/BoolectorAbstractProver.java @@ -81,7 +81,7 @@ public void close() { * Boolector should throw its own exceptions that tell you what went wrong! */ @Override - public boolean isUnsat() throws SolverException, InterruptedException { + protected boolean isUnsatImpl() throws SolverException, InterruptedException { Preconditions.checkState(!closed); wasLastSatCheckSat = false; final int result = BtorJNI.boolector_sat(btor); diff --git a/src/org/sosy_lab/java_smt/solvers/cvc4/CVC4TheoremProver.java b/src/org/sosy_lab/java_smt/solvers/cvc4/CVC4TheoremProver.java index 56b9149209..14e1ec79cd 100644 --- a/src/org/sosy_lab/java_smt/solvers/cvc4/CVC4TheoremProver.java +++ b/src/org/sosy_lab/java_smt/solvers/cvc4/CVC4TheoremProver.java @@ -192,9 +192,7 @@ public ImmutableList getModelAssignments() throws SolverExcepti @Override @SuppressWarnings("try") - public boolean isUnsat() throws InterruptedException, SolverException { - Preconditions.checkState(!closed); - closeAllEvaluators(); + protected boolean isUnsatImpl() throws InterruptedException, SolverException { changedSinceLastSatQuery = false; if (!incremental) { for (BooleanFormula f : getAssertedFormulas()) { diff --git a/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5AbstractProver.java b/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5AbstractProver.java index 252bba0237..a46a4b9fa3 100644 --- a/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5AbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5AbstractProver.java @@ -193,9 +193,7 @@ public ImmutableList getModelAssignments() throws SolverExcepti @Override @SuppressWarnings("try") - public boolean isUnsat() throws InterruptedException, SolverException { - Preconditions.checkState(!closed); - closeAllEvaluators(); + public boolean isUnsatImpl() throws InterruptedException, SolverException { changedSinceLastSatQuery = false; if (!incremental) { getAssertedFormulas().forEach(f -> solver.assertFormula(creator.extractInfo(f))); diff --git a/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5AbstractProver.java b/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5AbstractProver.java index 1879af3d5e..411bf0b157 100644 --- a/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5AbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5AbstractProver.java @@ -95,7 +95,7 @@ private long buildConfig(Set opts) { protected abstract void createConfig(Map pConfig); @Override - public boolean isUnsat() throws InterruptedException, SolverException { + protected boolean isUnsatImpl() throws InterruptedException, SolverException { Preconditions.checkState(!closed); final long hook = msat_set_termination_callback(curEnv, getTerminationTest()); diff --git a/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtAbstractProver.java b/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtAbstractProver.java index 58b864529b..8adf86c177 100644 --- a/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtAbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtAbstractProver.java @@ -225,9 +225,7 @@ protected String getReasonFromSolverFeatures( @Override @SuppressWarnings("try") // ShutdownHook is never referenced, and this is correct. - public boolean isUnsat() throws InterruptedException, SolverException { - Preconditions.checkState(!closed); - closeAllEvaluators(); + protected boolean isUnsatImpl() throws InterruptedException, SolverException { changedSinceLastSatQuery = false; sstat result; diff --git a/src/org/sosy_lab/java_smt/solvers/princess/PrincessAbstractProver.java b/src/org/sosy_lab/java_smt/solvers/princess/PrincessAbstractProver.java index a816ed5c7e..6513c09ad3 100644 --- a/src/org/sosy_lab/java_smt/solvers/princess/PrincessAbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/princess/PrincessAbstractProver.java @@ -85,7 +85,7 @@ protected PrincessAbstractProver( * SAT or UNSAT. */ @Override - public boolean isUnsat() throws SolverException { + protected boolean isUnsatImpl() throws SolverException { Preconditions.checkState(!closed); wasLastSatCheckSat = false; evaluatedTerms.clear(); diff --git a/src/org/sosy_lab/java_smt/solvers/smtinterpol/LoggingSmtInterpolInterpolatingProver.java b/src/org/sosy_lab/java_smt/solvers/smtinterpol/LoggingSmtInterpolInterpolatingProver.java index 3b9544fdfb..f92b2190f8 100644 --- a/src/org/sosy_lab/java_smt/solvers/smtinterpol/LoggingSmtInterpolInterpolatingProver.java +++ b/src/org/sosy_lab/java_smt/solvers/smtinterpol/LoggingSmtInterpolInterpolatingProver.java @@ -90,9 +90,9 @@ public R allSat(AllSatCallback callback, List predicates) } @Override - public boolean isUnsat() throws InterruptedException { + protected boolean isUnsatImpl() throws InterruptedException { out.print("(check-sat)"); - boolean isUnsat = super.isUnsat(); + boolean isUnsat = super.isUnsatImpl(); out.println(" ; " + (isUnsat ? "UNSAT" : "SAT")); return isUnsat; } diff --git a/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolAbstractProver.java b/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolAbstractProver.java index 420fe58fcd..ba8658d9a3 100644 --- a/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolAbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolAbstractProver.java @@ -100,7 +100,7 @@ protected String addConstraint0(BooleanFormula constraint) { } @Override - public boolean isUnsat() throws InterruptedException { + protected boolean isUnsatImpl() throws InterruptedException { checkState(!closed); // We actually terminate SmtInterpol during the analysis diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2TheoremProver.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2TheoremProver.java index ec21759699..c3cdfb3756 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2TheoremProver.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2TheoremProver.java @@ -118,7 +118,7 @@ protected void pushImpl() throws InterruptedException { } @Override - public boolean isUnsat() throws SolverException, InterruptedException { + protected boolean isUnsatImpl() throws SolverException, InterruptedException { Preconditions.checkState(!closed); boolean unsat; if (generateUnsatCores) { // unsat core does not work with incremental mode diff --git a/src/org/sosy_lab/java_smt/solvers/z3/Z3OptimizationProver.java b/src/org/sosy_lab/java_smt/solvers/z3/Z3OptimizationProver.java index 3c87cf7739..924fbd4d86 100644 --- a/src/org/sosy_lab/java_smt/solvers/z3/Z3OptimizationProver.java +++ b/src/org/sosy_lab/java_smt/solvers/z3/Z3OptimizationProver.java @@ -132,7 +132,7 @@ protected long getUnsatCore0() { } @Override - public boolean isUnsat() throws SolverException, InterruptedException { + protected boolean isUnsatImpl() throws SolverException, InterruptedException { Preconditions.checkState(!closed); logSolverStack(); return check() == OptStatus.UNSAT; diff --git a/src/org/sosy_lab/java_smt/solvers/z3/Z3TheoremProver.java b/src/org/sosy_lab/java_smt/solvers/z3/Z3TheoremProver.java index 66038fa11d..96bc5171fa 100644 --- a/src/org/sosy_lab/java_smt/solvers/z3/Z3TheoremProver.java +++ b/src/org/sosy_lab/java_smt/solvers/z3/Z3TheoremProver.java @@ -83,7 +83,7 @@ protected void assertContraintAndTrack(long constraint, long symbol) { } @Override - public boolean isUnsat() throws SolverException, InterruptedException { + protected boolean isUnsatImpl() throws SolverException, InterruptedException { Preconditions.checkState(!closed); logSolverStack(); int result; From e73b88924df72d1807869ec29a74b5297fadc976 Mon Sep 17 00:00:00 2001 From: BaierD Date: Mon, 2 Jun 2025 15:02:18 +0200 Subject: [PATCH 08/87] Add more timeout/shutdown tests: - test context interrupt with subsequent prover usage - test prover interrupt with subsequent feature usage (ignored because unfinished) --- .../sosy_lab/java_smt/test/TimeoutTest.java | 181 +++++++++++++++++- 1 file changed, 172 insertions(+), 9 deletions(-) diff --git a/src/org/sosy_lab/java_smt/test/TimeoutTest.java b/src/org/sosy_lab/java_smt/test/TimeoutTest.java index b0e92d9adb..1057302a84 100644 --- a/src/org/sosy_lab/java_smt/test/TimeoutTest.java +++ b/src/org/sosy_lab/java_smt/test/TimeoutTest.java @@ -11,12 +11,15 @@ import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.TruthJUnit.assume; import static org.junit.Assert.assertThrows; +import static org.sosy_lab.java_smt.SolverContextFactory.Solvers.BOOLECTOR; +import com.google.common.collect.ImmutableList; import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.function.Supplier; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -25,6 +28,7 @@ import org.sosy_lab.java_smt.SolverContextFactory.Solvers; import org.sosy_lab.java_smt.api.BasicProverEnvironment; import org.sosy_lab.java_smt.api.BooleanFormula; +import org.sosy_lab.java_smt.api.SolverContext.ProverOptions; import org.sosy_lab.java_smt.api.SolverException; import org.sosy_lab.java_smt.api.Tactic; import org.sosy_lab.java_smt.solvers.opensmt.Logics; @@ -140,21 +144,14 @@ public void testProverInterruptWithSubsequentNewProverUsageInt() public void testContextInterruptWithSubsequentNewProverUsageBv() throws InterruptedException, SolverException { requireBitvectors(); - requireIsolatedProverShutdown(); testBasicContextTimeoutBv(() -> context.newProverEnvironment()); assertThat(shutdownManager.getNotifier().shouldShutdown()).isTrue(); HardBitvectorFormulaGenerator gen = new HardBitvectorFormulaGenerator(bvmgr, bmgr); try (BasicProverEnvironment pe = context.newProverEnvironment()) { - pe.push(gen.generate(8)); + assertThrows(InterruptedException.class, () -> pe.push(gen.generate(8))); assertThrows(InterruptedException.class, pe::isUnsat); - - } catch (InterruptedException expected) { - // We don't really know where an exception is coming from currently. - // TODO: define where and how exceptions are thrown if we build a new prover but shutdown - // has been requested. - assertThat(expected).isNotNull(); } } @@ -163,7 +160,6 @@ public void testContextInterruptWithSubsequentNewProverUsageBv() public void testContextInterruptWithSubsequentNewProverUsageInt() throws InterruptedException, SolverException { requireIntegers(); - requireIsolatedProverShutdown(); testBasicContextTimeoutInt(() -> context.newProverEnvironment()); assertThat(shutdownManager.getNotifier().shouldShutdown()).isTrue(); @@ -181,6 +177,122 @@ public void testContextInterruptWithSubsequentNewProverUsageInt() } } + // Test shutdown of context-wide shutdown manager. No prover should be usable afterward! + // This test re-uses provers that already existed before the shutdown. + @Test(timeout = TIMEOUT_MILLISECONDS) + public void testContextInterruptWithSubsequentProverUsageBv() throws InterruptedException { + requireBitvectors(); + assume() + .withMessage("Boolector does not support multiple provers") + .that(solverToUse()) + .isNotEqualTo(BOOLECTOR); + + HardBitvectorFormulaGenerator gen = new HardBitvectorFormulaGenerator(bvmgr, bmgr); + try (BasicProverEnvironment pe1 = context.newProverEnvironment()) { + try (BasicProverEnvironment pe2 = context.newProverEnvironment()) { + pe2.push(gen.generate(8)); + + testBasicContextTimeoutBv(() -> context.newProverEnvironment()); + assertThat(shutdownManager.getNotifier().shouldShutdown()).isTrue(); + try { + assertThat(pe1.getShutdownManagerForProver().getNotifier().shouldShutdown()).isTrue(); + assertThat(pe2.getShutdownManagerForProver().getNotifier().shouldShutdown()).isTrue(); + } catch (UnsupportedOperationException mayBeThrown) { + // Do nothing, we can't check for solvers that don't support this + } + + assertThrows(InterruptedException.class, () -> pe1.push(gen.generate(8))); + assertThrows(InterruptedException.class, pe2::isUnsat); + } + } + } + + // Test shutdown of context-wide shutdown manager. No prover should be usable afterward! + // This test re-uses provers that already existed before the shutdown. + @Test(timeout = TIMEOUT_MILLISECONDS) + public void testContextInterruptWithSubsequentProverUsageInt() throws InterruptedException { + requireIntegers(); + + HardIntegerFormulaGenerator gen = new HardIntegerFormulaGenerator(imgr, bmgr); + try (BasicProverEnvironment pe1 = context.newProverEnvironment()) { + try (BasicProverEnvironment pe2 = context.newProverEnvironment()) { + pe2.push(gen.generate(8)); + + testBasicContextTimeoutInt(() -> context.newProverEnvironment()); + assertThat(shutdownManager.getNotifier().shouldShutdown()).isTrue(); + try { + assertThat(pe1.getShutdownManagerForProver().getNotifier().shouldShutdown()).isTrue(); + assertThat(pe2.getShutdownManagerForProver().getNotifier().shouldShutdown()).isTrue(); + } catch (UnsupportedOperationException mayBeThrown) { + // Do nothing, we can't check for solvers that don't support this + } + + assertThrows(InterruptedException.class, () -> pe1.push(gen.generate(8))); + assertThrows(InterruptedException.class, pe2::isUnsat); + } + } + } + + // Test shutdown of prover and subsequent feature usage. + @Ignore + @Test(timeout = TIMEOUT_MILLISECONDS) + public void testProverInterruptWithSubsequentFeatureUsageBv() throws InterruptedException { + requireBitvectors(); + requireIsolatedProverShutdown(); + + HardBitvectorFormulaGenerator gen = new HardBitvectorFormulaGenerator(bvmgr, bmgr); + try (BasicProverEnvironment pe1 = context.newProverEnvironment()) { + try (BasicProverEnvironment pe2 = context.newProverEnvironment()) { + pe2.push(gen.generate(8)); + + testBasicProverTimeoutWithFeatureUsageBv(() -> context.newProverEnvironment()); + assertThat(shutdownManager.getNotifier().shouldShutdown()).isTrue(); + try { + assertThat(pe1.getShutdownManagerForProver().getNotifier().shouldShutdown()).isTrue(); + assertThat(pe2.getShutdownManagerForProver().getNotifier().shouldShutdown()).isTrue(); + } catch (UnsupportedOperationException mayBeThrown) { + // Do nothing, we can't check for solvers that don't support this + } + + assertThrows(InterruptedException.class, () -> pe1.push(gen.generate(8))); + assertThrows(InterruptedException.class, pe2::isUnsat); + } + } + } + + // Test shutdown of prover and subsequent feature usage. + @Ignore + @Test(timeout = TIMEOUT_MILLISECONDS) + public void testContextInterruptWithSubsequentFeatureUsageInt() throws InterruptedException { + requireIntegers(); + requireIsolatedProverShutdown(); + + HardIntegerFormulaGenerator gen = new HardIntegerFormulaGenerator(imgr, bmgr); + try (BasicProverEnvironment pe1 = context.newProverEnvironment()) { + try (BasicProverEnvironment pe2 = context.newProverEnvironment()) { + pe2.push(gen.generate(8)); + + testBasicProverTimeoutWithFeatureUsageInt( + () -> + context.newProverEnvironment( + ProverOptions.GENERATE_UNSAT_CORE, + ProverOptions.GENERATE_MODELS, + ProverOptions.GENERATE_ALL_SAT, + ProverOptions.GENERATE_UNSAT_CORE_OVER_ASSUMPTIONS)); + assertThat(shutdownManager.getNotifier().shouldShutdown()).isTrue(); + try { + assertThat(pe1.getShutdownManagerForProver().getNotifier().shouldShutdown()).isTrue(); + assertThat(pe2.getShutdownManagerForProver().getNotifier().shouldShutdown()).isTrue(); + } catch (UnsupportedOperationException mayBeThrown) { + // Do nothing, we can't check for solvers that don't support this + } + + assertThrows(InterruptedException.class, () -> pe1.push(gen.generate(8))); + assertThrows(InterruptedException.class, pe2::isUnsat); + } + } + } + @Test(timeout = TIMEOUT_MILLISECONDS) public void testInterpolationProverTimeout() throws InterruptedException { requireInterpolation(); @@ -227,6 +339,26 @@ private void testBasicProverTimeoutBv(Supplier> prover testBasicProverBasedTimeout(proverConstructor, gen.generate(200)); } + /** + * Shuts down the shutdown manager of the prover. Throws an exception for non-supporting solvers. + * Will try to use all available features of the solver afterward. (Model, UnsatCore etc.) + */ + private void testBasicProverTimeoutWithFeatureUsageInt( + Supplier> proverConstructor) throws InterruptedException { + HardIntegerFormulaGenerator gen = new HardIntegerFormulaGenerator(imgr, bmgr); + testProverBasedTimeoutWithFeatures(proverConstructor, gen.generate(200)); + } + + /** + * Shuts down the shutdown manager of the prover. Throws an exception for non-supporting solvers. + * Will try to use all available features of the solver afterward. (Model, UnsatCore etc.) + */ + private void testBasicProverTimeoutWithFeatureUsageBv( + Supplier> proverConstructor) throws InterruptedException { + HardBitvectorFormulaGenerator gen = new HardBitvectorFormulaGenerator(bvmgr, bmgr); + testProverBasedTimeoutWithFeatures(proverConstructor, gen.generate(200)); + } + @SuppressWarnings("CheckReturnValue") private void testBasicContextBasedTimeout( Supplier> proverConstructor, BooleanFormula instance) @@ -269,4 +401,35 @@ private void testBasicProverBasedTimeout( assertThrows(InterruptedException.class, pe::isUnsat); } } + + private void testProverBasedTimeoutWithFeatures( + Supplier> proverConstructor, BooleanFormula instance) + throws InterruptedException { + + // TODO: maybe add a test that solves something correctly before interrupting? + + try (BasicProverEnvironment pe = proverConstructor.get()) { + Thread t = + new Thread( + () -> { + try { + Thread.sleep(delay); + pe.getShutdownManagerForProver().requestShutdown("Shutdown Request"); + } catch (InterruptedException exception) { + throw new UnsupportedOperationException("Unexpected interrupt", exception); + } + }); + pe.push(instance); + t.start(); + assertThrows(InterruptedException.class, pe::isUnsat); + assertThrows(InterruptedException.class, pe::getModel); + assertThrows(InterruptedException.class, pe::getUnsatCore); + assertThrows( + InterruptedException.class, () -> pe.isUnsatWithAssumptions(ImmutableList.of(instance))); + assertThrows(InterruptedException.class, () -> pe.addConstraint(instance)); + assertThrows(InterruptedException.class, () -> pe.push(instance)); + assertThrows(InterruptedException.class, pe::push); + assertThrows(InterruptedException.class, pe::pop); + } + } } From ba6c2bc7d8f879223a8205de2e130104a6d536c0 Mon Sep 17 00:00:00 2001 From: BaierD Date: Mon, 2 Jun 2025 15:38:54 +0200 Subject: [PATCH 09/87] Add a model test that checks error when requesting a model for UNSAT (do we have this already elsewhere?) --- src/org/sosy_lab/java_smt/test/ModelTest.java | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/org/sosy_lab/java_smt/test/ModelTest.java b/src/org/sosy_lab/java_smt/test/ModelTest.java index c8a9370415..22feeab36f 100644 --- a/src/org/sosy_lab/java_smt/test/ModelTest.java +++ b/src/org/sosy_lab/java_smt/test/ModelTest.java @@ -2431,6 +2431,32 @@ public void testDeeplyNestedFormulaBV() throws SolverException, InterruptedExcep var -> bvmgr.equal(var, bvmgr.makeBitvector(4, 1))); } + @Test + public void testModelAfterUnsatInt() throws SolverException, InterruptedException { + requireIntegers(); + try (ProverEnvironment prover = context.newProverEnvironment(ProverOptions.GENERATE_MODELS)) { + HardIntegerFormulaGenerator gen = new HardIntegerFormulaGenerator(imgr, bmgr); + prover.push(gen.generate(8)); + + assertThat(prover).isUnsatisfiable(); + + assertThrows(IllegalStateException.class, prover::getModel); + } + } + + @Test + public void testModelAfterUnsatBv() throws SolverException, InterruptedException { + requireBitvectors(); + try (ProverEnvironment prover = context.newProverEnvironment(ProverOptions.GENERATE_MODELS)) { + HardBitvectorFormulaGenerator gen = new HardBitvectorFormulaGenerator(bvmgr, bmgr); + prover.push(gen.generate(8)); + + assertThat(prover).isUnsatisfiable(); + + assertThrows(IllegalStateException.class, prover::getModel); + } + } + /** * Build a deep nesting that is easy to solve and can not be simplified by the solver. If any part * of JavaSMT or the solver tries to analyse all branches of this formula, the runtime is @@ -2459,7 +2485,9 @@ private void testDeeplyNestedFormula( private void evaluateInModel(BooleanFormula constraint, Formula variable, Object expectedValue) throws SolverException, InterruptedException { - try (ProverEnvironment prover = context.newProverEnvironment(ProverOptions.GENERATE_MODELS)) { + try (ProverEnvironment prover = + context.newProverEnvironment( + ProverOptions.GENERATE_MODELS, ProverOptions.GENERATE_UNSAT_CORE)) { prover.push(constraint); assertThat(prover).isSatisfiable(); From 28d56482ebf011f2db5034919fa7bb88e440b2a7 Mon Sep 17 00:00:00 2001 From: BaierD Date: Mon, 2 Jun 2025 15:41:55 +0200 Subject: [PATCH 10/87] Remove unnecessary exceptions from test methods in TimeoutTest --- src/org/sosy_lab/java_smt/test/TimeoutTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/org/sosy_lab/java_smt/test/TimeoutTest.java b/src/org/sosy_lab/java_smt/test/TimeoutTest.java index 1057302a84..7009593d95 100644 --- a/src/org/sosy_lab/java_smt/test/TimeoutTest.java +++ b/src/org/sosy_lab/java_smt/test/TimeoutTest.java @@ -142,7 +142,7 @@ public void testProverInterruptWithSubsequentNewProverUsageInt() // Test shutdown of context-wide shutdown manager. No prover should be usable afterward! @Test(timeout = TIMEOUT_MILLISECONDS) public void testContextInterruptWithSubsequentNewProverUsageBv() - throws InterruptedException, SolverException { + throws InterruptedException { requireBitvectors(); testBasicContextTimeoutBv(() -> context.newProverEnvironment()); @@ -158,7 +158,7 @@ public void testContextInterruptWithSubsequentNewProverUsageBv() // Test shutdown of context-wide shutdown manager. No prover should be usable afterward! @Test(timeout = TIMEOUT_MILLISECONDS) public void testContextInterruptWithSubsequentNewProverUsageInt() - throws InterruptedException, SolverException { + throws InterruptedException { requireIntegers(); testBasicContextTimeoutInt(() -> context.newProverEnvironment()); From 5de59716be5bba69f754f3644c094a62554243b3 Mon Sep 17 00:00:00 2001 From: BaierD Date: Mon, 2 Jun 2025 16:19:07 +0200 Subject: [PATCH 11/87] Format TimeoutTest --- src/org/sosy_lab/java_smt/test/TimeoutTest.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/org/sosy_lab/java_smt/test/TimeoutTest.java b/src/org/sosy_lab/java_smt/test/TimeoutTest.java index 7009593d95..d2f685b4d8 100644 --- a/src/org/sosy_lab/java_smt/test/TimeoutTest.java +++ b/src/org/sosy_lab/java_smt/test/TimeoutTest.java @@ -141,8 +141,7 @@ public void testProverInterruptWithSubsequentNewProverUsageInt() // Test shutdown of context-wide shutdown manager. No prover should be usable afterward! @Test(timeout = TIMEOUT_MILLISECONDS) - public void testContextInterruptWithSubsequentNewProverUsageBv() - throws InterruptedException { + public void testContextInterruptWithSubsequentNewProverUsageBv() throws InterruptedException { requireBitvectors(); testBasicContextTimeoutBv(() -> context.newProverEnvironment()); @@ -157,8 +156,7 @@ public void testContextInterruptWithSubsequentNewProverUsageBv() // Test shutdown of context-wide shutdown manager. No prover should be usable afterward! @Test(timeout = TIMEOUT_MILLISECONDS) - public void testContextInterruptWithSubsequentNewProverUsageInt() - throws InterruptedException { + public void testContextInterruptWithSubsequentNewProverUsageInt() throws InterruptedException { requireIntegers(); testBasicContextTimeoutInt(() -> context.newProverEnvironment()); @@ -247,6 +245,7 @@ public void testProverInterruptWithSubsequentFeatureUsageBv() throws Interrupted testBasicProverTimeoutWithFeatureUsageBv(() -> context.newProverEnvironment()); assertThat(shutdownManager.getNotifier().shouldShutdown()).isTrue(); + try { assertThat(pe1.getShutdownManagerForProver().getNotifier().shouldShutdown()).isTrue(); assertThat(pe2.getShutdownManagerForProver().getNotifier().shouldShutdown()).isTrue(); From 0f8e75768c7f4ee5d86a3c35ba53c5f5357b3dc5 Mon Sep 17 00:00:00 2001 From: BaierD Date: Mon, 2 Jun 2025 16:20:42 +0200 Subject: [PATCH 12/87] Add default handling for basic prover API like isUnsat(), getUnsatCore() etc. so that interrupts and common prerequisites are uniformly handled --- .../java_smt/api/BasicProverEnvironment.java | 13 +-- .../java_smt/basicimpl/AbstractProver.java | 79 ++++++++++++++++++- .../DebuggingBasicProverEnvironment.java | 7 ++ .../StatisticsBasicProverEnvironment.java | 7 ++ .../SynchronizedBasicProverEnvironment.java | 7 ++ ...izedBasicProverEnvironmentWithContext.java | 6 ++ .../bitwuzla/BitwuzlaTheoremProver.java | 19 +---- .../boolector/BoolectorAbstractProver.java | 12 ++- .../solvers/cvc4/CVC4TheoremProver.java | 41 ++-------- .../solvers/cvc5/CVC5AbstractProver.java | 39 ++------- .../mathsat5/Mathsat5AbstractProver.java | 11 +-- .../mathsat5/Mathsat5OptimizationProver.java | 7 +- .../opensmt/OpenSmtAbstractProver.java | 40 ++-------- .../princess/PrincessAbstractProver.java | 13 +-- .../SmtInterpolAbstractProver.java | 14 +--- .../solvers/yices2/Yices2TheoremProver.java | 14 +--- .../java_smt/solvers/z3/Z3AbstractProver.java | 10 +-- .../solvers/z3/Z3OptimizationProver.java | 6 +- .../java_smt/solvers/z3/Z3TheoremProver.java | 4 +- 19 files changed, 167 insertions(+), 182 deletions(-) diff --git a/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java b/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java index 69a331cf16..073ee38735 100644 --- a/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java +++ b/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java @@ -24,8 +24,13 @@ * provides only the common operations. In most cases, just use one of the two sub-interfaces */ public interface BasicProverEnvironment extends AutoCloseable { + String NO_MODEL_HELP = "Model computation failed. Are the pushed formulae " + "satisfiable?"; - String NO_MODEL_HELP = "Model computation failed. Are the pushed formulae satisfiable?"; + String NO_UNSAT_CORE_HELP = + "UnsatCore computation failed. Are the pushed formulae " + "unsatisfiable?"; + + String STACK_CHANGED_HELP = + "Computation failed. The prover state has changed since the last " + "call to isUnsat()."; /** * Push a backtracking point and add a formula to the current stack, asserting it. The return @@ -109,11 +114,7 @@ default Evaluator getEvaluator() throws SolverException { *

Note that if you need to iterate multiple times over the model it may be more efficient to * use this method instead of {@link #getModel()} (depending on the solver). */ - default ImmutableList getModelAssignments() throws SolverException { - try (Model model = getModel()) { - return model.asList(); - } - } + ImmutableList getModelAssignments() throws SolverException; /** * Get an unsat core. This should be called only immediately after an {@link #isUnsat()} call that diff --git a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java index 2608d11f47..c7fa72d2a2 100644 --- a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java +++ b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java @@ -18,8 +18,10 @@ import com.google.common.collect.Multimap; import com.google.errorprone.annotations.CanIgnoreReturnValue; import java.util.ArrayList; +import java.util.Collection; import java.util.LinkedHashSet; import java.util.List; +import java.util.Optional; import java.util.Set; import org.checkerframework.checker.nullness.qual.Nullable; import org.sosy_lab.common.ShutdownManager; @@ -27,6 +29,7 @@ import org.sosy_lab.java_smt.api.BasicProverEnvironment; import org.sosy_lab.java_smt.api.BooleanFormula; import org.sosy_lab.java_smt.api.Evaluator; +import org.sosy_lab.java_smt.api.Model; import org.sosy_lab.java_smt.api.SolverContext.ProverOptions; import org.sosy_lab.java_smt.api.SolverException; @@ -38,6 +41,8 @@ public abstract class AbstractProver implements BasicProverEnvironment { private final boolean generateUnsatCoresOverAssumptions; protected final boolean enableSL; protected boolean closed = false; + protected boolean wasLastSatCheckSat = false; + protected boolean stackChangedSinceLastQuery = false; private final Set evaluators = new LinkedHashSet<>(); @@ -75,11 +80,11 @@ protected final void checkGenerateAllSat() { Preconditions.checkState(generateAllSat, TEMPLATE, ProverOptions.GENERATE_ALL_SAT); } - protected final void checkGenerateUnsatCores() { + private final void checkGenerateUnsatCores() { Preconditions.checkState(generateUnsatCores, TEMPLATE, ProverOptions.GENERATE_UNSAT_CORE); } - protected final void checkGenerateUnsatCoresOverAssumptions() { + private final void checkGenerateUnsatCoresOverAssumptions() { Preconditions.checkState( generateUnsatCoresOverAssumptions, TEMPLATE, @@ -99,18 +104,68 @@ public int size() { @Override public final boolean isUnsat() throws SolverException, InterruptedException { checkState(!closed); - closeAllEvaluators(); // TODO: needed? + closeAllEvaluators(); proverShutdownNotifier.shutdownIfNecessary(); - return isUnsatImpl(); + wasLastSatCheckSat = !isUnsatImpl(); + stackChangedSinceLastQuery = false; + return !wasLastSatCheckSat; } protected abstract boolean isUnsatImpl() throws SolverException, InterruptedException; + @Override + public List getUnsatCore() { + checkState(!closed); + checkState(!proverShutdownNotifier.shouldShutdown()); + checkState(!wasLastSatCheckSat, NO_UNSAT_CORE_HELP); + checkState(!stackChangedSinceLastQuery, STACK_CHANGED_HELP); + checkGenerateUnsatCores(); + return getUnsatCoreImpl(); + } + + protected abstract List getUnsatCoreImpl(); + + @Override + public final Optional> unsatCoreOverAssumptions( + Collection assumptions) throws SolverException, InterruptedException { + checkState(!closed); + proverShutdownNotifier.shutdownIfNecessary(); + checkGenerateUnsatCoresOverAssumptions(); + return unsatCoreOverAssumptionsImpl(assumptions); + } + + protected abstract Optional> unsatCoreOverAssumptionsImpl( + Collection assumptions) throws SolverException, InterruptedException; + + @Override + public final boolean isUnsatWithAssumptions(Collection assumptions) + throws SolverException, InterruptedException { + checkState(!closed); + proverShutdownNotifier.shutdownIfNecessary(); + return isUnsatWithAssumptionsImpl(assumptions); + } + + protected abstract boolean isUnsatWithAssumptionsImpl(Collection assumptions) + throws SolverException, InterruptedException; + + @Override + public final Model getModel() throws SolverException { + checkState(!closed); + checkState(!proverShutdownNotifier.shouldShutdown()); + checkState(wasLastSatCheckSat, NO_MODEL_HELP); + checkState(!stackChangedSinceLastQuery, STACK_CHANGED_HELP); + checkGenerateModels(); + return getModelImpl(); + } + + protected abstract Model getModelImpl() throws SolverException; + @Override public final void push() throws InterruptedException { checkState(!closed); proverShutdownNotifier.shutdownIfNecessary(); pushImpl(); + stackChangedSinceLastQuery = true; assertedFormulas.add(LinkedHashMultimap.create()); } @@ -121,6 +176,9 @@ public final void pop() { checkState(!closed); checkState(assertedFormulas.size() > 1, "initial level must remain until close"); assertedFormulas.remove(assertedFormulas.size() - 1); // remove last + // TODO: technically only needed if the level removed was non empty. + stackChangedSinceLastQuery = true; + wasLastSatCheckSat = false; popImpl(); } @@ -133,6 +191,8 @@ public final void pop() { proverShutdownNotifier.shutdownIfNecessary(); T t = addConstraintImpl(constraint); Iterables.getLast(assertedFormulas).put(constraint, t); + stackChangedSinceLastQuery = true; + wasLastSatCheckSat = false; return t; } @@ -173,6 +233,17 @@ protected void closeAllEvaluators() { evaluators.clear(); } + @Override + public ImmutableList getModelAssignments() throws SolverException { + Preconditions.checkState(!closed); + checkState(!proverShutdownNotifier.shouldShutdown()); + Preconditions.checkState(!stackChangedSinceLastQuery, STACK_CHANGED_HELP); + checkState(wasLastSatCheckSat); + try (Model model = getModel()) { + return model.asList(); + } + } + @Override public void close() { assertedFormulas.clear(); diff --git a/src/org/sosy_lab/java_smt/delegate/debugging/DebuggingBasicProverEnvironment.java b/src/org/sosy_lab/java_smt/delegate/debugging/DebuggingBasicProverEnvironment.java index 45155f5eb3..ce1bf994fb 100644 --- a/src/org/sosy_lab/java_smt/delegate/debugging/DebuggingBasicProverEnvironment.java +++ b/src/org/sosy_lab/java_smt/delegate/debugging/DebuggingBasicProverEnvironment.java @@ -10,6 +10,7 @@ import static com.google.common.base.Preconditions.checkNotNull; +import com.google.common.collect.ImmutableList; import java.util.Collection; import java.util.List; import java.util.Optional; @@ -18,6 +19,7 @@ import org.sosy_lab.java_smt.api.BasicProverEnvironment; import org.sosy_lab.java_smt.api.BooleanFormula; import org.sosy_lab.java_smt.api.Model; +import org.sosy_lab.java_smt.api.Model.ValueAssignment; import org.sosy_lab.java_smt.api.SolverException; class DebuggingBasicProverEnvironment implements BasicProverEnvironment { @@ -83,6 +85,11 @@ public Model getModel() throws SolverException { return new DebuggingModel(delegate.getModel(), debugging); } + @Override + public ImmutableList getModelAssignments() throws SolverException { + return delegate.getModelAssignments(); + } + @Override public List getUnsatCore() { debugging.assertThreadLocal(); diff --git a/src/org/sosy_lab/java_smt/delegate/statistics/StatisticsBasicProverEnvironment.java b/src/org/sosy_lab/java_smt/delegate/statistics/StatisticsBasicProverEnvironment.java index 84a5109b0d..47ef8bef5e 100644 --- a/src/org/sosy_lab/java_smt/delegate/statistics/StatisticsBasicProverEnvironment.java +++ b/src/org/sosy_lab/java_smt/delegate/statistics/StatisticsBasicProverEnvironment.java @@ -10,6 +10,7 @@ import static com.google.common.base.Preconditions.checkNotNull; +import com.google.common.collect.ImmutableList; import java.util.Collection; import java.util.List; import java.util.Optional; @@ -18,6 +19,7 @@ import org.sosy_lab.java_smt.api.BasicProverEnvironment; import org.sosy_lab.java_smt.api.BooleanFormula; import org.sosy_lab.java_smt.api.Model; +import org.sosy_lab.java_smt.api.Model.ValueAssignment; import org.sosy_lab.java_smt.api.SolverException; import org.sosy_lab.java_smt.delegate.statistics.TimerPool.TimerWrapper; @@ -92,6 +94,11 @@ public Model getModel() throws SolverException { return new StatisticsModel(delegate.getModel(), stats); } + @Override + public ImmutableList getModelAssignments() throws SolverException { + return delegate.getModelAssignments(); + } + @Override public List getUnsatCore() { stats.unsatCore.getAndIncrement(); diff --git a/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedBasicProverEnvironment.java b/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedBasicProverEnvironment.java index 17497f0540..92c4496007 100644 --- a/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedBasicProverEnvironment.java +++ b/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedBasicProverEnvironment.java @@ -10,6 +10,7 @@ import static com.google.common.base.Preconditions.checkNotNull; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import java.util.Collection; import java.util.List; @@ -19,6 +20,7 @@ import org.sosy_lab.java_smt.api.BasicProverEnvironment; import org.sosy_lab.java_smt.api.BooleanFormula; import org.sosy_lab.java_smt.api.Model; +import org.sosy_lab.java_smt.api.Model.ValueAssignment; import org.sosy_lab.java_smt.api.SolverContext; import org.sosy_lab.java_smt.api.SolverException; @@ -88,6 +90,11 @@ public Model getModel() throws SolverException { } } + @Override + public ImmutableList getModelAssignments() throws SolverException { + return delegate.getModelAssignments(); + } + @Override public List getUnsatCore() { synchronized (sync) { diff --git a/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedBasicProverEnvironmentWithContext.java b/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedBasicProverEnvironmentWithContext.java index 9b7fda176b..89bb05042a 100644 --- a/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedBasicProverEnvironmentWithContext.java +++ b/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedBasicProverEnvironmentWithContext.java @@ -21,6 +21,7 @@ import org.sosy_lab.java_smt.api.BooleanFormula; import org.sosy_lab.java_smt.api.FormulaManager; import org.sosy_lab.java_smt.api.Model; +import org.sosy_lab.java_smt.api.Model.ValueAssignment; import org.sosy_lab.java_smt.api.SolverContext; import org.sosy_lab.java_smt.api.SolverException; @@ -98,6 +99,11 @@ public Model getModel() throws SolverException { } } + @Override + public ImmutableList getModelAssignments() throws SolverException { + return delegate.getModelAssignments(); + } + @Override public List getUnsatCore() { return translate(delegate.getUnsatCore(), otherManager, manager); diff --git a/src/org/sosy_lab/java_smt/solvers/bitwuzla/BitwuzlaTheoremProver.java b/src/org/sosy_lab/java_smt/solvers/bitwuzla/BitwuzlaTheoremProver.java index 6e555476a8..ff97a08e6b 100644 --- a/src/org/sosy_lab/java_smt/solvers/bitwuzla/BitwuzlaTheoremProver.java +++ b/src/org/sosy_lab/java_smt/solvers/bitwuzla/BitwuzlaTheoremProver.java @@ -48,7 +48,6 @@ public boolean terminate() { private final BitwuzlaFormulaManager manager; private final BitwuzlaFormulaCreator creator; - protected boolean wasLastSatCheckSat = false; // and stack is not changed protected BitwuzlaTheoremProver( BitwuzlaFormulaManager pManager, @@ -143,11 +142,8 @@ protected boolean isUnsatImpl() throws SolverException, InterruptedException { * @param assumptions A list of literals. */ @Override - public boolean isUnsatWithAssumptions(Collection assumptions) + protected boolean isUnsatWithAssumptionsImpl(Collection assumptions) throws SolverException, InterruptedException { - Preconditions.checkState(!closed); - wasLastSatCheckSat = false; - Collection newAssumptions = new LinkedHashSet<>(); for (BooleanFormula formula : assumptions) { Term term = creator.extractInfo(formula); @@ -170,8 +166,7 @@ public boolean isUnsatWithAssumptions(Collection assumptions) */ @SuppressWarnings("resource") @Override - public Model getModel() throws SolverException { - Preconditions.checkState(!closed); + protected Model getModelImpl() throws SolverException { Preconditions.checkState(wasLastSatCheckSat, NO_MODEL_HELP); checkGenerateModels(); return new CachingModel( @@ -196,9 +191,7 @@ private List getUnsatCore0() { * returned false. */ @Override - public List getUnsatCore() { - Preconditions.checkState(!closed); - checkGenerateUnsatCores(); + protected List getUnsatCoreImpl() { Preconditions.checkState(!wasLastSatCheckSat); return getUnsatCore0(); } @@ -212,12 +205,8 @@ public List getUnsatCore() { * assumptions which is unsatisfiable with the original constraints otherwise. */ @Override - public Optional> unsatCoreOverAssumptions( + protected Optional> unsatCoreOverAssumptionsImpl( Collection assumptions) throws SolverException, InterruptedException { - Preconditions.checkNotNull(assumptions); - Preconditions.checkState(!closed); - checkGenerateUnsatCores(); // FIXME: JavaDoc say ProverOptions.GENERATE_UNSAT_CORE is not needed - Preconditions.checkState(!wasLastSatCheckSat); boolean sat = !isUnsatWithAssumptions(assumptions); return sat ? Optional.empty() : Optional.of(getUnsatCore0()); } diff --git a/src/org/sosy_lab/java_smt/solvers/boolector/BoolectorAbstractProver.java b/src/org/sosy_lab/java_smt/solvers/boolector/BoolectorAbstractProver.java index 864bc3b85b..c5e6c8f7da 100644 --- a/src/org/sosy_lab/java_smt/solvers/boolector/BoolectorAbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/boolector/BoolectorAbstractProver.java @@ -33,7 +33,6 @@ abstract class BoolectorAbstractProver extends AbstractProverWithAllSat { private final long btor; private final BoolectorFormulaManager manager; private final BoolectorFormulaCreator creator; - protected boolean wasLastSatCheckSat = false; // and stack is not changed private final TerminationCallback terminationCallback; private final long terminationCallbackHelper; @@ -114,7 +113,7 @@ protected void pushImpl() throws InterruptedException { } @Override - public boolean isUnsatWithAssumptions(Collection pAssumptions) + protected boolean isUnsatWithAssumptionsImpl(Collection pAssumptions) throws SolverException, InterruptedException { Preconditions.checkState(!closed); for (BooleanFormula assumption : pAssumptions) { @@ -125,8 +124,7 @@ public boolean isUnsatWithAssumptions(Collection pAssumptions) @SuppressWarnings("resource") @Override - public Model getModel() throws SolverException { - Preconditions.checkState(!closed); + protected Model getModelImpl() throws SolverException { Preconditions.checkState(wasLastSatCheckSat, NO_MODEL_HELP); checkGenerateModels(); return new CachingModel(getEvaluatorWithoutChecks()); @@ -139,13 +137,13 @@ protected BoolectorModel getEvaluatorWithoutChecks() { } @Override - public List getUnsatCore() { + protected List getUnsatCoreImpl() { throw new UnsupportedOperationException("Unsat core is not supported by Boolector."); } @Override - public Optional> unsatCoreOverAssumptions( - Collection pAssumptions) throws SolverException, InterruptedException { + protected Optional> unsatCoreOverAssumptionsImpl( + Collection pAssumptions) { throw new UnsupportedOperationException( "Unsat core with assumptions is not supported by Boolector."); } diff --git a/src/org/sosy_lab/java_smt/solvers/cvc4/CVC4TheoremProver.java b/src/org/sosy_lab/java_smt/solvers/cvc4/CVC4TheoremProver.java index 14e1ec79cd..14e6023e3a 100644 --- a/src/org/sosy_lab/java_smt/solvers/cvc4/CVC4TheoremProver.java +++ b/src/org/sosy_lab/java_smt/solvers/cvc4/CVC4TheoremProver.java @@ -10,7 +10,6 @@ import com.google.common.base.Preconditions; import com.google.common.collect.Collections2; -import com.google.common.collect.ImmutableList; import edu.stanford.CVC4.Exception; import edu.stanford.CVC4.Expr; import edu.stanford.CVC4.ExprManager; @@ -30,7 +29,6 @@ import org.sosy_lab.java_smt.api.BooleanFormula; import org.sosy_lab.java_smt.api.BooleanFormulaManager; import org.sosy_lab.java_smt.api.Evaluator; -import org.sosy_lab.java_smt.api.Model.ValueAssignment; import org.sosy_lab.java_smt.api.ProverEnvironment; import org.sosy_lab.java_smt.api.SolverContext.ProverOptions; import org.sosy_lab.java_smt.api.SolverException; @@ -42,7 +40,6 @@ class CVC4TheoremProver extends AbstractProverWithAllSat private final CVC4FormulaCreator creator; SmtEngine smtEngine; // final except for SL theory - private boolean changedSinceLastSatQuery = false; /** * The local exprManager allows to set options per Prover (and not globally). See getModelAssignments() throws SolverException { - Preconditions.checkState(!closed); - Preconditions.checkState(!changedSinceLastSatQuery); - return super.getModelAssignments(); - } - @Override @SuppressWarnings("try") protected boolean isUnsatImpl() throws InterruptedException, SolverException { - changedSinceLastSatQuery = false; if (!incremental) { for (BooleanFormula f : getAssertedFormulas()) { assertFormula(f); @@ -227,10 +199,9 @@ private boolean convertSatResult(Result result) throws InterruptedException, Sol } @Override - public List getUnsatCore() { - Preconditions.checkState(!closed); - checkGenerateUnsatCores(); - Preconditions.checkState(!changedSinceLastSatQuery); + protected List getUnsatCoreImpl() { + Preconditions.checkState(!wasLastSatCheckSat); + Preconditions.checkState(!stackChangedSinceLastQuery); List converted = new ArrayList<>(); for (Expr aCore : smtEngine.getUnsatCore()) { converted.add(creator.encapsulateBoolean(exportExpr(aCore))); @@ -239,13 +210,13 @@ public List getUnsatCore() { } @Override - public boolean isUnsatWithAssumptions(Collection pAssumptions) + protected boolean isUnsatWithAssumptionsImpl(Collection pAssumptions) throws SolverException, InterruptedException { throw new UnsupportedOperationException(); } @Override - public Optional> unsatCoreOverAssumptions( + protected Optional> unsatCoreOverAssumptionsImpl( Collection pAssumptions) throws SolverException, InterruptedException { throw new UnsupportedOperationException(); } diff --git a/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5AbstractProver.java b/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5AbstractProver.java index a46a4b9fa3..bb6cfd938d 100644 --- a/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5AbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5AbstractProver.java @@ -10,7 +10,6 @@ import com.google.common.base.Preconditions; import com.google.common.collect.Collections2; -import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.errorprone.annotations.CanIgnoreReturnValue; import io.github.cvc5.CVC5ApiException; @@ -34,7 +33,6 @@ import org.sosy_lab.java_smt.api.BooleanFormula; import org.sosy_lab.java_smt.api.Evaluator; import org.sosy_lab.java_smt.api.FormulaManager; -import org.sosy_lab.java_smt.api.Model.ValueAssignment; import org.sosy_lab.java_smt.api.SolverContext.ProverOptions; import org.sosy_lab.java_smt.api.SolverException; import org.sosy_lab.java_smt.basicimpl.AbstractProverWithAllSat; @@ -46,7 +44,6 @@ abstract class CVC5AbstractProver extends AbstractProverWithAllSat { private final FormulaManager mgr; protected final CVC5FormulaCreator creator; protected final Solver solver; - private boolean changedSinceLastSatQuery = false; protected final Deque> assertedTerms = new ArrayDeque<>(); // TODO: does CVC5 support separation logic in incremental mode? @@ -109,7 +106,6 @@ protected void setSolverOptions( @Override protected void pushImpl() throws InterruptedException { - setChanged(); assertedTerms.push(assertedTerms.peek()); // add copy of top-level if (incremental) { try { @@ -123,7 +119,6 @@ protected void pushImpl() throws InterruptedException { @Override protected void popImpl() { - setChanged(); if (incremental) { try { solver.pop(); @@ -138,7 +133,6 @@ protected void popImpl() { @CanIgnoreReturnValue protected String addConstraint0(BooleanFormula pF) { Preconditions.checkState(!closed); - setChanged(); Term exp = creator.extractInfo(pF); if (incremental) { solver.assertFormula(exp); @@ -150,10 +144,7 @@ protected String addConstraint0(BooleanFormula pF) { @SuppressWarnings("resource") @Override - public CVC5Model getModel() throws SolverException { - Preconditions.checkState(!closed); - Preconditions.checkState(!changedSinceLastSatQuery); - checkGenerateModels(); + protected CVC5Model getModelImpl() throws SolverException { // special case for CVC5: Models are not permanent and need to be closed // before any change is applied to the prover stack. So, we register the Model as Evaluator. return registerEvaluator( @@ -177,24 +168,9 @@ protected Evaluator getEvaluatorWithoutChecks() { return registerEvaluator(new CVC5Evaluator(this, creator)); } - protected void setChanged() { - if (!changedSinceLastSatQuery) { - changedSinceLastSatQuery = true; - closeAllEvaluators(); - } - } - - @Override - public ImmutableList getModelAssignments() throws SolverException { - Preconditions.checkState(!closed); - Preconditions.checkState(!changedSinceLastSatQuery); - return super.getModelAssignments(); - } - @Override @SuppressWarnings("try") public boolean isUnsatImpl() throws InterruptedException, SolverException { - changedSinceLastSatQuery = false; if (!incremental) { getAssertedFormulas().forEach(f -> solver.assertFormula(creator.extractInfo(f))); } @@ -218,10 +194,9 @@ private boolean convertSatResult(Result result) throws InterruptedException, Sol } @Override - public List getUnsatCore() { - Preconditions.checkState(!closed); - checkGenerateUnsatCores(); - Preconditions.checkState(!changedSinceLastSatQuery); + protected List getUnsatCoreImpl() { + Preconditions.checkState(!stackChangedSinceLastQuery); + Preconditions.checkState(!wasLastSatCheckSat); List converted = new ArrayList<>(); for (Term aCore : solver.getUnsatCore()) { converted.add(creator.encapsulateBoolean(aCore)); @@ -230,14 +205,14 @@ public List getUnsatCore() { } @Override - public boolean isUnsatWithAssumptions(Collection pAssumptions) + protected boolean isUnsatWithAssumptionsImpl(Collection pAssumptions) throws SolverException, InterruptedException { throw new UnsupportedOperationException(); } @Override - public Optional> unsatCoreOverAssumptions( - Collection pAssumptions) throws SolverException, InterruptedException { + protected Optional> unsatCoreOverAssumptionsImpl( + Collection pAssumptions) { throw new UnsupportedOperationException(); } diff --git a/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5AbstractProver.java b/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5AbstractProver.java index 411bf0b157..b6cc980498 100644 --- a/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5AbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5AbstractProver.java @@ -119,7 +119,7 @@ private TerminationCallback getTerminationTest() { } @Override - public boolean isUnsatWithAssumptions(Collection pAssumptions) + protected boolean isUnsatWithAssumptionsImpl(Collection pAssumptions) throws SolverException, InterruptedException { Preconditions.checkState(!closed); checkForLiterals(pAssumptions); @@ -148,8 +148,7 @@ && msat_term_is_boolean_constant(curEnv, msat_term_get_arg(t, 0))) { @SuppressWarnings("resource") @Override - public Model getModel() throws SolverException { - Preconditions.checkState(!closed); + protected Model getModelImpl() throws SolverException { checkGenerateModels(); return new CachingModel(new Mathsat5Model(getMsatModel(), creator, this)); } @@ -193,15 +192,13 @@ public int size() { } @Override - public List getUnsatCore() { - Preconditions.checkState(!closed); - checkGenerateUnsatCores(); + protected List getUnsatCoreImpl() { long[] terms = msat_get_unsat_core(curEnv); return encapsulate(terms); } @Override - public Optional> unsatCoreOverAssumptions( + protected Optional> unsatCoreOverAssumptionsImpl( Collection assumptions) throws SolverException, InterruptedException { Preconditions.checkNotNull(assumptions); closeAllEvaluators(); diff --git a/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5OptimizationProver.java b/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5OptimizationProver.java index dc7fc69436..ce375fc3ea 100644 --- a/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5OptimizationProver.java +++ b/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5OptimizationProver.java @@ -98,8 +98,11 @@ public int minimize(Formula objective) { @Override public OptStatus check() throws InterruptedException, SolverException { checkState(!closed); + wasLastSatCheckSat = false; final boolean isSatisfiable = msat_check_sat(curEnv); + stackChangedSinceLastQuery = false; if (isSatisfiable) { + wasLastSatCheckSat = true; return OptStatus.OPT; } else { return OptStatus.UNSAT; @@ -145,11 +148,11 @@ private Optional getValue(int handle, Rational epsilon) { } @Override - public Model getModel() throws SolverException { + protected Model getModelImpl() throws SolverException { checkState(!closed); if (!objectiveMap.isEmpty()) { msat_load_objective_model(curEnv, objectiveMap.values().iterator().next()); } - return super.getModel(); + return super.getModelImpl(); } } diff --git a/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtAbstractProver.java b/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtAbstractProver.java index 8adf86c177..683f38e88b 100644 --- a/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtAbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtAbstractProver.java @@ -10,7 +10,6 @@ import com.google.common.base.Preconditions; import com.google.common.collect.Collections2; -import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import java.util.ArrayList; import java.util.Collection; @@ -26,7 +25,6 @@ import org.sosy_lab.java_smt.api.Evaluator; import org.sosy_lab.java_smt.api.FormulaManager; import org.sosy_lab.java_smt.api.Model; -import org.sosy_lab.java_smt.api.Model.ValueAssignment; import org.sosy_lab.java_smt.api.SolverContext.ProverOptions; import org.sosy_lab.java_smt.api.SolverException; import org.sosy_lab.java_smt.basicimpl.AbstractProverWithAllSat; @@ -48,8 +46,6 @@ public abstract class OpenSmtAbstractProver extends AbstractProverWithAllSat< protected final MainSolver osmtSolver; protected final SMTConfig osmtConfig; - private boolean changedSinceLastSatQuery = false; - protected OpenSmtAbstractProver( OpenSmtFormulaCreator pFormulaCreator, FormulaManager pMgr, @@ -93,13 +89,11 @@ final MainSolver getOsmtSolver() { @Override protected void pushImpl() { - setChanged(); osmtSolver.push(); } @Override protected void popImpl() { - setChanged(); osmtSolver.pop(); } @@ -109,17 +103,13 @@ protected void popImpl() { @Override @Nullable protected T addConstraintImpl(BooleanFormula pF) throws InterruptedException { - setChanged(); PTRef f = creator.extractInfo(pF); return addConstraintImpl(f); } @SuppressWarnings("resource") @Override - public Model getModel() { - Preconditions.checkState(!closed); - checkGenerateModels(); - + protected Model getModelImpl() { Model model = new OpenSmtModel( this, creator, Collections2.transform(getAssertedFormulas(), creator::extractInfo)); @@ -139,20 +129,6 @@ protected Evaluator getEvaluatorWithoutChecks() { return registerEvaluator(new OpenSmtEvaluator(this, creator)); } - protected void setChanged() { - if (!changedSinceLastSatQuery) { - changedSinceLastSatQuery = true; - closeAllEvaluators(); - } - } - - @Override - public ImmutableList getModelAssignments() throws SolverException { - Preconditions.checkState(!closed); - Preconditions.checkState(!changedSinceLastSatQuery); - return super.getModelAssignments(); - } - /** * Make sure that the assertions only use features supported by the selected logic. Otherwise, * OpenSMT will fail on checking satisfiability without further information, if the selected logic @@ -226,7 +202,6 @@ protected String getReasonFromSolverFeatures( @Override @SuppressWarnings("try") // ShutdownHook is never referenced, and this is correct. protected boolean isUnsatImpl() throws InterruptedException, SolverException { - changedSinceLastSatQuery = false; sstat result; try (ShutdownHook listener = new ShutdownHook(proverShutdownNotifier, osmtSolver::stop)) { @@ -262,22 +237,21 @@ protected boolean isUnsatImpl() throws InterruptedException, SolverException { } @Override - public List getUnsatCore() { - Preconditions.checkState(!closed); - checkGenerateUnsatCores(); - Preconditions.checkState(!changedSinceLastSatQuery); + protected List getUnsatCoreImpl() { + Preconditions.checkState(!wasLastSatCheckSat); + Preconditions.checkState(!stackChangedSinceLastQuery); return Lists.transform(osmtSolver.getUnsatCore(), creator::encapsulateBoolean); } @Override - public boolean isUnsatWithAssumptions(Collection pAssumptions) + protected boolean isUnsatWithAssumptionsImpl(Collection pAssumptions) throws SolverException, InterruptedException { throw new UnsupportedOperationException("OpenSMT does not support solving with assumptions."); } @Override - public Optional> unsatCoreOverAssumptions( - Collection pAssumptions) throws SolverException, InterruptedException { + protected Optional> unsatCoreOverAssumptionsImpl( + Collection pAssumptions) { throw new UnsupportedOperationException("OpenSMT does not support solving with assumptions."); } diff --git a/src/org/sosy_lab/java_smt/solvers/princess/PrincessAbstractProver.java b/src/org/sosy_lab/java_smt/solvers/princess/PrincessAbstractProver.java index 6513c09ad3..ffdb6353aa 100644 --- a/src/org/sosy_lab/java_smt/solvers/princess/PrincessAbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/princess/PrincessAbstractProver.java @@ -63,7 +63,6 @@ abstract class PrincessAbstractProver extends AbstractProverWithAllSat { protected final Deque> partitions = new ArrayDeque<>(); private final PrincessFormulaCreator creator; - protected boolean wasLastSatCheckSat = false; // and stack is not changed protected PrincessAbstractProver( PrincessFormulaManager pMgr, @@ -158,10 +157,8 @@ void addEvaluatedTerm(IFormula pFormula) { @SuppressWarnings("resource") @Override - public Model getModel() throws SolverException { - Preconditions.checkState(!closed); + protected Model getModelImpl() throws SolverException { Preconditions.checkState(wasLastSatCheckSat, NO_MODEL_HELP); - checkGenerateModels(); return new CachingModel(getEvaluatorWithoutChecks()); } @@ -187,15 +184,13 @@ private PartialModel partialModel() throws SimpleAPIException { } @Override - public boolean isUnsatWithAssumptions(Collection pAssumptions) + protected boolean isUnsatWithAssumptionsImpl(Collection pAssumptions) throws SolverException, InterruptedException { throw new UnsupportedOperationException("Solving with assumptions is not supported."); } @Override - public List getUnsatCore() { - Preconditions.checkState(!closed); - checkGenerateUnsatCores(); + protected List getUnsatCoreImpl() { final List result = new ArrayList<>(); final Set core = asJava(api.getUnsatCore()); for (Object partitionId : core) { @@ -205,7 +200,7 @@ public List getUnsatCore() { } @Override - public Optional> unsatCoreOverAssumptions( + protected Optional> unsatCoreOverAssumptionsImpl( Collection assumptions) { throw new UnsupportedOperationException( "UNSAT cores over assumptions not supported by Princess"); diff --git a/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolAbstractProver.java b/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolAbstractProver.java index ba8658d9a3..616aee3eb7 100644 --- a/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolAbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolAbstractProver.java @@ -140,9 +140,7 @@ protected boolean isUnsatImpl() throws InterruptedException { @SuppressWarnings("resource") @Override - public org.sosy_lab.java_smt.api.Model getModel() { - checkState(!closed); - checkGenerateModels(); + protected org.sosy_lab.java_smt.api.Model getModelImpl() { final Model model; try { model = env.getModel(); @@ -167,9 +165,7 @@ protected static String generateTermName() { } @Override - public List getUnsatCore() { - checkState(!closed); - checkGenerateUnsatCores(); + protected List getUnsatCoreImpl() { return getUnsatCore0(annotatedTerms.peek()); } @@ -190,10 +186,8 @@ private List getUnsatCore0(Map annotated } @Override - public Optional> unsatCoreOverAssumptions( + protected Optional> unsatCoreOverAssumptionsImpl( Collection assumptions) throws InterruptedException, SolverException { - checkState(!closed); - checkGenerateUnsatCoresOverAssumptions(); Map annotatedConstraints = new LinkedHashMap<>(); push(); for (BooleanFormula assumption : assumptions) { @@ -224,7 +218,7 @@ public void close() { } @Override - public boolean isUnsatWithAssumptions(Collection pAssumptions) + protected boolean isUnsatWithAssumptionsImpl(Collection pAssumptions) throws SolverException, InterruptedException { throw new UnsupportedOperationException("Assumption-solving is not supported."); } diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2TheoremProver.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2TheoremProver.java index c3cdfb3756..773279396e 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2TheoremProver.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2TheoremProver.java @@ -147,7 +147,7 @@ private int[] getAllConstraints() { } @Override - public boolean isUnsatWithAssumptions(Collection pAssumptions) + protected boolean isUnsatWithAssumptionsImpl(Collection pAssumptions) throws SolverException, InterruptedException { Preconditions.checkState(!closed); // TODO handle BooleanFormulaCollection / check for literals @@ -161,9 +161,7 @@ public boolean isUnsatWithAssumptions(Collection pAssumptions) @SuppressWarnings("resource") @Override - public Model getModel() throws SolverException { - Preconditions.checkState(!closed); - checkGenerateModels(); + protected Model getModelImpl() throws SolverException { return new CachingModel(getEvaluatorWithoutChecks()); } @@ -190,9 +188,7 @@ private int[] uncapsulate(Collection terms) { } @Override - public List getUnsatCore() { - Preconditions.checkState(!closed); - checkGenerateUnsatCores(); + protected List getUnsatCoreImpl() { return getUnsatCore0(); } @@ -201,10 +197,8 @@ private List getUnsatCore0() { } @Override - public Optional> unsatCoreOverAssumptions( + protected Optional> unsatCoreOverAssumptionsImpl( Collection pAssumptions) throws SolverException, InterruptedException { - Preconditions.checkState(!isClosed()); - checkGenerateUnsatCoresOverAssumptions(); boolean sat = !isUnsatWithAssumptions(pAssumptions); return sat ? Optional.empty() : Optional.of(getUnsatCore0()); } diff --git a/src/org/sosy_lab/java_smt/solvers/z3/Z3AbstractProver.java b/src/org/sosy_lab/java_smt/solvers/z3/Z3AbstractProver.java index 678dcd9438..963da37f8c 100644 --- a/src/org/sosy_lab/java_smt/solvers/z3/Z3AbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/z3/Z3AbstractProver.java @@ -105,8 +105,7 @@ protected void logSolverStack() throws SolverException { @SuppressWarnings("resource") @Override - public Model getModel() throws SolverException { - Preconditions.checkState(!closed); + protected Model getModelImpl() throws SolverException { checkGenerateModels(); return new CachingModel(getEvaluatorWithoutChecks()); } @@ -158,9 +157,7 @@ protected void pop0() { protected abstract long getUnsatCore0(); @Override - public List getUnsatCore() { - Preconditions.checkState(!closed); - checkGenerateUnsatCores(); + protected List getUnsatCoreImpl() { if (storedConstraints == null) { throw new UnsupportedOperationException( "Option to generate the UNSAT core wasn't enabled when creating the prover environment."); @@ -181,9 +178,8 @@ public List getUnsatCore() { } @Override - public Optional> unsatCoreOverAssumptions( + protected Optional> unsatCoreOverAssumptionsImpl( Collection assumptions) throws SolverException, InterruptedException { - checkGenerateUnsatCoresOverAssumptions(); if (!isUnsatWithAssumptions(assumptions)) { return Optional.empty(); } diff --git a/src/org/sosy_lab/java_smt/solvers/z3/Z3OptimizationProver.java b/src/org/sosy_lab/java_smt/solvers/z3/Z3OptimizationProver.java index 924fbd4d86..d84ba3b087 100644 --- a/src/org/sosy_lab/java_smt/solvers/z3/Z3OptimizationProver.java +++ b/src/org/sosy_lab/java_smt/solvers/z3/Z3OptimizationProver.java @@ -75,6 +75,7 @@ public int minimize(Formula objective) { public OptStatus check() throws InterruptedException, SolverException { Preconditions.checkState(!closed); int status; + wasLastSatCheckSat = false; try { status = Native.optimizeCheck( @@ -83,6 +84,7 @@ public OptStatus check() throws InterruptedException, SolverException { 0, // number of assumptions null // assumptions ); + stackChangedSinceLastQuery = false; } catch (Z3Exception ex) { throw creator.handleZ3Exception(ex); } @@ -96,6 +98,7 @@ public OptStatus check() throws InterruptedException, SolverException { Native.optimizeGetReasonUnknown(z3context, z3optSolver)); return OptStatus.UNDEF; } else { + wasLastSatCheckSat = true; return OptStatus.OPT; } } @@ -139,8 +142,7 @@ protected boolean isUnsatImpl() throws SolverException, InterruptedException { } @Override - public boolean isUnsatWithAssumptions(Collection assumptions) - throws SolverException, InterruptedException { + protected boolean isUnsatWithAssumptionsImpl(Collection assumptions) { return false; } diff --git a/src/org/sosy_lab/java_smt/solvers/z3/Z3TheoremProver.java b/src/org/sosy_lab/java_smt/solvers/z3/Z3TheoremProver.java index 96bc5171fa..68132114ec 100644 --- a/src/org/sosy_lab/java_smt/solvers/z3/Z3TheoremProver.java +++ b/src/org/sosy_lab/java_smt/solvers/z3/Z3TheoremProver.java @@ -97,10 +97,8 @@ protected boolean isUnsatImpl() throws SolverException, InterruptedException { } @Override - public boolean isUnsatWithAssumptions(Collection assumptions) + protected boolean isUnsatWithAssumptionsImpl(Collection assumptions) throws SolverException, InterruptedException { - Preconditions.checkState(!closed); - int result; try { result = From 1b6f52b71d673b867b9ada2fd1976b2672ca7faa Mon Sep 17 00:00:00 2001 From: BaierD Date: Mon, 2 Jun 2025 16:47:53 +0200 Subject: [PATCH 13/87] Remove unnecessary final modifiers in AbstractProver --- src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java index c7fa72d2a2..78b99d18b4 100644 --- a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java +++ b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java @@ -80,11 +80,11 @@ protected final void checkGenerateAllSat() { Preconditions.checkState(generateAllSat, TEMPLATE, ProverOptions.GENERATE_ALL_SAT); } - private final void checkGenerateUnsatCores() { + private void checkGenerateUnsatCores() { Preconditions.checkState(generateUnsatCores, TEMPLATE, ProverOptions.GENERATE_UNSAT_CORE); } - private final void checkGenerateUnsatCoresOverAssumptions() { + private void checkGenerateUnsatCoresOverAssumptions() { Preconditions.checkState( generateUnsatCoresOverAssumptions, TEMPLATE, From 77ab3d65e7eca7795f25ca9f757077792d703d3f Mon Sep 17 00:00:00 2001 From: BaierD Date: Mon, 2 Jun 2025 16:50:35 +0200 Subject: [PATCH 14/87] Add more uniform handling of prerequisites of interpolation API --- .../solvers/cvc5/CVC5InterpolatingProver.java | 7 +++++++ .../mathsat5/Mathsat5InterpolatingProver.java | 16 +++++++++++++--- .../opensmt/OpenSmtInterpolatingProver.java | 6 +++++- .../SmtInterpolInterpolatingProver.java | 11 +++++++++-- 4 files changed, 34 insertions(+), 6 deletions(-) diff --git a/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5InterpolatingProver.java b/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5InterpolatingProver.java index 2f99bca077..3db0461ab3 100644 --- a/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5InterpolatingProver.java +++ b/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5InterpolatingProver.java @@ -84,6 +84,9 @@ protected String addConstraintImpl(BooleanFormula constraint) throws Interrupted public BooleanFormula getInterpolant(Collection pFormulasOfA) throws SolverException, InterruptedException { checkState(!closed); + proverShutdownNotifier.shutdownIfNecessary(); + checkState(!wasLastSatCheckSat); + checkState(!stackChangedSinceLastQuery); checkArgument( getAssertedConstraintIds().containsAll(pFormulasOfA), "interpolation can only be done over previously asserted formulas."); @@ -101,6 +104,10 @@ public BooleanFormula getInterpolant(Collection pFormulasOfA) @Override public List getSeqInterpolants(List> partitions) throws SolverException, InterruptedException { + checkState(!closed); + proverShutdownNotifier.shutdownIfNecessary(); + checkState(!wasLastSatCheckSat); + checkState(!stackChangedSinceLastQuery); checkArgument(!partitions.isEmpty(), "at least one partition should be available."); final ImmutableSet assertedConstraintIds = getAssertedConstraintIds(); checkArgument( diff --git a/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5InterpolatingProver.java b/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5InterpolatingProver.java index ea1fd42e2e..dcca8e5d67 100644 --- a/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5InterpolatingProver.java +++ b/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5InterpolatingProver.java @@ -9,6 +9,7 @@ package org.sosy_lab.java_smt.solvers.mathsat5; import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkState; import static org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.msat_assert_formula; import static org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.msat_create_itp_group; import static org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.msat_get_interpolant; @@ -99,8 +100,12 @@ protected long getMsatModel() throws SolverException { } @Override - public BooleanFormula getInterpolant(Collection formulasOfA) throws SolverException { - Preconditions.checkState(!closed); + public BooleanFormula getInterpolant(Collection formulasOfA) + throws SolverException, InterruptedException { + checkState(!closed); + proverShutdownNotifier.shutdownIfNecessary(); + checkState(!wasLastSatCheckSat); + checkState(!stackChangedSinceLastQuery); checkArgument( getAssertedConstraintIds().containsAll(formulasOfA), "interpolation can only be done over previously asserted formulas."); @@ -125,7 +130,12 @@ public BooleanFormula getInterpolant(Collection formulasOfA) throws Sol @Override public List getSeqInterpolants( - List> partitionedFormulas) throws SolverException { + List> partitionedFormulas) + throws SolverException, InterruptedException { + checkState(!closed); + proverShutdownNotifier.shutdownIfNecessary(); + checkState(!wasLastSatCheckSat); + checkState(!stackChangedSinceLastQuery); Preconditions.checkArgument( !partitionedFormulas.isEmpty(), "at least one partition should be available."); final ImmutableSet assertedConstraintIds = getAssertedConstraintIds(); diff --git a/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtInterpolatingProver.java b/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtInterpolatingProver.java index 5fd6a8f71e..589a375e18 100644 --- a/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtInterpolatingProver.java +++ b/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtInterpolatingProver.java @@ -73,8 +73,12 @@ protected void popImpl() { } @Override - public BooleanFormula getInterpolant(Collection formulasOfA) { + public BooleanFormula getInterpolant(Collection formulasOfA) + throws InterruptedException { checkState(!closed); + proverShutdownNotifier.shutdownIfNecessary(); + checkState(!wasLastSatCheckSat); + checkState(!stackChangedSinceLastQuery); checkArgument( getAssertedConstraintIds().containsAll(formulasOfA), "interpolation can only be done over previously asserted formulas."); diff --git a/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolInterpolatingProver.java b/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolInterpolatingProver.java index 8507444c22..843b0c0f90 100644 --- a/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolInterpolatingProver.java +++ b/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolInterpolatingProver.java @@ -9,6 +9,7 @@ package org.sosy_lab.java_smt.solvers.smtinterpol; import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkState; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; @@ -47,7 +48,10 @@ protected String addConstraintImpl(BooleanFormula constraint) throws Interrupted @Override public BooleanFormula getInterpolant(Collection pTermNamesOfA) throws SolverException, InterruptedException { - Preconditions.checkState(!closed); + checkState(!closed); + proverShutdownNotifier.shutdownIfNecessary(); + checkState(!wasLastSatCheckSat); + checkState(!stackChangedSinceLastQuery); checkArgument( getAssertedConstraintIds().containsAll(pTermNamesOfA), "interpolation can only be done over previously asserted formulas."); @@ -74,7 +78,10 @@ public BooleanFormula getInterpolant(Collection pTermNamesOfA) public List getTreeInterpolants( List> partitionedTermNames, int[] startOfSubTree) throws SolverException, InterruptedException { - Preconditions.checkState(!closed); + checkState(!closed); + proverShutdownNotifier.shutdownIfNecessary(); + checkState(!wasLastSatCheckSat); + checkState(!stackChangedSinceLastQuery); final ImmutableSet assertedConstraintIds = getAssertedConstraintIds(); checkArgument( partitionedTermNames.stream().allMatch(assertedConstraintIds::containsAll), From 223624c071d99fd48d68af857f1421e65f7f7265 Mon Sep 17 00:00:00 2001 From: BaierD Date: Mon, 2 Jun 2025 17:15:20 +0200 Subject: [PATCH 15/87] Add clarification JavaDoc for getShutdownManagerForProver() --- src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java b/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java index 073ee38735..56b9b0e963 100644 --- a/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java +++ b/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java @@ -211,7 +211,7 @@ default boolean registerUserPropagator(UserPropagator propagator) { * guaranteed to be a child of the {@link ShutdownNotifier} given to the creating {@link * SolverContext}, resulting in shutdown when the {@link SolverContext}s notifier is shutting * down. The notifier returned here can be shut down independently of the creating contexts - * notifier. + * notifier. JavaSMT will never attempt to shut down this manager on its own. * * @return a {@link ShutdownManager} who is the child of the {@link ShutdownNotifier} used in the * creating {@link SolverContext}, that can be used to shut down only this {@link From 55f8e08acdda53ae0e53ceba4f0b11a1a793fd26 Mon Sep 17 00:00:00 2001 From: BaierD Date: Mon, 2 Jun 2025 17:16:09 +0200 Subject: [PATCH 16/87] Add clarification JavaDoc about needed options for unsatCoreOverAssumptions() --- src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java b/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java index 56b9b0e963..87c9aed689 100644 --- a/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java +++ b/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java @@ -124,7 +124,8 @@ default Evaluator getEvaluator() throws SolverException { /** * Returns an UNSAT core (if it exists, otherwise {@code Optional.empty()}), over the chosen - * assumptions. Does NOT require the {@link ProverOptions#GENERATE_UNSAT_CORE} option to work. + * assumptions. Does NOT require the {@link ProverOptions#GENERATE_UNSAT_CORE} option to work, + * but {@link ProverOptions#GENERATE_UNSAT_CORE_OVER_ASSUMPTIONS}. * * @param assumptions Selected assumptions * @return Empty optional if the constraints with assumptions are satisfiable, subset of From 6613b2148dc66be1a439fbc5fe63c0629b5ed11b Mon Sep 17 00:00:00 2001 From: BaierD Date: Mon, 2 Jun 2025 20:55:43 +0200 Subject: [PATCH 17/87] Add more internal information about shutdown re-use for Z3 and Bitwuzla --- .../java_smt/solvers/bitwuzla/BitwuzlaTheoremProver.java | 3 +++ src/org/sosy_lab/java_smt/solvers/z3/Z3TheoremProver.java | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/org/sosy_lab/java_smt/solvers/bitwuzla/BitwuzlaTheoremProver.java b/src/org/sosy_lab/java_smt/solvers/bitwuzla/BitwuzlaTheoremProver.java index ff97a08e6b..6ee8c85b8e 100644 --- a/src/org/sosy_lab/java_smt/solvers/bitwuzla/BitwuzlaTheoremProver.java +++ b/src/org/sosy_lab/java_smt/solvers/bitwuzla/BitwuzlaTheoremProver.java @@ -35,6 +35,9 @@ import org.sosy_lab.java_smt.solvers.bitwuzla.api.Vector_Term; class BitwuzlaTheoremProver extends AbstractProverWithAllSat implements ProverEnvironment { + + // Bitwuzlas termination is fully reusable. Even the terminated stack can be re-used. Confirmed + // by Mathias Preiner. private final Terminator terminator = new Terminator() { @Override diff --git a/src/org/sosy_lab/java_smt/solvers/z3/Z3TheoremProver.java b/src/org/sosy_lab/java_smt/solvers/z3/Z3TheoremProver.java index 68132114ec..2abadd214b 100644 --- a/src/org/sosy_lab/java_smt/solvers/z3/Z3TheoremProver.java +++ b/src/org/sosy_lab/java_smt/solvers/z3/Z3TheoremProver.java @@ -29,6 +29,9 @@ class Z3TheoremProver extends Z3AbstractProver implements ProverEnvironment { private final long z3solver; + + // Z3 interruption via solverInterrupt() is re-usable, but might provide partial results if it + // is stopping UnsatCore generation for example. private final ShutdownRequestListener interruptListener; private @Nullable Z3UserPropagator propagator = null; From 843b0eef7ea7678c2411f8ac5cb5669293b7b64b Mon Sep 17 00:00:00 2001 From: BaierD Date: Mon, 2 Jun 2025 20:56:00 +0200 Subject: [PATCH 18/87] Format JavaDoc --- src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java b/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java index 87c9aed689..625a089c25 100644 --- a/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java +++ b/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java @@ -124,8 +124,8 @@ default Evaluator getEvaluator() throws SolverException { /** * Returns an UNSAT core (if it exists, otherwise {@code Optional.empty()}), over the chosen - * assumptions. Does NOT require the {@link ProverOptions#GENERATE_UNSAT_CORE} option to work, - * but {@link ProverOptions#GENERATE_UNSAT_CORE_OVER_ASSUMPTIONS}. + * assumptions. Does NOT require the {@link ProverOptions#GENERATE_UNSAT_CORE} option to work, but + * {@link ProverOptions#GENERATE_UNSAT_CORE_OVER_ASSUMPTIONS}. * * @param assumptions Selected assumptions * @return Empty optional if the constraints with assumptions are satisfiable, subset of From e6587bd5d031135e0c16d2f801e0acd049a376db Mon Sep 17 00:00:00 2001 From: BaierD Date: Wed, 4 Jun 2025 13:39:23 +0200 Subject: [PATCH 19/87] Add API for requesting new prover environments with a dedicated prover shutdown notifier + default implementation --- .../sosy_lab/java_smt/api/SolverContext.java | 70 +++++++++++++++++++ .../basicimpl/AbstractSolverContext.java | 68 ++++++++++++++---- 2 files changed, 125 insertions(+), 13 deletions(-) diff --git a/src/org/sosy_lab/java_smt/api/SolverContext.java b/src/org/sosy_lab/java_smt/api/SolverContext.java index 3fbd476c77..b049023cd7 100644 --- a/src/org/sosy_lab/java_smt/api/SolverContext.java +++ b/src/org/sosy_lab/java_smt/api/SolverContext.java @@ -9,6 +9,7 @@ package org.sosy_lab.java_smt.api; import com.google.common.collect.ImmutableMap; +import org.sosy_lab.common.ShutdownNotifier; import org.sosy_lab.java_smt.SolverContextFactory.Solvers; /** @@ -65,6 +66,28 @@ enum ProverOptions { */ ProverEnvironment newProverEnvironment(ProverOptions... options); + /** + * Create a fresh new {@link ProverEnvironment} which encapsulates an assertion stack and can be + * used to check formulas for unsatisfiability. Allows the shutdown of the prover instance + * returned with the given {@link ShutdownNotifier}, without stopping other provers of the context + * calling this (except for provers also connected via the given {@link ShutdownNotifier}). + * + * @param pProverShutdownNotifier a {@link ShutdownNotifier} that stops the prover returned by + * this method. The prover is not usable anymore after a shutdown has been requested and only + * ever returns {@link InterruptedException}s. The context can be used normally and new + * provers can be created and used. If a {@link ShutdownNotifier} has been given to the + * context that is used to call this method, both notifiers can be used to stop the prover + * returned by this method. Note that once a shutdown-request has been given to the contexts + * {@link ShutdownNotifier}, no prover can ever be used again on that context instance. + * Solvers that don't support isolated prover shutdown throw a {@link + * UnsupportedOperationException} for this method and {@link + * #newProverEnvironment(ProverOptions...)} should be used instead. + * @param options Options specified for the prover environment. All the options specified in + * {@link ProverOptions} are turned off by default. + */ + ProverEnvironment newProverEnvironment( + ShutdownNotifier pProverShutdownNotifier, ProverOptions... options); + /** * Create a fresh new {@link InterpolatingProverEnvironment} which encapsulates an assertion stack * and allows generating and retrieve interpolants for unsatisfiable formulas. If the SMT solver @@ -76,6 +99,31 @@ enum ProverOptions { */ InterpolatingProverEnvironment newProverEnvironmentWithInterpolation(ProverOptions... options); + /** + * Create a fresh new {@link InterpolatingProverEnvironment} which encapsulates an assertion stack + * and allows generating and retrieve interpolants for unsatisfiable formulas. If the SMT solver + * is able to handle satisfiability tests with assumptions please consider implementing the {@link + * InterpolatingProverEnvironment} interface, and return an Object of this type here. Allows the + * shutdown of the prover instance returned with the given {@link ShutdownNotifier}, without + * stopping other provers of the context calling this (except for provers also connected via the + * given {@link ShutdownNotifier}). + * + * @param pProverShutdownNotifier a {@link ShutdownNotifier} that stops the prover returned by + * this method. The prover is not usable anymore after a shutdown has been requested and only + * ever returns {@link InterruptedException}s. The context can be used normally and new + * provers can be created and used. If a {@link ShutdownNotifier} has been given to the + * context that is used to call this method, both notifiers can be used to stop the prover + * returned by this method. Note that once a shutdown-request has been given to the contexts + * {@link ShutdownNotifier}, no prover can ever be used again on that context instance. + * Solvers that don't support isolated prover shutdown throw a {@link + * UnsupportedOperationException} for this method and {@link + * #newProverEnvironment(ProverOptions...)} should be used instead. + * @param options Options specified for the prover environment. All the options specified in + * {@link ProverOptions} are turned off by default. + */ + InterpolatingProverEnvironment newProverEnvironmentWithInterpolation( + ShutdownNotifier pProverShutdownNotifier, ProverOptions... options); + /** * Create a fresh new {@link OptimizationProverEnvironment} which encapsulates an assertion stack * and allows solving optimization queries. @@ -85,6 +133,28 @@ enum ProverOptions { */ OptimizationProverEnvironment newOptimizationProverEnvironment(ProverOptions... options); + /** + * Create a fresh new {@link OptimizationProverEnvironment} which encapsulates an assertion stack + * and allows solving optimization queries. Allows the shutdown of the prover instance returned + * with the given {@link ShutdownNotifier}, without stopping other provers of the context calling + * this (except for provers also connected via the given {@link ShutdownNotifier}). + * + * @param pProverShutdownNotifier a {@link ShutdownNotifier} that stops the prover returned by + * this method. The prover is not usable anymore after a shutdown has been requested and only + * ever returns {@link InterruptedException}s. The context can be used normally and new + * provers can be created and used. If a {@link ShutdownNotifier} has been given to the + * context that is used to call this method, both notifiers can be used to stop the prover + * returned by this method. Note that once a shutdown-request has been given to the contexts + * {@link ShutdownNotifier}, no prover can ever be used again on that context instance. + * Solvers that don't support isolated prover shutdown throw a {@link + * UnsupportedOperationException} for this method and {@link + * #newProverEnvironment(ProverOptions...)} should be used instead. + * @param options Options specified for the prover environment. All the options specified in + * {@link ProverOptions} are turned off by default. + */ + OptimizationProverEnvironment newOptimizationProverEnvironment( + ShutdownNotifier pProverShutdownNotifier, ProverOptions... options); + /** * Get version information out of the solver. * diff --git a/src/org/sosy_lab/java_smt/basicimpl/AbstractSolverContext.java b/src/org/sosy_lab/java_smt/basicimpl/AbstractSolverContext.java index f071b00d29..f9d777de42 100644 --- a/src/org/sosy_lab/java_smt/basicimpl/AbstractSolverContext.java +++ b/src/org/sosy_lab/java_smt/basicimpl/AbstractSolverContext.java @@ -14,6 +14,8 @@ import java.util.List; import java.util.Set; import java.util.function.Consumer; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.sosy_lab.common.ShutdownNotifier; import org.sosy_lab.java_smt.api.FormulaManager; import org.sosy_lab.java_smt.api.InterpolatingProverEnvironment; import org.sosy_lab.java_smt.api.OptimizationProverEnvironment; @@ -38,43 +40,83 @@ public final FormulaManager getFormulaManager() { @SuppressWarnings("resource") @Override public final ProverEnvironment newProverEnvironment(ProverOptions... options) { - ProverEnvironment out = newProverEnvironment0(toSet(options)); + ProverEnvironment out = newProverEnvironment0(null, toSet(options)); + return wrapProverEnvironmentWithAssumptionsWrapper(out); + } + + @SuppressWarnings("resource") + @Override + public final ProverEnvironment newProverEnvironment( + ShutdownNotifier pProverShutdownNotifier, ProverOptions... options) { + ProverEnvironment out = newProverEnvironment0(pProverShutdownNotifier, toSet(options)); + return wrapProverEnvironmentWithAssumptionsWrapper(out); + } + + // TODO: switch to 2 methods with a default exception for pProverShutdownNotifier? + protected abstract ProverEnvironment newProverEnvironment0( + @Nullable ShutdownNotifier pProverShutdownNotifier, Set options); + + private ProverEnvironment wrapProverEnvironmentWithAssumptionsWrapper( + ProverEnvironment pProverEnvironment) { if (!supportsAssumptionSolving()) { // In the case we do not already have a prover environment with assumptions, // we add a wrapper to it - out = new ProverWithAssumptionsWrapper(out); + return new ProverWithAssumptionsWrapper(pProverEnvironment); } - return out; + return pProverEnvironment; } - protected abstract ProverEnvironment newProverEnvironment0(Set options); - @SuppressWarnings("resource") @Override public final InterpolatingProverEnvironment newProverEnvironmentWithInterpolation( ProverOptions... options) { - InterpolatingProverEnvironment out = newProverEnvironmentWithInterpolation0(toSet(options)); + InterpolatingProverEnvironment out = + newProverEnvironmentWithInterpolation0(null, toSet(options)); + return wrapProverEnvironmentWithAssumptionsWrapper(out); + } + + @SuppressWarnings("resource") + @Override + public final InterpolatingProverEnvironment newProverEnvironmentWithInterpolation( + ShutdownNotifier pProverShutdownNotifier, ProverOptions... options) { + + InterpolatingProverEnvironment out = + newProverEnvironmentWithInterpolation0(pProverShutdownNotifier, toSet(options)); + return wrapProverEnvironmentWithAssumptionsWrapper(out); + } + + // TODO: switch to 2 methods with a default exception for pProverShutdownNotifier? + protected abstract InterpolatingProverEnvironment newProverEnvironmentWithInterpolation0( + @Nullable ShutdownNotifier pProverShutdownNotifier, Set pSet); + + private InterpolatingProverEnvironment wrapProverEnvironmentWithAssumptionsWrapper( + InterpolatingProverEnvironment pInterpolatingProverEnvironment) { if (!supportsAssumptionSolving()) { // In the case we do not already have a prover environment with assumptions, // we add a wrapper to it - out = new InterpolatingProverWithAssumptionsWrapper<>(out, fmgr); + return new InterpolatingProverWithAssumptionsWrapper<>(pInterpolatingProverEnvironment, fmgr); } - return out; + return pInterpolatingProverEnvironment; } - protected abstract InterpolatingProverEnvironment newProverEnvironmentWithInterpolation0( - Set pSet); - @SuppressWarnings("resource") @Override public final OptimizationProverEnvironment newOptimizationProverEnvironment( ProverOptions... options) { - return newOptimizationProverEnvironment0(toSet(options)); + return newOptimizationProverEnvironment0(null, toSet(options)); + } + + @SuppressWarnings("resource") + @Override + public final OptimizationProverEnvironment newOptimizationProverEnvironment( + ShutdownNotifier pProverShutdownNotifier, ProverOptions... options) { + return newOptimizationProverEnvironment0(pProverShutdownNotifier, toSet(options)); } + // TODO: switch to 2 methods with a default exception for pProverShutdownNotifier? protected abstract OptimizationProverEnvironment newOptimizationProverEnvironment0( - Set pSet); + @Nullable ShutdownNotifier pProverShutdownNotifier, Set pSet); /** * Whether the solver supports solving under some given assumptions (with all corresponding From 418bc8b41962837c653b68c8a44a34889742ec64 Mon Sep 17 00:00:00 2001 From: BaierD Date: Wed, 4 Jun 2025 13:40:01 +0200 Subject: [PATCH 20/87] Remove old getter for created shutdown manager in the BasicProverEnvironment --- .../java_smt/api/BasicProverEnvironment.java | 22 ------------------- 1 file changed, 22 deletions(-) diff --git a/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java b/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java index 625a089c25..d66e9cef07 100644 --- a/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java +++ b/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java @@ -15,8 +15,6 @@ import java.util.List; import java.util.Optional; import org.checkerframework.checker.nullness.qual.Nullable; -import org.sosy_lab.common.ShutdownManager; -import org.sosy_lab.common.ShutdownNotifier; import org.sosy_lab.java_smt.api.SolverContext.ProverOptions; /** @@ -206,24 +204,4 @@ interface AllSatCallback { default boolean registerUserPropagator(UserPropagator propagator) { return false; } - - /** - * Returns the {@link ShutdownManager} registered for this {@link ProverEnvironment}. It is - * guaranteed to be a child of the {@link ShutdownNotifier} given to the creating {@link - * SolverContext}, resulting in shutdown when the {@link SolverContext}s notifier is shutting - * down. The notifier returned here can be shut down independently of the creating contexts - * notifier. JavaSMT will never attempt to shut down this manager on its own. - * - * @return a {@link ShutdownManager} who is the child of the {@link ShutdownNotifier} used in the - * creating {@link SolverContext}, that can be used to shut down only this {@link - * ProverEnvironment}. - * @throws UnsupportedOperationException if the solver does not support prover specific shutdown. - */ - default ShutdownManager getShutdownManagerForProver() { - // Override this with the prover specific ShutdownManagers notifier for supporting solvers. - // The solver should then use the prover specific ShutdownManagers notifier for stopping - // instead of the contexts' notifier! - throw new UnsupportedOperationException( - "The chosen solver does not support isolated prover shutdown"); - } } From c85042b3f325141921f038447c9f19d2258adf9c Mon Sep 17 00:00:00 2001 From: BaierD Date: Wed, 4 Jun 2025 13:41:13 +0200 Subject: [PATCH 21/87] Add new prover environments with a dedicated prover shutdown notifier to delegates --- .../DebuggingBasicProverEnvironment.java | 6 --- ...ebuggingOptimizationProverEnvironment.java | 6 --- .../debugging/DebuggingSolverContext.java | 29 +++++++++++ .../LoggingBasicProverEnvironment.java | 6 --- .../logging/LoggingSolverContext.java | 25 +++++++++ .../delegate/logging/PackageSanityTest.java | 9 +++- .../StatisticsBasicProverEnvironment.java | 6 --- .../statistics/StatisticsSolverContext.java | 25 +++++++++ .../SynchronizedBasicProverEnvironment.java | 6 --- ...izedBasicProverEnvironmentWithContext.java | 6 --- ...rpolatingProverEnvironmentWithContext.java | 6 --- .../SynchronizedSolverContext.java | 51 +++++++++++++++++++ ...LoggingSmtInterpolInterpolatingProver.java | 6 ++- 13 files changed, 142 insertions(+), 45 deletions(-) diff --git a/src/org/sosy_lab/java_smt/delegate/debugging/DebuggingBasicProverEnvironment.java b/src/org/sosy_lab/java_smt/delegate/debugging/DebuggingBasicProverEnvironment.java index ce1bf994fb..5199faf773 100644 --- a/src/org/sosy_lab/java_smt/delegate/debugging/DebuggingBasicProverEnvironment.java +++ b/src/org/sosy_lab/java_smt/delegate/debugging/DebuggingBasicProverEnvironment.java @@ -15,7 +15,6 @@ import java.util.List; import java.util.Optional; import org.checkerframework.checker.nullness.qual.Nullable; -import org.sosy_lab.common.ShutdownManager; import org.sosy_lab.java_smt.api.BasicProverEnvironment; import org.sosy_lab.java_smt.api.BooleanFormula; import org.sosy_lab.java_smt.api.Model; @@ -32,11 +31,6 @@ class DebuggingBasicProverEnvironment implements BasicProverEnvironment { debugging = pDebugging; } - @Override - public ShutdownManager getShutdownManagerForProver() throws UnsupportedOperationException { - return delegate.getShutdownManagerForProver(); - } - @Override public void pop() { debugging.assertThreadLocal(); diff --git a/src/org/sosy_lab/java_smt/delegate/debugging/DebuggingOptimizationProverEnvironment.java b/src/org/sosy_lab/java_smt/delegate/debugging/DebuggingOptimizationProverEnvironment.java index a41c30e364..9c178112f6 100644 --- a/src/org/sosy_lab/java_smt/delegate/debugging/DebuggingOptimizationProverEnvironment.java +++ b/src/org/sosy_lab/java_smt/delegate/debugging/DebuggingOptimizationProverEnvironment.java @@ -9,7 +9,6 @@ package org.sosy_lab.java_smt.delegate.debugging; import java.util.Optional; -import org.sosy_lab.common.ShutdownManager; import org.sosy_lab.common.rationals.Rational; import org.sosy_lab.java_smt.api.Formula; import org.sosy_lab.java_smt.api.OptimizationProverEnvironment; @@ -27,11 +26,6 @@ public DebuggingOptimizationProverEnvironment( debugging = pDebugging; } - @Override - public ShutdownManager getShutdownManagerForProver() throws UnsupportedOperationException { - return delegate.getShutdownManagerForProver(); - } - @Override public int maximize(Formula objective) { debugging.assertThreadLocal(); diff --git a/src/org/sosy_lab/java_smt/delegate/debugging/DebuggingSolverContext.java b/src/org/sosy_lab/java_smt/delegate/debugging/DebuggingSolverContext.java index e3a95aa069..1c327c7b40 100644 --- a/src/org/sosy_lab/java_smt/delegate/debugging/DebuggingSolverContext.java +++ b/src/org/sosy_lab/java_smt/delegate/debugging/DebuggingSolverContext.java @@ -11,6 +11,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import com.google.common.collect.ImmutableMap; +import org.sosy_lab.common.ShutdownNotifier; import org.sosy_lab.common.configuration.Configuration; import org.sosy_lab.common.configuration.InvalidConfigurationException; import org.sosy_lab.java_smt.SolverContextFactory.Solvers; @@ -47,6 +48,15 @@ public ProverEnvironment newProverEnvironment(ProverOptions... options) { return new DebuggingProverEnvironment(delegate.newProverEnvironment(options), debugging); } + @SuppressWarnings("resource") + @Override + public ProverEnvironment newProverEnvironment( + ShutdownNotifier pProverShutdownNotifier, ProverOptions... options) { + debugging.assertThreadLocal(); + return new DebuggingProverEnvironment( + delegate.newProverEnvironment(pProverShutdownNotifier, options), debugging); + } + @SuppressWarnings("resource") @Override public InterpolatingProverEnvironment newProverEnvironmentWithInterpolation( @@ -56,6 +66,16 @@ public InterpolatingProverEnvironment newProverEnvironmentWithInterpolation( delegate.newProverEnvironmentWithInterpolation(options), debugging); } + @SuppressWarnings("resource") + @Override + public InterpolatingProverEnvironment newProverEnvironmentWithInterpolation( + ShutdownNotifier pProverShutdownNotifier, ProverOptions... options) { + debugging.assertThreadLocal(); + return new DebuggingInterpolatingProverEnvironment<>( + delegate.newProverEnvironmentWithInterpolation(pProverShutdownNotifier, options), + debugging); + } + @SuppressWarnings("resource") @Override public OptimizationProverEnvironment newOptimizationProverEnvironment(ProverOptions... options) { @@ -64,6 +84,15 @@ public OptimizationProverEnvironment newOptimizationProverEnvironment(ProverOpti delegate.newOptimizationProverEnvironment(options), debugging); } + @SuppressWarnings("resource") + @Override + public OptimizationProverEnvironment newOptimizationProverEnvironment( + ShutdownNotifier pProverShutdownNotifier, ProverOptions... options) { + debugging.assertThreadLocal(); + return new DebuggingOptimizationProverEnvironment( + delegate.newOptimizationProverEnvironment(pProverShutdownNotifier, options), debugging); + } + @Override public String getVersion() { debugging.assertThreadLocal(); diff --git a/src/org/sosy_lab/java_smt/delegate/logging/LoggingBasicProverEnvironment.java b/src/org/sosy_lab/java_smt/delegate/logging/LoggingBasicProverEnvironment.java index 6776639382..2f194c6125 100644 --- a/src/org/sosy_lab/java_smt/delegate/logging/LoggingBasicProverEnvironment.java +++ b/src/org/sosy_lab/java_smt/delegate/logging/LoggingBasicProverEnvironment.java @@ -18,7 +18,6 @@ import java.util.Optional; import java.util.logging.Level; import org.checkerframework.checker.nullness.qual.Nullable; -import org.sosy_lab.common.ShutdownManager; import org.sosy_lab.common.log.LogManager; import org.sosy_lab.java_smt.api.BasicProverEnvironment; import org.sosy_lab.java_smt.api.BooleanFormula; @@ -39,11 +38,6 @@ class LoggingBasicProverEnvironment implements BasicProverEnvironment { logger = checkNotNull(pLogger); } - @Override - public ShutdownManager getShutdownManagerForProver() throws UnsupportedOperationException { - return wrapped.getShutdownManagerForProver(); - } - @Override public @Nullable T push(BooleanFormula f) throws InterruptedException { logger.log(Level.FINE, "up to level " + level++); diff --git a/src/org/sosy_lab/java_smt/delegate/logging/LoggingSolverContext.java b/src/org/sosy_lab/java_smt/delegate/logging/LoggingSolverContext.java index b68b9e8c5b..b49fe3fc60 100644 --- a/src/org/sosy_lab/java_smt/delegate/logging/LoggingSolverContext.java +++ b/src/org/sosy_lab/java_smt/delegate/logging/LoggingSolverContext.java @@ -11,6 +11,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import com.google.common.collect.ImmutableMap; +import org.sosy_lab.common.ShutdownNotifier; import org.sosy_lab.common.log.LogManager; import org.sosy_lab.java_smt.SolverContextFactory.Solvers; import org.sosy_lab.java_smt.api.FormulaManager; @@ -41,6 +42,14 @@ public ProverEnvironment newProverEnvironment(ProverOptions... pOptions) { return new LoggingProverEnvironment(logger, delegate.newProverEnvironment(pOptions)); } + @SuppressWarnings("resource") + @Override + public ProverEnvironment newProverEnvironment( + ShutdownNotifier pProverShutdownNotifier, ProverOptions... pOptions) { + return new LoggingProverEnvironment( + logger, delegate.newProverEnvironment(pProverShutdownNotifier, pOptions)); + } + @SuppressWarnings("resource") @Override public InterpolatingProverEnvironment newProverEnvironmentWithInterpolation( @@ -49,6 +58,14 @@ public InterpolatingProverEnvironment newProverEnvironmentWithInterpolation( logger, delegate.newProverEnvironmentWithInterpolation(options)); } + @SuppressWarnings("resource") + @Override + public InterpolatingProverEnvironment newProverEnvironmentWithInterpolation( + ShutdownNotifier pProverShutdownNotifier, ProverOptions... options) { + return new LoggingInterpolatingProverEnvironment<>( + logger, delegate.newProverEnvironmentWithInterpolation(pProverShutdownNotifier, options)); + } + @SuppressWarnings("resource") @Override public OptimizationProverEnvironment newOptimizationProverEnvironment(ProverOptions... options) { @@ -56,6 +73,14 @@ public OptimizationProverEnvironment newOptimizationProverEnvironment(ProverOpti logger, delegate.newOptimizationProverEnvironment(options)); } + @SuppressWarnings("resource") + @Override + public OptimizationProverEnvironment newOptimizationProverEnvironment( + ShutdownNotifier pProverShutdownNotifier, ProverOptions... options) { + return new LoggingOptimizationProverEnvironment( + logger, delegate.newOptimizationProverEnvironment(pProverShutdownNotifier, options)); + } + @Override public String getVersion() { return delegate.getVersion(); diff --git a/src/org/sosy_lab/java_smt/delegate/logging/PackageSanityTest.java b/src/org/sosy_lab/java_smt/delegate/logging/PackageSanityTest.java index b48a8ba3e2..a09c0042ab 100644 --- a/src/org/sosy_lab/java_smt/delegate/logging/PackageSanityTest.java +++ b/src/org/sosy_lab/java_smt/delegate/logging/PackageSanityTest.java @@ -9,5 +9,12 @@ package org.sosy_lab.java_smt.delegate.logging; import com.google.common.testing.AbstractPackageSanityTests; +import org.sosy_lab.common.ShutdownManager; -public class PackageSanityTest extends AbstractPackageSanityTests {} +public class PackageSanityTest extends AbstractPackageSanityTests { + + // WTF? + { + setDefault(org.sosy_lab.common.ShutdownNotifier.class, ShutdownManager.create().getNotifier()); + } +} diff --git a/src/org/sosy_lab/java_smt/delegate/statistics/StatisticsBasicProverEnvironment.java b/src/org/sosy_lab/java_smt/delegate/statistics/StatisticsBasicProverEnvironment.java index 47ef8bef5e..8720bc1c8c 100644 --- a/src/org/sosy_lab/java_smt/delegate/statistics/StatisticsBasicProverEnvironment.java +++ b/src/org/sosy_lab/java_smt/delegate/statistics/StatisticsBasicProverEnvironment.java @@ -15,7 +15,6 @@ import java.util.List; import java.util.Optional; import org.checkerframework.checker.nullness.qual.Nullable; -import org.sosy_lab.common.ShutdownManager; import org.sosy_lab.java_smt.api.BasicProverEnvironment; import org.sosy_lab.java_smt.api.BooleanFormula; import org.sosy_lab.java_smt.api.Model; @@ -38,11 +37,6 @@ class StatisticsBasicProverEnvironment implements BasicProverEnvironment { stats.provers.getAndIncrement(); } - @Override - public ShutdownManager getShutdownManagerForProver() throws UnsupportedOperationException { - return delegate.getShutdownManagerForProver(); - } - @Override public void pop() { stats.pop.getAndIncrement(); diff --git a/src/org/sosy_lab/java_smt/delegate/statistics/StatisticsSolverContext.java b/src/org/sosy_lab/java_smt/delegate/statistics/StatisticsSolverContext.java index 214d2dd576..c00f039e59 100644 --- a/src/org/sosy_lab/java_smt/delegate/statistics/StatisticsSolverContext.java +++ b/src/org/sosy_lab/java_smt/delegate/statistics/StatisticsSolverContext.java @@ -12,6 +12,7 @@ import com.google.common.collect.ImmutableMap; import java.util.Map; +import org.sosy_lab.common.ShutdownNotifier; import org.sosy_lab.java_smt.SolverContextFactory.Solvers; import org.sosy_lab.java_smt.api.FormulaManager; import org.sosy_lab.java_smt.api.InterpolatingProverEnvironment; @@ -39,6 +40,14 @@ public ProverEnvironment newProverEnvironment(ProverOptions... pOptions) { return new StatisticsProverEnvironment(delegate.newProverEnvironment(pOptions), stats); } + @SuppressWarnings("resource") + @Override + public ProverEnvironment newProverEnvironment( + ShutdownNotifier pProverShutdownNotifier, ProverOptions... pOptions) { + return new StatisticsProverEnvironment( + delegate.newProverEnvironment(pProverShutdownNotifier, pOptions), stats); + } + @SuppressWarnings("resource") @Override public InterpolatingProverEnvironment newProverEnvironmentWithInterpolation( @@ -47,6 +56,14 @@ public InterpolatingProverEnvironment newProverEnvironmentWithInterpolation( delegate.newProverEnvironmentWithInterpolation(pOptions), stats); } + @SuppressWarnings("resource") + @Override + public InterpolatingProverEnvironment newProverEnvironmentWithInterpolation( + ShutdownNotifier pProverShutdownNotifier, ProverOptions... options) { + return new StatisticsInterpolatingProverEnvironment<>( + delegate.newProverEnvironmentWithInterpolation(pProverShutdownNotifier, options), stats); + } + @SuppressWarnings("resource") @Override public OptimizationProverEnvironment newOptimizationProverEnvironment(ProverOptions... pOptions) { @@ -54,6 +71,14 @@ public OptimizationProverEnvironment newOptimizationProverEnvironment(ProverOpti delegate.newOptimizationProverEnvironment(pOptions), stats); } + @SuppressWarnings("resource") + @Override + public OptimizationProverEnvironment newOptimizationProverEnvironment( + ShutdownNotifier pProverShutdownNotifier, ProverOptions... options) { + return new StatisticsOptimizationProverEnvironment( + delegate.newOptimizationProverEnvironment(pProverShutdownNotifier, options), stats); + } + @Override public String getVersion() { return delegate.getVersion(); diff --git a/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedBasicProverEnvironment.java b/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedBasicProverEnvironment.java index 92c4496007..f3832815c2 100644 --- a/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedBasicProverEnvironment.java +++ b/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedBasicProverEnvironment.java @@ -16,7 +16,6 @@ import java.util.List; import java.util.Optional; import org.checkerframework.checker.nullness.qual.Nullable; -import org.sosy_lab.common.ShutdownManager; import org.sosy_lab.java_smt.api.BasicProverEnvironment; import org.sosy_lab.java_smt.api.BooleanFormula; import org.sosy_lab.java_smt.api.Model; @@ -34,11 +33,6 @@ class SynchronizedBasicProverEnvironment implements BasicProverEnvironment sync = checkNotNull(pSync); } - @Override - public ShutdownManager getShutdownManagerForProver() throws UnsupportedOperationException { - return delegate.getShutdownManagerForProver(); - } - @Override public void pop() { synchronized (sync) { diff --git a/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedBasicProverEnvironmentWithContext.java b/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedBasicProverEnvironmentWithContext.java index 89bb05042a..fd6a084a8e 100644 --- a/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedBasicProverEnvironmentWithContext.java +++ b/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedBasicProverEnvironmentWithContext.java @@ -16,7 +16,6 @@ import java.util.List; import java.util.Optional; import org.checkerframework.checker.nullness.qual.Nullable; -import org.sosy_lab.common.ShutdownManager; import org.sosy_lab.java_smt.api.BasicProverEnvironment; import org.sosy_lab.java_smt.api.BooleanFormula; import org.sosy_lab.java_smt.api.FormulaManager; @@ -151,11 +150,6 @@ public R allSat(AllSatCallback pCallback, List pImportant } } - @Override - public ShutdownManager getShutdownManagerForProver() throws UnsupportedOperationException { - return delegate.getShutdownManagerForProver(); - } - private class AllSatCallbackWithContext implements AllSatCallback { private final AllSatCallback delegateCallback; diff --git a/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedInterpolatingProverEnvironmentWithContext.java b/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedInterpolatingProverEnvironmentWithContext.java index d365ffad46..52e99c1e90 100644 --- a/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedInterpolatingProverEnvironmentWithContext.java +++ b/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedInterpolatingProverEnvironmentWithContext.java @@ -12,7 +12,6 @@ import java.util.Collection; import java.util.List; -import org.sosy_lab.common.ShutdownManager; import org.sosy_lab.java_smt.api.BooleanFormula; import org.sosy_lab.java_smt.api.FormulaManager; import org.sosy_lab.java_smt.api.InterpolatingProverEnvironment; @@ -34,11 +33,6 @@ class SynchronizedInterpolatingProverEnvironmentWithContext delegate = checkNotNull(pDelegate); } - @Override - public ShutdownManager getShutdownManagerForProver() throws UnsupportedOperationException { - return delegate.getShutdownManagerForProver(); - } - @Override public BooleanFormula getInterpolant(Collection pFormulasOfA) throws SolverException, InterruptedException { diff --git a/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedSolverContext.java b/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedSolverContext.java index bea5a9fb00..0f9a53aeab 100644 --- a/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedSolverContext.java +++ b/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedSolverContext.java @@ -94,6 +94,25 @@ public ProverEnvironment newProverEnvironment(ProverOptions... pOptions) { } } + @SuppressWarnings("resource") + @Override + public ProverEnvironment newProverEnvironment( + ShutdownNotifier pProverShutdownNotifier, ProverOptions... pOptions) { + synchronized (sync) { + if (useSeperateProvers) { + SolverContext otherContext = createOtherContext(); + return new SynchronizedProverEnvironmentWithContext( + otherContext.newProverEnvironment(pProverShutdownNotifier, pOptions), + sync, + delegate.getFormulaManager(), + otherContext.getFormulaManager()); + } else { + return new SynchronizedProverEnvironment( + delegate.newProverEnvironment(pProverShutdownNotifier, pOptions), delegate); + } + } + } + @SuppressWarnings("resource") @Override public InterpolatingProverEnvironment newProverEnvironmentWithInterpolation( @@ -113,6 +132,26 @@ public InterpolatingProverEnvironment newProverEnvironmentWithInterpolation( } } + @SuppressWarnings("resource") + @Override + public InterpolatingProverEnvironment newProverEnvironmentWithInterpolation( + ShutdownNotifier pProverShutdownNotifier, ProverOptions... pOptions) { + synchronized (sync) { + if (useSeperateProvers) { + SolverContext otherContext = createOtherContext(); + return new SynchronizedInterpolatingProverEnvironmentWithContext<>( + otherContext.newProverEnvironmentWithInterpolation(pProverShutdownNotifier, pOptions), + sync, + delegate.getFormulaManager(), + otherContext.getFormulaManager()); + } else { + return new SynchronizedInterpolatingProverEnvironment<>( + delegate.newProverEnvironmentWithInterpolation(pProverShutdownNotifier, pOptions), + delegate); + } + } + } + @SuppressWarnings("resource") @Override public OptimizationProverEnvironment newOptimizationProverEnvironment(ProverOptions... pOptions) { @@ -124,6 +163,18 @@ public OptimizationProverEnvironment newOptimizationProverEnvironment(ProverOpti } } + @SuppressWarnings("resource") + @Override + public OptimizationProverEnvironment newOptimizationProverEnvironment( + ShutdownNotifier pProverShutdownNotifier, ProverOptions... pOptions) { + synchronized (sync) { + // seperate prover environment not available, because we can not translate arbitrary formulae. + // if (useSeperateProvers) { } + return new SynchronizedOptimizationProverEnvironment( + delegate.newOptimizationProverEnvironment(pProverShutdownNotifier, pOptions), delegate); + } + } + @Override public String getVersion() { synchronized (sync) { diff --git a/src/org/sosy_lab/java_smt/solvers/smtinterpol/LoggingSmtInterpolInterpolatingProver.java b/src/org/sosy_lab/java_smt/solvers/smtinterpol/LoggingSmtInterpolInterpolatingProver.java index f92b2190f8..076ba9fe8c 100644 --- a/src/org/sosy_lab/java_smt/solvers/smtinterpol/LoggingSmtInterpolInterpolatingProver.java +++ b/src/org/sosy_lab/java_smt/solvers/smtinterpol/LoggingSmtInterpolInterpolatingProver.java @@ -22,6 +22,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import org.checkerframework.checker.nullness.qual.Nullable; import org.sosy_lab.common.ShutdownNotifier; import org.sosy_lab.common.io.IO; import org.sosy_lab.java_smt.api.BooleanFormula; @@ -37,10 +38,11 @@ class LoggingSmtInterpolInterpolatingProver extends SmtInterpolInterpolatingProv SmtInterpolFormulaManager pMgr, Script pScript, Set pOptions, - ShutdownNotifier pShutdownNotifier, + ShutdownNotifier pContextShutdownNotifier, + @Nullable ShutdownNotifier pProverShutdownNotifier, Map pGlobalOptions, Path pLogfile) { - super(pMgr, pScript, pOptions, pShutdownNotifier); + super(pMgr, pScript, pOptions, pContextShutdownNotifier, pProverShutdownNotifier); try { out = initializeLoggerForInterpolation(pGlobalOptions, pLogfile); } catch (IOException e) { From 2fe5c2b1feeceb638cb1c5a0db88fd4a6e0a19c6 Mon Sep 17 00:00:00 2001 From: BaierD Date: Wed, 4 Jun 2025 13:42:12 +0200 Subject: [PATCH 22/87] Add dedicated prover shutdown notifier to abstract provers --- .../java_smt/basicimpl/AbstractProver.java | 45 +++++++++++++------ .../basicimpl/AbstractProverWithAllSat.java | 14 +++--- .../BasicProverWithAssumptionsWrapper.java | 6 --- 3 files changed, 39 insertions(+), 26 deletions(-) diff --git a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java index 78b99d18b4..011dcaab56 100644 --- a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java +++ b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java @@ -24,7 +24,6 @@ import java.util.Optional; import java.util.Set; import org.checkerframework.checker.nullness.qual.Nullable; -import org.sosy_lab.common.ShutdownManager; import org.sosy_lab.common.ShutdownNotifier; import org.sosy_lab.java_smt.api.BasicProverEnvironment; import org.sosy_lab.java_smt.api.BooleanFormula; @@ -55,10 +54,13 @@ public abstract class AbstractProver implements BasicProverEnvironment { private static final String TEMPLATE = "Please set the prover option %s."; - protected final ShutdownNotifier proverShutdownNotifier; - protected final ShutdownManager proverShutdownManager; + protected final @Nullable ShutdownNotifier proverShutdownNotifier; + protected final ShutdownNotifier contextShutdownNotifier; - protected AbstractProver(ShutdownNotifier pShutdownNotifier, Set pOptions) { + protected AbstractProver( + ShutdownNotifier pContextShutdownNotifier, + @Nullable ShutdownNotifier pProverShutdownNotifier, + Set pOptions) { generateModels = pOptions.contains(ProverOptions.GENERATE_MODELS); generateAllSat = pOptions.contains(ProverOptions.GENERATE_ALL_SAT); generateUnsatCores = pOptions.contains(ProverOptions.GENERATE_UNSAT_CORE); @@ -68,8 +70,22 @@ protected AbstractProver(ShutdownNotifier pShutdownNotifier, Set assertedFormulas.add(LinkedHashMultimap.create()); - proverShutdownManager = ShutdownManager.createWithParent(pShutdownNotifier); - proverShutdownNotifier = proverShutdownManager.getNotifier(); + contextShutdownNotifier = pContextShutdownNotifier; + proverShutdownNotifier = pProverShutdownNotifier; + } + + protected final void shutdownIfNecessary() throws InterruptedException { + contextShutdownNotifier.shutdownIfNecessary(); + if (proverShutdownNotifier != null) { + proverShutdownNotifier.shutdownIfNecessary(); + } + } + + protected final boolean shouldShutdown() { + if (proverShutdownNotifier != null) { + return contextShutdownNotifier.shouldShutdown() || proverShutdownNotifier.shouldShutdown(); + } + return contextShutdownNotifier.shouldShutdown(); } protected final void checkGenerateModels() { @@ -105,7 +121,7 @@ public int size() { public final boolean isUnsat() throws SolverException, InterruptedException { checkState(!closed); closeAllEvaluators(); - proverShutdownNotifier.shutdownIfNecessary(); + shutdownIfNecessary(); wasLastSatCheckSat = !isUnsatImpl(); stackChangedSinceLastQuery = false; return !wasLastSatCheckSat; @@ -116,7 +132,7 @@ public final boolean isUnsat() throws SolverException, InterruptedException { @Override public List getUnsatCore() { checkState(!closed); - checkState(!proverShutdownNotifier.shouldShutdown()); + checkState(!shouldShutdown()); checkState(!wasLastSatCheckSat, NO_UNSAT_CORE_HELP); checkState(!stackChangedSinceLastQuery, STACK_CHANGED_HELP); checkGenerateUnsatCores(); @@ -129,7 +145,7 @@ public List getUnsatCore() { public final Optional> unsatCoreOverAssumptions( Collection assumptions) throws SolverException, InterruptedException { checkState(!closed); - proverShutdownNotifier.shutdownIfNecessary(); + shutdownIfNecessary(); checkGenerateUnsatCoresOverAssumptions(); return unsatCoreOverAssumptionsImpl(assumptions); } @@ -141,7 +157,8 @@ protected abstract Optional> unsatCoreOverAssumptionsImpl( public final boolean isUnsatWithAssumptions(Collection assumptions) throws SolverException, InterruptedException { checkState(!closed); - proverShutdownNotifier.shutdownIfNecessary(); + shutdownIfNecessary(); + stackChangedSinceLastQuery = false; return isUnsatWithAssumptionsImpl(assumptions); } @@ -151,7 +168,7 @@ protected abstract boolean isUnsatWithAssumptionsImpl(Collection @Override public final Model getModel() throws SolverException { checkState(!closed); - checkState(!proverShutdownNotifier.shouldShutdown()); + checkState(!shouldShutdown()); checkState(wasLastSatCheckSat, NO_MODEL_HELP); checkState(!stackChangedSinceLastQuery, STACK_CHANGED_HELP); checkGenerateModels(); @@ -163,7 +180,7 @@ public final Model getModel() throws SolverException { @Override public final void push() throws InterruptedException { checkState(!closed); - proverShutdownNotifier.shutdownIfNecessary(); + shutdownIfNecessary(); pushImpl(); stackChangedSinceLastQuery = true; assertedFormulas.add(LinkedHashMultimap.create()); @@ -188,7 +205,7 @@ public final void pop() { @CanIgnoreReturnValue public final @Nullable T addConstraint(BooleanFormula constraint) throws InterruptedException { checkState(!closed); - proverShutdownNotifier.shutdownIfNecessary(); + shutdownIfNecessary(); T t = addConstraintImpl(constraint); Iterables.getLast(assertedFormulas).put(constraint, t); stackChangedSinceLastQuery = true; @@ -236,7 +253,7 @@ protected void closeAllEvaluators() { @Override public ImmutableList getModelAssignments() throws SolverException { Preconditions.checkState(!closed); - checkState(!proverShutdownNotifier.shouldShutdown()); + checkState(!shouldShutdown()); Preconditions.checkState(!stackChangedSinceLastQuery, STACK_CHANGED_HELP); checkState(wasLastSatCheckSat); try (Model model = getModel()) { diff --git a/src/org/sosy_lab/java_smt/basicimpl/AbstractProverWithAllSat.java b/src/org/sosy_lab/java_smt/basicimpl/AbstractProverWithAllSat.java index d178188c1d..184bc22819 100644 --- a/src/org/sosy_lab/java_smt/basicimpl/AbstractProverWithAllSat.java +++ b/src/org/sosy_lab/java_smt/basicimpl/AbstractProverWithAllSat.java @@ -14,6 +14,7 @@ import java.util.Deque; import java.util.List; import java.util.Set; +import org.checkerframework.checker.nullness.qual.Nullable; import org.sosy_lab.common.ShutdownNotifier; import org.sosy_lab.java_smt.api.BooleanFormula; import org.sosy_lab.java_smt.api.BooleanFormulaManager; @@ -33,8 +34,9 @@ public abstract class AbstractProverWithAllSat extends AbstractProver { protected AbstractProverWithAllSat( Set pOptions, BooleanFormulaManager pBmgr, - ShutdownNotifier pShutdownNotifier) { - super(pShutdownNotifier, pOptions); + ShutdownNotifier pContextShutdownNotifier, + @Nullable ShutdownNotifier pProverShutdownNotifier) { + super(pContextShutdownNotifier, pProverShutdownNotifier, pOptions); bmgr = pBmgr; } @@ -66,7 +68,7 @@ private void iterateOverAllModels( AllSatCallback callback, List importantPredicates) throws SolverException, InterruptedException { while (!isUnsat()) { - proverShutdownNotifier.shutdownIfNecessary(); + shutdownIfNecessary(); ImmutableList.Builder valuesOfModel = ImmutableList.builder(); try (Evaluator evaluator = getEvaluatorWithoutChecks()) { @@ -86,11 +88,11 @@ private void iterateOverAllModels( final ImmutableList values = valuesOfModel.build(); callback.apply(values); - proverShutdownNotifier.shutdownIfNecessary(); + shutdownIfNecessary(); BooleanFormula negatedModel = bmgr.not(bmgr.and(values)); addConstraint(negatedModel); - proverShutdownNotifier.shutdownIfNecessary(); + shutdownIfNecessary(); } } @@ -111,7 +113,7 @@ private void iterateOverAllPredicateCombinations( Deque valuesOfModel) throws SolverException, InterruptedException { - proverShutdownNotifier.shutdownIfNecessary(); + shutdownIfNecessary(); if (isUnsat()) { return; diff --git a/src/org/sosy_lab/java_smt/basicimpl/withAssumptionsWrapper/BasicProverWithAssumptionsWrapper.java b/src/org/sosy_lab/java_smt/basicimpl/withAssumptionsWrapper/BasicProverWithAssumptionsWrapper.java index 4cb6dc051f..f2bf7435fe 100644 --- a/src/org/sosy_lab/java_smt/basicimpl/withAssumptionsWrapper/BasicProverWithAssumptionsWrapper.java +++ b/src/org/sosy_lab/java_smt/basicimpl/withAssumptionsWrapper/BasicProverWithAssumptionsWrapper.java @@ -14,7 +14,6 @@ import java.util.Collection; import java.util.List; import java.util.Optional; -import org.sosy_lab.common.ShutdownManager; import org.sosy_lab.java_smt.api.BasicProverEnvironment; import org.sosy_lab.java_smt.api.BooleanFormula; import org.sosy_lab.java_smt.api.Model; @@ -129,9 +128,4 @@ public R allSat(AllSatCallback pCallback, List pImportant clearAssumptions(); return delegate.allSat(pCallback, pImportant); } - - @Override - public ShutdownManager getShutdownManagerForProver() throws UnsupportedOperationException { - return delegate.getShutdownManagerForProver(); - } } From 028ef5b6a1eb2ba7262c4dc9feaba132af05e972 Mon Sep 17 00:00:00 2001 From: BaierD Date: Wed, 4 Jun 2025 13:42:28 +0200 Subject: [PATCH 23/87] Add dedicated prover shutdown notifier to Bitwuzla --- .../bitwuzla/BitwuzlaSolverContext.java | 14 ++++++++------ .../bitwuzla/BitwuzlaTheoremProver.java | 19 +++++++++---------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/org/sosy_lab/java_smt/solvers/bitwuzla/BitwuzlaSolverContext.java b/src/org/sosy_lab/java_smt/solvers/bitwuzla/BitwuzlaSolverContext.java index 20c0a2a389..a79303ed8a 100644 --- a/src/org/sosy_lab/java_smt/solvers/bitwuzla/BitwuzlaSolverContext.java +++ b/src/org/sosy_lab/java_smt/solvers/bitwuzla/BitwuzlaSolverContext.java @@ -132,7 +132,7 @@ protected String getFurtherOptions() { private final BitwuzlaFormulaManager manager; private final BitwuzlaFormulaCreator creator; - private final ShutdownNotifier shutdownNotifier; + private final ShutdownNotifier contextShutdownNotifier; private final Options solverOptions; @@ -146,7 +146,7 @@ protected String getFurtherOptions() { super(pManager); manager = pManager; creator = pCreator; - shutdownNotifier = pShutdownNotifier; + contextShutdownNotifier = pShutdownNotifier; solverOptions = pOptions; } @@ -290,21 +290,23 @@ public void close() { } @Override - protected ProverEnvironment newProverEnvironment0(Set options) { + protected ProverEnvironment newProverEnvironment0( + @Nullable ShutdownNotifier pProverShutdownNotifier, Set options) { Preconditions.checkState(!closed, "solver context is already closed"); - return new BitwuzlaTheoremProver(manager, creator, shutdownNotifier, options, solverOptions); + return new BitwuzlaTheoremProver( + manager, creator, contextShutdownNotifier, pProverShutdownNotifier, options, solverOptions); } @Override protected InterpolatingProverEnvironment newProverEnvironmentWithInterpolation0( - Set pF) { + @Nullable ShutdownNotifier pProverShutdownNotifier, Set pF) { throw new UnsupportedOperationException("Bitwuzla does not support interpolation"); } @Override protected OptimizationProverEnvironment newOptimizationProverEnvironment0( - Set pSet) { + @Nullable ShutdownNotifier pProverShutdownNotifier, Set pSet) { throw new UnsupportedOperationException("Bitwuzla does not support optimization"); } diff --git a/src/org/sosy_lab/java_smt/solvers/bitwuzla/BitwuzlaTheoremProver.java b/src/org/sosy_lab/java_smt/solvers/bitwuzla/BitwuzlaTheoremProver.java index 6ee8c85b8e..73486d04f3 100644 --- a/src/org/sosy_lab/java_smt/solvers/bitwuzla/BitwuzlaTheoremProver.java +++ b/src/org/sosy_lab/java_smt/solvers/bitwuzla/BitwuzlaTheoremProver.java @@ -17,7 +17,6 @@ import java.util.Optional; import java.util.Set; import org.checkerframework.checker.nullness.qual.Nullable; -import org.sosy_lab.common.ShutdownManager; import org.sosy_lab.common.ShutdownNotifier; import org.sosy_lab.java_smt.api.BooleanFormula; import org.sosy_lab.java_smt.api.Model; @@ -42,7 +41,7 @@ class BitwuzlaTheoremProver extends AbstractProverWithAllSat implements Pr new Terminator() { @Override public boolean terminate() { - return proverShutdownNotifier.shouldShutdown(); + return shouldShutdown(); } }; private final Bitwuzla env; @@ -55,10 +54,15 @@ public boolean terminate() { protected BitwuzlaTheoremProver( BitwuzlaFormulaManager pManager, BitwuzlaFormulaCreator pCreator, - ShutdownNotifier pShutdownNotifier, + ShutdownNotifier pContextShutdownNotifier, + @Nullable ShutdownNotifier pProverShutdownNotifier, Set pOptions, Options pSolverOptions) { - super(pOptions, pManager.getBooleanFormulaManager(), pShutdownNotifier); + super( + pOptions, + pManager.getBooleanFormulaManager(), + pContextShutdownNotifier, + pProverShutdownNotifier); manager = pManager; creator = pCreator; @@ -122,7 +126,7 @@ private boolean readSATResult(Result resultValue) throws SolverException, Interr return false; } else if (resultValue == Result.UNSAT) { return true; - } else if (resultValue == Result.UNKNOWN && proverShutdownNotifier.shouldShutdown()) { + } else if (resultValue == Result.UNKNOWN && shouldShutdown()) { throw new InterruptedException(); } else { throw new SolverException("Bitwuzla returned UNKNOWN."); @@ -239,11 +243,6 @@ protected BitwuzlaModel getEvaluatorWithoutChecks() { Collections2.transform(getAssertedFormulas(), creator::extractInfo))); } - @Override - public ShutdownManager getShutdownManagerForProver() throws UnsupportedOperationException { - return proverShutdownManager; - } - public boolean isClosed() { return closed; } From b122b50cfdaf39f847436cbf4167cb4c83153660 Mon Sep 17 00:00:00 2001 From: BaierD Date: Wed, 4 Jun 2025 13:42:37 +0200 Subject: [PATCH 24/87] Add dedicated prover shutdown notifier to ShutdownHook --- .../java_smt/basicimpl/ShutdownHook.java | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/org/sosy_lab/java_smt/basicimpl/ShutdownHook.java b/src/org/sosy_lab/java_smt/basicimpl/ShutdownHook.java index 61f176572a..fd0ee0c8cd 100644 --- a/src/org/sosy_lab/java_smt/basicimpl/ShutdownHook.java +++ b/src/org/sosy_lab/java_smt/basicimpl/ShutdownHook.java @@ -22,13 +22,23 @@ */ public final class ShutdownHook implements ShutdownRequestListener, AutoCloseable { - private final ShutdownNotifier shutdownNotifier; + private final ShutdownNotifier contextShutdownNotifier; + private final @Nullable ShutdownNotifier proverShutdownNotifier; private final Runnable interruptCall; - public ShutdownHook(ShutdownNotifier pShutdownNotifier, Runnable pInterruptCall) { + public ShutdownHook( + ShutdownNotifier pContextShutdownNotifier, + @Nullable ShutdownNotifier pProverShutdownNotifier, + Runnable pInterruptCall) { interruptCall = Preconditions.checkNotNull(pInterruptCall); - shutdownNotifier = Preconditions.checkNotNull(pShutdownNotifier); - shutdownNotifier.register(this); + contextShutdownNotifier = Preconditions.checkNotNull(pContextShutdownNotifier); + contextShutdownNotifier.register(this); + if (pProverShutdownNotifier != null) { + proverShutdownNotifier = pProverShutdownNotifier; + proverShutdownNotifier.register(this); + } else { + proverShutdownNotifier = null; + } } final AtomicBoolean isActiveHook = new AtomicBoolean(true); @@ -51,6 +61,9 @@ public void shutdownRequested(@Nullable String reasonUnused) { @Override public void close() { isActiveHook.set(false); - shutdownNotifier.unregister(this); + contextShutdownNotifier.unregister(this); + if (proverShutdownNotifier != null) { + proverShutdownNotifier.unregister(this); + } } } From b1ad38fb4f75ba22f45823ccea6f7bd9f70d6a12 Mon Sep 17 00:00:00 2001 From: BaierD Date: Wed, 4 Jun 2025 13:43:11 +0200 Subject: [PATCH 25/87] Add dedicated prover shutdown notifier to Boolector and remove unneeded abstract prover class (move everything to TheoremProver) --- .../boolector/BoolectorAbstractProver.java | 172 ------------------ .../solvers/boolector/BoolectorModel.java | 4 +- .../boolector/BoolectorSolverContext.java | 19 +- .../boolector/BoolectorTheoremProver.java | 153 +++++++++++++++- 4 files changed, 164 insertions(+), 184 deletions(-) delete mode 100644 src/org/sosy_lab/java_smt/solvers/boolector/BoolectorAbstractProver.java diff --git a/src/org/sosy_lab/java_smt/solvers/boolector/BoolectorAbstractProver.java b/src/org/sosy_lab/java_smt/solvers/boolector/BoolectorAbstractProver.java deleted file mode 100644 index c5e6c8f7da..0000000000 --- a/src/org/sosy_lab/java_smt/solvers/boolector/BoolectorAbstractProver.java +++ /dev/null @@ -1,172 +0,0 @@ -// This file is part of JavaSMT, -// an API wrapper for a collection of SMT solvers: -// https://github.com/sosy-lab/java-smt -// -// SPDX-FileCopyrightText: 2020 Dirk Beyer -// -// SPDX-License-Identifier: Apache-2.0 - -package org.sosy_lab.java_smt.solvers.boolector; - -import com.google.common.base.Preconditions; -import com.google.common.collect.Collections2; -import java.util.Collection; -import java.util.List; -import java.util.Optional; -import java.util.Set; -import java.util.concurrent.atomic.AtomicBoolean; -import org.checkerframework.checker.nullness.qual.Nullable; -import org.sosy_lab.common.ShutdownNotifier; -import org.sosy_lab.java_smt.api.BooleanFormula; -import org.sosy_lab.java_smt.api.Model; -import org.sosy_lab.java_smt.api.SolverContext.ProverOptions; -import org.sosy_lab.java_smt.api.SolverException; -import org.sosy_lab.java_smt.basicimpl.AbstractProverWithAllSat; -import org.sosy_lab.java_smt.basicimpl.CachingModel; -import org.sosy_lab.java_smt.solvers.boolector.BtorJNI.TerminationCallback; - -abstract class BoolectorAbstractProver extends AbstractProverWithAllSat { - - /** Boolector does not support multiple solver stacks. */ - private final AtomicBoolean isAnyStackAlive; - - private final long btor; - private final BoolectorFormulaManager manager; - private final BoolectorFormulaCreator creator; - private final TerminationCallback terminationCallback; - private final long terminationCallbackHelper; - - // Used/Built by TheoremProver - protected BoolectorAbstractProver( - BoolectorFormulaManager manager, - BoolectorFormulaCreator creator, - long btor, - ShutdownNotifier pShutdownNotifier, - Set pOptions, - AtomicBoolean pIsAnyStackAlive) { - super(pOptions, manager.getBooleanFormulaManager(), pShutdownNotifier); - this.manager = manager; - this.creator = creator; - this.btor = btor; - terminationCallback = proverShutdownNotifier::shouldShutdown; - terminationCallbackHelper = addTerminationCallback(); - - isAnyStackAlive = pIsAnyStackAlive; - // avoid dual stack usage - Preconditions.checkState( - !isAnyStackAlive.getAndSet(true), - "Boolector does not support the usage of multiple " - + "solver stacks at the same time. Please close any existing solver stack."); - // push an initial level, required for cleaning up later (see #close), for reusage of Boolector. - BtorJNI.boolector_push(manager.getEnvironment(), 1); - } - - @Override - public void close() { - if (!closed) { - // Free resources of callback - BtorJNI.boolector_free_termination(terminationCallbackHelper); - // remove the whole stack, including the initial level from the constructor call. - BtorJNI.boolector_pop(manager.getEnvironment(), size() + 1); - // You can't use delete here because you wouldn't be able to access model - // Wait till we have visitor/toList, after that we can delete here - // BtorJNI.boolector_delete(btor); - Preconditions.checkState(isAnyStackAlive.getAndSet(false)); - } - super.close(); - } - - /* - * Boolector should throw its own exceptions that tell you what went wrong! - */ - @Override - protected boolean isUnsatImpl() throws SolverException, InterruptedException { - Preconditions.checkState(!closed); - wasLastSatCheckSat = false; - final int result = BtorJNI.boolector_sat(btor); - if (result == BtorJNI.BTOR_RESULT_SAT_get()) { - wasLastSatCheckSat = true; - return false; - } else if (result == BtorJNI.BTOR_RESULT_UNSAT_get()) { - return true; - } else if (result == BtorJNI.BTOR_RESULT_UNKNOWN_get()) { - if (BtorJNI.boolector_terminate(btor) == 0) { - throw new SolverException( - "Boolector has encountered a problem or ran out of stack or heap memory, " - + "try increasing their sizes."); - } else { - throw new InterruptedException("Boolector was terminated via ShutdownManager."); - } - } else { - throw new SolverException("Boolector sat call returned " + result); - } - } - - @Override - protected void popImpl() { - BtorJNI.boolector_pop(manager.getEnvironment(), 1); - } - - @Override - protected void pushImpl() throws InterruptedException { - BtorJNI.boolector_push(manager.getEnvironment(), 1); - } - - @Override - protected boolean isUnsatWithAssumptionsImpl(Collection pAssumptions) - throws SolverException, InterruptedException { - Preconditions.checkState(!closed); - for (BooleanFormula assumption : pAssumptions) { - BtorJNI.boolector_assume(btor, BoolectorFormulaManager.getBtorTerm(assumption)); - } - return isUnsat(); - } - - @SuppressWarnings("resource") - @Override - protected Model getModelImpl() throws SolverException { - Preconditions.checkState(wasLastSatCheckSat, NO_MODEL_HELP); - checkGenerateModels(); - return new CachingModel(getEvaluatorWithoutChecks()); - } - - @Override - protected BoolectorModel getEvaluatorWithoutChecks() { - return new BoolectorModel( - btor, creator, this, Collections2.transform(getAssertedFormulas(), creator::extractInfo)); - } - - @Override - protected List getUnsatCoreImpl() { - throw new UnsupportedOperationException("Unsat core is not supported by Boolector."); - } - - @Override - protected Optional> unsatCoreOverAssumptionsImpl( - Collection pAssumptions) { - throw new UnsupportedOperationException( - "Unsat core with assumptions is not supported by Boolector."); - } - - @Override - @Nullable - protected T addConstraintImpl(BooleanFormula constraint) throws InterruptedException { - BtorJNI.boolector_assert( - manager.getEnvironment(), BoolectorFormulaManager.getBtorTerm(constraint)); - return null; - } - - /** - * Simply returns true if the prover is closed. False otherwise. - * - * @return bool return value. - */ - protected boolean isClosed() { - return closed; - } - - private long addTerminationCallback() { - Preconditions.checkState(!closed, "solver context is already closed"); - return BtorJNI.boolector_set_termination(btor, terminationCallback); - } -} diff --git a/src/org/sosy_lab/java_smt/solvers/boolector/BoolectorModel.java b/src/org/sosy_lab/java_smt/solvers/boolector/BoolectorModel.java index abea4910e1..fd7edf1218 100644 --- a/src/org/sosy_lab/java_smt/solvers/boolector/BoolectorModel.java +++ b/src/org/sosy_lab/java_smt/solvers/boolector/BoolectorModel.java @@ -80,14 +80,14 @@ class BoolectorModel extends AbstractModel { "set-option"); private final long btor; - private final BoolectorAbstractProver prover; + private final BoolectorTheoremProver prover; private final BoolectorFormulaCreator bfCreator; private final ImmutableList assertedTerms; BoolectorModel( long btor, BoolectorFormulaCreator creator, - BoolectorAbstractProver pProver, + BoolectorTheoremProver pProver, Collection assertedTerms) { super(pProver, creator); this.bfCreator = creator; diff --git a/src/org/sosy_lab/java_smt/solvers/boolector/BoolectorSolverContext.java b/src/org/sosy_lab/java_smt/solvers/boolector/BoolectorSolverContext.java index 6d2bb3b9d9..dcbb77585f 100644 --- a/src/org/sosy_lab/java_smt/solvers/boolector/BoolectorSolverContext.java +++ b/src/org/sosy_lab/java_smt/solvers/boolector/BoolectorSolverContext.java @@ -62,7 +62,7 @@ private static class BoolectorSettings { private final BoolectorFormulaManager manager; private final BoolectorFormulaCreator creator; - private final ShutdownNotifier shutdownNotifier; + private final ShutdownNotifier contextShutdownNotifier; private boolean closed = false; private final AtomicBoolean isAnyStackAlive = new AtomicBoolean(false); @@ -73,7 +73,7 @@ private static class BoolectorSettings { super(pManager); manager = pManager; creator = pCreator; - shutdownNotifier = pShutdownNotifier; + contextShutdownNotifier = pShutdownNotifier; } public static BoolectorSolverContext create( @@ -196,21 +196,28 @@ public void close() { @SuppressWarnings("resource") @Override - protected ProverEnvironment newProverEnvironment0(Set pOptions) { + protected ProverEnvironment newProverEnvironment0( + @Nullable ShutdownNotifier pProverShutdownNotifier, Set pOptions) { Preconditions.checkState(!closed, "solver context is already closed"); return new BoolectorTheoremProver( - manager, creator, creator.getEnv(), shutdownNotifier, pOptions, isAnyStackAlive); + manager, + creator, + creator.getEnv(), + contextShutdownNotifier, + pProverShutdownNotifier, + pOptions, + isAnyStackAlive); } @Override protected InterpolatingProverEnvironment newProverEnvironmentWithInterpolation0( - Set pSet) { + @Nullable ShutdownNotifier pProverShutdownNotifier, Set pSet) { throw new UnsupportedOperationException("Boolector does not support interpolation"); } @Override protected OptimizationProverEnvironment newOptimizationProverEnvironment0( - Set pSet) { + @Nullable ShutdownNotifier pProverShutdownNotifier, Set pSet) { throw new UnsupportedOperationException("Boolector does not support optimization"); } diff --git a/src/org/sosy_lab/java_smt/solvers/boolector/BoolectorTheoremProver.java b/src/org/sosy_lab/java_smt/solvers/boolector/BoolectorTheoremProver.java index d3df11c181..43fd1239b9 100644 --- a/src/org/sosy_lab/java_smt/solvers/boolector/BoolectorTheoremProver.java +++ b/src/org/sosy_lab/java_smt/solvers/boolector/BoolectorTheoremProver.java @@ -8,22 +8,167 @@ package org.sosy_lab.java_smt.solvers.boolector; +import com.google.common.base.Preconditions; +import com.google.common.collect.Collections2; +import java.util.Collection; +import java.util.List; +import java.util.Optional; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; +import org.checkerframework.checker.nullness.qual.Nullable; import org.sosy_lab.common.ShutdownNotifier; +import org.sosy_lab.java_smt.api.BooleanFormula; +import org.sosy_lab.java_smt.api.Model; import org.sosy_lab.java_smt.api.ProverEnvironment; import org.sosy_lab.java_smt.api.SolverContext.ProverOptions; +import org.sosy_lab.java_smt.api.SolverException; +import org.sosy_lab.java_smt.basicimpl.AbstractProverWithAllSat; +import org.sosy_lab.java_smt.basicimpl.CachingModel; -class BoolectorTheoremProver extends BoolectorAbstractProver implements ProverEnvironment { - // Used as standard prover. Built by method newProverEnvironment0 in BtorSolverContext +class BoolectorTheoremProver extends AbstractProverWithAllSat implements ProverEnvironment { + + /** Boolector does not support multiple solver stacks. */ + private final AtomicBoolean isAnyStackAlive; + + private final long btor; + private final BoolectorFormulaManager manager; + private final BoolectorFormulaCreator creator; + private final long terminationCallbackHelper; protected BoolectorTheoremProver( BoolectorFormulaManager manager, BoolectorFormulaCreator creator, long btor, - ShutdownNotifier pShutdownNotifier, + ShutdownNotifier pContextShutdownNotifier, + @Nullable ShutdownNotifier pProverShutdownNotifier, Set pOptions, AtomicBoolean pIsAnyStackAlive) { - super(manager, creator, btor, pShutdownNotifier, pOptions, pIsAnyStackAlive); + super( + pOptions, + manager.getBooleanFormulaManager(), + pContextShutdownNotifier, + pProverShutdownNotifier); + this.manager = manager; + this.creator = creator; + this.btor = btor; + terminationCallbackHelper = addTerminationCallback(); + + isAnyStackAlive = pIsAnyStackAlive; + // avoid dual stack usage + Preconditions.checkState( + !isAnyStackAlive.getAndSet(true), + "Boolector does not support the usage of multiple " + + "solver stacks at the same time. Please close any existing solver stack."); + // push an initial level, required for cleaning up later (see #close), for reusage of Boolector. + BtorJNI.boolector_push(manager.getEnvironment(), 1); + } + + @Override + public void close() { + if (!closed) { + // Free resources of callback + BtorJNI.boolector_free_termination(terminationCallbackHelper); + // remove the whole stack, including the initial level from the constructor call. + BtorJNI.boolector_pop(manager.getEnvironment(), size() + 1); + // You can't use delete here because you wouldn't be able to access model + // Wait till we have visitor/toList, after that we can delete here + // BtorJNI.boolector_delete(btor); + Preconditions.checkState(isAnyStackAlive.getAndSet(false)); + } + super.close(); + } + + /* + * Boolector should throw its own exceptions that tell you what went wrong! + */ + @Override + protected boolean isUnsatImpl() throws SolverException, InterruptedException { + Preconditions.checkState(!closed); + wasLastSatCheckSat = false; + final int result = BtorJNI.boolector_sat(btor); + if (result == BtorJNI.BTOR_RESULT_SAT_get()) { + wasLastSatCheckSat = true; + return false; + } else if (result == BtorJNI.BTOR_RESULT_UNSAT_get()) { + return true; + } else if (result == BtorJNI.BTOR_RESULT_UNKNOWN_get()) { + if (BtorJNI.boolector_terminate(btor) == 0) { + throw new SolverException( + "Boolector has encountered a problem or ran out of stack or heap memory, " + + "try increasing their sizes."); + } else { + throw new InterruptedException("Boolector was terminated via ShutdownManager."); + } + } else { + throw new SolverException("Boolector sat call returned " + result); + } + } + + @Override + protected void popImpl() { + BtorJNI.boolector_pop(manager.getEnvironment(), 1); + } + + @Override + protected void pushImpl() throws InterruptedException { + BtorJNI.boolector_push(manager.getEnvironment(), 1); + } + + @Override + protected boolean isUnsatWithAssumptionsImpl(Collection pAssumptions) + throws SolverException, InterruptedException { + Preconditions.checkState(!closed); + for (BooleanFormula assumption : pAssumptions) { + BtorJNI.boolector_assume(btor, BoolectorFormulaManager.getBtorTerm(assumption)); + } + return isUnsat(); + } + + @SuppressWarnings("resource") + @Override + protected Model getModelImpl() throws SolverException { + Preconditions.checkState(wasLastSatCheckSat, NO_MODEL_HELP); + checkGenerateModels(); + return new CachingModel(getEvaluatorWithoutChecks()); + } + + @Override + protected BoolectorModel getEvaluatorWithoutChecks() { + return new BoolectorModel( + btor, creator, this, Collections2.transform(getAssertedFormulas(), creator::extractInfo)); + } + + @Override + protected List getUnsatCoreImpl() { + throw new UnsupportedOperationException("Unsat core is not supported by Boolector."); + } + + @Override + protected Optional> unsatCoreOverAssumptionsImpl( + Collection pAssumptions) { + throw new UnsupportedOperationException( + "Unsat core with assumptions is not supported by Boolector."); + } + + @Override + @Nullable + protected Void addConstraintImpl(BooleanFormula constraint) throws InterruptedException { + BtorJNI.boolector_assert( + manager.getEnvironment(), BoolectorFormulaManager.getBtorTerm(constraint)); + return null; + } + + /** + * Simply returns true if the prover is closed. False otherwise. + * + * @return bool return value. + */ + protected boolean isClosed() { + return closed; + } + + private long addTerminationCallback() { + Preconditions.checkState(!closed, "solver context is already closed"); + return BtorJNI.boolector_set_termination(btor, this::shouldShutdown); } } From 856d3b6e05f12ec2b57c5463a8bd10a759fe2c56 Mon Sep 17 00:00:00 2001 From: BaierD Date: Wed, 4 Jun 2025 13:43:19 +0200 Subject: [PATCH 26/87] Add dedicated prover shutdown notifier to CVC4 --- .../solvers/cvc4/CVC4SolverContext.java | 15 +++++++++------ .../solvers/cvc4/CVC4TheoremProver.java | 18 +++++++----------- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/src/org/sosy_lab/java_smt/solvers/cvc4/CVC4SolverContext.java b/src/org/sosy_lab/java_smt/solvers/cvc4/CVC4SolverContext.java index b5bd086812..ce0ce55e8c 100644 --- a/src/org/sosy_lab/java_smt/solvers/cvc4/CVC4SolverContext.java +++ b/src/org/sosy_lab/java_smt/solvers/cvc4/CVC4SolverContext.java @@ -16,6 +16,7 @@ import java.util.Set; import java.util.function.Consumer; import java.util.logging.Level; +import org.checkerframework.checker.nullness.qual.Nullable; import org.sosy_lab.common.ShutdownNotifier; import org.sosy_lab.common.log.LogManager; import org.sosy_lab.java_smt.SolverContextFactory.Solvers; @@ -31,7 +32,7 @@ public final class CVC4SolverContext extends AbstractSolverContext { // creator is final, except after closing, then null. private CVC4FormulaCreator creator; - private final ShutdownNotifier shutdownNotifier; + private final ShutdownNotifier contextShutdownNotifier; private final int randomSeed; private CVC4SolverContext( @@ -41,7 +42,7 @@ private CVC4SolverContext( int pRandomSeed) { super(manager); this.creator = creator; - shutdownNotifier = pShutdownNotifier; + contextShutdownNotifier = pShutdownNotifier; randomSeed = pRandomSeed; } @@ -128,10 +129,12 @@ public Solvers getSolverName() { } @Override - public ProverEnvironment newProverEnvironment0(Set pOptions) { + public ProverEnvironment newProverEnvironment0( + @Nullable ShutdownNotifier pProverShutdownNotifier, Set pOptions) { return new CVC4TheoremProver( creator, - shutdownNotifier, + contextShutdownNotifier, + pProverShutdownNotifier, randomSeed, pOptions, getFormulaManager().getBooleanFormulaManager()); @@ -144,13 +147,13 @@ protected boolean supportsAssumptionSolving() { @Override protected InterpolatingProverEnvironment newProverEnvironmentWithInterpolation0( - Set pSet) { + @Nullable ShutdownNotifier pProverShutdownNotifier, Set pSet) { throw new UnsupportedOperationException("CVC4 does not support interpolation"); } @Override protected OptimizationProverEnvironment newOptimizationProverEnvironment0( - Set pSet) { + @Nullable ShutdownNotifier pProverShutdownNotifier, Set pSet) { throw new UnsupportedOperationException("CVC4 does not support optimization"); } } diff --git a/src/org/sosy_lab/java_smt/solvers/cvc4/CVC4TheoremProver.java b/src/org/sosy_lab/java_smt/solvers/cvc4/CVC4TheoremProver.java index 14e6023e3a..f1f73be532 100644 --- a/src/org/sosy_lab/java_smt/solvers/cvc4/CVC4TheoremProver.java +++ b/src/org/sosy_lab/java_smt/solvers/cvc4/CVC4TheoremProver.java @@ -23,7 +23,6 @@ import java.util.Optional; import java.util.Set; import org.checkerframework.checker.nullness.qual.Nullable; -import org.sosy_lab.common.ShutdownManager; import org.sosy_lab.common.ShutdownNotifier; import org.sosy_lab.java_smt.api.BasicProverEnvironment; import org.sosy_lab.java_smt.api.BooleanFormula; @@ -58,11 +57,12 @@ class CVC4TheoremProver extends AbstractProverWithAllSat protected CVC4TheoremProver( CVC4FormulaCreator pFormulaCreator, - ShutdownNotifier pShutdownNotifier, + ShutdownNotifier pContextShutdownNotifier, + @Nullable ShutdownNotifier pProverShutdownNotifier, int randomSeed, Set pOptions, BooleanFormulaManager pBmgr) { - super(pOptions, pBmgr, pShutdownNotifier); + super(pOptions, pBmgr, pContextShutdownNotifier, pProverShutdownNotifier); creator = pFormulaCreator; smtEngine = new SmtEngine(exprManager); @@ -173,11 +173,12 @@ protected boolean isUnsatImpl() throws InterruptedException, SolverException { } Result result; - try (ShutdownHook hook = new ShutdownHook(proverShutdownNotifier, smtEngine::interrupt)) { - proverShutdownNotifier.shutdownIfNecessary(); + try (ShutdownHook hook = + new ShutdownHook(contextShutdownNotifier, proverShutdownNotifier, smtEngine::interrupt)) { + shutdownIfNecessary(); result = smtEngine.checkSat(); } - proverShutdownNotifier.shutdownIfNecessary(); + shutdownIfNecessary(); return convertSatResult(result); } @@ -230,9 +231,4 @@ public void close() { } super.close(); } - - @Override - public ShutdownManager getShutdownManagerForProver() throws UnsupportedOperationException { - return proverShutdownManager; - } } From 3b169490fc1fc9b80d1c5f249409263a93e796ca Mon Sep 17 00:00:00 2001 From: BaierD Date: Wed, 4 Jun 2025 13:43:38 +0200 Subject: [PATCH 27/87] Add dedicated prover shutdown notifier to CVC5 implementation, but make it not usable --- .../solvers/cvc5/CVC5AbstractProver.java | 12 ++++++-- .../solvers/cvc5/CVC5InterpolatingProver.java | 17 ++++++++--- .../solvers/cvc5/CVC5SolverContext.java | 30 ++++++++++++++----- .../solvers/cvc5/CVC5TheoremProver.java | 12 ++++++-- 4 files changed, 55 insertions(+), 16 deletions(-) diff --git a/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5AbstractProver.java b/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5AbstractProver.java index bb6cfd938d..cb152c1dbd 100644 --- a/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5AbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5AbstractProver.java @@ -26,6 +26,7 @@ import java.util.List; import java.util.Optional; import java.util.Set; +import org.checkerframework.checker.nullness.qual.Nullable; import org.sosy_lab.common.ShutdownNotifier; import org.sosy_lab.common.UniqueIdGenerator; import org.sosy_lab.common.collect.PathCopyingPersistentTreeMap; @@ -51,12 +52,17 @@ abstract class CVC5AbstractProver extends AbstractProverWithAllSat { protected CVC5AbstractProver( CVC5FormulaCreator pFormulaCreator, - ShutdownNotifier pShutdownNotifier, + ShutdownNotifier pContextShutdownNotifier, + @Nullable ShutdownNotifier pProverShutdownNotifier, @SuppressWarnings("unused") int randomSeed, Set pOptions, FormulaManager pMgr, ImmutableMap pFurtherOptionsMap) { - super(pOptions, pMgr.getBooleanFormulaManager(), pShutdownNotifier); + super( + pOptions, + pMgr.getBooleanFormulaManager(), + pContextShutdownNotifier, + pProverShutdownNotifier); mgr = pMgr; creator = pFormulaCreator; @@ -177,7 +183,7 @@ public boolean isUnsatImpl() throws InterruptedException, SolverException { /* Shutdown currently not possible in CVC5. */ Result result = solver.checkSat(); - proverShutdownNotifier.shutdownIfNecessary(); + shutdownIfNecessary(); return convertSatResult(result); } diff --git a/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5InterpolatingProver.java b/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5InterpolatingProver.java index 3db0461ab3..44217c5604 100644 --- a/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5InterpolatingProver.java +++ b/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5InterpolatingProver.java @@ -25,6 +25,7 @@ import java.util.Collection; import java.util.List; import java.util.Set; +import org.checkerframework.checker.nullness.qual.Nullable; import org.sosy_lab.common.ShutdownNotifier; import org.sosy_lab.java_smt.api.BooleanFormula; import org.sosy_lab.java_smt.api.FormulaManager; @@ -46,13 +47,21 @@ public class CVC5InterpolatingProver extends CVC5AbstractProver CVC5InterpolatingProver( CVC5FormulaCreator pFormulaCreator, - ShutdownNotifier pShutdownNotifier, + ShutdownNotifier pContextShutdownNotifier, + @Nullable ShutdownNotifier pProverShutdownNotifier, int randomSeed, Set pOptions, FormulaManager pMgr, ImmutableMap pFurtherOptionsMap, boolean pValidateInterpolants) { - super(pFormulaCreator, pShutdownNotifier, randomSeed, pOptions, pMgr, pFurtherOptionsMap); + super( + pFormulaCreator, + pContextShutdownNotifier, + pProverShutdownNotifier, + randomSeed, + pOptions, + pMgr, + pFurtherOptionsMap); mgr = pMgr; solverOptions = pOptions; seed = randomSeed; @@ -84,7 +93,7 @@ protected String addConstraintImpl(BooleanFormula constraint) throws Interrupted public BooleanFormula getInterpolant(Collection pFormulasOfA) throws SolverException, InterruptedException { checkState(!closed); - proverShutdownNotifier.shutdownIfNecessary(); + shutdownIfNecessary(); checkState(!wasLastSatCheckSat); checkState(!stackChangedSinceLastQuery); checkArgument( @@ -105,7 +114,7 @@ public BooleanFormula getInterpolant(Collection pFormulasOfA) public List getSeqInterpolants(List> partitions) throws SolverException, InterruptedException { checkState(!closed); - proverShutdownNotifier.shutdownIfNecessary(); + shutdownIfNecessary(); checkState(!wasLastSatCheckSat); checkState(!stackChangedSinceLastQuery); checkArgument(!partitions.isEmpty(), "at least one partition should be available."); diff --git a/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5SolverContext.java b/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5SolverContext.java index 97e0d269b2..2d46fc0f13 100644 --- a/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5SolverContext.java +++ b/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5SolverContext.java @@ -20,6 +20,7 @@ import java.util.Map.Entry; import java.util.Set; import java.util.function.Consumer; +import org.checkerframework.checker.nullness.qual.Nullable; import org.sosy_lab.common.ShutdownNotifier; import org.sosy_lab.common.configuration.Configuration; import org.sosy_lab.common.configuration.InvalidConfigurationException; @@ -76,7 +77,7 @@ private CVC5Settings(Configuration config) throws InvalidConfigurationException private CVC5FormulaCreator creator; private final TermManager termManager; private final Solver solver; - private final ShutdownNotifier shutdownNotifier; + private final ShutdownNotifier contextShutdownNotifier; private final int randomSeed; private final CVC5Settings settings; private boolean closed = false; @@ -91,7 +92,7 @@ private CVC5SolverContext( CVC5Settings pSettings) { super(pManager); creator = pCreator; - shutdownNotifier = pShutdownNotifier; + contextShutdownNotifier = pShutdownNotifier; randomSeed = pRandomSeed; termManager = pTermManager; solver = pSolver; @@ -215,11 +216,19 @@ public Solvers getSolverName() { } @Override - public ProverEnvironment newProverEnvironment0(Set pOptions) { + public ProverEnvironment newProverEnvironment0( + @Nullable ShutdownNotifier pProverShutdownNotifier, Set pOptions) { Preconditions.checkState(!closed, "solver context is already closed"); + + if (pProverShutdownNotifier != null) { + // TODO: CVC5 does not support shutdown at all currently. Remove completely? + throw new UnsupportedOperationException("CVC5 does not support interruption of provers"); + } + return new CVC5TheoremProver( creator, - shutdownNotifier, + contextShutdownNotifier, + null, randomSeed, pOptions, getFormulaManager(), @@ -233,11 +242,18 @@ protected boolean supportsAssumptionSolving() { @Override protected InterpolatingProverEnvironment newProverEnvironmentWithInterpolation0( - Set pOptions) { + @Nullable ShutdownNotifier pProverShutdownNotifier, Set pOptions) { Preconditions.checkState(!closed, "solver context is already closed"); + + if (pProverShutdownNotifier != null) { + // TODO: CVC5 does not support shutdown at all currently. Remove completely? + throw new UnsupportedOperationException("CVC5 does not support interruption of provers"); + } + return new CVC5InterpolatingProver( creator, - shutdownNotifier, + contextShutdownNotifier, + null, randomSeed, pOptions, getFormulaManager(), @@ -247,7 +263,7 @@ protected InterpolatingProverEnvironment newProverEnvironmentWithInterpolatio @Override protected OptimizationProverEnvironment newOptimizationProverEnvironment0( - Set pSet) { + @Nullable ShutdownNotifier pProverShutdownNotifier, Set pSet) { throw new UnsupportedOperationException("CVC5 does not support optimization"); } } diff --git a/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5TheoremProver.java b/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5TheoremProver.java index cef35c500b..cb1941042f 100644 --- a/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5TheoremProver.java +++ b/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5TheoremProver.java @@ -23,12 +23,20 @@ class CVC5TheoremProver extends CVC5AbstractProver protected CVC5TheoremProver( CVC5FormulaCreator pFormulaCreator, - ShutdownNotifier pShutdownNotifier, + ShutdownNotifier pContextShutdownNotifier, + @Nullable ShutdownNotifier pProverShutdownNotifier, @SuppressWarnings("unused") int randomSeed, Set pOptions, FormulaManager pMgr, ImmutableMap pFurtherOptionsMap) { - super(pFormulaCreator, pShutdownNotifier, randomSeed, pOptions, pMgr, pFurtherOptionsMap); + super( + pFormulaCreator, + pContextShutdownNotifier, + pProverShutdownNotifier, + randomSeed, + pOptions, + pMgr, + pFurtherOptionsMap); } @Override From fa7dfb2e55f4d1a0e947f665a387c7b60468375b Mon Sep 17 00:00:00 2001 From: BaierD Date: Wed, 4 Jun 2025 13:43:51 +0200 Subject: [PATCH 28/87] Add dedicated prover shutdown notifier to MathSAT5 --- .../mathsat5/Mathsat5AbstractProver.java | 16 ++++++--------- .../mathsat5/Mathsat5InterpolatingProver.java | 10 ++++++---- .../mathsat5/Mathsat5OptimizationProver.java | 5 +++-- .../mathsat5/Mathsat5SolverContext.java | 20 +++++++++++-------- .../mathsat5/Mathsat5TheoremProver.java | 5 +++-- 5 files changed, 30 insertions(+), 26 deletions(-) diff --git a/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5AbstractProver.java b/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5AbstractProver.java index b6cc980498..3af56e98be 100644 --- a/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5AbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5AbstractProver.java @@ -42,7 +42,7 @@ import java.util.Map; import java.util.Optional; import java.util.Set; -import org.sosy_lab.common.ShutdownManager; +import org.checkerframework.checker.nullness.qual.Nullable; import org.sosy_lab.common.ShutdownNotifier; import org.sosy_lab.java_smt.api.BooleanFormula; import org.sosy_lab.java_smt.api.Evaluator; @@ -65,8 +65,9 @@ protected Mathsat5AbstractProver( Mathsat5SolverContext pContext, Set pOptions, Mathsat5FormulaCreator pCreator, - ShutdownNotifier pShutdownNotifier) { - super(pShutdownNotifier, pOptions); + ShutdownNotifier pContextShutdownNotifier, + @Nullable ShutdownNotifier pProverShutdownNotifier) { + super(pContextShutdownNotifier, pProverShutdownNotifier, pOptions); creator = pCreator; curConfig = buildConfig(pOptions); curEnv = pContext.createEnvironment(curConfig); @@ -113,7 +114,7 @@ protected boolean isUnsatImpl() throws InterruptedException, SolverException { */ private TerminationCallback getTerminationTest() { return () -> { - proverShutdownNotifier.shutdownIfNecessary(); + shutdownIfNecessary(); return false; }; } @@ -280,15 +281,10 @@ class MathsatAllSatCallback implements AllSatModelCallback { @Override public void callback(long[] model) throws InterruptedException { - proverShutdownNotifier.shutdownIfNecessary(); + shutdownIfNecessary(); clientCallback.apply( Collections.unmodifiableList( Lists.transform(Longs.asList(model), creator::encapsulateBoolean))); } } - - @Override - public ShutdownManager getShutdownManagerForProver() throws UnsupportedOperationException { - return proverShutdownManager; - } } diff --git a/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5InterpolatingProver.java b/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5InterpolatingProver.java index dcca8e5d67..cfd2c425ad 100644 --- a/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5InterpolatingProver.java +++ b/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5InterpolatingProver.java @@ -26,6 +26,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import org.checkerframework.checker.nullness.qual.Nullable; import org.sosy_lab.common.ShutdownNotifier; import org.sosy_lab.java_smt.api.BooleanFormula; import org.sosy_lab.java_smt.api.InterpolatingProverEnvironment; @@ -57,10 +58,11 @@ class Mathsat5InterpolatingProver extends Mathsat5AbstractProver Mathsat5InterpolatingProver( Mathsat5SolverContext pMgr, - ShutdownNotifier pShutdownNotifier, + ShutdownNotifier pContextShutdownNotifier, + @Nullable ShutdownNotifier pProverShutdownNotifier, Mathsat5FormulaCreator creator, Set options) { - super(pMgr, options, creator, pShutdownNotifier); + super(pMgr, options, creator, pContextShutdownNotifier, pProverShutdownNotifier); } @Override @@ -103,7 +105,7 @@ protected long getMsatModel() throws SolverException { public BooleanFormula getInterpolant(Collection formulasOfA) throws SolverException, InterruptedException { checkState(!closed); - proverShutdownNotifier.shutdownIfNecessary(); + shutdownIfNecessary(); checkState(!wasLastSatCheckSat); checkState(!stackChangedSinceLastQuery); checkArgument( @@ -133,7 +135,7 @@ public List getSeqInterpolants( List> partitionedFormulas) throws SolverException, InterruptedException { checkState(!closed); - proverShutdownNotifier.shutdownIfNecessary(); + shutdownIfNecessary(); checkState(!wasLastSatCheckSat); checkState(!stackChangedSinceLastQuery); Preconditions.checkArgument( diff --git a/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5OptimizationProver.java b/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5OptimizationProver.java index ce375fc3ea..1c6b3d4d65 100644 --- a/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5OptimizationProver.java +++ b/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5OptimizationProver.java @@ -57,10 +57,11 @@ class Mathsat5OptimizationProver extends Mathsat5AbstractProver Mathsat5OptimizationProver( Mathsat5SolverContext pMgr, - ShutdownNotifier pShutdownNotifier, + ShutdownNotifier pContextShutdownNotifier, + @Nullable ShutdownNotifier pProverShutdownNotifier, Mathsat5FormulaCreator creator, Set options) { - super(pMgr, options, creator, pShutdownNotifier); + super(pMgr, options, creator, pContextShutdownNotifier, pProverShutdownNotifier); } @Override diff --git a/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5SolverContext.java b/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5SolverContext.java index 4e107395e5..f4b97d3ecc 100644 --- a/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5SolverContext.java +++ b/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5SolverContext.java @@ -94,7 +94,7 @@ private Mathsat5Settings(Configuration config, @Nullable PathCounterTemplate pLo private final Mathsat5Settings settings; private final long randomSeed; - private final ShutdownNotifier shutdownNotifier; + private final ShutdownNotifier contextShutdownNotifier; private final Mathsat5FormulaCreator creator; private boolean closed = false; @@ -116,7 +116,7 @@ private Mathsat5SolverContext( this.mathsatConfig = mathsatConfig; this.settings = settings; this.randomSeed = randomSeed; - this.shutdownNotifier = shutdownNotifier; + this.contextShutdownNotifier = shutdownNotifier; this.creator = creator; } @@ -252,23 +252,27 @@ long createEnvironment(long cfg) { } @Override - protected ProverEnvironment newProverEnvironment0(Set options) { + protected ProverEnvironment newProverEnvironment0( + @Nullable ShutdownNotifier pProverShutdownNotifier, Set options) { Preconditions.checkState(!closed, "solver context is already closed"); - return new Mathsat5TheoremProver(this, shutdownNotifier, creator, options); + return new Mathsat5TheoremProver( + this, contextShutdownNotifier, pProverShutdownNotifier, creator, options); } @Override protected InterpolatingProverEnvironment newProverEnvironmentWithInterpolation0( - Set options) { + @Nullable ShutdownNotifier pProverShutdownNotifier, Set options) { Preconditions.checkState(!closed, "solver context is already closed"); - return new Mathsat5InterpolatingProver(this, shutdownNotifier, creator, options); + return new Mathsat5InterpolatingProver( + this, contextShutdownNotifier, pProverShutdownNotifier, creator, options); } @Override public OptimizationProverEnvironment newOptimizationProverEnvironment0( - Set options) { + @Nullable ShutdownNotifier pProverShutdownNotifier, Set options) { Preconditions.checkState(!closed, "solver context is already closed"); - return new Mathsat5OptimizationProver(this, shutdownNotifier, creator, options); + return new Mathsat5OptimizationProver( + this, contextShutdownNotifier, pProverShutdownNotifier, creator, options); } @Override diff --git a/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5TheoremProver.java b/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5TheoremProver.java index 4801c5904f..ebc9419e48 100644 --- a/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5TheoremProver.java +++ b/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5TheoremProver.java @@ -24,10 +24,11 @@ class Mathsat5TheoremProver extends Mathsat5AbstractProver implements Prov Mathsat5TheoremProver( Mathsat5SolverContext pMgr, - ShutdownNotifier pShutdownNotifier, + ShutdownNotifier pContextShutdownNotifier, + @Nullable ShutdownNotifier pProverShutdownNotifier, Mathsat5FormulaCreator creator, Set options) { - super(pMgr, options, creator, pShutdownNotifier); + super(pMgr, options, creator, pContextShutdownNotifier, pProverShutdownNotifier); } @Override From 37a58eec94563a84717d02e890a3b8667d8280c7 Mon Sep 17 00:00:00 2001 From: BaierD Date: Wed, 4 Jun 2025 13:43:58 +0200 Subject: [PATCH 29/87] Add dedicated prover shutdown notifier to OpenSMT2 --- .../opensmt/OpenSmtAbstractProver.java | 22 +++++++++---------- .../opensmt/OpenSmtInterpolatingProver.java | 9 +++++--- .../solvers/opensmt/OpenSmtSolverContext.java | 22 +++++++++++++++---- .../solvers/opensmt/OpenSmtTheoremProver.java | 7 ++++-- 4 files changed, 40 insertions(+), 20 deletions(-) diff --git a/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtAbstractProver.java b/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtAbstractProver.java index 683f38e88b..c976b3210c 100644 --- a/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtAbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtAbstractProver.java @@ -19,7 +19,6 @@ import java.util.Optional; import java.util.Set; import org.checkerframework.checker.nullness.qual.Nullable; -import org.sosy_lab.common.ShutdownManager; import org.sosy_lab.common.ShutdownNotifier; import org.sosy_lab.java_smt.api.BooleanFormula; import org.sosy_lab.java_smt.api.Evaluator; @@ -49,10 +48,15 @@ public abstract class OpenSmtAbstractProver extends AbstractProverWithAllSat< protected OpenSmtAbstractProver( OpenSmtFormulaCreator pFormulaCreator, FormulaManager pMgr, - ShutdownNotifier pShutdownNotifier, + ShutdownNotifier pContextShutdownNotifier, + @Nullable ShutdownNotifier pProverShutdownNotifier, SMTConfig pConfig, Set pOptions) { - super(pOptions, pMgr.getBooleanFormulaManager(), pShutdownNotifier); + super( + pOptions, + pMgr.getBooleanFormulaManager(), + pContextShutdownNotifier, + pProverShutdownNotifier); creator = pFormulaCreator; @@ -204,8 +208,9 @@ protected String getReasonFromSolverFeatures( protected boolean isUnsatImpl() throws InterruptedException, SolverException { sstat result; - try (ShutdownHook listener = new ShutdownHook(proverShutdownNotifier, osmtSolver::stop)) { - proverShutdownNotifier.shutdownIfNecessary(); + try (ShutdownHook listener = + new ShutdownHook(contextShutdownNotifier, proverShutdownNotifier, osmtSolver::stop)) { + shutdownIfNecessary(); try { result = osmtSolver.check(); } catch (Exception e) { @@ -224,7 +229,7 @@ protected boolean isUnsatImpl() throws InterruptedException, SolverException { throw new SolverException("OpenSMT crashed while checking satisfiability.", e); } } - proverShutdownNotifier.shutdownIfNecessary(); + shutdownIfNecessary(); } if (result.equals(sstat.Error())) { @@ -262,9 +267,4 @@ public void close() { } super.close(); } - - @Override - public ShutdownManager getShutdownManagerForProver() throws UnsupportedOperationException { - return proverShutdownManager; - } } diff --git a/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtInterpolatingProver.java b/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtInterpolatingProver.java index 589a375e18..0cf242311d 100644 --- a/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtInterpolatingProver.java +++ b/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtInterpolatingProver.java @@ -18,6 +18,7 @@ import java.util.Deque; import java.util.List; import java.util.Set; +import org.checkerframework.checker.nullness.qual.Nullable; import org.sosy_lab.common.ShutdownNotifier; import org.sosy_lab.java_smt.api.BooleanFormula; import org.sosy_lab.java_smt.api.FormulaManager; @@ -40,13 +41,15 @@ class OpenSmtInterpolatingProver extends OpenSmtAbstractProver OpenSmtInterpolatingProver( OpenSmtFormulaCreator pFormulaCreator, FormulaManager pMgr, - ShutdownNotifier pShutdownNotifier, + ShutdownNotifier pContextShutdownNotifier, + @Nullable ShutdownNotifier pProverShutdownNotifier, Set pOptions, OpenSMTOptions pSolverOptions) { super( pFormulaCreator, pMgr, - pShutdownNotifier, + pContextShutdownNotifier, + pProverShutdownNotifier, getConfigInstance(pOptions, pSolverOptions, true), pOptions); trackedConstraints.push(0); // initialize first level @@ -76,7 +79,7 @@ protected void popImpl() { public BooleanFormula getInterpolant(Collection formulasOfA) throws InterruptedException { checkState(!closed); - proverShutdownNotifier.shutdownIfNecessary(); + shutdownIfNecessary(); checkState(!wasLastSatCheckSat); checkState(!stackChangedSinceLastQuery); checkArgument( diff --git a/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtSolverContext.java b/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtSolverContext.java index cc525d7c5b..33e210d42f 100644 --- a/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtSolverContext.java +++ b/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtSolverContext.java @@ -11,6 +11,7 @@ import com.google.common.base.Preconditions; import java.util.Set; import java.util.function.Consumer; +import org.checkerframework.checker.nullness.qual.Nullable; import org.sosy_lab.common.ShutdownNotifier; import org.sosy_lab.common.configuration.Configuration; import org.sosy_lab.common.configuration.InvalidConfigurationException; @@ -33,7 +34,7 @@ public final class OpenSmtSolverContext extends AbstractSolverContext { @SuppressWarnings("unused") private final LogManager logger; - private final ShutdownNotifier shutdownNotifier; + private final ShutdownNotifier contextShutdownNotifier; private final OpenSMTOptions solverOptions; private boolean closed = false; @@ -72,7 +73,7 @@ private OpenSmtSolverContext( creator = pCreator; manager = pManager; logger = pLogger; - shutdownNotifier = pShutdownNotifier; + contextShutdownNotifier = pShutdownNotifier; solverOptions = pSolverOptions; } @@ -130,24 +131,37 @@ public String getVersion() { @Override protected OptimizationProverEnvironment newOptimizationProverEnvironment0( + @Nullable ShutdownNotifier pProverShutdownNotifier, Set options) { throw new UnsupportedOperationException("OpenSMT does not support optimization."); } @Override protected ProverEnvironment newProverEnvironment0( + @Nullable ShutdownNotifier pProverShutdownNotifier, Set pProverOptions) { Preconditions.checkState(!closed, "solver context is already closed"); return new OpenSmtTheoremProver( - creator, manager, shutdownNotifier, pProverOptions, solverOptions); + creator, + manager, + contextShutdownNotifier, + pProverShutdownNotifier, + pProverOptions, + solverOptions); } @Override protected InterpolatingProverEnvironment newProverEnvironmentWithInterpolation0( + @Nullable ShutdownNotifier pProverShutdownNotifier, Set pProverOptions) { Preconditions.checkState(!closed, "solver context is already closed"); return new OpenSmtInterpolatingProver( - creator, manager, shutdownNotifier, pProverOptions, solverOptions); + creator, + manager, + contextShutdownNotifier, + pProverShutdownNotifier, + pProverOptions, + solverOptions); } @Override diff --git a/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtTheoremProver.java b/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtTheoremProver.java index bcfaba9098..1f17e37946 100644 --- a/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtTheoremProver.java +++ b/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtTheoremProver.java @@ -9,6 +9,7 @@ package org.sosy_lab.java_smt.solvers.opensmt; import java.util.Set; +import org.checkerframework.checker.nullness.qual.Nullable; import org.sosy_lab.common.ShutdownNotifier; import org.sosy_lab.java_smt.api.FormulaManager; import org.sosy_lab.java_smt.api.ProverEnvironment; @@ -21,13 +22,15 @@ class OpenSmtTheoremProver extends OpenSmtAbstractProver implements Prover OpenSmtTheoremProver( OpenSmtFormulaCreator pFormulaCreator, FormulaManager pMgr, - ShutdownNotifier pShutdownNotifier, + ShutdownNotifier pContextShutdownNotifier, + @Nullable ShutdownNotifier pProverShutdownNotifier, Set pOptions, OpenSMTOptions pSolverOptions) { super( pFormulaCreator, pMgr, - pShutdownNotifier, + pContextShutdownNotifier, + pProverShutdownNotifier, getConfigInstance(pOptions, pSolverOptions, false), pOptions); } From 3538fdcffb4eb83bdcf9e236279a5ba81c421b02 Mon Sep 17 00:00:00 2001 From: BaierD Date: Wed, 4 Jun 2025 13:44:14 +0200 Subject: [PATCH 30/87] Add dedicated prover shutdown notifier to Princess but make it not usable as it does not support shutdown --- .../princess/PrincessAbstractProver.java | 10 ++++++++-- .../solvers/princess/PrincessEnvironment.java | 13 ++++++++----- .../princess/PrincessInterpolatingProver.java | 6 ++++-- .../solvers/princess/PrincessSolverContext.java | 17 ++++++++++++++--- .../solvers/princess/PrincessTheoremProver.java | 5 +++-- 5 files changed, 37 insertions(+), 14 deletions(-) diff --git a/src/org/sosy_lab/java_smt/solvers/princess/PrincessAbstractProver.java b/src/org/sosy_lab/java_smt/solvers/princess/PrincessAbstractProver.java index ffdb6353aa..f00921f9dd 100644 --- a/src/org/sosy_lab/java_smt/solvers/princess/PrincessAbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/princess/PrincessAbstractProver.java @@ -29,6 +29,7 @@ import java.util.List; import java.util.Optional; import java.util.Set; +import org.checkerframework.checker.nullness.qual.Nullable; import org.sosy_lab.common.ShutdownNotifier; import org.sosy_lab.common.UniqueIdGenerator; import org.sosy_lab.common.collect.PathCopyingPersistentTreeMap; @@ -68,9 +69,14 @@ protected PrincessAbstractProver( PrincessFormulaManager pMgr, PrincessFormulaCreator creator, SimpleAPI pApi, - ShutdownNotifier pShutdownNotifier, + ShutdownNotifier pContextShutdownNotifier, + @Nullable ShutdownNotifier pProverShutdownNotifier, Set pOptions) { - super(pOptions, pMgr.getBooleanFormulaManager(), pShutdownNotifier); + super( + pOptions, + pMgr.getBooleanFormulaManager(), + pContextShutdownNotifier, + pProverShutdownNotifier); this.mgr = pMgr; this.creator = creator; this.api = checkNotNull(pApi); diff --git a/src/org/sosy_lab/java_smt/solvers/princess/PrincessEnvironment.java b/src/org/sosy_lab/java_smt/solvers/princess/PrincessEnvironment.java index 61a42339c3..2fc96218fb 100644 --- a/src/org/sosy_lab/java_smt/solvers/princess/PrincessEnvironment.java +++ b/src/org/sosy_lab/java_smt/solvers/princess/PrincessEnvironment.java @@ -179,7 +179,7 @@ class PrincessEnvironment { private final int randomSeed; private final @Nullable PathCounterTemplate basicLogfile; - private final ShutdownNotifier shutdownNotifier; + private final ShutdownNotifier contextShutdownNotifier; /** * The wrapped API is the first created API. It will never be used outside this class and never be @@ -199,7 +199,7 @@ class PrincessEnvironment { config.inject(this); basicLogfile = pBasicLogfile; - shutdownNotifier = pShutdownNotifier; + contextShutdownNotifier = pShutdownNotifier; randomSeed = pRandomSeed; // this api is only used local in this environment, no need for interpolation @@ -226,9 +226,12 @@ PrincessAbstractProver getNewProver( PrincessAbstractProver prover; if (useForInterpolation) { - prover = new PrincessInterpolatingProver(mgr, creator, newApi, shutdownNotifier, pOptions); + prover = + new PrincessInterpolatingProver( + mgr, creator, newApi, contextShutdownNotifier, null, pOptions); } else { - prover = new PrincessTheoremProver(mgr, creator, newApi, shutdownNotifier, pOptions); + prover = + new PrincessTheoremProver(mgr, creator, newApi, contextShutdownNotifier, null, pOptions); } registeredProvers.add(prover); return prover; @@ -403,7 +406,7 @@ public void appendTo(Appendable out) throws IOException { appendTo0(out); } catch (scala.MatchError e) { // exception might be thrown in case of interrupt, then we wrap it in an interrupt. - if (shutdownNotifier.shouldShutdown()) { + if (contextShutdownNotifier.shouldShutdown()) { InterruptedException interrupt = new InterruptedException(); interrupt.addSuppressed(e); throwCheckedAsUnchecked(interrupt); diff --git a/src/org/sosy_lab/java_smt/solvers/princess/PrincessInterpolatingProver.java b/src/org/sosy_lab/java_smt/solvers/princess/PrincessInterpolatingProver.java index f29354ae77..37fa04b726 100644 --- a/src/org/sosy_lab/java_smt/solvers/princess/PrincessInterpolatingProver.java +++ b/src/org/sosy_lab/java_smt/solvers/princess/PrincessInterpolatingProver.java @@ -29,6 +29,7 @@ import java.util.Deque; import java.util.List; import java.util.Set; +import org.checkerframework.checker.nullness.qual.Nullable; import org.sosy_lab.common.ShutdownNotifier; import org.sosy_lab.java_smt.api.BooleanFormula; import org.sosy_lab.java_smt.api.InterpolatingProverEnvironment; @@ -44,9 +45,10 @@ class PrincessInterpolatingProver extends PrincessAbstractProver PrincessFormulaManager pMgr, PrincessFormulaCreator creator, SimpleAPI pApi, - ShutdownNotifier pShutdownNotifier, + ShutdownNotifier pContextShutdownNotifier, + @Nullable ShutdownNotifier pProverShutdownNotifier, Set pOptions) { - super(pMgr, creator, pApi, pShutdownNotifier, pOptions); + super(pMgr, creator, pApi, pContextShutdownNotifier, pProverShutdownNotifier, pOptions); } @Override diff --git a/src/org/sosy_lab/java_smt/solvers/princess/PrincessSolverContext.java b/src/org/sosy_lab/java_smt/solvers/princess/PrincessSolverContext.java index bb7b14d6f8..fc6beaceed 100644 --- a/src/org/sosy_lab/java_smt/solvers/princess/PrincessSolverContext.java +++ b/src/org/sosy_lab/java_smt/solvers/princess/PrincessSolverContext.java @@ -74,7 +74,13 @@ public static SolverContext create( @SuppressWarnings("resource") @Override - protected ProverEnvironment newProverEnvironment0(Set options) { + protected ProverEnvironment newProverEnvironment0( + @Nullable ShutdownNotifier pProverShutdownNotifier, Set options) { + + if (pProverShutdownNotifier != null) { + throw new UnsupportedOperationException("Shutdown is not supported for Princess."); + } + if (options.contains(ProverOptions.GENERATE_UNSAT_CORE_OVER_ASSUMPTIONS)) { throw new UnsupportedOperationException( "Princess does not support unsat core generation with assumptions yet"); @@ -85,14 +91,19 @@ protected ProverEnvironment newProverEnvironment0(Set options) { @SuppressWarnings("resource") @Override protected InterpolatingProverEnvironment newProverEnvironmentWithInterpolation0( - Set options) { + @Nullable ShutdownNotifier pProverShutdownNotifier, Set options) { + + if (pProverShutdownNotifier != null) { + throw new UnsupportedOperationException("Shutdown is not supported for Princess."); + } + return (PrincessInterpolatingProver) creator.getEnv().getNewProver(true, manager, creator, options); } @Override public OptimizationProverEnvironment newOptimizationProverEnvironment0( - Set options) { + @Nullable ShutdownNotifier pProverShutdownNotifier, Set options) { throw new UnsupportedOperationException("Princess does not support optimization"); } diff --git a/src/org/sosy_lab/java_smt/solvers/princess/PrincessTheoremProver.java b/src/org/sosy_lab/java_smt/solvers/princess/PrincessTheoremProver.java index ab087b3389..84e9b6f732 100644 --- a/src/org/sosy_lab/java_smt/solvers/princess/PrincessTheoremProver.java +++ b/src/org/sosy_lab/java_smt/solvers/princess/PrincessTheoremProver.java @@ -22,9 +22,10 @@ class PrincessTheoremProver extends PrincessAbstractProver implements Prov PrincessFormulaManager pMgr, PrincessFormulaCreator creator, SimpleAPI pApi, - ShutdownNotifier pShutdownNotifier, + ShutdownNotifier pContextShutdownNotifier, + @Nullable ShutdownNotifier pProverShutdownNotifier, Set pOptions) { - super(pMgr, creator, pApi, pShutdownNotifier, pOptions); + super(pMgr, creator, pApi, pContextShutdownNotifier, pProverShutdownNotifier, pOptions); } @Override From 9e6d0ba54cc878856cf57a4e4ac32ff5eafe74a5 Mon Sep 17 00:00:00 2001 From: BaierD Date: Wed, 4 Jun 2025 13:44:38 +0200 Subject: [PATCH 31/87] Add dedicated prover shutdown notifier to SMTInterpol but make it not usable as we don't know if it works yet --- .../SmtInterpolAbstractProver.java | 14 ++++---- .../SmtInterpolInterpolatingProver.java | 12 ++++--- .../smtinterpol/SmtInterpolSolverContext.java | 36 ++++++++++++++----- .../smtinterpol/SmtInterpolTheoremProver.java | 5 +-- 4 files changed, 45 insertions(+), 22 deletions(-) diff --git a/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolAbstractProver.java b/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolAbstractProver.java index 616aee3eb7..829b414b67 100644 --- a/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolAbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolAbstractProver.java @@ -32,6 +32,7 @@ import java.util.Map; import java.util.Optional; import java.util.Set; +import org.checkerframework.checker.nullness.qual.Nullable; import org.sosy_lab.common.ShutdownNotifier; import org.sosy_lab.common.UniqueIdGenerator; import org.sosy_lab.common.collect.Collections3; @@ -61,8 +62,9 @@ abstract class SmtInterpolAbstractProver extends AbstractProver { SmtInterpolFormulaManager pMgr, Script pEnv, Set options, - ShutdownNotifier pShutdownNotifier) { - super(pShutdownNotifier, options); + ShutdownNotifier pContextShutdownNotifier, + @Nullable ShutdownNotifier pProverShutdownNotifier) { + super(pContextShutdownNotifier, pProverShutdownNotifier, options); mgr = pMgr; creator = pMgr.getFormulaCreator(); env = pEnv; @@ -107,7 +109,7 @@ protected boolean isUnsatImpl() throws InterruptedException { // by using a shutdown listener. However, SmtInterpol resets the // mStopEngine flag in DPLLEngine before starting to solve, // so we check here, too. - proverShutdownNotifier.shutdownIfNecessary(); + shutdownIfNecessary(); LBool result = env.checkSat(); switch (result) { @@ -125,9 +127,7 @@ protected boolean isUnsatImpl() throws InterruptedException { // SMTInterpol catches OOM, but we want to have it thrown. throw new OutOfMemoryError("Out of memory during SMTInterpol operation"); case CANCELLED: - proverShutdownManager - .getNotifier() - .shutdownIfNecessary(); // expected if we requested termination + shutdownIfNecessary(); // expected if we requested termination throw new SMTLIBException("checkSat returned UNKNOWN with unexpected reason " + reason); default: throw new SMTLIBException("checkSat returned UNKNOWN with unexpected reason " + reason); @@ -238,7 +238,7 @@ public R allSat(AllSatCallback callback, List important) // by using a shutdown listener. However, SmtInterpol resets the // mStopEngine flag in DPLLEngine before starting to solve, // so we check here, too. - proverShutdownNotifier.shutdownIfNecessary(); + shutdownIfNecessary(); for (Term[] model : env.checkAllsat(importantTerms)) { callback.apply(Collections3.transformedImmutableListCopy(model, creator::encapsulateBoolean)); } diff --git a/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolInterpolatingProver.java b/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolInterpolatingProver.java index 843b0c0f90..8726d9b6c9 100644 --- a/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolInterpolatingProver.java +++ b/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolInterpolatingProver.java @@ -23,6 +23,7 @@ import java.util.Collection; import java.util.List; import java.util.Set; +import org.checkerframework.checker.nullness.qual.Nullable; import org.sosy_lab.common.ShutdownNotifier; import org.sosy_lab.java_smt.api.BooleanFormula; import org.sosy_lab.java_smt.api.InterpolatingProverEnvironment; @@ -36,8 +37,9 @@ class SmtInterpolInterpolatingProver extends SmtInterpolAbstractProver SmtInterpolFormulaManager pMgr, Script pScript, Set options, - ShutdownNotifier pShutdownNotifier) { - super(pMgr, pScript, options, pShutdownNotifier); + ShutdownNotifier pContextShutdownNotifier, + @Nullable ShutdownNotifier pProverShutdownNotifier) { + super(pMgr, pScript, options, pContextShutdownNotifier, pProverShutdownNotifier); } @Override @@ -49,7 +51,7 @@ protected String addConstraintImpl(BooleanFormula constraint) throws Interrupted public BooleanFormula getInterpolant(Collection pTermNamesOfA) throws SolverException, InterruptedException { checkState(!closed); - proverShutdownNotifier.shutdownIfNecessary(); + shutdownIfNecessary(); checkState(!wasLastSatCheckSat); checkState(!stackChangedSinceLastQuery); checkArgument( @@ -79,7 +81,7 @@ public List getTreeInterpolants( List> partitionedTermNames, int[] startOfSubTree) throws SolverException, InterruptedException { checkState(!closed); - proverShutdownNotifier.shutdownIfNecessary(); + shutdownIfNecessary(); checkState(!wasLastSatCheckSat); checkState(!stackChangedSinceLastQuery); final ImmutableSet assertedConstraintIds = getAssertedConstraintIds(); @@ -107,7 +109,7 @@ public List getTreeInterpolants( } } catch (SMTLIBException e) { if ("Timeout exceeded".equals(e.getMessage())) { - proverShutdownNotifier.shutdownIfNecessary(); + shutdownIfNecessary(); } throw new AssertionError(e); } diff --git a/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolSolverContext.java b/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolSolverContext.java index 80f6a0e9c6..eacd71d1b9 100644 --- a/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolSolverContext.java +++ b/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolSolverContext.java @@ -92,7 +92,7 @@ private SmtInterpolSettings( } private final SmtInterpolSettings settings; - private final ShutdownNotifier shutdownNotifier; + private final ShutdownNotifier contextShutdownNotifier; private final SmtInterpolFormulaManager manager; private SmtInterpolSolverContext( @@ -101,7 +101,7 @@ private SmtInterpolSolverContext( SmtInterpolSettings pSettings) { super(pManager); settings = pSettings; - shutdownNotifier = checkNotNull(pShutdownNotifier); + contextShutdownNotifier = checkNotNull(pShutdownNotifier); manager = pManager; } @@ -226,26 +226,46 @@ private SMTInterpol getSmtInterpol() { @SuppressWarnings("resource") @Override - protected ProverEnvironment newProverEnvironment0(Set options) { + protected ProverEnvironment newProverEnvironment0( + @Nullable ShutdownNotifier pProverShutdownNotifier, Set options) { + + if (pProverShutdownNotifier != null) { + // TODO: check re-usability of SMTInterpol after shutdown. + throw new UnsupportedOperationException( + "Isolated prover shutdown is not supported for " + + "SMTInterpol. Please use the context-bound ShutdownNotifier instead."); + } + Script newScript = createNewScript(options); - return new SmtInterpolTheoremProver(manager, newScript, options, shutdownNotifier); + return new SmtInterpolTheoremProver(manager, newScript, options, contextShutdownNotifier, null); } @SuppressWarnings("resource") @Override protected InterpolatingProverEnvironment newProverEnvironmentWithInterpolation0( - Set options) { + @Nullable ShutdownNotifier pProverShutdownNotifier, Set options) { + + if (pProverShutdownNotifier != null) { + // TODO: check re-usability of SMTInterpol after shutdown. + throw new UnsupportedOperationException( + "Isolated prover shutdown is not supported for " + + "SMTInterpol. Please use the context-bound ShutdownNotifier instead."); + } + Script newScript = createNewScript(options); final SmtInterpolInterpolatingProver prover; if (settings.smtLogfile == null) { - prover = new SmtInterpolInterpolatingProver(manager, newScript, options, shutdownNotifier); + prover = + new SmtInterpolInterpolatingProver( + manager, newScript, options, contextShutdownNotifier, null); } else { prover = new LoggingSmtInterpolInterpolatingProver( manager, newScript, options, - shutdownNotifier, + contextShutdownNotifier, + null, settings.optionsMap, settings.smtLogfile.getFreshPath()); } @@ -254,7 +274,7 @@ protected InterpolatingProverEnvironment newProverEnvironmentWithInterpolatio @Override public OptimizationProverEnvironment newOptimizationProverEnvironment0( - Set options) { + @Nullable ShutdownNotifier pProverShutdownNotifier, Set options) { throw new UnsupportedOperationException("SMTInterpol does not support optimization"); } diff --git a/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolTheoremProver.java b/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolTheoremProver.java index bfb524f0a4..79af10f648 100644 --- a/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolTheoremProver.java +++ b/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolTheoremProver.java @@ -23,8 +23,9 @@ class SmtInterpolTheoremProver extends SmtInterpolAbstractProver SmtInterpolFormulaManager pMgr, Script pEnv, Set options, - ShutdownNotifier pShutdownNotifier) { - super(pMgr, pEnv, options, pShutdownNotifier); + ShutdownNotifier pContextShutdownNotifier, + @Nullable ShutdownNotifier pProverShutdownNotifier) { + super(pMgr, pEnv, options, pContextShutdownNotifier, pProverShutdownNotifier); } @Override From 02bdda972d5f5c4c5f4d99ba20909a5d58cfac8b Mon Sep 17 00:00:00 2001 From: BaierD Date: Wed, 4 Jun 2025 13:44:48 +0200 Subject: [PATCH 32/87] Add dedicated prover shutdown notifier to Yices2 --- .../solvers/yices2/Yices2NativeApi.java | 41 +++++++++++++++---- .../solvers/yices2/Yices2SolverContext.java | 15 ++++--- .../solvers/yices2/Yices2TheoremProver.java | 16 ++++---- 3 files changed, 49 insertions(+), 23 deletions(-) diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApi.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApi.java index d642fd74e3..2e770dc042 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApi.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApi.java @@ -9,6 +9,7 @@ package org.sosy_lab.java_smt.solvers.yices2; import java.util.function.Supplier; +import org.checkerframework.checker.nullness.qual.Nullable; import org.sosy_lab.common.ShutdownNotifier; import org.sosy_lab.java_smt.basicimpl.ShutdownHook; @@ -656,34 +657,58 @@ public static native int yices_check_context_with_assumptions( /** * @param params Set to 0 for default search parameters. */ - public static boolean yices_check_sat(long ctx, long params, ShutdownNotifier shutdownNotifier) + public static boolean yices_check_sat( + long ctx, + long params, + ShutdownNotifier contextShutdownNotifier, + @Nullable ShutdownNotifier proverShutdownNotifier) throws IllegalStateException, InterruptedException { return satCheckWithShutdownNotifier( - () -> yices_check_context(ctx, params), ctx, shutdownNotifier); + () -> yices_check_context(ctx, params), + ctx, + contextShutdownNotifier, + proverShutdownNotifier); } /** * @param params Set to 0 for default search parameters. */ public static boolean yices_check_sat_with_assumptions( - long ctx, long params, int size, int[] assumptions, ShutdownNotifier shutdownNotifier) + long ctx, + long params, + int size, + int[] assumptions, + ShutdownNotifier contextShutdownNotifier, + @Nullable ShutdownNotifier proverShutdownNotifier) throws InterruptedException { return satCheckWithShutdownNotifier( () -> yices_check_context_with_assumptions(ctx, params, size, assumptions), ctx, - shutdownNotifier); + contextShutdownNotifier, + proverShutdownNotifier); } @SuppressWarnings("try") private static boolean satCheckWithShutdownNotifier( - Supplier satCheck, long pCtx, ShutdownNotifier shutdownNotifier) + Supplier satCheck, + long pCtx, + ShutdownNotifier contextShutdownNotifier, + @Nullable ShutdownNotifier proverShutdownNotifier) throws InterruptedException { int result; - try (ShutdownHook hook = new ShutdownHook(shutdownNotifier, () -> yices_stop_search(pCtx))) { - shutdownNotifier.shutdownIfNecessary(); + try (ShutdownHook hook = + new ShutdownHook( + contextShutdownNotifier, proverShutdownNotifier, () -> yices_stop_search(pCtx))) { + contextShutdownNotifier.shutdownIfNecessary(); + if (proverShutdownNotifier != null) { + proverShutdownNotifier.shutdownIfNecessary(); + } result = satCheck.get(); // the expensive computation } - shutdownNotifier.shutdownIfNecessary(); + if (proverShutdownNotifier != null) { + proverShutdownNotifier.shutdownIfNecessary(); + } + contextShutdownNotifier.shutdownIfNecessary(); return check_result(result); } diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2SolverContext.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2SolverContext.java index 2b8a12c3f4..613d75144c 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2SolverContext.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2SolverContext.java @@ -16,6 +16,7 @@ import java.util.Set; import java.util.function.Consumer; +import org.checkerframework.checker.nullness.qual.Nullable; import org.sosy_lab.common.ShutdownNotifier; import org.sosy_lab.java_smt.SolverContextFactory.Solvers; import org.sosy_lab.java_smt.api.BooleanFormulaManager; @@ -30,7 +31,7 @@ public class Yices2SolverContext extends AbstractSolverContext { private final Yices2FormulaCreator creator; private final BooleanFormulaManager bfmgr; - private final ShutdownNotifier shutdownManager; + private final ShutdownNotifier contextShutdownManager; private static int numLoadedInstances = 0; private boolean closed = false; @@ -43,7 +44,7 @@ public Yices2SolverContext( super(pFmgr); this.creator = creator; bfmgr = pBfmgr; - shutdownManager = pShutdownManager; + contextShutdownManager = pShutdownManager; } public static Yices2SolverContext create( @@ -110,19 +111,21 @@ public synchronized void close() { } @Override - protected ProverEnvironment newProverEnvironment0(Set pOptions) { - return new Yices2TheoremProver(creator, pOptions, bfmgr, shutdownManager); + protected ProverEnvironment newProverEnvironment0( + @Nullable ShutdownNotifier pProverShutdownNotifier, Set pOptions) { + return new Yices2TheoremProver( + creator, pOptions, bfmgr, contextShutdownManager, pProverShutdownNotifier); } @Override protected InterpolatingProverEnvironment newProverEnvironmentWithInterpolation0( - Set pSet) { + @Nullable ShutdownNotifier pProverShutdownNotifier, Set pSet) { throw new UnsupportedOperationException("Yices does not support interpolation"); } @Override protected OptimizationProverEnvironment newOptimizationProverEnvironment0( - Set pSet) { + @Nullable ShutdownNotifier pProverShutdownNotifier, Set pSet) { throw new UnsupportedOperationException("Yices does not support optimization"); } diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2TheoremProver.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2TheoremProver.java index 773279396e..4cb4a21016 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2TheoremProver.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2TheoremProver.java @@ -32,7 +32,6 @@ import java.util.Set; import java.util.stream.Collectors; import org.checkerframework.checker.nullness.qual.Nullable; -import org.sosy_lab.common.ShutdownManager; import org.sosy_lab.common.ShutdownNotifier; import org.sosy_lab.java_smt.api.BooleanFormula; import org.sosy_lab.java_smt.api.BooleanFormulaManager; @@ -72,8 +71,9 @@ protected Yices2TheoremProver( Yices2FormulaCreator creator, Set pOptions, BooleanFormulaManager pBmgr, - ShutdownNotifier pShutdownNotifier) { - super(pOptions, pBmgr, pShutdownNotifier); + ShutdownNotifier pContextShutdownNotifier, + @Nullable ShutdownNotifier pProverShutdownNotifier) { + super(pOptions, pBmgr, pContextShutdownNotifier, pProverShutdownNotifier); this.creator = creator; curCfg = yices_new_config(); yices_set_config(curCfg, "solver-type", "dpllt"); @@ -129,9 +129,11 @@ protected boolean isUnsatImpl() throws SolverException, InterruptedException { DEFAULT_PARAMS, allConstraints.length, allConstraints, + contextShutdownNotifier, proverShutdownNotifier); } else { - unsat = !yices_check_sat(curEnv, DEFAULT_PARAMS, proverShutdownNotifier); + unsat = + !yices_check_sat(curEnv, DEFAULT_PARAMS, contextShutdownNotifier, proverShutdownNotifier); if (unsat && stackSizeToUnsat == Integer.MAX_VALUE) { stackSizeToUnsat = size(); // If sat check is UNSAT and stackSizeToUnsat waS not already set, @@ -156,6 +158,7 @@ protected boolean isUnsatWithAssumptionsImpl(Collection pAssumpt DEFAULT_PARAMS, pAssumptions.size(), uncapsulate(pAssumptions), + contextShutdownNotifier, proverShutdownNotifier); } @@ -212,9 +215,4 @@ public void close() { } super.close(); } - - @Override - public ShutdownManager getShutdownManagerForProver() throws UnsupportedOperationException { - return proverShutdownManager; - } } From 30a74ddfdd74ddc83e746a59443639d026d572d1 Mon Sep 17 00:00:00 2001 From: BaierD Date: Wed, 4 Jun 2025 13:44:57 +0200 Subject: [PATCH 33/87] Add dedicated prover shutdown notifier to Z3 --- .../java_smt/solvers/z3/Z3AbstractProver.java | 19 ++++++------ .../java_smt/solvers/z3/Z3FormulaCreator.java | 21 ++++++++----- .../java_smt/solvers/z3/Z3FormulaManager.java | 2 +- .../sosy_lab/java_smt/solvers/z3/Z3Model.java | 6 ++-- .../solvers/z3/Z3OptimizationProver.java | 13 ++++---- .../java_smt/solvers/z3/Z3SolverContext.java | 30 ++++++++++++++----- .../java_smt/solvers/z3/Z3TheoremProver.java | 25 ++++++++++------ 7 files changed, 72 insertions(+), 44 deletions(-) diff --git a/src/org/sosy_lab/java_smt/solvers/z3/Z3AbstractProver.java b/src/org/sosy_lab/java_smt/solvers/z3/Z3AbstractProver.java index 963da37f8c..001c5c59b2 100644 --- a/src/org/sosy_lab/java_smt/solvers/z3/Z3AbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/z3/Z3AbstractProver.java @@ -25,7 +25,6 @@ import java.util.Optional; import java.util.Set; import org.checkerframework.checker.nullness.qual.Nullable; -import org.sosy_lab.common.ShutdownManager; import org.sosy_lab.common.ShutdownNotifier; import org.sosy_lab.common.UniqueIdGenerator; import org.sosy_lab.common.collect.PathCopyingPersistentTreeMap; @@ -54,8 +53,13 @@ abstract class Z3AbstractProver extends AbstractProverWithAllSat { Z3FormulaManager pMgr, Set pOptions, @Nullable PathCounterTemplate pLogfile, - ShutdownNotifier pShutdownNotifier) { - super(pOptions, pMgr.getBooleanFormulaManager(), pShutdownNotifier); + ShutdownNotifier pContextShutdownNotifier, + @Nullable ShutdownNotifier pProverShutdownNotifier) { + super( + pOptions, + pMgr.getBooleanFormulaManager(), + pContextShutdownNotifier, + pProverShutdownNotifier); creator = pCreator; z3context = creator.getEnv(); @@ -135,7 +139,7 @@ protected Void addConstraintImpl(BooleanFormula f) throws InterruptedException { assertContraint(e); } } catch (Z3Exception exception) { - throw creator.handleZ3ExceptionAsRuntimeException(exception); + throw creator.handleZ3ExceptionAsRuntimeException(exception, proverShutdownNotifier); } return null; } @@ -255,12 +259,7 @@ public R allSat(AllSatCallback callback, List important) try { return super.allSat(callback, important); } catch (Z3Exception e) { - throw creator.handleZ3Exception(e); + throw creator.handleZ3Exception(e, proverShutdownNotifier); } } - - @Override - public ShutdownManager getShutdownManagerForProver() throws UnsupportedOperationException { - return proverShutdownManager; - } } diff --git a/src/org/sosy_lab/java_smt/solvers/z3/Z3FormulaCreator.java b/src/org/sosy_lab/java_smt/solvers/z3/Z3FormulaCreator.java index 6655bfed9f..aedb62ab07 100644 --- a/src/org/sosy_lab/java_smt/solvers/z3/Z3FormulaCreator.java +++ b/src/org/sosy_lab/java_smt/solvers/z3/Z3FormulaCreator.java @@ -131,7 +131,7 @@ class Z3FormulaCreator extends FormulaCreator { // todo: getters for statistic. private final Timer cleanupTimer = new Timer(); - protected final ShutdownNotifier shutdownNotifier; + protected final ShutdownNotifier contextShutdownNotifier; @SuppressWarnings("ParameterNumber") Z3FormulaCreator( @@ -142,10 +142,10 @@ class Z3FormulaCreator extends FormulaCreator { long pStringType, long pRegexType, Configuration config, - ShutdownNotifier pShutdownNotifier) + ShutdownNotifier pContextShutdownNotifier) throws InvalidConfigurationException { super(pEnv, pBoolType, pIntegerType, pRealType, pStringType, pRegexType); - shutdownNotifier = pShutdownNotifier; + contextShutdownNotifier = pContextShutdownNotifier; config.inject(this); if (usePhantomReferences) { @@ -165,10 +165,14 @@ class Z3FormulaCreator extends FormulaCreator { * Otherwise, the given exception is wrapped and thrown as a SolverException. */ @CanIgnoreReturnValue - final SolverException handleZ3Exception(Z3Exception e) + final SolverException handleZ3Exception( + Z3Exception e, @Nullable ShutdownNotifier pAdditionalShutdownNotifier) throws SolverException, InterruptedException { if (Z3_INTERRUPT_ERRORS.contains(e.getMessage())) { - shutdownNotifier.shutdownIfNecessary(); + contextShutdownNotifier.shutdownIfNecessary(); + if (pAdditionalShutdownNotifier != null) { + pAdditionalShutdownNotifier.shutdownIfNecessary(); + } } throw new SolverException("Z3 has thrown an exception", e); } @@ -181,9 +185,10 @@ final SolverException handleZ3Exception(Z3Exception e) * @return nothing, always throw a RuntimeException * @throws RuntimeException always thrown for the given Z3Exception */ - final RuntimeException handleZ3ExceptionAsRuntimeException(Z3Exception e) { + final RuntimeException handleZ3ExceptionAsRuntimeException( + Z3Exception e, @Nullable ShutdownNotifier pAdditionalShutdownNotifier) { try { - throw handleZ3Exception(e); + throw handleZ3Exception(e, pAdditionalShutdownNotifier); } catch (InterruptedException ex) { Thread.currentThread().interrupt(); throw sneakyThrow(e); @@ -1080,7 +1085,7 @@ public long applyTactic(long z3context, long pF, String tactic) try { result = Native.tacticApply(z3context, tacticObject, goal); } catch (Z3Exception exp) { - throw handleZ3Exception(exp); + throw handleZ3Exception(exp, null); } try { diff --git a/src/org/sosy_lab/java_smt/solvers/z3/Z3FormulaManager.java b/src/org/sosy_lab/java_smt/solvers/z3/Z3FormulaManager.java index d5abf99371..cde6b4f964 100644 --- a/src/org/sosy_lab/java_smt/solvers/z3/Z3FormulaManager.java +++ b/src/org/sosy_lab/java_smt/solvers/z3/Z3FormulaManager.java @@ -192,7 +192,7 @@ protected Long simplify(Long pF) throws InterruptedException { try { return Native.simplify(getFormulaCreator().getEnv(), pF); } catch (Z3Exception exp) { - throw formulaCreator.handleZ3Exception(exp); + throw formulaCreator.handleZ3Exception(exp, null); } } catch (SolverException e) { // ignore exception and return original formula AS-IS. diff --git a/src/org/sosy_lab/java_smt/solvers/z3/Z3Model.java b/src/org/sosy_lab/java_smt/solvers/z3/Z3Model.java index b1d5ed6cc1..c48874c7ea 100644 --- a/src/org/sosy_lab/java_smt/solvers/z3/Z3Model.java +++ b/src/org/sosy_lab/java_smt/solvers/z3/Z3Model.java @@ -67,7 +67,8 @@ public ImmutableList asList() { Native.decRef(z3context, funcDecl); } } catch (Z3Exception e) { - throw z3creator.handleZ3ExceptionAsRuntimeException(e); + // TODO: Do we need the prover shutdown notifier here? + throw z3creator.handleZ3ExceptionAsRuntimeException(e, null); } return out.build(); @@ -388,7 +389,8 @@ protected Long evalImpl(Long formula) { try { satisfiableModel = Native.modelEval(z3context, model, formula, false, resultPtr); } catch (Z3Exception e) { - throw z3creator.handleZ3ExceptionAsRuntimeException(e); + // TODO: Do we need the prover shutdown notifier here? + throw z3creator.handleZ3ExceptionAsRuntimeException(e, null); } Preconditions.checkState(satisfiableModel); if (resultPtr.value == 0) { diff --git a/src/org/sosy_lab/java_smt/solvers/z3/Z3OptimizationProver.java b/src/org/sosy_lab/java_smt/solvers/z3/Z3OptimizationProver.java index d84ba3b087..5af2a8ce1d 100644 --- a/src/org/sosy_lab/java_smt/solvers/z3/Z3OptimizationProver.java +++ b/src/org/sosy_lab/java_smt/solvers/z3/Z3OptimizationProver.java @@ -43,8 +43,9 @@ class Z3OptimizationProver extends Z3AbstractProver implements OptimizationProve Set pOptions, ImmutableMap pSolverOptions, @Nullable PathCounterTemplate pLogfile, - ShutdownNotifier pShutdownNotifier) { - super(creator, pMgr, pOptions, pLogfile, pShutdownNotifier); + ShutdownNotifier pContextShutdownNotifier, + @Nullable ShutdownNotifier pProverShutdownNotifier) { + super(creator, pMgr, pOptions, pLogfile, pContextShutdownNotifier, pProverShutdownNotifier); z3optSolver = Native.mkOptimize(z3context); Native.optimizeIncRef(z3context, z3optSolver); logger = pLogger; @@ -86,12 +87,12 @@ public OptStatus check() throws InterruptedException, SolverException { ); stackChangedSinceLastQuery = false; } catch (Z3Exception ex) { - throw creator.handleZ3Exception(ex); + throw creator.handleZ3Exception(ex, proverShutdownNotifier); } if (status == Z3_lbool.Z3_L_FALSE.toInt()) { return OptStatus.UNSAT; } else if (status == Z3_lbool.Z3_L_UNDEF.toInt()) { - creator.shutdownNotifier.shutdownIfNecessary(); + shutdownIfNecessary(); logger.log( Level.INFO, "Solver returned an unknown status, explanation: ", @@ -109,7 +110,7 @@ protected void pushImpl() { try { Native.optimizePush(z3context, z3optSolver); } catch (Z3Exception exception) { - throw creator.handleZ3ExceptionAsRuntimeException(exception); + throw creator.handleZ3ExceptionAsRuntimeException(exception, proverShutdownNotifier); } } @@ -203,7 +204,7 @@ protected long getZ3Model() { try { return Native.optimizeGetModel(z3context, z3optSolver); } catch (Z3Exception e) { - throw creator.handleZ3ExceptionAsRuntimeException(e); + throw creator.handleZ3ExceptionAsRuntimeException(e, proverShutdownNotifier); } } diff --git a/src/org/sosy_lab/java_smt/solvers/z3/Z3SolverContext.java b/src/org/sosy_lab/java_smt/solvers/z3/Z3SolverContext.java index 7d408faf11..571b8b0f4a 100644 --- a/src/org/sosy_lab/java_smt/solvers/z3/Z3SolverContext.java +++ b/src/org/sosy_lab/java_smt/solvers/z3/Z3SolverContext.java @@ -41,7 +41,7 @@ public final class Z3SolverContext extends AbstractSolverContext { private final ShutdownRequestListener interruptListener; - private final ShutdownNotifier shutdownNotifier; + private final ShutdownNotifier contextShutdownNotifier; private final LogManager logger; private final ExtraOptions extraOptions; private final Z3FormulaCreator creator; @@ -100,7 +100,7 @@ private Z3SolverContext( creator = pFormulaCreator; interruptListener = reason -> Native.interrupt(pFormulaCreator.getEnv()); - shutdownNotifier = pShutdownNotifier; + contextShutdownNotifier = pShutdownNotifier; pShutdownNotifier.register(interruptListener); logger = pLogger; manager = pManager; @@ -214,7 +214,8 @@ public static synchronized Z3SolverContext create( } @Override - protected ProverEnvironment newProverEnvironment0(Set options) { + protected ProverEnvironment newProverEnvironment0( + @Nullable ShutdownNotifier pProverShutdownNotifier, Set options) { Preconditions.checkState(!closed, "solver context is already closed"); final ImmutableMap solverOptions = ImmutableMap.builder() @@ -229,18 +230,24 @@ protected ProverEnvironment newProverEnvironment0(Set options) { || options.contains(ProverOptions.GENERATE_UNSAT_CORE_OVER_ASSUMPTIONS)) .buildOrThrow(); return new Z3TheoremProver( - creator, manager, options, solverOptions, extraOptions.logfile, shutdownNotifier); + creator, + manager, + options, + solverOptions, + extraOptions.logfile, + contextShutdownNotifier, + pProverShutdownNotifier); } @Override protected InterpolatingProverEnvironment newProverEnvironmentWithInterpolation0( - Set options) { + @Nullable ShutdownNotifier pProverShutdownNotifier, Set options) { throw new UnsupportedOperationException("Z3 does not support interpolation"); } @Override public OptimizationProverEnvironment newOptimizationProverEnvironment0( - Set options) { + @Nullable ShutdownNotifier pProverShutdownNotifier, Set options) { Preconditions.checkState(!closed, "solver context is already closed"); final ImmutableMap solverOptions = ImmutableMap.builder() @@ -249,7 +256,14 @@ public OptimizationProverEnvironment newOptimizationProverEnvironment0( .put(OPT_PRIORITY_CONFIG_KEY, extraOptions.objectivePrioritizationMode) .build(); return new Z3OptimizationProver( - creator, logger, manager, options, solverOptions, extraOptions.logfile, shutdownNotifier); + creator, + logger, + manager, + options, + solverOptions, + extraOptions.logfile, + contextShutdownNotifier, + pProverShutdownNotifier); } @Override @@ -273,7 +287,7 @@ public void close() { closed = true; long context = creator.getEnv(); creator.forceClose(); - shutdownNotifier.unregister(interruptListener); + contextShutdownNotifier.unregister(interruptListener); Native.closeLog(); Native.delContext(context); } diff --git a/src/org/sosy_lab/java_smt/solvers/z3/Z3TheoremProver.java b/src/org/sosy_lab/java_smt/solvers/z3/Z3TheoremProver.java index 2abadd214b..d469dcc08f 100644 --- a/src/org/sosy_lab/java_smt/solvers/z3/Z3TheoremProver.java +++ b/src/org/sosy_lab/java_smt/solvers/z3/Z3TheoremProver.java @@ -42,13 +42,17 @@ class Z3TheoremProver extends Z3AbstractProver implements ProverEnvironment { Set pOptions, ImmutableMap pSolverOptions, @Nullable PathCounterTemplate pLogfile, - ShutdownNotifier pShutdownNotifier) { - super(creator, pMgr, pOptions, pLogfile, pShutdownNotifier); + ShutdownNotifier pContextShutdownNotifier, + @Nullable ShutdownNotifier pProverShutdownNotifier) { + super(creator, pMgr, pOptions, pLogfile, pContextShutdownNotifier, pProverShutdownNotifier); z3solver = Native.mkSolver(z3context); Native.solverIncRef(z3context, z3solver); interruptListener = reason -> Native.solverInterrupt(z3context, z3solver); - proverShutdownNotifier.register(interruptListener); + pContextShutdownNotifier.register(interruptListener); + if (pProverShutdownNotifier != null) { + pProverShutdownNotifier.register(interruptListener); + } long z3params = Native.mkParams(z3context); Native.paramsIncRef(z3context, z3params); @@ -65,7 +69,7 @@ protected void pushImpl() { try { Native.solverPush(z3context, z3solver); } catch (Z3Exception exception) { - throw creator.handleZ3ExceptionAsRuntimeException(exception); + throw creator.handleZ3ExceptionAsRuntimeException(exception, proverShutdownNotifier); } } @@ -93,7 +97,7 @@ protected boolean isUnsatImpl() throws SolverException, InterruptedException { try { result = Native.solverCheck(z3context, z3solver); } catch (Z3Exception e) { - throw creator.handleZ3Exception(e); + throw creator.handleZ3Exception(e, proverShutdownNotifier); } undefinedStatusToException(result); return result == Z3_lbool.Z3_L_FALSE.toInt(); @@ -111,7 +115,7 @@ protected boolean isUnsatWithAssumptionsImpl(Collection assumpti assumptions.size(), assumptions.stream().mapToLong(creator::extractInfo).toArray()); } catch (Z3Exception e) { - throw creator.handleZ3Exception(e); + throw creator.handleZ3Exception(e, proverShutdownNotifier); } undefinedStatusToException(result); return result == Z3_lbool.Z3_L_FALSE.toInt(); @@ -120,7 +124,7 @@ protected boolean isUnsatWithAssumptionsImpl(Collection assumpti private void undefinedStatusToException(int solverStatus) throws SolverException, InterruptedException { if (solverStatus == Z3_lbool.Z3_L_UNDEF.toInt()) { - creator.shutdownNotifier.shutdownIfNecessary(); + shutdownIfNecessary(); final String reason = Native.solverGetReasonUnknown(z3context, z3solver); switch (reason) { case "canceled": // see Z3: src/tactic/tactic.cpp @@ -143,7 +147,7 @@ protected long getZ3Model() { try { return Native.solverGetModel(z3context, z3solver); } catch (Z3Exception e) { - throw creator.handleZ3ExceptionAsRuntimeException(e); + throw creator.handleZ3ExceptionAsRuntimeException(e, proverShutdownNotifier); } } @@ -193,7 +197,10 @@ public void close() { propagator.close(); propagator = null; } - proverShutdownNotifier.unregister(interruptListener); + contextShutdownNotifier.unregister(interruptListener); + if (proverShutdownNotifier != null) { + proverShutdownNotifier.unregister(interruptListener); + } } super.close(); } From 1812dfc26f14d3de2c108688ffa187ef31f76e9a Mon Sep 17 00:00:00 2001 From: BaierD Date: Wed, 4 Jun 2025 13:45:25 +0200 Subject: [PATCH 34/87] Change TimeoutTest for the new way prover shutdown can be requested and extend tests for it --- .../sosy_lab/java_smt/test/TimeoutTest.java | 333 ++++++++++++++---- 1 file changed, 268 insertions(+), 65 deletions(-) diff --git a/src/org/sosy_lab/java_smt/test/TimeoutTest.java b/src/org/sosy_lab/java_smt/test/TimeoutTest.java index d2f685b4d8..5ae9e9a87e 100644 --- a/src/org/sosy_lab/java_smt/test/TimeoutTest.java +++ b/src/org/sosy_lab/java_smt/test/TimeoutTest.java @@ -25,9 +25,14 @@ import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameter; import org.junit.runners.Parameterized.Parameters; +import org.sosy_lab.common.ShutdownManager; +import org.sosy_lab.common.rationals.Rational; import org.sosy_lab.java_smt.SolverContextFactory.Solvers; import org.sosy_lab.java_smt.api.BasicProverEnvironment; +import org.sosy_lab.java_smt.api.BasicProverEnvironment.AllSatCallback; import org.sosy_lab.java_smt.api.BooleanFormula; +import org.sosy_lab.java_smt.api.InterpolatingProverEnvironment; +import org.sosy_lab.java_smt.api.OptimizationProverEnvironment; import org.sosy_lab.java_smt.api.SolverContext.ProverOptions; import org.sosy_lab.java_smt.api.SolverException; import org.sosy_lab.java_smt.api.Tactic; @@ -112,8 +117,11 @@ public void testProverInterruptWithSubsequentNewProverUsageBv() requireBitvectors(); requireIsolatedProverShutdown(); - testBasicProverTimeoutBv(() -> context.newProverEnvironment()); + ShutdownManager sm1 = ShutdownManager.create(); + + testBasicProverTimeoutBv(() -> context.newProverEnvironment(sm1.getNotifier()), sm1); assertThat(shutdownManager.getNotifier().shouldShutdown()).isFalse(); + assertThat(sm1.getNotifier().shouldShutdown()).isTrue(); HardBitvectorFormulaGenerator gen = new HardBitvectorFormulaGenerator(bvmgr, bmgr); try (BasicProverEnvironment pe = context.newProverEnvironment()) { @@ -129,8 +137,11 @@ public void testProverInterruptWithSubsequentNewProverUsageInt() requireIntegers(); requireIsolatedProverShutdown(); - testBasicProverTimeoutInt(() -> context.newProverEnvironment()); + ShutdownManager sm1 = ShutdownManager.create(); + + testBasicProverTimeoutInt(() -> context.newProverEnvironment(sm1.getNotifier()), sm1); assertThat(shutdownManager.getNotifier().shouldShutdown()).isFalse(); + assertThat(sm1.getNotifier().shouldShutdown()).isTrue(); HardIntegerFormulaGenerator gen = new HardIntegerFormulaGenerator(imgr, bmgr); try (BasicProverEnvironment pe = context.newProverEnvironment()) { @@ -139,6 +150,8 @@ public void testProverInterruptWithSubsequentNewProverUsageInt() } } + // TODO: add model evaluation interrupt test for context and prover interrupt + // Test shutdown of context-wide shutdown manager. No prover should be usable afterward! @Test(timeout = TIMEOUT_MILLISECONDS) public void testContextInterruptWithSubsequentNewProverUsageBv() throws InterruptedException { @@ -192,16 +205,12 @@ public void testContextInterruptWithSubsequentProverUsageBv() throws Interrupted testBasicContextTimeoutBv(() -> context.newProverEnvironment()); assertThat(shutdownManager.getNotifier().shouldShutdown()).isTrue(); - try { - assertThat(pe1.getShutdownManagerForProver().getNotifier().shouldShutdown()).isTrue(); - assertThat(pe2.getShutdownManagerForProver().getNotifier().shouldShutdown()).isTrue(); - } catch (UnsupportedOperationException mayBeThrown) { - // Do nothing, we can't check for solvers that don't support this - } - - assertThrows(InterruptedException.class, () -> pe1.push(gen.generate(8))); + + assertThrows(InterruptedException.class, () -> pe2.push(gen.generate(8))); assertThrows(InterruptedException.class, pe2::isUnsat); } + assertThrows(InterruptedException.class, () -> pe1.push(gen.generate(8))); + assertThrows(InterruptedException.class, pe1::isUnsat); } } @@ -218,44 +227,110 @@ public void testContextInterruptWithSubsequentProverUsageInt() throws Interrupte testBasicContextTimeoutInt(() -> context.newProverEnvironment()); assertThat(shutdownManager.getNotifier().shouldShutdown()).isTrue(); - try { - assertThat(pe1.getShutdownManagerForProver().getNotifier().shouldShutdown()).isTrue(); - assertThat(pe2.getShutdownManagerForProver().getNotifier().shouldShutdown()).isTrue(); - } catch (UnsupportedOperationException mayBeThrown) { - // Do nothing, we can't check for solvers that don't support this - } - - assertThrows(InterruptedException.class, () -> pe1.push(gen.generate(8))); + + assertThrows(InterruptedException.class, () -> pe2.push(gen.generate(8))); assertThrows(InterruptedException.class, pe2::isUnsat); } + assertThrows(InterruptedException.class, () -> pe1.push(gen.generate(8))); + assertThrows(InterruptedException.class, pe1::isUnsat); } } - // Test shutdown of prover and subsequent feature usage. - @Ignore + // Test shutdown of context-wide shutdown manager. No prover should be usable afterward! + // This test re-uses provers that already existed before the shutdown with their own prover + // based shutdown notifiers that have not been triggered. @Test(timeout = TIMEOUT_MILLISECONDS) - public void testProverInterruptWithSubsequentFeatureUsageBv() throws InterruptedException { + public void testContextInterruptWithSubsequentProverWithNotifierUsageBv() + throws InterruptedException { requireBitvectors(); + assume() + .withMessage("Boolector does not support multiple provers") + .that(solverToUse()) + .isNotEqualTo(BOOLECTOR); requireIsolatedProverShutdown(); + ShutdownManager sm1 = ShutdownManager.create(); + ShutdownManager sm2 = ShutdownManager.create(); + ShutdownManager sm3 = ShutdownManager.create(); + HardBitvectorFormulaGenerator gen = new HardBitvectorFormulaGenerator(bvmgr, bmgr); - try (BasicProverEnvironment pe1 = context.newProverEnvironment()) { - try (BasicProverEnvironment pe2 = context.newProverEnvironment()) { + try (BasicProverEnvironment pe1 = context.newProverEnvironment(sm1.getNotifier())) { + try (BasicProverEnvironment pe2 = context.newProverEnvironment(sm2.getNotifier())) { pe2.push(gen.generate(8)); - testBasicProverTimeoutWithFeatureUsageBv(() -> context.newProverEnvironment()); + testBasicContextTimeoutBv(() -> context.newProverEnvironment(sm3.getNotifier())); assertThat(shutdownManager.getNotifier().shouldShutdown()).isTrue(); + assertThat(sm1.getNotifier().shouldShutdown()).isFalse(); + assertThat(sm2.getNotifier().shouldShutdown()).isFalse(); + assertThat(sm3.getNotifier().shouldShutdown()).isFalse(); - try { - assertThat(pe1.getShutdownManagerForProver().getNotifier().shouldShutdown()).isTrue(); - assertThat(pe2.getShutdownManagerForProver().getNotifier().shouldShutdown()).isTrue(); - } catch (UnsupportedOperationException mayBeThrown) { - // Do nothing, we can't check for solvers that don't support this - } + assertThrows(InterruptedException.class, () -> pe2.push(gen.generate(8))); + assertThrows(InterruptedException.class, pe2::isUnsat); + } + assertThrows(InterruptedException.class, () -> pe1.push(gen.generate(8))); + assertThrows(InterruptedException.class, pe1::isUnsat); + } + } + + // Test shutdown of context-wide shutdown manager. No prover should be usable afterward! + // This test re-uses provers that already existed before the shutdown with their own prover + // based shutdown notifiers that have not been triggered. + @Test(timeout = TIMEOUT_MILLISECONDS) + public void testContextInterruptWithSubsequentProverWithNotifierUsageInt() + throws InterruptedException { + requireIntegers(); + requireIsolatedProverShutdown(); + + ShutdownManager sm1 = ShutdownManager.create(); + ShutdownManager sm2 = ShutdownManager.create(); + ShutdownManager sm3 = ShutdownManager.create(); - assertThrows(InterruptedException.class, () -> pe1.push(gen.generate(8))); + HardIntegerFormulaGenerator gen = new HardIntegerFormulaGenerator(imgr, bmgr); + try (BasicProverEnvironment pe1 = context.newProverEnvironment(sm1.getNotifier())) { + try (BasicProverEnvironment pe2 = context.newProverEnvironment(sm2.getNotifier())) { + pe2.push(gen.generate(8)); + + testBasicContextTimeoutInt(() -> context.newProverEnvironment(sm3.getNotifier())); + assertThat(shutdownManager.getNotifier().shouldShutdown()).isTrue(); + assertThat(sm1.getNotifier().shouldShutdown()).isFalse(); + assertThat(sm2.getNotifier().shouldShutdown()).isFalse(); + assertThat(sm3.getNotifier().shouldShutdown()).isFalse(); + + assertThrows(InterruptedException.class, () -> pe2.push(gen.generate(8))); assertThrows(InterruptedException.class, pe2::isUnsat); } + assertThrows(InterruptedException.class, () -> pe1.push(gen.generate(8))); + assertThrows(InterruptedException.class, pe1::isUnsat); + } + } + + // Test shutdown of prover and subsequent feature usage. + @Ignore + @Test(timeout = TIMEOUT_MILLISECONDS) + public void testProverInterruptWithSubsequentFeatureUsageBv() throws InterruptedException { + requireBitvectors(); + requireIsolatedProverShutdown(); + + ShutdownManager sm1 = ShutdownManager.create(); + ShutdownManager sm2 = ShutdownManager.create(); + ShutdownManager sm3 = ShutdownManager.create(); + + try (BasicProverEnvironment pe1 = context.newProverEnvironment(sm1.getNotifier())) { + assertProverAPIUsable(pe1); + try (BasicProverEnvironment pe2 = context.newProverEnvironment(sm2.getNotifier())) { + assertProverAPIUsable(pe2); + + testBasicProverTimeoutWithFeatureUsageBv( + () -> context.newProverEnvironment(sm3.getNotifier()), sm3); + assertThat(shutdownManager.getNotifier().shouldShutdown()).isTrue(); + + assertThat(sm1.getNotifier().shouldShutdown()).isFalse(); + assertThat(sm2.getNotifier().shouldShutdown()).isFalse(); + assertThat(sm3.getNotifier().shouldShutdown()).isTrue(); + + assertProverAPIUsable(pe2); + } + assertProverAPIUsable(pe1); } } @@ -266,29 +341,33 @@ public void testContextInterruptWithSubsequentFeatureUsageInt() throws Interrupt requireIntegers(); requireIsolatedProverShutdown(); - HardIntegerFormulaGenerator gen = new HardIntegerFormulaGenerator(imgr, bmgr); - try (BasicProverEnvironment pe1 = context.newProverEnvironment()) { - try (BasicProverEnvironment pe2 = context.newProverEnvironment()) { - pe2.push(gen.generate(8)); + ShutdownManager sm1 = ShutdownManager.create(); + ShutdownManager sm2 = ShutdownManager.create(); + ShutdownManager sm3 = ShutdownManager.create(); + + try (BasicProverEnvironment pe1 = context.newProverEnvironment(sm1.getNotifier())) { + assertProverAPIUsable(pe1); + try (BasicProverEnvironment pe2 = context.newProverEnvironment(sm2.getNotifier())) { + assertProverAPIUsable(pe2); testBasicProverTimeoutWithFeatureUsageInt( () -> context.newProverEnvironment( + sm3.getNotifier(), ProverOptions.GENERATE_UNSAT_CORE, ProverOptions.GENERATE_MODELS, ProverOptions.GENERATE_ALL_SAT, - ProverOptions.GENERATE_UNSAT_CORE_OVER_ASSUMPTIONS)); + ProverOptions.GENERATE_UNSAT_CORE_OVER_ASSUMPTIONS), + sm3); + assertThat(shutdownManager.getNotifier().shouldShutdown()).isTrue(); - try { - assertThat(pe1.getShutdownManagerForProver().getNotifier().shouldShutdown()).isTrue(); - assertThat(pe2.getShutdownManagerForProver().getNotifier().shouldShutdown()).isTrue(); - } catch (UnsupportedOperationException mayBeThrown) { - // Do nothing, we can't check for solvers that don't support this - } - - assertThrows(InterruptedException.class, () -> pe1.push(gen.generate(8))); - assertThrows(InterruptedException.class, pe2::isUnsat); + assertThat(sm1.getNotifier().shouldShutdown()).isFalse(); + assertThat(sm2.getNotifier().shouldShutdown()).isFalse(); + assertThat(sm3.getNotifier().shouldShutdown()).isTrue(); + + assertProverAPIUsable(pe2); } + assertProverAPIUsable(pe1); } } @@ -323,19 +402,21 @@ private void testBasicContextTimeoutBv(Supplier> prove /** * Shuts down the shutdown manager of the prover. Throws an exception for non-supporting solvers. */ - private void testBasicProverTimeoutInt(Supplier> proverConstructor) + private void testBasicProverTimeoutInt( + Supplier> proverConstructor, ShutdownManager managerToInterrupt) throws InterruptedException { HardIntegerFormulaGenerator gen = new HardIntegerFormulaGenerator(imgr, bmgr); - testBasicProverBasedTimeout(proverConstructor, gen.generate(200)); + testBasicProverBasedTimeout(proverConstructor, gen.generate(200), managerToInterrupt); } /** * Shuts down the shutdown manager of the prover. Throws an exception for non-supporting solvers. */ - private void testBasicProverTimeoutBv(Supplier> proverConstructor) + private void testBasicProverTimeoutBv( + Supplier> proverConstructor, ShutdownManager managerToInterrupt) throws InterruptedException { HardBitvectorFormulaGenerator gen = new HardBitvectorFormulaGenerator(bvmgr, bmgr); - testBasicProverBasedTimeout(proverConstructor, gen.generate(200)); + testBasicProverBasedTimeout(proverConstructor, gen.generate(200), managerToInterrupt); } /** @@ -343,9 +424,10 @@ private void testBasicProverTimeoutBv(Supplier> prover * Will try to use all available features of the solver afterward. (Model, UnsatCore etc.) */ private void testBasicProverTimeoutWithFeatureUsageInt( - Supplier> proverConstructor) throws InterruptedException { + Supplier> proverConstructor, ShutdownManager managerToInterrupt) + throws InterruptedException { HardIntegerFormulaGenerator gen = new HardIntegerFormulaGenerator(imgr, bmgr); - testProverBasedTimeoutWithFeatures(proverConstructor, gen.generate(200)); + testProverBasedTimeoutWithFeatures(proverConstructor, gen.generate(200), managerToInterrupt); } /** @@ -353,9 +435,10 @@ private void testBasicProverTimeoutWithFeatureUsageInt( * Will try to use all available features of the solver afterward. (Model, UnsatCore etc.) */ private void testBasicProverTimeoutWithFeatureUsageBv( - Supplier> proverConstructor) throws InterruptedException { + Supplier> proverConstructor, ShutdownManager managerToInterrupt) + throws InterruptedException { HardBitvectorFormulaGenerator gen = new HardBitvectorFormulaGenerator(bvmgr, bmgr); - testProverBasedTimeoutWithFeatures(proverConstructor, gen.generate(200)); + testProverBasedTimeoutWithFeatures(proverConstructor, gen.generate(200), managerToInterrupt); } @SuppressWarnings("CheckReturnValue") @@ -381,7 +464,9 @@ private void testBasicContextBasedTimeout( } private void testBasicProverBasedTimeout( - Supplier> proverConstructor, BooleanFormula instance) + Supplier> proverConstructor, + BooleanFormula instance, + ShutdownManager managerToInterrupt) throws InterruptedException { try (BasicProverEnvironment pe = proverConstructor.get()) { @@ -390,7 +475,7 @@ private void testBasicProverBasedTimeout( () -> { try { Thread.sleep(delay); - pe.getShutdownManagerForProver().requestShutdown("Shutdown Request"); + managerToInterrupt.requestShutdown("Shutdown Request"); } catch (InterruptedException exception) { throw new UnsupportedOperationException("Unexpected interrupt", exception); } @@ -401,8 +486,14 @@ private void testBasicProverBasedTimeout( } } + /** + * You can hand this a TheoremProver, InterpolatingProver or OptimizationProver, and it tests all + * common features after interrupt. + */ private void testProverBasedTimeoutWithFeatures( - Supplier> proverConstructor, BooleanFormula instance) + Supplier> proverConstructor, + BooleanFormula instance, + ShutdownManager managerToInterrupt) throws InterruptedException { // TODO: maybe add a test that solves something correctly before interrupting? @@ -413,22 +504,134 @@ private void testProverBasedTimeoutWithFeatures( () -> { try { Thread.sleep(delay); - pe.getShutdownManagerForProver().requestShutdown("Shutdown Request"); + managerToInterrupt.requestShutdown("Shutdown Request"); } catch (InterruptedException exception) { throw new UnsupportedOperationException("Unexpected interrupt", exception); } }); pe.push(instance); t.start(); - assertThrows(InterruptedException.class, pe::isUnsat); - assertThrows(InterruptedException.class, pe::getModel); - assertThrows(InterruptedException.class, pe::getUnsatCore); + assertProverAPIThrowsInterruptedException(pe); + } + } + + /** + * This always starts with isUnsat() that should be interrupted (either while solving or before). + * The correct options for the usage of UnsatCore and UnsatCoreOverAssumptions have not to be set! + */ + private void assertProverAPIThrowsInterruptedException(BasicProverEnvironment pe) { + assertThrows(InterruptedException.class, pe::isUnsat); + assertThrows(InterruptedException.class, pe::getModel); + assertThrows(InterruptedException.class, pe::getModelAssignments); + assertThrows(InterruptedException.class, pe::getEvaluator); + assertThrows(InterruptedException.class, pe::getUnsatCore); + assertThrows( + InterruptedException.class, + () -> + pe.allSat( + new AllSatCallback<>() { + + private final List> models = new ArrayList<>(); + + @Override + public void apply(List pModel) { + models.add(pModel); + } + + @Override + public List> getResult() { + return models; + } + }, + ImmutableList.of(bmgr.makeFalse()))); + assertThrows( + InterruptedException.class, + () -> pe.unsatCoreOverAssumptions(ImmutableList.of(bmgr.makeFalse()))); + assertThrows( + InterruptedException.class, + () -> pe.isUnsatWithAssumptions(ImmutableList.of(bmgr.makeFalse()))); + assertThrows(InterruptedException.class, () -> pe.addConstraint(bmgr.makeFalse())); + assertThrows(InterruptedException.class, () -> pe.push(bmgr.makeFalse())); + assertThrows(InterruptedException.class, pe::push); + assertThrows(InterruptedException.class, pe::pop); + if (pe instanceof InterpolatingProverEnvironment) { + InterpolatingProverEnvironment ipe = (InterpolatingProverEnvironment) pe; + assertThrows(InterruptedException.class, () -> ipe.getInterpolant(ImmutableList.of())); + assertThrows(InterruptedException.class, () -> ipe.getSeqInterpolants(ImmutableList.of())); + assertThrows(InterruptedException.class, () -> ipe.getSeqInterpolants0(ImmutableList.of())); + assertThrows( + InterruptedException.class, + () -> ipe.getTreeInterpolants(ImmutableList.of(), new int[] {0})); assertThrows( - InterruptedException.class, () -> pe.isUnsatWithAssumptions(ImmutableList.of(instance))); - assertThrows(InterruptedException.class, () -> pe.addConstraint(instance)); - assertThrows(InterruptedException.class, () -> pe.push(instance)); - assertThrows(InterruptedException.class, pe::push); - assertThrows(InterruptedException.class, pe::pop); + InterruptedException.class, + () -> ipe.getTreeInterpolants0(ImmutableList.of(), new int[] {0})); + } + if (pe instanceof OptimizationProverEnvironment) { + OptimizationProverEnvironment ope = (OptimizationProverEnvironment) pe; + assertThrows(InterruptedException.class, () -> ope.maximize(bmgr.makeFalse())); + assertThrows(InterruptedException.class, () -> ope.minimize(bmgr.makeFalse())); + assertThrows(InterruptedException.class, ope::check); + assertThrows(InterruptedException.class, () -> ope.upper(1, Rational.ZERO)); + assertThrows(InterruptedException.class, () -> ope.lower(1, Rational.ZERO)); + assertThrows(InterruptedException.class, ope::getModel); + } + } + + private void assertProverAPIUsable(BasicProverEnvironment pe) { + assertThrows(InterruptedException.class, pe::isUnsat); + assertThrows(InterruptedException.class, pe::getModel); + assertThrows(InterruptedException.class, pe::getModelAssignments); + assertThrows(InterruptedException.class, pe::getEvaluator); + assertThrows(InterruptedException.class, pe::getUnsatCore); + assertThrows( + InterruptedException.class, + () -> + pe.allSat( + new AllSatCallback<>() { + + private final List> models = new ArrayList<>(); + + @Override + public void apply(List pModel) { + models.add(pModel); + } + + @Override + public List> getResult() { + return models; + } + }, + ImmutableList.of(bmgr.makeFalse()))); + assertThrows( + InterruptedException.class, + () -> pe.unsatCoreOverAssumptions(ImmutableList.of(bmgr.makeFalse()))); + assertThrows( + InterruptedException.class, + () -> pe.isUnsatWithAssumptions(ImmutableList.of(bmgr.makeFalse()))); + assertThrows(InterruptedException.class, () -> pe.addConstraint(bmgr.makeFalse())); + assertThrows(InterruptedException.class, () -> pe.push(bmgr.makeFalse())); + assertThrows(InterruptedException.class, pe::push); + assertThrows(InterruptedException.class, pe::pop); + if (pe instanceof InterpolatingProverEnvironment) { + InterpolatingProverEnvironment ipe = (InterpolatingProverEnvironment) pe; + assertThrows(InterruptedException.class, () -> ipe.getInterpolant(ImmutableList.of())); + assertThrows(InterruptedException.class, () -> ipe.getSeqInterpolants(ImmutableList.of())); + assertThrows(InterruptedException.class, () -> ipe.getSeqInterpolants0(ImmutableList.of())); + assertThrows( + InterruptedException.class, + () -> ipe.getTreeInterpolants(ImmutableList.of(), new int[] {0})); + assertThrows( + InterruptedException.class, + () -> ipe.getTreeInterpolants0(ImmutableList.of(), new int[] {0})); + } + if (pe instanceof OptimizationProverEnvironment) { + OptimizationProverEnvironment ope = (OptimizationProverEnvironment) pe; + assertThrows(InterruptedException.class, () -> ope.maximize(bmgr.makeFalse())); + assertThrows(InterruptedException.class, () -> ope.minimize(bmgr.makeFalse())); + assertThrows(InterruptedException.class, ope::check); + assertThrows(InterruptedException.class, () -> ope.upper(1, Rational.ZERO)); + assertThrows(InterruptedException.class, () -> ope.lower(1, Rational.ZERO)); + assertThrows(InterruptedException.class, ope::getModel); } } } From 17ec72edaa9fbdf2159149e241ca3f1372cb34c6 Mon Sep 17 00:00:00 2001 From: BaierD Date: Wed, 4 Jun 2025 14:50:49 +0200 Subject: [PATCH 35/87] Add default behavior/failure checks for getEvaluator() --- .../java_smt/basicimpl/AbstractProver.java | 14 ++++++++++++++ .../java_smt/solvers/cvc4/CVC4TheoremProver.java | 4 +--- .../java_smt/solvers/cvc5/CVC5AbstractProver.java | 4 +--- .../solvers/mathsat5/Mathsat5AbstractProver.java | 4 +--- .../solvers/opensmt/OpenSmtAbstractProver.java | 4 +--- 5 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java index 011dcaab56..5365524e3d 100644 --- a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java +++ b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java @@ -177,6 +177,20 @@ public final Model getModel() throws SolverException { protected abstract Model getModelImpl() throws SolverException; + @Override + public final Evaluator getEvaluator() throws SolverException { + checkState(!closed); + checkState(!shouldShutdown()); + checkState(wasLastSatCheckSat, NO_MODEL_HELP); + checkState(!stackChangedSinceLastQuery, STACK_CHANGED_HELP); + checkGenerateModels(); + return getEvaluatorImpl(); + } + + protected Evaluator getEvaluatorImpl() throws SolverException { + return getModel(); + } + @Override public final void push() throws InterruptedException { checkState(!closed); diff --git a/src/org/sosy_lab/java_smt/solvers/cvc4/CVC4TheoremProver.java b/src/org/sosy_lab/java_smt/solvers/cvc4/CVC4TheoremProver.java index f1f73be532..9153fc0371 100644 --- a/src/org/sosy_lab/java_smt/solvers/cvc4/CVC4TheoremProver.java +++ b/src/org/sosy_lab/java_smt/solvers/cvc4/CVC4TheoremProver.java @@ -151,9 +151,7 @@ protected CVC4Model getModelImpl() throws SolverException { } @Override - public Evaluator getEvaluator() { - Preconditions.checkState(!closed); - checkGenerateModels(); + public Evaluator getEvaluatorImpl() { return getEvaluatorWithoutChecks(); } diff --git a/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5AbstractProver.java b/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5AbstractProver.java index cb152c1dbd..2f80b1631a 100644 --- a/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5AbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5AbstractProver.java @@ -162,9 +162,7 @@ protected CVC5Model getModelImpl() throws SolverException { } @Override - public Evaluator getEvaluator() { - Preconditions.checkState(!closed); - checkGenerateModels(); + public Evaluator getEvaluatorImpl() { return getEvaluatorWithoutChecks(); } diff --git a/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5AbstractProver.java b/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5AbstractProver.java index 3af56e98be..1a86cff448 100644 --- a/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5AbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5AbstractProver.java @@ -164,9 +164,7 @@ protected long getMsatModel() throws SolverException { @SuppressWarnings("resource") @Override - public Evaluator getEvaluator() { - Preconditions.checkState(!closed); - checkGenerateModels(); + public Evaluator getEvaluatorImpl() { return registerEvaluator(new Mathsat5Evaluator(this, creator, curEnv)); } diff --git a/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtAbstractProver.java b/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtAbstractProver.java index c976b3210c..2b577741bd 100644 --- a/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtAbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtAbstractProver.java @@ -121,9 +121,7 @@ protected Model getModelImpl() { } @Override - public Evaluator getEvaluator() { - Preconditions.checkState(!closed); - checkGenerateModels(); + public Evaluator getEvaluatorImpl() { return getEvaluatorWithoutChecks(); } From 5a20e6dff97c8b97f1882639e260535d5be64472 Mon Sep 17 00:00:00 2001 From: BaierD Date: Wed, 11 Jun 2025 12:10:49 +0200 Subject: [PATCH 36/87] Add default behavior/failure checks for pop() for termination --- src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java index 5365524e3d..d80f8c7e43 100644 --- a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java +++ b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java @@ -205,6 +205,7 @@ public final void push() throws InterruptedException { @Override public final void pop() { checkState(!closed); + checkState(!shouldShutdown()); checkState(assertedFormulas.size() > 1, "initial level must remain until close"); assertedFormulas.remove(assertedFormulas.size() - 1); // remove last // TODO: technically only needed if the level removed was non empty. From 0b95f112bce4b6937264db68b65de5d01f77421f Mon Sep 17 00:00:00 2001 From: BaierD Date: Wed, 11 Jun 2025 12:18:51 +0200 Subject: [PATCH 37/87] Concat static string error msgs --- src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java b/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java index d66e9cef07..d9bc9c4b11 100644 --- a/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java +++ b/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java @@ -22,13 +22,13 @@ * provides only the common operations. In most cases, just use one of the two sub-interfaces */ public interface BasicProverEnvironment extends AutoCloseable { - String NO_MODEL_HELP = "Model computation failed. Are the pushed formulae " + "satisfiable?"; + String NO_MODEL_HELP = "Model computation failed. Are the pushed formulae satisfiable?"; String NO_UNSAT_CORE_HELP = - "UnsatCore computation failed. Are the pushed formulae " + "unsatisfiable?"; + "UnsatCore computation failed. Are the pushed formulae unsatisfiable?"; String STACK_CHANGED_HELP = - "Computation failed. The prover state has changed since the last " + "call to isUnsat()."; + "Computation failed. The prover state has changed since the last call to isUnsat()."; /** * Push a backtracking point and add a formula to the current stack, asserting it. The return From 1cd34dd2e1184d018c21d0d52513fc796ce62c89 Mon Sep 17 00:00:00 2001 From: BaierD Date: Wed, 11 Jun 2025 12:20:04 +0200 Subject: [PATCH 38/87] Add shutdown reason to exception msg for non-interrupted exception throwing methods --- .../java_smt/basicimpl/AbstractProver.java | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java index d80f8c7e43..0de50c0a6b 100644 --- a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java +++ b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java @@ -88,6 +88,16 @@ protected final boolean shouldShutdown() { return contextShutdownNotifier.shouldShutdown(); } + protected final String getShutdownReason() { + String msg = "Prover is not usable due to shutdown with message: "; + if (proverShutdownNotifier != null && proverShutdownNotifier.shouldShutdown()) { + return msg + contextShutdownNotifier.getReason(); + } + + checkState(contextShutdownNotifier.shouldShutdown()); + return msg + contextShutdownNotifier.getReason(); + } + protected final void checkGenerateModels() { Preconditions.checkState(generateModels, TEMPLATE, ProverOptions.GENERATE_MODELS); } @@ -132,7 +142,7 @@ public final boolean isUnsat() throws SolverException, InterruptedException { @Override public List getUnsatCore() { checkState(!closed); - checkState(!shouldShutdown()); + checkState(!shouldShutdown(), getShutdownReason()); checkState(!wasLastSatCheckSat, NO_UNSAT_CORE_HELP); checkState(!stackChangedSinceLastQuery, STACK_CHANGED_HELP); checkGenerateUnsatCores(); @@ -168,7 +178,7 @@ protected abstract boolean isUnsatWithAssumptionsImpl(Collection @Override public final Model getModel() throws SolverException { checkState(!closed); - checkState(!shouldShutdown()); + checkState(!shouldShutdown(), getShutdownReason()); checkState(wasLastSatCheckSat, NO_MODEL_HELP); checkState(!stackChangedSinceLastQuery, STACK_CHANGED_HELP); checkGenerateModels(); @@ -180,7 +190,7 @@ public final Model getModel() throws SolverException { @Override public final Evaluator getEvaluator() throws SolverException { checkState(!closed); - checkState(!shouldShutdown()); + checkState(!shouldShutdown(), getShutdownReason()); checkState(wasLastSatCheckSat, NO_MODEL_HELP); checkState(!stackChangedSinceLastQuery, STACK_CHANGED_HELP); checkGenerateModels(); @@ -205,7 +215,7 @@ public final void push() throws InterruptedException { @Override public final void pop() { checkState(!closed); - checkState(!shouldShutdown()); + checkState(!shouldShutdown(), getShutdownReason()); checkState(assertedFormulas.size() > 1, "initial level must remain until close"); assertedFormulas.remove(assertedFormulas.size() - 1); // remove last // TODO: technically only needed if the level removed was non empty. @@ -268,7 +278,7 @@ protected void closeAllEvaluators() { @Override public ImmutableList getModelAssignments() throws SolverException { Preconditions.checkState(!closed); - checkState(!shouldShutdown()); + checkState(!shouldShutdown(), getShutdownReason()); Preconditions.checkState(!stackChangedSinceLastQuery, STACK_CHANGED_HELP); checkState(wasLastSatCheckSat); try (Model model = getModel()) { From c85c030f3b073c0f76dea4bd54df9622c0167f96 Mon Sep 17 00:00:00 2001 From: BaierD Date: Wed, 11 Jun 2025 14:08:16 +0200 Subject: [PATCH 39/87] Add recovery of assertProverAPIThrowsInterruptedException from methods not throwing it to basic impls of prover --- .../java_smt/api/BasicProverEnvironment.java | 3 ++ .../java_smt/basicimpl/AbstractProver.java | 5 ++-- .../BasicProverWithAssumptionsWrapper.java | 29 +++++++++++++++---- 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java b/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java index d9bc9c4b11..e7c1d8422e 100644 --- a/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java +++ b/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java @@ -30,6 +30,9 @@ public interface BasicProverEnvironment extends AutoCloseable { String STACK_CHANGED_HELP = "Computation failed. The prover state has changed since the last call to isUnsat()."; + // Used as prefix concatenated with the reason in the IllegalStateException thrown for shutdowns + String SHUTDOWN_EXCEPTION_PREFIX = "Prover is not usable due to interrupt with message: "; + /** * Push a backtracking point and add a formula to the current stack, asserting it. The return * value may be used to identify this formula later on in a query (this depends on the sub-type of diff --git a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java index 0de50c0a6b..ea4d6e7abe 100644 --- a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java +++ b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java @@ -89,13 +89,12 @@ protected final boolean shouldShutdown() { } protected final String getShutdownReason() { - String msg = "Prover is not usable due to shutdown with message: "; if (proverShutdownNotifier != null && proverShutdownNotifier.shouldShutdown()) { - return msg + contextShutdownNotifier.getReason(); + return SHUTDOWN_EXCEPTION_PREFIX + contextShutdownNotifier.getReason(); } checkState(contextShutdownNotifier.shouldShutdown()); - return msg + contextShutdownNotifier.getReason(); + return SHUTDOWN_EXCEPTION_PREFIX + contextShutdownNotifier.getReason(); } protected final void checkGenerateModels() { diff --git a/src/org/sosy_lab/java_smt/basicimpl/withAssumptionsWrapper/BasicProverWithAssumptionsWrapper.java b/src/org/sosy_lab/java_smt/basicimpl/withAssumptionsWrapper/BasicProverWithAssumptionsWrapper.java index f2bf7435fe..404e850255 100644 --- a/src/org/sosy_lab/java_smt/basicimpl/withAssumptionsWrapper/BasicProverWithAssumptionsWrapper.java +++ b/src/org/sosy_lab/java_smt/basicimpl/withAssumptionsWrapper/BasicProverWithAssumptionsWrapper.java @@ -18,6 +18,7 @@ import org.sosy_lab.java_smt.api.BooleanFormula; import org.sosy_lab.java_smt.api.Model; import org.sosy_lab.java_smt.api.SolverException; +import org.sosy_lab.java_smt.basicimpl.AbstractProver; public class BasicProverWithAssumptionsWrapper> implements BasicProverEnvironment { @@ -36,6 +37,21 @@ protected void clearAssumptions() { solverAssumptionsAsFormula.clear(); } + protected void clearAssumptionsWithInterruptedException() throws InterruptedException { + for (int i = 0; i < solverAssumptionsAsFormula.size(); i++) { + try { + delegate.pop(); + } catch (IllegalStateException ise) { + if (ise.getMessage().startsWith(AbstractProver.SHUTDOWN_EXCEPTION_PREFIX)) { + throw new InterruptedException( + ise.getMessage() + .replace("Prover is not usable due " + "to shutdown with message: ", "")); + } + } + } + solverAssumptionsAsFormula.clear(); + } + @Override public void pop() { clearAssumptions(); @@ -44,13 +60,16 @@ public void pop() { @Override public T addConstraint(BooleanFormula constraint) throws InterruptedException { - clearAssumptions(); + // This might throw the "wrong" exception because it pops the assumptions + // (which does not return a InterruptedException for interrupts) + clearAssumptionsWithInterruptedException(); + return delegate.addConstraint(constraint); } @Override public void push() throws InterruptedException { - clearAssumptions(); + clearAssumptionsWithInterruptedException(); delegate.push(); } @@ -61,14 +80,14 @@ public int size() { @Override public boolean isUnsat() throws SolverException, InterruptedException { - clearAssumptions(); + clearAssumptionsWithInterruptedException(); return delegate.isUnsat(); } @Override public boolean isUnsatWithAssumptions(Collection assumptions) throws SolverException, InterruptedException { - clearAssumptions(); + clearAssumptionsWithInterruptedException(); solverAssumptionsAsFormula.addAll(assumptions); for (BooleanFormula formula : assumptions) { registerPushedFormula(delegate.push(formula)); @@ -125,7 +144,7 @@ public String toString() { @Override public R allSat(AllSatCallback pCallback, List pImportant) throws InterruptedException, SolverException { - clearAssumptions(); + clearAssumptionsWithInterruptedException(); return delegate.allSat(pCallback, pImportant); } } From 407f52a8ee272809210164e04decdc6915ddad64 Mon Sep 17 00:00:00 2001 From: BaierD Date: Wed, 11 Jun 2025 14:11:22 +0200 Subject: [PATCH 40/87] Remove redundant checks from BoolectorTheoremProver.java --- .../java_smt/solvers/boolector/BoolectorTheoremProver.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/org/sosy_lab/java_smt/solvers/boolector/BoolectorTheoremProver.java b/src/org/sosy_lab/java_smt/solvers/boolector/BoolectorTheoremProver.java index 43fd1239b9..95a2a779bb 100644 --- a/src/org/sosy_lab/java_smt/solvers/boolector/BoolectorTheoremProver.java +++ b/src/org/sosy_lab/java_smt/solvers/boolector/BoolectorTheoremProver.java @@ -83,7 +83,6 @@ public void close() { */ @Override protected boolean isUnsatImpl() throws SolverException, InterruptedException { - Preconditions.checkState(!closed); wasLastSatCheckSat = false; final int result = BtorJNI.boolector_sat(btor); if (result == BtorJNI.BTOR_RESULT_SAT_get()) { @@ -117,7 +116,6 @@ protected void pushImpl() throws InterruptedException { @Override protected boolean isUnsatWithAssumptionsImpl(Collection pAssumptions) throws SolverException, InterruptedException { - Preconditions.checkState(!closed); for (BooleanFormula assumption : pAssumptions) { BtorJNI.boolector_assume(btor, BoolectorFormulaManager.getBtorTerm(assumption)); } @@ -127,8 +125,6 @@ protected boolean isUnsatWithAssumptionsImpl(Collection pAssumpt @SuppressWarnings("resource") @Override protected Model getModelImpl() throws SolverException { - Preconditions.checkState(wasLastSatCheckSat, NO_MODEL_HELP); - checkGenerateModels(); return new CachingModel(getEvaluatorWithoutChecks()); } From 384c7b166534bce46c11a02812c0fe3ac695ce82 Mon Sep 17 00:00:00 2001 From: BaierD Date: Wed, 11 Jun 2025 14:12:56 +0200 Subject: [PATCH 41/87] Remove commented out old code --- .../solvers/smtinterpol/SmtInterpolAbstractProver.java | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolAbstractProver.java b/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolAbstractProver.java index 829b414b67..8831450ccb 100644 --- a/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolAbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolAbstractProver.java @@ -244,11 +244,4 @@ public R allSat(AllSatCallback callback, List important) } return callback.getResult(); } - - /* TODO: the shutdownNotifier is bound to the Script. But this is done in the context. It seems - like it might be re-usable after a shutdown. - @Override - protected ShutdownManager getShutdownManagerForProverImpl() throws UnsupportedOperationException { - return proverShutdownManager; - }*/ } From 97c44b6f16f265036b40adfcd0044b1b1c199a1c Mon Sep 17 00:00:00 2001 From: BaierD Date: Wed, 11 Jun 2025 14:22:19 +0200 Subject: [PATCH 42/87] Add full shutdown/interrupt exception handling to Z3 model --- .../java_smt/solvers/z3/Z3AbstractProver.java | 2 +- src/org/sosy_lab/java_smt/solvers/z3/Z3Model.java | 13 ++++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/org/sosy_lab/java_smt/solvers/z3/Z3AbstractProver.java b/src/org/sosy_lab/java_smt/solvers/z3/Z3AbstractProver.java index 001c5c59b2..7e4e34126a 100644 --- a/src/org/sosy_lab/java_smt/solvers/z3/Z3AbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/z3/Z3AbstractProver.java @@ -116,7 +116,7 @@ protected Model getModelImpl() throws SolverException { @Override protected Z3Model getEvaluatorWithoutChecks() throws SolverException { - return new Z3Model(this, z3context, getZ3Model(), creator); + return new Z3Model(this, z3context, getZ3Model(), creator, proverShutdownNotifier); } protected abstract long getZ3Model() throws SolverException; diff --git a/src/org/sosy_lab/java_smt/solvers/z3/Z3Model.java b/src/org/sosy_lab/java_smt/solvers/z3/Z3Model.java index c48874c7ea..e964cb9bd4 100644 --- a/src/org/sosy_lab/java_smt/solvers/z3/Z3Model.java +++ b/src/org/sosy_lab/java_smt/solvers/z3/Z3Model.java @@ -23,6 +23,7 @@ import java.util.Set; import java.util.regex.Pattern; import org.checkerframework.checker.nullness.qual.Nullable; +import org.sosy_lab.common.ShutdownNotifier; import org.sosy_lab.java_smt.basicimpl.AbstractModel; import org.sosy_lab.java_smt.basicimpl.AbstractProver; @@ -34,12 +35,16 @@ final class Z3Model extends AbstractModel { private final Z3FormulaCreator z3creator; - Z3Model(AbstractProver pProver, long z3context, long z3model, Z3FormulaCreator pCreator) { + private final @Nullable ShutdownNotifier proverShutdownNotifier; + + Z3Model(AbstractProver pProver, long z3context, long z3model, Z3FormulaCreator pCreator, + @Nullable ShutdownNotifier pProverShutdownNotifier) { super(pProver, pCreator); Native.modelIncRef(z3context, z3model); model = z3model; this.z3context = z3context; z3creator = pCreator; + proverShutdownNotifier = pProverShutdownNotifier; } @Override @@ -67,8 +72,7 @@ public ImmutableList asList() { Native.decRef(z3context, funcDecl); } } catch (Z3Exception e) { - // TODO: Do we need the prover shutdown notifier here? - throw z3creator.handleZ3ExceptionAsRuntimeException(e, null); + throw z3creator.handleZ3ExceptionAsRuntimeException(e, proverShutdownNotifier); } return out.build(); @@ -389,8 +393,7 @@ protected Long evalImpl(Long formula) { try { satisfiableModel = Native.modelEval(z3context, model, formula, false, resultPtr); } catch (Z3Exception e) { - // TODO: Do we need the prover shutdown notifier here? - throw z3creator.handleZ3ExceptionAsRuntimeException(e, null); + throw z3creator.handleZ3ExceptionAsRuntimeException(e, proverShutdownNotifier); } Preconditions.checkState(satisfiableModel); if (resultPtr.value == 0) { From cfa1cdbf851b8ec9f982e158d7ac1077457fff06 Mon Sep 17 00:00:00 2001 From: BaierD Date: Wed, 11 Jun 2025 14:28:06 +0200 Subject: [PATCH 43/87] Remove redundant checks and code from provers/solvers --- .../java_smt/solvers/cvc4/CVC4TheoremProver.java | 4 ---- .../java_smt/solvers/cvc5/CVC5AbstractProver.java | 10 ---------- .../solvers/opensmt/OpenSmtAbstractProver.java | 3 --- src/org/sosy_lab/java_smt/solvers/z3/Z3Model.java | 8 ++++++-- 4 files changed, 6 insertions(+), 19 deletions(-) diff --git a/src/org/sosy_lab/java_smt/solvers/cvc4/CVC4TheoremProver.java b/src/org/sosy_lab/java_smt/solvers/cvc4/CVC4TheoremProver.java index 9153fc0371..032578cd54 100644 --- a/src/org/sosy_lab/java_smt/solvers/cvc4/CVC4TheoremProver.java +++ b/src/org/sosy_lab/java_smt/solvers/cvc4/CVC4TheoremProver.java @@ -8,7 +8,6 @@ package org.sosy_lab.java_smt.solvers.cvc4; -import com.google.common.base.Preconditions; import com.google.common.collect.Collections2; import edu.stanford.CVC4.Exception; import edu.stanford.CVC4.Expr; @@ -121,7 +120,6 @@ protected void popImpl() { @Override protected @Nullable Void addConstraintImpl(BooleanFormula pF) throws InterruptedException { - Preconditions.checkState(!closed); if (incremental) { assertFormula(pF); } @@ -199,8 +197,6 @@ private boolean convertSatResult(Result result) throws InterruptedException, Sol @Override protected List getUnsatCoreImpl() { - Preconditions.checkState(!wasLastSatCheckSat); - Preconditions.checkState(!stackChangedSinceLastQuery); List converted = new ArrayList<>(); for (Expr aCore : smtEngine.getUnsatCore()) { converted.add(creator.encapsulateBoolean(exportExpr(aCore))); diff --git a/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5AbstractProver.java b/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5AbstractProver.java index 2f80b1631a..4ab8cdcf82 100644 --- a/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5AbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5AbstractProver.java @@ -8,7 +8,6 @@ package org.sosy_lab.java_smt.solvers.cvc5; -import com.google.common.base.Preconditions; import com.google.common.collect.Collections2; import com.google.common.collect.ImmutableMap; import com.google.errorprone.annotations.CanIgnoreReturnValue; @@ -138,7 +137,6 @@ protected void popImpl() { @CanIgnoreReturnValue protected String addConstraint0(BooleanFormula pF) { - Preconditions.checkState(!closed); Term exp = creator.extractInfo(pF); if (incremental) { solver.assertFormula(exp); @@ -199,8 +197,6 @@ private boolean convertSatResult(Result result) throws InterruptedException, Sol @Override protected List getUnsatCoreImpl() { - Preconditions.checkState(!stackChangedSinceLastQuery); - Preconditions.checkState(!wasLastSatCheckSat); List converted = new ArrayList<>(); for (Term aCore : solver.getUnsatCore()) { converted.add(creator.encapsulateBoolean(aCore)); @@ -228,10 +224,4 @@ public void close() { } super.close(); } - - /* TODO: revisit once CVC5 supports interruption - @Override - protected ShutdownManager getShutdownManagerForProverImpl() throws UnsupportedOperationException { - return proverShutdownManager; - }*/ } diff --git a/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtAbstractProver.java b/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtAbstractProver.java index 2b577741bd..275ae7a99f 100644 --- a/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtAbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtAbstractProver.java @@ -8,7 +8,6 @@ package org.sosy_lab.java_smt.solvers.opensmt; -import com.google.common.base.Preconditions; import com.google.common.collect.Collections2; import com.google.common.collect.Lists; import java.util.ArrayList; @@ -241,8 +240,6 @@ protected boolean isUnsatImpl() throws InterruptedException, SolverException { @Override protected List getUnsatCoreImpl() { - Preconditions.checkState(!wasLastSatCheckSat); - Preconditions.checkState(!stackChangedSinceLastQuery); return Lists.transform(osmtSolver.getUnsatCore(), creator::encapsulateBoolean); } diff --git a/src/org/sosy_lab/java_smt/solvers/z3/Z3Model.java b/src/org/sosy_lab/java_smt/solvers/z3/Z3Model.java index e964cb9bd4..0659a09beb 100644 --- a/src/org/sosy_lab/java_smt/solvers/z3/Z3Model.java +++ b/src/org/sosy_lab/java_smt/solvers/z3/Z3Model.java @@ -37,8 +37,12 @@ final class Z3Model extends AbstractModel { private final @Nullable ShutdownNotifier proverShutdownNotifier; - Z3Model(AbstractProver pProver, long z3context, long z3model, Z3FormulaCreator pCreator, - @Nullable ShutdownNotifier pProverShutdownNotifier) { + Z3Model( + AbstractProver pProver, + long z3context, + long z3model, + Z3FormulaCreator pCreator, + @Nullable ShutdownNotifier pProverShutdownNotifier) { super(pProver, pCreator); Native.modelIncRef(z3context, z3model); model = z3model; From 799385c4916de1c3d9326e221af86c711db0b70e Mon Sep 17 00:00:00 2001 From: BaierD Date: Wed, 25 Jun 2025 15:35:19 +0200 Subject: [PATCH 44/87] Directly use shutdown exception text constant when checking for hidden InterruptedExceptions --- .../BasicProverWithAssumptionsWrapper.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/org/sosy_lab/java_smt/basicimpl/withAssumptionsWrapper/BasicProverWithAssumptionsWrapper.java b/src/org/sosy_lab/java_smt/basicimpl/withAssumptionsWrapper/BasicProverWithAssumptionsWrapper.java index 404e850255..ee710b0caf 100644 --- a/src/org/sosy_lab/java_smt/basicimpl/withAssumptionsWrapper/BasicProverWithAssumptionsWrapper.java +++ b/src/org/sosy_lab/java_smt/basicimpl/withAssumptionsWrapper/BasicProverWithAssumptionsWrapper.java @@ -18,7 +18,6 @@ import org.sosy_lab.java_smt.api.BooleanFormula; import org.sosy_lab.java_smt.api.Model; import org.sosy_lab.java_smt.api.SolverException; -import org.sosy_lab.java_smt.basicimpl.AbstractProver; public class BasicProverWithAssumptionsWrapper> implements BasicProverEnvironment { @@ -42,10 +41,8 @@ protected void clearAssumptionsWithInterruptedException() throws InterruptedExce try { delegate.pop(); } catch (IllegalStateException ise) { - if (ise.getMessage().startsWith(AbstractProver.SHUTDOWN_EXCEPTION_PREFIX)) { - throw new InterruptedException( - ise.getMessage() - .replace("Prover is not usable due " + "to shutdown with message: ", "")); + if (ise.getMessage().startsWith(SHUTDOWN_EXCEPTION_PREFIX)) { + throw new InterruptedException(ise.getMessage().replace(SHUTDOWN_EXCEPTION_PREFIX, "")); } } } From b4fbc2f8527c21b38a254fd5ca3d0d4d288e46f9 Mon Sep 17 00:00:00 2001 From: BaierD Date: Wed, 25 Jun 2025 19:51:53 +0200 Subject: [PATCH 45/87] Lazily eval shutdown msg when checking in non throwing methods --- .../java_smt/basicimpl/AbstractProver.java | 25 +++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java index ea4d6e7abe..d227f947d9 100644 --- a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java +++ b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java @@ -88,12 +88,23 @@ protected final boolean shouldShutdown() { return contextShutdownNotifier.shouldShutdown(); } + private void checkShutdownState() { + // Refaster forced me to do this! + if (shouldShutdown()) { + String reason = getShutdownReason(); + checkState(!shouldShutdown(), reason); + } + } + + /** + * Only to be called when at least one of the shutdown notifiers is supposed to be shutting down! + * Throws an Exception if no shutdown is requested! + */ protected final String getShutdownReason() { if (proverShutdownNotifier != null && proverShutdownNotifier.shouldShutdown()) { - return SHUTDOWN_EXCEPTION_PREFIX + contextShutdownNotifier.getReason(); + return SHUTDOWN_EXCEPTION_PREFIX + proverShutdownNotifier.getReason(); } - checkState(contextShutdownNotifier.shouldShutdown()); return SHUTDOWN_EXCEPTION_PREFIX + contextShutdownNotifier.getReason(); } @@ -141,7 +152,7 @@ public final boolean isUnsat() throws SolverException, InterruptedException { @Override public List getUnsatCore() { checkState(!closed); - checkState(!shouldShutdown(), getShutdownReason()); + checkShutdownState(); checkState(!wasLastSatCheckSat, NO_UNSAT_CORE_HELP); checkState(!stackChangedSinceLastQuery, STACK_CHANGED_HELP); checkGenerateUnsatCores(); @@ -177,7 +188,7 @@ protected abstract boolean isUnsatWithAssumptionsImpl(Collection @Override public final Model getModel() throws SolverException { checkState(!closed); - checkState(!shouldShutdown(), getShutdownReason()); + checkShutdownState(); checkState(wasLastSatCheckSat, NO_MODEL_HELP); checkState(!stackChangedSinceLastQuery, STACK_CHANGED_HELP); checkGenerateModels(); @@ -189,7 +200,7 @@ public final Model getModel() throws SolverException { @Override public final Evaluator getEvaluator() throws SolverException { checkState(!closed); - checkState(!shouldShutdown(), getShutdownReason()); + checkShutdownState(); checkState(wasLastSatCheckSat, NO_MODEL_HELP); checkState(!stackChangedSinceLastQuery, STACK_CHANGED_HELP); checkGenerateModels(); @@ -214,7 +225,7 @@ public final void push() throws InterruptedException { @Override public final void pop() { checkState(!closed); - checkState(!shouldShutdown(), getShutdownReason()); + checkShutdownState(); checkState(assertedFormulas.size() > 1, "initial level must remain until close"); assertedFormulas.remove(assertedFormulas.size() - 1); // remove last // TODO: technically only needed if the level removed was non empty. @@ -277,7 +288,7 @@ protected void closeAllEvaluators() { @Override public ImmutableList getModelAssignments() throws SolverException { Preconditions.checkState(!closed); - checkState(!shouldShutdown(), getShutdownReason()); + checkShutdownState(); Preconditions.checkState(!stackChangedSinceLastQuery, STACK_CHANGED_HELP); checkState(wasLastSatCheckSat); try (Model model = getModel()) { From 1f5c86669fa9acd8f1400a35076473c13a241bc0 Mon Sep 17 00:00:00 2001 From: BaierD Date: Wed, 25 Jun 2025 19:59:05 +0200 Subject: [PATCH 46/87] Reduce args for CVC5InterpolatingProver constructor --- .../solvers/cvc5/CVC5InterpolatingProver.java | 10 +++++----- .../java_smt/solvers/cvc5/CVC5SolverContext.java | 13 ++++++++++--- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5InterpolatingProver.java b/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5InterpolatingProver.java index 44217c5604..7eeb41f705 100644 --- a/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5InterpolatingProver.java +++ b/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5InterpolatingProver.java @@ -32,6 +32,7 @@ import org.sosy_lab.java_smt.api.InterpolatingProverEnvironment; import org.sosy_lab.java_smt.api.SolverContext.ProverOptions; import org.sosy_lab.java_smt.api.SolverException; +import org.sosy_lab.java_smt.solvers.cvc5.CVC5SolverContext.CVC5Settings; public class CVC5InterpolatingProver extends CVC5AbstractProver implements InterpolatingProverEnvironment { @@ -52,8 +53,7 @@ public class CVC5InterpolatingProver extends CVC5AbstractProver int randomSeed, Set pOptions, FormulaManager pMgr, - ImmutableMap pFurtherOptionsMap, - boolean pValidateInterpolants) { + CVC5Settings settings) { super( pFormulaCreator, pContextShutdownNotifier, @@ -61,13 +61,13 @@ public class CVC5InterpolatingProver extends CVC5AbstractProver randomSeed, pOptions, pMgr, - pFurtherOptionsMap); + settings.getFurtherOptions()); mgr = pMgr; solverOptions = pOptions; seed = randomSeed; bmgr = (CVC5BooleanFormulaManager) mgr.getBooleanFormulaManager(); - validateInterpolants = pValidateInterpolants; - furtherOptionsMap = pFurtherOptionsMap; + validateInterpolants = settings.isValidateInterpolants(); + furtherOptionsMap = settings.getFurtherOptions(); } /** diff --git a/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5SolverContext.java b/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5SolverContext.java index 2d46fc0f13..3a7acf1ebc 100644 --- a/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5SolverContext.java +++ b/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5SolverContext.java @@ -39,7 +39,7 @@ public final class CVC5SolverContext extends AbstractSolverContext { @Options(prefix = "solver.cvc5") - private static final class CVC5Settings { + public static final class CVC5Settings { @Option( secure = true, @@ -71,6 +71,14 @@ private CVC5Settings(Configuration config) throws InvalidConfigurationException "Invalid CVC5 option in \"" + furtherOptions + "\": " + e.getMessage(), e); } } + + ImmutableMap getFurtherOptions() { + return furtherOptionsMap; + } + + boolean isValidateInterpolants() { + return validateInterpolants; + } } // creator is final, except after closing, then null. @@ -257,8 +265,7 @@ protected InterpolatingProverEnvironment newProverEnvironmentWithInterpolatio randomSeed, pOptions, getFormulaManager(), - settings.furtherOptionsMap, - settings.validateInterpolants); + settings); } @Override From 676aebbf8837b655a59afe9210611f1ac253215d Mon Sep 17 00:00:00 2001 From: BaierD Date: Wed, 25 Jun 2025 20:51:17 +0200 Subject: [PATCH 47/87] Apply refaster patch --- src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java index d227f947d9..e6003fabad 100644 --- a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java +++ b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java @@ -89,10 +89,10 @@ protected final boolean shouldShutdown() { } private void checkShutdownState() { - // Refaster forced me to do this! if (shouldShutdown()) { String reason = getShutdownReason(); - checkState(!shouldShutdown(), reason); + // Refaster forced me to do this! + checkState(!shouldShutdown(), /* TODO make lazy */ reason); } } From 65407fb8bf7bb47a750017f994cdc06f8c8d6fa7 Mon Sep 17 00:00:00 2001 From: BaierD Date: Thu, 26 Jun 2025 17:00:56 +0200 Subject: [PATCH 48/87] Switch to lazy and self implemented shutdown state check --- src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java index e6003fabad..cde89381f3 100644 --- a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java +++ b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java @@ -24,6 +24,7 @@ import java.util.Optional; import java.util.Set; import org.checkerframework.checker.nullness.qual.Nullable; +import org.sosy_lab.common.MoreStrings; import org.sosy_lab.common.ShutdownNotifier; import org.sosy_lab.java_smt.api.BasicProverEnvironment; import org.sosy_lab.java_smt.api.BooleanFormula; @@ -88,11 +89,9 @@ protected final boolean shouldShutdown() { return contextShutdownNotifier.shouldShutdown(); } - private void checkShutdownState() { + public void checkShutdownState() { if (shouldShutdown()) { - String reason = getShutdownReason(); - // Refaster forced me to do this! - checkState(!shouldShutdown(), /* TODO make lazy */ reason); + throw new IllegalStateException(MoreStrings.lazyString(this::getShutdownReason).toString()); } } From 2e83b93736ffe0682783c42a8aa194041b1c7c02 Mon Sep 17 00:00:00 2001 From: BaierD Date: Thu, 26 Jun 2025 17:55:18 +0200 Subject: [PATCH 49/87] Centralize getInterpolant ID checking and also give back the mismatched IDs in case of errors --- .../java_smt/basicimpl/AbstractProver.java | 14 ++++++++++++++ .../mathsat5/Mathsat5InterpolatingProver.java | 4 +--- .../opensmt/OpenSmtInterpolatingProver.java | 4 +--- .../princess/PrincessInterpolatingProver.java | 4 +--- .../SmtInterpolInterpolatingProver.java | 4 +--- 5 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java index cde89381f3..2d64c196c4 100644 --- a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java +++ b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java @@ -8,6 +8,7 @@ package org.sosy_lab.java_smt.basicimpl; +import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkState; import com.google.common.base.Preconditions; @@ -266,6 +267,19 @@ protected ImmutableSet getAssertedConstraintIds() { return builder.build(); } + protected void checkInterpolationArguments(Collection formulasOfA) { + checkArgument( + getAssertedConstraintIds().containsAll(formulasOfA), + "interpolation can only be done over previously asserted formulas. Missing IDs: %s", + MoreStrings.lazyString( + () -> + formulasOfA.stream() + .filter(e -> !getAssertedConstraintIds().contains(e)) + .collect(ImmutableSet.toImmutableSet()) + .toString()) + .toString()); + } + /** * This method registers the Evaluator to be cleaned up before the next change on the prover * stack. diff --git a/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5InterpolatingProver.java b/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5InterpolatingProver.java index cfd2c425ad..d9a8d47201 100644 --- a/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5InterpolatingProver.java +++ b/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5InterpolatingProver.java @@ -108,9 +108,7 @@ public BooleanFormula getInterpolant(Collection formulasOfA) shutdownIfNecessary(); checkState(!wasLastSatCheckSat); checkState(!stackChangedSinceLastQuery); - checkArgument( - getAssertedConstraintIds().containsAll(formulasOfA), - "interpolation can only be done over previously asserted formulas."); + checkInterpolationArguments(formulasOfA); int[] groupsOfA = Ints.toArray(formulasOfA); long itp; diff --git a/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtInterpolatingProver.java b/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtInterpolatingProver.java index 0cf242311d..aadfdb46c6 100644 --- a/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtInterpolatingProver.java +++ b/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtInterpolatingProver.java @@ -82,9 +82,7 @@ public BooleanFormula getInterpolant(Collection formulasOfA) shutdownIfNecessary(); checkState(!wasLastSatCheckSat); checkState(!stackChangedSinceLastQuery); - checkArgument( - getAssertedConstraintIds().containsAll(formulasOfA), - "interpolation can only be done over previously asserted formulas."); + checkInterpolationArguments(formulasOfA); return creator.encapsulateBoolean( osmtSolver.getInterpolationContext().getSingleInterpolant(new VectorInt(formulasOfA))); diff --git a/src/org/sosy_lab/java_smt/solvers/princess/PrincessInterpolatingProver.java b/src/org/sosy_lab/java_smt/solvers/princess/PrincessInterpolatingProver.java index 37fa04b726..3cff548d05 100644 --- a/src/org/sosy_lab/java_smt/solvers/princess/PrincessInterpolatingProver.java +++ b/src/org/sosy_lab/java_smt/solvers/princess/PrincessInterpolatingProver.java @@ -59,9 +59,7 @@ protected Integer addConstraintImpl(BooleanFormula constraint) throws Interrupte @Override public BooleanFormula getInterpolant(Collection pTermNamesOfA) throws SolverException { Preconditions.checkState(!closed); - checkArgument( - getAssertedConstraintIds().containsAll(pTermNamesOfA), - "interpolation can only be done over previously asserted formulas."); + checkInterpolationArguments(pTermNamesOfA); Set indexesOfA = ImmutableSet.copyOf(pTermNamesOfA); diff --git a/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolInterpolatingProver.java b/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolInterpolatingProver.java index 8726d9b6c9..e2a596f33b 100644 --- a/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolInterpolatingProver.java +++ b/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolInterpolatingProver.java @@ -54,9 +54,7 @@ public BooleanFormula getInterpolant(Collection pTermNamesOfA) shutdownIfNecessary(); checkState(!wasLastSatCheckSat); checkState(!stackChangedSinceLastQuery); - checkArgument( - getAssertedConstraintIds().containsAll(pTermNamesOfA), - "interpolation can only be done over previously asserted formulas."); + checkInterpolationArguments(pTermNamesOfA); // SMTInterpol is not able to handle the trivial cases, // so we need to check them explicitly From ee5eee08543c994e29ac70a698606b646d7bf01a Mon Sep 17 00:00:00 2001 From: BaierD Date: Thu, 26 Jun 2025 17:55:26 +0200 Subject: [PATCH 50/87] Centralize getInterpolant ID checking and also give back the mismatched IDs in case of errors (2) --- .../java_smt/solvers/cvc5/CVC5InterpolatingProver.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5InterpolatingProver.java b/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5InterpolatingProver.java index 7eeb41f705..ddebf33846 100644 --- a/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5InterpolatingProver.java +++ b/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5InterpolatingProver.java @@ -96,9 +96,7 @@ public BooleanFormula getInterpolant(Collection pFormulasOfA) shutdownIfNecessary(); checkState(!wasLastSatCheckSat); checkState(!stackChangedSinceLastQuery); - checkArgument( - getAssertedConstraintIds().containsAll(pFormulasOfA), - "interpolation can only be done over previously asserted formulas."); + checkInterpolationArguments(pFormulasOfA); final Set assertedFormulas = transformedImmutableSetCopy(getAssertedFormulas(), creator::extractInfo); From c1dc784972d2d0b99542be0c5abef20dae030917 Mon Sep 17 00:00:00 2001 From: BaierD Date: Thu, 26 Jun 2025 17:56:00 +0200 Subject: [PATCH 51/87] Correctly reset assumptions for interpolation in the assumption wrapper with interrupt handling --- .../InterpolatingProverWithAssumptionsWrapper.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/org/sosy_lab/java_smt/basicimpl/withAssumptionsWrapper/InterpolatingProverWithAssumptionsWrapper.java b/src/org/sosy_lab/java_smt/basicimpl/withAssumptionsWrapper/InterpolatingProverWithAssumptionsWrapper.java index 40f5e4e18e..240aed11bb 100644 --- a/src/org/sosy_lab/java_smt/basicimpl/withAssumptionsWrapper/InterpolatingProverWithAssumptionsWrapper.java +++ b/src/org/sosy_lab/java_smt/basicimpl/withAssumptionsWrapper/InterpolatingProverWithAssumptionsWrapper.java @@ -86,6 +86,12 @@ protected void clearAssumptions() { solverAssumptionsFromPush.clear(); } + @Override + protected void clearAssumptionsWithInterruptedException() throws InterruptedException { + super.clearAssumptionsWithInterruptedException(); + solverAssumptionsFromPush.clear(); + } + final class RemoveAssumptionsFromFormulaVisitor extends BooleanFormulaTransformationVisitor { private RemoveAssumptionsFromFormulaVisitor() { From 41daa1f4e41f398826629417f41ee7d95de60d56 Mon Sep 17 00:00:00 2001 From: BaierD Date: Thu, 26 Jun 2025 17:56:48 +0200 Subject: [PATCH 52/87] Remove unneeded lazy handling of error msg --- src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java index 2d64c196c4..5b738d972b 100644 --- a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java +++ b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java @@ -92,7 +92,7 @@ protected final boolean shouldShutdown() { public void checkShutdownState() { if (shouldShutdown()) { - throw new IllegalStateException(MoreStrings.lazyString(this::getShutdownReason).toString()); + throw new IllegalStateException(getShutdownReason()); } } From d06d41c5e9450bf49fd3717384c49a9d9bbe3c32 Mon Sep 17 00:00:00 2001 From: BaierD Date: Thu, 26 Jun 2025 19:01:06 +0200 Subject: [PATCH 53/87] Extend TimeoutTest with checking for all prover API, including interpolation and optimization (optimization currently not included in the tests, but the tests can handle it) --- .../sosy_lab/java_smt/test/TimeoutTest.java | 330 ++++++++++++------ 1 file changed, 231 insertions(+), 99 deletions(-) diff --git a/src/org/sosy_lab/java_smt/test/TimeoutTest.java b/src/org/sosy_lab/java_smt/test/TimeoutTest.java index 5ae9e9a87e..36a3628cf5 100644 --- a/src/org/sosy_lab/java_smt/test/TimeoutTest.java +++ b/src/org/sosy_lab/java_smt/test/TimeoutTest.java @@ -19,7 +19,6 @@ import java.util.Random; import java.util.function.Supplier; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -305,28 +304,74 @@ public void testContextInterruptWithSubsequentProverWithNotifierUsageInt() } // Test shutdown of prover and subsequent feature usage. - @Ignore @Test(timeout = TIMEOUT_MILLISECONDS) - public void testProverInterruptWithSubsequentFeatureUsageBv() throws InterruptedException { + public void testProverInterruptWithSubsequentFeatureUsageBv() + throws InterruptedException, SolverException { requireBitvectors(); requireIsolatedProverShutdown(); ShutdownManager sm1 = ShutdownManager.create(); ShutdownManager sm2 = ShutdownManager.create(); ShutdownManager sm3 = ShutdownManager.create(); - - try (BasicProverEnvironment pe1 = context.newProverEnvironment(sm1.getNotifier())) { + ShutdownManager sm4 = ShutdownManager.create(); + + try (BasicProverEnvironment pe1 = + context.newProverEnvironment( + sm1.getNotifier(), + ProverOptions.GENERATE_UNSAT_CORE, + ProverOptions.GENERATE_MODELS, + ProverOptions.GENERATE_ALL_SAT, + ProverOptions.GENERATE_UNSAT_CORE_OVER_ASSUMPTIONS)) { assertProverAPIUsable(pe1); - try (BasicProverEnvironment pe2 = context.newProverEnvironment(sm2.getNotifier())) { + try (BasicProverEnvironment pe2 = + context.newProverEnvironment( + sm2.getNotifier(), + ProverOptions.GENERATE_UNSAT_CORE, + ProverOptions.GENERATE_MODELS, + ProverOptions.GENERATE_ALL_SAT, + ProverOptions.GENERATE_UNSAT_CORE_OVER_ASSUMPTIONS)) { assertProverAPIUsable(pe2); testBasicProverTimeoutWithFeatureUsageBv( - () -> context.newProverEnvironment(sm3.getNotifier()), sm3); - assertThat(shutdownManager.getNotifier().shouldShutdown()).isTrue(); + () -> + context.newProverEnvironment( + sm3.getNotifier(), + ProverOptions.GENERATE_UNSAT_CORE, + ProverOptions.GENERATE_MODELS, + ProverOptions.GENERATE_ALL_SAT, + ProverOptions.GENERATE_UNSAT_CORE_OVER_ASSUMPTIONS), + sm3); + assertThat(shutdownManager.getNotifier().shouldShutdown()).isFalse(); assertThat(sm1.getNotifier().shouldShutdown()).isFalse(); assertThat(sm2.getNotifier().shouldShutdown()).isFalse(); assertThat(sm3.getNotifier().shouldShutdown()).isTrue(); + assertThat(sm4.getNotifier().shouldShutdown()).isFalse(); + + boolean notifier4Shutdown = true; + + try { + testBasicProverTimeoutWithFeatureUsageBv( + () -> + context.newProverEnvironmentWithInterpolation( + sm4.getNotifier(), + ProverOptions.GENERATE_UNSAT_CORE, + ProverOptions.GENERATE_MODELS, + ProverOptions.GENERATE_ALL_SAT, + ProverOptions.GENERATE_UNSAT_CORE_OVER_ASSUMPTIONS), + sm4); + } catch (UnsupportedOperationException ignore) { + // Do nothing, not supported + notifier4Shutdown = false; + } + + // TODO: optimization (or prover gen as test param?) + + assertThat(shutdownManager.getNotifier().shouldShutdown()).isFalse(); + assertThat(sm1.getNotifier().shouldShutdown()).isFalse(); + assertThat(sm2.getNotifier().shouldShutdown()).isFalse(); + assertThat(sm3.getNotifier().shouldShutdown()).isTrue(); + assertThat(sm4.getNotifier().shouldShutdown()).isEqualTo(notifier4Shutdown); assertProverAPIUsable(pe2); } @@ -335,21 +380,37 @@ public void testProverInterruptWithSubsequentFeatureUsageBv() throws Interrupted } // Test shutdown of prover and subsequent feature usage. - @Ignore @Test(timeout = TIMEOUT_MILLISECONDS) - public void testContextInterruptWithSubsequentFeatureUsageInt() throws InterruptedException { + public void testProverInterruptWithSubsequentFeatureUsageInt() + throws InterruptedException, SolverException { requireIntegers(); requireIsolatedProverShutdown(); ShutdownManager sm1 = ShutdownManager.create(); ShutdownManager sm2 = ShutdownManager.create(); ShutdownManager sm3 = ShutdownManager.create(); + ShutdownManager sm4 = ShutdownManager.create(); + + try (BasicProverEnvironment pe1 = + context.newProverEnvironment( + sm1.getNotifier(), + ProverOptions.GENERATE_UNSAT_CORE, + ProverOptions.GENERATE_MODELS, + ProverOptions.GENERATE_ALL_SAT, + ProverOptions.GENERATE_UNSAT_CORE_OVER_ASSUMPTIONS)) { - try (BasicProverEnvironment pe1 = context.newProverEnvironment(sm1.getNotifier())) { assertProverAPIUsable(pe1); - try (BasicProverEnvironment pe2 = context.newProverEnvironment(sm2.getNotifier())) { + + try (BasicProverEnvironment pe2 = + context.newProverEnvironment( + sm2.getNotifier(), + ProverOptions.GENERATE_UNSAT_CORE, + ProverOptions.GENERATE_MODELS, + ProverOptions.GENERATE_ALL_SAT, + ProverOptions.GENERATE_UNSAT_CORE_OVER_ASSUMPTIONS)) { assertProverAPIUsable(pe2); + // Test Shutdown of prover with notifier sm3 testBasicProverTimeoutWithFeatureUsageInt( () -> context.newProverEnvironment( @@ -360,10 +421,42 @@ public void testContextInterruptWithSubsequentFeatureUsageInt() throws Interrupt ProverOptions.GENERATE_UNSAT_CORE_OVER_ASSUMPTIONS), sm3); - assertThat(shutdownManager.getNotifier().shouldShutdown()).isTrue(); + assertThat(shutdownManager.getNotifier().shouldShutdown()).isFalse(); + assertThat(sm1.getNotifier().shouldShutdown()).isFalse(); + assertThat(sm2.getNotifier().shouldShutdown()).isFalse(); + assertThat(sm3.getNotifier().shouldShutdown()).isTrue(); + assertThat(sm4.getNotifier().shouldShutdown()).isFalse(); + + boolean notifier4Shutdown = true; + + try { + testBasicProverTimeoutWithFeatureUsageInt( + () -> + context.newProverEnvironmentWithInterpolation( + sm4.getNotifier(), + ProverOptions.GENERATE_UNSAT_CORE, + ProverOptions.GENERATE_MODELS, + ProverOptions.GENERATE_ALL_SAT, + ProverOptions.GENERATE_UNSAT_CORE_OVER_ASSUMPTIONS), + sm4); + } catch (UnsupportedOperationException ignore) { + // Do nothing, not supported + notifier4Shutdown = false; + } + + assertThat(shutdownManager.getNotifier().shouldShutdown()).isFalse(); + assertThat(sm1.getNotifier().shouldShutdown()).isFalse(); + assertThat(sm2.getNotifier().shouldShutdown()).isFalse(); + assertThat(sm3.getNotifier().shouldShutdown()).isTrue(); + assertThat(sm4.getNotifier().shouldShutdown()).isEqualTo(notifier4Shutdown); + + // TODO: optimization (or prover gen as test param?) + + assertThat(shutdownManager.getNotifier().shouldShutdown()).isFalse(); assertThat(sm1.getNotifier().shouldShutdown()).isFalse(); assertThat(sm2.getNotifier().shouldShutdown()).isFalse(); assertThat(sm3.getNotifier().shouldShutdown()).isTrue(); + assertThat(sm4.getNotifier().shouldShutdown()).isEqualTo(notifier4Shutdown); assertProverAPIUsable(pe2); } @@ -425,7 +518,7 @@ private void testBasicProverTimeoutBv( */ private void testBasicProverTimeoutWithFeatureUsageInt( Supplier> proverConstructor, ShutdownManager managerToInterrupt) - throws InterruptedException { + throws InterruptedException, SolverException { HardIntegerFormulaGenerator gen = new HardIntegerFormulaGenerator(imgr, bmgr); testProverBasedTimeoutWithFeatures(proverConstructor, gen.generate(200), managerToInterrupt); } @@ -436,7 +529,7 @@ private void testBasicProverTimeoutWithFeatureUsageInt( */ private void testBasicProverTimeoutWithFeatureUsageBv( Supplier> proverConstructor, ShutdownManager managerToInterrupt) - throws InterruptedException { + throws InterruptedException, SolverException { HardBitvectorFormulaGenerator gen = new HardBitvectorFormulaGenerator(bvmgr, bmgr); testProverBasedTimeoutWithFeatures(proverConstructor, gen.generate(200), managerToInterrupt); } @@ -494,7 +587,7 @@ private void testProverBasedTimeoutWithFeatures( Supplier> proverConstructor, BooleanFormula instance, ShutdownManager managerToInterrupt) - throws InterruptedException { + throws InterruptedException, SolverException { // TODO: maybe add a test that solves something correctly before interrupting? @@ -519,31 +612,37 @@ private void testProverBasedTimeoutWithFeatures( * This always starts with isUnsat() that should be interrupted (either while solving or before). * The correct options for the usage of UnsatCore and UnsatCoreOverAssumptions have not to be set! */ - private void assertProverAPIThrowsInterruptedException(BasicProverEnvironment pe) { + @SuppressWarnings("CheckReturnValue") + private void assertProverAPIThrowsInterruptedException(BasicProverEnvironment pe) + throws SolverException { assertThrows(InterruptedException.class, pe::isUnsat); - assertThrows(InterruptedException.class, pe::getModel); - assertThrows(InterruptedException.class, pe::getModelAssignments); - assertThrows(InterruptedException.class, pe::getEvaluator); - assertThrows(InterruptedException.class, pe::getUnsatCore); - assertThrows( - InterruptedException.class, - () -> - pe.allSat( - new AllSatCallback<>() { - - private final List> models = new ArrayList<>(); - - @Override - public void apply(List pModel) { - models.add(pModel); - } - - @Override - public List> getResult() { - return models; - } - }, - ImmutableList.of(bmgr.makeFalse()))); + // TODO: let all the API in prover throw interrupted? + assertThrows(IllegalStateException.class, pe::getModel); + assertThrows(IllegalStateException.class, pe::getModelAssignments); + assertThrows(IllegalStateException.class, pe::getEvaluator); + assertThrows(IllegalStateException.class, pe::getUnsatCore); + try { + pe.allSat( + new AllSatCallback<>() { + + private final List> models = new ArrayList<>(); + + @Override + public void apply(List pModel) { + models.add(pModel); + } + + @Override + public List> getResult() { + return models; + } + }, + ImmutableList.of(bmgr.makeFalse())); + } catch (UnsupportedOperationException ignore) { + // Feature not supported + } catch (InterruptedException expected) { + assertThat(expected).isNotNull(); + } assertThrows( InterruptedException.class, () -> pe.unsatCoreOverAssumptions(ImmutableList.of(bmgr.makeFalse()))); @@ -551,20 +650,42 @@ public List> getResult() { InterruptedException.class, () -> pe.isUnsatWithAssumptions(ImmutableList.of(bmgr.makeFalse()))); assertThrows(InterruptedException.class, () -> pe.addConstraint(bmgr.makeFalse())); + + assertThrows(InterruptedException.class, () -> pe.addConstraint(bmgr.makeFalse())); assertThrows(InterruptedException.class, () -> pe.push(bmgr.makeFalse())); assertThrows(InterruptedException.class, pe::push); - assertThrows(InterruptedException.class, pe::pop); + assertThrows(IllegalStateException.class, pe::pop); if (pe instanceof InterpolatingProverEnvironment) { InterpolatingProverEnvironment ipe = (InterpolatingProverEnvironment) pe; assertThrows(InterruptedException.class, () -> ipe.getInterpolant(ImmutableList.of())); - assertThrows(InterruptedException.class, () -> ipe.getSeqInterpolants(ImmutableList.of())); - assertThrows(InterruptedException.class, () -> ipe.getSeqInterpolants0(ImmutableList.of())); - assertThrows( - InterruptedException.class, - () -> ipe.getTreeInterpolants(ImmutableList.of(), new int[] {0})); - assertThrows( - InterruptedException.class, - () -> ipe.getTreeInterpolants0(ImmutableList.of(), new int[] {0})); + try { + ipe.getSeqInterpolants(ImmutableList.of()); + } catch (UnsupportedOperationException ignore) { + // Feature not supported + } catch (InterruptedException expected) { + assertThat(expected).isNotNull(); + } + try { + ipe.getSeqInterpolants0(ImmutableList.of()); + } catch (UnsupportedOperationException ignore) { + // Feature not supported + } catch (InterruptedException expected) { + assertThat(expected).isNotNull(); + } + try { + ipe.getTreeInterpolants(ImmutableList.of(), new int[] {0}); + } catch (UnsupportedOperationException ignore) { + // Feature not supported + } catch (InterruptedException expected) { + assertThat(expected).isNotNull(); + } + try { + ipe.getTreeInterpolants0(ImmutableList.of(), new int[] {0}); + } catch (UnsupportedOperationException ignore) { + // Feature not supported + } catch (InterruptedException expected) { + assertThat(expected).isNotNull(); + } } if (pe instanceof OptimizationProverEnvironment) { OptimizationProverEnvironment ope = (OptimizationProverEnvironment) pe; @@ -577,61 +698,72 @@ public List> getResult() { } } - private void assertProverAPIUsable(BasicProverEnvironment pe) { - assertThrows(InterruptedException.class, pe::isUnsat); - assertThrows(InterruptedException.class, pe::getModel); - assertThrows(InterruptedException.class, pe::getModelAssignments); - assertThrows(InterruptedException.class, pe::getEvaluator); - assertThrows(InterruptedException.class, pe::getUnsatCore); - assertThrows( - InterruptedException.class, - () -> - pe.allSat( - new AllSatCallback<>() { - - private final List> models = new ArrayList<>(); - - @Override - public void apply(List pModel) { - models.add(pModel); - } - - @Override - public List> getResult() { - return models; - } - }, - ImmutableList.of(bmgr.makeFalse()))); - assertThrows( - InterruptedException.class, - () -> pe.unsatCoreOverAssumptions(ImmutableList.of(bmgr.makeFalse()))); - assertThrows( - InterruptedException.class, - () -> pe.isUnsatWithAssumptions(ImmutableList.of(bmgr.makeFalse()))); - assertThrows(InterruptedException.class, () -> pe.addConstraint(bmgr.makeFalse())); - assertThrows(InterruptedException.class, () -> pe.push(bmgr.makeFalse())); - assertThrows(InterruptedException.class, pe::push); - assertThrows(InterruptedException.class, pe::pop); + @SuppressWarnings("CheckReturnValue") + private void assertProverAPIUsable(BasicProverEnvironment pe) + throws SolverException, InterruptedException { + pe.addConstraint(bmgr.makeTrue()); + pe.isUnsat(); + pe.getModel().close(); + pe.getModelAssignments(); + pe.getEvaluator().close(); + try { + pe.allSat( + new AllSatCallback<>() { + + private final List> models = new ArrayList<>(); + + @Override + public void apply(List pModel) { + models.add(pModel); + } + + @Override + public List> getResult() { + return models; + } + }, + ImmutableList.of(bmgr.makeTrue())); + } catch (SolverException allowed) { + assertThat(allowed.getMessage()) + .isEqualTo( + "Error occurred during Mathsat allsat: allsat is " + + "not compatible with proof generation"); + } + + pe.push(); + pe.pop(); + pe.push(bmgr.makeFalse()); + pe.isUnsat(); + pe.getUnsatCore(); + + try { + pe.unsatCoreOverAssumptions(ImmutableList.of(bmgr.makeFalse())); + } catch (UnsupportedOperationException ignore) { + // Do nothing, solver does not support this feature + } + try { + pe.isUnsatWithAssumptions(ImmutableList.of(bmgr.makeFalse())); + } catch (UnsupportedOperationException ignore) { + // Do nothing, solver does not support this feature + } + pe.pop(); // Reset to SAT for repeated usage + if (pe instanceof InterpolatingProverEnvironment) { InterpolatingProverEnvironment ipe = (InterpolatingProverEnvironment) pe; - assertThrows(InterruptedException.class, () -> ipe.getInterpolant(ImmutableList.of())); - assertThrows(InterruptedException.class, () -> ipe.getSeqInterpolants(ImmutableList.of())); - assertThrows(InterruptedException.class, () -> ipe.getSeqInterpolants0(ImmutableList.of())); - assertThrows( - InterruptedException.class, - () -> ipe.getTreeInterpolants(ImmutableList.of(), new int[] {0})); - assertThrows( - InterruptedException.class, - () -> ipe.getTreeInterpolants0(ImmutableList.of(), new int[] {0})); + ipe.getInterpolant(ImmutableList.of()); + ipe.getSeqInterpolants(ImmutableList.of()); + ipe.getSeqInterpolants0(ImmutableList.of()); + ipe.getTreeInterpolants(ImmutableList.of(), new int[] {0}); + ipe.getTreeInterpolants0(ImmutableList.of(), new int[] {0}); } if (pe instanceof OptimizationProverEnvironment) { OptimizationProverEnvironment ope = (OptimizationProverEnvironment) pe; - assertThrows(InterruptedException.class, () -> ope.maximize(bmgr.makeFalse())); - assertThrows(InterruptedException.class, () -> ope.minimize(bmgr.makeFalse())); - assertThrows(InterruptedException.class, ope::check); - assertThrows(InterruptedException.class, () -> ope.upper(1, Rational.ZERO)); - assertThrows(InterruptedException.class, () -> ope.lower(1, Rational.ZERO)); - assertThrows(InterruptedException.class, ope::getModel); + ope.maximize(bmgr.makeFalse()); + ope.minimize(bmgr.makeFalse()); + ope.check(); + ope.upper(1, Rational.ZERO); + ope.lower(1, Rational.ZERO); + ope.getModel().close(); } } } From 4a4cac81fca7db7db9b5b382b946219812a1dbc8 Mon Sep 17 00:00:00 2001 From: BaierD Date: Mon, 30 Jun 2025 13:12:37 +0200 Subject: [PATCH 54/87] Improve interpolation input error messages by including a null check and error msg --- .../java_smt/basicimpl/AbstractProver.java | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java index 5b738d972b..b7c450affe 100644 --- a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java +++ b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java @@ -270,14 +270,20 @@ protected ImmutableSet getAssertedConstraintIds() { protected void checkInterpolationArguments(Collection formulasOfA) { checkArgument( getAssertedConstraintIds().containsAll(formulasOfA), - "interpolation can only be done over previously asserted formulas. Missing IDs: %s", - MoreStrings.lazyString( - () -> - formulasOfA.stream() - .filter(e -> !getAssertedConstraintIds().contains(e)) - .collect(ImmutableSet.toImmutableSet()) - .toString()) - .toString()); + "Interpolation can only be done over previously asserted formulas. %s", + MoreStrings.lazyString(() -> getErrorString(formulasOfA)).toString()); + } + + private String getErrorString(Collection formulasOfA) { + ImmutableSet.Builder builder = ImmutableSet.builder(); + for (T formula : formulasOfA) { + if (formula == null) { + return "Null element found, but not allowed."; + } else { + builder.add(formula); + } + } + return "Missing IDs: " + builder.build(); } /** From 0c683e8c471fc1f4e28cabeb07a1520d0e88c100 Mon Sep 17 00:00:00 2001 From: BaierD Date: Mon, 30 Jun 2025 13:15:09 +0200 Subject: [PATCH 55/87] Reduce query size for timeout test (was unnecessarily high) --- src/org/sosy_lab/java_smt/test/TimeoutTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/org/sosy_lab/java_smt/test/TimeoutTest.java b/src/org/sosy_lab/java_smt/test/TimeoutTest.java index 36a3628cf5..e8668f6322 100644 --- a/src/org/sosy_lab/java_smt/test/TimeoutTest.java +++ b/src/org/sosy_lab/java_smt/test/TimeoutTest.java @@ -124,7 +124,7 @@ public void testProverInterruptWithSubsequentNewProverUsageBv() HardBitvectorFormulaGenerator gen = new HardBitvectorFormulaGenerator(bvmgr, bmgr); try (BasicProverEnvironment pe = context.newProverEnvironment()) { - pe.push(gen.generate(8)); + pe.push(gen.generate(3)); assertThat(pe.isUnsat()).isTrue(); } } @@ -144,7 +144,7 @@ public void testProverInterruptWithSubsequentNewProverUsageInt() HardIntegerFormulaGenerator gen = new HardIntegerFormulaGenerator(imgr, bmgr); try (BasicProverEnvironment pe = context.newProverEnvironment()) { - pe.push(gen.generate(8)); + pe.push(gen.generate(3)); assertThat(pe.isUnsat()).isTrue(); } } From 79ba7d7e1826f5dbfe6b53297d551d7c88757f2a Mon Sep 17 00:00:00 2001 From: BaierD Date: Mon, 30 Jun 2025 13:45:17 +0200 Subject: [PATCH 56/87] Rename shutdownManagers in tests to make their use/source more clear --- .../sosy_lab/java_smt/test/DebugModeTest.java | 2 +- .../java_smt/test/SolverBasedTest0.java | 8 +- .../java_smt/test/SolverContextTest.java | 7 +- .../sosy_lab/java_smt/test/TimeoutTest.java | 173 ++++++++++-------- 4 files changed, 102 insertions(+), 88 deletions(-) diff --git a/src/org/sosy_lab/java_smt/test/DebugModeTest.java b/src/org/sosy_lab/java_smt/test/DebugModeTest.java index f6d5ea092c..5898f5f4a0 100644 --- a/src/org/sosy_lab/java_smt/test/DebugModeTest.java +++ b/src/org/sosy_lab/java_smt/test/DebugModeTest.java @@ -54,7 +54,7 @@ public void init() throws InvalidConfigurationException { .setOption("solver.solver", solverToUse().toString()) .setOption("solver.useDebugMode", String.valueOf(true)) .build(); - debugFactory = new SolverContextFactory(debugConfig, logger, shutdownNotifierToUse()); + debugFactory = new SolverContextFactory(debugConfig, logger, contextShutdownNotifierToUse()); debugContext = debugFactory.generateContext(); FormulaManager debugMgr = debugContext.getFormulaManager(); diff --git a/src/org/sosy_lab/java_smt/test/SolverBasedTest0.java b/src/org/sosy_lab/java_smt/test/SolverBasedTest0.java index 6e2b81dc5b..257f19569b 100644 --- a/src/org/sosy_lab/java_smt/test/SolverBasedTest0.java +++ b/src/org/sosy_lab/java_smt/test/SolverBasedTest0.java @@ -104,10 +104,10 @@ public abstract class SolverBasedTest0 { protected @Nullable FloatingPointFormulaManager fpmgr; protected @Nullable StringFormulaManager smgr; protected @Nullable EnumerationFormulaManager emgr; - protected ShutdownManager shutdownManager = ShutdownManager.create(); + protected ShutdownManager contextShutdownManager = ShutdownManager.create(); - protected ShutdownNotifier shutdownNotifierToUse() { - return shutdownManager.getNotifier(); + protected ShutdownNotifier contextShutdownNotifierToUse() { + return contextShutdownManager.getNotifier(); } /** @@ -136,7 +136,7 @@ protected ConfigurationBuilder createTestConfigBuilder() { public final void initSolver() throws InvalidConfigurationException { config = createTestConfigBuilder().build(); - factory = new SolverContextFactory(config, logger, shutdownNotifierToUse()); + factory = new SolverContextFactory(config, logger, contextShutdownNotifierToUse()); try { context = factory.generateContext(); } catch (InvalidConfigurationException e) { diff --git a/src/org/sosy_lab/java_smt/test/SolverContextTest.java b/src/org/sosy_lab/java_smt/test/SolverContextTest.java index 3619cd6ce4..a4bd4ccc7c 100644 --- a/src/org/sosy_lab/java_smt/test/SolverContextTest.java +++ b/src/org/sosy_lab/java_smt/test/SolverContextTest.java @@ -137,7 +137,7 @@ public void testCVC5WithValidOptions() throws InvalidConfigurationException { createTestConfigBuilder() .setOption("solver.cvc5.furtherOptions", "solve-bv-as-int=bitwise") .build(); - var factory2 = new SolverContextFactory(config2, logger, shutdownNotifierToUse()); + var factory2 = new SolverContextFactory(config2, logger, contextShutdownNotifierToUse()); try (var context2 = factory2.generateContext()) { // create and ignore } @@ -152,7 +152,8 @@ public void testCVC5WithValidOptionsTimeLimit() // tlimit-per is time limit in ms of wall clock time per query var configValid = createTestConfigBuilder().setOption("solver.cvc5.furtherOptions", "tlimit-per=1").build(); - var factoryWOption = new SolverContextFactory(configValid, logger, shutdownNotifierToUse()); + var factoryWOption = + new SolverContextFactory(configValid, logger, contextShutdownNotifierToUse()); try (SolverContext contextWTimeLimit = factoryWOption.generateContext()) { FormulaManager fmgrTimeLimit = contextWTimeLimit.getFormulaManager(); HardIntegerFormulaGenerator hifg = @@ -172,7 +173,7 @@ public void testCVC5WithInvalidOptions() throws InvalidConfigurationException { var config2 = createTestConfigBuilder().setOption("solver.cvc5.furtherOptions", "foo=bar").build(); - var factory2 = new SolverContextFactory(config2, logger, shutdownNotifierToUse()); + var factory2 = new SolverContextFactory(config2, logger, contextShutdownNotifierToUse()); assertThrows(InvalidConfigurationException.class, factory2::generateContext); } } diff --git a/src/org/sosy_lab/java_smt/test/TimeoutTest.java b/src/org/sosy_lab/java_smt/test/TimeoutTest.java index e8668f6322..44eed3afa0 100644 --- a/src/org/sosy_lab/java_smt/test/TimeoutTest.java +++ b/src/org/sosy_lab/java_smt/test/TimeoutTest.java @@ -93,7 +93,7 @@ public void testTacticTimeout() { Fuzzer fuzzer = new Fuzzer(mgr, new Random(0)); String msg = "ShutdownRequest"; BooleanFormula test = fuzzer.fuzz(20, 3); - shutdownManager.requestShutdown(msg); + contextShutdownManager.requestShutdown(msg); assertThrows(msg, InterruptedException.class, () -> mgr.applyTactic(test, Tactic.NNF)); } @@ -116,11 +116,13 @@ public void testProverInterruptWithSubsequentNewProverUsageBv() requireBitvectors(); requireIsolatedProverShutdown(); - ShutdownManager sm1 = ShutdownManager.create(); + ShutdownManager proverShutdownManager1 = ShutdownManager.create(); - testBasicProverTimeoutBv(() -> context.newProverEnvironment(sm1.getNotifier()), sm1); - assertThat(shutdownManager.getNotifier().shouldShutdown()).isFalse(); - assertThat(sm1.getNotifier().shouldShutdown()).isTrue(); + testBasicProverTimeoutBv( + () -> context.newProverEnvironment(proverShutdownManager1.getNotifier()), + proverShutdownManager1); + assertThat(contextShutdownManager.getNotifier().shouldShutdown()).isFalse(); + assertThat(proverShutdownManager1.getNotifier().shouldShutdown()).isTrue(); HardBitvectorFormulaGenerator gen = new HardBitvectorFormulaGenerator(bvmgr, bmgr); try (BasicProverEnvironment pe = context.newProverEnvironment()) { @@ -136,11 +138,13 @@ public void testProverInterruptWithSubsequentNewProverUsageInt() requireIntegers(); requireIsolatedProverShutdown(); - ShutdownManager sm1 = ShutdownManager.create(); + ShutdownManager proverShutdownManager1 = ShutdownManager.create(); - testBasicProverTimeoutInt(() -> context.newProverEnvironment(sm1.getNotifier()), sm1); - assertThat(shutdownManager.getNotifier().shouldShutdown()).isFalse(); - assertThat(sm1.getNotifier().shouldShutdown()).isTrue(); + testBasicProverTimeoutInt( + () -> context.newProverEnvironment(proverShutdownManager1.getNotifier()), + proverShutdownManager1); + assertThat(contextShutdownManager.getNotifier().shouldShutdown()).isFalse(); + assertThat(proverShutdownManager1.getNotifier().shouldShutdown()).isTrue(); HardIntegerFormulaGenerator gen = new HardIntegerFormulaGenerator(imgr, bmgr); try (BasicProverEnvironment pe = context.newProverEnvironment()) { @@ -157,7 +161,7 @@ public void testContextInterruptWithSubsequentNewProverUsageBv() throws Interrup requireBitvectors(); testBasicContextTimeoutBv(() -> context.newProverEnvironment()); - assertThat(shutdownManager.getNotifier().shouldShutdown()).isTrue(); + assertThat(contextShutdownManager.getNotifier().shouldShutdown()).isTrue(); HardBitvectorFormulaGenerator gen = new HardBitvectorFormulaGenerator(bvmgr, bmgr); try (BasicProverEnvironment pe = context.newProverEnvironment()) { @@ -172,7 +176,7 @@ public void testContextInterruptWithSubsequentNewProverUsageInt() throws Interru requireIntegers(); testBasicContextTimeoutInt(() -> context.newProverEnvironment()); - assertThat(shutdownManager.getNotifier().shouldShutdown()).isTrue(); + assertThat(contextShutdownManager.getNotifier().shouldShutdown()).isTrue(); HardIntegerFormulaGenerator gen = new HardIntegerFormulaGenerator(imgr, bmgr); try (BasicProverEnvironment pe = context.newProverEnvironment()) { @@ -203,7 +207,7 @@ public void testContextInterruptWithSubsequentProverUsageBv() throws Interrupted pe2.push(gen.generate(8)); testBasicContextTimeoutBv(() -> context.newProverEnvironment()); - assertThat(shutdownManager.getNotifier().shouldShutdown()).isTrue(); + assertThat(contextShutdownManager.getNotifier().shouldShutdown()).isTrue(); assertThrows(InterruptedException.class, () -> pe2.push(gen.generate(8))); assertThrows(InterruptedException.class, pe2::isUnsat); @@ -225,7 +229,7 @@ public void testContextInterruptWithSubsequentProverUsageInt() throws Interrupte pe2.push(gen.generate(8)); testBasicContextTimeoutInt(() -> context.newProverEnvironment()); - assertThat(shutdownManager.getNotifier().shouldShutdown()).isTrue(); + assertThat(contextShutdownManager.getNotifier().shouldShutdown()).isTrue(); assertThrows(InterruptedException.class, () -> pe2.push(gen.generate(8))); assertThrows(InterruptedException.class, pe2::isUnsat); @@ -248,20 +252,23 @@ public void testContextInterruptWithSubsequentProverWithNotifierUsageBv() .isNotEqualTo(BOOLECTOR); requireIsolatedProverShutdown(); - ShutdownManager sm1 = ShutdownManager.create(); - ShutdownManager sm2 = ShutdownManager.create(); - ShutdownManager sm3 = ShutdownManager.create(); + ShutdownManager proverShutdownManager1 = ShutdownManager.create(); + ShutdownManager proverShutdownManager2 = ShutdownManager.create(); + ShutdownManager proverShutdownManager3 = ShutdownManager.create(); HardBitvectorFormulaGenerator gen = new HardBitvectorFormulaGenerator(bvmgr, bmgr); - try (BasicProverEnvironment pe1 = context.newProverEnvironment(sm1.getNotifier())) { - try (BasicProverEnvironment pe2 = context.newProverEnvironment(sm2.getNotifier())) { + try (BasicProverEnvironment pe1 = + context.newProverEnvironment(proverShutdownManager1.getNotifier())) { + try (BasicProverEnvironment pe2 = + context.newProverEnvironment(proverShutdownManager2.getNotifier())) { pe2.push(gen.generate(8)); - testBasicContextTimeoutBv(() -> context.newProverEnvironment(sm3.getNotifier())); - assertThat(shutdownManager.getNotifier().shouldShutdown()).isTrue(); - assertThat(sm1.getNotifier().shouldShutdown()).isFalse(); - assertThat(sm2.getNotifier().shouldShutdown()).isFalse(); - assertThat(sm3.getNotifier().shouldShutdown()).isFalse(); + testBasicContextTimeoutBv( + () -> context.newProverEnvironment(proverShutdownManager3.getNotifier())); + assertThat(contextShutdownManager.getNotifier().shouldShutdown()).isTrue(); + assertThat(proverShutdownManager1.getNotifier().shouldShutdown()).isFalse(); + assertThat(proverShutdownManager2.getNotifier().shouldShutdown()).isFalse(); + assertThat(proverShutdownManager3.getNotifier().shouldShutdown()).isFalse(); assertThrows(InterruptedException.class, () -> pe2.push(gen.generate(8))); assertThrows(InterruptedException.class, pe2::isUnsat); @@ -280,20 +287,23 @@ public void testContextInterruptWithSubsequentProverWithNotifierUsageInt() requireIntegers(); requireIsolatedProverShutdown(); - ShutdownManager sm1 = ShutdownManager.create(); - ShutdownManager sm2 = ShutdownManager.create(); - ShutdownManager sm3 = ShutdownManager.create(); + ShutdownManager proverShutdownManager1 = ShutdownManager.create(); + ShutdownManager proverShutdownManager2 = ShutdownManager.create(); + ShutdownManager proverShutdownManager3 = ShutdownManager.create(); HardIntegerFormulaGenerator gen = new HardIntegerFormulaGenerator(imgr, bmgr); - try (BasicProverEnvironment pe1 = context.newProverEnvironment(sm1.getNotifier())) { - try (BasicProverEnvironment pe2 = context.newProverEnvironment(sm2.getNotifier())) { + try (BasicProverEnvironment pe1 = + context.newProverEnvironment(proverShutdownManager1.getNotifier())) { + try (BasicProverEnvironment pe2 = + context.newProverEnvironment(proverShutdownManager2.getNotifier())) { pe2.push(gen.generate(8)); - testBasicContextTimeoutInt(() -> context.newProverEnvironment(sm3.getNotifier())); - assertThat(shutdownManager.getNotifier().shouldShutdown()).isTrue(); - assertThat(sm1.getNotifier().shouldShutdown()).isFalse(); - assertThat(sm2.getNotifier().shouldShutdown()).isFalse(); - assertThat(sm3.getNotifier().shouldShutdown()).isFalse(); + testBasicContextTimeoutInt( + () -> context.newProverEnvironment(proverShutdownManager3.getNotifier())); + assertThat(contextShutdownManager.getNotifier().shouldShutdown()).isTrue(); + assertThat(proverShutdownManager1.getNotifier().shouldShutdown()).isFalse(); + assertThat(proverShutdownManager2.getNotifier().shouldShutdown()).isFalse(); + assertThat(proverShutdownManager3.getNotifier().shouldShutdown()).isFalse(); assertThrows(InterruptedException.class, () -> pe2.push(gen.generate(8))); assertThrows(InterruptedException.class, pe2::isUnsat); @@ -310,14 +320,14 @@ public void testProverInterruptWithSubsequentFeatureUsageBv() requireBitvectors(); requireIsolatedProverShutdown(); - ShutdownManager sm1 = ShutdownManager.create(); - ShutdownManager sm2 = ShutdownManager.create(); - ShutdownManager sm3 = ShutdownManager.create(); - ShutdownManager sm4 = ShutdownManager.create(); + ShutdownManager proverShutdownManager1 = ShutdownManager.create(); + ShutdownManager proverShutdownManager2 = ShutdownManager.create(); + ShutdownManager proverShutdownManager3 = ShutdownManager.create(); + ShutdownManager proverShutdownManager4 = ShutdownManager.create(); try (BasicProverEnvironment pe1 = context.newProverEnvironment( - sm1.getNotifier(), + proverShutdownManager1.getNotifier(), ProverOptions.GENERATE_UNSAT_CORE, ProverOptions.GENERATE_MODELS, ProverOptions.GENERATE_ALL_SAT, @@ -325,7 +335,7 @@ public void testProverInterruptWithSubsequentFeatureUsageBv() assertProverAPIUsable(pe1); try (BasicProverEnvironment pe2 = context.newProverEnvironment( - sm2.getNotifier(), + proverShutdownManager2.getNotifier(), ProverOptions.GENERATE_UNSAT_CORE, ProverOptions.GENERATE_MODELS, ProverOptions.GENERATE_ALL_SAT, @@ -335,18 +345,18 @@ public void testProverInterruptWithSubsequentFeatureUsageBv() testBasicProverTimeoutWithFeatureUsageBv( () -> context.newProverEnvironment( - sm3.getNotifier(), + proverShutdownManager3.getNotifier(), ProverOptions.GENERATE_UNSAT_CORE, ProverOptions.GENERATE_MODELS, ProverOptions.GENERATE_ALL_SAT, ProverOptions.GENERATE_UNSAT_CORE_OVER_ASSUMPTIONS), - sm3); + proverShutdownManager3); - assertThat(shutdownManager.getNotifier().shouldShutdown()).isFalse(); - assertThat(sm1.getNotifier().shouldShutdown()).isFalse(); - assertThat(sm2.getNotifier().shouldShutdown()).isFalse(); - assertThat(sm3.getNotifier().shouldShutdown()).isTrue(); - assertThat(sm4.getNotifier().shouldShutdown()).isFalse(); + assertThat(contextShutdownManager.getNotifier().shouldShutdown()).isFalse(); + assertThat(proverShutdownManager1.getNotifier().shouldShutdown()).isFalse(); + assertThat(proverShutdownManager2.getNotifier().shouldShutdown()).isFalse(); + assertThat(proverShutdownManager3.getNotifier().shouldShutdown()).isTrue(); + assertThat(proverShutdownManager4.getNotifier().shouldShutdown()).isFalse(); boolean notifier4Shutdown = true; @@ -354,12 +364,12 @@ public void testProverInterruptWithSubsequentFeatureUsageBv() testBasicProverTimeoutWithFeatureUsageBv( () -> context.newProverEnvironmentWithInterpolation( - sm4.getNotifier(), + proverShutdownManager4.getNotifier(), ProverOptions.GENERATE_UNSAT_CORE, ProverOptions.GENERATE_MODELS, ProverOptions.GENERATE_ALL_SAT, ProverOptions.GENERATE_UNSAT_CORE_OVER_ASSUMPTIONS), - sm4); + proverShutdownManager4); } catch (UnsupportedOperationException ignore) { // Do nothing, not supported notifier4Shutdown = false; @@ -367,11 +377,12 @@ public void testProverInterruptWithSubsequentFeatureUsageBv() // TODO: optimization (or prover gen as test param?) - assertThat(shutdownManager.getNotifier().shouldShutdown()).isFalse(); - assertThat(sm1.getNotifier().shouldShutdown()).isFalse(); - assertThat(sm2.getNotifier().shouldShutdown()).isFalse(); - assertThat(sm3.getNotifier().shouldShutdown()).isTrue(); - assertThat(sm4.getNotifier().shouldShutdown()).isEqualTo(notifier4Shutdown); + assertThat(contextShutdownManager.getNotifier().shouldShutdown()).isFalse(); + assertThat(proverShutdownManager1.getNotifier().shouldShutdown()).isFalse(); + assertThat(proverShutdownManager2.getNotifier().shouldShutdown()).isFalse(); + assertThat(proverShutdownManager3.getNotifier().shouldShutdown()).isTrue(); + assertThat(proverShutdownManager4.getNotifier().shouldShutdown()) + .isEqualTo(notifier4Shutdown); assertProverAPIUsable(pe2); } @@ -386,14 +397,14 @@ public void testProverInterruptWithSubsequentFeatureUsageInt() requireIntegers(); requireIsolatedProverShutdown(); - ShutdownManager sm1 = ShutdownManager.create(); - ShutdownManager sm2 = ShutdownManager.create(); - ShutdownManager sm3 = ShutdownManager.create(); - ShutdownManager sm4 = ShutdownManager.create(); + ShutdownManager proverShutdownManager1 = ShutdownManager.create(); + ShutdownManager proverShutdownManager2 = ShutdownManager.create(); + ShutdownManager proverShutdownManager3 = ShutdownManager.create(); + ShutdownManager proverShutdownManager4 = ShutdownManager.create(); try (BasicProverEnvironment pe1 = context.newProverEnvironment( - sm1.getNotifier(), + proverShutdownManager1.getNotifier(), ProverOptions.GENERATE_UNSAT_CORE, ProverOptions.GENERATE_MODELS, ProverOptions.GENERATE_ALL_SAT, @@ -403,29 +414,29 @@ public void testProverInterruptWithSubsequentFeatureUsageInt() try (BasicProverEnvironment pe2 = context.newProverEnvironment( - sm2.getNotifier(), + proverShutdownManager2.getNotifier(), ProverOptions.GENERATE_UNSAT_CORE, ProverOptions.GENERATE_MODELS, ProverOptions.GENERATE_ALL_SAT, ProverOptions.GENERATE_UNSAT_CORE_OVER_ASSUMPTIONS)) { assertProverAPIUsable(pe2); - // Test Shutdown of prover with notifier sm3 + // Test Shutdown of prover with notifier proverShutdownManager3 testBasicProverTimeoutWithFeatureUsageInt( () -> context.newProverEnvironment( - sm3.getNotifier(), + proverShutdownManager3.getNotifier(), ProverOptions.GENERATE_UNSAT_CORE, ProverOptions.GENERATE_MODELS, ProverOptions.GENERATE_ALL_SAT, ProverOptions.GENERATE_UNSAT_CORE_OVER_ASSUMPTIONS), - sm3); + proverShutdownManager3); - assertThat(shutdownManager.getNotifier().shouldShutdown()).isFalse(); - assertThat(sm1.getNotifier().shouldShutdown()).isFalse(); - assertThat(sm2.getNotifier().shouldShutdown()).isFalse(); - assertThat(sm3.getNotifier().shouldShutdown()).isTrue(); - assertThat(sm4.getNotifier().shouldShutdown()).isFalse(); + assertThat(contextShutdownManager.getNotifier().shouldShutdown()).isFalse(); + assertThat(proverShutdownManager1.getNotifier().shouldShutdown()).isFalse(); + assertThat(proverShutdownManager2.getNotifier().shouldShutdown()).isFalse(); + assertThat(proverShutdownManager3.getNotifier().shouldShutdown()).isTrue(); + assertThat(proverShutdownManager4.getNotifier().shouldShutdown()).isFalse(); boolean notifier4Shutdown = true; @@ -433,30 +444,32 @@ public void testProverInterruptWithSubsequentFeatureUsageInt() testBasicProverTimeoutWithFeatureUsageInt( () -> context.newProverEnvironmentWithInterpolation( - sm4.getNotifier(), + proverShutdownManager4.getNotifier(), ProverOptions.GENERATE_UNSAT_CORE, ProverOptions.GENERATE_MODELS, ProverOptions.GENERATE_ALL_SAT, ProverOptions.GENERATE_UNSAT_CORE_OVER_ASSUMPTIONS), - sm4); + proverShutdownManager4); } catch (UnsupportedOperationException ignore) { // Do nothing, not supported notifier4Shutdown = false; } - assertThat(shutdownManager.getNotifier().shouldShutdown()).isFalse(); - assertThat(sm1.getNotifier().shouldShutdown()).isFalse(); - assertThat(sm2.getNotifier().shouldShutdown()).isFalse(); - assertThat(sm3.getNotifier().shouldShutdown()).isTrue(); - assertThat(sm4.getNotifier().shouldShutdown()).isEqualTo(notifier4Shutdown); + assertThat(contextShutdownManager.getNotifier().shouldShutdown()).isFalse(); + assertThat(proverShutdownManager1.getNotifier().shouldShutdown()).isFalse(); + assertThat(proverShutdownManager2.getNotifier().shouldShutdown()).isFalse(); + assertThat(proverShutdownManager3.getNotifier().shouldShutdown()).isTrue(); + assertThat(proverShutdownManager4.getNotifier().shouldShutdown()) + .isEqualTo(notifier4Shutdown); // TODO: optimization (or prover gen as test param?) - assertThat(shutdownManager.getNotifier().shouldShutdown()).isFalse(); - assertThat(sm1.getNotifier().shouldShutdown()).isFalse(); - assertThat(sm2.getNotifier().shouldShutdown()).isFalse(); - assertThat(sm3.getNotifier().shouldShutdown()).isTrue(); - assertThat(sm4.getNotifier().shouldShutdown()).isEqualTo(notifier4Shutdown); + assertThat(contextShutdownManager.getNotifier().shouldShutdown()).isFalse(); + assertThat(proverShutdownManager1.getNotifier().shouldShutdown()).isFalse(); + assertThat(proverShutdownManager2.getNotifier().shouldShutdown()).isFalse(); + assertThat(proverShutdownManager3.getNotifier().shouldShutdown()).isTrue(); + assertThat(proverShutdownManager4.getNotifier().shouldShutdown()) + .isEqualTo(notifier4Shutdown); assertProverAPIUsable(pe2); } @@ -543,7 +556,7 @@ private void testBasicContextBasedTimeout( () -> { try { Thread.sleep(delay); - shutdownManager.requestShutdown("Shutdown Request"); + contextShutdownManager.requestShutdown("Shutdown Request"); } catch (InterruptedException exception) { throw new UnsupportedOperationException("Unexpected interrupt", exception); } From 295e01a5c9027e478d6bde9f869927bac9b6f7e7 Mon Sep 17 00:00:00 2001 From: BaierD Date: Mon, 30 Jun 2025 14:11:45 +0200 Subject: [PATCH 57/87] Make internal prover variables private and add setter and getter where necessary --- .../java_smt/basicimpl/AbstractProver.java | 45 ++++++++++++++++--- .../basicimpl/AbstractProverWithAllSat.java | 2 +- .../bitwuzla/BitwuzlaTheoremProver.java | 20 ++++----- .../boolector/BoolectorTheoremProver.java | 11 ++--- .../solvers/cvc4/CVC4TheoremProver.java | 4 +- .../solvers/cvc5/CVC5AbstractProver.java | 4 +- .../solvers/cvc5/CVC5InterpolatingProver.java | 12 ++--- .../mathsat5/Mathsat5AbstractProver.java | 15 ++++--- .../mathsat5/Mathsat5InterpolatingProver.java | 12 ++--- .../mathsat5/Mathsat5OptimizationProver.java | 18 ++++---- .../mathsat5/Mathsat5TheoremProver.java | 2 +- .../opensmt/OpenSmtAbstractProver.java | 2 +- .../opensmt/OpenSmtInterpolatingProver.java | 8 ++-- .../princess/PrincessAbstractProver.java | 26 +++++------ .../princess/PrincessInterpolatingProver.java | 6 +-- .../SmtInterpolAbstractProver.java | 11 ++--- .../SmtInterpolInterpolatingProver.java | 14 +++--- .../solvers/yices2/Yices2TheoremProver.java | 19 ++++---- .../java_smt/solvers/z3/Z3AbstractProver.java | 10 ++--- .../solvers/z3/Z3OptimizationProver.java | 20 ++++----- .../java_smt/solvers/z3/Z3TheoremProver.java | 10 ++--- 21 files changed, 154 insertions(+), 117 deletions(-) diff --git a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java index b7c450affe..696e311589 100644 --- a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java +++ b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java @@ -38,12 +38,12 @@ public abstract class AbstractProver implements BasicProverEnvironment { private final boolean generateModels; private final boolean generateAllSat; - protected final boolean generateUnsatCores; + private final boolean generateUnsatCores; private final boolean generateUnsatCoresOverAssumptions; - protected final boolean enableSL; - protected boolean closed = false; - protected boolean wasLastSatCheckSat = false; - protected boolean stackChangedSinceLastQuery = false; + private final boolean enableSL; + private boolean closed = false; + private boolean wasLastSatCheckSat = false; + private boolean stackChangedSinceLastQuery = false; private final Set evaluators = new LinkedHashSet<>(); @@ -96,6 +96,39 @@ public void checkShutdownState() { } } + protected boolean isGenerateUnsatCores() { + return generateUnsatCores; + } + + // Maybe even make this public? + protected boolean isClosed() { + return closed; + } + + protected boolean isSeparationLogicEnabled() { + return enableSL; + } + + protected boolean stackChangedSinceLastQuery() { + return stackChangedSinceLastQuery; + } + + protected void setStackNotChangedSinceLastQuery() { + stackChangedSinceLastQuery = false; + } + + protected boolean wasLastSatCheckSat() { + return wasLastSatCheckSat; + } + + protected void setLastSatCheckSat() { + wasLastSatCheckSat = true; + } + + protected void setLastSatCheckUnsat() { + wasLastSatCheckSat = false; + } + /** * Only to be called when at least one of the shutdown notifiers is supposed to be shutting down! * Throws an Exception if no shutdown is requested! @@ -306,7 +339,7 @@ protected void closeAllEvaluators() { @Override public ImmutableList getModelAssignments() throws SolverException { - Preconditions.checkState(!closed); + Preconditions.checkState(!isClosed()); checkShutdownState(); Preconditions.checkState(!stackChangedSinceLastQuery, STACK_CHANGED_HELP); checkState(wasLastSatCheckSat); diff --git a/src/org/sosy_lab/java_smt/basicimpl/AbstractProverWithAllSat.java b/src/org/sosy_lab/java_smt/basicimpl/AbstractProverWithAllSat.java index 184bc22819..91ca8c6a42 100644 --- a/src/org/sosy_lab/java_smt/basicimpl/AbstractProverWithAllSat.java +++ b/src/org/sosy_lab/java_smt/basicimpl/AbstractProverWithAllSat.java @@ -43,7 +43,7 @@ protected AbstractProverWithAllSat( @Override public R allSat(AllSatCallback callback, List importantPredicates) throws InterruptedException, SolverException { - Preconditions.checkState(!closed); + Preconditions.checkState(!isClosed()); checkGenerateAllSat(); push(); diff --git a/src/org/sosy_lab/java_smt/solvers/bitwuzla/BitwuzlaTheoremProver.java b/src/org/sosy_lab/java_smt/solvers/bitwuzla/BitwuzlaTheoremProver.java index 73486d04f3..c6d3da42d8 100644 --- a/src/org/sosy_lab/java_smt/solvers/bitwuzla/BitwuzlaTheoremProver.java +++ b/src/org/sosy_lab/java_smt/solvers/bitwuzla/BitwuzlaTheoremProver.java @@ -99,7 +99,7 @@ public void popImpl() { @Override public @Nullable Void addConstraintImpl(BooleanFormula constraint) throws InterruptedException { - wasLastSatCheckSat = false; + setLastSatCheckUnsat(); Term formula = creator.extractInfo(constraint); env.assert_formula(formula); for (Term t : creator.getConstraintsForTerm(formula)) { @@ -122,7 +122,7 @@ public void pushImpl() throws InterruptedException { private boolean readSATResult(Result resultValue) throws SolverException, InterruptedException { if (resultValue == Result.SAT) { - wasLastSatCheckSat = true; + setLastSatCheckSat(); return false; } else if (resultValue == Result.UNSAT) { return true; @@ -136,8 +136,8 @@ private boolean readSATResult(Result resultValue) throws SolverException, Interr /** Check whether the conjunction of all formulas on the stack is unsatisfiable. */ @Override protected boolean isUnsatImpl() throws SolverException, InterruptedException { - Preconditions.checkState(!closed); - wasLastSatCheckSat = false; + Preconditions.checkState(!isClosed()); + setLastSatCheckUnsat(); final Result result = env.check_sat(); return readSATResult(result); } @@ -174,7 +174,7 @@ protected boolean isUnsatWithAssumptionsImpl(Collection assumpti @SuppressWarnings("resource") @Override protected Model getModelImpl() throws SolverException { - Preconditions.checkState(wasLastSatCheckSat, NO_MODEL_HELP); + Preconditions.checkState(wasLastSatCheckSat(), NO_MODEL_HELP); checkGenerateModels(); return new CachingModel( registerEvaluator( @@ -199,7 +199,7 @@ private List getUnsatCore0() { */ @Override protected List getUnsatCoreImpl() { - Preconditions.checkState(!wasLastSatCheckSat); + Preconditions.checkState(!wasLastSatCheckSat()); return getUnsatCore0(); } @@ -225,8 +225,7 @@ protected Optional> unsatCoreOverAssumptionsImpl( */ @Override public void close() { - if (!closed) { - closed = true; + if (!isClosed()) { env.delete(); } super.close(); @@ -243,7 +242,8 @@ protected BitwuzlaModel getEvaluatorWithoutChecks() { Collections2.transform(getAssertedFormulas(), creator::extractInfo))); } - public boolean isClosed() { - return closed; + @Override + protected boolean isClosed() { + return super.isClosed(); } } diff --git a/src/org/sosy_lab/java_smt/solvers/boolector/BoolectorTheoremProver.java b/src/org/sosy_lab/java_smt/solvers/boolector/BoolectorTheoremProver.java index 95a2a779bb..fc6c43c940 100644 --- a/src/org/sosy_lab/java_smt/solvers/boolector/BoolectorTheoremProver.java +++ b/src/org/sosy_lab/java_smt/solvers/boolector/BoolectorTheoremProver.java @@ -65,7 +65,7 @@ protected BoolectorTheoremProver( @Override public void close() { - if (!closed) { + if (!isClosed()) { // Free resources of callback BtorJNI.boolector_free_termination(terminationCallbackHelper); // remove the whole stack, including the initial level from the constructor call. @@ -83,10 +83,10 @@ public void close() { */ @Override protected boolean isUnsatImpl() throws SolverException, InterruptedException { - wasLastSatCheckSat = false; + setLastSatCheckUnsat(); final int result = BtorJNI.boolector_sat(btor); if (result == BtorJNI.BTOR_RESULT_SAT_get()) { - wasLastSatCheckSat = true; + setLastSatCheckSat(); return false; } else if (result == BtorJNI.BTOR_RESULT_UNSAT_get()) { return true; @@ -159,12 +159,13 @@ protected Void addConstraintImpl(BooleanFormula constraint) throws InterruptedEx * * @return bool return value. */ + @Override protected boolean isClosed() { - return closed; + return super.isClosed(); } private long addTerminationCallback() { - Preconditions.checkState(!closed, "solver context is already closed"); + Preconditions.checkState(!isClosed(), "solver context is already closed"); return BtorJNI.boolector_set_termination(btor, this::shouldShutdown); } } diff --git a/src/org/sosy_lab/java_smt/solvers/cvc4/CVC4TheoremProver.java b/src/org/sosy_lab/java_smt/solvers/cvc4/CVC4TheoremProver.java index 032578cd54..b9a879daa7 100644 --- a/src/org/sosy_lab/java_smt/solvers/cvc4/CVC4TheoremProver.java +++ b/src/org/sosy_lab/java_smt/solvers/cvc4/CVC4TheoremProver.java @@ -65,7 +65,7 @@ protected CVC4TheoremProver( creator = pFormulaCreator; smtEngine = new SmtEngine(exprManager); - incremental = !enableSL; + incremental = !isSeparationLogicEnabled(); setOptions(randomSeed, pOptions); } @@ -218,7 +218,7 @@ protected Optional> unsatCoreOverAssumptionsImpl( @Override public void close() { - if (!closed) { + if (!isClosed()) { exportMapping.delete(); // smtEngine.delete(); exprManager.delete(); diff --git a/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5AbstractProver.java b/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5AbstractProver.java index 4ab8cdcf82..d91dcbfd13 100644 --- a/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5AbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5AbstractProver.java @@ -65,7 +65,7 @@ protected CVC5AbstractProver( mgr = pMgr; creator = pFormulaCreator; - incremental = !enableSL; + incremental = !isSeparationLogicEnabled(); assertedTerms.add(PathCopyingPersistentTreeMap.of()); TermManager termManager = creator.getEnv(); @@ -218,7 +218,7 @@ protected Optional> unsatCoreOverAssumptionsImpl( @Override public void close() { - if (!closed) { + if (!isClosed()) { assertedTerms.clear(); solver.deletePointer(); } diff --git a/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5InterpolatingProver.java b/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5InterpolatingProver.java index ddebf33846..5deb0e7a04 100644 --- a/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5InterpolatingProver.java +++ b/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5InterpolatingProver.java @@ -92,10 +92,10 @@ protected String addConstraintImpl(BooleanFormula constraint) throws Interrupted @Override public BooleanFormula getInterpolant(Collection pFormulasOfA) throws SolverException, InterruptedException { - checkState(!closed); + checkState(!isClosed()); shutdownIfNecessary(); - checkState(!wasLastSatCheckSat); - checkState(!stackChangedSinceLastQuery); + checkState(!wasLastSatCheckSat()); + checkState(!stackChangedSinceLastQuery()); checkInterpolationArguments(pFormulasOfA); final Set assertedFormulas = @@ -111,10 +111,10 @@ public BooleanFormula getInterpolant(Collection pFormulasOfA) @Override public List getSeqInterpolants(List> partitions) throws SolverException, InterruptedException { - checkState(!closed); + checkState(!isClosed()); shutdownIfNecessary(); - checkState(!wasLastSatCheckSat); - checkState(!stackChangedSinceLastQuery); + checkState(!wasLastSatCheckSat()); + checkState(!stackChangedSinceLastQuery()); checkArgument(!partitions.isEmpty(), "at least one partition should be available."); final ImmutableSet assertedConstraintIds = getAssertedConstraintIds(); checkArgument( diff --git a/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5AbstractProver.java b/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5AbstractProver.java index 1a86cff448..62e55abcf1 100644 --- a/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5AbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5AbstractProver.java @@ -97,7 +97,7 @@ private long buildConfig(Set opts) { @Override protected boolean isUnsatImpl() throws InterruptedException, SolverException { - Preconditions.checkState(!closed); + Preconditions.checkState(!isClosed()); final long hook = msat_set_termination_callback(curEnv, getTerminationTest()); try { @@ -122,7 +122,7 @@ private TerminationCallback getTerminationTest() { @Override protected boolean isUnsatWithAssumptionsImpl(Collection pAssumptions) throws SolverException, InterruptedException { - Preconditions.checkState(!closed); + Preconditions.checkState(!isClosed()); checkForLiterals(pAssumptions); final long hook = msat_set_termination_callback(curEnv, getTerminationTest()); @@ -181,7 +181,7 @@ protected void popImpl() { @Override public int size() { - Preconditions.checkState(!closed); + Preconditions.checkState(!isClosed()); Preconditions.checkState( msat_num_backtrack_points(curEnv) == super.size(), "prover-size %s does not match stack-size %s", @@ -221,7 +221,7 @@ private List encapsulate(long[] terms) { @Override public ImmutableMap getStatistics() { // Mathsat sigsevs if you try to get statistics for closed environments - Preconditions.checkState(!closed); + Preconditions.checkState(!isClosed()); final String stats = msat_get_search_stats(curEnv); return ImmutableMap.copyOf( Splitter.on("\n").trimResults().omitEmptyStrings().withKeyValueSeparator(" ").split(stats)); @@ -229,21 +229,22 @@ public ImmutableMap getStatistics() { @Override public void close() { - if (!closed) { + if (!isClosed()) { msat_destroy_env(curEnv); msat_destroy_config(curConfig); } super.close(); } + @Override protected boolean isClosed() { - return closed; + return super.isClosed(); } @Override public T allSat(AllSatCallback callback, List important) throws InterruptedException, SolverException { - Preconditions.checkState(!closed); + Preconditions.checkState(!isClosed()); checkGenerateAllSat(); closeAllEvaluators(); diff --git a/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5InterpolatingProver.java b/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5InterpolatingProver.java index d9a8d47201..309699e19f 100644 --- a/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5InterpolatingProver.java +++ b/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5InterpolatingProver.java @@ -104,10 +104,10 @@ protected long getMsatModel() throws SolverException { @Override public BooleanFormula getInterpolant(Collection formulasOfA) throws SolverException, InterruptedException { - checkState(!closed); + checkState(!isClosed()); shutdownIfNecessary(); - checkState(!wasLastSatCheckSat); - checkState(!stackChangedSinceLastQuery); + checkState(!wasLastSatCheckSat()); + checkState(!stackChangedSinceLastQuery()); checkInterpolationArguments(formulasOfA); int[] groupsOfA = Ints.toArray(formulasOfA); @@ -132,10 +132,10 @@ public BooleanFormula getInterpolant(Collection formulasOfA) public List getSeqInterpolants( List> partitionedFormulas) throws SolverException, InterruptedException { - checkState(!closed); + checkState(!isClosed()); shutdownIfNecessary(); - checkState(!wasLastSatCheckSat); - checkState(!stackChangedSinceLastQuery); + checkState(!wasLastSatCheckSat()); + checkState(!stackChangedSinceLastQuery()); Preconditions.checkArgument( !partitionedFormulas.isEmpty(), "at least one partition should be available."); final ImmutableSet assertedConstraintIds = getAssertedConstraintIds(); diff --git a/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5OptimizationProver.java b/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5OptimizationProver.java index 1c6b3d4d65..cd5663c519 100644 --- a/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5OptimizationProver.java +++ b/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5OptimizationProver.java @@ -78,7 +78,7 @@ protected Void addConstraintImpl(BooleanFormula constraint) throws InterruptedEx @Override public int maximize(Formula objective) { - checkState(!closed); + checkState(!isClosed()); long objectiveId = msat_make_maximize(curEnv, getMsatTerm(objective)); msat_assert_objective(curEnv, objectiveId); int id = idGenerator.getFreshId(); // mapping needed to avoid long-int-conversion @@ -88,7 +88,7 @@ public int maximize(Formula objective) { @Override public int minimize(Formula objective) { - checkState(!closed); + checkState(!isClosed()); long objectiveId = msat_make_minimize(curEnv, getMsatTerm(objective)); msat_assert_objective(curEnv, objectiveId); int id = idGenerator.getFreshId(); // mapping needed to avoid long-int-conversion @@ -98,12 +98,12 @@ public int minimize(Formula objective) { @Override public OptStatus check() throws InterruptedException, SolverException { - checkState(!closed); - wasLastSatCheckSat = false; + checkState(!isClosed()); + setLastSatCheckUnsat(); final boolean isSatisfiable = msat_check_sat(curEnv); - stackChangedSinceLastQuery = false; + setStackNotChangedSinceLastQuery(); if (isSatisfiable) { - wasLastSatCheckSat = true; + setLastSatCheckSat(); return OptStatus.OPT; } else { return OptStatus.UNSAT; @@ -124,13 +124,13 @@ protected void popImpl() { @Override public Optional upper(int handle, Rational epsilon) { - checkState(!closed); + checkState(!isClosed()); return getValue(handle, epsilon); } @Override public Optional lower(int handle, Rational epsilon) { - checkState(!closed); + checkState(!isClosed()); return getValue(handle, epsilon); } @@ -150,7 +150,7 @@ private Optional getValue(int handle, Rational epsilon) { @Override protected Model getModelImpl() throws SolverException { - checkState(!closed); + checkState(!isClosed()); if (!objectiveMap.isEmpty()) { msat_load_objective_model(curEnv, objectiveMap.values().iterator().next()); } diff --git a/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5TheoremProver.java b/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5TheoremProver.java index ebc9419e48..7f01b17801 100644 --- a/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5TheoremProver.java +++ b/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5TheoremProver.java @@ -39,7 +39,7 @@ protected void createConfig(Map pConfig) { @Override @Nullable protected Void addConstraintImpl(BooleanFormula constraint) throws InterruptedException { - Preconditions.checkState(!closed); + Preconditions.checkState(!isClosed()); closeAllEvaluators(); msat_assert_formula(curEnv, getMsatTerm(constraint)); return null; diff --git a/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtAbstractProver.java b/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtAbstractProver.java index 275ae7a99f..f687a55ab5 100644 --- a/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtAbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtAbstractProver.java @@ -257,7 +257,7 @@ protected Optional> unsatCoreOverAssumptionsImpl( @Override public void close() { - if (!closed) { + if (!isClosed()) { osmtSolver.delete(); } super.close(); diff --git a/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtInterpolatingProver.java b/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtInterpolatingProver.java index aadfdb46c6..7dfb28aa8e 100644 --- a/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtInterpolatingProver.java +++ b/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtInterpolatingProver.java @@ -78,10 +78,10 @@ protected void popImpl() { @Override public BooleanFormula getInterpolant(Collection formulasOfA) throws InterruptedException { - checkState(!closed); + checkState(!isClosed()); shutdownIfNecessary(); - checkState(!wasLastSatCheckSat); - checkState(!stackChangedSinceLastQuery); + checkState(!wasLastSatCheckSat()); + checkState(!stackChangedSinceLastQuery()); checkInterpolationArguments(formulasOfA); return creator.encapsulateBoolean( @@ -91,7 +91,7 @@ public BooleanFormula getInterpolant(Collection formulasOfA) @Override public List getSeqInterpolants( List> partitionedFormulas) { - checkState(!closed); + checkState(!isClosed()); checkArgument(!partitionedFormulas.isEmpty(), "Interpolation sequence must not be empty"); final ImmutableSet assertedConstraintIds = getAssertedConstraintIds(); checkArgument( diff --git a/src/org/sosy_lab/java_smt/solvers/princess/PrincessAbstractProver.java b/src/org/sosy_lab/java_smt/solvers/princess/PrincessAbstractProver.java index f00921f9dd..c0bd339452 100644 --- a/src/org/sosy_lab/java_smt/solvers/princess/PrincessAbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/princess/PrincessAbstractProver.java @@ -91,12 +91,12 @@ protected PrincessAbstractProver( */ @Override protected boolean isUnsatImpl() throws SolverException { - Preconditions.checkState(!closed); - wasLastSatCheckSat = false; + Preconditions.checkState(!isClosed()); + setLastSatCheckUnsat(); evaluatedTerms.clear(); final Value result = api.checkSat(true); if (result.equals(SimpleAPI.ProverStatus$.MODULE$.Sat())) { - wasLastSatCheckSat = true; + setLastSatCheckSat(); evaluatedTerms.add(api.partialModelAsFormula()); return false; } else if (result.equals(SimpleAPI.ProverStatus$.MODULE$.Unsat())) { @@ -111,8 +111,8 @@ protected boolean isUnsatImpl() throws SolverException { @CanIgnoreReturnValue protected int addConstraint0(BooleanFormula constraint) { - Preconditions.checkState(!closed); - wasLastSatCheckSat = false; + Preconditions.checkState(!isClosed()); + setLastSatCheckUnsat(); final int formulaId = idGenerator.getFreshId(); partitions.push(partitions.pop().putAndCopy(formulaId, constraint)); @@ -126,7 +126,7 @@ protected int addConstraint0(BooleanFormula constraint) { @Override protected final void pushImpl() { - wasLastSatCheckSat = false; + setLastSatCheckUnsat(); api.push(); trackingStack.push(new Level()); partitions.push(partitions.peek()); @@ -134,7 +134,7 @@ protected final void pushImpl() { @Override protected void popImpl() { - wasLastSatCheckSat = false; + setLastSatCheckUnsat(); api.pop(); // we have to recreate symbols on lower levels, because JavaSMT assumes "global" symbols. @@ -164,7 +164,7 @@ void addEvaluatedTerm(IFormula pFormula) { @SuppressWarnings("resource") @Override protected Model getModelImpl() throws SolverException { - Preconditions.checkState(wasLastSatCheckSat, NO_MODEL_HELP); + Preconditions.checkState(wasLastSatCheckSat(), NO_MODEL_HELP); return new CachingModel(getEvaluatorWithoutChecks()); } @@ -216,7 +216,7 @@ protected Optional> unsatCoreOverAssumptionsImpl( public void close() { checkNotNull(api); checkNotNull(mgr); - if (!closed) { + if (!isClosed()) { api.shutDown(); api.reset(); // cleanup memory, even if we keep a reference to "api" and "mgr" creator.getEnv().unregisterStack(this); @@ -229,13 +229,13 @@ public void close() { public T allSat(AllSatCallback callback, List important) throws InterruptedException, SolverException { T result = super.allSat(callback, important); - wasLastSatCheckSat = false; // we do not know about the current state, thus we reset the flag. + setLastSatCheckUnsat(); // we do not know about the current state, thus we reset the flag. return result; } /** add external definition: boolean variable. */ void addSymbol(IFormula f) { - Preconditions.checkState(!closed); + Preconditions.checkState(!isClosed()); api.addBooleanVariable(f); if (!trackingStack.isEmpty()) { trackingStack.peek().booleanSymbols.add(f); @@ -244,7 +244,7 @@ void addSymbol(IFormula f) { /** add external definition: theory variable (integer, rational, string, etc). */ void addSymbol(ITerm f) { - Preconditions.checkState(!closed); + Preconditions.checkState(!isClosed()); api.addConstant(f); if (!trackingStack.isEmpty()) { trackingStack.peek().theorySymbols.add(f); @@ -253,7 +253,7 @@ void addSymbol(ITerm f) { /** add external definition: uninterpreted function. */ void addSymbol(IFunction f) { - Preconditions.checkState(!closed); + Preconditions.checkState(!isClosed()); api.addFunction(f); if (!trackingStack.isEmpty()) { trackingStack.peek().functionSymbols.add(f); diff --git a/src/org/sosy_lab/java_smt/solvers/princess/PrincessInterpolatingProver.java b/src/org/sosy_lab/java_smt/solvers/princess/PrincessInterpolatingProver.java index 3cff548d05..15c70062d6 100644 --- a/src/org/sosy_lab/java_smt/solvers/princess/PrincessInterpolatingProver.java +++ b/src/org/sosy_lab/java_smt/solvers/princess/PrincessInterpolatingProver.java @@ -58,7 +58,7 @@ protected Integer addConstraintImpl(BooleanFormula constraint) throws Interrupte @Override public BooleanFormula getInterpolant(Collection pTermNamesOfA) throws SolverException { - Preconditions.checkState(!closed); + Preconditions.checkState(!isClosed()); checkInterpolationArguments(pTermNamesOfA); Set indexesOfA = ImmutableSet.copyOf(pTermNamesOfA); @@ -76,7 +76,7 @@ public BooleanFormula getInterpolant(Collection pTermNamesOfA) throws S @Override public List getSeqInterpolants( final List> pPartitions) throws SolverException { - Preconditions.checkState(!closed); + Preconditions.checkState(!isClosed()); Preconditions.checkArgument( !pPartitions.isEmpty(), "at least one partition should be available."); final ImmutableSet assertedConstraintIds = getAssertedConstraintIds(); @@ -118,7 +118,7 @@ public List getSeqInterpolants( public List getTreeInterpolants( List> partitionedFormulas, int[] startOfSubTree) throws SolverException { - Preconditions.checkState(!closed); + Preconditions.checkState(!isClosed()); final ImmutableSet assertedConstraintIds = getAssertedConstraintIds(); checkArgument( partitionedFormulas.stream().allMatch(assertedConstraintIds::containsAll), diff --git a/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolAbstractProver.java b/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolAbstractProver.java index 8831450ccb..968c702b90 100644 --- a/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolAbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolAbstractProver.java @@ -71,8 +71,9 @@ abstract class SmtInterpolAbstractProver extends AbstractProver { annotatedTerms.add(PathCopyingPersistentTreeMap.of()); } + @Override protected boolean isClosed() { - return closed; + return super.isClosed(); } @Override @@ -89,7 +90,7 @@ protected void popImpl() { @CanIgnoreReturnValue protected String addConstraint0(BooleanFormula constraint) { - Preconditions.checkState(!closed); + Preconditions.checkState(!isClosed()); // create a term-name, used for unsat-core or interpolation, otherwise there is no overhead. String termName = generateTermName(); @@ -103,7 +104,7 @@ protected String addConstraint0(BooleanFormula constraint) { @Override protected boolean isUnsatImpl() throws InterruptedException { - checkState(!closed); + checkState(!isClosed()); // We actually terminate SmtInterpol during the analysis // by using a shutdown listener. However, SmtInterpol resets the @@ -209,7 +210,7 @@ public ImmutableMap getStatistics() { @Override public void close() { - if (!closed) { + if (!isClosed()) { annotatedTerms.clear(); env.resetAssertions(); env.exit(); @@ -226,7 +227,7 @@ protected boolean isUnsatWithAssumptionsImpl(Collection pAssumpt @Override public R allSat(AllSatCallback callback, List important) throws InterruptedException, SolverException { - checkState(!closed); + checkState(!isClosed()); checkGenerateAllSat(); Term[] importantTerms = new Term[important.size()]; diff --git a/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolInterpolatingProver.java b/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolInterpolatingProver.java index e2a596f33b..7cd3d87640 100644 --- a/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolInterpolatingProver.java +++ b/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolInterpolatingProver.java @@ -50,10 +50,10 @@ protected String addConstraintImpl(BooleanFormula constraint) throws Interrupted @Override public BooleanFormula getInterpolant(Collection pTermNamesOfA) throws SolverException, InterruptedException { - checkState(!closed); + checkState(!isClosed()); shutdownIfNecessary(); - checkState(!wasLastSatCheckSat); - checkState(!stackChangedSinceLastQuery); + checkState(!wasLastSatCheckSat()); + checkState(!stackChangedSinceLastQuery()); checkInterpolationArguments(pTermNamesOfA); // SMTInterpol is not able to handle the trivial cases, @@ -78,10 +78,10 @@ public BooleanFormula getInterpolant(Collection pTermNamesOfA) public List getTreeInterpolants( List> partitionedTermNames, int[] startOfSubTree) throws SolverException, InterruptedException { - checkState(!closed); + checkState(!isClosed()); shutdownIfNecessary(); - checkState(!wasLastSatCheckSat); - checkState(!stackChangedSinceLastQuery); + checkState(!wasLastSatCheckSat()); + checkState(!stackChangedSinceLastQuery()); final ImmutableSet assertedConstraintIds = getAssertedConstraintIds(); checkArgument( partitionedTermNames.stream().allMatch(assertedConstraintIds::containsAll), @@ -121,7 +121,7 @@ public List getTreeInterpolants( } private Term buildConjunctionOfNamedTerms(Collection termNames) { - Preconditions.checkState(!closed); + Preconditions.checkState(!isClosed()); Preconditions.checkArgument(!termNames.isEmpty()); if (termNames.size() == 1) { diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2TheoremProver.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2TheoremProver.java index 4cb4a21016..7efeb0f1b3 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2TheoremProver.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2TheoremProver.java @@ -81,10 +81,6 @@ protected Yices2TheoremProver( curEnv = yices_new_context(curCfg); } - boolean isClosed() { - return closed; - } - @Override protected void popImpl() { if (size() < stackSizeToUnsat) { // constraintStack and Yices stack have same level. @@ -97,7 +93,7 @@ protected void popImpl() { @Override protected @Nullable Void addConstraintImpl(BooleanFormula pConstraint) throws InterruptedException { - if (!generateUnsatCores) { // unsat core does not work with incremental mode + if (!isGenerateUnsatCores()) { // unsat core does not work with incremental mode int constraint = creator.extractInfo(pConstraint); yices_assert_formula(curEnv, constraint); } @@ -119,9 +115,9 @@ protected void pushImpl() throws InterruptedException { @Override protected boolean isUnsatImpl() throws SolverException, InterruptedException { - Preconditions.checkState(!closed); + Preconditions.checkState(!isClosed()); boolean unsat; - if (generateUnsatCores) { // unsat core does not work with incremental mode + if (isGenerateUnsatCores()) { // unsat core does not work with incremental mode int[] allConstraints = getAllConstraints(); unsat = !yices_check_sat_with_assumptions( @@ -151,7 +147,7 @@ private int[] getAllConstraints() { @Override protected boolean isUnsatWithAssumptionsImpl(Collection pAssumptions) throws SolverException, InterruptedException { - Preconditions.checkState(!closed); + Preconditions.checkState(!isClosed()); // TODO handle BooleanFormulaCollection / check for literals return !yices_check_sat_with_assumptions( curEnv, @@ -208,11 +204,16 @@ protected Optional> unsatCoreOverAssumptionsImpl( @Override public void close() { - if (!closed) { + if (!isClosed()) { yices_free_context(curEnv); yices_free_config(curCfg); stackSizeToUnsat = Integer.MAX_VALUE; } super.close(); } + + @Override + protected boolean isClosed() { + return super.isClosed(); + } } diff --git a/src/org/sosy_lab/java_smt/solvers/z3/Z3AbstractProver.java b/src/org/sosy_lab/java_smt/solvers/z3/Z3AbstractProver.java index 7e4e34126a..7345b00b43 100644 --- a/src/org/sosy_lab/java_smt/solvers/z3/Z3AbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/z3/Z3AbstractProver.java @@ -127,7 +127,7 @@ protected Z3Model getEvaluatorWithoutChecks() throws SolverException { @Override protected Void addConstraintImpl(BooleanFormula f) throws InterruptedException { - Preconditions.checkState(!closed); + Preconditions.checkState(!isClosed()); long e = creator.extractInfo(f); try { if (storedConstraints != null) { // Unsat core generation is on. @@ -145,14 +145,14 @@ protected Void addConstraintImpl(BooleanFormula f) throws InterruptedException { } protected void push0() { - Preconditions.checkState(!closed); + Preconditions.checkState(!isClosed()); if (storedConstraints != null) { storedConstraints.push(storedConstraints.peek()); } } protected void pop0() { - Preconditions.checkState(!closed); + Preconditions.checkState(!isClosed()); if (storedConstraints != null) { storedConstraints.pop(); } @@ -203,7 +203,7 @@ protected Optional> unsatCoreOverAssumptionsImpl( @Override public ImmutableMap getStatistics() { // Z3 sigsevs if you try to get statistics for closed environments - Preconditions.checkState(!closed); + Preconditions.checkState(!isClosed()); ImmutableMap.Builder builder = ImmutableMap.builder(); Set seenKeys = new HashSet<>(); @@ -245,7 +245,7 @@ private String getUnusedKey(Set seenKeys, final String originalKey) { @Override public void close() { - if (!closed) { + if (!isClosed()) { if (storedConstraints != null) { storedConstraints.clear(); } diff --git a/src/org/sosy_lab/java_smt/solvers/z3/Z3OptimizationProver.java b/src/org/sosy_lab/java_smt/solvers/z3/Z3OptimizationProver.java index 5af2a8ce1d..61dae7d2a1 100644 --- a/src/org/sosy_lab/java_smt/solvers/z3/Z3OptimizationProver.java +++ b/src/org/sosy_lab/java_smt/solvers/z3/Z3OptimizationProver.java @@ -62,21 +62,21 @@ class Z3OptimizationProver extends Z3AbstractProver implements OptimizationProve @Override public int maximize(Formula objective) { - Preconditions.checkState(!closed); + Preconditions.checkState(!isClosed()); return Native.optimizeMaximize(z3context, z3optSolver, creator.extractInfo(objective)); } @Override public int minimize(Formula objective) { - Preconditions.checkState(!closed); + Preconditions.checkState(!isClosed()); return Native.optimizeMinimize(z3context, z3optSolver, creator.extractInfo(objective)); } @Override public OptStatus check() throws InterruptedException, SolverException { - Preconditions.checkState(!closed); + Preconditions.checkState(!isClosed()); int status; - wasLastSatCheckSat = false; + setLastSatCheckUnsat(); try { status = Native.optimizeCheck( @@ -85,7 +85,7 @@ public OptStatus check() throws InterruptedException, SolverException { 0, // number of assumptions null // assumptions ); - stackChangedSinceLastQuery = false; + setStackNotChangedSinceLastQuery(); } catch (Z3Exception ex) { throw creator.handleZ3Exception(ex, proverShutdownNotifier); } @@ -99,7 +99,7 @@ public OptStatus check() throws InterruptedException, SolverException { Native.optimizeGetReasonUnknown(z3context, z3optSolver)); return OptStatus.UNDEF; } else { - wasLastSatCheckSat = true; + setLastSatCheckSat(); return OptStatus.OPT; } } @@ -137,7 +137,7 @@ protected long getUnsatCore0() { @Override protected boolean isUnsatImpl() throws SolverException, InterruptedException { - Preconditions.checkState(!closed); + Preconditions.checkState(!isClosed()); logSolverStack(); return check() == OptStatus.UNSAT; } @@ -162,7 +162,7 @@ private interface RoundingFunction { } private Optional round(int handle, Rational epsilon, RoundingFunction direction) { - Preconditions.checkState(!closed); + Preconditions.checkState(!isClosed()); // Z3 exposes the rounding result as a tuple (infinity, number, epsilon) long vector = direction.round(z3context, z3optSolver, handle); @@ -216,13 +216,13 @@ protected long getStatistics0() { /** Dumps the optimized objectives and the constraints on the solver in the SMT-lib format. */ @Override public String toString() { - Preconditions.checkState(!closed); + Preconditions.checkState(!isClosed()); return Native.optimizeToString(z3context, z3optSolver); } @Override public void close() { - if (!closed) { + if (!isClosed()) { Native.optimizeDecRef(z3context, z3optSolver); } super.close(); diff --git a/src/org/sosy_lab/java_smt/solvers/z3/Z3TheoremProver.java b/src/org/sosy_lab/java_smt/solvers/z3/Z3TheoremProver.java index d469dcc08f..b280291701 100644 --- a/src/org/sosy_lab/java_smt/solvers/z3/Z3TheoremProver.java +++ b/src/org/sosy_lab/java_smt/solvers/z3/Z3TheoremProver.java @@ -91,7 +91,7 @@ protected void assertContraintAndTrack(long constraint, long symbol) { @Override protected boolean isUnsatImpl() throws SolverException, InterruptedException { - Preconditions.checkState(!closed); + Preconditions.checkState(!isClosed()); logSolverStack(); int result; try { @@ -153,7 +153,7 @@ protected long getZ3Model() { @Override public int size() { - Preconditions.checkState(!closed); + Preconditions.checkState(!isClosed()); Preconditions.checkState( Native.solverGetNumScopes(z3context, z3solver) == super.size(), "prover-size %s does not match stack-size %s", @@ -169,7 +169,7 @@ protected long getStatistics0() { @Override public boolean registerUserPropagator(UserPropagator prop) { - Preconditions.checkState(!closed); + Preconditions.checkState(!isClosed()); if (propagator != null) { propagator.close(); } @@ -180,13 +180,13 @@ public boolean registerUserPropagator(UserPropagator prop) { @Override public String toString() { - Preconditions.checkState(!closed); + Preconditions.checkState(!isClosed()); return Native.solverToString(z3context, z3solver); } @Override public void close() { - if (!closed) { + if (!isClosed()) { Preconditions.checkArgument( Native.solverGetNumScopes(z3context, z3solver) >= 0, "a negative number of scopes is not allowed"); From a9023f9a2a0230fd8c6702e26d6ac1c1b1dcd211 Mon Sep 17 00:00:00 2001 From: BaierD Date: Mon, 30 Jun 2025 14:17:30 +0200 Subject: [PATCH 58/87] Remove unneeded lambda from Mathsat termination check --- .../solvers/mathsat5/Mathsat5AbstractProver.java | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5AbstractProver.java b/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5AbstractProver.java index 62e55abcf1..4a4f6380d8 100644 --- a/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5AbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5AbstractProver.java @@ -52,7 +52,6 @@ import org.sosy_lab.java_smt.basicimpl.AbstractProver; import org.sosy_lab.java_smt.basicimpl.CachingModel; import org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.AllSatModelCallback; -import org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.TerminationCallback; /** Common base class for {@link Mathsat5TheoremProver} and {@link Mathsat5InterpolatingProver}. */ abstract class Mathsat5AbstractProver extends AbstractProver { @@ -99,7 +98,7 @@ private long buildConfig(Set opts) { protected boolean isUnsatImpl() throws InterruptedException, SolverException { Preconditions.checkState(!isClosed()); - final long hook = msat_set_termination_callback(curEnv, getTerminationTest()); + final long hook = msat_set_termination_callback(curEnv, this::getTerminationTest); try { return !msat_check_sat(curEnv); } finally { @@ -112,11 +111,9 @@ protected boolean isUnsatImpl() throws InterruptedException, SolverException { * callback can be registered upfront, i.e., before calling a possibly expensive computation in * the solver to allow a proper shutdown. */ - private TerminationCallback getTerminationTest() { - return () -> { - shutdownIfNecessary(); - return false; - }; + private boolean getTerminationTest() throws InterruptedException { + shutdownIfNecessary(); + return false; } @Override @@ -125,7 +122,7 @@ protected boolean isUnsatWithAssumptionsImpl(Collection pAssumpt Preconditions.checkState(!isClosed()); checkForLiterals(pAssumptions); - final long hook = msat_set_termination_callback(curEnv, getTerminationTest()); + final long hook = msat_set_termination_callback(curEnv, this::getTerminationTest); try { return !msat_check_sat_with_assumptions(curEnv, getMsatTerm(pAssumptions)); } finally { From 3ca9316eb0eaa3f9cb476cf4eb88435192441ccf Mon Sep 17 00:00:00 2001 From: BaierD Date: Mon, 30 Jun 2025 14:46:29 +0200 Subject: [PATCH 59/87] Add a sanity check in DebuggingBasicProverEnvironment for getModelAssignments() --- .../delegate/debugging/DebuggingBasicProverEnvironment.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/org/sosy_lab/java_smt/delegate/debugging/DebuggingBasicProverEnvironment.java b/src/org/sosy_lab/java_smt/delegate/debugging/DebuggingBasicProverEnvironment.java index 5199faf773..a34dd8bde9 100644 --- a/src/org/sosy_lab/java_smt/delegate/debugging/DebuggingBasicProverEnvironment.java +++ b/src/org/sosy_lab/java_smt/delegate/debugging/DebuggingBasicProverEnvironment.java @@ -81,6 +81,7 @@ public Model getModel() throws SolverException { @Override public ImmutableList getModelAssignments() throws SolverException { + debugging.assertThreadLocal(); return delegate.getModelAssignments(); } From 9e6381603284264f12b18d3875588c5b5323a141 Mon Sep 17 00:00:00 2001 From: BaierD Date: Mon, 30 Jun 2025 14:50:51 +0200 Subject: [PATCH 60/87] Mark implementation specifications with @implNote in SolverContext --- .../sosy_lab/java_smt/api/SolverContext.java | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/org/sosy_lab/java_smt/api/SolverContext.java b/src/org/sosy_lab/java_smt/api/SolverContext.java index b049023cd7..c3f20dc9b9 100644 --- a/src/org/sosy_lab/java_smt/api/SolverContext.java +++ b/src/org/sosy_lab/java_smt/api/SolverContext.java @@ -90,10 +90,11 @@ ProverEnvironment newProverEnvironment( /** * Create a fresh new {@link InterpolatingProverEnvironment} which encapsulates an assertion stack - * and allows generating and retrieve interpolants for unsatisfiable formulas. If the SMT solver - * is able to handle satisfiability tests with assumptions please consider implementing the {@link - * InterpolatingProverEnvironment} interface, and return an Object of this type here. + * and allows generating and retrieve interpolants for unsatisfiable formulas. * + * @implNote If the SMT solver is able to handle satisfiability tests with assumptions please + * consider implementing the {@link InterpolatingProverEnvironment} interface, and return an + * Object of this type here. * @param options Options specified for the prover environment. All the options specified in * {@link ProverOptions} are turned off by default. */ @@ -101,13 +102,14 @@ ProverEnvironment newProverEnvironment( /** * Create a fresh new {@link InterpolatingProverEnvironment} which encapsulates an assertion stack - * and allows generating and retrieve interpolants for unsatisfiable formulas. If the SMT solver - * is able to handle satisfiability tests with assumptions please consider implementing the {@link - * InterpolatingProverEnvironment} interface, and return an Object of this type here. Allows the - * shutdown of the prover instance returned with the given {@link ShutdownNotifier}, without - * stopping other provers of the context calling this (except for provers also connected via the - * given {@link ShutdownNotifier}). + * and allows generating and retrieve interpolants for unsatisfiable formulas. Allows the shutdown + * of the prover instance returned with the given {@link ShutdownNotifier}, without stopping other + * provers of the context calling this (except for provers also connected via the given {@link + * ShutdownNotifier}). * + * @implNote If the SMT solver is able to handle satisfiability tests with assumptions please + * consider implementing the {@link InterpolatingProverEnvironment} interface, and return an + * Object of this type here. * @param pProverShutdownNotifier a {@link ShutdownNotifier} that stops the prover returned by * this method. The prover is not usable anymore after a shutdown has been requested and only * ever returns {@link InterruptedException}s. The context can be used normally and new From ac5be008e012959d4e1e564598bbb1d9f196db79 Mon Sep 17 00:00:00 2001 From: BaierD Date: Mon, 30 Jun 2025 14:52:59 +0200 Subject: [PATCH 61/87] Make JavaDoc clearer for SolverContext prover requests and their interruption handling --- .../sosy_lab/java_smt/api/SolverContext.java | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/org/sosy_lab/java_smt/api/SolverContext.java b/src/org/sosy_lab/java_smt/api/SolverContext.java index c3f20dc9b9..1386f10d3f 100644 --- a/src/org/sosy_lab/java_smt/api/SolverContext.java +++ b/src/org/sosy_lab/java_smt/api/SolverContext.java @@ -111,13 +111,13 @@ ProverEnvironment newProverEnvironment( * consider implementing the {@link InterpolatingProverEnvironment} interface, and return an * Object of this type here. * @param pProverShutdownNotifier a {@link ShutdownNotifier} that stops the prover returned by - * this method. The prover is not usable anymore after a shutdown has been requested and only - * ever returns {@link InterruptedException}s. The context can be used normally and new - * provers can be created and used. If a {@link ShutdownNotifier} has been given to the - * context that is used to call this method, both notifiers can be used to stop the prover - * returned by this method. Note that once a shutdown-request has been given to the contexts - * {@link ShutdownNotifier}, no prover can ever be used again on that context instance. - * Solvers that don't support isolated prover shutdown throw a {@link + * this method. The prover is not usable anymore after a shutdown has been requested and in + * the following its methods only throw {@link InterruptedException}s. The context can be used + * normally and new provers can be created and used. If a {@link ShutdownNotifier} has been + * given to the context that is used to call this method, both notifiers can be used to stop + * the prover returned by this method. Note that once a shutdown-request has been given to the + * contexts {@link ShutdownNotifier}, no prover can ever be used again on that context + * instance. Solvers that don't support isolated prover shutdown throw a {@link * UnsupportedOperationException} for this method and {@link * #newProverEnvironment(ProverOptions...)} should be used instead. * @param options Options specified for the prover environment. All the options specified in @@ -142,13 +142,13 @@ InterpolatingProverEnvironment newProverEnvironmentWithInterpolation( * this (except for provers also connected via the given {@link ShutdownNotifier}). * * @param pProverShutdownNotifier a {@link ShutdownNotifier} that stops the prover returned by - * this method. The prover is not usable anymore after a shutdown has been requested and only - * ever returns {@link InterruptedException}s. The context can be used normally and new - * provers can be created and used. If a {@link ShutdownNotifier} has been given to the - * context that is used to call this method, both notifiers can be used to stop the prover - * returned by this method. Note that once a shutdown-request has been given to the contexts - * {@link ShutdownNotifier}, no prover can ever be used again on that context instance. - * Solvers that don't support isolated prover shutdown throw a {@link + * this method. The prover is not usable anymore after a shutdown has been requested and in + * the following its methods only throw {@link InterruptedException}s. The context can be used + * normally and new provers can be created and used. If a {@link ShutdownNotifier} has been + * given to the context that is used to call this method, both notifiers can be used to stop + * the prover returned by this method. Note that once a shutdown-request has been given to the + * contexts {@link ShutdownNotifier}, no prover can ever be used again on that context + * instance. Solvers that don't support isolated prover shutdown throw a {@link * UnsupportedOperationException} for this method and {@link * #newProverEnvironment(ProverOptions...)} should be used instead. * @param options Options specified for the prover environment. All the options specified in From 1d9ec5a2747e680b54662693aa0f994b0e769e1d Mon Sep 17 00:00:00 2001 From: BaierD Date: Mon, 30 Jun 2025 15:03:58 +0200 Subject: [PATCH 62/87] Improve JavaDoc of SolverContext in regard to shutdown of provers --- src/org/sosy_lab/java_smt/api/SolverContext.java | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/org/sosy_lab/java_smt/api/SolverContext.java b/src/org/sosy_lab/java_smt/api/SolverContext.java index 1386f10d3f..7df9c9b7d9 100644 --- a/src/org/sosy_lab/java_smt/api/SolverContext.java +++ b/src/org/sosy_lab/java_smt/api/SolverContext.java @@ -68,9 +68,8 @@ enum ProverOptions { /** * Create a fresh new {@link ProverEnvironment} which encapsulates an assertion stack and can be - * used to check formulas for unsatisfiability. Allows the shutdown of the prover instance - * returned with the given {@link ShutdownNotifier}, without stopping other provers of the context - * calling this (except for provers also connected via the given {@link ShutdownNotifier}). + * used to check formulas for unsatisfiability. The returned prover instance can be shut down + * using the given {@link ShutdownNotifier}. * * @param pProverShutdownNotifier a {@link ShutdownNotifier} that stops the prover returned by * this method. The prover is not usable anymore after a shutdown has been requested and only @@ -102,10 +101,8 @@ ProverEnvironment newProverEnvironment( /** * Create a fresh new {@link InterpolatingProverEnvironment} which encapsulates an assertion stack - * and allows generating and retrieve interpolants for unsatisfiable formulas. Allows the shutdown - * of the prover instance returned with the given {@link ShutdownNotifier}, without stopping other - * provers of the context calling this (except for provers also connected via the given {@link - * ShutdownNotifier}). + * and allows generating and retrieve interpolants for unsatisfiable formulas. The returned prover + * instance can be shut down using the given {@link ShutdownNotifier}. * * @implNote If the SMT solver is able to handle satisfiability tests with assumptions please * consider implementing the {@link InterpolatingProverEnvironment} interface, and return an @@ -137,9 +134,8 @@ InterpolatingProverEnvironment newProverEnvironmentWithInterpolation( /** * Create a fresh new {@link OptimizationProverEnvironment} which encapsulates an assertion stack - * and allows solving optimization queries. Allows the shutdown of the prover instance returned - * with the given {@link ShutdownNotifier}, without stopping other provers of the context calling - * this (except for provers also connected via the given {@link ShutdownNotifier}). + * and allows solving optimization queries. The returned prover instance can be shut down using + * the given {@link ShutdownNotifier}. * * @param pProverShutdownNotifier a {@link ShutdownNotifier} that stops the prover returned by * this method. The prover is not usable anymore after a shutdown has been requested and in From e4bf4e8f379ea13142d0e869ef9b8c7ea275cf3c Mon Sep 17 00:00:00 2001 From: BaierD Date: Mon, 30 Jun 2025 19:21:25 +0200 Subject: [PATCH 63/87] Hide common Strings used in provers from users --- .../java_smt/api/BasicProverEnvironment.java | 12 +----------- .../java_smt/basicimpl/AbstractProver.java | 14 ++++++++++++++ .../BasicProverWithAssumptionsWrapper.java | 5 +++++ .../smtinterpol/SmtInterpolAbstractProver.java | 3 +-- 4 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java b/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java index e7c1d8422e..0ac3593d2e 100644 --- a/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java +++ b/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java @@ -22,20 +22,10 @@ * provides only the common operations. In most cases, just use one of the two sub-interfaces */ public interface BasicProverEnvironment extends AutoCloseable { - String NO_MODEL_HELP = "Model computation failed. Are the pushed formulae satisfiable?"; - - String NO_UNSAT_CORE_HELP = - "UnsatCore computation failed. Are the pushed formulae unsatisfiable?"; - - String STACK_CHANGED_HELP = - "Computation failed. The prover state has changed since the last call to isUnsat()."; - - // Used as prefix concatenated with the reason in the IllegalStateException thrown for shutdowns - String SHUTDOWN_EXCEPTION_PREFIX = "Prover is not usable due to interrupt with message: "; /** * Push a backtracking point and add a formula to the current stack, asserting it. The return - * value may be used to identify this formula later on in a query (this depends on the sub-type of + * value may be used to identify this formula later on in a query (this depends on the subtype of * the environment). */ @Nullable diff --git a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java index 696e311589..f31f307e3c 100644 --- a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java +++ b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java @@ -36,6 +36,20 @@ public abstract class AbstractProver implements BasicProverEnvironment { + protected final String NO_MODEL_HELP = + "Model computation failed. Are the pushed formulae satisfiable?"; + + private final String NO_UNSAT_CORE_HELP = + "UnsatCore computation failed. Are the pushed formulae unsatisfiable?"; + + private final String STACK_CHANGED_HELP = + "Computation failed. The prover state has changed since the last call to isUnsat()."; + + // Used as prefix concatenated with the reason in the IllegalStateException thrown for shutdowns + // Keep in sync with BasicProverWithAssumptionsWrapper.SHUTDOWN_EXCEPTION_PREFIX + private static final String SHUTDOWN_EXCEPTION_PREFIX = + "Prover is not usable due to interrupt with message: "; + private final boolean generateModels; private final boolean generateAllSat; private final boolean generateUnsatCores; diff --git a/src/org/sosy_lab/java_smt/basicimpl/withAssumptionsWrapper/BasicProverWithAssumptionsWrapper.java b/src/org/sosy_lab/java_smt/basicimpl/withAssumptionsWrapper/BasicProverWithAssumptionsWrapper.java index ee710b0caf..e1815bab31 100644 --- a/src/org/sosy_lab/java_smt/basicimpl/withAssumptionsWrapper/BasicProverWithAssumptionsWrapper.java +++ b/src/org/sosy_lab/java_smt/basicimpl/withAssumptionsWrapper/BasicProverWithAssumptionsWrapper.java @@ -22,6 +22,11 @@ public class BasicProverWithAssumptionsWrapper> implements BasicProverEnvironment { + // Used as prefix concatenated with the reason in the IllegalStateException thrown for shutdowns + // Keep in sync with AbstractProver.SHUTDOWN_EXCEPTION_PREFIX + private static final String SHUTDOWN_EXCEPTION_PREFIX = + "Prover is not usable due to interrupt with message: "; + protected final P delegate; protected final List solverAssumptionsAsFormula = new ArrayList<>(); diff --git a/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolAbstractProver.java b/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolAbstractProver.java index 968c702b90..29547d5f41 100644 --- a/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolAbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolAbstractProver.java @@ -38,7 +38,6 @@ import org.sosy_lab.common.collect.Collections3; import org.sosy_lab.common.collect.PathCopyingPersistentTreeMap; import org.sosy_lab.common.collect.PersistentMap; -import org.sosy_lab.java_smt.api.BasicProverEnvironment; import org.sosy_lab.java_smt.api.BooleanFormula; import org.sosy_lab.java_smt.api.SolverContext.ProverOptions; import org.sosy_lab.java_smt.api.SolverException; @@ -147,7 +146,7 @@ protected org.sosy_lab.java_smt.api.Model getModelImpl() { model = env.getModel(); } catch (SMTLIBException e) { if (e.getMessage().contains("Context is inconsistent")) { - throw new IllegalStateException(BasicProverEnvironment.NO_MODEL_HELP, e); + throw new IllegalStateException(NO_MODEL_HELP, e); } else { // new stacktrace, but only the library calls are missing. throw e; From f16f77d0a049be6e44727c880c47f347471a395b Mon Sep 17 00:00:00 2001 From: BaierD Date: Mon, 30 Jun 2025 19:23:19 +0200 Subject: [PATCH 64/87] Make common Strings used in provers static --- src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java index f31f307e3c..d525e6968c 100644 --- a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java +++ b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java @@ -36,13 +36,13 @@ public abstract class AbstractProver implements BasicProverEnvironment { - protected final String NO_MODEL_HELP = + protected static final String NO_MODEL_HELP = "Model computation failed. Are the pushed formulae satisfiable?"; - private final String NO_UNSAT_CORE_HELP = + private static final String NO_UNSAT_CORE_HELP = "UnsatCore computation failed. Are the pushed formulae unsatisfiable?"; - private final String STACK_CHANGED_HELP = + private static final String STACK_CHANGED_HELP = "Computation failed. The prover state has changed since the last call to isUnsat()."; // Used as prefix concatenated with the reason in the IllegalStateException thrown for shutdowns From 1ab695529333edc0560c0a6e2a93dc9938a0c32a Mon Sep 17 00:00:00 2001 From: BaierD Date: Mon, 30 Jun 2025 19:26:14 +0200 Subject: [PATCH 65/87] Re-add default impl of getModelAssignments() --- src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java b/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java index 0ac3593d2e..871b165b2f 100644 --- a/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java +++ b/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java @@ -105,7 +105,11 @@ default Evaluator getEvaluator() throws SolverException { *

Note that if you need to iterate multiple times over the model it may be more efficient to * use this method instead of {@link #getModel()} (depending on the solver). */ - ImmutableList getModelAssignments() throws SolverException; + default ImmutableList getModelAssignments() throws SolverException { + try (Model model = getModel()) { + return model.asList(); + } + } /** * Get an unsat core. This should be called only immediately after an {@link #isUnsat()} call that From fc323b9379789105cdb47434cf445f3a6bae39d4 Mon Sep 17 00:00:00 2001 From: BaierD Date: Tue, 1 Jul 2025 10:48:49 +0200 Subject: [PATCH 66/87] Re-throw exception when clearing assumptions, and it's not another exception --- .../BasicProverWithAssumptionsWrapper.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/org/sosy_lab/java_smt/basicimpl/withAssumptionsWrapper/BasicProverWithAssumptionsWrapper.java b/src/org/sosy_lab/java_smt/basicimpl/withAssumptionsWrapper/BasicProverWithAssumptionsWrapper.java index e1815bab31..a0c03acb70 100644 --- a/src/org/sosy_lab/java_smt/basicimpl/withAssumptionsWrapper/BasicProverWithAssumptionsWrapper.java +++ b/src/org/sosy_lab/java_smt/basicimpl/withAssumptionsWrapper/BasicProverWithAssumptionsWrapper.java @@ -48,6 +48,8 @@ protected void clearAssumptionsWithInterruptedException() throws InterruptedExce } catch (IllegalStateException ise) { if (ise.getMessage().startsWith(SHUTDOWN_EXCEPTION_PREFIX)) { throw new InterruptedException(ise.getMessage().replace(SHUTDOWN_EXCEPTION_PREFIX, "")); + } else { + throw ise; } } } From 1b268a39285b22cc6e1d14be5d84e13c1f408b00 Mon Sep 17 00:00:00 2001 From: BaierD Date: Mon, 21 Jul 2025 17:25:48 +0200 Subject: [PATCH 67/87] Improve JavaDoc of constructor methods of new prover environments with ShutdownNotifiers --- .../sosy_lab/java_smt/api/SolverContext.java | 57 +++++++++---------- 1 file changed, 27 insertions(+), 30 deletions(-) diff --git a/src/org/sosy_lab/java_smt/api/SolverContext.java b/src/org/sosy_lab/java_smt/api/SolverContext.java index 7df9c9b7d9..71e9119777 100644 --- a/src/org/sosy_lab/java_smt/api/SolverContext.java +++ b/src/org/sosy_lab/java_smt/api/SolverContext.java @@ -71,18 +71,17 @@ enum ProverOptions { * used to check formulas for unsatisfiability. The returned prover instance can be shut down * using the given {@link ShutdownNotifier}. * - * @param pProverShutdownNotifier a {@link ShutdownNotifier} that stops the prover returned by - * this method. The prover is not usable anymore after a shutdown has been requested and only - * ever returns {@link InterruptedException}s. The context can be used normally and new - * provers can be created and used. If a {@link ShutdownNotifier} has been given to the - * context that is used to call this method, both notifiers can be used to stop the prover - * returned by this method. Note that once a shutdown-request has been given to the contexts - * {@link ShutdownNotifier}, no prover can ever be used again on that context instance. - * Solvers that don't support isolated prover shutdown throw a {@link - * UnsupportedOperationException} for this method and {@link - * #newProverEnvironment(ProverOptions...)} should be used instead. + * @param pProverShutdownNotifier a {@link ShutdownNotifier} that can be used to stop the prover + * returned by this method. The prover is not usable anymore after a shutdown has been + * requested. The context is uneffected by prover shutdown, and can be used to create new + * provers. Note that as for all provers, the prover returned by this method can also be shut + * down by a shutdown of the whole context using the {@link ShutdownNotifier} that was given + * when creating the context. * @param options Options specified for the prover environment. All the options specified in * {@link ProverOptions} are turned off by default. + * @throws UnsupportedOperationException Solvers that don't support isolated prover shutdown throw + * a {@link UnsupportedOperationException} for this method and {@link + * #newProverEnvironment(ProverOptions...)} should be used instead. */ ProverEnvironment newProverEnvironment( ShutdownNotifier pProverShutdownNotifier, ProverOptions... options); @@ -107,18 +106,17 @@ ProverEnvironment newProverEnvironment( * @implNote If the SMT solver is able to handle satisfiability tests with assumptions please * consider implementing the {@link InterpolatingProverEnvironment} interface, and return an * Object of this type here. - * @param pProverShutdownNotifier a {@link ShutdownNotifier} that stops the prover returned by - * this method. The prover is not usable anymore after a shutdown has been requested and in - * the following its methods only throw {@link InterruptedException}s. The context can be used - * normally and new provers can be created and used. If a {@link ShutdownNotifier} has been - * given to the context that is used to call this method, both notifiers can be used to stop - * the prover returned by this method. Note that once a shutdown-request has been given to the - * contexts {@link ShutdownNotifier}, no prover can ever be used again on that context - * instance. Solvers that don't support isolated prover shutdown throw a {@link - * UnsupportedOperationException} for this method and {@link - * #newProverEnvironment(ProverOptions...)} should be used instead. + * @param pProverShutdownNotifier a {@link ShutdownNotifier} that can be used to stop the prover + * returned by this method. The prover is not usable anymore after a shutdown has been + * requested. The context is uneffected by prover shutdown, and can be used to create new + * provers. Note that as for all provers, the prover returned by this method can also be shut + * down by a shutdown of the whole context using the {@link ShutdownNotifier} that was given + * when creating the context. * @param options Options specified for the prover environment. All the options specified in * {@link ProverOptions} are turned off by default. + * @throws UnsupportedOperationException Solvers that don't support isolated prover shutdown throw + * a {@link UnsupportedOperationException} for this method and {@link + * #newProverEnvironment(ProverOptions...)} should be used instead. */ InterpolatingProverEnvironment newProverEnvironmentWithInterpolation( ShutdownNotifier pProverShutdownNotifier, ProverOptions... options); @@ -137,18 +135,17 @@ InterpolatingProverEnvironment newProverEnvironmentWithInterpolation( * and allows solving optimization queries. The returned prover instance can be shut down using * the given {@link ShutdownNotifier}. * - * @param pProverShutdownNotifier a {@link ShutdownNotifier} that stops the prover returned by - * this method. The prover is not usable anymore after a shutdown has been requested and in - * the following its methods only throw {@link InterruptedException}s. The context can be used - * normally and new provers can be created and used. If a {@link ShutdownNotifier} has been - * given to the context that is used to call this method, both notifiers can be used to stop - * the prover returned by this method. Note that once a shutdown-request has been given to the - * contexts {@link ShutdownNotifier}, no prover can ever be used again on that context - * instance. Solvers that don't support isolated prover shutdown throw a {@link - * UnsupportedOperationException} for this method and {@link - * #newProverEnvironment(ProverOptions...)} should be used instead. + * @param pProverShutdownNotifier a {@link ShutdownNotifier} that can be used to stop the prover + * returned by this method. The prover is not usable anymore after a shutdown has been + * requested. The context is uneffected by prover shutdown, and can be used to create new + * provers. Note that as for all provers, the prover returned by this method can also be shut + * down by a shutdown of the whole context using the {@link ShutdownNotifier} that was given + * when creating the context. * @param options Options specified for the prover environment. All the options specified in * {@link ProverOptions} are turned off by default. + * @throws UnsupportedOperationException Solvers that don't support isolated prover shutdown throw + * a {@link UnsupportedOperationException} for this method and {@link + * #newProverEnvironment(ProverOptions...)} should be used instead. */ OptimizationProverEnvironment newOptimizationProverEnvironment( ShutdownNotifier pProverShutdownNotifier, ProverOptions... options); From c4a7a6521234b084a79556e01ba8be7476f91ae0 Mon Sep 17 00:00:00 2001 From: BaierD Date: Tue, 29 Jul 2025 16:07:40 +0200 Subject: [PATCH 68/87] Add warning for sneaky SolverExceptions in Model JavaDoc --- src/org/sosy_lab/java_smt/api/Model.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/org/sosy_lab/java_smt/api/Model.java b/src/org/sosy_lab/java_smt/api/Model.java index 27a5e7a9b1..b4c772a04f 100644 --- a/src/org/sosy_lab/java_smt/api/Model.java +++ b/src/org/sosy_lab/java_smt/api/Model.java @@ -49,13 +49,21 @@ public interface Model extends Evaluator, Iterable, AutoCloseab * within a quantified context, some value assignments can be missing in the iteration. * Please use a direct evaluation query to get the evaluation in such a case. * + * + *

Warning: this might throw an unchecked {@link SolverException} as an extension of {@link + * Throwable}. */ @Override default Iterator iterator() { return asList().iterator(); } - /** Build a list of assignments that stays valid after closing the model. */ + /** + * Build a list of assignments that stays valid after closing the model. + * + *

Warning: this might throw an unchecked {@link SolverException} as an extension of {@link + * Throwable}. + */ ImmutableList asList(); /** From b7da958d4c315cc0d5fe3da72b3121b2a5a4d81c Mon Sep 17 00:00:00 2001 From: BaierD Date: Tue, 29 Jul 2025 16:08:20 +0200 Subject: [PATCH 69/87] Throw sneaky SolverExceptions in Mathsat Model instead of confusing IllegalArgumentException for msat_model_create_iterator() --- .../solvers/mathsat5/Mathsat5Model.java | 4 ++-- .../solvers/mathsat5/Mathsat5NativeApi.java | 24 +++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5Model.java b/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5Model.java index e3dfdd1d98..3b7266262c 100644 --- a/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5Model.java +++ b/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5Model.java @@ -13,7 +13,7 @@ import static org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.msat_is_array_type; import static org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.msat_make_array_read; import static org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.msat_make_eq; -import static org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.msat_model_create_iterator; +import static org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.msat_model_create_iterator_with_sneaky_solver_exception; import static org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.msat_model_eval; import static org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.msat_model_iterator_has_next; import static org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.msat_model_iterator_next; @@ -53,7 +53,7 @@ public ImmutableList asList() { Preconditions.checkState(!prover.isClosed(), "cannot use model after prover is closed"); ImmutableList.Builder assignments = ImmutableList.builder(); - long modelIterator = msat_model_create_iterator(model); + long modelIterator = msat_model_create_iterator_with_sneaky_solver_exception(model); while (msat_model_iterator_has_next(modelIterator)) { long[] key = new long[1]; long[] value = new long[1]; diff --git a/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5NativeApi.java b/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5NativeApi.java index f0862ddaf8..45e7a0129b 100644 --- a/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5NativeApi.java +++ b/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5NativeApi.java @@ -780,8 +780,32 @@ private static native int msat_all_sat( public static native void msat_destroy_model(long model); + /** + * Only to be used in tests. Use msat_model_create_iterator_with_sneaky_solver_exception() + * instead, to throw a better exception in case of failures. + */ public static native long msat_model_create_iterator(long model); + /** + * This method returns the result of msat_model_create_iterator(), however it throws a + * IllegalArgumentException due to a problem, it throws a SolverException, reflecting the problem + * better. This method is used in places where we cannot throw a checked exception in JavaSMT due + * to API restrictions. + */ + static long msat_model_create_iterator_with_sneaky_solver_exception(long model) { + try { + return msat_model_create_iterator(model); + } catch (IllegalArgumentException iae) { + // This is not a bug in our code, but a problem of MathSAT. The context can still be used. + throw sneakyThrow(new SolverException(iae.getMessage() + ", model" + " not available")); + } + } + + @SuppressWarnings("unchecked") + private static RuntimeException sneakyThrow(Throwable e) throws E { + throw (E) e; + } + /** * Evaluates the input term in the given model. * From 50094eb4458feea3ede5798e076dff02c0dc93d9 Mon Sep 17 00:00:00 2001 From: BaierD Date: Tue, 29 Jul 2025 16:17:59 +0200 Subject: [PATCH 70/87] Add more sneaky throw warnings to API that may throw a SolverException as Throwable (due to Z3) --- .../java_smt/api/BasicProverEnvironment.java | 10 ++++++- src/org/sosy_lab/java_smt/api/Evaluator.java | 27 +++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java b/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java index dd086f6728..75903650b4 100644 --- a/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java +++ b/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java @@ -29,6 +29,9 @@ public interface BasicProverEnvironment extends AutoCloseable { * Push a backtracking point and add a formula to the current stack, asserting it. The return * value may be used to identify this formula later on in a query (this depends on the subtype of * the environment). + * + *

Warning: this might throw an unchecked {@link SolverException} as an extension of {@link + * Throwable}. */ @Nullable @CanIgnoreReturnValue @@ -43,7 +46,12 @@ default T push(BooleanFormula f) throws InterruptedException { */ void pop(); - /** Add a constraint to the latest backtracking point. */ + /** + * Add a constraint to the latest backtracking point. + * + *

Warning: this might throw an unchecked {@link SolverException} as an extension of {@link + * Throwable}. + */ @Nullable @CanIgnoreReturnValue T addConstraint(BooleanFormula constraint) throws InterruptedException; diff --git a/src/org/sosy_lab/java_smt/api/Evaluator.java b/src/org/sosy_lab/java_smt/api/Evaluator.java index 03ca8b00a0..44d0f37173 100644 --- a/src/org/sosy_lab/java_smt/api/Evaluator.java +++ b/src/org/sosy_lab/java_smt/api/Evaluator.java @@ -43,6 +43,9 @@ public interface Evaluator extends AutoCloseable { * will replace all symbols from the formula with their model values and then simplify the formula * into a simple formula, e.g., consisting only of a numeral expression. * + *

Warning: this might throw an unchecked {@link SolverException} as an extension of {@link + * Throwable}. + * * @param formula Input formula to be evaluated. * @return evaluation of the given formula or null if the solver does not provide a * better evaluation. @@ -58,6 +61,9 @@ public interface Evaluator extends AutoCloseable { * *

The formula does not need to be a variable, we also allow complex expression. * + *

Warning: this might throw an unchecked {@link SolverException} as an extension of {@link + * Throwable}. + * * @param formula Input formula * @return Either of: - Number (Rational/Double/BigInteger/Long/Integer) - Boolean * @throws IllegalArgumentException if a formula has unexpected type, e.g. Array. @@ -68,6 +74,9 @@ public interface Evaluator extends AutoCloseable { * Type-safe evaluation for integer formulas. * *

The formula does not need to be a variable, we also allow complex expression. + * + *

Warning: this might throw an unchecked {@link SolverException} as an extension of {@link + * Throwable}. */ @Nullable BigInteger evaluate(IntegerFormula formula); @@ -75,6 +84,9 @@ public interface Evaluator extends AutoCloseable { * Type-safe evaluation for rational formulas. * *

The formula does not need to be a variable, we also allow complex expression. + * + *

Warning: this might throw an unchecked {@link SolverException} as an extension of {@link + * Throwable}. */ @Nullable Rational evaluate(RationalFormula formula); @@ -82,6 +94,9 @@ public interface Evaluator extends AutoCloseable { * Type-safe evaluation for boolean formulas. * *

The formula does not need to be a variable, we also allow complex expression. + * + *

Warning: this might throw an unchecked {@link SolverException} as an extension of {@link + * Throwable}. */ @Nullable Boolean evaluate(BooleanFormula formula); @@ -89,6 +104,9 @@ public interface Evaluator extends AutoCloseable { * Type-safe evaluation for bitvector formulas. * *

The formula does not need to be a variable, we also allow complex expression. + * + *

Warning: this might throw an unchecked {@link SolverException} as an extension of {@link + * Throwable}. */ @Nullable BigInteger evaluate(BitvectorFormula formula); @@ -96,6 +114,9 @@ public interface Evaluator extends AutoCloseable { * Type-safe evaluation for string formulas. * *

The formula does not need to be a variable, we also allow complex expression. + * + *

Warning: this might throw an unchecked {@link SolverException} as an extension of {@link + * Throwable}. */ @Nullable String evaluate(StringFormula formula); @@ -103,6 +124,9 @@ public interface Evaluator extends AutoCloseable { * Type-safe evaluation for enumeration formulas. * *

The formula does not need to be a variable, we also allow complex expression. + * + *

Warning: this might throw an unchecked {@link SolverException} as an extension of {@link + * Throwable}. */ @Nullable String evaluate(EnumerationFormula formula); @@ -110,6 +134,9 @@ public interface Evaluator extends AutoCloseable { * Type-safe evaluation for floating-point formulas. * *

The formula does not need to be a variable, we also allow complex expression. + * + *

Warning: this might throw an unchecked {@link SolverException} as an extension of {@link + * Throwable}. */ @Nullable FloatingPointNumber evaluate(FloatingPointFormula formula); From 89837d5407139345870aec020e2ca1d8b9c7350e Mon Sep 17 00:00:00 2001 From: BaierD Date: Wed, 30 Jul 2025 16:04:18 +0200 Subject: [PATCH 71/87] Remove sneaky throw of SolverException from Mathsat native call --- .../solvers/mathsat5/Mathsat5NativeApi.java | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5NativeApi.java b/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5NativeApi.java index 45e7a0129b..699429b083 100644 --- a/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5NativeApi.java +++ b/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5NativeApi.java @@ -789,23 +789,18 @@ private static native int msat_all_sat( /** * This method returns the result of msat_model_create_iterator(), however it throws a * IllegalArgumentException due to a problem, it throws a SolverException, reflecting the problem - * better. This method is used in places where we cannot throw a checked exception in JavaSMT due - * to API restrictions. + * better. */ - static long msat_model_create_iterator_with_sneaky_solver_exception(long model) { + static long msat_model_create_iterator_with_solver_exception(long model) throws SolverException { try { return msat_model_create_iterator(model); } catch (IllegalArgumentException iae) { - // This is not a bug in our code, but a problem of MathSAT. The context can still be used. - throw sneakyThrow(new SolverException(iae.getMessage() + ", model" + " not available")); + // This is not a bug in our or user code, but a problem of MathSAT. The context can still be + // used. + throw new SolverException(iae.getMessage() + ", model not available"); } } - @SuppressWarnings("unchecked") - private static RuntimeException sneakyThrow(Throwable e) throws E { - throw (E) e; - } - /** * Evaluates the input term in the given model. * From dbbdc318e20c67762de2aae7e6fa300188b6ce2d Mon Sep 17 00:00:00 2001 From: BaierD Date: Wed, 30 Jul 2025 16:05:48 +0200 Subject: [PATCH 72/87] Remove sneaky throw of SolverException from Z3 model and add InterruptedException to it --- .../java_smt/solvers/z3/Z3AbstractProver.java | 6 +++--- .../sosy_lab/java_smt/solvers/z3/Z3Model.java | 17 ++++++++++------- .../java_smt/solvers/z3/Z3TheoremProver.java | 4 ++-- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/org/sosy_lab/java_smt/solvers/z3/Z3AbstractProver.java b/src/org/sosy_lab/java_smt/solvers/z3/Z3AbstractProver.java index 7da2fbdbf5..10cdd2f6dc 100644 --- a/src/org/sosy_lab/java_smt/solvers/z3/Z3AbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/z3/Z3AbstractProver.java @@ -104,18 +104,18 @@ protected void logSolverStack() throws SolverException { @SuppressWarnings("resource") @Override - public Model getModel() throws SolverException { + public Model getModel() throws SolverException, InterruptedException { Preconditions.checkState(!closed); checkGenerateModels(); return new CachingModel(getEvaluatorWithoutChecks()); } @Override - protected Z3Model getEvaluatorWithoutChecks() throws SolverException { + protected Z3Model getEvaluatorWithoutChecks() throws SolverException, InterruptedException { return new Z3Model(this, z3context, getZ3Model(), creator); } - protected abstract long getZ3Model() throws SolverException; + protected abstract long getZ3Model() throws SolverException, InterruptedException; protected abstract void assertContraint(long constraint); diff --git a/src/org/sosy_lab/java_smt/solvers/z3/Z3Model.java b/src/org/sosy_lab/java_smt/solvers/z3/Z3Model.java index 916a511345..1b31cf4cbd 100644 --- a/src/org/sosy_lab/java_smt/solvers/z3/Z3Model.java +++ b/src/org/sosy_lab/java_smt/solvers/z3/Z3Model.java @@ -23,6 +23,7 @@ import java.util.Set; import java.util.regex.Pattern; import org.checkerframework.checker.nullness.qual.Nullable; +import org.sosy_lab.java_smt.api.SolverException; import org.sosy_lab.java_smt.basicimpl.AbstractModel; import org.sosy_lab.java_smt.basicimpl.AbstractProver; @@ -43,7 +44,7 @@ final class Z3Model extends AbstractModel { } @Override - public ImmutableList asList() { + public ImmutableList asList() throws SolverException, InterruptedException { Preconditions.checkState(!isClosed()); ImmutableList.Builder out = ImmutableList.builder(); @@ -67,7 +68,7 @@ public ImmutableList asList() { Native.decRef(z3context, funcDecl); } } catch (Z3Exception e) { - throw z3creator.handleZ3ExceptionAsRuntimeException(e); + throw z3creator.handleZ3Exception(e); } return out.build(); @@ -92,7 +93,8 @@ private boolean isInternalSymbol(long funcDecl) { /** * @return ValueAssignments for a constant declaration in the model */ - private Collection getConstAssignments(long keyDecl) { + private Collection getConstAssignments(long keyDecl) + throws SolverException, InterruptedException { Preconditions.checkArgument( Native.getArity(z3context, keyDecl) == 0, "Declaration is not a constant"); @@ -146,7 +148,7 @@ private Collection getConstAssignments(long keyDecl) { /** unrolls an constant array assignment. */ private Collection getConstantArrayAssignment( - long arraySymbol, long value, long decl) { + long arraySymbol, long value, long decl) throws SolverException, InterruptedException { long arrayFormula = Native.mkConst(z3context, arraySymbol, Native.getSort(z3context, value)); Native.incRef(z3context, arrayFormula); @@ -212,7 +214,8 @@ private Collection getConstantArrayAssignment( * @return a list of assignments {@code a[1]=0; a[2]=0; a[5]=0}. */ private Collection getArrayAssignments( - long arraySymbol, long arrayFormula, long value, List upperIndices) { + long arraySymbol, long arrayFormula, long value, List upperIndices) + throws SolverException, InterruptedException { long evalDecl = Native.getAsArrayFuncDecl(z3context, value); Native.incRef(z3context, evalDecl); long interp = Native.modelGetFuncInterp(z3context, model, evalDecl); @@ -382,13 +385,13 @@ public void close() { @Override @Nullable - protected Long evalImpl(Long formula) { + protected Long evalImpl(Long formula) throws SolverException, InterruptedException { LongPtr resultPtr = new LongPtr(); boolean satisfiableModel; try { satisfiableModel = Native.modelEval(z3context, model, formula, false, resultPtr); } catch (Z3Exception e) { - throw z3creator.handleZ3ExceptionAsRuntimeException(e); + throw z3creator.handleZ3Exception(e); } Preconditions.checkState(satisfiableModel); if (resultPtr.value == 0) { diff --git a/src/org/sosy_lab/java_smt/solvers/z3/Z3TheoremProver.java b/src/org/sosy_lab/java_smt/solvers/z3/Z3TheoremProver.java index 5ec0eae466..5b1f4720d7 100644 --- a/src/org/sosy_lab/java_smt/solvers/z3/Z3TheoremProver.java +++ b/src/org/sosy_lab/java_smt/solvers/z3/Z3TheoremProver.java @@ -138,11 +138,11 @@ protected long getUnsatCore0() { } @Override - protected long getZ3Model() { + protected long getZ3Model() throws SolverException, InterruptedException { try { return Native.solverGetModel(z3context, z3solver); } catch (Z3Exception e) { - throw creator.handleZ3ExceptionAsRuntimeException(e); + throw creator.handleZ3Exception(e); } } From b0e7b444420926f59c71b531607b5352936953a2 Mon Sep 17 00:00:00 2001 From: BaierD Date: Wed, 30 Jul 2025 16:06:28 +0200 Subject: [PATCH 73/87] Add SolverException and InterruptedException to many calls related to the Model --- .../java_smt/api/BasicProverEnvironment.java | 7 +++-- src/org/sosy_lab/java_smt/api/Evaluator.java | 28 +++++++++--------- src/org/sosy_lab/java_smt/api/Model.java | 17 ++++++++--- .../api/OptimizationProverEnvironment.java | 2 +- .../java_smt/basicimpl/AbstractEvaluator.java | 26 ++++++++++------- .../java_smt/basicimpl/CachingModel.java | 29 ++++++++++++------- .../BasicProverWithAssumptionsWrapper.java | 5 ++-- .../DebuggingBasicProverEnvironment.java | 2 +- .../delegate/debugging/DebuggingModel.java | 29 ++++++++++++------- .../LoggingBasicProverEnvironment.java | 5 ++-- .../StatisticsBasicProverEnvironment.java | 2 +- .../delegate/statistics/StatisticsModel.java | 28 +++++++++++------- .../SynchronizedBasicProverEnvironment.java | 2 +- ...izedBasicProverEnvironmentWithContext.java | 2 +- .../synchronize/SynchronizedModel.java | 28 +++++++++++------- .../SynchronizedModelWithContext.java | 4 ++- .../sosy_lab/java_smt/example/NQueens.java | 3 +- .../solvers/bitwuzla/BitwuzlaModel.java | 9 ++++-- .../java_smt/solvers/cvc4/CVC4Model.java | 13 ++++++--- .../solvers/cvc4/CVC4TheoremProver.java | 5 ++-- .../solvers/cvc5/CVC5AbstractProver.java | 5 ++-- .../java_smt/solvers/cvc5/CVC5Model.java | 16 ++++++---- .../solvers/mathsat5/Mathsat5Model.java | 13 +++++---- .../opensmt/OpenSmtAbstractProver.java | 3 +- .../solvers/smtinterpol/SmtInterpolModel.java | 12 +++++--- .../java_smt/test/ModelEvaluationTest.java | 3 +- 26 files changed, 187 insertions(+), 111 deletions(-) diff --git a/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java b/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java index 75903650b4..58f13f099d 100644 --- a/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java +++ b/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java @@ -95,7 +95,7 @@ boolean isUnsatWithAssumptions(Collection assumptions) *

A model might contain additional symbols with their evaluation, if a solver uses its own * temporary symbols. There should be at least a value-assignment for each free symbol. */ - Model getModel() throws SolverException; + Model getModel() throws SolverException, InterruptedException; /** * Get a temporary view on the current satisfying assignment. This should be called only @@ -103,7 +103,7 @@ boolean isUnsatWithAssumptions(Collection assumptions) * should no longer be used as soon as any constraints are added to, pushed, or popped from the * prover stack. */ - default Evaluator getEvaluator() throws SolverException { + default Evaluator getEvaluator() throws SolverException, InterruptedException { return getModel(); } @@ -115,7 +115,8 @@ default Evaluator getEvaluator() throws SolverException { *

Note that if you need to iterate multiple times over the model it may be more efficient to * use this method instead of {@link #getModel()} (depending on the solver). */ - default ImmutableList getModelAssignments() throws SolverException { + default ImmutableList getModelAssignments() + throws SolverException, InterruptedException { try (Model model = getModel()) { return model.asList(); } diff --git a/src/org/sosy_lab/java_smt/api/Evaluator.java b/src/org/sosy_lab/java_smt/api/Evaluator.java index 44d0f37173..6ea3f2e31a 100644 --- a/src/org/sosy_lab/java_smt/api/Evaluator.java +++ b/src/org/sosy_lab/java_smt/api/Evaluator.java @@ -43,14 +43,11 @@ public interface Evaluator extends AutoCloseable { * will replace all symbols from the formula with their model values and then simplify the formula * into a simple formula, e.g., consisting only of a numeral expression. * - *

Warning: this might throw an unchecked {@link SolverException} as an extension of {@link - * Throwable}. - * * @param formula Input formula to be evaluated. * @return evaluation of the given formula or null if the solver does not provide a * better evaluation. */ - @Nullable T eval(T formula); + @Nullable T eval(T formula) throws SolverException, InterruptedException; /** * Evaluate a given formula substituting the values from the model. @@ -61,14 +58,11 @@ public interface Evaluator extends AutoCloseable { * *

The formula does not need to be a variable, we also allow complex expression. * - *

Warning: this might throw an unchecked {@link SolverException} as an extension of {@link - * Throwable}. - * * @param formula Input formula * @return Either of: - Number (Rational/Double/BigInteger/Long/Integer) - Boolean * @throws IllegalArgumentException if a formula has unexpected type, e.g. Array. */ - @Nullable Object evaluate(Formula formula); + @Nullable Object evaluate(Formula formula) throws SolverException, InterruptedException; /** * Type-safe evaluation for integer formulas. @@ -78,7 +72,8 @@ public interface Evaluator extends AutoCloseable { *

Warning: this might throw an unchecked {@link SolverException} as an extension of {@link * Throwable}. */ - @Nullable BigInteger evaluate(IntegerFormula formula); + @Nullable BigInteger evaluate(IntegerFormula formula) + throws SolverException, InterruptedException; /** * Type-safe evaluation for rational formulas. @@ -88,7 +83,7 @@ public interface Evaluator extends AutoCloseable { *

Warning: this might throw an unchecked {@link SolverException} as an extension of {@link * Throwable}. */ - @Nullable Rational evaluate(RationalFormula formula); + @Nullable Rational evaluate(RationalFormula formula) throws SolverException, InterruptedException; /** * Type-safe evaluation for boolean formulas. @@ -98,7 +93,7 @@ public interface Evaluator extends AutoCloseable { *

Warning: this might throw an unchecked {@link SolverException} as an extension of {@link * Throwable}. */ - @Nullable Boolean evaluate(BooleanFormula formula); + @Nullable Boolean evaluate(BooleanFormula formula) throws SolverException, InterruptedException; /** * Type-safe evaluation for bitvector formulas. @@ -108,7 +103,8 @@ public interface Evaluator extends AutoCloseable { *

Warning: this might throw an unchecked {@link SolverException} as an extension of {@link * Throwable}. */ - @Nullable BigInteger evaluate(BitvectorFormula formula); + @Nullable BigInteger evaluate(BitvectorFormula formula) + throws SolverException, InterruptedException; /** * Type-safe evaluation for string formulas. @@ -118,7 +114,7 @@ public interface Evaluator extends AutoCloseable { *

Warning: this might throw an unchecked {@link SolverException} as an extension of {@link * Throwable}. */ - @Nullable String evaluate(StringFormula formula); + @Nullable String evaluate(StringFormula formula) throws SolverException, InterruptedException; /** * Type-safe evaluation for enumeration formulas. @@ -128,7 +124,8 @@ public interface Evaluator extends AutoCloseable { *

Warning: this might throw an unchecked {@link SolverException} as an extension of {@link * Throwable}. */ - @Nullable String evaluate(EnumerationFormula formula); + @Nullable String evaluate(EnumerationFormula formula) + throws SolverException, InterruptedException; /** * Type-safe evaluation for floating-point formulas. @@ -138,7 +135,8 @@ public interface Evaluator extends AutoCloseable { *

Warning: this might throw an unchecked {@link SolverException} as an extension of {@link * Throwable}. */ - @Nullable FloatingPointNumber evaluate(FloatingPointFormula formula); + @Nullable FloatingPointNumber evaluate(FloatingPointFormula formula) + throws SolverException, InterruptedException; /** * Free resources associated with this evaluator (existing {@link Formula} instances stay valid, diff --git a/src/org/sosy_lab/java_smt/api/Model.java b/src/org/sosy_lab/java_smt/api/Model.java index b4c772a04f..8b4ac5fa3b 100644 --- a/src/org/sosy_lab/java_smt/api/Model.java +++ b/src/org/sosy_lab/java_smt/api/Model.java @@ -50,12 +50,21 @@ public interface Model extends Evaluator, Iterable, AutoCloseab * Please use a direct evaluation query to get the evaluation in such a case. * * - *

Warning: this might throw an unchecked {@link SolverException} as an extension of {@link - * Throwable}. + *

Warning: this might throw {@link SolverException} or {@link InterruptedException} as {@link + * RuntimeException} as checked exceptions are not supported by this method. */ @Override default Iterator iterator() { - return asList().iterator(); + try { + return asList().iterator(); + } catch (SolverException | InterruptedException pE) { + throw sneakyThrow(pE); + } + } + + @SuppressWarnings("unchecked") + private static RuntimeException sneakyThrow(Throwable e) throws E { + throw (E) e; } /** @@ -64,7 +73,7 @@ default Iterator iterator() { *

Warning: this might throw an unchecked {@link SolverException} as an extension of {@link * Throwable}. */ - ImmutableList asList(); + ImmutableList asList() throws SolverException, InterruptedException; /** * Pretty-printing of the model values. diff --git a/src/org/sosy_lab/java_smt/api/OptimizationProverEnvironment.java b/src/org/sosy_lab/java_smt/api/OptimizationProverEnvironment.java index 3d6b895a1b..0980864317 100644 --- a/src/org/sosy_lab/java_smt/api/OptimizationProverEnvironment.java +++ b/src/org/sosy_lab/java_smt/api/OptimizationProverEnvironment.java @@ -68,7 +68,7 @@ public interface OptimizationProverEnvironment extends BasicProverEnvironment T eval(T f) { + public final T eval(T f) throws SolverException, InterruptedException { Preconditions.checkState(!isClosed()); TFormulaInfo evaluation = evalImpl(creator.extractInfo(f)); return evaluation == null ? null : (T) creator.encapsulateWithTypeOf(evaluation); @@ -48,14 +49,14 @@ public final T eval(T f) { @Nullable @Override - public final BigInteger evaluate(IntegerFormula f) { + public final BigInteger evaluate(IntegerFormula f) throws SolverException, InterruptedException { Preconditions.checkState(!isClosed()); return (BigInteger) evaluateImpl(creator.extractInfo(f)); } @Nullable @Override - public Rational evaluate(RationalFormula f) { + public Rational evaluate(RationalFormula f) throws SolverException, InterruptedException { Object value = evaluateImpl(creator.extractInfo(f)); if (value instanceof BigInteger) { // We simplified the value internally. Here, we need to convert it back to Rational. @@ -67,41 +68,43 @@ public Rational evaluate(RationalFormula f) { @Nullable @Override - public final Boolean evaluate(BooleanFormula f) { + public final Boolean evaluate(BooleanFormula f) throws SolverException, InterruptedException { Preconditions.checkState(!isClosed()); return (Boolean) evaluateImpl(creator.extractInfo(f)); } @Nullable @Override - public final String evaluate(StringFormula f) { + public final String evaluate(StringFormula f) throws SolverException, InterruptedException { Preconditions.checkState(!isClosed()); return (String) evaluateImpl(creator.extractInfo(f)); } @Nullable @Override - public final String evaluate(EnumerationFormula f) { + public final String evaluate(EnumerationFormula f) throws SolverException, InterruptedException { Preconditions.checkState(!isClosed()); return (String) evaluateImpl(creator.extractInfo(f)); } @Override - public final @Nullable FloatingPointNumber evaluate(FloatingPointFormula f) { + public final @Nullable FloatingPointNumber evaluate(FloatingPointFormula f) + throws SolverException, InterruptedException { Preconditions.checkState(!isClosed()); return (FloatingPointNumber) evaluateImpl(creator.extractInfo(f)); } @Nullable @Override - public final BigInteger evaluate(BitvectorFormula f) { + public final BigInteger evaluate(BitvectorFormula f) + throws SolverException, InterruptedException { Preconditions.checkState(!isClosed()); return (BigInteger) evaluateImpl(creator.extractInfo(f)); } @Nullable @Override - public final Object evaluate(Formula f) { + public final Object evaluate(Formula f) throws SolverException, InterruptedException { Preconditions.checkState(!isClosed()); Preconditions.checkArgument( !(f instanceof ArrayFormula), @@ -114,7 +117,8 @@ public final Object evaluate(Formula f) { * set in the model and evaluation aborts, return null. */ @Nullable - protected abstract TFormulaInfo evalImpl(TFormulaInfo formula); + protected abstract TFormulaInfo evalImpl(TFormulaInfo formula) + throws SolverException, InterruptedException; /** * Simplify the given formula and replace all symbols with their model values. If a symbol is not @@ -122,7 +126,7 @@ public final Object evaluate(Formula f) { * into a Java object as far as possible, i.e., try to match a primitive or simple type. */ @Nullable - protected final Object evaluateImpl(TFormulaInfo f) { + protected final Object evaluateImpl(TFormulaInfo f) throws SolverException, InterruptedException { Preconditions.checkState(!isClosed()); TFormulaInfo evaluatedF = evalImpl(f); return evaluatedF == null ? null : creator.convertValue(f, evaluatedF); diff --git a/src/org/sosy_lab/java_smt/basicimpl/CachingModel.java b/src/org/sosy_lab/java_smt/basicimpl/CachingModel.java index ee379c61e1..0ae815d644 100644 --- a/src/org/sosy_lab/java_smt/basicimpl/CachingModel.java +++ b/src/org/sosy_lab/java_smt/basicimpl/CachingModel.java @@ -22,6 +22,7 @@ import org.sosy_lab.java_smt.api.Model; import org.sosy_lab.java_smt.api.NumeralFormula.IntegerFormula; import org.sosy_lab.java_smt.api.NumeralFormula.RationalFormula; +import org.sosy_lab.java_smt.api.SolverException; import org.sosy_lab.java_smt.api.StringFormula; public class CachingModel implements Model { @@ -35,7 +36,7 @@ public CachingModel(Model pDelegate) { } @Override - public ImmutableList asList() { + public ImmutableList asList() throws SolverException, InterruptedException { if (modelAssignments == null) { modelAssignments = delegate.asList(); } @@ -48,47 +49,55 @@ public void close() { } @Override - public @Nullable T eval(T formula) { + public @Nullable T eval(T formula) + throws SolverException, InterruptedException { return delegate.eval(formula); } @Override - public @Nullable Object evaluate(Formula formula) { + public @Nullable Object evaluate(Formula formula) throws SolverException, InterruptedException { return delegate.evaluate(formula); } @Override - public @Nullable BigInteger evaluate(IntegerFormula formula) { + public @Nullable BigInteger evaluate(IntegerFormula formula) + throws SolverException, InterruptedException { return delegate.evaluate(formula); } @Override - public @Nullable Rational evaluate(RationalFormula formula) { + public @Nullable Rational evaluate(RationalFormula formula) + throws SolverException, InterruptedException { return delegate.evaluate(formula); } @Override - public @Nullable Boolean evaluate(BooleanFormula formula) { + public @Nullable Boolean evaluate(BooleanFormula formula) + throws SolverException, InterruptedException { return delegate.evaluate(formula); } @Override - public @Nullable BigInteger evaluate(BitvectorFormula formula) { + public @Nullable BigInteger evaluate(BitvectorFormula formula) + throws SolverException, InterruptedException { return delegate.evaluate(formula); } @Override - public @Nullable String evaluate(StringFormula formula) { + public @Nullable String evaluate(StringFormula formula) + throws SolverException, InterruptedException { return delegate.evaluate(formula); } @Override - public @Nullable String evaluate(EnumerationFormula formula) { + public @Nullable String evaluate(EnumerationFormula formula) + throws SolverException, InterruptedException { return delegate.evaluate(formula); } @Override - public @Nullable FloatingPointNumber evaluate(FloatingPointFormula formula) { + public @Nullable FloatingPointNumber evaluate(FloatingPointFormula formula) + throws SolverException, InterruptedException { return delegate.evaluate(formula); } diff --git a/src/org/sosy_lab/java_smt/basicimpl/withAssumptionsWrapper/BasicProverWithAssumptionsWrapper.java b/src/org/sosy_lab/java_smt/basicimpl/withAssumptionsWrapper/BasicProverWithAssumptionsWrapper.java index 596f30f4eb..3afcbe0a41 100644 --- a/src/org/sosy_lab/java_smt/basicimpl/withAssumptionsWrapper/BasicProverWithAssumptionsWrapper.java +++ b/src/org/sosy_lab/java_smt/basicimpl/withAssumptionsWrapper/BasicProverWithAssumptionsWrapper.java @@ -80,12 +80,13 @@ public boolean isUnsatWithAssumptions(Collection assumptions) protected void registerPushedFormula(@SuppressWarnings("unused") T pPushResult) {} @Override - public Model getModel() throws SolverException { + public Model getModel() throws SolverException, InterruptedException { return delegate.getModel(); } @Override - public ImmutableList getModelAssignments() throws SolverException { + public ImmutableList getModelAssignments() + throws SolverException, InterruptedException { return delegate.getModelAssignments(); } diff --git a/src/org/sosy_lab/java_smt/delegate/debugging/DebuggingBasicProverEnvironment.java b/src/org/sosy_lab/java_smt/delegate/debugging/DebuggingBasicProverEnvironment.java index c548d30384..33e2ef8756 100644 --- a/src/org/sosy_lab/java_smt/delegate/debugging/DebuggingBasicProverEnvironment.java +++ b/src/org/sosy_lab/java_smt/delegate/debugging/DebuggingBasicProverEnvironment.java @@ -72,7 +72,7 @@ public boolean isUnsatWithAssumptions(Collection assumptions) @SuppressWarnings("resource") @Override - public Model getModel() throws SolverException { + public Model getModel() throws SolverException, InterruptedException { debugging.assertThreadLocal(); return new DebuggingModel(delegate.getModel(), debugging); } diff --git a/src/org/sosy_lab/java_smt/delegate/debugging/DebuggingModel.java b/src/org/sosy_lab/java_smt/delegate/debugging/DebuggingModel.java index 29b11eea9a..2f6c1a5cc8 100644 --- a/src/org/sosy_lab/java_smt/delegate/debugging/DebuggingModel.java +++ b/src/org/sosy_lab/java_smt/delegate/debugging/DebuggingModel.java @@ -23,6 +23,7 @@ import org.sosy_lab.java_smt.api.Model; import org.sosy_lab.java_smt.api.NumeralFormula.IntegerFormula; import org.sosy_lab.java_smt.api.NumeralFormula.RationalFormula; +import org.sosy_lab.java_smt.api.SolverException; import org.sosy_lab.java_smt.api.StringFormula; public class DebuggingModel implements Model { @@ -35,7 +36,8 @@ public class DebuggingModel implements Model { } @Override - public @Nullable T eval(T formula) { + public @Nullable T eval(T formula) + throws SolverException, InterruptedException { debugging.assertThreadLocal(); debugging.assertFormulaInContext(formula); T result = delegate.eval(formula); @@ -44,63 +46,70 @@ public class DebuggingModel implements Model { } @Override - public @Nullable Object evaluate(Formula formula) { + public @Nullable Object evaluate(Formula formula) throws SolverException, InterruptedException { debugging.assertThreadLocal(); debugging.assertFormulaInContext(formula); return delegate.evaluate(formula); } @Override - public @Nullable BigInteger evaluate(IntegerFormula formula) { + public @Nullable BigInteger evaluate(IntegerFormula formula) + throws SolverException, InterruptedException { debugging.assertThreadLocal(); debugging.assertFormulaInContext(formula); return delegate.evaluate(formula); } @Override - public @Nullable Rational evaluate(RationalFormula formula) { + public @Nullable Rational evaluate(RationalFormula formula) + throws SolverException, InterruptedException { debugging.assertThreadLocal(); debugging.assertFormulaInContext(formula); return delegate.evaluate(formula); } @Override - public @Nullable Boolean evaluate(BooleanFormula formula) { + public @Nullable Boolean evaluate(BooleanFormula formula) + throws SolverException, InterruptedException { debugging.assertThreadLocal(); debugging.assertFormulaInContext(formula); return delegate.evaluate(formula); } @Override - public @Nullable BigInteger evaluate(BitvectorFormula formula) { + public @Nullable BigInteger evaluate(BitvectorFormula formula) + throws SolverException, InterruptedException { debugging.assertThreadLocal(); debugging.assertFormulaInContext(formula); return delegate.evaluate(formula); } @Override - public @Nullable String evaluate(StringFormula formula) { + public @Nullable String evaluate(StringFormula formula) + throws SolverException, InterruptedException { debugging.assertThreadLocal(); debugging.assertFormulaInContext(formula); return delegate.evaluate(formula); } @Override - public @Nullable String evaluate(EnumerationFormula formula) { + public @Nullable String evaluate(EnumerationFormula formula) + throws SolverException, InterruptedException { debugging.assertThreadLocal(); debugging.assertFormulaInContext(formula); return delegate.evaluate(formula); } @Override - public @Nullable FloatingPointNumber evaluate(FloatingPointFormula formula) { + public @Nullable FloatingPointNumber evaluate(FloatingPointFormula formula) + throws SolverException, InterruptedException { debugging.assertThreadLocal(); debugging.assertFormulaInContext(formula); return delegate.evaluate(formula); } @Override - public ImmutableList asList() { + public ImmutableList asList() throws SolverException, InterruptedException { debugging.assertThreadLocal(); ImmutableList result = delegate.asList(); for (ValueAssignment v : result) { diff --git a/src/org/sosy_lab/java_smt/delegate/logging/LoggingBasicProverEnvironment.java b/src/org/sosy_lab/java_smt/delegate/logging/LoggingBasicProverEnvironment.java index 2f194c6125..78cb934251 100644 --- a/src/org/sosy_lab/java_smt/delegate/logging/LoggingBasicProverEnvironment.java +++ b/src/org/sosy_lab/java_smt/delegate/logging/LoggingBasicProverEnvironment.java @@ -87,14 +87,15 @@ public boolean isUnsatWithAssumptions(Collection pAssumptions) } @Override - public Model getModel() throws SolverException { + public Model getModel() throws SolverException, InterruptedException { Model m = wrapped.getModel(); logger.log(Level.FINE, "model", m); return m; } @Override - public ImmutableList getModelAssignments() throws SolverException { + public ImmutableList getModelAssignments() + throws SolverException, InterruptedException { ImmutableList m = wrapped.getModelAssignments(); logger.log(Level.FINE, "model", m); return m; diff --git a/src/org/sosy_lab/java_smt/delegate/statistics/StatisticsBasicProverEnvironment.java b/src/org/sosy_lab/java_smt/delegate/statistics/StatisticsBasicProverEnvironment.java index 49106d6324..1d5c7ece0f 100644 --- a/src/org/sosy_lab/java_smt/delegate/statistics/StatisticsBasicProverEnvironment.java +++ b/src/org/sosy_lab/java_smt/delegate/statistics/StatisticsBasicProverEnvironment.java @@ -81,7 +81,7 @@ public boolean isUnsatWithAssumptions(Collection pAssumptions) @SuppressWarnings("resource") @Override - public Model getModel() throws SolverException { + public Model getModel() throws SolverException, InterruptedException { stats.model.getAndIncrement(); return new StatisticsModel(delegate.getModel(), stats); } diff --git a/src/org/sosy_lab/java_smt/delegate/statistics/StatisticsModel.java b/src/org/sosy_lab/java_smt/delegate/statistics/StatisticsModel.java index e16ae324e1..d64795021d 100644 --- a/src/org/sosy_lab/java_smt/delegate/statistics/StatisticsModel.java +++ b/src/org/sosy_lab/java_smt/delegate/statistics/StatisticsModel.java @@ -23,6 +23,7 @@ import org.sosy_lab.java_smt.api.Model; import org.sosy_lab.java_smt.api.NumeralFormula.IntegerFormula; import org.sosy_lab.java_smt.api.NumeralFormula.RationalFormula; +import org.sosy_lab.java_smt.api.SolverException; import org.sosy_lab.java_smt.api.StringFormula; class StatisticsModel implements Model { @@ -36,61 +37,68 @@ class StatisticsModel implements Model { } @Override - public @Nullable T eval(T pFormula) { + public @Nullable T eval(T pFormula) + throws SolverException, InterruptedException { stats.modelEvaluations.getAndIncrement(); return delegate.eval(pFormula); } @Override - public @Nullable Object evaluate(Formula pF) { + public @Nullable Object evaluate(Formula pF) throws SolverException, InterruptedException { stats.modelEvaluations.getAndIncrement(); return delegate.evaluate(pF); } @Override - public @Nullable BigInteger evaluate(IntegerFormula pF) { + public @Nullable BigInteger evaluate(IntegerFormula pF) + throws SolverException, InterruptedException { stats.modelEvaluations.getAndIncrement(); return delegate.evaluate(pF); } @Override - public @Nullable Rational evaluate(RationalFormula pF) { + public @Nullable Rational evaluate(RationalFormula pF) + throws SolverException, InterruptedException { stats.modelEvaluations.getAndIncrement(); return delegate.evaluate(pF); } @Override - public @Nullable Boolean evaluate(BooleanFormula pF) { + public @Nullable Boolean evaluate(BooleanFormula pF) + throws SolverException, InterruptedException { stats.modelEvaluations.getAndIncrement(); return delegate.evaluate(pF); } @Override - public @Nullable BigInteger evaluate(BitvectorFormula pF) { + public @Nullable BigInteger evaluate(BitvectorFormula pF) + throws SolverException, InterruptedException { stats.modelEvaluations.getAndIncrement(); return delegate.evaluate(pF); } @Override - public @Nullable String evaluate(StringFormula pF) { + public @Nullable String evaluate(StringFormula pF) throws SolverException, InterruptedException { stats.modelEvaluations.getAndIncrement(); return delegate.evaluate(pF); } @Override - public @Nullable String evaluate(EnumerationFormula pF) { + public @Nullable String evaluate(EnumerationFormula pF) + throws SolverException, InterruptedException { stats.modelEvaluations.getAndIncrement(); return delegate.evaluate(pF); } @Override - public @Nullable FloatingPointNumber evaluate(FloatingPointFormula pF) { + public @Nullable FloatingPointNumber evaluate(FloatingPointFormula pF) + throws SolverException, InterruptedException { stats.modelEvaluations.getAndIncrement(); return delegate.evaluate(pF); } @Override - public ImmutableList asList() { + public ImmutableList asList() throws SolverException, InterruptedException { stats.modelListings.getAndIncrement(); return delegate.asList(); } diff --git a/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedBasicProverEnvironment.java b/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedBasicProverEnvironment.java index f0401c6db2..fa79246d01 100644 --- a/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedBasicProverEnvironment.java +++ b/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedBasicProverEnvironment.java @@ -76,7 +76,7 @@ public boolean isUnsatWithAssumptions(Collection pAssumptions) @SuppressWarnings("resource") @Override - public Model getModel() throws SolverException { + public Model getModel() throws SolverException, InterruptedException { synchronized (sync) { return new SynchronizedModel(delegate.getModel(), sync); } diff --git a/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedBasicProverEnvironmentWithContext.java b/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedBasicProverEnvironmentWithContext.java index 43922ccc25..4fecf91550 100644 --- a/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedBasicProverEnvironmentWithContext.java +++ b/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedBasicProverEnvironmentWithContext.java @@ -91,7 +91,7 @@ public boolean isUnsatWithAssumptions(Collection pAssumptions) @SuppressWarnings("resource") @Override - public Model getModel() throws SolverException { + public Model getModel() throws SolverException, InterruptedException { synchronized (sync) { return new SynchronizedModelWithContext(delegate.getModel(), sync, manager, otherManager); } diff --git a/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedModel.java b/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedModel.java index 3ebd078170..dbdf186521 100644 --- a/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedModel.java +++ b/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedModel.java @@ -24,6 +24,7 @@ import org.sosy_lab.java_smt.api.NumeralFormula.IntegerFormula; import org.sosy_lab.java_smt.api.NumeralFormula.RationalFormula; import org.sosy_lab.java_smt.api.SolverContext; +import org.sosy_lab.java_smt.api.SolverException; import org.sosy_lab.java_smt.api.StringFormula; class SynchronizedModel implements Model { @@ -37,70 +38,77 @@ class SynchronizedModel implements Model { } @Override - public @Nullable T eval(T pFormula) { + public @Nullable T eval(T pFormula) + throws SolverException, InterruptedException { synchronized (sync) { return delegate.eval(pFormula); } } @Override - public @Nullable Object evaluate(Formula pF) { + public @Nullable Object evaluate(Formula pF) throws SolverException, InterruptedException { synchronized (sync) { return delegate.evaluate(pF); } } @Override - public @Nullable BigInteger evaluate(IntegerFormula pF) { + public @Nullable BigInteger evaluate(IntegerFormula pF) + throws SolverException, InterruptedException { synchronized (sync) { return delegate.evaluate(pF); } } @Override - public @Nullable Rational evaluate(RationalFormula pF) { + public @Nullable Rational evaluate(RationalFormula pF) + throws SolverException, InterruptedException { synchronized (sync) { return delegate.evaluate(pF); } } @Override - public @Nullable Boolean evaluate(BooleanFormula pF) { + public @Nullable Boolean evaluate(BooleanFormula pF) + throws SolverException, InterruptedException { synchronized (sync) { return delegate.evaluate(pF); } } @Override - public @Nullable BigInteger evaluate(BitvectorFormula pF) { + public @Nullable BigInteger evaluate(BitvectorFormula pF) + throws SolverException, InterruptedException { synchronized (sync) { return delegate.evaluate(pF); } } @Override - public @Nullable String evaluate(StringFormula pF) { + public @Nullable String evaluate(StringFormula pF) throws SolverException, InterruptedException { synchronized (sync) { return delegate.evaluate(pF); } } @Override - public @Nullable String evaluate(EnumerationFormula pF) { + public @Nullable String evaluate(EnumerationFormula pF) + throws SolverException, InterruptedException { synchronized (sync) { return delegate.evaluate(pF); } } @Override - public @Nullable FloatingPointNumber evaluate(FloatingPointFormula pF) { + public @Nullable FloatingPointNumber evaluate(FloatingPointFormula pF) + throws SolverException, InterruptedException { synchronized (sync) { return delegate.evaluate(pF); } } @Override - public ImmutableList asList() { + public ImmutableList asList() throws SolverException, InterruptedException { synchronized (sync) { return delegate.asList(); } diff --git a/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedModelWithContext.java b/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedModelWithContext.java index e260776fce..a4ddc7b97d 100644 --- a/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedModelWithContext.java +++ b/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedModelWithContext.java @@ -25,6 +25,7 @@ import org.sosy_lab.java_smt.api.NumeralFormula.IntegerFormula; import org.sosy_lab.java_smt.api.NumeralFormula.RationalFormula; import org.sosy_lab.java_smt.api.SolverContext; +import org.sosy_lab.java_smt.api.SolverException; import org.sosy_lab.java_smt.api.StringFormula; class SynchronizedModelWithContext implements Model { @@ -66,7 +67,8 @@ class SynchronizedModelWithContext implements Model { } @Override - public @Nullable Boolean evaluate(BooleanFormula pF) { + public @Nullable Boolean evaluate(BooleanFormula pF) + throws SolverException, InterruptedException { BooleanFormula f; synchronized (sync) { f = otherManager.translateFrom(pF, manager); diff --git a/src/org/sosy_lab/java_smt/example/NQueens.java b/src/org/sosy_lab/java_smt/example/NQueens.java index 353e010c32..372acacc9d 100644 --- a/src/org/sosy_lab/java_smt/example/NQueens.java +++ b/src/org/sosy_lab/java_smt/example/NQueens.java @@ -260,7 +260,8 @@ private List diagonalRule(BooleanFormula[][] symbols) { * @param col the column index of the cell to check. * @return true if a queen is placed on the cell, false otherwise. */ - private boolean getValue(BooleanFormula[][] symbols, Model model, int row, int col) { + private boolean getValue(BooleanFormula[][] symbols, Model model, int row, int col) + throws SolverException, InterruptedException { return Boolean.TRUE.equals(model.evaluate(symbols[row][col])); } diff --git a/src/org/sosy_lab/java_smt/solvers/bitwuzla/BitwuzlaModel.java b/src/org/sosy_lab/java_smt/solvers/bitwuzla/BitwuzlaModel.java index 722fcaf05f..7c031e0833 100644 --- a/src/org/sosy_lab/java_smt/solvers/bitwuzla/BitwuzlaModel.java +++ b/src/org/sosy_lab/java_smt/solvers/bitwuzla/BitwuzlaModel.java @@ -19,6 +19,7 @@ import java.util.List; import java.util.Set; import org.checkerframework.checker.nullness.qual.Nullable; +import org.sosy_lab.java_smt.api.SolverException; import org.sosy_lab.java_smt.basicimpl.AbstractModel; import org.sosy_lab.java_smt.solvers.bitwuzla.api.Bitwuzla; import org.sosy_lab.java_smt.solvers.bitwuzla.api.Kind; @@ -50,7 +51,7 @@ protected BitwuzlaModel( /** Build a list of assignments that stays valid after closing the model. */ @Override - public ImmutableList asList() { + public ImmutableList asList() throws SolverException, InterruptedException { Preconditions.checkState(!isClosed()); Preconditions.checkState(!prover.isClosed(), "Cannot use model after prover is closed"); ImmutableSet.Builder variablesBuilder = ImmutableSet.builder(); @@ -108,13 +109,15 @@ private ValueAssignment getSimpleAssignment(Term pTerm) { argumentInterpretation); } - private Collection getArrayAssignment(Term pTerm) { + private Collection getArrayAssignment(Term pTerm) + throws SolverException, InterruptedException { return getArrayAssignments(pTerm, ImmutableList.of()); } // TODO: check this in detail. I think this might be incomplete. // We should add more Model tests in general. As most are parsing and int based! - private Collection getArrayAssignments(Term pTerm, List upperIndices) { + private Collection getArrayAssignments(Term pTerm, List upperIndices) + throws SolverException, InterruptedException { // Array children for store are structured in the following way: // {starting array, index, value} in "we add value at index to array" // Selections are structured: {starting array, index} diff --git a/src/org/sosy_lab/java_smt/solvers/cvc4/CVC4Model.java b/src/org/sosy_lab/java_smt/solvers/cvc4/CVC4Model.java index 483e9a8acf..ca99cc5c72 100644 --- a/src/org/sosy_lab/java_smt/solvers/cvc4/CVC4Model.java +++ b/src/org/sosy_lab/java_smt/solvers/cvc4/CVC4Model.java @@ -21,6 +21,7 @@ import java.util.List; import org.sosy_lab.java_smt.api.BooleanFormula; import org.sosy_lab.java_smt.api.Formula; +import org.sosy_lab.java_smt.api.SolverException; import org.sosy_lab.java_smt.basicimpl.AbstractModel; public class CVC4Model extends AbstractModel { @@ -34,7 +35,8 @@ public class CVC4Model extends AbstractModel { CVC4TheoremProver pProver, CVC4FormulaCreator pCreator, SmtEngine pSmtEngine, - Collection pAssertedExpressions) { + Collection pAssertedExpressions) + throws SolverException, InterruptedException { super(pProver, pCreator); smtEngine = pSmtEngine; prover = pProver; @@ -60,7 +62,8 @@ private Expr getValue(Expr f) { return prover.exportExpr(smtEngine.getValue(prover.importExpr(f))); } - private ImmutableList generateModel() { + private ImmutableList generateModel() + throws SolverException, InterruptedException { ImmutableSet.Builder builder = ImmutableSet.builder(); // Using creator.extractVariablesAndUFs we wouldn't get accurate information anymore as we // translate all bound vars back to their free counterparts in the visitor! @@ -72,7 +75,8 @@ private ImmutableList generateModel() { } // TODO this method is highly recursive and should be rewritten with a proper visitor - private void recursiveAssignmentFinder(ImmutableSet.Builder builder, Expr expr) { + private void recursiveAssignmentFinder(ImmutableSet.Builder builder, Expr expr) + throws SolverException, InterruptedException { if (expr.isConst() || expr.isNull()) { // We don't care about consts. return; @@ -95,7 +99,8 @@ private void recursiveAssignmentFinder(ImmutableSet.Builder bui } } - private ValueAssignment getAssignment(Expr pKeyTerm) { + private ValueAssignment getAssignment(Expr pKeyTerm) + throws SolverException, InterruptedException { List argumentInterpretation = new ArrayList<>(); for (Expr param : pKeyTerm) { argumentInterpretation.add(evaluateImpl(param)); diff --git a/src/org/sosy_lab/java_smt/solvers/cvc4/CVC4TheoremProver.java b/src/org/sosy_lab/java_smt/solvers/cvc4/CVC4TheoremProver.java index 3998fc59ff..a6c41002ee 100644 --- a/src/org/sosy_lab/java_smt/solvers/cvc4/CVC4TheoremProver.java +++ b/src/org/sosy_lab/java_smt/solvers/cvc4/CVC4TheoremProver.java @@ -144,7 +144,7 @@ private void assertFormula(BooleanFormula pF) { @SuppressWarnings("resource") @Override - public CVC4Model getModel() throws SolverException { + public CVC4Model getModel() throws SolverException, InterruptedException { Preconditions.checkState(!closed); Preconditions.checkState(!changedSinceLastSatQuery); checkGenerateModels(); @@ -183,7 +183,8 @@ private void setChanged() { } @Override - public ImmutableList getModelAssignments() throws SolverException { + public ImmutableList getModelAssignments() + throws SolverException, InterruptedException { Preconditions.checkState(!closed); Preconditions.checkState(!changedSinceLastSatQuery); return super.getModelAssignments(); diff --git a/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5AbstractProver.java b/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5AbstractProver.java index 85cfb0a23c..782a738f93 100644 --- a/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5AbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5AbstractProver.java @@ -150,7 +150,7 @@ protected String addConstraint0(BooleanFormula pF) { @SuppressWarnings("resource") @Override - public CVC5Model getModel() throws SolverException { + public CVC5Model getModel() throws SolverException, InterruptedException { Preconditions.checkState(!closed); Preconditions.checkState(!changedSinceLastSatQuery); checkGenerateModels(); @@ -185,7 +185,8 @@ protected void setChanged() { } @Override - public ImmutableList getModelAssignments() throws SolverException { + public ImmutableList getModelAssignments() + throws SolverException, InterruptedException { Preconditions.checkState(!closed); Preconditions.checkState(!changedSinceLastSatQuery); return super.getModelAssignments(); diff --git a/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5Model.java b/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5Model.java index dc57d3c5cf..6c2b39d93e 100644 --- a/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5Model.java +++ b/src/org/sosy_lab/java_smt/solvers/cvc5/CVC5Model.java @@ -21,6 +21,7 @@ import org.sosy_lab.java_smt.api.BooleanFormula; import org.sosy_lab.java_smt.api.Formula; import org.sosy_lab.java_smt.api.FormulaManager; +import org.sosy_lab.java_smt.api.SolverException; import org.sosy_lab.java_smt.basicimpl.AbstractModel; public class CVC5Model extends AbstractModel { @@ -37,7 +38,8 @@ public class CVC5Model extends AbstractModel { CVC5AbstractProver pProver, FormulaManager pMgr, CVC5FormulaCreator pCreator, - Collection pAssertedExpressions) { + Collection pAssertedExpressions) + throws SolverException, InterruptedException { super(pProver, pCreator); termManager = pCreator.getEnv(); solver = pProver.solver; @@ -56,7 +58,8 @@ public Term evalImpl(Term f) { return solver.getValue(f); } - private ImmutableList generateModel() { + private ImmutableList generateModel() + throws SolverException, InterruptedException { ImmutableSet.Builder builder = ImmutableSet.builder(); // Using creator.extractVariablesAndUFs we wouldn't get accurate information anymore as we // translate all bound vars back to their free counterparts in the visitor! @@ -68,7 +71,8 @@ private ImmutableList generateModel() { } // TODO this method is highly recursive and should be rewritten with a proper visitor - private void recursiveAssignmentFinder(ImmutableSet.Builder builder, Term expr) { + private void recursiveAssignmentFinder(ImmutableSet.Builder builder, Term expr) + throws SolverException, InterruptedException { try { Sort sort = expr.getSort(); Kind kind = expr.getKind(); @@ -109,7 +113,8 @@ private void recursiveAssignmentFinder(ImmutableSet.Builder bui } } - private ValueAssignment getAssignmentForUf(Term pKeyTerm) { + private ValueAssignment getAssignmentForUf(Term pKeyTerm) + throws SolverException, InterruptedException { // Ufs consist of arguments + 1 child, the first child is the function definition as a lambda // and the result, while the remaining children are the arguments. Note: we can't evaluate bound // variables! @@ -169,7 +174,8 @@ private ValueAssignment getAssignmentForUf(Term pKeyTerm) { keyFormula, valueFormula, equation, nameStr, value, argumentInterpretationBuilder.build()); } - private ValueAssignment getAssignment(Term pKeyTerm) { + private ValueAssignment getAssignment(Term pKeyTerm) + throws SolverException, InterruptedException { ImmutableList.Builder argumentInterpretationBuilder = ImmutableList.builder(); for (int i = 0; i < pKeyTerm.getNumChildren(); i++) { try { diff --git a/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5Model.java b/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5Model.java index 3b7266262c..a16c3a5995 100644 --- a/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5Model.java +++ b/src/org/sosy_lab/java_smt/solvers/mathsat5/Mathsat5Model.java @@ -13,7 +13,7 @@ import static org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.msat_is_array_type; import static org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.msat_make_array_read; import static org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.msat_make_eq; -import static org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.msat_model_create_iterator_with_sneaky_solver_exception; +import static org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.msat_model_create_iterator_with_solver_exception; import static org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.msat_model_eval; import static org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.msat_model_iterator_has_next; import static org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.msat_model_iterator_next; @@ -30,6 +30,7 @@ import java.util.List; import java.util.NoSuchElementException; import java.util.Set; +import org.sosy_lab.java_smt.api.SolverException; import org.sosy_lab.java_smt.basicimpl.AbstractModel; class Mathsat5Model extends AbstractModel { @@ -48,12 +49,12 @@ class Mathsat5Model extends AbstractModel { } @Override - public ImmutableList asList() { + public ImmutableList asList() throws SolverException, InterruptedException { Preconditions.checkState(!isClosed()); Preconditions.checkState(!prover.isClosed(), "cannot use model after prover is closed"); ImmutableList.Builder assignments = ImmutableList.builder(); - long modelIterator = msat_model_create_iterator_with_sneaky_solver_exception(model); + long modelIterator = msat_model_create_iterator_with_solver_exception(model); while (msat_model_iterator_has_next(modelIterator)) { long[] key = new long[1]; long[] value = new long[1]; @@ -71,7 +72,8 @@ public ImmutableList asList() { return assignments.build(); } - private ValueAssignment getAssignment(long key, long value) { + private ValueAssignment getAssignment(long key, long value) + throws SolverException, InterruptedException { List argumentInterpretation = new ArrayList<>(); for (int i = 0; i < msat_term_arity(key); i++) { long arg = msat_term_get_arg(key, i); @@ -89,7 +91,8 @@ private ValueAssignment getAssignment(long key, long value) { /** split an array-assignment into several assignments for all positions. */ private Collection getArrayAssignments( - long symbol, long key, long array, List upperIndices) { + long symbol, long key, long array, List upperIndices) + throws SolverException, InterruptedException { Collection assignments = new ArrayList<>(); Set indices = new HashSet<>(); while (msat_term_is_array_write(creator.getEnv(), array)) { diff --git a/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtAbstractProver.java b/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtAbstractProver.java index 845cd0ae9f..49d5893e16 100644 --- a/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtAbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/opensmt/OpenSmtAbstractProver.java @@ -146,7 +146,8 @@ protected void setChanged() { } @Override - public ImmutableList getModelAssignments() throws SolverException { + public ImmutableList getModelAssignments() + throws SolverException, InterruptedException { Preconditions.checkState(!closed); Preconditions.checkState(!changedSinceLastSatQuery); return super.getModelAssignments(); diff --git a/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolModel.java b/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolModel.java index 8194f78c14..7e6bfbb30b 100644 --- a/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolModel.java +++ b/src/org/sosy_lab/java_smt/solvers/smtinterpol/SmtInterpolModel.java @@ -22,6 +22,7 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Set; +import org.sosy_lab.java_smt.api.SolverException; import org.sosy_lab.java_smt.basicimpl.AbstractModel; import org.sosy_lab.java_smt.basicimpl.AbstractProver; import org.sosy_lab.java_smt.basicimpl.FormulaCreator; @@ -44,7 +45,7 @@ class SmtInterpolModel extends AbstractModel { } @Override - public ImmutableList asList() { + public ImmutableList asList() throws SolverException, InterruptedException { Set usedSymbols = new LinkedHashSet<>(); for (Term assertedTerm : assertedTerms) { @@ -95,7 +96,8 @@ private static String unescape(String s) { * @param upperIndices indices for multi-dimensional arrays */ private Collection getArrayAssignment( - String symbol, Term key, Term array, List upperIndices) { + String symbol, Term key, Term array, List upperIndices) + throws SolverException, InterruptedException { assert array.getSort().isArraySort(); Collection assignments = new ArrayList<>(); Term evaluation = model.evaluate(array); @@ -137,7 +139,8 @@ private Collection getArrayAssignment( } /** Get all modeled assignments for the UF. */ - private Collection getUFAssignments(FunctionSymbol symbol) { + private Collection getUFAssignments(FunctionSymbol symbol) + throws SolverException, InterruptedException { final Collection assignments = new ArrayList<>(); final String name = unescape(symbol.getApplicationString()); @@ -156,7 +159,8 @@ private Collection getUFAssignments(FunctionSymbol symbol) { return assignments; } - private ValueAssignment getAssignment(String key, ApplicationTerm term) { + private ValueAssignment getAssignment(String key, ApplicationTerm term) + throws SolverException, InterruptedException { Term value = model.evaluate(term); List argumentInterpretation = new ArrayList<>(); for (Term param : term.getParameters()) { diff --git a/src/org/sosy_lab/java_smt/test/ModelEvaluationTest.java b/src/org/sosy_lab/java_smt/test/ModelEvaluationTest.java index 8974490f3d..5efda13889 100644 --- a/src/org/sosy_lab/java_smt/test/ModelEvaluationTest.java +++ b/src/org/sosy_lab/java_smt/test/ModelEvaluationTest.java @@ -236,7 +236,8 @@ private List getConstraints() { return constraints; } - private BooleanFormula getNewConstraints(int i, Evaluator m) { + private BooleanFormula getNewConstraints(int i, Evaluator m) + throws SolverException, InterruptedException { BooleanFormula x = bmgr.makeVariable("x" + i); // prover.push(m.evaluate(x) ? bmgr.not(x) : x); return m.evaluate(x) ? x : bmgr.not(x); From 0ca8d4f723b415fb00354a3ab368fa919f1b1929 Mon Sep 17 00:00:00 2001 From: BaierD Date: Wed, 30 Jul 2025 16:08:35 +0200 Subject: [PATCH 74/87] Remove sneaky throws for Z3 specific code entirely --- .../java_smt/basicimpl/AbstractProver.java | 5 ++-- .../java_smt/solvers/z3/Z3AbstractProver.java | 4 ++-- .../java_smt/solvers/z3/Z3FormulaCreator.java | 24 ------------------- .../solvers/z3/Z3OptimizationProver.java | 8 +++---- .../java_smt/solvers/z3/Z3TheoremProver.java | 4 ++-- 5 files changed, 11 insertions(+), 34 deletions(-) diff --git a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java index 07dbbbb5d6..9262143157 100644 --- a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java +++ b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java @@ -26,6 +26,7 @@ import org.sosy_lab.java_smt.api.BooleanFormula; import org.sosy_lab.java_smt.api.Evaluator; import org.sosy_lab.java_smt.api.SolverContext.ProverOptions; +import org.sosy_lab.java_smt.api.SolverException; public abstract class AbstractProver implements BasicProverEnvironment { @@ -94,7 +95,7 @@ public final void push() throws InterruptedException { assertedFormulas.add(LinkedHashMultimap.create()); } - protected abstract void pushImpl() throws InterruptedException; + protected abstract void pushImpl() throws InterruptedException, SolverException; @Override public final void pop() { @@ -116,7 +117,7 @@ public final void pop() { } protected abstract @Nullable T addConstraintImpl(BooleanFormula constraint) - throws InterruptedException; + throws InterruptedException, SolverException; protected ImmutableSet getAssertedFormulas() { ImmutableSet.Builder builder = ImmutableSet.builder(); diff --git a/src/org/sosy_lab/java_smt/solvers/z3/Z3AbstractProver.java b/src/org/sosy_lab/java_smt/solvers/z3/Z3AbstractProver.java index 10cdd2f6dc..1d8beabc62 100644 --- a/src/org/sosy_lab/java_smt/solvers/z3/Z3AbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/z3/Z3AbstractProver.java @@ -122,7 +122,7 @@ protected Z3Model getEvaluatorWithoutChecks() throws SolverException, Interrupte protected abstract void assertContraintAndTrack(long constraint, long symbol); @Override - protected Void addConstraintImpl(BooleanFormula f) throws InterruptedException { + protected Void addConstraintImpl(BooleanFormula f) throws InterruptedException, SolverException { Preconditions.checkState(!closed); long e = creator.extractInfo(f); try { @@ -135,7 +135,7 @@ protected Void addConstraintImpl(BooleanFormula f) throws InterruptedException { assertContraint(e); } } catch (Z3Exception exception) { - throw creator.handleZ3ExceptionAsRuntimeException(exception); + throw creator.handleZ3Exception(exception); } return null; } diff --git a/src/org/sosy_lab/java_smt/solvers/z3/Z3FormulaCreator.java b/src/org/sosy_lab/java_smt/solvers/z3/Z3FormulaCreator.java index bde94b3e5f..b064f5593c 100644 --- a/src/org/sosy_lab/java_smt/solvers/z3/Z3FormulaCreator.java +++ b/src/org/sosy_lab/java_smt/solvers/z3/Z3FormulaCreator.java @@ -173,30 +173,6 @@ final SolverException handleZ3Exception(Z3Exception e) throw new SolverException("Z3 has thrown an exception", e); } - /** - * This method handles a Z3Exception, however it only throws a RuntimeException. This method is - * used in places where we cannot throw a checked exception in JavaSMT due to API restrictions. - * - * @param e the Z3Exception to handle - * @return nothing, always throw a RuntimeException - * @throws RuntimeException always thrown for the given Z3Exception - */ - final RuntimeException handleZ3ExceptionAsRuntimeException(Z3Exception e) { - try { - throw handleZ3Exception(e); - } catch (InterruptedException ex) { - Thread.currentThread().interrupt(); - throw sneakyThrow(e); - } catch (SolverException ex) { - throw sneakyThrow(e); - } - } - - @SuppressWarnings("unchecked") - private static RuntimeException sneakyThrow(Throwable e) throws E { - throw (E) e; - } - @Override public Long makeVariable(Long type, String varName) { long z3context = getEnv(); diff --git a/src/org/sosy_lab/java_smt/solvers/z3/Z3OptimizationProver.java b/src/org/sosy_lab/java_smt/solvers/z3/Z3OptimizationProver.java index 3c87cf7739..e50b39cc50 100644 --- a/src/org/sosy_lab/java_smt/solvers/z3/Z3OptimizationProver.java +++ b/src/org/sosy_lab/java_smt/solvers/z3/Z3OptimizationProver.java @@ -101,12 +101,12 @@ public OptStatus check() throws InterruptedException, SolverException { } @Override - protected void pushImpl() { + protected void pushImpl() throws SolverException, InterruptedException { push0(); try { Native.optimizePush(z3context, z3optSolver); } catch (Z3Exception exception) { - throw creator.handleZ3ExceptionAsRuntimeException(exception); + throw creator.handleZ3Exception(exception); } } @@ -197,11 +197,11 @@ private Optional round(int handle, Rational epsilon, RoundingFunction } @Override - protected long getZ3Model() { + protected long getZ3Model() throws SolverException, InterruptedException { try { return Native.optimizeGetModel(z3context, z3optSolver); } catch (Z3Exception e) { - throw creator.handleZ3ExceptionAsRuntimeException(e); + throw creator.handleZ3Exception(e); } } diff --git a/src/org/sosy_lab/java_smt/solvers/z3/Z3TheoremProver.java b/src/org/sosy_lab/java_smt/solvers/z3/Z3TheoremProver.java index 5b1f4720d7..4c8deefb1e 100644 --- a/src/org/sosy_lab/java_smt/solvers/z3/Z3TheoremProver.java +++ b/src/org/sosy_lab/java_smt/solvers/z3/Z3TheoremProver.java @@ -57,12 +57,12 @@ class Z3TheoremProver extends Z3AbstractProver implements ProverEnvironment { } @Override - protected void pushImpl() { + protected void pushImpl() throws SolverException, InterruptedException { push0(); try { Native.solverPush(z3context, z3solver); } catch (Z3Exception exception) { - throw creator.handleZ3ExceptionAsRuntimeException(exception); + throw creator.handleZ3Exception(exception); } } From cd51b02102ae5d0f2b24868caeb88385475bf128 Mon Sep 17 00:00:00 2001 From: BaierD Date: Wed, 30 Jul 2025 16:33:24 +0200 Subject: [PATCH 75/87] Add Solver- and InterruptedException to push() and addConstraint() API --- .../java_smt/api/BasicProverEnvironment.java | 6 +++--- .../java_smt/basicimpl/AbstractProver.java | 5 +++-- .../BasicProverWithAssumptionsWrapper.java | 4 ++-- .../DebuggingBasicProverEnvironment.java | 5 +++-- .../logging/LoggingBasicProverEnvironment.java | 7 ++++--- .../StatisticsBasicProverEnvironment.java | 5 +++-- .../SynchronizedBasicProverEnvironment.java | 5 +++-- ...hronizedBasicProverEnvironmentWithContext.java | 5 +++-- .../solvers/boolector/BoolectorNativeApiTest.java | 2 +- .../test/ProverEnvironmentSubjectTest.java | 4 ++-- .../java_smt/test/SolverConcurrencyTest.java | 4 ++-- .../sosy_lab/java_smt/test/SolverContextTest.java | 2 +- .../sosy_lab/java_smt/test/SolverStackTest0.java | 10 +++++----- .../java_smt/test/SolverThreadLocalityTest.java | 3 ++- src/org/sosy_lab/java_smt/test/TimeoutTest.java | 15 ++++++++------- 15 files changed, 45 insertions(+), 37 deletions(-) diff --git a/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java b/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java index 58f13f099d..a71a31eeca 100644 --- a/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java +++ b/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java @@ -35,7 +35,7 @@ public interface BasicProverEnvironment extends AutoCloseable { */ @Nullable @CanIgnoreReturnValue - default T push(BooleanFormula f) throws InterruptedException { + default T push(BooleanFormula f) throws InterruptedException, SolverException { push(); return addConstraint(f); } @@ -54,7 +54,7 @@ default T push(BooleanFormula f) throws InterruptedException { */ @Nullable @CanIgnoreReturnValue - T addConstraint(BooleanFormula constraint) throws InterruptedException; + T addConstraint(BooleanFormula constraint) throws InterruptedException, SolverException; /** * Create a new backtracking point, i.e., a new level on the assertion stack. Each level can hold @@ -63,7 +63,7 @@ default T push(BooleanFormula f) throws InterruptedException { *

If formulas are added before creating the first backtracking point, they can not be removed * via a POP-operation. */ - void push() throws InterruptedException; + void push() throws InterruptedException, SolverException; /** * Get the number of backtracking points/levels on the current stack. diff --git a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java index 9262143157..e6d81c1f53 100644 --- a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java +++ b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java @@ -89,7 +89,7 @@ public int size() { } @Override - public final void push() throws InterruptedException { + public final void push() throws InterruptedException, SolverException { checkState(!closed); pushImpl(); assertedFormulas.add(LinkedHashMultimap.create()); @@ -109,7 +109,8 @@ public final void pop() { @Override @CanIgnoreReturnValue - public final @Nullable T addConstraint(BooleanFormula constraint) throws InterruptedException { + public final @Nullable T addConstraint(BooleanFormula constraint) + throws InterruptedException, SolverException { checkState(!closed); T t = addConstraintImpl(constraint); Iterables.getLast(assertedFormulas).put(constraint, t); diff --git a/src/org/sosy_lab/java_smt/basicimpl/withAssumptionsWrapper/BasicProverWithAssumptionsWrapper.java b/src/org/sosy_lab/java_smt/basicimpl/withAssumptionsWrapper/BasicProverWithAssumptionsWrapper.java index 3afcbe0a41..b1ee0e3b15 100644 --- a/src/org/sosy_lab/java_smt/basicimpl/withAssumptionsWrapper/BasicProverWithAssumptionsWrapper.java +++ b/src/org/sosy_lab/java_smt/basicimpl/withAssumptionsWrapper/BasicProverWithAssumptionsWrapper.java @@ -43,13 +43,13 @@ public void pop() { } @Override - public T addConstraint(BooleanFormula constraint) throws InterruptedException { + public T addConstraint(BooleanFormula constraint) throws InterruptedException, SolverException { clearAssumptions(); return delegate.addConstraint(constraint); } @Override - public void push() throws InterruptedException { + public void push() throws InterruptedException, SolverException { clearAssumptions(); delegate.push(); } diff --git a/src/org/sosy_lab/java_smt/delegate/debugging/DebuggingBasicProverEnvironment.java b/src/org/sosy_lab/java_smt/delegate/debugging/DebuggingBasicProverEnvironment.java index 33e2ef8756..3cc3f92d47 100644 --- a/src/org/sosy_lab/java_smt/delegate/debugging/DebuggingBasicProverEnvironment.java +++ b/src/org/sosy_lab/java_smt/delegate/debugging/DebuggingBasicProverEnvironment.java @@ -36,14 +36,15 @@ public void pop() { } @Override - public @Nullable T addConstraint(BooleanFormula constraint) throws InterruptedException { + public @Nullable T addConstraint(BooleanFormula constraint) + throws InterruptedException, SolverException { debugging.assertThreadLocal(); debugging.assertFormulaInContext(constraint); return delegate.addConstraint(constraint); } @Override - public void push() throws InterruptedException { + public void push() throws InterruptedException, SolverException { debugging.assertThreadLocal(); delegate.push(); } diff --git a/src/org/sosy_lab/java_smt/delegate/logging/LoggingBasicProverEnvironment.java b/src/org/sosy_lab/java_smt/delegate/logging/LoggingBasicProverEnvironment.java index 78cb934251..3e0124a223 100644 --- a/src/org/sosy_lab/java_smt/delegate/logging/LoggingBasicProverEnvironment.java +++ b/src/org/sosy_lab/java_smt/delegate/logging/LoggingBasicProverEnvironment.java @@ -39,7 +39,7 @@ class LoggingBasicProverEnvironment implements BasicProverEnvironment { } @Override - public @Nullable T push(BooleanFormula f) throws InterruptedException { + public @Nullable T push(BooleanFormula f) throws InterruptedException, SolverException { logger.log(Level.FINE, "up to level " + level++); logger.log(Level.FINE, "formula pushed:", f); return wrapped.push(f); @@ -52,12 +52,13 @@ public void pop() { } @Override - public @Nullable T addConstraint(BooleanFormula constraint) throws InterruptedException { + public @Nullable T addConstraint(BooleanFormula constraint) + throws InterruptedException, SolverException { return wrapped.addConstraint(constraint); } @Override - public void push() throws InterruptedException { + public void push() throws InterruptedException, SolverException { logger.log(Level.FINE, "up to level " + level++); wrapped.push(); } diff --git a/src/org/sosy_lab/java_smt/delegate/statistics/StatisticsBasicProverEnvironment.java b/src/org/sosy_lab/java_smt/delegate/statistics/StatisticsBasicProverEnvironment.java index 1d5c7ece0f..f88e27cb9d 100644 --- a/src/org/sosy_lab/java_smt/delegate/statistics/StatisticsBasicProverEnvironment.java +++ b/src/org/sosy_lab/java_smt/delegate/statistics/StatisticsBasicProverEnvironment.java @@ -42,13 +42,14 @@ public void pop() { } @Override - public @Nullable T addConstraint(BooleanFormula pConstraint) throws InterruptedException { + public @Nullable T addConstraint(BooleanFormula pConstraint) + throws InterruptedException, SolverException { stats.constraint.getAndIncrement(); return delegate.addConstraint(pConstraint); } @Override - public void push() throws InterruptedException { + public void push() throws InterruptedException, SolverException { stats.push.getAndIncrement(); delegate.push(); } diff --git a/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedBasicProverEnvironment.java b/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedBasicProverEnvironment.java index fa79246d01..ef1c1f11a3 100644 --- a/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedBasicProverEnvironment.java +++ b/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedBasicProverEnvironment.java @@ -39,14 +39,15 @@ public void pop() { } @Override - public @Nullable T addConstraint(BooleanFormula pConstraint) throws InterruptedException { + public @Nullable T addConstraint(BooleanFormula pConstraint) + throws InterruptedException, SolverException { synchronized (sync) { return delegate.addConstraint(pConstraint); } } @Override - public void push() throws InterruptedException { + public void push() throws InterruptedException, SolverException { synchronized (sync) { delegate.push(); } diff --git a/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedBasicProverEnvironmentWithContext.java b/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedBasicProverEnvironmentWithContext.java index 4fecf91550..4ffe92e595 100644 --- a/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedBasicProverEnvironmentWithContext.java +++ b/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedBasicProverEnvironmentWithContext.java @@ -58,7 +58,8 @@ public void pop() { } @Override - public @Nullable T addConstraint(BooleanFormula pConstraint) throws InterruptedException { + public @Nullable T addConstraint(BooleanFormula pConstraint) + throws InterruptedException, SolverException { BooleanFormula constraint; synchronized (sync) { constraint = otherManager.translateFrom(pConstraint, manager); @@ -67,7 +68,7 @@ public void pop() { } @Override - public void push() throws InterruptedException { + public void push() throws InterruptedException, SolverException { delegate.push(); } diff --git a/src/org/sosy_lab/java_smt/solvers/boolector/BoolectorNativeApiTest.java b/src/org/sosy_lab/java_smt/solvers/boolector/BoolectorNativeApiTest.java index 6df6f5b30e..eb83b21111 100644 --- a/src/org/sosy_lab/java_smt/solvers/boolector/BoolectorNativeApiTest.java +++ b/src/org/sosy_lab/java_smt/solvers/boolector/BoolectorNativeApiTest.java @@ -153,7 +153,7 @@ public void dumpVariableTest() throws InvalidConfigurationException { @Test public void dumpVariableWithAssertionsOnStackTest() - throws InvalidConfigurationException, InterruptedException { + throws InvalidConfigurationException, InterruptedException, SolverException { ConfigurationBuilder config = Configuration.builder(); try (BoolectorSolverContext context = BoolectorSolverContext.create( diff --git a/src/org/sosy_lab/java_smt/test/ProverEnvironmentSubjectTest.java b/src/org/sosy_lab/java_smt/test/ProverEnvironmentSubjectTest.java index 743ea4b7d4..383a53bacf 100644 --- a/src/org/sosy_lab/java_smt/test/ProverEnvironmentSubjectTest.java +++ b/src/org/sosy_lab/java_smt/test/ProverEnvironmentSubjectTest.java @@ -51,7 +51,7 @@ public void testIsSatisfiableYes() throws SolverException, InterruptedException } @Test - public void testIsSatisfiableNo() throws InterruptedException { + public void testIsSatisfiableNo() throws InterruptedException, SolverException { requireUnsatCore(); try (ProverEnvironment env = context.newProverEnvironment( @@ -71,7 +71,7 @@ public void testIsUnsatisfiableYes() throws SolverException, InterruptedExceptio } @Test - public void testIsUnsatisfiableNo() throws InterruptedException { + public void testIsUnsatisfiableNo() throws InterruptedException, SolverException { requireModel(); try (ProverEnvironment env = context.newProverEnvironment(ProverOptions.GENERATE_MODELS)) { env.push(simpleFormula); diff --git a/src/org/sosy_lab/java_smt/test/SolverConcurrencyTest.java b/src/org/sosy_lab/java_smt/test/SolverConcurrencyTest.java index 3b3029a7d1..16b854cd4c 100644 --- a/src/org/sosy_lab/java_smt/test/SolverConcurrencyTest.java +++ b/src/org/sosy_lab/java_smt/test/SolverConcurrencyTest.java @@ -406,7 +406,7 @@ public void testConcurrentOptimization() { */ @Test public void testConcurrentIntegerStack() - throws InvalidConfigurationException, InterruptedException { + throws InvalidConfigurationException, InterruptedException, SolverException { requireIntegers(); requireConcurrentMultipleStackSupport(); SolverContext context = initSolver(); @@ -439,7 +439,7 @@ public void testConcurrentIntegerStack() */ @Test public void testConcurrentBitvectorStack() - throws InvalidConfigurationException, InterruptedException { + throws InvalidConfigurationException, InterruptedException, SolverException { requireBitvectors(); requireConcurrentMultipleStackSupport(); SolverContext context = initSolver(); diff --git a/src/org/sosy_lab/java_smt/test/SolverContextTest.java b/src/org/sosy_lab/java_smt/test/SolverContextTest.java index af349e5053..2b206fa03d 100644 --- a/src/org/sosy_lab/java_smt/test/SolverContextTest.java +++ b/src/org/sosy_lab/java_smt/test/SolverContextTest.java @@ -146,7 +146,7 @@ public void testCVC5WithValidOptions() throws InvalidConfigurationException { @Test(timeout = 5000) @SuppressWarnings({"try", "CheckReturnValue"}) public void testCVC5WithValidOptionsTimeLimit() - throws InvalidConfigurationException, InterruptedException { + throws InvalidConfigurationException, InterruptedException, SolverException { assume().that(solverToUse()).isEqualTo(Solvers.CVC5); // tlimit-per is time limit in ms of wall clock time per query diff --git a/src/org/sosy_lab/java_smt/test/SolverStackTest0.java b/src/org/sosy_lab/java_smt/test/SolverStackTest0.java index 6bbcdae4c8..74322eee55 100644 --- a/src/org/sosy_lab/java_smt/test/SolverStackTest0.java +++ b/src/org/sosy_lab/java_smt/test/SolverStackTest0.java @@ -194,7 +194,7 @@ public void stackTest() { } @Test - public void stackTest2() throws InterruptedException { + public void stackTest2() throws InterruptedException, SolverException { BasicProverEnvironment stack = newEnvironmentForTest(context); stack.push(); assertThat(stack.size()).isEqualTo(1); @@ -203,7 +203,7 @@ public void stackTest2() throws InterruptedException { } @Test - public void stackTest3() throws InterruptedException { + public void stackTest3() throws InterruptedException, SolverException { BasicProverEnvironment stack = newEnvironmentForTest(context); stack.push(); assertThat(stack.size()).isEqualTo(1); @@ -216,7 +216,7 @@ public void stackTest3() throws InterruptedException { } @Test - public void stackTest4() throws InterruptedException { + public void stackTest4() throws InterruptedException, SolverException { BasicProverEnvironment stack = newEnvironmentForTest(context); stack.push(); stack.push(); @@ -262,7 +262,7 @@ public void largerStackUsageTest() throws InterruptedException, SolverException } @Test - public void stackTest5() throws InterruptedException { + public void stackTest5() throws InterruptedException, SolverException { BasicProverEnvironment stack = newEnvironmentForTest(context); stack.push(); stack.pop(); @@ -508,7 +508,7 @@ public void multiStackTest() throws SolverException, InterruptedException { } @Test - public void avoidDualStacksIfNotSupported() throws InterruptedException { + public void avoidDualStacksIfNotSupported() throws InterruptedException, SolverException { assume() .withMessage("Solver does not support multiple stacks yet") .that(solver) diff --git a/src/org/sosy_lab/java_smt/test/SolverThreadLocalityTest.java b/src/org/sosy_lab/java_smt/test/SolverThreadLocalityTest.java index a08232a24a..f529528ae9 100644 --- a/src/org/sosy_lab/java_smt/test/SolverThreadLocalityTest.java +++ b/src/org/sosy_lab/java_smt/test/SolverThreadLocalityTest.java @@ -262,7 +262,8 @@ public void localInterpolationTest() throws InterruptedException, SolverExce @SuppressWarnings({"unchecked", "resource"}) @Test - public void nonLocalInterpolationTest() throws InterruptedException, ExecutionException { + public void nonLocalInterpolationTest() + throws InterruptedException, ExecutionException, SolverException { requireIntegers(); requireInterpolation(); assume().that(solverToUse()).isNotEqualTo(Solvers.CVC5); diff --git a/src/org/sosy_lab/java_smt/test/TimeoutTest.java b/src/org/sosy_lab/java_smt/test/TimeoutTest.java index 59d6d6a0c3..050848df92 100644 --- a/src/org/sosy_lab/java_smt/test/TimeoutTest.java +++ b/src/org/sosy_lab/java_smt/test/TimeoutTest.java @@ -24,6 +24,7 @@ import org.sosy_lab.java_smt.SolverContextFactory.Solvers; import org.sosy_lab.java_smt.api.BasicProverEnvironment; import org.sosy_lab.java_smt.api.BooleanFormula; +import org.sosy_lab.java_smt.api.SolverException; import org.sosy_lab.java_smt.api.Tactic; import org.sosy_lab.java_smt.solvers.opensmt.Logics; @@ -88,39 +89,39 @@ public void testTacticTimeout() { } @Test(timeout = TIMEOUT_MILLISECONDS) - public void testProverTimeoutInt() throws InterruptedException { + public void testProverTimeoutInt() throws InterruptedException, SolverException { requireIntegers(); testBasicProverTimeoutInt(() -> context.newProverEnvironment()); } @Test(timeout = TIMEOUT_MILLISECONDS) - public void testProverTimeoutBv() throws InterruptedException { + public void testProverTimeoutBv() throws InterruptedException, SolverException { requireBitvectors(); testBasicProverTimeoutBv(() -> context.newProverEnvironment()); } @Test(timeout = TIMEOUT_MILLISECONDS) - public void testInterpolationProverTimeout() throws InterruptedException { + public void testInterpolationProverTimeout() throws InterruptedException, SolverException { requireInterpolation(); requireIntegers(); testBasicProverTimeoutInt(() -> context.newProverEnvironmentWithInterpolation()); } @Test(timeout = TIMEOUT_MILLISECONDS) - public void testOptimizationProverTimeout() throws InterruptedException { + public void testOptimizationProverTimeout() throws InterruptedException, SolverException { requireOptimization(); requireIntegers(); testBasicProverTimeoutInt(() -> context.newOptimizationProverEnvironment()); } private void testBasicProverTimeoutInt(Supplier> proverConstructor) - throws InterruptedException { + throws InterruptedException, SolverException { HardIntegerFormulaGenerator gen = new HardIntegerFormulaGenerator(imgr, bmgr); testBasicProverTimeout(proverConstructor, gen.generate(200)); } private void testBasicProverTimeoutBv(Supplier> proverConstructor) - throws InterruptedException { + throws InterruptedException, SolverException { HardBitvectorFormulaGenerator gen = new HardBitvectorFormulaGenerator(bvmgr, bmgr); testBasicProverTimeout(proverConstructor, gen.generate(200)); } @@ -128,7 +129,7 @@ private void testBasicProverTimeoutBv(Supplier> prover @SuppressWarnings("CheckReturnValue") private void testBasicProverTimeout( Supplier> proverConstructor, BooleanFormula instance) - throws InterruptedException { + throws InterruptedException, SolverException { Thread t = new Thread( () -> { From 898832d35851d3d4539846f0a32da899f30d3e5c Mon Sep 17 00:00:00 2001 From: BaierD Date: Wed, 30 Jul 2025 16:39:42 +0200 Subject: [PATCH 76/87] Remove warnings about sneaky throws where they can't happen anymore --- .../java_smt/api/BasicProverEnvironment.java | 6 ----- src/org/sosy_lab/java_smt/api/Evaluator.java | 27 +++++-------------- src/org/sosy_lab/java_smt/api/Model.java | 3 --- 3 files changed, 6 insertions(+), 30 deletions(-) diff --git a/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java b/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java index a71a31eeca..459bd0ac6e 100644 --- a/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java +++ b/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java @@ -29,9 +29,6 @@ public interface BasicProverEnvironment extends AutoCloseable { * Push a backtracking point and add a formula to the current stack, asserting it. The return * value may be used to identify this formula later on in a query (this depends on the subtype of * the environment). - * - *

Warning: this might throw an unchecked {@link SolverException} as an extension of {@link - * Throwable}. */ @Nullable @CanIgnoreReturnValue @@ -48,9 +45,6 @@ default T push(BooleanFormula f) throws InterruptedException, SolverException { /** * Add a constraint to the latest backtracking point. - * - *

Warning: this might throw an unchecked {@link SolverException} as an extension of {@link - * Throwable}. */ @Nullable @CanIgnoreReturnValue diff --git a/src/org/sosy_lab/java_smt/api/Evaluator.java b/src/org/sosy_lab/java_smt/api/Evaluator.java index 6ea3f2e31a..5bd94038d5 100644 --- a/src/org/sosy_lab/java_smt/api/Evaluator.java +++ b/src/org/sosy_lab/java_smt/api/Evaluator.java @@ -68,9 +68,6 @@ public interface Evaluator extends AutoCloseable { * Type-safe evaluation for integer formulas. * *

The formula does not need to be a variable, we also allow complex expression. - * - *

Warning: this might throw an unchecked {@link SolverException} as an extension of {@link - * Throwable}. */ @Nullable BigInteger evaluate(IntegerFormula formula) throws SolverException, InterruptedException; @@ -79,9 +76,7 @@ public interface Evaluator extends AutoCloseable { * Type-safe evaluation for rational formulas. * *

The formula does not need to be a variable, we also allow complex expression. - * - *

Warning: this might throw an unchecked {@link SolverException} as an extension of {@link - * Throwable}. + */ @Nullable Rational evaluate(RationalFormula formula) throws SolverException, InterruptedException; @@ -89,9 +84,7 @@ public interface Evaluator extends AutoCloseable { * Type-safe evaluation for boolean formulas. * *

The formula does not need to be a variable, we also allow complex expression. - * - *

Warning: this might throw an unchecked {@link SolverException} as an extension of {@link - * Throwable}. + */ @Nullable Boolean evaluate(BooleanFormula formula) throws SolverException, InterruptedException; @@ -99,9 +92,7 @@ public interface Evaluator extends AutoCloseable { * Type-safe evaluation for bitvector formulas. * *

The formula does not need to be a variable, we also allow complex expression. - * - *

Warning: this might throw an unchecked {@link SolverException} as an extension of {@link - * Throwable}. + */ @Nullable BigInteger evaluate(BitvectorFormula formula) throws SolverException, InterruptedException; @@ -110,9 +101,7 @@ public interface Evaluator extends AutoCloseable { * Type-safe evaluation for string formulas. * *

The formula does not need to be a variable, we also allow complex expression. - * - *

Warning: this might throw an unchecked {@link SolverException} as an extension of {@link - * Throwable}. + */ @Nullable String evaluate(StringFormula formula) throws SolverException, InterruptedException; @@ -120,9 +109,7 @@ public interface Evaluator extends AutoCloseable { * Type-safe evaluation for enumeration formulas. * *

The formula does not need to be a variable, we also allow complex expression. - * - *

Warning: this might throw an unchecked {@link SolverException} as an extension of {@link - * Throwable}. + */ @Nullable String evaluate(EnumerationFormula formula) throws SolverException, InterruptedException; @@ -131,9 +118,7 @@ public interface Evaluator extends AutoCloseable { * Type-safe evaluation for floating-point formulas. * *

The formula does not need to be a variable, we also allow complex expression. - * - *

Warning: this might throw an unchecked {@link SolverException} as an extension of {@link - * Throwable}. + */ @Nullable FloatingPointNumber evaluate(FloatingPointFormula formula) throws SolverException, InterruptedException; diff --git a/src/org/sosy_lab/java_smt/api/Model.java b/src/org/sosy_lab/java_smt/api/Model.java index 8b4ac5fa3b..ad070de12c 100644 --- a/src/org/sosy_lab/java_smt/api/Model.java +++ b/src/org/sosy_lab/java_smt/api/Model.java @@ -69,9 +69,6 @@ private static RuntimeException sneakyThrow(Throwable e) t /** * Build a list of assignments that stays valid after closing the model. - * - *

Warning: this might throw an unchecked {@link SolverException} as an extension of {@link - * Throwable}. */ ImmutableList asList() throws SolverException, InterruptedException; From c9003997ea55e707f64bce084c8c113f16357202 Mon Sep 17 00:00:00 2001 From: BaierD Date: Wed, 30 Jul 2025 16:40:19 +0200 Subject: [PATCH 77/87] Format: remove warnings about sneaky throws where they can't happen anymore --- src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java | 4 +--- src/org/sosy_lab/java_smt/api/Evaluator.java | 6 ------ src/org/sosy_lab/java_smt/api/Model.java | 4 +--- 3 files changed, 2 insertions(+), 12 deletions(-) diff --git a/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java b/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java index 459bd0ac6e..d832794937 100644 --- a/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java +++ b/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java @@ -43,9 +43,7 @@ default T push(BooleanFormula f) throws InterruptedException, SolverException { */ void pop(); - /** - * Add a constraint to the latest backtracking point. - */ + /** Add a constraint to the latest backtracking point. */ @Nullable @CanIgnoreReturnValue T addConstraint(BooleanFormula constraint) throws InterruptedException, SolverException; diff --git a/src/org/sosy_lab/java_smt/api/Evaluator.java b/src/org/sosy_lab/java_smt/api/Evaluator.java index 5bd94038d5..7fa0199467 100644 --- a/src/org/sosy_lab/java_smt/api/Evaluator.java +++ b/src/org/sosy_lab/java_smt/api/Evaluator.java @@ -76,7 +76,6 @@ public interface Evaluator extends AutoCloseable { * Type-safe evaluation for rational formulas. * *

The formula does not need to be a variable, we also allow complex expression. - */ @Nullable Rational evaluate(RationalFormula formula) throws SolverException, InterruptedException; @@ -84,7 +83,6 @@ public interface Evaluator extends AutoCloseable { * Type-safe evaluation for boolean formulas. * *

The formula does not need to be a variable, we also allow complex expression. - */ @Nullable Boolean evaluate(BooleanFormula formula) throws SolverException, InterruptedException; @@ -92,7 +90,6 @@ public interface Evaluator extends AutoCloseable { * Type-safe evaluation for bitvector formulas. * *

The formula does not need to be a variable, we also allow complex expression. - */ @Nullable BigInteger evaluate(BitvectorFormula formula) throws SolverException, InterruptedException; @@ -101,7 +98,6 @@ public interface Evaluator extends AutoCloseable { * Type-safe evaluation for string formulas. * *

The formula does not need to be a variable, we also allow complex expression. - */ @Nullable String evaluate(StringFormula formula) throws SolverException, InterruptedException; @@ -109,7 +105,6 @@ public interface Evaluator extends AutoCloseable { * Type-safe evaluation for enumeration formulas. * *

The formula does not need to be a variable, we also allow complex expression. - */ @Nullable String evaluate(EnumerationFormula formula) throws SolverException, InterruptedException; @@ -118,7 +113,6 @@ public interface Evaluator extends AutoCloseable { * Type-safe evaluation for floating-point formulas. * *

The formula does not need to be a variable, we also allow complex expression. - */ @Nullable FloatingPointNumber evaluate(FloatingPointFormula formula) throws SolverException, InterruptedException; diff --git a/src/org/sosy_lab/java_smt/api/Model.java b/src/org/sosy_lab/java_smt/api/Model.java index ad070de12c..cb9e4c1297 100644 --- a/src/org/sosy_lab/java_smt/api/Model.java +++ b/src/org/sosy_lab/java_smt/api/Model.java @@ -67,9 +67,7 @@ private static RuntimeException sneakyThrow(Throwable e) t throw (E) e; } - /** - * Build a list of assignments that stays valid after closing the model. - */ + /** Build a list of assignments that stays valid after closing the model. */ ImmutableList asList() throws SolverException, InterruptedException; /** From 216641051a1bbd1ade305edbb95d2a1d308399c8 Mon Sep 17 00:00:00 2001 From: BaierD Date: Wed, 30 Jul 2025 17:13:32 +0200 Subject: [PATCH 78/87] Rename exception variable to fit naming schema --- src/org/sosy_lab/java_smt/api/Model.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/org/sosy_lab/java_smt/api/Model.java b/src/org/sosy_lab/java_smt/api/Model.java index cb9e4c1297..68e8c792c3 100644 --- a/src/org/sosy_lab/java_smt/api/Model.java +++ b/src/org/sosy_lab/java_smt/api/Model.java @@ -57,8 +57,8 @@ public interface Model extends Evaluator, Iterable, AutoCloseab default Iterator iterator() { try { return asList().iterator(); - } catch (SolverException | InterruptedException pE) { - throw sneakyThrow(pE); + } catch (SolverException | InterruptedException ex) { + throw sneakyThrow(ex); } } From 64b21b3b8b766b07e54ebd0bd525e797057b0688 Mon Sep 17 00:00:00 2001 From: BaierD Date: Wed, 30 Jul 2025 17:18:48 +0200 Subject: [PATCH 79/87] Improve warning for sneaky throws in model iterator() as suggested by Philipp --- src/org/sosy_lab/java_smt/api/Model.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/org/sosy_lab/java_smt/api/Model.java b/src/org/sosy_lab/java_smt/api/Model.java index 68e8c792c3..816fbdad7a 100644 --- a/src/org/sosy_lab/java_smt/api/Model.java +++ b/src/org/sosy_lab/java_smt/api/Model.java @@ -50,8 +50,9 @@ public interface Model extends Evaluator, Iterable, AutoCloseab * Please use a direct evaluation query to get the evaluation in such a case. * * - *

Warning: this might throw {@link SolverException} or {@link InterruptedException} as {@link - * RuntimeException} as checked exceptions are not supported by this method. + *

Warning: This method may throw the checked exceptions SolverException (in case of solver + * failures) and InterruptedException (in case of shutdown requests) although these exceptions are + * not declared with throws. */ @Override default Iterator iterator() { From 477efd085b3135cb93e1b08192b813c9b6277649 Mon Sep 17 00:00:00 2001 From: BaierD Date: Thu, 31 Jul 2025 16:57:09 +0200 Subject: [PATCH 80/87] Remove special handling of interrupts for API that did not throw InterruptedException for assumption removal and just throw it --- .../java_smt/basicimpl/AbstractProver.java | 3 +-- .../BasicProverWithAssumptionsWrapper.java | 26 +++---------------- ...rpolatingProverWithAssumptionsWrapper.java | 6 ----- 3 files changed, 4 insertions(+), 31 deletions(-) diff --git a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java index 9e8b4fca23..08c791b725 100644 --- a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java +++ b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java @@ -45,8 +45,7 @@ public abstract class AbstractProver implements BasicProverEnvironment { private static final String STACK_CHANGED_HELP = "Computation failed. The prover state has changed since the last call to isUnsat()."; - // Used as prefix concatenated with the reason in the IllegalStateException thrown for shutdowns - // Keep in sync with BasicProverWithAssumptionsWrapper.SHUTDOWN_EXCEPTION_PREFIX + // Used as prefix concatenated with the reason in the IllegalStateException private static final String SHUTDOWN_EXCEPTION_PREFIX = "Prover is not usable due to interrupt with message: "; diff --git a/src/org/sosy_lab/java_smt/basicimpl/withAssumptionsWrapper/BasicProverWithAssumptionsWrapper.java b/src/org/sosy_lab/java_smt/basicimpl/withAssumptionsWrapper/BasicProverWithAssumptionsWrapper.java index 288e4f6f7e..ce8954543d 100644 --- a/src/org/sosy_lab/java_smt/basicimpl/withAssumptionsWrapper/BasicProverWithAssumptionsWrapper.java +++ b/src/org/sosy_lab/java_smt/basicimpl/withAssumptionsWrapper/BasicProverWithAssumptionsWrapper.java @@ -22,11 +22,6 @@ public class BasicProverWithAssumptionsWrapper> implements BasicProverEnvironment { - // Used as prefix concatenated with the reason in the IllegalStateException thrown for shutdowns - // Keep in sync with AbstractProver.SHUTDOWN_EXCEPTION_PREFIX - private static final String SHUTDOWN_EXCEPTION_PREFIX = - "Prover is not usable due to interrupt with message: "; - protected final P delegate; protected final List solverAssumptionsAsFormula = new ArrayList<>(); @@ -41,21 +36,6 @@ protected void clearAssumptions() throws InterruptedException { solverAssumptionsAsFormula.clear(); } - protected void clearAssumptionsWithInterruptedException() throws InterruptedException { - for (int i = 0; i < solverAssumptionsAsFormula.size(); i++) { - try { - delegate.pop(); - } catch (IllegalStateException ise) { - if (ise.getMessage().startsWith(SHUTDOWN_EXCEPTION_PREFIX)) { - throw new InterruptedException(ise.getMessage().replace(SHUTDOWN_EXCEPTION_PREFIX, "")); - } else { - throw ise; - } - } - } - solverAssumptionsAsFormula.clear(); - } - @Override public void pop() throws InterruptedException { clearAssumptions(); @@ -81,14 +61,14 @@ public int size() { @Override public boolean isUnsat() throws SolverException, InterruptedException { - clearAssumptionsWithInterruptedException(); + clearAssumptions(); return delegate.isUnsat(); } @Override public boolean isUnsatWithAssumptions(Collection assumptions) throws SolverException, InterruptedException { - clearAssumptionsWithInterruptedException(); + clearAssumptions(); solverAssumptionsAsFormula.addAll(assumptions); for (BooleanFormula formula : assumptions) { registerPushedFormula(delegate.push(formula)); @@ -146,7 +126,7 @@ public String toString() { @Override public R allSat(AllSatCallback pCallback, List pImportant) throws InterruptedException, SolverException { - clearAssumptionsWithInterruptedException(); + clearAssumptions(); return delegate.allSat(pCallback, pImportant); } } diff --git a/src/org/sosy_lab/java_smt/basicimpl/withAssumptionsWrapper/InterpolatingProverWithAssumptionsWrapper.java b/src/org/sosy_lab/java_smt/basicimpl/withAssumptionsWrapper/InterpolatingProverWithAssumptionsWrapper.java index b9c23ed43f..726290ae47 100644 --- a/src/org/sosy_lab/java_smt/basicimpl/withAssumptionsWrapper/InterpolatingProverWithAssumptionsWrapper.java +++ b/src/org/sosy_lab/java_smt/basicimpl/withAssumptionsWrapper/InterpolatingProverWithAssumptionsWrapper.java @@ -86,12 +86,6 @@ protected void clearAssumptions() throws InterruptedException { solverAssumptionsFromPush.clear(); } - @Override - protected void clearAssumptionsWithInterruptedException() throws InterruptedException { - super.clearAssumptionsWithInterruptedException(); - solverAssumptionsFromPush.clear(); - } - final class RemoveAssumptionsFromFormulaVisitor extends BooleanFormulaTransformationVisitor { private RemoveAssumptionsFromFormulaVisitor() { From ca14eff7af662bce4383b74ad0656f4742bf63b7 Mon Sep 17 00:00:00 2001 From: BaierD Date: Thu, 31 Jul 2025 17:14:51 +0200 Subject: [PATCH 81/87] Remove special handling of interrupts for API that did not throw InterruptedException and just throw it, including getUnsatCore() --- .../java_smt/api/BasicProverEnvironment.java | 2 +- .../java_smt/basicimpl/AbstractProver.java | 32 +++---------------- .../BasicProverWithAssumptionsWrapper.java | 2 +- .../DebuggingBasicProverEnvironment.java | 2 +- .../LoggingBasicProverEnvironment.java | 2 +- .../StatisticsBasicProverEnvironment.java | 2 +- .../SynchronizedBasicProverEnvironment.java | 2 +- ...izedBasicProverEnvironmentWithContext.java | 2 +- ...LoggingSmtInterpolInterpolatingProver.java | 2 +- 9 files changed, 13 insertions(+), 35 deletions(-) diff --git a/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java b/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java index de83b6c732..1340124878 100644 --- a/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java +++ b/src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java @@ -116,7 +116,7 @@ default ImmutableList getModelAssignments() * Get an unsat core. This should be called only immediately after an {@link #isUnsat()} call that * returned false. */ - List getUnsatCore(); + List getUnsatCore() throws InterruptedException; /** * Returns an UNSAT core (if it exists, otherwise {@code Optional.empty()}), over the chosen diff --git a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java index 08c791b725..9c621a30e4 100644 --- a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java +++ b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java @@ -45,10 +45,6 @@ public abstract class AbstractProver implements BasicProverEnvironment { private static final String STACK_CHANGED_HELP = "Computation failed. The prover state has changed since the last call to isUnsat()."; - // Used as prefix concatenated with the reason in the IllegalStateException - private static final String SHUTDOWN_EXCEPTION_PREFIX = - "Prover is not usable due to interrupt with message: "; - private final boolean generateModels; private final boolean generateAllSat; private final boolean generateUnsatCores; @@ -103,12 +99,6 @@ protected final boolean shouldShutdown() { return contextShutdownNotifier.shouldShutdown(); } - public void checkShutdownState() { - if (shouldShutdown()) { - throw new IllegalStateException(getShutdownReason()); - } - } - protected boolean isGenerateUnsatCores() { return generateUnsatCores; } @@ -142,18 +132,6 @@ protected void setLastSatCheckUnsat() { wasLastSatCheckSat = false; } - /** - * Only to be called when at least one of the shutdown notifiers is supposed to be shutting down! - * Throws an Exception if no shutdown is requested! - */ - protected final String getShutdownReason() { - if (proverShutdownNotifier != null && proverShutdownNotifier.shouldShutdown()) { - return SHUTDOWN_EXCEPTION_PREFIX + proverShutdownNotifier.getReason(); - } - - return SHUTDOWN_EXCEPTION_PREFIX + contextShutdownNotifier.getReason(); - } - protected final void checkGenerateModels() { Preconditions.checkState(generateModels, TEMPLATE, ProverOptions.GENERATE_MODELS); } @@ -196,9 +174,9 @@ public final boolean isUnsat() throws SolverException, InterruptedException { protected abstract boolean isUnsatImpl() throws SolverException, InterruptedException; @Override - public List getUnsatCore() { + public List getUnsatCore() throws InterruptedException { checkState(!closed); - checkShutdownState(); + shutdownIfNecessary(); checkState(!wasLastSatCheckSat, NO_UNSAT_CORE_HELP); checkState(!stackChangedSinceLastQuery, STACK_CHANGED_HELP); checkGenerateUnsatCores(); @@ -234,7 +212,7 @@ protected abstract boolean isUnsatWithAssumptionsImpl(Collection @Override public final Model getModel() throws SolverException, InterruptedException { checkState(!closed); - checkShutdownState(); + shutdownIfNecessary(); checkState(wasLastSatCheckSat, NO_MODEL_HELP); checkState(!stackChangedSinceLastQuery, STACK_CHANGED_HELP); checkGenerateModels(); @@ -246,7 +224,7 @@ public final Model getModel() throws SolverException, InterruptedException { @Override public final Evaluator getEvaluator() throws SolverException, InterruptedException { checkState(!closed); - checkShutdownState(); + shutdownIfNecessary(); checkState(wasLastSatCheckSat, NO_MODEL_HELP); checkState(!stackChangedSinceLastQuery, STACK_CHANGED_HELP); checkGenerateModels(); @@ -355,7 +333,7 @@ protected void closeAllEvaluators() { public ImmutableList getModelAssignments() throws SolverException, InterruptedException { Preconditions.checkState(!isClosed()); - checkShutdownState(); + shutdownIfNecessary(); Preconditions.checkState(!stackChangedSinceLastQuery, STACK_CHANGED_HELP); checkState(wasLastSatCheckSat); try (Model model = getModel()) { diff --git a/src/org/sosy_lab/java_smt/basicimpl/withAssumptionsWrapper/BasicProverWithAssumptionsWrapper.java b/src/org/sosy_lab/java_smt/basicimpl/withAssumptionsWrapper/BasicProverWithAssumptionsWrapper.java index ce8954543d..278cf2a26e 100644 --- a/src/org/sosy_lab/java_smt/basicimpl/withAssumptionsWrapper/BasicProverWithAssumptionsWrapper.java +++ b/src/org/sosy_lab/java_smt/basicimpl/withAssumptionsWrapper/BasicProverWithAssumptionsWrapper.java @@ -91,7 +91,7 @@ public ImmutableList getModelAssignments() } @Override - public List getUnsatCore() { + public List getUnsatCore() throws InterruptedException { return delegate.getUnsatCore(); } diff --git a/src/org/sosy_lab/java_smt/delegate/debugging/DebuggingBasicProverEnvironment.java b/src/org/sosy_lab/java_smt/delegate/debugging/DebuggingBasicProverEnvironment.java index 1a3daf705f..51a694be62 100644 --- a/src/org/sosy_lab/java_smt/delegate/debugging/DebuggingBasicProverEnvironment.java +++ b/src/org/sosy_lab/java_smt/delegate/debugging/DebuggingBasicProverEnvironment.java @@ -88,7 +88,7 @@ public ImmutableList getModelAssignments() } @Override - public List getUnsatCore() { + public List getUnsatCore() throws InterruptedException { debugging.assertThreadLocal(); return delegate.getUnsatCore(); } diff --git a/src/org/sosy_lab/java_smt/delegate/logging/LoggingBasicProverEnvironment.java b/src/org/sosy_lab/java_smt/delegate/logging/LoggingBasicProverEnvironment.java index 78f7b43098..03266d0f02 100644 --- a/src/org/sosy_lab/java_smt/delegate/logging/LoggingBasicProverEnvironment.java +++ b/src/org/sosy_lab/java_smt/delegate/logging/LoggingBasicProverEnvironment.java @@ -103,7 +103,7 @@ public ImmutableList getModelAssignments() } @Override - public List getUnsatCore() { + public List getUnsatCore() throws InterruptedException { List unsatCore = wrapped.getUnsatCore(); logger.log(Level.FINE, "unsat-core", unsatCore); return unsatCore; diff --git a/src/org/sosy_lab/java_smt/delegate/statistics/StatisticsBasicProverEnvironment.java b/src/org/sosy_lab/java_smt/delegate/statistics/StatisticsBasicProverEnvironment.java index 84222d1b4c..a76f926473 100644 --- a/src/org/sosy_lab/java_smt/delegate/statistics/StatisticsBasicProverEnvironment.java +++ b/src/org/sosy_lab/java_smt/delegate/statistics/StatisticsBasicProverEnvironment.java @@ -96,7 +96,7 @@ public ImmutableList getModelAssignments() } @Override - public List getUnsatCore() { + public List getUnsatCore() throws InterruptedException { stats.unsatCore.getAndIncrement(); return delegate.getUnsatCore(); } diff --git a/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedBasicProverEnvironment.java b/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedBasicProverEnvironment.java index 78e2ce278e..c5295289c1 100644 --- a/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedBasicProverEnvironment.java +++ b/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedBasicProverEnvironment.java @@ -92,7 +92,7 @@ public ImmutableList getModelAssignments() } @Override - public List getUnsatCore() { + public List getUnsatCore() throws InterruptedException { synchronized (sync) { return delegate.getUnsatCore(); } diff --git a/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedBasicProverEnvironmentWithContext.java b/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedBasicProverEnvironmentWithContext.java index efe13fa871..069130593d 100644 --- a/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedBasicProverEnvironmentWithContext.java +++ b/src/org/sosy_lab/java_smt/delegate/synchronize/SynchronizedBasicProverEnvironmentWithContext.java @@ -106,7 +106,7 @@ public ImmutableList getModelAssignments() } @Override - public List getUnsatCore() { + public List getUnsatCore() throws InterruptedException { return translate(delegate.getUnsatCore(), otherManager, manager); } diff --git a/src/org/sosy_lab/java_smt/solvers/smtinterpol/LoggingSmtInterpolInterpolatingProver.java b/src/org/sosy_lab/java_smt/solvers/smtinterpol/LoggingSmtInterpolInterpolatingProver.java index 076ba9fe8c..b7e83177e3 100644 --- a/src/org/sosy_lab/java_smt/solvers/smtinterpol/LoggingSmtInterpolInterpolatingProver.java +++ b/src/org/sosy_lab/java_smt/solvers/smtinterpol/LoggingSmtInterpolInterpolatingProver.java @@ -79,7 +79,7 @@ protected String addConstraintImpl(BooleanFormula f) throws InterruptedException } @Override - public List getUnsatCore() { + public List getUnsatCore() throws InterruptedException { out.println("(get-unsat-core)"); return super.getUnsatCore(); } From 4b429db4a99c1e564ba0a6f44db314ca9244d5cc Mon Sep 17 00:00:00 2001 From: BaierD Date: Thu, 31 Jul 2025 17:15:10 +0200 Subject: [PATCH 82/87] Switch all expected exceptions after interrupt to InterruptedException in TimeoutTest.java --- src/org/sosy_lab/java_smt/test/TimeoutTest.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/org/sosy_lab/java_smt/test/TimeoutTest.java b/src/org/sosy_lab/java_smt/test/TimeoutTest.java index 6a9c3349c1..cd42c5d0e3 100644 --- a/src/org/sosy_lab/java_smt/test/TimeoutTest.java +++ b/src/org/sosy_lab/java_smt/test/TimeoutTest.java @@ -633,11 +633,10 @@ private void testProverBasedTimeoutWithFeatures( private void assertProverAPIThrowsInterruptedException(BasicProverEnvironment pe) throws SolverException { assertThrows(InterruptedException.class, pe::isUnsat); - // TODO: let all the API in prover throw interrupted? - assertThrows(IllegalStateException.class, pe::getModel); - assertThrows(IllegalStateException.class, pe::getModelAssignments); - assertThrows(IllegalStateException.class, pe::getEvaluator); - assertThrows(IllegalStateException.class, pe::getUnsatCore); + assertThrows(InterruptedException.class, pe::getModel); + assertThrows(InterruptedException.class, pe::getModelAssignments); + assertThrows(InterruptedException.class, pe::getEvaluator); + assertThrows(InterruptedException.class, pe::getUnsatCore); try { pe.allSat( new AllSatCallback<>() { @@ -671,7 +670,7 @@ public List> getResult() { assertThrows(InterruptedException.class, () -> pe.addConstraint(bmgr.makeFalse())); assertThrows(InterruptedException.class, () -> pe.push(bmgr.makeFalse())); assertThrows(InterruptedException.class, pe::push); - assertThrows(IllegalStateException.class, pe::pop); + assertThrows(InterruptedException.class, pe::pop); if (pe instanceof InterpolatingProverEnvironment) { InterpolatingProverEnvironment ipe = (InterpolatingProverEnvironment) pe; assertThrows(InterruptedException.class, () -> ipe.getInterpolant(ImmutableList.of())); From d44790291edeb345645b8621fe0e4b7bd2da9c89 Mon Sep 17 00:00:00 2001 From: BaierD Date: Thu, 31 Jul 2025 17:23:29 +0200 Subject: [PATCH 83/87] Remove toString() in lazy evaluation to be actually lazy in AbstractProver checkInterpolationArguments() --- src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java index 9c621a30e4..0d1a094c79 100644 --- a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java +++ b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java @@ -296,7 +296,7 @@ protected void checkInterpolationArguments(Collection formulasOfA) { checkArgument( getAssertedConstraintIds().containsAll(formulasOfA), "Interpolation can only be done over previously asserted formulas. %s", - MoreStrings.lazyString(() -> getErrorString(formulasOfA)).toString()); + MoreStrings.lazyString(() -> getErrorString(formulasOfA))); } private String getErrorString(Collection formulasOfA) { From 22bc81185749977cc2d4d6899ea9ec5a0353a601 Mon Sep 17 00:00:00 2001 From: BaierD Date: Thu, 31 Jul 2025 18:30:52 +0200 Subject: [PATCH 84/87] Move JavaDoc from throws to general info for prover environment creation with shutdown notifiers --- .../sosy_lab/java_smt/api/SolverContext.java | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/org/sosy_lab/java_smt/api/SolverContext.java b/src/org/sosy_lab/java_smt/api/SolverContext.java index 71e9119777..fba08f6202 100644 --- a/src/org/sosy_lab/java_smt/api/SolverContext.java +++ b/src/org/sosy_lab/java_smt/api/SolverContext.java @@ -69,7 +69,9 @@ enum ProverOptions { /** * Create a fresh new {@link ProverEnvironment} which encapsulates an assertion stack and can be * used to check formulas for unsatisfiability. The returned prover instance can be shut down - * using the given {@link ShutdownNotifier}. + * using the given {@link ShutdownNotifier}. Solvers that don't support isolated prover shutdown + * throw a {@link UnsupportedOperationException} for this method and {@link + * #newProverEnvironment(ProverOptions...)} should be used instead. * * @param pProverShutdownNotifier a {@link ShutdownNotifier} that can be used to stop the prover * returned by this method. The prover is not usable anymore after a shutdown has been @@ -79,9 +81,6 @@ enum ProverOptions { * when creating the context. * @param options Options specified for the prover environment. All the options specified in * {@link ProverOptions} are turned off by default. - * @throws UnsupportedOperationException Solvers that don't support isolated prover shutdown throw - * a {@link UnsupportedOperationException} for this method and {@link - * #newProverEnvironment(ProverOptions...)} should be used instead. */ ProverEnvironment newProverEnvironment( ShutdownNotifier pProverShutdownNotifier, ProverOptions... options); @@ -101,7 +100,9 @@ ProverEnvironment newProverEnvironment( /** * Create a fresh new {@link InterpolatingProverEnvironment} which encapsulates an assertion stack * and allows generating and retrieve interpolants for unsatisfiable formulas. The returned prover - * instance can be shut down using the given {@link ShutdownNotifier}. + * instance can be shut down using the given {@link ShutdownNotifier}. Solvers that don't support + * isolated prover shutdown throw a {@link UnsupportedOperationException} for this method and + * {@link #newProverEnvironment(ProverOptions...)} should be used instead. * * @implNote If the SMT solver is able to handle satisfiability tests with assumptions please * consider implementing the {@link InterpolatingProverEnvironment} interface, and return an @@ -114,9 +115,6 @@ ProverEnvironment newProverEnvironment( * when creating the context. * @param options Options specified for the prover environment. All the options specified in * {@link ProverOptions} are turned off by default. - * @throws UnsupportedOperationException Solvers that don't support isolated prover shutdown throw - * a {@link UnsupportedOperationException} for this method and {@link - * #newProverEnvironment(ProverOptions...)} should be used instead. */ InterpolatingProverEnvironment newProverEnvironmentWithInterpolation( ShutdownNotifier pProverShutdownNotifier, ProverOptions... options); @@ -133,7 +131,9 @@ InterpolatingProverEnvironment newProverEnvironmentWithInterpolation( /** * Create a fresh new {@link OptimizationProverEnvironment} which encapsulates an assertion stack * and allows solving optimization queries. The returned prover instance can be shut down using - * the given {@link ShutdownNotifier}. + * the given {@link ShutdownNotifier}. Solvers that don't support isolated prover shutdown throw a + * {@link UnsupportedOperationException} for this method and {@link + * #newProverEnvironment(ProverOptions...)} should be used instead. * * @param pProverShutdownNotifier a {@link ShutdownNotifier} that can be used to stop the prover * returned by this method. The prover is not usable anymore after a shutdown has been @@ -143,9 +143,6 @@ InterpolatingProverEnvironment newProverEnvironmentWithInterpolation( * when creating the context. * @param options Options specified for the prover environment. All the options specified in * {@link ProverOptions} are turned off by default. - * @throws UnsupportedOperationException Solvers that don't support isolated prover shutdown throw - * a {@link UnsupportedOperationException} for this method and {@link - * #newProverEnvironment(ProverOptions...)} should be used instead. */ OptimizationProverEnvironment newOptimizationProverEnvironment( ShutdownNotifier pProverShutdownNotifier, ProverOptions... options); From a75ec8a294bb1e725f4213b52d4af991233cd6dd Mon Sep 17 00:00:00 2001 From: BaierD Date: Thu, 31 Jul 2025 19:09:16 +0200 Subject: [PATCH 85/87] Use dummy ShutdownNotifier instead of null if there is no prover specific one --- .../java_smt/basicimpl/AbstractProver.java | 18 +++++++++--------- .../java_smt/basicimpl/ShutdownHook.java | 4 +--- .../solvers/yices2/Yices2NativeApi.java | 8 ++------ .../java_smt/solvers/z3/Z3TheoremProver.java | 4 +--- 4 files changed, 13 insertions(+), 21 deletions(-) diff --git a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java index 0d1a094c79..2a1dcb92d5 100644 --- a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java +++ b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java @@ -65,7 +65,7 @@ public abstract class AbstractProver implements BasicProverEnvironment { private static final String TEMPLATE = "Please set the prover option %s."; - protected final @Nullable ShutdownNotifier proverShutdownNotifier; + protected final ShutdownNotifier proverShutdownNotifier; protected final ShutdownNotifier contextShutdownNotifier; protected AbstractProver( @@ -82,21 +82,21 @@ protected AbstractProver( assertedFormulas.add(LinkedHashMultimap.create()); contextShutdownNotifier = pContextShutdownNotifier; - proverShutdownNotifier = pProverShutdownNotifier; + + if (pProverShutdownNotifier == null) { + proverShutdownNotifier = ShutdownNotifier.createDummy(); + } else { + proverShutdownNotifier = pProverShutdownNotifier; + } } protected final void shutdownIfNecessary() throws InterruptedException { contextShutdownNotifier.shutdownIfNecessary(); - if (proverShutdownNotifier != null) { - proverShutdownNotifier.shutdownIfNecessary(); - } + proverShutdownNotifier.shutdownIfNecessary(); } protected final boolean shouldShutdown() { - if (proverShutdownNotifier != null) { - return contextShutdownNotifier.shouldShutdown() || proverShutdownNotifier.shouldShutdown(); - } - return contextShutdownNotifier.shouldShutdown(); + return contextShutdownNotifier.shouldShutdown() || proverShutdownNotifier.shouldShutdown(); } protected boolean isGenerateUnsatCores() { diff --git a/src/org/sosy_lab/java_smt/basicimpl/ShutdownHook.java b/src/org/sosy_lab/java_smt/basicimpl/ShutdownHook.java index fd0ee0c8cd..49ea73c5ba 100644 --- a/src/org/sosy_lab/java_smt/basicimpl/ShutdownHook.java +++ b/src/org/sosy_lab/java_smt/basicimpl/ShutdownHook.java @@ -62,8 +62,6 @@ public void shutdownRequested(@Nullable String reasonUnused) { public void close() { isActiveHook.set(false); contextShutdownNotifier.unregister(this); - if (proverShutdownNotifier != null) { - proverShutdownNotifier.unregister(this); - } + proverShutdownNotifier.unregister(this); } } diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApi.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApi.java index 2e770dc042..6977652640 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApi.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApi.java @@ -700,14 +700,10 @@ private static boolean satCheckWithShutdownNotifier( new ShutdownHook( contextShutdownNotifier, proverShutdownNotifier, () -> yices_stop_search(pCtx))) { contextShutdownNotifier.shutdownIfNecessary(); - if (proverShutdownNotifier != null) { - proverShutdownNotifier.shutdownIfNecessary(); - } - result = satCheck.get(); // the expensive computation - } - if (proverShutdownNotifier != null) { proverShutdownNotifier.shutdownIfNecessary(); + result = satCheck.get(); // the expensive computation } + proverShutdownNotifier.shutdownIfNecessary(); contextShutdownNotifier.shutdownIfNecessary(); return check_result(result); } diff --git a/src/org/sosy_lab/java_smt/solvers/z3/Z3TheoremProver.java b/src/org/sosy_lab/java_smt/solvers/z3/Z3TheoremProver.java index 86e3602b07..f2ed34c142 100644 --- a/src/org/sosy_lab/java_smt/solvers/z3/Z3TheoremProver.java +++ b/src/org/sosy_lab/java_smt/solvers/z3/Z3TheoremProver.java @@ -198,9 +198,7 @@ public void close() { propagator = null; } contextShutdownNotifier.unregister(interruptListener); - if (proverShutdownNotifier != null) { - proverShutdownNotifier.unregister(interruptListener); - } + proverShutdownNotifier.unregister(interruptListener); } super.close(); } From 5f30d4291b728f40a147c8f998d9ef44d0dd27a6 Mon Sep 17 00:00:00 2001 From: BaierD Date: Mon, 4 Aug 2025 16:42:29 +0200 Subject: [PATCH 86/87] Remove null checks for prover based ShutdownNotifier when no longer needed --- .../sosy_lab/java_smt/basicimpl/ShutdownHook.java | 12 ++++-------- .../java_smt/solvers/yices2/Yices2NativeApi.java | 7 +++---- .../java_smt/solvers/z3/Z3FormulaCreator.java | 8 +++----- src/org/sosy_lab/java_smt/solvers/z3/Z3Model.java | 4 ++-- .../java_smt/solvers/z3/Z3TheoremProver.java | 4 +--- 5 files changed, 13 insertions(+), 22 deletions(-) diff --git a/src/org/sosy_lab/java_smt/basicimpl/ShutdownHook.java b/src/org/sosy_lab/java_smt/basicimpl/ShutdownHook.java index 49ea73c5ba..b78e63402d 100644 --- a/src/org/sosy_lab/java_smt/basicimpl/ShutdownHook.java +++ b/src/org/sosy_lab/java_smt/basicimpl/ShutdownHook.java @@ -23,22 +23,18 @@ public final class ShutdownHook implements ShutdownRequestListener, AutoCloseable { private final ShutdownNotifier contextShutdownNotifier; - private final @Nullable ShutdownNotifier proverShutdownNotifier; + private final ShutdownNotifier proverShutdownNotifier; private final Runnable interruptCall; public ShutdownHook( ShutdownNotifier pContextShutdownNotifier, - @Nullable ShutdownNotifier pProverShutdownNotifier, + ShutdownNotifier pProverShutdownNotifier, Runnable pInterruptCall) { interruptCall = Preconditions.checkNotNull(pInterruptCall); contextShutdownNotifier = Preconditions.checkNotNull(pContextShutdownNotifier); contextShutdownNotifier.register(this); - if (pProverShutdownNotifier != null) { - proverShutdownNotifier = pProverShutdownNotifier; - proverShutdownNotifier.register(this); - } else { - proverShutdownNotifier = null; - } + proverShutdownNotifier = pProverShutdownNotifier; + proverShutdownNotifier.register(this); } final AtomicBoolean isActiveHook = new AtomicBoolean(true); diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApi.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApi.java index 6977652640..e80ff2800f 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApi.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApi.java @@ -9,7 +9,6 @@ package org.sosy_lab.java_smt.solvers.yices2; import java.util.function.Supplier; -import org.checkerframework.checker.nullness.qual.Nullable; import org.sosy_lab.common.ShutdownNotifier; import org.sosy_lab.java_smt.basicimpl.ShutdownHook; @@ -661,7 +660,7 @@ public static boolean yices_check_sat( long ctx, long params, ShutdownNotifier contextShutdownNotifier, - @Nullable ShutdownNotifier proverShutdownNotifier) + ShutdownNotifier proverShutdownNotifier) throws IllegalStateException, InterruptedException { return satCheckWithShutdownNotifier( () -> yices_check_context(ctx, params), @@ -679,7 +678,7 @@ public static boolean yices_check_sat_with_assumptions( int size, int[] assumptions, ShutdownNotifier contextShutdownNotifier, - @Nullable ShutdownNotifier proverShutdownNotifier) + ShutdownNotifier proverShutdownNotifier) throws InterruptedException { return satCheckWithShutdownNotifier( () -> yices_check_context_with_assumptions(ctx, params, size, assumptions), @@ -693,7 +692,7 @@ private static boolean satCheckWithShutdownNotifier( Supplier satCheck, long pCtx, ShutdownNotifier contextShutdownNotifier, - @Nullable ShutdownNotifier proverShutdownNotifier) + ShutdownNotifier proverShutdownNotifier) throws InterruptedException { int result; try (ShutdownHook hook = diff --git a/src/org/sosy_lab/java_smt/solvers/z3/Z3FormulaCreator.java b/src/org/sosy_lab/java_smt/solvers/z3/Z3FormulaCreator.java index 03d49f2052..2df83d5d03 100644 --- a/src/org/sosy_lab/java_smt/solvers/z3/Z3FormulaCreator.java +++ b/src/org/sosy_lab/java_smt/solvers/z3/Z3FormulaCreator.java @@ -168,13 +168,11 @@ class Z3FormulaCreator extends FormulaCreator { */ @CanIgnoreReturnValue final SolverException handleZ3Exception( - Z3Exception e, @Nullable ShutdownNotifier pAdditionalShutdownNotifier) + Z3Exception e, ShutdownNotifier pAdditionalShutdownNotifier) throws SolverException, InterruptedException { if (Z3_INTERRUPT_ERRORS.contains(e.getMessage())) { contextShutdownNotifier.shutdownIfNecessary(); - if (pAdditionalShutdownNotifier != null) { - pAdditionalShutdownNotifier.shutdownIfNecessary(); - } + pAdditionalShutdownNotifier.shutdownIfNecessary(); } throw new SolverException("Z3 has thrown an exception", e); } @@ -188,7 +186,7 @@ final SolverException handleZ3Exception( * @throws RuntimeException always thrown for the given Z3Exception */ final RuntimeException handleZ3ExceptionAsRuntimeException( - Z3Exception e, @Nullable ShutdownNotifier pAdditionalShutdownNotifier) { + Z3Exception e, ShutdownNotifier pAdditionalShutdownNotifier) { try { throw handleZ3Exception(e, pAdditionalShutdownNotifier); } catch (InterruptedException ex) { diff --git a/src/org/sosy_lab/java_smt/solvers/z3/Z3Model.java b/src/org/sosy_lab/java_smt/solvers/z3/Z3Model.java index 36100f568a..29a99e6472 100644 --- a/src/org/sosy_lab/java_smt/solvers/z3/Z3Model.java +++ b/src/org/sosy_lab/java_smt/solvers/z3/Z3Model.java @@ -36,14 +36,14 @@ final class Z3Model extends AbstractModel { private final Z3FormulaCreator z3creator; - private final @Nullable ShutdownNotifier proverShutdownNotifier; + private final ShutdownNotifier proverShutdownNotifier; Z3Model( AbstractProver pProver, long z3context, long z3model, Z3FormulaCreator pCreator, - @Nullable ShutdownNotifier pProverShutdownNotifier) { + ShutdownNotifier pProverShutdownNotifier) { super(pProver, pCreator); Native.modelIncRef(z3context, z3model); model = z3model; diff --git a/src/org/sosy_lab/java_smt/solvers/z3/Z3TheoremProver.java b/src/org/sosy_lab/java_smt/solvers/z3/Z3TheoremProver.java index f2ed34c142..89cce5af01 100644 --- a/src/org/sosy_lab/java_smt/solvers/z3/Z3TheoremProver.java +++ b/src/org/sosy_lab/java_smt/solvers/z3/Z3TheoremProver.java @@ -50,9 +50,7 @@ class Z3TheoremProver extends Z3AbstractProver implements ProverEnvironment { interruptListener = reason -> Native.solverInterrupt(z3context, z3solver); pContextShutdownNotifier.register(interruptListener); - if (pProverShutdownNotifier != null) { - pProverShutdownNotifier.register(interruptListener); - } + proverShutdownNotifier.register(interruptListener); long z3params = Native.mkParams(z3context); Native.paramsIncRef(z3context, z3params); From b8c9a06c516fad73fd4a1f1a6223210ce7ba7819 Mon Sep 17 00:00:00 2001 From: BaierD Date: Mon, 4 Aug 2025 16:45:44 +0200 Subject: [PATCH 87/87] Remove Z3 specific code for throwing checked exceptions as runtime exceptions as the new API changes do not need this anymore --- .../java_smt/solvers/z3/Z3FormulaCreator.java | 25 ------------------- 1 file changed, 25 deletions(-) diff --git a/src/org/sosy_lab/java_smt/solvers/z3/Z3FormulaCreator.java b/src/org/sosy_lab/java_smt/solvers/z3/Z3FormulaCreator.java index 2df83d5d03..a28b585b4e 100644 --- a/src/org/sosy_lab/java_smt/solvers/z3/Z3FormulaCreator.java +++ b/src/org/sosy_lab/java_smt/solvers/z3/Z3FormulaCreator.java @@ -177,31 +177,6 @@ final SolverException handleZ3Exception( throw new SolverException("Z3 has thrown an exception", e); } - /** - * This method handles a Z3Exception, however it only throws a RuntimeException. This method is - * used in places where we cannot throw a checked exception in JavaSMT due to API restrictions. - * - * @param e the Z3Exception to handle - * @return nothing, always throw a RuntimeException - * @throws RuntimeException always thrown for the given Z3Exception - */ - final RuntimeException handleZ3ExceptionAsRuntimeException( - Z3Exception e, ShutdownNotifier pAdditionalShutdownNotifier) { - try { - throw handleZ3Exception(e, pAdditionalShutdownNotifier); - } catch (InterruptedException ex) { - Thread.currentThread().interrupt(); - throw sneakyThrow(e); - } catch (SolverException ex) { - throw sneakyThrow(e); - } - } - - @SuppressWarnings("unchecked") - private static RuntimeException sneakyThrow(Throwable e) throws E { - throw (E) e; - } - @Override public Long makeVariable(Long type, String varName) { long z3context = getEnv();