1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
/*++
Copyright (c) 2012 Microsoft Corporation
Module Name:
nlsat_solver.h
Abstract:
Nonlinear arithmetic satisfiability procedure. The procedure is
complete for nonlinear real arithmetic, but it also has limited
support for integers.
Author:
Leonardo de Moura (leonardo) 2012-01-02.
Revision History:
--*/
#pragma once
#include "nlsat/nlsat_types.h"
#include "util/params.h"
#include "util/statistics.h"
#include "util/rlimit.h"
#include "util/dependency.h"
namespace nlsat {
class evaluator;
class explain;
class display_assumption_proc {
public:
virtual ~display_assumption_proc() = default;
virtual std::ostream& operator()(std::ostream& out, assumption a) const = 0;
};
struct bound_constraint {
var x;
polynomial_ref A, B;
bool is_strict;
clause* c;
bound_constraint(var x, polynomial_ref& A, polynomial_ref& B, bool is_strict, clause* c) :
x(x), A(A), B(B), is_strict(is_strict), c(c) {}
};
class solver {
struct imp;
struct ctx;
imp * m_imp;
ctx * m_ctx;
solver(ctx& c);
public:
solver(reslimit& rlim, params_ref const & p, bool incremental);
~solver();
/**
\brief Return reference to rational manager.
*/
unsynch_mpq_manager & qm();
/**
\brief Return reference to algebraic number manager.
*/
anum_manager & am();
/**
\brief Return a reference to the polynomial manager used by the solver.
*/
pmanager & pm();
void set_display_var(display_var_proc const & proc);
void set_display_assumption(display_assumption_proc const& proc);
// -----------------------
//
// Variable, Atoms, Clauses & Assumption creation
//
// -----------------------
/**
\brief Create a fresh boolean variable that is not associated with any
nonlinear arithmetic atom.
*/
bool_var mk_bool_var();
literal mk_true();
/**
\brief Create a real/integer variable.
*/
var mk_var(bool is_int);
/**
\brief Create an atom of the form: p=0, p<0, p>0
Where p = ps[0]^e[0]*...*ps[sz-1]^e[sz-1]
e[i] = 1 if is_even[i] is false
e[i] = 2 if is_even[i] is true
\pre sz > 0
*/
bool_var mk_ineq_atom(atom::kind k, unsigned sz, poly * const * ps, bool const * is_even);
/**
\brief Create a literal for the p=0, p<0, p>0.
Where p = ps[0]^e[0]*...*ps[sz-1]^e[sz-1] for sz > 0
p = 1 for sz = 0
e[i] = 1 if is_even[i] is false
e[i] = 2 if is_even[i] is true
*/
literal mk_ineq_literal(atom::kind k, unsigned sz, poly * const * ps, bool const * is_even, bool simplify = false);
/**
\brief Create an atom of the form: x=root[i](p), x<root[i](p), x>root[i](p)
*/
bool_var mk_root_atom(atom::kind k, var x, unsigned i, poly * p);
void inc_ref(bool_var b);
void inc_ref(literal l) { inc_ref(l.var()); }
void dec_ref(bool_var b);
void dec_ref(literal l) { dec_ref(l.var()); }
void inc_ref(assumption a);
void dec_ref(assumption a);
/**
\brief Create a new clause.
*/
void mk_clause(unsigned num_lits, literal * lits, assumption a = nullptr);
// -----------------------
//
// Basic
//
// -----------------------
/**
\brief Return the number of Boolean variables.
*/
unsigned num_bool_vars() const;
/**
\brief Get atom associated with Boolean variable. Return 0 if there is none.
*/
atom * bool_var2atom(bool_var b);
/**
\brief extract free variables from literal.
*/
void vars(literal l, var_vector& vs);
/**
\brief provide access to atoms. Used by explain.
*/
atom_vector const& get_atoms();
/**
\brief Access var -> asserted equality.
*/
atom_vector const& get_var2eq();
/**
\brief expose evaluator.
*/
evaluator& get_evaluator();
/**
\brief Access explanation module.
*/
explain& get_explain();
/**
\brief Access assignments to variables.
*/
void get_rvalues(assignment& as);
void set_rvalues(assignment const& as);
void get_bvalues(svector<bool_var> const& bvars, svector<lbool>& vs);
void set_bvalues(svector<lbool> const& vs);
/**
* \brief Access functions for simplify module.
*/
void del_clause(clause* c);
clause* mk_clause(unsigned n, literal const* lits, bool learned, internal_assumption a);
bool has_root_atom(clause const& c) const;
assumption join(assumption a, assumption b);
void inc_simplify();
void record_levelwise_result(bool success);
void add_bound(bound_constraint const& c);
/**
\brief reorder variables.
*/
void reorder(unsigned sz, var const* permutation);
void restore_order();
/**
\brief Return number of integer/real variables
*/
unsigned num_vars() const;
bool is_int(var x) const;
// -----------------------
//
// Search
//
// -----------------------
lbool check();
lbool check(literal_vector& assumptions);
//
// check satisfiability of asserted formulas relative to state of the nlsat solver.
// produce either,
// l_true - a model is available (rvalues can be ignored) or,
// l_false - a clause (not core v not cell) excluding a cell around rvalues if core (consisting of atoms
// passed to nlsat) is asserted.
// l_undef - if the search was interrupted by a resource limit.
// clause is a list of literals. Their disjunction is valid.
// Different implementations of check are possible. One where cell comprises of linear polynomials could
// produce lemmas that are friendly to linear arithmetic solvers.
//
lbool check(assignment const& rvalues, literal_vector& clause);
// -----------------------
//
// Model
//
// -----------------------
anum const & value(var x) const;
lbool bvalue(bool_var b) const;
bool is_interpreted(bool_var b) const;
lbool value(literal l) const;
// -----------------------
//
// Core
//
// -----------------------
void get_core(vector<assumption, false>& deps);
// -----------------------
//
// Misc
//
// -----------------------
void updt_params(params_ref const & p);
static void collect_param_descrs(param_descrs & d);
const assignment& sample() const;
assignment& sample();
bool apply_levelwise() const;
unsigned lws_spt_threshold() const;
bool lws_witness_subs_lc() const;
bool lws_witness_subs_disc() const;
void reset();
void collect_statistics(statistics & st);
void reset_statistics();
void display_status(std::ostream & out) const;
// -----------------------
//
// Pretty printing
//
// -----------------------
/**
\brief Display solver's state.
*/
std::ostream& display(std::ostream & out) const;
/**
\brief Display literal
*/
std::ostream& display(std::ostream & out, literal l) const;
std::ostream& display(std::ostream & out, unsigned n, literal const* ls) const;
std::ostream& display(std::ostream& out, clause const& c) const;
std::ostream& display(std::ostream & out, literal_vector const& ls) const;
std::ostream& display(std::ostream & out, atom const& a) const;
std::ostream& display_smt2(std::ostream & out, literal l) const;
std::ostream& display_smt2(std::ostream & out, unsigned n, literal const* ls) const;
std::ostream& display_smt2(std::ostream & out, literal_vector const& ls) const;
std::ostream& display_smt2(std::ostream & out) const;
/**
\brief Display variable
*/
std::ostream& display(std::ostream & out, var x) const;
display_var_proc const & display_proc() const;
std::ostream& display_assignment(std::ostream& out) const;
std::ostream& display_var(std::ostream& out, unsigned j) const;
};
}