Quickstart Guide

First, create a cvc5 TermManager instance:

TermManager tm = new TermManager();

Then, create a cvc5 Solver instance:

Solver solver = new Solver(tm);

To produce models and unsat cores, we have to enable the following options.

solver.setOption("produce-models", "true");
solver.setOption("produce-unsat-cores", "true");

Next we set the logic. The simplest way to set a logic for the solver is to choose "ALL" . This enables all logics in the solver. Alternatively, "QF_ALL" enables all logics without quantifiers. To optimize the solver’s behavior for a more specific logic, use the logic name, e.g. "QF_BV" or "QF_AUFBV" .

solver.setLogic("ALL");

In the following, we will define real and integer constraints. For this, we first query the solver for the corresponding sorts.

Sort realSort = tm.getRealSort();
Sort intSort = tm.getIntegerSort();

Now, we create two constants x and y of sort Real , and two constants a and b of sort Integer . Notice that these are symbolic constants, not actual values.

Term x = tm.mkConst(realSort, "x");
Term y = tm.mkConst(realSort, "y");
Term a = tm.mkConst(intSort, "a");
Term b = tm.mkConst(intSort, "b");

We define the following constraints regarding x and y :

\[(0 < x) \wedge (0 < y) \wedge (x + y < 1) \wedge (x \leq y)\]

We construct the required terms and assert them as follows:

// Formally, constraints are also terms. Their sort is Boolean.
// We will construct these constraints gradually,
// by defining each of their components.
// We start with the constant numerals 0 and 1:
Term zero = tm.mkReal(0);
Term one = tm.mkReal(1);

// Next, we construct the term x + y
Term xPlusY = tm.mkTerm(Kind.ADD, x, y);

// Now we can define the constraints.
// They use the operators +, <=, and <.
// In the API, these are denoted by ADD, LEQ, and LT.
// A list of available operators is available in:
// src/api/cpp/cvc5_kind.h
Term constraint1 = tm.mkTerm(Kind.LT, zero, x);
Term constraint2 = tm.mkTerm(Kind.LT, zero, y);
Term constraint3 = tm.mkTerm(Kind.LT, xPlusY, one);
Term constraint4 = tm.mkTerm(Kind.LEQ, x, y);

// Now we assert the constraints to the solver.
solver.assertFormula(constraint1);
solver.assertFormula(constraint2);
solver.assertFormula(constraint3);
solver.assertFormula(constraint4);

Now we check if the asserted formula is satisfiable, that is, we check if there exist values of sort Real for x and y that satisfy all the constraints.

Result r1 = solver.checkSat();

The result we get from this satisfiability check is either sat , unsat or unknown . It’s status can be queried via Result.isSat , Result.isUnsat and Result.isSatUnknown . Alternatively, it can also be printed.

System.out.println("expected: sat");
System.out.println("result: " + r1);

This will print:

expected: sat
result: sat

Now, we query the solver for the values for x and y that satisfy the constraints.

Term xVal = solver.getValue(x);
Term yVal = solver.getValue(y);

It is also possible to get values for terms that do not appear in the original formula.

Term xMinusY = tm.mkTerm(Kind.SUB, x, y);
Term xMinusYVal = solver.getValue(xMinusY);

We can convert these values to Java types.

Pair<BigInteger, BigInteger> xPair = xVal.getRealValue();
Pair<BigInteger, BigInteger> yPair = yVal.getRealValue();
Pair<BigInteger, BigInteger> xMinusYPair = xMinusYVal.getRealValue();

System.out.println("value for x: " + xPair.first + "/" + xPair.second);
System.out.println("value for y: " + yPair.first + "/" + yPair.second);
System.out.println("value for x - y: " + xMinusYPair.first + "/" + xMinusYPair.second);

Another way to independently compute the value of x - y would be to perform the (rational) arithmetic manually. However, for more complex terms, it is easier to let the solver do the evaluation.

Pair<BigInteger, BigInteger> xMinusYComputed = new Pair<>(
    xPair.first.multiply(yPair.second).subtract(xPair.second.multiply(yPair.first)),
    xPair.second.multiply(yPair.second));
BigInteger g = xMinusYComputed.first.gcd(xMinusYComputed.second);
xMinusYComputed =
    new Pair<>(xMinusYComputed.first.divide(g), xMinusYComputed.second.divide(g));
if (xMinusYComputed.equals(xMinusYPair))
{
  System.out.println("computed correctly");
}
else
{
  System.out.println("computed incorrectly");
}

This will print:

computed correctly

Next, we will check satisfiability of the same formula, only this time over integer variables a and b . For this, we first reset the assertions added to the solver.

solver.resetAssertions();

Next, we assert the same assertions as above, but with integers. This time, we inline the construction of terms in the assertion command.

solver.assertFormula(tm.mkTerm(Kind.LT, tm.mkInteger(0), a));
solver.assertFormula(tm.mkTerm(Kind.LT, tm.mkInteger(0), b));
solver.assertFormula(tm.mkTerm(Kind.LT, tm.mkTerm(Kind.ADD, a, b), tm.mkInteger(1)));
solver.assertFormula(tm.mkTerm(Kind.LEQ, a, b));

