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