KSMT

Unified Kotlin/Java API for various SMT solvers and SMT formula manipulation library

Stage
prototype-ready
Tool Category
quality
Supported Languages

java 

kotlin 
Reason

Ultimate tool to work with SMT expressions and solver in Java world

#opensource

Get the most out of SMT solving with KSMT features:

Get started

To start using KSMT, install it via Gradle:

// core 
implementation("io.ksmt:ksmt-core:0.5.7")
// z3 solver
implementation("io.ksmt:ksmt-z3:0.5.7")

Find basic instructions in the Getting started guide and try it out with the Kotlin or Java examples.

To go beyond the basic scenarios, proceed to the Advanced usage guide and try the advanced example.

To get guided experience in KSMT, step through the detailed scenario for creating custom expressions.

Find more on KSMT features

Check the Roadmap to know more about current feature support and plans for the nearest future.

Supported solvers and theories

KSMT provides support for various solvers:

SMT solver Linux-x64 Windows-x64 macOS-aarch64 macOS-x64
Z3 :heavy_check_mark: :heavy_check_mark: :heavy_check_mark: :heavy_check_mark:
Bitwuzla :heavy_check_mark: :heavy_check_mark: :heavy_check_mark:  
Yices2 :heavy_check_mark: :heavy_check_mark: :heavy_check_mark:  
cvc5 :heavy_check_mark: :heavy_check_mark: :heavy_check_mark:  

You can also use SMT solvers across multiple theories:

Theory Z3 Bitwuzla Yices2 cvc5
Bitvectors :heavy_check_mark: :heavy_check_mark: :heavy_check_mark: :heavy_check_mark:
Arrays :heavy_check_mark: :heavy_check_mark: :heavy_check_mark: :heavy_check_mark:
IEEE Floats :heavy_check_mark: :heavy_check_mark: :heavy_check_mark: 1 :heavy_check_mark:
Uninterpreted Functions :heavy_check_mark: :heavy_check_mark: :heavy_check_mark: :heavy_check_mark:
Arithmetic :heavy_check_mark:   :heavy_check_mark: :heavy_check_mark:

Solver-agnostic formula representation

Various scenarios are available for using SMT solvers: you can use a single solver to determine whether a formula is satisfiable, or you can apply several solvers to the same expression successively. In the latter case, you need a solver-agnostic formula representation.

We implemented it in KSMT, so you can

  • transform expressions from the solver native representation to KSMT representation and vice versa,
  • use formula introspection,
  • manipulate expressions without involving a solver,
  • use expressions even if the solver is freed.

Expression interning (hash consing) affords faster expression comparison: we do not need to compare the expression trees. Expressions are deduplicated, so we avoid redundant memory allocation.

Kotlin-based DSL for SMT formulas

KSMT provides you with a unified DSL for SMT expressions:

val array by mkArraySort(intSort, intSort)
val index by intSort
val value by intSort

val expr = (array.select(index - 1.expr) lt value) and
        (array.select(index + 1.expr) gt value)

Utilities to simplify and transform expressions

KSMT provides a simplification engine applicable to all supported expressions for all supported theories:

  • reduce expression size and complexity
  • evaluate expressions (including those with free variables) — reduce your expression to a constant
  • perform formula transformations
  • substitute expressions

KSMT simplification engine implements more than 200 rules. By default, it attempts to apply simplifications when you create the expressions, but you can turn this feature off, if necessary. You can also simplify an arbitrary expression manually.

Using multiple solvers (portfolio mode)

SMT solvers may differ in performance across different formulas: see the International Satisfiability Modulo Theories Competition.

With KSMT portfolio solving, you can run multiple solvers in parallel on the same formula — until you get the first (the fastest) result.

For detailed instructions on running multiple solvers, see Advanced usage.

Running solvers in separate processes

Most of the SMT solvers are research projects — they are implemented via native libraries and are sometimes not production ready:

  • they may ignore timeouts — they sometimes hang in a long-running operation, and you cannot interrupt it;
  • they may suddenly crash interrupting the entire process — because of a pointer issue, for example.

KSMT runs each solver in a separate process, which adds to stability of your application and provides support for portfolio mode.

KSMT distribution

Many solvers do not have prebuilt binaries, or binaries are for Linux only.

KSMT is distributed as JVM library with solver binaries provided. The library has been tested against the SMT-LIB benchmarks. Documentation and examples are also available.

  1. IEEE Floats are supported in Yices2 using ksmt-symfpu