Skip to content

Add Prover Based ShutdownManager #489

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 88 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
88 commits
Select commit Hold shift + click to select a range
b8ccbe0
Revert "Revert changes supposed to be on a feature branch"
May 30, 2025
7422f4c
Reduce complexity of prover based shutdown getter
Jun 2, 2025
a43d183
Reduce complexity of prover based shutdown getter even more
Jun 2, 2025
5af69e6
Remove unnecessary comment in BitwuzlaTheoremProver
Jun 2, 2025
2b81ac8
Allow and use direct access to prover specific ShutdownNotifier
Jun 2, 2025
92f2f60
Add Int and BV test for context shutdown and prover reuse afterward
Jun 2, 2025
b048f56
Add default implementation of isUnsat() to centralize checks (closed,…
Jun 2, 2025
e73b889
Add more timeout/shutdown tests:
Jun 2, 2025
ba6c2bc
Add a model test that checks error when requesting a model for UNSAT …
Jun 2, 2025
28d5648
Remove unnecessary exceptions from test methods in TimeoutTest
Jun 2, 2025
5de5971
Format TimeoutTest
Jun 2, 2025
0f8e757
Add default handling for basic prover API like isUnsat(), getUnsatCor…
Jun 2, 2025
1b6f52b
Remove unnecessary final modifiers in AbstractProver
Jun 2, 2025
77ab3d6
Add more uniform handling of prerequisites of interpolation API
Jun 2, 2025
223624c
Add clarification JavaDoc for getShutdownManagerForProver()
Jun 2, 2025
55f8e08
Add clarification JavaDoc about needed options for unsatCoreOverAssum…
Jun 2, 2025
6613b21
Add more internal information about shutdown re-use for Z3 and Bitwuzla
Jun 2, 2025
843b0ee
Format JavaDoc
Jun 2, 2025
e6587bd
Add API for requesting new prover environments with a dedicated prove…
Jun 4, 2025
418bc8b
Remove old getter for created shutdown manager in the BasicProverEnvi…
Jun 4, 2025
c85042b
Add new prover environments with a dedicated prover shutdown notifier…
Jun 4, 2025
2fe5c2b
Add dedicated prover shutdown notifier to abstract provers
Jun 4, 2025
028ef5b
Add dedicated prover shutdown notifier to Bitwuzla
Jun 4, 2025
b122b50
Add dedicated prover shutdown notifier to ShutdownHook
Jun 4, 2025
b1ad38f
Add dedicated prover shutdown notifier to Boolector and remove unneed…
Jun 4, 2025
856d3b6
Add dedicated prover shutdown notifier to CVC4
Jun 4, 2025
3b16949
Add dedicated prover shutdown notifier to CVC5 implementation, but ma…
Jun 4, 2025
fa7dfb2
Add dedicated prover shutdown notifier to MathSAT5
Jun 4, 2025
37a58ee
Add dedicated prover shutdown notifier to OpenSMT2
Jun 4, 2025
3538fdc
Add dedicated prover shutdown notifier to Princess but make it not us…
Jun 4, 2025
9e6d0ba
Add dedicated prover shutdown notifier to SMTInterpol but make it not…
Jun 4, 2025
02bdda9
Add dedicated prover shutdown notifier to Yices2
Jun 4, 2025
30a74dd
Add dedicated prover shutdown notifier to Z3
Jun 4, 2025
1812dfc
Change TimeoutTest for the new way prover shutdown can be requested a…
Jun 4, 2025
17ec72e
Add default behavior/failure checks for getEvaluator()
Jun 4, 2025
5a20e6d
Add default behavior/failure checks for pop() for termination
Jun 11, 2025
0b95f11
Concat static string error msgs
Jun 11, 2025
1cd34dd
Add shutdown reason to exception msg for non-interrupted exception th…
Jun 11, 2025
c85c030
Add recovery of assertProverAPIThrowsInterruptedException from method…
Jun 11, 2025
407f52a
Remove redundant checks from BoolectorTheoremProver.java
Jun 11, 2025
384c7b1
Remove commented out old code
Jun 11, 2025
97c44b6
Add full shutdown/interrupt exception handling to Z3 model
Jun 11, 2025
cfa1cdb
Remove redundant checks and code from provers/solvers
Jun 11, 2025
799385c
Directly use shutdown exception text constant when checking for hidde…
Jun 25, 2025
b4fbc2f
Lazily eval shutdown msg when checking in non throwing methods
Jun 25, 2025
1f5c866
Reduce args for CVC5InterpolatingProver constructor
Jun 25, 2025
676aebb
Apply refaster patch
Jun 25, 2025
65407fb
Switch to lazy and self implemented shutdown state check
Jun 26, 2025
2e83b93
Centralize getInterpolant ID checking and also give back the mismatch…
Jun 26, 2025
ee5eee0
Centralize getInterpolant ID checking and also give back the mismatch…
Jun 26, 2025
c1dc784
Correctly reset assumptions for interpolation in the assumption wrapp…
Jun 26, 2025
41daa1f
Remove unneeded lazy handling of error msg
Jun 26, 2025
d06d41c
Extend TimeoutTest with checking for all prover API, including interp…
Jun 26, 2025
4a4cac8
Improve interpolation input error messages by including a null check …
Jun 30, 2025
0c683e8
Reduce query size for timeout test (was unnecessarily high)
Jun 30, 2025
79ba7d7
Rename shutdownManagers in tests to make their use/source more clear
Jun 30, 2025
295e01a
Make internal prover variables private and add setter and getter wher…
Jun 30, 2025
a9023f9
Remove unneeded lambda from Mathsat termination check
Jun 30, 2025
3ca9316
Add a sanity check in DebuggingBasicProverEnvironment for getModelAss…
Jun 30, 2025
9e63816
Mark implementation specifications with @implNote in SolverContext
Jun 30, 2025
ac5be00
Make JavaDoc clearer for SolverContext prover requests and their inte…
Jun 30, 2025
1d9ec5a
Improve JavaDoc of SolverContext in regard to shutdown of provers
Jun 30, 2025
e4bf4e8
Hide common Strings used in provers from users
Jun 30, 2025
f16f77d
Make common Strings used in provers static
Jun 30, 2025
1ab6955
Re-add default impl of getModelAssignments()
Jun 30, 2025
fc323b9
Re-throw exception when clearing assumptions, and it's not another ex…
Jul 1, 2025
1b268a3
Improve JavaDoc of constructor methods of new prover environments wit…
Jul 21, 2025
c4a7a65
Add warning for sneaky SolverExceptions in Model JavaDoc
Jul 29, 2025
b7da958
Throw sneaky SolverExceptions in Mathsat Model instead of confusing I…
Jul 29, 2025
50094eb
Add more sneaky throw warnings to API that may throw a SolverExceptio…
Jul 29, 2025
89837d5
Remove sneaky throw of SolverException from Mathsat native call
Jul 30, 2025
dbbdc31
Remove sneaky throw of SolverException from Z3 model and add Interrup…
Jul 30, 2025
b0e7b44
Add SolverException and InterruptedException to many calls related to…
Jul 30, 2025
0ca8d4f
Remove sneaky throws for Z3 specific code entirely
Jul 30, 2025
cd51b02
Add Solver- and InterruptedException to push() and addConstraint() API
Jul 30, 2025
898832d
Remove warnings about sneaky throws where they can't happen anymore
Jul 30, 2025
c900399
Format: remove warnings about sneaky throws where they can't happen a…
Jul 30, 2025
2166410
Rename exception variable to fit naming schema
Jul 30, 2025
64b21b3
Improve warning for sneaky throws in model iterator() as suggested by…
Jul 30, 2025
cd3ef20
Merge feature branch 481-mathsat5-returns-null-for-msat_model_create_…
Jul 31, 2025
477efd0
Remove special handling of interrupts for API that did not throw Inte…
Jul 31, 2025
ca14eff
Remove special handling of interrupts for API that did not throw Inte…
Jul 31, 2025
4b429db
Switch all expected exceptions after interrupt to InterruptedExceptio…
Jul 31, 2025
d447902
Remove toString() in lazy evaluation to be actually lazy in AbstractP…
Jul 31, 2025
22bc811
Move JavaDoc from throws to general info for prover environment creat…
Jul 31, 2025
a75ec8a
Use dummy ShutdownNotifier instead of null if there is no prover spec…
Jul 31, 2025
5f30d42
Remove null checks for prover based ShutdownNotifier when no longer n…
Aug 4, 2025
b8c9a06
Remove Z3 specific code for throwing checked exceptions as runtime ex…
Aug 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions src/org/sosy_lab/java_smt/api/BasicProverEnvironment.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,14 @@
*/
public interface BasicProverEnvironment<T> extends AutoCloseable {

String NO_MODEL_HELP = "Model computation failed. Are the pushed formulae satisfiable?";

/**
* 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).
*/
@Nullable
@CanIgnoreReturnValue
default T push(BooleanFormula f) throws InterruptedException {
default T push(BooleanFormula f) throws InterruptedException, SolverException {
push();
return addConstraint(f);
}
Expand All @@ -41,12 +39,12 @@ default T push(BooleanFormula f) throws InterruptedException {
* Remove one backtracking point/level from the current stack. This removes the latest level
* including all of its formulas, i.e., all formulas that were added for this backtracking point.
*/
void pop();
void pop() throws InterruptedException;

/** Add a constraint to the latest backtracking point. */
@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
Expand All @@ -55,7 +53,7 @@ default T push(BooleanFormula f) throws InterruptedException {
* <p>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.
Expand Down Expand Up @@ -87,15 +85,15 @@ boolean isUnsatWithAssumptions(Collection<BooleanFormula> assumptions)
* <p>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
* immediately after an {@link #isUnsat()} call that returned <code>false</code>. The evaluator
* 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();
}

Expand All @@ -107,7 +105,8 @@ default Evaluator getEvaluator() throws SolverException {
* <p>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<Model.ValueAssignment> getModelAssignments() throws SolverException {
default ImmutableList<Model.ValueAssignment> getModelAssignments()
throws SolverException, InterruptedException {
try (Model model = getModel()) {
return model.asList();
}
Expand All @@ -117,11 +116,12 @@ default ImmutableList<Model.ValueAssignment> getModelAssignments() throws Solver
* Get an unsat core. This should be called only immediately after an {@link #isUnsat()} call that
* returned <code>false</code>.
*/
List<BooleanFormula> getUnsatCore();
List<BooleanFormula> getUnsatCore() throws InterruptedException;

/**
* 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
Expand Down
22 changes: 13 additions & 9 deletions src/org/sosy_lab/java_smt/api/Evaluator.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public interface Evaluator extends AutoCloseable {
* @return evaluation of the given formula or <code>null</code> if the solver does not provide a
* better evaluation.
*/
@Nullable <T extends Formula> T eval(T formula);
@Nullable <T extends Formula> T eval(T formula) throws SolverException, InterruptedException;

/**
* Evaluate a given formula substituting the values from the model.
Expand All @@ -62,56 +62,60 @@ public interface Evaluator extends AutoCloseable {
* @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.
*
* <p>The formula does not need to be a variable, we also allow complex expression.
*/
@Nullable BigInteger evaluate(IntegerFormula formula);
@Nullable BigInteger evaluate(IntegerFormula formula)
throws SolverException, InterruptedException;

/**
* Type-safe evaluation for rational formulas.
*
* <p>The formula does not need to be a variable, we also allow complex expression.
*/
@Nullable Rational evaluate(RationalFormula formula);
@Nullable Rational evaluate(RationalFormula formula) throws SolverException, InterruptedException;

/**
* Type-safe evaluation for boolean formulas.
*
* <p>The formula does not need to be a variable, we also allow complex expression.
*/
@Nullable Boolean evaluate(BooleanFormula formula);
@Nullable Boolean evaluate(BooleanFormula formula) throws SolverException, InterruptedException;

/**
* Type-safe evaluation for bitvector formulas.
*
* <p>The formula does not need to be a variable, we also allow complex expression.
*/
@Nullable BigInteger evaluate(BitvectorFormula formula);
@Nullable BigInteger evaluate(BitvectorFormula formula)
throws SolverException, InterruptedException;

/**
* Type-safe evaluation for string formulas.
*
* <p>The formula does not need to be a variable, we also allow complex expression.
*/
@Nullable String evaluate(StringFormula formula);
@Nullable String evaluate(StringFormula formula) throws SolverException, InterruptedException;

/**
* Type-safe evaluation for enumeration formulas.
*
* <p>The formula does not need to be a variable, we also allow complex expression.
*/
@Nullable String evaluate(EnumerationFormula formula);
@Nullable String evaluate(EnumerationFormula formula)
throws SolverException, InterruptedException;

/**
* Type-safe evaluation for floating-point formulas.
*
* <p>The formula does not need to be a variable, we also allow complex expression.
*/
@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,
Expand Down
17 changes: 15 additions & 2 deletions src/org/sosy_lab/java_smt/api/Model.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,27 @@ public interface Model extends Evaluator, Iterable<ValueAssignment>, 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.
* </ul>
*
* <p>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<ValueAssignment> iterator() {
return asList().iterator();
try {
return asList().iterator();
} catch (SolverException | InterruptedException ex) {
throw sneakyThrow(ex);
}
}

@SuppressWarnings("unchecked")
private static <E extends Throwable> RuntimeException sneakyThrow(Throwable e) throws E {
throw (E) e;
}

/** Build a list of assignments that stays valid after closing the model. */
ImmutableList<ValueAssignment> asList();
ImmutableList<ValueAssignment> asList() throws SolverException, InterruptedException;

/**
* Pretty-printing of the model values.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public interface OptimizationProverEnvironment extends BasicProverEnvironment<Vo
* (epsilon is irrelevant here and can be zero). The model returns the optimal assignment x=9.
*/
@Override
Model getModel() throws SolverException;
Model getModel() throws SolverException, InterruptedException;

/** Status of the optimization problem. */
enum OptStatus {
Expand Down
68 changes: 65 additions & 3 deletions src/org/sosy_lab/java_smt/api/SolverContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/**
Expand Down Expand Up @@ -65,17 +66,59 @@ 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. The returned prover 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.
*
* @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.
*/
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
* 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.
Comment on lines +92 to +94
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand this comment. The return type of the method is InterpolatingProverEnvironment, one always needs to return such an instance. What does this have to do with "solving with assumptions"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a comment for developers (e.g. students) so that they get info what to implement. We have this at several locations and for example helped me back in my bachelors thesis.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, having @implNotes is good. But what does this one want to say? Isn't InterpolatingProverEnvironment always required, and what does implementing it have to do with "satisfiability tests with assumptions"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No it is not always required. The default impl throws a UnsupportedOperationException.
It is meant to lead the developer to the conclusion that this needs to be implemented if you want to interpolate. Usually students (in my experience) notice once they run the tests that things are missing ;D

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, but then the comment should still refer to interpolation and not satisfiability tests with assumptions.

* @param options Options specified for the prover environment. All the options specified in
* {@link ProverOptions} are turned off by default.
*/
InterpolatingProverEnvironment<?> newProverEnvironmentWithInterpolation(ProverOptions... options);

/**
* 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}. 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
* Object of this type here.
* @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.
*/
InterpolatingProverEnvironment<?> newProverEnvironmentWithInterpolation(
ShutdownNotifier pProverShutdownNotifier, ProverOptions... options);

/**
* Create a fresh new {@link OptimizationProverEnvironment} which encapsulates an assertion stack
* and allows solving optimization queries.
Expand All @@ -85,6 +128,25 @@ enum ProverOptions {
*/
OptimizationProverEnvironment newOptimizationProverEnvironment(ProverOptions... options);

/**
* 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}. 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.
*/
OptimizationProverEnvironment newOptimizationProverEnvironment(
ShutdownNotifier pProverShutdownNotifier, ProverOptions... options);

/**
* Get version information out of the solver.
*
Expand Down
Loading