Now, we check whether the revised assertion is satisfiable.

Result r2 = solver.checkSat();

// This time the formula is unsatisfiable
System.out.println("expected: unsat");
System.out.println("result: " + r2);

This time the asserted formula is unsatisfiable:

expected: unsat
result: unsat

We can query the solver for an unsatisfiable core, that is, a subset of the assertions that is already unsatisfiable.

List<Term> unsatCore = Arrays.asList(solver.getUnsatCore());
System.out.println("unsat core size: " + unsatCore.size());
System.out.println("unsat core: ");
for (Term t : unsatCore)
{
  System.out.println(t);
}

This will print:

unsat core size: 3
unsat core:
(< 0 a)
(< 0 b)
(< (+ a b) 1)

Example

examples/api/java/QuickStart.java

  1/******************************************************************************
  2 * This file is part of the cvc5 project.
  3 *
  4 * Copyright (c) 2009-2026 by the authors listed in the file AUTHORS
  5 * in the top-level source directory and their institutional affiliations.
  6 * All rights reserved.  See the file COPYING in the top-level source
  7 * directory for licensing information.
  8 * ****************************************************************************
  9 *
 10 * A simple demonstration of the api capabilities of cvc5.
 11 *
 12 */
 13
 14import io.github.cvc5.*;
 15import java.math.BigInteger;
 16import java.util.ArrayList;
 17import java.util.Arrays;
 18import java.util.List;
 19
 20public class QuickStart
 21{
 22  public static void main(String args[]) throws CVC5ApiException
 23  {
 24    // Create a term manager
 25    //! [docs-java-quickstart-0 start]
 26    TermManager tm = new TermManager();
 27    //! [docs-java-quickstart-0 end]
 28    // Create a solver
 29    //! [docs-java-quickstart-1 start]
 30    Solver solver = new Solver(tm);
 31    //! [docs-java-quickstart-1 end]
 32    // Release the native memory of the term manager and solver when done
 33    try (tm; solver)
 34    {
 35      // We will ask the solver to produce models and unsat cores,
 36      // hence these options should be turned on.
 37      //! [docs-java-quickstart-2 start]
 38      solver.setOption("produce-models", "true");
 39      solver.setOption("produce-unsat-cores", "true");
 40      //! [docs-java-quickstart-2 end]
 41
 42      // The simplest way to set a logic for the solver is to choose "ALL".
 43      // This enables all logics in the solver.
 44      // Alternatively, "QF_ALL" enables all logics without quantifiers.
 45      // To optimize the solver's behavior for a more specific logic,
 46      // use the logic name, e.g. "QF_BV" or "QF_AUFBV".
 47
 48      // Set the logic
 49      //! [docs-java-quickstart-3 start]
 50      solver.setLogic("ALL");
 51      //! [docs-java-quickstart-3 end]
 52
 53      // In this example, we will define constraints over reals and integers.
 54      // Hence, we first obtain the corresponding sorts.
 55      //! [docs-java-quickstart-4 start]
 56      Sort realSort = tm.getRealSort();
 57      Sort intSort = tm.getIntegerSort();
 58      //! [docs-java-quickstart-4 end]
 59
 60      // x and y will be real variables, while a and b will be integer variables.
 61      // Formally, their cpp type is Term,
 62      // and they are called "constants" in SMT jargon:
 63      //! [docs-java-quickstart-5 start]
 64      Term x = tm.mkConst(realSort, "x");
 65      Term y = tm.mkConst(realSort, "y");
 66      Term a = tm.mkConst(intSort, "a");
 67      Term b = tm.mkConst(intSort, "b");
 68      //! [docs-java-quickstart-5 end]
 69
 70      // Our constraints regarding x and y will be:
 71      //
 72      //   (1)  0 < x
 73      //   (2)  0 < y
 74      //   (3)  x + y < 1
 75      //   (4)  x <= y
 76      //
 77
 78      //! [docs-java-quickstart-6 start]
 79      // Formally, constraints are also terms. Their sort is Boolean.
 80      // We will construct these constraints gradually,
 81      // by defining each of their components.
 82      // We start with the constant numerals 0 and 1:
 83      Term zero = tm.mkReal(0);
 84      Term one = tm.mkReal(1);
 85
 86      // Next, we construct the term x + y
 87      Term xPlusY = tm.mkTerm(Kind.ADD, x, y);
 88
 89      // Now we can define the constraints.
 90      // They use the operators +, <=, and <.
 91      // In the API, these are denoted by ADD, LEQ, and LT.
 92      // A list of available operators is available in:
 93      // src/api/cpp/cvc5_kind.h
 94      Term constraint1 = tm.mkTerm(Kind.LT, zero, x);
 95      Term constraint2 = tm.mkTerm(Kind.LT, zero, y);
 96      Term constraint3 = tm.mkTerm(Kind.LT, xPlusY, one);
 97      Term constraint4 = tm.mkTerm(Kind.LEQ, x, y);
 98
 99      // Now we assert the constraints to the solver.
100      solver.assertFormula(constraint1);
101      solver.assertFormula(constraint2);
102      solver.assertFormula(constraint3);
103      solver.assertFormula(constraint4);
104      //! [docs-java-quickstart-6 end]
105
106      // Check if the formula is satisfiable, that is,
107      // are there real values for x and y that satisfy all the constraints?
108      //! [docs-java-quickstart-7 start]
109      Result r1 = solver.checkSat();
110      //! [docs-java-quickstart-7 end]
111
112      // The result is either SAT, UNSAT, or UNKNOWN.
113      // In this case, it is SAT.
114      //! [docs-java-quickstart-8 start]
115      System.out.println("expected: sat");
116      System.out.println("result: " + r1);
117      //! [docs-java-quickstart-8 end]
118
119      // We can get the values for x and y that satisfy the constraints.
120      //! [docs-java-quickstart-9 start]
121      Term xVal = solver.getValue(x);
122      Term yVal = solver.getValue(y);
123      //! [docs-java-quickstart-9 end]
124
125      // It is also possible to get values for compound terms,
126      // even if those did not appear in the original formula.
127      //! [docs-java-quickstart-10 start]
128      Term xMinusY = tm.mkTerm(Kind.SUB, x, y);
129      Term xMinusYVal = solver.getValue(xMinusY);
130      //! [docs-java-quickstart-10 end]
131
132      // Further, we can convert the values to java types
133      //! [docs-java-quickstart-11 start]
134      Pair<BigInteger, BigInteger> xPair = xVal.getRealValue();
135      Pair<BigInteger, BigInteger> yPair = yVal.getRealValue();
136      Pair<BigInteger, BigInteger> xMinusYPair = xMinusYVal.getRealValue();
137
138      System.out.println("value for x: " + xPair.first + "/" + xPair.second);
139      System.out.println("value for y: " + yPair.first + "/" + yPair.second);
140      System.out.println("value for x - y: " + xMinusYPair.first + "/" + xMinusYPair.second);
141      //! [docs-java-quickstart-11 end]
142
143      // Another way to independently compute the value of x - y would be
144      // to perform the (rational) arithmetic manually.
145      // However, for more complex terms,
146      // it is easier to let the solver do the evaluation.
147      //! [docs-java-quickstart-12 start]
148      Pair<BigInteger, BigInteger> xMinusYComputed = new Pair<>(
149          xPair.first.multiply(yPair.second).subtract(xPair.second.multiply(yPair.first)),
150          xPair.second.multiply(yPair.second));
151      BigInteger g = xMinusYComputed.first.gcd(xMinusYComputed.second);
152      xMinusYComputed =
153          new Pair<>(xMinusYComputed.first.divide(g), xMinusYComputed.second.divide(g));
154      if (xMinusYComputed.equals(xMinusYPair))
155      {
156        System.out.println("computed correctly");
157      }
158      else
159      {
160        System.out.println("computed incorrectly");
161      }
162      //! [docs-java-quickstart-12 end]
163
164      // Next, we will check satisfiability of the same formula,
165      // only this time over integer variables a and b.
166
167      // We start by resetting assertions added to the solver.
168      //! [docs-java-quickstart-13 start]
169      solver.resetAssertions();
170      //! [docs-java-quickstart-13 end]
171
172      // Next, we assert the same assertions above with integers.
173      // This time, we inline the construction of terms
174      // to the assertion command.
175      //! [docs-java-quickstart-14 start]
176      solver.assertFormula(tm.mkTerm(Kind.LT, tm.mkInteger(0), a));
177      solver.assertFormula(tm.mkTerm(Kind.LT, tm.mkInteger(0), b));
178      solver.assertFormula(tm.mkTerm(Kind.LT, tm.mkTerm(Kind.ADD, a, b), tm.mkInteger(1)));
179      solver.assertFormula(tm.mkTerm(Kind.LEQ, a, b));
180      //! [docs-java-quickstart-14 end]
181
182      // We check whether the revised assertion is satisfiable.
183      //! [docs-java-quickstart-15 start]
184      Result r2 = solver.checkSat();
185
186      // This time the formula is unsatisfiable
187      System.out.println("expected: unsat");
188      System.out.println("result: " + r2);
189      //! [docs-java-quickstart-15 end]
190
191      // We can query the solver for an unsatisfiable core, i.e., a subset
192      // of the assertions that is already unsatisfiable.
193      //! [docs-java-quickstart-16 start]
194      List<Term> unsatCore = Arrays.asList(solver.getUnsatCore());
195      System.out.println("unsat core size: " + unsatCore.size());
196      System.out.println("unsat core: ");
197      for (Term t : unsatCore)
198      {
199        System.out.println(t);
200      }
201      //! [docs-java-quickstart-16 end]
202    }
203  }
204}