Feature | Status |
---|---|
Rich expression system | Done |
Expression interning | Done |
Basic theories support | Done |
SMT-LIB2 parser | Done partially |
SMT-LIB2 serializer | TODO |
Unsupported features handling | Done partially |
SMT solver support | Done |
Z3 solver support | Done |
Bitwuzla solver support | Done |
Yices2 solver support | Done |
CVC5 solver support | Done |
External process runner | Done |
Portfolio solver | Done |
Solver configuration API | Done |
Deployment | Done |
Expression simplification / evaluation | Done |
Performance tests | TODO |
Better Z3 API | Done partially |
Better Bitwuzla bindings | Done |
Solver specific features API | TODO |
Quantifier elimination | TODO |
Interpolation | TODO |
Model based projection | TODO |
Support more theories | TODO |
Solver proofs | TODO |
SymFpu | Done |
... | - |
Provide a solver-independent formula representation with back and forth transformations to the solver's native representation. Such representation allows introspection of formulas and transformation of formulas independent of the solver. Check out KASt and its inheritors for implementation details.
Interning (aka hash consing) is needed for:
- Constant time ast comparison. Otherwise, we need to compare trees.
- Ast deduplication. We can have many duplicate nodes (e.g. constants).
Currently, interning is implemented via KContext which manages all created asts.
Support theories in KSMT expressions system. Each theory consists of:
- Expressions. Theory specific operations over terms. All implementations are in expr package.
- Sorts. Theory specific types. All implementations are in sort package.
- Declarations. Declarations (name, argument sorts, result sort) of theory specific functions. All implementations are in decl package.
KSMT expression system supports following theories and their combinations:
- Core. Basic boolean operations.
- BV. Bit vectors with arbitrary size.
- Arithmetic. Integers, Reals, and their combinations.
- FP. IEEE Floating point numbers.
- Arrays.
- UF. Uninterpreted functions and sorts.
- Quantifiers. Existential and universal quantifiers.
Provide a parser for formulas, written in the SMT-LIB2 language. Main goals are:
- Allow the user to instantiate KSMT expressions from SMT-LIB.
- Provide us the opportunity to use a rich database of benchmarks.
Currently, implemented on top of Z3 SMT solver. A solver-agnostic implementation may be done in the future.
Provide a serializer for KSMT expressions in SMT-LIB2 format.
Motivation:
- SMT-LIB is an easy way to interact with new SMT solver.
- SMT-LIB format is well known to the community and is the most suitable way to visualize formulas.
Can be implemented on top of the Z3 SMT solver (easy version) or in a solver-independent way.
If some solver doesn't support some theory (e.g. BV) or some feature (e.g. unsat-core generation) we need to throw specialized exception. Currently, KSolverUnsupportedFeatureException is thrown.
To simplify the user experience, the exception may contain a recommendation to switch to another solver. This recommendation feature may be implemented in the future.
Provide an interface to interact with various SMT solvers. Features:
- Expression assertion.
- Check-sat with timeout.
- Model generation.
- Unsat-core generation.
- Incremental solving via push/pop.
- Incremental solving via assumptions.
For implementation details, check out KSolver.
Z3 is a well known production ready SMT solver.
Z3 has native support for all theories, listed in KSMT supported theories and provides all the functionality, listed in SMT solver features.
For implementation details, check out KZ3Solver.
Bitwuzla is a research solver based on Boolector. Bitwuzla specializes on BV and Fp theories and performs well on SMT-COMP.
Bitwuzla has native support for the following theories:
- BV. Full support
- FP. Full support
- Arrays. QF_ABVFP only. No nested arrays allowed.
Other theories and nested arrays will not be supported.
For the solver features, listed in SMT solver features, Bitwuzla provides full native support.
For implementation details, check out KBitwuzlaSolver.
Yices2 is a well performing SMT solver.
Yices2 has native support for all theories, listed in KSMT supported theories, except FP.
Yices2 provides all the functionality, listed in SMT solver features.
For FP support SymFpu approach can be used (rewrite all FP expressions over BV terms).
CVC5 is a well performing SMT solver.
CVC5 has native support for all theories, listed in KSMT supported theories and provides all the functionality, listed in SMT solver features.
Run solvers in separate processes to preserve user applications stability.
SMT solvers are implemented via native libraries and usually have the following issues:
- Timeout ignore. SMT solver may hang in a long-running operation before reaching a checkpoint. Since solver is a native library, there is no way to interrupt it.
- Solvers are usually research projects with a bunch of bugs, e.g. pointer issues. Such errors lead to the interruption of the entire process, including the user's app.
Currently, we have a process runner implementation, that allows us to force the solver to respect timeouts and survive after native errors.
Various SMT solvers usually show different performance on a same SMT formula. Portfolio solving is a simple idea of running different solvers on the same formula simultaneously and waiting only for the first result.
This approach can be implemented on top of external process runner.
Extend SMT solver interface with an option to pass solver specific parameters to the underlying solver.
For implementation details, check out corresponding PR.
Deliver KSMT to end users.
Released on Maven Central.
Implement simplification rules for KSMT expressions, and apply it to:
- Expression simplification
- Lightweight eager simplification during expressions creation
- Expression evaluation wrt model (special case of simplification)
List of currently implemented simplification rules: simplification rules
Measure overhead of the following operations for all supported solvers:
- Expression translation from KSMT to solver native. The most used and the most expensive operation.
- Expression conversion from solver native to KSMT. Usually operates on small expressions, obtained from model.
- KSMT expression simplification (when available).
Current state
Measure the performance of the expression assertion as it requires internalization and is the most possible bottleneck.
Internalization performance
Single term internalization requires about 1 microsecond on average.
Compared to other numbers, solver instance creation (a single native call) takes about 1 millisecond.
Comparing to the Z3 native SMT-LIB parser, the KSMT internalizer is 2.3 times faster on average and 1.1 faster in the worst case.
KSMT runner performace
Runner adds some overhead, since it performs serialization / deserialization and network communication.
Expression assertion via runner is 5 times slower on average and is 7.1 slower in the worst case.
Reduce expression translation time and memory consumption by switching from using Z3 expression wrappers to working directly with native pointers.
Currently, Bitwuzla bindings are implemented via JNA framework with the following issues:
- JNA has huge function call overhead.
- Error handling in Bitwuzla is performed via callbacks mechanism. There is no way to setup callback from JNA to properly handle native errors.
- Bitwuzla use callbacks for timeouts checks. Currently, Bitwuzla performs many slow calls from native to java to check timeout.
SMT solvers provides their own specific features (e.g. tactics in Z3).
Currently, KSMT provides expression translation from KSMT to solver native and expression translation from solver native to KSMT features, which allows us to potentially use any solver feature.
Implement quantifier elimination in KSMT.
Provide a pure KSMT implementation or use solver (e.g. qe_lite
tactic in Z3).
Implement interpolant computation in KSMT.
Model based projection under-approximates existential quantification with quantifier-free formulas. Implement MBP in a pure KSMT or use solver provided implementation (e.g. Z3).
Add support for the following theories:
- Strings. Operations over string terms.
- Datatypes. Algebraic data types.
- Sequences. Sequences of known length.
Some solvers provide native support for theories above, e.g. Z3 and CVC5.
In case of UNSAT many solvers can produce proof.
Provide a universal representation of proof in KSMT and implement conversion from solver native proof.
Support for Fp theory in SMT solvers that support Bv (e.g. Yices2). The SymFpu approach proposes to rewrite all FP expressions over BV terms.