Class Solver_bitwuzla
- All Implemented Interfaces:
ISolver
AbstractSolver apart from a handful of real, empirically
confirmed (against 0.9.1) protocol gaps:
1) Bitwuzla has no get-info, get-option, get-assertions,
get-assignment or get-proof at all -- each is rejected with
[error] <stdin>:L:C: unsupported command '...' and, critically, that rejection
KILLS the process (see point 2), so these are answered entirely client-side
and never forwarded. get_option(org.smtlib.IExpr.IKeyword) therefore tracks values itself (via the
inherited options map, falling back to smtConfig.utils.defaults)
rather than relying on AbstractSolver's default of asking the solver.
2) Unlike cvc5/yices2 (which die only after some errors), Bitwuzla's process exits
immediately after essentially ANY error -- an unsupported command, an unsupported
logic, a sort mismatch in an assertion, etc. -- not just protocol violations. selfReportsImmediateExit() is therefore true, and :error-behavior is
reported (via the hardcoded get_info(org.smtlib.IExpr.IKeyword)) as immediate-exit, which is
simply the truth for this solver, not a workaround.
3) Bitwuzla's own error text for a genuine semantic error (e.g. [error]
<stdin>:3:14: expected terms of same sort ...) is not SMT-LIB (error "...")
syntax -- the leading [ is not valid s-expression syntax at all, and feeding
it to the standard parser doesn't just fail to parse cleanly, it throws a raw
ClassCastException out of the lexer (a LexError token reaching code that assumes an
IError) instead of the IParser.ParserException that AbstractSolver.parseResponse(java.lang.String) already knows how to turn into a clean error response.
parseResponse(java.lang.String) widens that catch locally so a non-conforming response
produces an ordinary error IResponse instead of crashing the whole run.
4) With its :produce-* option on, Bitwuzla writes nothing at all, or the start of a
list followed by an error on standard error, for get-model, get-value, get-unsat-core
and get-unsat-assumptions when it has no answer (e.g. get-value after unknown, or
get-unsat-core after an assert that followed unsat); it writes nothing or a fragment for
get-unsat-assumptions whenever that option is off. The adapter answers those cases with an
error itself, tracking Bitwuzla's own state (see lastCheck).
-
Nested Class Summary
Nested classes/interfaces inherited from class org.smtlib.AbstractSolver
AbstractSolver.Pending, AbstractSolver.Shape, AbstractSolver.StackChangeNested classes/interfaces inherited from interface org.smtlib.ISolver
ISolver.CreationException -
Field Summary
FieldsModifier and TypeFieldDescriptionprotected String[]The command-line arguments for launching the solver.Fields inherited from class org.smtlib.AbstractSolver
checkSatStatus, END_WAIT_MILLIS, endedByTimeLimit, isMac, isWindows, linesOffset, options, printSuccess, printSuccessResponse, smtConfig, SOLVER_EXITED, solverProcess -
Constructor Summary
ConstructorsConstructorDescriptionSolver_bitwuzla(SMT.Configuration smtConfig, String executable) Creates an instance of the solverSolver_bitwuzla(SMT.Configuration smtConfig, String[] command) Launches the given command as is (a .command property, #147), without adding the flags the executable form adds -
Method Summary
Modifier and TypeMethodDescriptionassertExpr(IExpr sexpr) Adds the given expression to the current assertion-stack frame.Checks whether the current assertion set is satisfiable under the current logic.check_sat_assuming(IExpr... exprs) Checks satisfiability under the current assertion set plus the given propositional assumptions.Not sent: Bitwuzla exits on it (see above)Not sent: Bitwuzla exits on it (see above)Not sent: Bitwuzla exits on it (see above)Not sent: Bitwuzla exits on it (see above)Not sent: Bitwuzla exits on it (see above)Seeget_proof(): Bitwuzla rejects get-assertions the same way.Seeget_proof(): Bitwuzla rejects get-assignment the same way.get_info(IExpr.IKeyword key) Answered entirely client-side (never forwarded -- see class comment point 1).With :produce-models on, Bitwuzla writes nothing for get-model unless its last check returned sat (and crashes if a reset came since); after an assert, push, pop or reset-assertions, or with the option set after the check, it writes an ordinary error.get_option(IExpr.IKeyword key) Answered entirely client-side (never forwarded -- see class comment point 1): from whatever this run has set viaset_option_impl(org.smtlib.IExpr.IKeyword, org.smtlib.IAttributeValue), falling back to the standard SMT-LIB default for any option never set, and "unsupported" for anything not a recognized standard option at all (matching what a compliant solver would say about an option it doesn't have).Bitwuzla rejects get-proof as an unsupported command and exits (class comment point 1); a conforming solver without proofs answers unsupported.Bitwuzla writes nothing for get-unsat-assumptions unless its last check returned unsat; then it writes a fragment and an error if the option is off or was set after the check, or an assert, push, pop, reset-assertions or reset came since.With :produce-unsat-cores on, Bitwuzla writes nothing for get-unsat-core unless its last check returned unsat, and a fragment and an error if an assert, push, pop, reset-assertions or reset came since or the option was set after the check.With :produce-models on, Bitwuzla writes nothing for get-value unless its last check returned sat, and a fragment and an error if an assert, push, pop or reset-assertions came since or the option was set after the check.protected booleanisFlatResponse(String response) Bitwuzla writes its errors as "[error] ..." lines (class comment point 3), so for the get- commands that parse a list reply such a line goes toparseResponse(java.lang.String), not the list parser.protected booleanisTimeLimitResponse(String rawResponse) When its whole-run limit (--time-limit) ends it, Bitwuzla writes unknown -- as the answer to a running check-sat, or unprompted while idle -- and exits with code 0 (checked with 0.9.1).Patterns matching the line numbers in this solver's messages about the command answered: group 1 is the text before the number, group 2 the number, group 3 the text after itprotected IResponseparseResponse(String response) Parses the solver's raw response text.pop(int number) Removes the given number of assertion-stack frames from the solver state.push(int number) Adds the given number of empty assertion-stack frames to the solver state.protected booleanWhether the solver's messages name lines of earlier commands (seeAbstractSolver.earlierSourceLine(int))reset()Bitwuzla's reset restores its option defaults, so the values get_option answers from are dropped too (except the output channels, which are jSMTLIB's own and stay redirected).Removes asserted formulae (but not global declarations when :global-declarations is true).protected booleanOverridden by a subclass whose target solver's :error-behavior is immediate-exit (e.g.Bitwuzla (0.9.1) accepts a second set-logic, which SMT-LIB forbids outside start mode, so that is reported here (--relax allows it).protected IResponseset_option_impl(IExpr.IKeyword key, IAttributeValue value) Sent to bitwuzla, and also kept here for get_option, which bitwuzla does not supportstart()Starts the solver; this is not an SMT-LIB command, but it is convenient in some implementations to separate the starting and initialization from the construction of the solver instance.Methods inherited from class org.smtlib.AbstractSolver
checkImmediateExit, checkPrintSuccess, checkSatStatus, checkShape, checkStatus, comment, correctResponse, declare_const, declare_fun, declare_sort, define_const, define_fun, define_sort, earlierSourceLine, echo, errorStopsSolver, execute, executePipelined, exit, exitedResponse, finishPipelined, forceExit, hasPending, inSatMode, interrupt, inUnsatMode, logSolverDiagnostics, modelResponse, nextSolverLine, normalizeForTesting, outOfStep, pipelines, proofResponse, readPipelined, recordChange, reportSeedIgnored, requireNoChangeSinceCheck, requireOptionEnabled, requireSatOrUnknown, requireUnsat, responseEnd, sendChange, sendCommand, sendExitCommand, sendFailure, sendFailure, sendPipelined, sendScriptText, sendSeed, set_info, set_option, setSourceLine, shapeOf, smt, solverName, solverPrintsSuccess, successOrEmpty, timeLimitResponse, timeLimitResponseAfterExit, translate, unsatAssumptionsElements, unsatCoreElements, withSourceLinesMethods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitMethods inherited from interface org.smtlib.ISolver
checkSatStatus, comment, declare_const, declare_fun, declare_sort, define_const, define_fun, define_sort, echo, execute, exit, forceExit, set_info, set_option, setSourceLine, smt, solverName
-
Field Details
-
cmds
The command-line arguments for launching the solver.
-
-
Constructor Details
-
Solver_bitwuzla
Creates an instance of the solver -
Solver_bitwuzla
Launches the given command as is (a .command property, #147), without adding the flags the executable form adds
-
-
Method Details
-
selfReportsImmediateExit
protected boolean selfReportsImmediateExit()Description copied from class:AbstractSolverOverridden by a subclass whose target solver's :error-behavior is immediate-exit (e.g. cvc5, yices2) rather than the SMT-LIB default of continued-execution -- such a solver's process may start exiting asynchronously right after it reports an error, andSolverProcess.send(boolean, String...)'s own process.isAlive() check can still read true for a brief window afterward (OS process-death bookkeeping lags the actual exit) -- seeAbstractSolver.sendCommand(ICommand, boolean), which uses this to give a solver that just reported an error a moment to actually finish dying before the next command's liveness check runs, closing that race deterministically rather than guessing from the error's content whether the process will actually exit.- Overrides:
selfReportsImmediateExitin classAbstractSolver
-
start
Description copied from interface:ISolverStarts the solver; this is not an SMT-LIB command, but it is convenient in some implementations to separate the starting and initialization from the construction of the solver instance.- Specified by:
startin interfaceISolver- Overrides:
startin classAbstractSolver- Returns:
- success or an SMT error response
- See Also:
-
parseResponse
Description copied from class:AbstractSolverParses the solver's raw response text. The base behavior assumes the response is exactly standard SMT-LIB concrete syntax: success/sat/unsat/unknown/unsupported/ true/false, an(error "...")s-expression, a bare value (get-option), or a single(:keyword value)attribute pair (get-info). It does not build the richer structured IResponse subtypes that get_value/get_model/get_proof/ get_assertions/get_unsat_core/get_unsat_assumptions/get_assignment need, nor does it correct for any real solver's non-compliant quirks (e.g. legacy bit-vector literal syntax) — override in a subclass whose target solver needs either.- Overrides:
parseResponsein classAbstractSolver
-
isTimeLimitResponse
When its whole-run limit (--time-limit) ends it, Bitwuzla writes unknown -- as the answer to a running check-sat, or unprompted while idle -- and exits with code 0 (checked with 0.9.1). An unknown for any other reason (e.g. the per-query limit) leaves it running, so an unknown is the whole-run limit only if the process then exits.- Overrides:
isTimeLimitResponsein classAbstractSolver
-
isFlatResponse
Bitwuzla writes its errors as "[error] ..." lines (class comment point 3), so for the get- commands that parse a list reply such a line goes toparseResponse(java.lang.String), not the list parser.- Overrides:
isFlatResponsein classAbstractSolver
-
lineNumberPatterns
Description copied from class:AbstractSolverPatterns matching the line numbers in this solver's messages about the command answered: group 1 is the text before the number, group 2 the number, group 3 the text after it- Overrides:
lineNumberPatternsin classAbstractSolver
-
reportsEarlierLines
protected boolean reportsEarlierLines()Description copied from class:AbstractSolverWhether the solver's messages name lines of earlier commands (seeAbstractSolver.earlierSourceLine(int))- Overrides:
reportsEarlierLinesin classAbstractSolver
-
set_option_impl
Sent to bitwuzla, and also kept here for get_option, which bitwuzla does not support- Overrides:
set_option_implin classAbstractSolver
-
get_option
Answered entirely client-side (never forwarded -- see class comment point 1): from whatever this run has set viaset_option_impl(org.smtlib.IExpr.IKeyword, org.smtlib.IAttributeValue), falling back to the standard SMT-LIB default for any option never set, and "unsupported" for anything not a recognized standard option at all (matching what a compliant solver would say about an option it doesn't have).- Specified by:
get_optionin interfaceISolver- Overrides:
get_optionin classAbstractSolver- Parameters:
key- the keyword naming the option- Returns:
- the option value, or unsupported, or an SMT error response
- See Also:
-
get_info
Answered entirely client-side (never forwarded -- see class comment point 1). :version/:authors are fixed to the 0.9.1 build this adapter was written and tested against; if jsmtlib.properties is ever pointed at a different Bitwuzla build, update these to match.- Specified by:
get_infoin interfaceISolver- Overrides:
get_infoin classAbstractSolver- Parameters:
key- the info keyword- Returns:
- the info value, or unsupported, or an SMT error response
- See Also:
-
get_proof
Bitwuzla rejects get-proof as an unsupported command and exits (class comment point 1); a conforming solver without proofs answers unsupported.- Specified by:
get_proofin interfaceISolver- Overrides:
get_proofin classAbstractSolver- Returns:
- a proof, unsupported, or an SMT error response
- See Also:
-
get_assignment
Seeget_proof(): Bitwuzla rejects get-assignment the same way.- Specified by:
get_assignmentin interfaceISolver- Overrides:
get_assignmentin classAbstractSolver- Returns:
- a list of name–Boolean pairs, unsupported, or an SMT error response
- See Also:
-
get_assertions
Seeget_proof(): Bitwuzla rejects get-assertions the same way.- Specified by:
get_assertionsin interfaceISolver- Overrides:
get_assertionsin classAbstractSolver- Returns:
- a sequence of asserted terms, unsupported, or an SMT error response
- See Also:
-
check_sat
Description copied from interface:ISolverChecks whether the current assertion set is satisfiable under the current logic.- Specified by:
check_satin interfaceISolver- Overrides:
check_satin classAbstractSolver- Returns:
- sat, unsat, unknown, or an SMT error response
- See Also:
-
check_sat_assuming
Description copied from interface:ISolverChecks satisfiability under the current assertion set plus the given propositional assumptions.- Specified by:
check_sat_assumingin interfaceISolver- Overrides:
check_sat_assumingin classAbstractSolver- Returns:
- sat, unsat, unknown, or an SMT error response
- See Also:
-
declare_datatype
Not sent: Bitwuzla exits on it (see above)- Specified by:
declare_datatypein interfaceISolver- Overrides:
declare_datatypein classAbstractSolver
-
declare_datatypes
Not sent: Bitwuzla exits on it (see above)- Specified by:
declare_datatypesin interfaceISolver- Overrides:
declare_datatypesin classAbstractSolver
-
define_fun_rec
Not sent: Bitwuzla exits on it (see above)- Specified by:
define_fun_recin interfaceISolver- Overrides:
define_fun_recin classAbstractSolver- See Also:
-
define_funs_rec
Not sent: Bitwuzla exits on it (see above)- Specified by:
define_funs_recin interfaceISolver- Overrides:
define_funs_recin classAbstractSolver- See Also:
-
declare_sort_parameter
Not sent: Bitwuzla exits on it (see above)- Specified by:
declare_sort_parameterin interfaceISolver- Overrides:
declare_sort_parameterin classAbstractSolver- See Also:
-
assertExpr
Description copied from interface:ISolverAdds the given expression to the current assertion-stack frame. The SMT-LIB command name isassert; the Java method name differs to avoid the Java reserved word.- Specified by:
assertExprin interfaceISolver- Overrides:
assertExprin classAbstractSolver- Returns:
- success or an SMT error response
- See Also:
-
push
Description copied from interface:ISolverAdds the given number of empty assertion-stack frames to the solver state.- Specified by:
pushin interfaceISolver- Overrides:
pushin classAbstractSolver- Parameters:
number- non-negative number of frames to push- Returns:
- success or an SMT error response
- See Also:
-
pop
Description copied from interface:ISolverRemoves the given number of assertion-stack frames from the solver state.- Specified by:
popin interfaceISolver- Overrides:
popin classAbstractSolver- Parameters:
number- non-negative number of frames to pop- Returns:
- success or an SMT error response
- See Also:
-
reset_assertions
Description copied from interface:ISolverRemoves asserted formulae (but not global declarations when :global-declarations is true).- Specified by:
reset_assertionsin interfaceISolver- Overrides:
reset_assertionsin classAbstractSolver- Returns:
- success or an SMT error response
- See Also:
-
reset
Bitwuzla's reset restores its option defaults, so the values get_option answers from are dropped too (except the output channels, which are jSMTLIB's own and stay redirected).- Specified by:
resetin interfaceISolver- Overrides:
resetin classAbstractSolver- Returns:
- success or an SMT error response
- See Also:
-
set_logic
Bitwuzla (0.9.1) accepts a second set-logic, which SMT-LIB forbids outside start mode, so that is reported here (--relax allows it). After one it accepts, it still answers the get- commands about its last check, so that check is dropped here, as for reset.- Specified by:
set_logicin interfaceISolver- Overrides:
set_logicin classAbstractSolver- Parameters:
logicName- the name of the logicpos- source position used only for error messages; may be null- Returns:
- success or unsupported or an SMT error response
- See Also:
-
get_model
With :produce-models on, Bitwuzla writes nothing for get-model unless its last check returned sat (and crashes if a reset came since); after an assert, push, pop or reset-assertions, or with the option set after the check, it writes an ordinary error. Bitwuzla also answers it in assert mode, after a declare or define following the check.- Specified by:
get_modelin interfaceISolver- Overrides:
get_modelin classAbstractSolver- Returns:
- a model, unsupported, or an SMT error response
- See Also:
-
get_value
With :produce-models on, Bitwuzla writes nothing for get-value unless its last check returned sat, and a fragment and an error if an assert, push, pop or reset-assertions came since or the option was set after the check. Bitwuzla also answers it in assert mode, after a declare or define following the check.- Specified by:
get_valuein interfaceISolver- Overrides:
get_valuein classAbstractSolver- Parameters:
terms- expressions to evaluate- Returns:
- a list of term–value pairs, unsupported, or an SMT error response
- See Also:
-
get_unsat_core
With :produce-unsat-cores on, Bitwuzla writes nothing for get-unsat-core unless its last check returned unsat, and a fragment and an error if an assert, push, pop, reset-assertions or reset came since or the option was set after the check. Bitwuzla also answers it in assert mode, after a declare or define following the check.- Specified by:
get_unsat_corein interfaceISolver- Overrides:
get_unsat_corein classAbstractSolver- Returns:
- a list of formula names, unsupported, or an SMT error response
- See Also:
-
get_unsat_assumptions
Bitwuzla writes nothing for get-unsat-assumptions unless its last check returned unsat; then it writes a fragment and an error if the option is off or was set after the check, or an assert, push, pop, reset-assertions or reset came since. Bitwuzla also answers it in assert mode, after a declare or define following the check.- Specified by:
get_unsat_assumptionsin interfaceISolver- Overrides:
get_unsat_assumptionsin classAbstractSolver- Returns:
- a list of assumption literals, unsupported, or an SMT error response
- See Also:
-