1 /******************************************************************************
2 * Top contributors (to current version):
5 * This file is part of the cvc5 project.
7 * Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
8 * in the top-level source directory and their institutional affiliations.
9 * All rights reserved. See the file COPYING in the top-level source
10 * directory for licensing information.
11 * ****************************************************************************
13 * A simple demonstration of the api capabilities of cvc5.
17 import io
.github
.cvc5
.api
.*;
18 import java
.math
.BigInteger
;
19 import java
.util
.ArrayList
;
20 import java
.util
.Arrays
;
21 import java
.util
.List
;
23 public class QuickStart
25 public static void main(String args
[]) throws CVC5ApiException
28 try (Solver solver
= new Solver())
30 // We will ask the solver to produce models and unsat cores,
31 // hence these options should be turned on.
32 solver
.setOption("produce-models", "true");
33 solver
.setOption("produce-unsat-cores", "true");
35 // The simplest way to set a logic for the solver is to choose "ALL".
36 // This enables all logics in the solver.
37 // Alternatively, "QF_ALL" enables all logics without quantifiers.
38 // To optimize the solver's behavior for a more specific logic,
39 // use the logic name, e.g. "QF_BV" or "QF_AUFBV".
42 solver
.setLogic("ALL");
44 // In this example, we will define constraints over reals and integers.
45 // Hence, we first obtain the corresponding sorts.
46 Sort realSort
= solver
.getRealSort();
47 Sort intSort
= solver
.getIntegerSort();
49 // x and y will be real variables, while a and b will be integer variables.
50 // Formally, their cpp type is Term,
51 // and they are called "constants" in SMT jargon:
52 Term x
= solver
.mkConst(realSort
, "x");
53 Term y
= solver
.mkConst(realSort
, "y");
54 Term a
= solver
.mkConst(intSort
, "a");
55 Term b
= solver
.mkConst(intSort
, "b");
57 // Our constraints regarding x and y will be:
65 // Formally, constraints are also terms. Their sort is Boolean.
66 // We will construct these constraints gradually,
67 // by defining each of their components.
68 // We start with the constant numerals 0 and 1:
69 Term zero
= solver
.mkReal(0);
70 Term one
= solver
.mkReal(1);
72 // Next, we construct the term x + y
73 Term xPlusY
= solver
.mkTerm(Kind
.PLUS
, x
, y
);
75 // Now we can define the constraints.
76 // They use the operators +, <=, and <.
77 // In the API, these are denoted by PLUS, LEQ, and LT.
78 // A list of available operators is available in:
79 // src/api/cpp/cvc5_kind.h
80 Term constraint1
= solver
.mkTerm(Kind
.LT
, zero
, x
);
81 Term constraint2
= solver
.mkTerm(Kind
.LT
, zero
, y
);
82 Term constraint3
= solver
.mkTerm(Kind
.LT
, xPlusY
, one
);
83 Term constraint4
= solver
.mkTerm(Kind
.LEQ
, x
, y
);
85 // Now we assert the constraints to the solver.
86 solver
.assertFormula(constraint1
);
87 solver
.assertFormula(constraint2
);
88 solver
.assertFormula(constraint3
);
89 solver
.assertFormula(constraint4
);
91 // Check if the formula is satisfiable, that is,
92 // are there real values for x and y that satisfy all the constraints?
93 Result r1
= solver
.checkSat();
95 // The result is either SAT, UNSAT, or UNKNOWN.
96 // In this case, it is SAT.
97 System
.out
.println("expected: sat");
98 System
.out
.println("result: " + r1
);
100 // We can get the values for x and y that satisfy the constraints.
101 Term xVal
= solver
.getValue(x
);
102 Term yVal
= solver
.getValue(y
);
104 // It is also possible to get values for compound terms,
105 // even if those did not appear in the original formula.
106 Term xMinusY
= solver
.mkTerm(Kind
.MINUS
, x
, y
);
107 Term xMinusYVal
= solver
.getValue(xMinusY
);
109 // Further, we can convert the values to java types
110 Pair
<BigInteger
, BigInteger
> xPair
= xVal
.getRealValue();
111 Pair
<BigInteger
, BigInteger
> yPair
= yVal
.getRealValue();
112 Pair
<BigInteger
, BigInteger
> xMinusYPair
= xMinusYVal
.getRealValue();
114 System
.out
.println("value for x: " + xPair
.first
+ "/" + xPair
.second
);
115 System
.out
.println("value for y: " + yPair
.first
+ "/" + yPair
.second
);
116 System
.out
.println("value for x - y: " + xMinusYPair
.first
+ "/" + xMinusYPair
.second
);
118 // Another way to independently compute the value of x - y would be
119 // to perform the (rational) arithmetic manually.
120 // However, for more complex terms,
121 // it is easier to let the solver do the evaluation.
122 Pair
<BigInteger
, BigInteger
> xMinusYComputed
=
123 new Pair(xPair
.first
.multiply(yPair
.second
).subtract(xPair
.second
.multiply(yPair
.first
)),
124 xPair
.second
.multiply(yPair
.second
));
125 BigInteger g
= xMinusYComputed
.first
.gcd(xMinusYComputed
.second
);
126 xMinusYComputed
= new Pair(xMinusYComputed
.first
.divide(g
), xMinusYComputed
.second
.divide(g
));
127 if (xMinusYComputed
.equals(xMinusYPair
))
129 System
.out
.println("computed correctly");
133 System
.out
.println("computed incorrectly");
136 // Next, we will check satisfiability of the same formula,
137 // only this time over integer variables a and b.
139 // We start by resetting assertions added to the solver.
140 solver
.resetAssertions();
142 // Next, we assert the same assertions above with integers.
143 // This time, we inline the construction of terms
144 // to the assertion command.
145 solver
.assertFormula(solver
.mkTerm(Kind
.LT
, solver
.mkInteger(0), a
));
146 solver
.assertFormula(solver
.mkTerm(Kind
.LT
, solver
.mkInteger(0), b
));
147 solver
.assertFormula(
148 solver
.mkTerm(Kind
.LT
, solver
.mkTerm(Kind
.PLUS
, a
, b
), solver
.mkInteger(1)));
149 solver
.assertFormula(solver
.mkTerm(Kind
.LEQ
, a
, b
));
151 // We check whether the revised assertion is satisfiable.
152 Result r2
= solver
.checkSat();
154 // This time the formula is unsatisfiable
155 System
.out
.println("expected: unsat");
156 System
.out
.println("result: " + r2
);
158 // We can query the solver for an unsatisfiable core, i.e., a subset
159 // of the assertions that is already unsatisfiable.
160 List
<Term
> unsatCore
= Arrays
.asList(solver
.getUnsatCore());
161 System
.out
.println("unsat core size: " + unsatCore
.size());
162 System
.out
.println("unsat core: ");
163 for (Term t
: unsatCore
)
165 System
.out
.println(t
);