1db695c83SMikhail R. Gadelha //== Z3Solver.cpp -----------------------------------------------*- C++ -*--==//
2db695c83SMikhail R. Gadelha //
3db695c83SMikhail R. Gadelha // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4db695c83SMikhail R. Gadelha // See https://llvm.org/LICENSE.txt for license information.
5db695c83SMikhail R. Gadelha // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6db695c83SMikhail R. Gadelha //
7db695c83SMikhail R. Gadelha //===----------------------------------------------------------------------===//
8db695c83SMikhail R. Gadelha
9db695c83SMikhail R. Gadelha #include "llvm/Config/config.h"
10db695c83SMikhail R. Gadelha #include "llvm/Support/SMTAPI.h"
11db695c83SMikhail R. Gadelha
12db695c83SMikhail R. Gadelha using namespace llvm;
13db695c83SMikhail R. Gadelha
14db695c83SMikhail R. Gadelha #if LLVM_WITH_Z3
15db695c83SMikhail R. Gadelha
16*60cb83d5SBalazs Benics #include "llvm/ADT/SmallString.h"
17efec6b80Sserge-sans-paille #include "llvm/ADT/Twine.h"
18efec6b80Sserge-sans-paille
19e61a1a98Sserge-sans-paille #include <set>
20e61a1a98Sserge-sans-paille
21db695c83SMikhail R. Gadelha #include <z3.h>
22db695c83SMikhail R. Gadelha
23db695c83SMikhail R. Gadelha namespace {
24db695c83SMikhail R. Gadelha
25db695c83SMikhail R. Gadelha /// Configuration class for Z3
26db695c83SMikhail R. Gadelha class Z3Config {
27db695c83SMikhail R. Gadelha friend class Z3Context;
28db695c83SMikhail R. Gadelha
29db695c83SMikhail R. Gadelha Z3_config Config;
30db695c83SMikhail R. Gadelha
31db695c83SMikhail R. Gadelha public:
Z3Config()32db695c83SMikhail R. Gadelha Z3Config() : Config(Z3_mk_config()) {
33db695c83SMikhail R. Gadelha // Enable model finding
34db695c83SMikhail R. Gadelha Z3_set_param_value(Config, "model", "true");
35db695c83SMikhail R. Gadelha // Disable proof generation
36db695c83SMikhail R. Gadelha Z3_set_param_value(Config, "proof", "false");
37db695c83SMikhail R. Gadelha // Set timeout to 15000ms = 15s
38db695c83SMikhail R. Gadelha Z3_set_param_value(Config, "timeout", "15000");
39db695c83SMikhail R. Gadelha }
40db695c83SMikhail R. Gadelha
~Z3Config()41db695c83SMikhail R. Gadelha ~Z3Config() { Z3_del_config(Config); }
42db695c83SMikhail R. Gadelha }; // end class Z3Config
43db695c83SMikhail R. Gadelha
44db695c83SMikhail R. Gadelha // Function used to report errors
Z3ErrorHandler(Z3_context Context,Z3_error_code Error)45db695c83SMikhail R. Gadelha void Z3ErrorHandler(Z3_context Context, Z3_error_code Error) {
46db695c83SMikhail R. Gadelha llvm::report_fatal_error("Z3 error: " +
47db695c83SMikhail R. Gadelha llvm::Twine(Z3_get_error_msg(Context, Error)));
48db695c83SMikhail R. Gadelha }
49db695c83SMikhail R. Gadelha
50db695c83SMikhail R. Gadelha /// Wrapper for Z3 context
51db695c83SMikhail R. Gadelha class Z3Context {
52db695c83SMikhail R. Gadelha public:
53db695c83SMikhail R. Gadelha Z3_context Context;
54db695c83SMikhail R. Gadelha
Z3Context()55db695c83SMikhail R. Gadelha Z3Context() {
56db695c83SMikhail R. Gadelha Context = Z3_mk_context_rc(Z3Config().Config);
57db695c83SMikhail R. Gadelha // The error function is set here because the context is the first object
58db695c83SMikhail R. Gadelha // created by the backend
59db695c83SMikhail R. Gadelha Z3_set_error_handler(Context, Z3ErrorHandler);
60db695c83SMikhail R. Gadelha }
61db695c83SMikhail R. Gadelha
~Z3Context()62db695c83SMikhail R. Gadelha virtual ~Z3Context() {
63db695c83SMikhail R. Gadelha Z3_del_context(Context);
64db695c83SMikhail R. Gadelha Context = nullptr;
65db695c83SMikhail R. Gadelha }
66db695c83SMikhail R. Gadelha }; // end class Z3Context
67db695c83SMikhail R. Gadelha
68db695c83SMikhail R. Gadelha /// Wrapper for Z3 Sort
69db695c83SMikhail R. Gadelha class Z3Sort : public SMTSort {
70db695c83SMikhail R. Gadelha friend class Z3Solver;
71db695c83SMikhail R. Gadelha
72db695c83SMikhail R. Gadelha Z3Context &Context;
73db695c83SMikhail R. Gadelha
74db695c83SMikhail R. Gadelha Z3_sort Sort;
75db695c83SMikhail R. Gadelha
76db695c83SMikhail R. Gadelha public:
77db695c83SMikhail R. Gadelha /// Default constructor, mainly used by make_shared
Z3Sort(Z3Context & C,Z3_sort ZS)78db695c83SMikhail R. Gadelha Z3Sort(Z3Context &C, Z3_sort ZS) : Context(C), Sort(ZS) {
79db695c83SMikhail R. Gadelha Z3_inc_ref(Context.Context, reinterpret_cast<Z3_ast>(Sort));
80db695c83SMikhail R. Gadelha }
81db695c83SMikhail R. Gadelha
82db695c83SMikhail R. Gadelha /// Override implicit copy constructor for correct reference counting.
Z3Sort(const Z3Sort & Other)83db695c83SMikhail R. Gadelha Z3Sort(const Z3Sort &Other) : Context(Other.Context), Sort(Other.Sort) {
84db695c83SMikhail R. Gadelha Z3_inc_ref(Context.Context, reinterpret_cast<Z3_ast>(Sort));
85db695c83SMikhail R. Gadelha }
86db695c83SMikhail R. Gadelha
87db695c83SMikhail R. Gadelha /// Override implicit copy assignment constructor for correct reference
88db695c83SMikhail R. Gadelha /// counting.
operator =(const Z3Sort & Other)89db695c83SMikhail R. Gadelha Z3Sort &operator=(const Z3Sort &Other) {
90db695c83SMikhail R. Gadelha Z3_inc_ref(Context.Context, reinterpret_cast<Z3_ast>(Other.Sort));
91db695c83SMikhail R. Gadelha Z3_dec_ref(Context.Context, reinterpret_cast<Z3_ast>(Sort));
92db695c83SMikhail R. Gadelha Sort = Other.Sort;
93db695c83SMikhail R. Gadelha return *this;
94db695c83SMikhail R. Gadelha }
95db695c83SMikhail R. Gadelha
96db695c83SMikhail R. Gadelha Z3Sort(Z3Sort &&Other) = delete;
97db695c83SMikhail R. Gadelha Z3Sort &operator=(Z3Sort &&Other) = delete;
98db695c83SMikhail R. Gadelha
~Z3Sort()99db695c83SMikhail R. Gadelha ~Z3Sort() {
100db695c83SMikhail R. Gadelha if (Sort)
101db695c83SMikhail R. Gadelha Z3_dec_ref(Context.Context, reinterpret_cast<Z3_ast>(Sort));
102db695c83SMikhail R. Gadelha }
103db695c83SMikhail R. Gadelha
Profile(llvm::FoldingSetNodeID & ID) const104db695c83SMikhail R. Gadelha void Profile(llvm::FoldingSetNodeID &ID) const override {
105db695c83SMikhail R. Gadelha ID.AddInteger(
106db695c83SMikhail R. Gadelha Z3_get_ast_id(Context.Context, reinterpret_cast<Z3_ast>(Sort)));
107db695c83SMikhail R. Gadelha }
108db695c83SMikhail R. Gadelha
isBitvectorSortImpl() const109db695c83SMikhail R. Gadelha bool isBitvectorSortImpl() const override {
110db695c83SMikhail R. Gadelha return (Z3_get_sort_kind(Context.Context, Sort) == Z3_BV_SORT);
111db695c83SMikhail R. Gadelha }
112db695c83SMikhail R. Gadelha
isFloatSortImpl() const113db695c83SMikhail R. Gadelha bool isFloatSortImpl() const override {
114db695c83SMikhail R. Gadelha return (Z3_get_sort_kind(Context.Context, Sort) == Z3_FLOATING_POINT_SORT);
115db695c83SMikhail R. Gadelha }
116db695c83SMikhail R. Gadelha
isBooleanSortImpl() const117db695c83SMikhail R. Gadelha bool isBooleanSortImpl() const override {
118db695c83SMikhail R. Gadelha return (Z3_get_sort_kind(Context.Context, Sort) == Z3_BOOL_SORT);
119db695c83SMikhail R. Gadelha }
120db695c83SMikhail R. Gadelha
getBitvectorSortSizeImpl() const121db695c83SMikhail R. Gadelha unsigned getBitvectorSortSizeImpl() const override {
122db695c83SMikhail R. Gadelha return Z3_get_bv_sort_size(Context.Context, Sort);
123db695c83SMikhail R. Gadelha }
124db695c83SMikhail R. Gadelha
getFloatSortSizeImpl() const125db695c83SMikhail R. Gadelha unsigned getFloatSortSizeImpl() const override {
126db695c83SMikhail R. Gadelha return Z3_fpa_get_ebits(Context.Context, Sort) +
127db695c83SMikhail R. Gadelha Z3_fpa_get_sbits(Context.Context, Sort);
128db695c83SMikhail R. Gadelha }
129db695c83SMikhail R. Gadelha
equal_to(SMTSort const & Other) const130db695c83SMikhail R. Gadelha bool equal_to(SMTSort const &Other) const override {
131db695c83SMikhail R. Gadelha return Z3_is_eq_sort(Context.Context, Sort,
132db695c83SMikhail R. Gadelha static_cast<const Z3Sort &>(Other).Sort);
133db695c83SMikhail R. Gadelha }
134db695c83SMikhail R. Gadelha
print(raw_ostream & OS) const135db695c83SMikhail R. Gadelha void print(raw_ostream &OS) const override {
136db695c83SMikhail R. Gadelha OS << Z3_sort_to_string(Context.Context, Sort);
137db695c83SMikhail R. Gadelha }
138db695c83SMikhail R. Gadelha }; // end class Z3Sort
139db695c83SMikhail R. Gadelha
toZ3Sort(const SMTSort & S)140db695c83SMikhail R. Gadelha static const Z3Sort &toZ3Sort(const SMTSort &S) {
141db695c83SMikhail R. Gadelha return static_cast<const Z3Sort &>(S);
142db695c83SMikhail R. Gadelha }
143db695c83SMikhail R. Gadelha
144db695c83SMikhail R. Gadelha class Z3Expr : public SMTExpr {
145db695c83SMikhail R. Gadelha friend class Z3Solver;
146db695c83SMikhail R. Gadelha
147db695c83SMikhail R. Gadelha Z3Context &Context;
148db695c83SMikhail R. Gadelha
149db695c83SMikhail R. Gadelha Z3_ast AST;
150db695c83SMikhail R. Gadelha
151db695c83SMikhail R. Gadelha public:
Z3Expr(Z3Context & C,Z3_ast ZA)152db695c83SMikhail R. Gadelha Z3Expr(Z3Context &C, Z3_ast ZA) : SMTExpr(), Context(C), AST(ZA) {
153db695c83SMikhail R. Gadelha Z3_inc_ref(Context.Context, AST);
154db695c83SMikhail R. Gadelha }
155db695c83SMikhail R. Gadelha
156db695c83SMikhail R. Gadelha /// Override implicit copy constructor for correct reference counting.
Z3Expr(const Z3Expr & Copy)157db695c83SMikhail R. Gadelha Z3Expr(const Z3Expr &Copy) : SMTExpr(), Context(Copy.Context), AST(Copy.AST) {
158db695c83SMikhail R. Gadelha Z3_inc_ref(Context.Context, AST);
159db695c83SMikhail R. Gadelha }
160db695c83SMikhail R. Gadelha
161db695c83SMikhail R. Gadelha /// Override implicit copy assignment constructor for correct reference
162db695c83SMikhail R. Gadelha /// counting.
operator =(const Z3Expr & Other)163db695c83SMikhail R. Gadelha Z3Expr &operator=(const Z3Expr &Other) {
164db695c83SMikhail R. Gadelha Z3_inc_ref(Context.Context, Other.AST);
165db695c83SMikhail R. Gadelha Z3_dec_ref(Context.Context, AST);
166db695c83SMikhail R. Gadelha AST = Other.AST;
167db695c83SMikhail R. Gadelha return *this;
168db695c83SMikhail R. Gadelha }
169db695c83SMikhail R. Gadelha
170db695c83SMikhail R. Gadelha Z3Expr(Z3Expr &&Other) = delete;
171db695c83SMikhail R. Gadelha Z3Expr &operator=(Z3Expr &&Other) = delete;
172db695c83SMikhail R. Gadelha
~Z3Expr()173db695c83SMikhail R. Gadelha ~Z3Expr() {
174db695c83SMikhail R. Gadelha if (AST)
175db695c83SMikhail R. Gadelha Z3_dec_ref(Context.Context, AST);
176db695c83SMikhail R. Gadelha }
177db695c83SMikhail R. Gadelha
Profile(llvm::FoldingSetNodeID & ID) const178db695c83SMikhail R. Gadelha void Profile(llvm::FoldingSetNodeID &ID) const override {
179db695c83SMikhail R. Gadelha ID.AddInteger(Z3_get_ast_id(Context.Context, AST));
180db695c83SMikhail R. Gadelha }
181db695c83SMikhail R. Gadelha
182db695c83SMikhail R. Gadelha /// Comparison of AST equality, not model equivalence.
equal_to(SMTExpr const & Other) const183db695c83SMikhail R. Gadelha bool equal_to(SMTExpr const &Other) const override {
184db695c83SMikhail R. Gadelha assert(Z3_is_eq_sort(Context.Context, Z3_get_sort(Context.Context, AST),
185db695c83SMikhail R. Gadelha Z3_get_sort(Context.Context,
186db695c83SMikhail R. Gadelha static_cast<const Z3Expr &>(Other).AST)) &&
187db695c83SMikhail R. Gadelha "AST's must have the same sort");
188db695c83SMikhail R. Gadelha return Z3_is_eq_ast(Context.Context, AST,
189db695c83SMikhail R. Gadelha static_cast<const Z3Expr &>(Other).AST);
190db695c83SMikhail R. Gadelha }
191db695c83SMikhail R. Gadelha
print(raw_ostream & OS) const192db695c83SMikhail R. Gadelha void print(raw_ostream &OS) const override {
193db695c83SMikhail R. Gadelha OS << Z3_ast_to_string(Context.Context, AST);
194db695c83SMikhail R. Gadelha }
195db695c83SMikhail R. Gadelha }; // end class Z3Expr
196db695c83SMikhail R. Gadelha
toZ3Expr(const SMTExpr & E)197db695c83SMikhail R. Gadelha static const Z3Expr &toZ3Expr(const SMTExpr &E) {
198db695c83SMikhail R. Gadelha return static_cast<const Z3Expr &>(E);
199db695c83SMikhail R. Gadelha }
200db695c83SMikhail R. Gadelha
201db695c83SMikhail R. Gadelha class Z3Model {
202db695c83SMikhail R. Gadelha friend class Z3Solver;
203db695c83SMikhail R. Gadelha
204db695c83SMikhail R. Gadelha Z3Context &Context;
205db695c83SMikhail R. Gadelha
206db695c83SMikhail R. Gadelha Z3_model Model;
207db695c83SMikhail R. Gadelha
208db695c83SMikhail R. Gadelha public:
Z3Model(Z3Context & C,Z3_model ZM)209db695c83SMikhail R. Gadelha Z3Model(Z3Context &C, Z3_model ZM) : Context(C), Model(ZM) {
210db695c83SMikhail R. Gadelha Z3_model_inc_ref(Context.Context, Model);
211db695c83SMikhail R. Gadelha }
212db695c83SMikhail R. Gadelha
213db695c83SMikhail R. Gadelha Z3Model(const Z3Model &Other) = delete;
214db695c83SMikhail R. Gadelha Z3Model(Z3Model &&Other) = delete;
215db695c83SMikhail R. Gadelha Z3Model &operator=(Z3Model &Other) = delete;
216db695c83SMikhail R. Gadelha Z3Model &operator=(Z3Model &&Other) = delete;
217db695c83SMikhail R. Gadelha
~Z3Model()218db695c83SMikhail R. Gadelha ~Z3Model() {
219db695c83SMikhail R. Gadelha if (Model)
220db695c83SMikhail R. Gadelha Z3_model_dec_ref(Context.Context, Model);
221db695c83SMikhail R. Gadelha }
222db695c83SMikhail R. Gadelha
print(raw_ostream & OS) const223db695c83SMikhail R. Gadelha void print(raw_ostream &OS) const {
224db695c83SMikhail R. Gadelha OS << Z3_model_to_string(Context.Context, Model);
225db695c83SMikhail R. Gadelha }
226db695c83SMikhail R. Gadelha
dump() const227db695c83SMikhail R. Gadelha LLVM_DUMP_METHOD void dump() const { print(llvm::errs()); }
228db695c83SMikhail R. Gadelha }; // end class Z3Model
229db695c83SMikhail R. Gadelha
230db695c83SMikhail R. Gadelha /// Get the corresponding IEEE floating-point type for a given bitwidth.
getFloatSemantics(unsigned BitWidth)231db695c83SMikhail R. Gadelha static const llvm::fltSemantics &getFloatSemantics(unsigned BitWidth) {
232db695c83SMikhail R. Gadelha switch (BitWidth) {
233db695c83SMikhail R. Gadelha default:
234db695c83SMikhail R. Gadelha llvm_unreachable("Unsupported floating-point semantics!");
235db695c83SMikhail R. Gadelha break;
236db695c83SMikhail R. Gadelha case 16:
237db695c83SMikhail R. Gadelha return llvm::APFloat::IEEEhalf();
238db695c83SMikhail R. Gadelha case 32:
239db695c83SMikhail R. Gadelha return llvm::APFloat::IEEEsingle();
240db695c83SMikhail R. Gadelha case 64:
241db695c83SMikhail R. Gadelha return llvm::APFloat::IEEEdouble();
242db695c83SMikhail R. Gadelha case 128:
243db695c83SMikhail R. Gadelha return llvm::APFloat::IEEEquad();
244db695c83SMikhail R. Gadelha }
245db695c83SMikhail R. Gadelha }
246db695c83SMikhail R. Gadelha
247db695c83SMikhail R. Gadelha // Determine whether two float semantics are equivalent
areEquivalent(const llvm::fltSemantics & LHS,const llvm::fltSemantics & RHS)248db695c83SMikhail R. Gadelha static bool areEquivalent(const llvm::fltSemantics &LHS,
249db695c83SMikhail R. Gadelha const llvm::fltSemantics &RHS) {
250db695c83SMikhail R. Gadelha return (llvm::APFloat::semanticsPrecision(LHS) ==
251db695c83SMikhail R. Gadelha llvm::APFloat::semanticsPrecision(RHS)) &&
252db695c83SMikhail R. Gadelha (llvm::APFloat::semanticsMinExponent(LHS) ==
253db695c83SMikhail R. Gadelha llvm::APFloat::semanticsMinExponent(RHS)) &&
254db695c83SMikhail R. Gadelha (llvm::APFloat::semanticsMaxExponent(LHS) ==
255db695c83SMikhail R. Gadelha llvm::APFloat::semanticsMaxExponent(RHS)) &&
256db695c83SMikhail R. Gadelha (llvm::APFloat::semanticsSizeInBits(LHS) ==
257db695c83SMikhail R. Gadelha llvm::APFloat::semanticsSizeInBits(RHS));
258db695c83SMikhail R. Gadelha }
259db695c83SMikhail R. Gadelha
260db695c83SMikhail R. Gadelha class Z3Solver : public SMTSolver {
261db695c83SMikhail R. Gadelha friend class Z3ConstraintManager;
262db695c83SMikhail R. Gadelha
263db695c83SMikhail R. Gadelha Z3Context Context;
264db695c83SMikhail R. Gadelha
265db695c83SMikhail R. Gadelha Z3_solver Solver;
266db695c83SMikhail R. Gadelha
267db695c83SMikhail R. Gadelha // Cache Sorts
268db695c83SMikhail R. Gadelha std::set<Z3Sort> CachedSorts;
269db695c83SMikhail R. Gadelha
270db695c83SMikhail R. Gadelha // Cache Exprs
271db695c83SMikhail R. Gadelha std::set<Z3Expr> CachedExprs;
272db695c83SMikhail R. Gadelha
273db695c83SMikhail R. Gadelha public:
Z3Solver()274db695c83SMikhail R. Gadelha Z3Solver() : Solver(Z3_mk_simple_solver(Context.Context)) {
275db695c83SMikhail R. Gadelha Z3_solver_inc_ref(Context.Context, Solver);
276db695c83SMikhail R. Gadelha }
277db695c83SMikhail R. Gadelha
278db695c83SMikhail R. Gadelha Z3Solver(const Z3Solver &Other) = delete;
279db695c83SMikhail R. Gadelha Z3Solver(Z3Solver &&Other) = delete;
280db695c83SMikhail R. Gadelha Z3Solver &operator=(Z3Solver &Other) = delete;
281db695c83SMikhail R. Gadelha Z3Solver &operator=(Z3Solver &&Other) = delete;
282db695c83SMikhail R. Gadelha
~Z3Solver()283db695c83SMikhail R. Gadelha ~Z3Solver() {
284db695c83SMikhail R. Gadelha if (Solver)
285db695c83SMikhail R. Gadelha Z3_solver_dec_ref(Context.Context, Solver);
286db695c83SMikhail R. Gadelha }
287db695c83SMikhail R. Gadelha
addConstraint(const SMTExprRef & Exp) const288db695c83SMikhail R. Gadelha void addConstraint(const SMTExprRef &Exp) const override {
289db695c83SMikhail R. Gadelha Z3_solver_assert(Context.Context, Solver, toZ3Expr(*Exp).AST);
290db695c83SMikhail R. Gadelha }
291db695c83SMikhail R. Gadelha
292db695c83SMikhail R. Gadelha // Given an SMTSort, adds/retrives it from the cache and returns
293db695c83SMikhail R. Gadelha // an SMTSortRef to the SMTSort in the cache
newSortRef(const SMTSort & Sort)294db695c83SMikhail R. Gadelha SMTSortRef newSortRef(const SMTSort &Sort) {
295db695c83SMikhail R. Gadelha auto It = CachedSorts.insert(toZ3Sort(Sort));
296db695c83SMikhail R. Gadelha return &(*It.first);
297db695c83SMikhail R. Gadelha }
298db695c83SMikhail R. Gadelha
299db695c83SMikhail R. Gadelha // Given an SMTExpr, adds/retrives it from the cache and returns
300db695c83SMikhail R. Gadelha // an SMTExprRef to the SMTExpr in the cache
newExprRef(const SMTExpr & Exp)301db695c83SMikhail R. Gadelha SMTExprRef newExprRef(const SMTExpr &Exp) {
302db695c83SMikhail R. Gadelha auto It = CachedExprs.insert(toZ3Expr(Exp));
303db695c83SMikhail R. Gadelha return &(*It.first);
304db695c83SMikhail R. Gadelha }
305db695c83SMikhail R. Gadelha
getBoolSort()306db695c83SMikhail R. Gadelha SMTSortRef getBoolSort() override {
307db695c83SMikhail R. Gadelha return newSortRef(Z3Sort(Context, Z3_mk_bool_sort(Context.Context)));
308db695c83SMikhail R. Gadelha }
309db695c83SMikhail R. Gadelha
getBitvectorSort(unsigned BitWidth)310db695c83SMikhail R. Gadelha SMTSortRef getBitvectorSort(unsigned BitWidth) override {
311db695c83SMikhail R. Gadelha return newSortRef(
312db695c83SMikhail R. Gadelha Z3Sort(Context, Z3_mk_bv_sort(Context.Context, BitWidth)));
313db695c83SMikhail R. Gadelha }
314db695c83SMikhail R. Gadelha
getSort(const SMTExprRef & Exp)315db695c83SMikhail R. Gadelha SMTSortRef getSort(const SMTExprRef &Exp) override {
316db695c83SMikhail R. Gadelha return newSortRef(
317db695c83SMikhail R. Gadelha Z3Sort(Context, Z3_get_sort(Context.Context, toZ3Expr(*Exp).AST)));
318db695c83SMikhail R. Gadelha }
319db695c83SMikhail R. Gadelha
getFloat16Sort()320db695c83SMikhail R. Gadelha SMTSortRef getFloat16Sort() override {
321db695c83SMikhail R. Gadelha return newSortRef(Z3Sort(Context, Z3_mk_fpa_sort_16(Context.Context)));
322db695c83SMikhail R. Gadelha }
323db695c83SMikhail R. Gadelha
getFloat32Sort()324db695c83SMikhail R. Gadelha SMTSortRef getFloat32Sort() override {
325db695c83SMikhail R. Gadelha return newSortRef(Z3Sort(Context, Z3_mk_fpa_sort_32(Context.Context)));
326db695c83SMikhail R. Gadelha }
327db695c83SMikhail R. Gadelha
getFloat64Sort()328db695c83SMikhail R. Gadelha SMTSortRef getFloat64Sort() override {
329db695c83SMikhail R. Gadelha return newSortRef(Z3Sort(Context, Z3_mk_fpa_sort_64(Context.Context)));
330db695c83SMikhail R. Gadelha }
331db695c83SMikhail R. Gadelha
getFloat128Sort()332db695c83SMikhail R. Gadelha SMTSortRef getFloat128Sort() override {
333db695c83SMikhail R. Gadelha return newSortRef(Z3Sort(Context, Z3_mk_fpa_sort_128(Context.Context)));
334db695c83SMikhail R. Gadelha }
335db695c83SMikhail R. Gadelha
mkBVNeg(const SMTExprRef & Exp)336db695c83SMikhail R. Gadelha SMTExprRef mkBVNeg(const SMTExprRef &Exp) override {
337db695c83SMikhail R. Gadelha return newExprRef(
338db695c83SMikhail R. Gadelha Z3Expr(Context, Z3_mk_bvneg(Context.Context, toZ3Expr(*Exp).AST)));
339db695c83SMikhail R. Gadelha }
340db695c83SMikhail R. Gadelha
mkBVNot(const SMTExprRef & Exp)341db695c83SMikhail R. Gadelha SMTExprRef mkBVNot(const SMTExprRef &Exp) override {
342db695c83SMikhail R. Gadelha return newExprRef(
343db695c83SMikhail R. Gadelha Z3Expr(Context, Z3_mk_bvnot(Context.Context, toZ3Expr(*Exp).AST)));
344db695c83SMikhail R. Gadelha }
345db695c83SMikhail R. Gadelha
mkNot(const SMTExprRef & Exp)346db695c83SMikhail R. Gadelha SMTExprRef mkNot(const SMTExprRef &Exp) override {
347db695c83SMikhail R. Gadelha return newExprRef(
348db695c83SMikhail R. Gadelha Z3Expr(Context, Z3_mk_not(Context.Context, toZ3Expr(*Exp).AST)));
349db695c83SMikhail R. Gadelha }
350db695c83SMikhail R. Gadelha
mkBVAdd(const SMTExprRef & LHS,const SMTExprRef & RHS)351db695c83SMikhail R. Gadelha SMTExprRef mkBVAdd(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
352db695c83SMikhail R. Gadelha return newExprRef(
353db695c83SMikhail R. Gadelha Z3Expr(Context, Z3_mk_bvadd(Context.Context, toZ3Expr(*LHS).AST,
354db695c83SMikhail R. Gadelha toZ3Expr(*RHS).AST)));
355db695c83SMikhail R. Gadelha }
356db695c83SMikhail R. Gadelha
mkBVSub(const SMTExprRef & LHS,const SMTExprRef & RHS)357db695c83SMikhail R. Gadelha SMTExprRef mkBVSub(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
358db695c83SMikhail R. Gadelha return newExprRef(
359db695c83SMikhail R. Gadelha Z3Expr(Context, Z3_mk_bvsub(Context.Context, toZ3Expr(*LHS).AST,
360db695c83SMikhail R. Gadelha toZ3Expr(*RHS).AST)));
361db695c83SMikhail R. Gadelha }
362db695c83SMikhail R. Gadelha
mkBVMul(const SMTExprRef & LHS,const SMTExprRef & RHS)363db695c83SMikhail R. Gadelha SMTExprRef mkBVMul(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
364db695c83SMikhail R. Gadelha return newExprRef(
365db695c83SMikhail R. Gadelha Z3Expr(Context, Z3_mk_bvmul(Context.Context, toZ3Expr(*LHS).AST,
366db695c83SMikhail R. Gadelha toZ3Expr(*RHS).AST)));
367db695c83SMikhail R. Gadelha }
368db695c83SMikhail R. Gadelha
mkBVSRem(const SMTExprRef & LHS,const SMTExprRef & RHS)369db695c83SMikhail R. Gadelha SMTExprRef mkBVSRem(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
370db695c83SMikhail R. Gadelha return newExprRef(
371db695c83SMikhail R. Gadelha Z3Expr(Context, Z3_mk_bvsrem(Context.Context, toZ3Expr(*LHS).AST,
372db695c83SMikhail R. Gadelha toZ3Expr(*RHS).AST)));
373db695c83SMikhail R. Gadelha }
374db695c83SMikhail R. Gadelha
mkBVURem(const SMTExprRef & LHS,const SMTExprRef & RHS)375db695c83SMikhail R. Gadelha SMTExprRef mkBVURem(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
376db695c83SMikhail R. Gadelha return newExprRef(
377db695c83SMikhail R. Gadelha Z3Expr(Context, Z3_mk_bvurem(Context.Context, toZ3Expr(*LHS).AST,
378db695c83SMikhail R. Gadelha toZ3Expr(*RHS).AST)));
379db695c83SMikhail R. Gadelha }
380db695c83SMikhail R. Gadelha
mkBVSDiv(const SMTExprRef & LHS,const SMTExprRef & RHS)381db695c83SMikhail R. Gadelha SMTExprRef mkBVSDiv(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
382db695c83SMikhail R. Gadelha return newExprRef(
383db695c83SMikhail R. Gadelha Z3Expr(Context, Z3_mk_bvsdiv(Context.Context, toZ3Expr(*LHS).AST,
384db695c83SMikhail R. Gadelha toZ3Expr(*RHS).AST)));
385db695c83SMikhail R. Gadelha }
386db695c83SMikhail R. Gadelha
mkBVUDiv(const SMTExprRef & LHS,const SMTExprRef & RHS)387db695c83SMikhail R. Gadelha SMTExprRef mkBVUDiv(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
388db695c83SMikhail R. Gadelha return newExprRef(
389db695c83SMikhail R. Gadelha Z3Expr(Context, Z3_mk_bvudiv(Context.Context, toZ3Expr(*LHS).AST,
390db695c83SMikhail R. Gadelha toZ3Expr(*RHS).AST)));
391db695c83SMikhail R. Gadelha }
392db695c83SMikhail R. Gadelha
mkBVShl(const SMTExprRef & LHS,const SMTExprRef & RHS)393db695c83SMikhail R. Gadelha SMTExprRef mkBVShl(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
394db695c83SMikhail R. Gadelha return newExprRef(
395db695c83SMikhail R. Gadelha Z3Expr(Context, Z3_mk_bvshl(Context.Context, toZ3Expr(*LHS).AST,
396db695c83SMikhail R. Gadelha toZ3Expr(*RHS).AST)));
397db695c83SMikhail R. Gadelha }
398db695c83SMikhail R. Gadelha
mkBVAshr(const SMTExprRef & LHS,const SMTExprRef & RHS)399db695c83SMikhail R. Gadelha SMTExprRef mkBVAshr(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
400db695c83SMikhail R. Gadelha return newExprRef(
401db695c83SMikhail R. Gadelha Z3Expr(Context, Z3_mk_bvashr(Context.Context, toZ3Expr(*LHS).AST,
402db695c83SMikhail R. Gadelha toZ3Expr(*RHS).AST)));
403db695c83SMikhail R. Gadelha }
404db695c83SMikhail R. Gadelha
mkBVLshr(const SMTExprRef & LHS,const SMTExprRef & RHS)405db695c83SMikhail R. Gadelha SMTExprRef mkBVLshr(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
406db695c83SMikhail R. Gadelha return newExprRef(
407db695c83SMikhail R. Gadelha Z3Expr(Context, Z3_mk_bvlshr(Context.Context, toZ3Expr(*LHS).AST,
408db695c83SMikhail R. Gadelha toZ3Expr(*RHS).AST)));
409db695c83SMikhail R. Gadelha }
410db695c83SMikhail R. Gadelha
mkBVXor(const SMTExprRef & LHS,const SMTExprRef & RHS)411db695c83SMikhail R. Gadelha SMTExprRef mkBVXor(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
412db695c83SMikhail R. Gadelha return newExprRef(
413db695c83SMikhail R. Gadelha Z3Expr(Context, Z3_mk_bvxor(Context.Context, toZ3Expr(*LHS).AST,
414db695c83SMikhail R. Gadelha toZ3Expr(*RHS).AST)));
415db695c83SMikhail R. Gadelha }
416db695c83SMikhail R. Gadelha
mkBVOr(const SMTExprRef & LHS,const SMTExprRef & RHS)417db695c83SMikhail R. Gadelha SMTExprRef mkBVOr(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
418db695c83SMikhail R. Gadelha return newExprRef(
419db695c83SMikhail R. Gadelha Z3Expr(Context, Z3_mk_bvor(Context.Context, toZ3Expr(*LHS).AST,
420db695c83SMikhail R. Gadelha toZ3Expr(*RHS).AST)));
421db695c83SMikhail R. Gadelha }
422db695c83SMikhail R. Gadelha
mkBVAnd(const SMTExprRef & LHS,const SMTExprRef & RHS)423db695c83SMikhail R. Gadelha SMTExprRef mkBVAnd(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
424db695c83SMikhail R. Gadelha return newExprRef(
425db695c83SMikhail R. Gadelha Z3Expr(Context, Z3_mk_bvand(Context.Context, toZ3Expr(*LHS).AST,
426db695c83SMikhail R. Gadelha toZ3Expr(*RHS).AST)));
427db695c83SMikhail R. Gadelha }
428db695c83SMikhail R. Gadelha
mkBVUlt(const SMTExprRef & LHS,const SMTExprRef & RHS)429db695c83SMikhail R. Gadelha SMTExprRef mkBVUlt(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
430db695c83SMikhail R. Gadelha return newExprRef(
431db695c83SMikhail R. Gadelha Z3Expr(Context, Z3_mk_bvult(Context.Context, toZ3Expr(*LHS).AST,
432db695c83SMikhail R. Gadelha toZ3Expr(*RHS).AST)));
433db695c83SMikhail R. Gadelha }
434db695c83SMikhail R. Gadelha
mkBVSlt(const SMTExprRef & LHS,const SMTExprRef & RHS)435db695c83SMikhail R. Gadelha SMTExprRef mkBVSlt(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
436db695c83SMikhail R. Gadelha return newExprRef(
437db695c83SMikhail R. Gadelha Z3Expr(Context, Z3_mk_bvslt(Context.Context, toZ3Expr(*LHS).AST,
438db695c83SMikhail R. Gadelha toZ3Expr(*RHS).AST)));
439db695c83SMikhail R. Gadelha }
440db695c83SMikhail R. Gadelha
mkBVUgt(const SMTExprRef & LHS,const SMTExprRef & RHS)441db695c83SMikhail R. Gadelha SMTExprRef mkBVUgt(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
442db695c83SMikhail R. Gadelha return newExprRef(
443db695c83SMikhail R. Gadelha Z3Expr(Context, Z3_mk_bvugt(Context.Context, toZ3Expr(*LHS).AST,
444db695c83SMikhail R. Gadelha toZ3Expr(*RHS).AST)));
445db695c83SMikhail R. Gadelha }
446db695c83SMikhail R. Gadelha
mkBVSgt(const SMTExprRef & LHS,const SMTExprRef & RHS)447db695c83SMikhail R. Gadelha SMTExprRef mkBVSgt(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
448db695c83SMikhail R. Gadelha return newExprRef(
449db695c83SMikhail R. Gadelha Z3Expr(Context, Z3_mk_bvsgt(Context.Context, toZ3Expr(*LHS).AST,
450db695c83SMikhail R. Gadelha toZ3Expr(*RHS).AST)));
451db695c83SMikhail R. Gadelha }
452db695c83SMikhail R. Gadelha
mkBVUle(const SMTExprRef & LHS,const SMTExprRef & RHS)453db695c83SMikhail R. Gadelha SMTExprRef mkBVUle(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
454db695c83SMikhail R. Gadelha return newExprRef(
455db695c83SMikhail R. Gadelha Z3Expr(Context, Z3_mk_bvule(Context.Context, toZ3Expr(*LHS).AST,
456db695c83SMikhail R. Gadelha toZ3Expr(*RHS).AST)));
457db695c83SMikhail R. Gadelha }
458db695c83SMikhail R. Gadelha
mkBVSle(const SMTExprRef & LHS,const SMTExprRef & RHS)459db695c83SMikhail R. Gadelha SMTExprRef mkBVSle(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
460db695c83SMikhail R. Gadelha return newExprRef(
461db695c83SMikhail R. Gadelha Z3Expr(Context, Z3_mk_bvsle(Context.Context, toZ3Expr(*LHS).AST,
462db695c83SMikhail R. Gadelha toZ3Expr(*RHS).AST)));
463db695c83SMikhail R. Gadelha }
464db695c83SMikhail R. Gadelha
mkBVUge(const SMTExprRef & LHS,const SMTExprRef & RHS)465db695c83SMikhail R. Gadelha SMTExprRef mkBVUge(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
466db695c83SMikhail R. Gadelha return newExprRef(
467db695c83SMikhail R. Gadelha Z3Expr(Context, Z3_mk_bvuge(Context.Context, toZ3Expr(*LHS).AST,
468db695c83SMikhail R. Gadelha toZ3Expr(*RHS).AST)));
469db695c83SMikhail R. Gadelha }
470db695c83SMikhail R. Gadelha
mkBVSge(const SMTExprRef & LHS,const SMTExprRef & RHS)471db695c83SMikhail R. Gadelha SMTExprRef mkBVSge(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
472db695c83SMikhail R. Gadelha return newExprRef(
473db695c83SMikhail R. Gadelha Z3Expr(Context, Z3_mk_bvsge(Context.Context, toZ3Expr(*LHS).AST,
474db695c83SMikhail R. Gadelha toZ3Expr(*RHS).AST)));
475db695c83SMikhail R. Gadelha }
476db695c83SMikhail R. Gadelha
mkAnd(const SMTExprRef & LHS,const SMTExprRef & RHS)477db695c83SMikhail R. Gadelha SMTExprRef mkAnd(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
478db695c83SMikhail R. Gadelha Z3_ast Args[2] = {toZ3Expr(*LHS).AST, toZ3Expr(*RHS).AST};
479db695c83SMikhail R. Gadelha return newExprRef(Z3Expr(Context, Z3_mk_and(Context.Context, 2, Args)));
480db695c83SMikhail R. Gadelha }
481db695c83SMikhail R. Gadelha
mkOr(const SMTExprRef & LHS,const SMTExprRef & RHS)482db695c83SMikhail R. Gadelha SMTExprRef mkOr(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
483db695c83SMikhail R. Gadelha Z3_ast Args[2] = {toZ3Expr(*LHS).AST, toZ3Expr(*RHS).AST};
484db695c83SMikhail R. Gadelha return newExprRef(Z3Expr(Context, Z3_mk_or(Context.Context, 2, Args)));
485db695c83SMikhail R. Gadelha }
486db695c83SMikhail R. Gadelha
mkEqual(const SMTExprRef & LHS,const SMTExprRef & RHS)487db695c83SMikhail R. Gadelha SMTExprRef mkEqual(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
488db695c83SMikhail R. Gadelha return newExprRef(
489db695c83SMikhail R. Gadelha Z3Expr(Context, Z3_mk_eq(Context.Context, toZ3Expr(*LHS).AST,
490db695c83SMikhail R. Gadelha toZ3Expr(*RHS).AST)));
491db695c83SMikhail R. Gadelha }
492db695c83SMikhail R. Gadelha
mkFPNeg(const SMTExprRef & Exp)493db695c83SMikhail R. Gadelha SMTExprRef mkFPNeg(const SMTExprRef &Exp) override {
494db695c83SMikhail R. Gadelha return newExprRef(
495db695c83SMikhail R. Gadelha Z3Expr(Context, Z3_mk_fpa_neg(Context.Context, toZ3Expr(*Exp).AST)));
496db695c83SMikhail R. Gadelha }
497db695c83SMikhail R. Gadelha
mkFPIsInfinite(const SMTExprRef & Exp)498db695c83SMikhail R. Gadelha SMTExprRef mkFPIsInfinite(const SMTExprRef &Exp) override {
499db695c83SMikhail R. Gadelha return newExprRef(Z3Expr(
500db695c83SMikhail R. Gadelha Context, Z3_mk_fpa_is_infinite(Context.Context, toZ3Expr(*Exp).AST)));
501db695c83SMikhail R. Gadelha }
502db695c83SMikhail R. Gadelha
mkFPIsNaN(const SMTExprRef & Exp)503db695c83SMikhail R. Gadelha SMTExprRef mkFPIsNaN(const SMTExprRef &Exp) override {
504db695c83SMikhail R. Gadelha return newExprRef(
505db695c83SMikhail R. Gadelha Z3Expr(Context, Z3_mk_fpa_is_nan(Context.Context, toZ3Expr(*Exp).AST)));
506db695c83SMikhail R. Gadelha }
507db695c83SMikhail R. Gadelha
mkFPIsNormal(const SMTExprRef & Exp)508db695c83SMikhail R. Gadelha SMTExprRef mkFPIsNormal(const SMTExprRef &Exp) override {
509db695c83SMikhail R. Gadelha return newExprRef(Z3Expr(
510db695c83SMikhail R. Gadelha Context, Z3_mk_fpa_is_normal(Context.Context, toZ3Expr(*Exp).AST)));
511db695c83SMikhail R. Gadelha }
512db695c83SMikhail R. Gadelha
mkFPIsZero(const SMTExprRef & Exp)513db695c83SMikhail R. Gadelha SMTExprRef mkFPIsZero(const SMTExprRef &Exp) override {
514db695c83SMikhail R. Gadelha return newExprRef(Z3Expr(
515db695c83SMikhail R. Gadelha Context, Z3_mk_fpa_is_zero(Context.Context, toZ3Expr(*Exp).AST)));
516db695c83SMikhail R. Gadelha }
517db695c83SMikhail R. Gadelha
mkFPMul(const SMTExprRef & LHS,const SMTExprRef & RHS)518db695c83SMikhail R. Gadelha SMTExprRef mkFPMul(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
519db695c83SMikhail R. Gadelha SMTExprRef RoundingMode = getFloatRoundingMode();
520db695c83SMikhail R. Gadelha return newExprRef(
521db695c83SMikhail R. Gadelha Z3Expr(Context,
5225fc05c37SGabor Marton Z3_mk_fpa_mul(Context.Context, toZ3Expr(*RoundingMode).AST,
5235fc05c37SGabor Marton toZ3Expr(*LHS).AST, toZ3Expr(*RHS).AST)));
524db695c83SMikhail R. Gadelha }
525db695c83SMikhail R. Gadelha
mkFPDiv(const SMTExprRef & LHS,const SMTExprRef & RHS)526db695c83SMikhail R. Gadelha SMTExprRef mkFPDiv(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
527db695c83SMikhail R. Gadelha SMTExprRef RoundingMode = getFloatRoundingMode();
528db695c83SMikhail R. Gadelha return newExprRef(
529db695c83SMikhail R. Gadelha Z3Expr(Context,
5305fc05c37SGabor Marton Z3_mk_fpa_div(Context.Context, toZ3Expr(*RoundingMode).AST,
5315fc05c37SGabor Marton toZ3Expr(*LHS).AST, toZ3Expr(*RHS).AST)));
532db695c83SMikhail R. Gadelha }
533db695c83SMikhail R. Gadelha
mkFPRem(const SMTExprRef & LHS,const SMTExprRef & RHS)534db695c83SMikhail R. Gadelha SMTExprRef mkFPRem(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
535db695c83SMikhail R. Gadelha return newExprRef(
536db695c83SMikhail R. Gadelha Z3Expr(Context, Z3_mk_fpa_rem(Context.Context, toZ3Expr(*LHS).AST,
537db695c83SMikhail R. Gadelha toZ3Expr(*RHS).AST)));
538db695c83SMikhail R. Gadelha }
539db695c83SMikhail R. Gadelha
mkFPAdd(const SMTExprRef & LHS,const SMTExprRef & RHS)540db695c83SMikhail R. Gadelha SMTExprRef mkFPAdd(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
541db695c83SMikhail R. Gadelha SMTExprRef RoundingMode = getFloatRoundingMode();
542db695c83SMikhail R. Gadelha return newExprRef(
543db695c83SMikhail R. Gadelha Z3Expr(Context,
5445fc05c37SGabor Marton Z3_mk_fpa_add(Context.Context, toZ3Expr(*RoundingMode).AST,
5455fc05c37SGabor Marton toZ3Expr(*LHS).AST, toZ3Expr(*RHS).AST)));
546db695c83SMikhail R. Gadelha }
547db695c83SMikhail R. Gadelha
mkFPSub(const SMTExprRef & LHS,const SMTExprRef & RHS)548db695c83SMikhail R. Gadelha SMTExprRef mkFPSub(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
549db695c83SMikhail R. Gadelha SMTExprRef RoundingMode = getFloatRoundingMode();
550db695c83SMikhail R. Gadelha return newExprRef(
551db695c83SMikhail R. Gadelha Z3Expr(Context,
5525fc05c37SGabor Marton Z3_mk_fpa_sub(Context.Context, toZ3Expr(*RoundingMode).AST,
5535fc05c37SGabor Marton toZ3Expr(*LHS).AST, toZ3Expr(*RHS).AST)));
554db695c83SMikhail R. Gadelha }
555db695c83SMikhail R. Gadelha
mkFPLt(const SMTExprRef & LHS,const SMTExprRef & RHS)556db695c83SMikhail R. Gadelha SMTExprRef mkFPLt(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
557db695c83SMikhail R. Gadelha return newExprRef(
558db695c83SMikhail R. Gadelha Z3Expr(Context, Z3_mk_fpa_lt(Context.Context, toZ3Expr(*LHS).AST,
559db695c83SMikhail R. Gadelha toZ3Expr(*RHS).AST)));
560db695c83SMikhail R. Gadelha }
561db695c83SMikhail R. Gadelha
mkFPGt(const SMTExprRef & LHS,const SMTExprRef & RHS)562db695c83SMikhail R. Gadelha SMTExprRef mkFPGt(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
563db695c83SMikhail R. Gadelha return newExprRef(
564db695c83SMikhail R. Gadelha Z3Expr(Context, Z3_mk_fpa_gt(Context.Context, toZ3Expr(*LHS).AST,
565db695c83SMikhail R. Gadelha toZ3Expr(*RHS).AST)));
566db695c83SMikhail R. Gadelha }
567db695c83SMikhail R. Gadelha
mkFPLe(const SMTExprRef & LHS,const SMTExprRef & RHS)568db695c83SMikhail R. Gadelha SMTExprRef mkFPLe(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
569db695c83SMikhail R. Gadelha return newExprRef(
570db695c83SMikhail R. Gadelha Z3Expr(Context, Z3_mk_fpa_leq(Context.Context, toZ3Expr(*LHS).AST,
571db695c83SMikhail R. Gadelha toZ3Expr(*RHS).AST)));
572db695c83SMikhail R. Gadelha }
573db695c83SMikhail R. Gadelha
mkFPGe(const SMTExprRef & LHS,const SMTExprRef & RHS)574db695c83SMikhail R. Gadelha SMTExprRef mkFPGe(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
575db695c83SMikhail R. Gadelha return newExprRef(
576db695c83SMikhail R. Gadelha Z3Expr(Context, Z3_mk_fpa_geq(Context.Context, toZ3Expr(*LHS).AST,
577db695c83SMikhail R. Gadelha toZ3Expr(*RHS).AST)));
578db695c83SMikhail R. Gadelha }
579db695c83SMikhail R. Gadelha
mkFPEqual(const SMTExprRef & LHS,const SMTExprRef & RHS)580db695c83SMikhail R. Gadelha SMTExprRef mkFPEqual(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
581db695c83SMikhail R. Gadelha return newExprRef(
582db695c83SMikhail R. Gadelha Z3Expr(Context, Z3_mk_fpa_eq(Context.Context, toZ3Expr(*LHS).AST,
583db695c83SMikhail R. Gadelha toZ3Expr(*RHS).AST)));
584db695c83SMikhail R. Gadelha }
585db695c83SMikhail R. Gadelha
mkIte(const SMTExprRef & Cond,const SMTExprRef & T,const SMTExprRef & F)586db695c83SMikhail R. Gadelha SMTExprRef mkIte(const SMTExprRef &Cond, const SMTExprRef &T,
587db695c83SMikhail R. Gadelha const SMTExprRef &F) override {
588db695c83SMikhail R. Gadelha return newExprRef(
589db695c83SMikhail R. Gadelha Z3Expr(Context, Z3_mk_ite(Context.Context, toZ3Expr(*Cond).AST,
590db695c83SMikhail R. Gadelha toZ3Expr(*T).AST, toZ3Expr(*F).AST)));
591db695c83SMikhail R. Gadelha }
592db695c83SMikhail R. Gadelha
mkBVSignExt(unsigned i,const SMTExprRef & Exp)593db695c83SMikhail R. Gadelha SMTExprRef mkBVSignExt(unsigned i, const SMTExprRef &Exp) override {
594db695c83SMikhail R. Gadelha return newExprRef(Z3Expr(
595db695c83SMikhail R. Gadelha Context, Z3_mk_sign_ext(Context.Context, i, toZ3Expr(*Exp).AST)));
596db695c83SMikhail R. Gadelha }
597db695c83SMikhail R. Gadelha
mkBVZeroExt(unsigned i,const SMTExprRef & Exp)598db695c83SMikhail R. Gadelha SMTExprRef mkBVZeroExt(unsigned i, const SMTExprRef &Exp) override {
599db695c83SMikhail R. Gadelha return newExprRef(Z3Expr(
600db695c83SMikhail R. Gadelha Context, Z3_mk_zero_ext(Context.Context, i, toZ3Expr(*Exp).AST)));
601db695c83SMikhail R. Gadelha }
602db695c83SMikhail R. Gadelha
mkBVExtract(unsigned High,unsigned Low,const SMTExprRef & Exp)603db695c83SMikhail R. Gadelha SMTExprRef mkBVExtract(unsigned High, unsigned Low,
604db695c83SMikhail R. Gadelha const SMTExprRef &Exp) override {
605db695c83SMikhail R. Gadelha return newExprRef(Z3Expr(Context, Z3_mk_extract(Context.Context, High, Low,
606db695c83SMikhail R. Gadelha toZ3Expr(*Exp).AST)));
607db695c83SMikhail R. Gadelha }
608db695c83SMikhail R. Gadelha
609f5f8d27dSMikhail R. Gadelha /// Creates a predicate that checks for overflow in a bitvector addition
610f5f8d27dSMikhail R. Gadelha /// operation
mkBVAddNoOverflow(const SMTExprRef & LHS,const SMTExprRef & RHS,bool isSigned)611f5f8d27dSMikhail R. Gadelha SMTExprRef mkBVAddNoOverflow(const SMTExprRef &LHS, const SMTExprRef &RHS,
612f5f8d27dSMikhail R. Gadelha bool isSigned) override {
613f5f8d27dSMikhail R. Gadelha return newExprRef(Z3Expr(
614f5f8d27dSMikhail R. Gadelha Context, Z3_mk_bvadd_no_overflow(Context.Context, toZ3Expr(*LHS).AST,
615f5f8d27dSMikhail R. Gadelha toZ3Expr(*RHS).AST, isSigned)));
616f5f8d27dSMikhail R. Gadelha }
617f5f8d27dSMikhail R. Gadelha
618f5f8d27dSMikhail R. Gadelha /// Creates a predicate that checks for underflow in a signed bitvector
619f5f8d27dSMikhail R. Gadelha /// addition operation
mkBVAddNoUnderflow(const SMTExprRef & LHS,const SMTExprRef & RHS)620f5f8d27dSMikhail R. Gadelha SMTExprRef mkBVAddNoUnderflow(const SMTExprRef &LHS,
621f5f8d27dSMikhail R. Gadelha const SMTExprRef &RHS) override {
622f5f8d27dSMikhail R. Gadelha return newExprRef(Z3Expr(
623f5f8d27dSMikhail R. Gadelha Context, Z3_mk_bvadd_no_underflow(Context.Context, toZ3Expr(*LHS).AST,
624f5f8d27dSMikhail R. Gadelha toZ3Expr(*RHS).AST)));
625f5f8d27dSMikhail R. Gadelha }
626f5f8d27dSMikhail R. Gadelha
627f5f8d27dSMikhail R. Gadelha /// Creates a predicate that checks for overflow in a signed bitvector
628f5f8d27dSMikhail R. Gadelha /// subtraction operation
mkBVSubNoOverflow(const SMTExprRef & LHS,const SMTExprRef & RHS)629f5f8d27dSMikhail R. Gadelha SMTExprRef mkBVSubNoOverflow(const SMTExprRef &LHS,
630f5f8d27dSMikhail R. Gadelha const SMTExprRef &RHS) override {
631f5f8d27dSMikhail R. Gadelha return newExprRef(Z3Expr(
632f5f8d27dSMikhail R. Gadelha Context, Z3_mk_bvsub_no_overflow(Context.Context, toZ3Expr(*LHS).AST,
633f5f8d27dSMikhail R. Gadelha toZ3Expr(*RHS).AST)));
634f5f8d27dSMikhail R. Gadelha }
635f5f8d27dSMikhail R. Gadelha
636f5f8d27dSMikhail R. Gadelha /// Creates a predicate that checks for underflow in a bitvector subtraction
637f5f8d27dSMikhail R. Gadelha /// operation
mkBVSubNoUnderflow(const SMTExprRef & LHS,const SMTExprRef & RHS,bool isSigned)638f5f8d27dSMikhail R. Gadelha SMTExprRef mkBVSubNoUnderflow(const SMTExprRef &LHS, const SMTExprRef &RHS,
639f5f8d27dSMikhail R. Gadelha bool isSigned) override {
640f5f8d27dSMikhail R. Gadelha return newExprRef(Z3Expr(
641f5f8d27dSMikhail R. Gadelha Context, Z3_mk_bvsub_no_underflow(Context.Context, toZ3Expr(*LHS).AST,
642f5f8d27dSMikhail R. Gadelha toZ3Expr(*RHS).AST, isSigned)));
643f5f8d27dSMikhail R. Gadelha }
644f5f8d27dSMikhail R. Gadelha
645f5f8d27dSMikhail R. Gadelha /// Creates a predicate that checks for overflow in a signed bitvector
646f5f8d27dSMikhail R. Gadelha /// division/modulus operation
mkBVSDivNoOverflow(const SMTExprRef & LHS,const SMTExprRef & RHS)647f5f8d27dSMikhail R. Gadelha SMTExprRef mkBVSDivNoOverflow(const SMTExprRef &LHS,
648f5f8d27dSMikhail R. Gadelha const SMTExprRef &RHS) override {
649f5f8d27dSMikhail R. Gadelha return newExprRef(Z3Expr(
650f5f8d27dSMikhail R. Gadelha Context, Z3_mk_bvsdiv_no_overflow(Context.Context, toZ3Expr(*LHS).AST,
651f5f8d27dSMikhail R. Gadelha toZ3Expr(*RHS).AST)));
652f5f8d27dSMikhail R. Gadelha }
653f5f8d27dSMikhail R. Gadelha
654f5f8d27dSMikhail R. Gadelha /// Creates a predicate that checks for overflow in a bitvector negation
655f5f8d27dSMikhail R. Gadelha /// operation
mkBVNegNoOverflow(const SMTExprRef & Exp)656f5f8d27dSMikhail R. Gadelha SMTExprRef mkBVNegNoOverflow(const SMTExprRef &Exp) override {
657f5f8d27dSMikhail R. Gadelha return newExprRef(Z3Expr(
658f5f8d27dSMikhail R. Gadelha Context, Z3_mk_bvneg_no_overflow(Context.Context, toZ3Expr(*Exp).AST)));
659f5f8d27dSMikhail R. Gadelha }
660f5f8d27dSMikhail R. Gadelha
661f5f8d27dSMikhail R. Gadelha /// Creates a predicate that checks for overflow in a bitvector multiplication
662f5f8d27dSMikhail R. Gadelha /// operation
mkBVMulNoOverflow(const SMTExprRef & LHS,const SMTExprRef & RHS,bool isSigned)663f5f8d27dSMikhail R. Gadelha SMTExprRef mkBVMulNoOverflow(const SMTExprRef &LHS, const SMTExprRef &RHS,
664f5f8d27dSMikhail R. Gadelha bool isSigned) override {
665f5f8d27dSMikhail R. Gadelha return newExprRef(Z3Expr(
666f5f8d27dSMikhail R. Gadelha Context, Z3_mk_bvmul_no_overflow(Context.Context, toZ3Expr(*LHS).AST,
667f5f8d27dSMikhail R. Gadelha toZ3Expr(*RHS).AST, isSigned)));
668f5f8d27dSMikhail R. Gadelha }
669f5f8d27dSMikhail R. Gadelha
670f5f8d27dSMikhail R. Gadelha /// Creates a predicate that checks for underflow in a signed bitvector
671f5f8d27dSMikhail R. Gadelha /// multiplication operation
mkBVMulNoUnderflow(const SMTExprRef & LHS,const SMTExprRef & RHS)672f5f8d27dSMikhail R. Gadelha SMTExprRef mkBVMulNoUnderflow(const SMTExprRef &LHS,
673f5f8d27dSMikhail R. Gadelha const SMTExprRef &RHS) override {
674f5f8d27dSMikhail R. Gadelha return newExprRef(Z3Expr(
675f5f8d27dSMikhail R. Gadelha Context, Z3_mk_bvmul_no_underflow(Context.Context, toZ3Expr(*LHS).AST,
676f5f8d27dSMikhail R. Gadelha toZ3Expr(*RHS).AST)));
677f5f8d27dSMikhail R. Gadelha }
678f5f8d27dSMikhail R. Gadelha
mkBVConcat(const SMTExprRef & LHS,const SMTExprRef & RHS)679db695c83SMikhail R. Gadelha SMTExprRef mkBVConcat(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
680db695c83SMikhail R. Gadelha return newExprRef(
681db695c83SMikhail R. Gadelha Z3Expr(Context, Z3_mk_concat(Context.Context, toZ3Expr(*LHS).AST,
682db695c83SMikhail R. Gadelha toZ3Expr(*RHS).AST)));
683db695c83SMikhail R. Gadelha }
684db695c83SMikhail R. Gadelha
mkFPtoFP(const SMTExprRef & From,const SMTSortRef & To)685db695c83SMikhail R. Gadelha SMTExprRef mkFPtoFP(const SMTExprRef &From, const SMTSortRef &To) override {
686db695c83SMikhail R. Gadelha SMTExprRef RoundingMode = getFloatRoundingMode();
687db695c83SMikhail R. Gadelha return newExprRef(Z3Expr(
688db695c83SMikhail R. Gadelha Context,
689db695c83SMikhail R. Gadelha Z3_mk_fpa_to_fp_float(Context.Context, toZ3Expr(*RoundingMode).AST,
690db695c83SMikhail R. Gadelha toZ3Expr(*From).AST, toZ3Sort(*To).Sort)));
691db695c83SMikhail R. Gadelha }
692db695c83SMikhail R. Gadelha
mkSBVtoFP(const SMTExprRef & From,const SMTSortRef & To)693db695c83SMikhail R. Gadelha SMTExprRef mkSBVtoFP(const SMTExprRef &From, const SMTSortRef &To) override {
694db695c83SMikhail R. Gadelha SMTExprRef RoundingMode = getFloatRoundingMode();
695db695c83SMikhail R. Gadelha return newExprRef(Z3Expr(
696db695c83SMikhail R. Gadelha Context,
697db695c83SMikhail R. Gadelha Z3_mk_fpa_to_fp_signed(Context.Context, toZ3Expr(*RoundingMode).AST,
698db695c83SMikhail R. Gadelha toZ3Expr(*From).AST, toZ3Sort(*To).Sort)));
699db695c83SMikhail R. Gadelha }
700db695c83SMikhail R. Gadelha
mkUBVtoFP(const SMTExprRef & From,const SMTSortRef & To)701db695c83SMikhail R. Gadelha SMTExprRef mkUBVtoFP(const SMTExprRef &From, const SMTSortRef &To) override {
702db695c83SMikhail R. Gadelha SMTExprRef RoundingMode = getFloatRoundingMode();
703db695c83SMikhail R. Gadelha return newExprRef(Z3Expr(
704db695c83SMikhail R. Gadelha Context,
705db695c83SMikhail R. Gadelha Z3_mk_fpa_to_fp_unsigned(Context.Context, toZ3Expr(*RoundingMode).AST,
706db695c83SMikhail R. Gadelha toZ3Expr(*From).AST, toZ3Sort(*To).Sort)));
707db695c83SMikhail R. Gadelha }
708db695c83SMikhail R. Gadelha
mkFPtoSBV(const SMTExprRef & From,unsigned ToWidth)709db695c83SMikhail R. Gadelha SMTExprRef mkFPtoSBV(const SMTExprRef &From, unsigned ToWidth) override {
710db695c83SMikhail R. Gadelha SMTExprRef RoundingMode = getFloatRoundingMode();
711db695c83SMikhail R. Gadelha return newExprRef(Z3Expr(
712db695c83SMikhail R. Gadelha Context, Z3_mk_fpa_to_sbv(Context.Context, toZ3Expr(*RoundingMode).AST,
713db695c83SMikhail R. Gadelha toZ3Expr(*From).AST, ToWidth)));
714db695c83SMikhail R. Gadelha }
715db695c83SMikhail R. Gadelha
mkFPtoUBV(const SMTExprRef & From,unsigned ToWidth)716db695c83SMikhail R. Gadelha SMTExprRef mkFPtoUBV(const SMTExprRef &From, unsigned ToWidth) override {
717db695c83SMikhail R. Gadelha SMTExprRef RoundingMode = getFloatRoundingMode();
718db695c83SMikhail R. Gadelha return newExprRef(Z3Expr(
719db695c83SMikhail R. Gadelha Context, Z3_mk_fpa_to_ubv(Context.Context, toZ3Expr(*RoundingMode).AST,
720db695c83SMikhail R. Gadelha toZ3Expr(*From).AST, ToWidth)));
721db695c83SMikhail R. Gadelha }
722db695c83SMikhail R. Gadelha
mkBoolean(const bool b)723db695c83SMikhail R. Gadelha SMTExprRef mkBoolean(const bool b) override {
724db695c83SMikhail R. Gadelha return newExprRef(Z3Expr(Context, b ? Z3_mk_true(Context.Context)
725db695c83SMikhail R. Gadelha : Z3_mk_false(Context.Context)));
726db695c83SMikhail R. Gadelha }
727db695c83SMikhail R. Gadelha
mkBitvector(const llvm::APSInt Int,unsigned BitWidth)728db695c83SMikhail R. Gadelha SMTExprRef mkBitvector(const llvm::APSInt Int, unsigned BitWidth) override {
729815a8100SBalazs Benics const Z3_sort Z3Sort = toZ3Sort(*getBitvectorSort(BitWidth)).Sort;
730815a8100SBalazs Benics
731815a8100SBalazs Benics // Slow path, when 64 bits are not enough.
732815a8100SBalazs Benics if (LLVM_UNLIKELY(Int.getBitWidth() > 64u)) {
733815a8100SBalazs Benics SmallString<40> Buffer;
734815a8100SBalazs Benics Int.toString(Buffer, 10);
735815a8100SBalazs Benics return newExprRef(Z3Expr(
736815a8100SBalazs Benics Context, Z3_mk_numeral(Context.Context, Buffer.c_str(), Z3Sort)));
737815a8100SBalazs Benics }
738815a8100SBalazs Benics
739815a8100SBalazs Benics const int64_t BitReprAsSigned = Int.getExtValue();
740815a8100SBalazs Benics const uint64_t BitReprAsUnsigned =
741815a8100SBalazs Benics reinterpret_cast<const uint64_t &>(BitReprAsSigned);
742815a8100SBalazs Benics
743815a8100SBalazs Benics Z3_ast Literal =
744815a8100SBalazs Benics Int.isSigned()
745815a8100SBalazs Benics ? Z3_mk_int64(Context.Context, BitReprAsSigned, Z3Sort)
746815a8100SBalazs Benics : Z3_mk_unsigned_int64(Context.Context, BitReprAsUnsigned, Z3Sort);
747815a8100SBalazs Benics return newExprRef(Z3Expr(Context, Literal));
748db695c83SMikhail R. Gadelha }
749db695c83SMikhail R. Gadelha
mkFloat(const llvm::APFloat Float)750db695c83SMikhail R. Gadelha SMTExprRef mkFloat(const llvm::APFloat Float) override {
751db695c83SMikhail R. Gadelha SMTSortRef Sort =
752db695c83SMikhail R. Gadelha getFloatSort(llvm::APFloat::semanticsSizeInBits(Float.getSemantics()));
753db695c83SMikhail R. Gadelha
754db695c83SMikhail R. Gadelha llvm::APSInt Int = llvm::APSInt(Float.bitcastToAPInt(), false);
755db695c83SMikhail R. Gadelha SMTExprRef Z3Int = mkBitvector(Int, Int.getBitWidth());
756db695c83SMikhail R. Gadelha return newExprRef(Z3Expr(
757db695c83SMikhail R. Gadelha Context, Z3_mk_fpa_to_fp_bv(Context.Context, toZ3Expr(*Z3Int).AST,
758db695c83SMikhail R. Gadelha toZ3Sort(*Sort).Sort)));
759db695c83SMikhail R. Gadelha }
760db695c83SMikhail R. Gadelha
mkSymbol(const char * Name,SMTSortRef Sort)761db695c83SMikhail R. Gadelha SMTExprRef mkSymbol(const char *Name, SMTSortRef Sort) override {
762db695c83SMikhail R. Gadelha return newExprRef(
763db695c83SMikhail R. Gadelha Z3Expr(Context, Z3_mk_const(Context.Context,
764db695c83SMikhail R. Gadelha Z3_mk_string_symbol(Context.Context, Name),
765db695c83SMikhail R. Gadelha toZ3Sort(*Sort).Sort)));
766db695c83SMikhail R. Gadelha }
767db695c83SMikhail R. Gadelha
getBitvector(const SMTExprRef & Exp,unsigned BitWidth,bool isUnsigned)768db695c83SMikhail R. Gadelha llvm::APSInt getBitvector(const SMTExprRef &Exp, unsigned BitWidth,
769db695c83SMikhail R. Gadelha bool isUnsigned) override {
770db695c83SMikhail R. Gadelha return llvm::APSInt(
771db695c83SMikhail R. Gadelha llvm::APInt(BitWidth,
772db695c83SMikhail R. Gadelha Z3_get_numeral_string(Context.Context, toZ3Expr(*Exp).AST),
773db695c83SMikhail R. Gadelha 10),
774db695c83SMikhail R. Gadelha isUnsigned);
775db695c83SMikhail R. Gadelha }
776db695c83SMikhail R. Gadelha
getBoolean(const SMTExprRef & Exp)777db695c83SMikhail R. Gadelha bool getBoolean(const SMTExprRef &Exp) override {
778db695c83SMikhail R. Gadelha return Z3_get_bool_value(Context.Context, toZ3Expr(*Exp).AST) == Z3_L_TRUE;
779db695c83SMikhail R. Gadelha }
780db695c83SMikhail R. Gadelha
getFloatRoundingMode()781db695c83SMikhail R. Gadelha SMTExprRef getFloatRoundingMode() override {
782db695c83SMikhail R. Gadelha // TODO: Don't assume nearest ties to even rounding mode
783db695c83SMikhail R. Gadelha return newExprRef(Z3Expr(Context, Z3_mk_fpa_rne(Context.Context)));
784db695c83SMikhail R. Gadelha }
785db695c83SMikhail R. Gadelha
toAPFloat(const SMTSortRef & Sort,const SMTExprRef & AST,llvm::APFloat & Float,bool useSemantics)786db695c83SMikhail R. Gadelha bool toAPFloat(const SMTSortRef &Sort, const SMTExprRef &AST,
787db695c83SMikhail R. Gadelha llvm::APFloat &Float, bool useSemantics) {
788db695c83SMikhail R. Gadelha assert(Sort->isFloatSort() && "Unsupported sort to floating-point!");
789db695c83SMikhail R. Gadelha
790db695c83SMikhail R. Gadelha llvm::APSInt Int(Sort->getFloatSortSize(), true);
791db695c83SMikhail R. Gadelha const llvm::fltSemantics &Semantics =
792db695c83SMikhail R. Gadelha getFloatSemantics(Sort->getFloatSortSize());
793db695c83SMikhail R. Gadelha SMTSortRef BVSort = getBitvectorSort(Sort->getFloatSortSize());
794db695c83SMikhail R. Gadelha if (!toAPSInt(BVSort, AST, Int, true)) {
795db695c83SMikhail R. Gadelha return false;
796db695c83SMikhail R. Gadelha }
797db695c83SMikhail R. Gadelha
798db695c83SMikhail R. Gadelha if (useSemantics && !areEquivalent(Float.getSemantics(), Semantics)) {
799db695c83SMikhail R. Gadelha assert(false && "Floating-point types don't match!");
800db695c83SMikhail R. Gadelha return false;
801db695c83SMikhail R. Gadelha }
802db695c83SMikhail R. Gadelha
803db695c83SMikhail R. Gadelha Float = llvm::APFloat(Semantics, Int);
804db695c83SMikhail R. Gadelha return true;
805db695c83SMikhail R. Gadelha }
806db695c83SMikhail R. Gadelha
toAPSInt(const SMTSortRef & Sort,const SMTExprRef & AST,llvm::APSInt & Int,bool useSemantics)807db695c83SMikhail R. Gadelha bool toAPSInt(const SMTSortRef &Sort, const SMTExprRef &AST,
808db695c83SMikhail R. Gadelha llvm::APSInt &Int, bool useSemantics) {
809db695c83SMikhail R. Gadelha if (Sort->isBitvectorSort()) {
810db695c83SMikhail R. Gadelha if (useSemantics && Int.getBitWidth() != Sort->getBitvectorSortSize()) {
811db695c83SMikhail R. Gadelha assert(false && "Bitvector types don't match!");
812db695c83SMikhail R. Gadelha return false;
813db695c83SMikhail R. Gadelha }
814db695c83SMikhail R. Gadelha
815db695c83SMikhail R. Gadelha // FIXME: This function is also used to retrieve floating-point values,
816db695c83SMikhail R. Gadelha // which can be 16, 32, 64 or 128 bits long. Bitvectors can be anything
817db695c83SMikhail R. Gadelha // between 1 and 64 bits long, which is the reason we have this weird
818db695c83SMikhail R. Gadelha // guard. In the future, we need proper calls in the backend to retrieve
819db695c83SMikhail R. Gadelha // floating-points and its special values (NaN, +/-infinity, +/-zero),
820db695c83SMikhail R. Gadelha // then we can drop this weird condition.
821db695c83SMikhail R. Gadelha if (Sort->getBitvectorSortSize() <= 64 ||
822db695c83SMikhail R. Gadelha Sort->getBitvectorSortSize() == 128) {
823db695c83SMikhail R. Gadelha Int = getBitvector(AST, Int.getBitWidth(), Int.isUnsigned());
824db695c83SMikhail R. Gadelha return true;
825db695c83SMikhail R. Gadelha }
826db695c83SMikhail R. Gadelha
827db695c83SMikhail R. Gadelha assert(false && "Bitwidth not supported!");
828db695c83SMikhail R. Gadelha return false;
829db695c83SMikhail R. Gadelha }
830db695c83SMikhail R. Gadelha
831db695c83SMikhail R. Gadelha if (Sort->isBooleanSort()) {
832db695c83SMikhail R. Gadelha if (useSemantics && Int.getBitWidth() < 1) {
833db695c83SMikhail R. Gadelha assert(false && "Boolean type doesn't match!");
834db695c83SMikhail R. Gadelha return false;
835db695c83SMikhail R. Gadelha }
836db695c83SMikhail R. Gadelha
837db695c83SMikhail R. Gadelha Int = llvm::APSInt(llvm::APInt(Int.getBitWidth(), getBoolean(AST)),
838db695c83SMikhail R. Gadelha Int.isUnsigned());
839db695c83SMikhail R. Gadelha return true;
840db695c83SMikhail R. Gadelha }
841db695c83SMikhail R. Gadelha
842db695c83SMikhail R. Gadelha llvm_unreachable("Unsupported sort to integer!");
843db695c83SMikhail R. Gadelha }
844db695c83SMikhail R. Gadelha
getInterpretation(const SMTExprRef & Exp,llvm::APSInt & Int)845db695c83SMikhail R. Gadelha bool getInterpretation(const SMTExprRef &Exp, llvm::APSInt &Int) override {
846db695c83SMikhail R. Gadelha Z3Model Model(Context, Z3_solver_get_model(Context.Context, Solver));
847db695c83SMikhail R. Gadelha Z3_func_decl Func = Z3_get_app_decl(
848db695c83SMikhail R. Gadelha Context.Context, Z3_to_app(Context.Context, toZ3Expr(*Exp).AST));
849db695c83SMikhail R. Gadelha if (Z3_model_has_interp(Context.Context, Model.Model, Func) != Z3_L_TRUE)
850db695c83SMikhail R. Gadelha return false;
851db695c83SMikhail R. Gadelha
852db695c83SMikhail R. Gadelha SMTExprRef Assign = newExprRef(
853db695c83SMikhail R. Gadelha Z3Expr(Context,
854db695c83SMikhail R. Gadelha Z3_model_get_const_interp(Context.Context, Model.Model, Func)));
855db695c83SMikhail R. Gadelha SMTSortRef Sort = getSort(Assign);
856db695c83SMikhail R. Gadelha return toAPSInt(Sort, Assign, Int, true);
857db695c83SMikhail R. Gadelha }
858db695c83SMikhail R. Gadelha
getInterpretation(const SMTExprRef & Exp,llvm::APFloat & Float)859db695c83SMikhail R. Gadelha bool getInterpretation(const SMTExprRef &Exp, llvm::APFloat &Float) override {
860db695c83SMikhail R. Gadelha Z3Model Model(Context, Z3_solver_get_model(Context.Context, Solver));
861db695c83SMikhail R. Gadelha Z3_func_decl Func = Z3_get_app_decl(
862db695c83SMikhail R. Gadelha Context.Context, Z3_to_app(Context.Context, toZ3Expr(*Exp).AST));
863db695c83SMikhail R. Gadelha if (Z3_model_has_interp(Context.Context, Model.Model, Func) != Z3_L_TRUE)
864db695c83SMikhail R. Gadelha return false;
865db695c83SMikhail R. Gadelha
866db695c83SMikhail R. Gadelha SMTExprRef Assign = newExprRef(
867db695c83SMikhail R. Gadelha Z3Expr(Context,
868db695c83SMikhail R. Gadelha Z3_model_get_const_interp(Context.Context, Model.Model, Func)));
869db695c83SMikhail R. Gadelha SMTSortRef Sort = getSort(Assign);
870db695c83SMikhail R. Gadelha return toAPFloat(Sort, Assign, Float, true);
871db695c83SMikhail R. Gadelha }
872db695c83SMikhail R. Gadelha
check() const873db695c83SMikhail R. Gadelha Optional<bool> check() const override {
874db695c83SMikhail R. Gadelha Z3_lbool res = Z3_solver_check(Context.Context, Solver);
875db695c83SMikhail R. Gadelha if (res == Z3_L_TRUE)
876db695c83SMikhail R. Gadelha return true;
877db695c83SMikhail R. Gadelha
878db695c83SMikhail R. Gadelha if (res == Z3_L_FALSE)
879db695c83SMikhail R. Gadelha return false;
880db695c83SMikhail R. Gadelha
881db695c83SMikhail R. Gadelha return Optional<bool>();
882db695c83SMikhail R. Gadelha }
883db695c83SMikhail R. Gadelha
push()884db695c83SMikhail R. Gadelha void push() override { return Z3_solver_push(Context.Context, Solver); }
885db695c83SMikhail R. Gadelha
pop(unsigned NumStates=1)886db695c83SMikhail R. Gadelha void pop(unsigned NumStates = 1) override {
887db695c83SMikhail R. Gadelha assert(Z3_solver_get_num_scopes(Context.Context, Solver) >= NumStates);
888db695c83SMikhail R. Gadelha return Z3_solver_pop(Context.Context, Solver, NumStates);
889db695c83SMikhail R. Gadelha }
890db695c83SMikhail R. Gadelha
isFPSupported()891db695c83SMikhail R. Gadelha bool isFPSupported() override { return true; }
892db695c83SMikhail R. Gadelha
893db695c83SMikhail R. Gadelha /// Reset the solver and remove all constraints.
reset()894db695c83SMikhail R. Gadelha void reset() override { Z3_solver_reset(Context.Context, Solver); }
895db695c83SMikhail R. Gadelha
print(raw_ostream & OS) const896db695c83SMikhail R. Gadelha void print(raw_ostream &OS) const override {
897db695c83SMikhail R. Gadelha OS << Z3_solver_to_string(Context.Context, Solver);
898db695c83SMikhail R. Gadelha }
899db695c83SMikhail R. Gadelha }; // end class Z3Solver
900db695c83SMikhail R. Gadelha
901db695c83SMikhail R. Gadelha } // end anonymous namespace
902db695c83SMikhail R. Gadelha
903db695c83SMikhail R. Gadelha #endif
904db695c83SMikhail R. Gadelha
CreateZ3Solver()905db695c83SMikhail R. Gadelha llvm::SMTSolverRef llvm::CreateZ3Solver() {
906db695c83SMikhail R. Gadelha #if LLVM_WITH_Z3
9070eaee545SJonas Devlieghere return std::make_unique<Z3Solver>();
908db695c83SMikhail R. Gadelha #else
909db695c83SMikhail R. Gadelha llvm::report_fatal_error("LLVM was not compiled with Z3 support, rebuild "
910db695c83SMikhail R. Gadelha "with -DLLVM_ENABLE_Z3_SOLVER=ON",
911db695c83SMikhail R. Gadelha false);
912db695c83SMikhail R. Gadelha return nullptr;
913db695c83SMikhail R. Gadelha #endif
914db695c83SMikhail R. Gadelha }
91525f9094dSMikhail R. Gadelha
dump() const91625f9094dSMikhail R. Gadelha LLVM_DUMP_METHOD void SMTSort::dump() const { print(llvm::errs()); }
dump() const91725f9094dSMikhail R. Gadelha LLVM_DUMP_METHOD void SMTExpr::dump() const { print(llvm::errs()); }
dump() const91825f9094dSMikhail R. Gadelha LLVM_DUMP_METHOD void SMTSolver::dump() const { print(llvm::errs()); }
919