@@ -18,6 +18,7 @@ namespace nra {
18
18
typedef nla::mon_eq mon_eq;
19
19
20
20
typedef nla::variable_map_type variable_map_type;
21
+
21
22
struct solver ::imp {
22
23
lp::lar_solver& lra;
23
24
reslimit& m_limit;
@@ -68,12 +69,12 @@ struct solver::imp {
68
69
}
69
70
}
70
71
71
- for (auto const & m : m_nla_core.m_to_refine )
72
- todo.push_back (m);
72
+ for (auto const & m : m_nla_core.m_to_refine )
73
+ todo.push_back (m);
73
74
74
75
for (unsigned i = 0 ; i < todo.size (); ++i) {
75
76
auto v = todo[i];
76
- if (visited.contains (v))
77
+ if (visited.contains (v))
77
78
continue ;
78
79
visited.insert (v);
79
80
var2occurs.reserve (v + 1 );
@@ -82,22 +83,22 @@ struct solver::imp {
82
83
auto const & c = lra.constraints ()[ci];
83
84
for (auto const & [coeff, w] : c.coeffs ())
84
85
todo.push_back (w);
85
- }
86
+ }
86
87
for (auto w : var2occurs[v].monics )
87
88
todo.push_back (w);
88
89
89
90
if (lra.column_corresponds_to_term (v)) {
90
91
m_term_set.insert (v);
91
92
lp::tv ti = lp::tv::raw (lra.column_to_reported_index (v));
92
- for (auto kv : lra.get_term (ti))
93
- todo.push_back (kv.column ().index ());
93
+ for (auto kv : lra.get_term (ti))
94
+ todo.push_back (kv.column ().index ());
94
95
}
95
96
96
97
if (m_nla_core.is_monic_var (v)) {
97
98
m_mon_set.insert (v);
98
99
for (auto w : m_nla_core.emons ()[v])
99
100
todo.push_back (w);
100
- }
101
+ }
101
102
}
102
103
}
103
104
@@ -112,7 +113,7 @@ struct solver::imp {
112
113
TBD: use partial model from lra_solver to prime the state of nlsat_solver.
113
114
TBD: explore more incremental ways of applying nlsat (using assumptions)
114
115
*/
115
- lbool check () {
116
+ lbool check () {
116
117
SASSERT (need_check ());
117
118
m_values = nullptr ;
118
119
m_nlsat = alloc (nlsat::solver, m_limit, m_params, false );
@@ -125,18 +126,18 @@ struct solver::imp {
125
126
// add linear inequalities from lra_solver
126
127
for (auto ci : m_constraint_set)
127
128
add_constraint (ci);
128
-
129
+
129
130
// add polynomial definitions.
130
- for (auto const & m : m_mon_set)
131
- add_monic_eq (m_nla_core.emons ()[m]);
131
+ for (auto const & m : m_mon_set)
132
+ add_monic_eq (m_nla_core.emons ()[m]);
132
133
133
134
// add term definitions.
134
- for (unsigned i : m_term_set)
135
+ for (unsigned i : m_term_set)
135
136
add_term (i);
136
137
137
138
lbool r = l_undef;
138
139
try {
139
- r = m_nlsat->check ();
140
+ r = m_nlsat->check ();
140
141
}
141
142
catch (z3_exception&) {
142
143
if (m_limit.is_canceled ()) {
@@ -146,30 +147,31 @@ struct solver::imp {
146
147
throw ;
147
148
}
148
149
}
149
- TRACE (" nra" ,
150
+ #if 0
151
+ TRACE("nra",
150
152
m_nlsat->display(tout << r << "\n");
151
- display (tout);
152
- for (auto [j, x] : m_lp2nl) tout << " j" << j << " := x" << x << " \n " ;
153
- );
153
+ display(tout);
154
+ for (auto [j, x] : m_lp2nl) tout << "j" << j << " := x" << x << "\n";);
155
+ # endif
154
156
switch (r) {
155
- case l_true:
157
+ case l_true:
156
158
m_nla_core.set_use_nra_model (true );
157
- lra.init_model ();
158
- for (lp::constraint_index ci : lra.constraints ().indices ())
159
- if (!check_constraint (ci)) {
160
- IF_VERBOSE (0 , verbose_stream () << " constraint " << ci << " violated\n " ;
161
- lra.constraints ().display (verbose_stream ()));
162
- UNREACHABLE ();
163
- return l_undef;
164
- }
165
- for (auto const & m : m_nla_core.emons ()) {
166
- if (!check_monic (m)) {
167
- IF_VERBOSE (0 , verbose_stream () << " monic " << m << " violated\n " ;
168
- lra.constraints ().display (verbose_stream ()));
169
- UNREACHABLE ();
170
- return l_undef;
171
- }
159
+ lra.init_model ();
160
+ for (lp::constraint_index ci : lra.constraints ().indices ())
161
+ if (!check_constraint (ci)) {
162
+ IF_VERBOSE (0 , verbose_stream () << " constraint " << ci << " violated\n " ;
163
+ lra.constraints ().display (verbose_stream ()));
164
+ UNREACHABLE ();
165
+ return l_undef;
172
166
}
167
+ for (auto const & m : m_nla_core.emons ()) {
168
+ if (!check_monic (m)) {
169
+ IF_VERBOSE (0 , verbose_stream () << " monic " << m << " violated\n " ;
170
+ lra.constraints ().display (verbose_stream ()));
171
+ UNREACHABLE ();
172
+ return l_undef;
173
+ }
174
+ }
173
175
break ;
174
176
case l_false: {
175
177
lp::explanation ex;
@@ -186,9 +188,9 @@ struct solver::imp {
186
188
}
187
189
case l_undef:
188
190
break ;
189
- }
191
+ }
190
192
return r;
191
- }
193
+ }
192
194
193
195
void add_monic_eq_bound (mon_eq const & m) {
194
196
if (!lra.column_has_lower_bound (m.var ()) &&
@@ -322,22 +324,22 @@ struct solver::imp {
322
324
m_lp2nl.reset ();
323
325
m_term_set.reset ();
324
326
for (auto const & eq : eqs)
325
- add_eq (*eq);
326
- for (auto const & m : m_nla_core.emons ())
327
- if (any_of (m.vars (), [&](lp::lpvar v) { return m_lp2nl.contains (v); }))
328
- add_monic_eq_bound (m);
329
- for (unsigned i : m_term_set)
330
- add_term (i);
327
+ add_eq (*eq);
328
+ for (auto const & m : m_nla_core.emons ())
329
+ if (any_of (m.vars (), [&](lp::lpvar v) { return m_lp2nl.contains (v); }))
330
+ add_monic_eq_bound (m);
331
+ for (unsigned i : m_term_set)
332
+ add_term (i);
331
333
for (auto const & [v, w] : m_lp2nl) {
332
- if (lra.column_has_lower_bound (v))
333
- add_lb (lra.get_lower_bound (v), w, lra.get_column_lower_bound_witness (v));
334
- if (lra.column_has_upper_bound (v))
335
- add_ub (lra.get_upper_bound (v), w, lra.get_column_upper_bound_witness (v));
334
+ if (lra.column_has_lower_bound (v))
335
+ add_lb (lra.get_lower_bound (v), w, lra.get_column_lower_bound_witness (v));
336
+ if (lra.column_has_upper_bound (v))
337
+ add_ub (lra.get_upper_bound (v), w, lra.get_column_upper_bound_witness (v));
336
338
}
337
339
338
340
lbool r = l_undef;
339
341
try {
340
- r = m_nlsat->check ();
342
+ r = m_nlsat->check ();
341
343
}
342
344
catch (z3_exception&) {
343
345
if (m_limit.is_canceled ()) {
@@ -349,13 +351,13 @@ struct solver::imp {
349
351
}
350
352
351
353
switch (r) {
352
- case l_true:
354
+ case l_true:
353
355
m_nla_core.set_use_nra_model (true );
354
356
lra.init_model ();
355
- for (lp::constraint_index ci : lra.constraints ().indices ())
357
+ for (lp::constraint_index ci : lra.constraints ().indices ())
356
358
if (!check_constraint (ci))
357
- return l_undef;
358
- for (auto const & m : m_nla_core.emons ()) {
359
+ return l_undef;
360
+ for (auto const & m : m_nla_core.emons ())
359
361
if (!check_monic (m))
360
362
return l_undef;
361
363
break ;
@@ -365,7 +367,7 @@ struct solver::imp {
365
367
m_nlsat->get_core (core);
366
368
u_dependency_manager dm;
367
369
vector<unsigned , false > lv;
368
- for (auto c : core)
370
+ for (auto c : core)
369
371
dm.linearize (static_cast <u_dependency*>(c), lv);
370
372
for (auto ci : lv)
371
373
ex.push_back (ci);
@@ -375,8 +377,7 @@ struct solver::imp {
375
377
}
376
378
case l_undef:
377
379
break ;
378
- }
379
-
380
+ }
380
381
return r;
381
382
}
382
383
@@ -388,18 +389,18 @@ struct solver::imp {
388
389
m_term_set.reset ();
389
390
for (auto const & eq : eqs)
390
391
add_eq (eq);
391
- for (auto const & m : m_nla_core.emons ())
392
- add_monic_eq (m);
392
+ for (auto const & m : m_nla_core.emons ())
393
+ add_monic_eq (m);
393
394
for (auto const & [v, w] : m_lp2nl) {
394
395
if (lra.column_has_lower_bound (v))
395
396
add_lb (lra.get_lower_bound (v), w);
396
397
if (lra.column_has_upper_bound (v))
397
398
add_ub (lra.get_upper_bound (v), w);
398
399
}
399
-
400
+
400
401
lbool r = l_undef;
401
402
try {
402
- r = m_nlsat->check ();
403
+ r = m_nlsat->check ();
403
404
}
404
405
catch (z3_exception&) {
405
406
if (m_limit.is_canceled ()) {
@@ -412,46 +413,44 @@ struct solver::imp {
412
413
413
414
if (r == l_true)
414
415
return r;
415
-
416
+
416
417
IF_VERBOSE (0 , verbose_stream () << " check-nra " << r << " \n " ;
417
418
m_nlsat->display (verbose_stream ());
418
419
for (auto const & [v, w] : m_lp2nl) {
419
420
if (lra.column_has_lower_bound (v))
420
421
verbose_stream () << " x" << w << " >= " << lra.get_lower_bound (v) << " \n " ;
421
422
if (lra.column_has_upper_bound (v))
422
423
verbose_stream () << " x" << w << " <= " << lra.get_upper_bound (v) << " \n " ;
423
- });
424
-
425
-
424
+ });
425
+
426
426
return r;
427
427
}
428
-
428
+
429
429
void add_eq (dd::solver::equation const & eq) {
430
430
add_eq (eq.poly (), eq.dep ());
431
431
}
432
-
432
+
433
433
void add_eq (dd::pdd const & eq, nlsat::assumption a = nullptr ) {
434
434
dd::pdd normeq = eq;
435
435
rational lc (1 );
436
- for (auto const & [c, m] : eq)
436
+ for (auto const & [c, m] : eq)
437
437
lc = lcm (denominator (c), lc);
438
438
if (lc != 1 )
439
439
normeq *= lc;
440
440
polynomial::manager& pm = m_nlsat->pm ();
441
441
polynomial::polynomial_ref p (pdd2polynomial (normeq), pm);
442
- bool is_even[1 ] = { false };
443
- polynomial::polynomial* ps[1 ] = { p };
444
- nlsat::literal lit = m_nlsat->mk_ineq_literal (nlsat::atom::kind::EQ, 1 , ps, is_even);
442
+ bool is_even[1 ] = {false };
443
+ polynomial::polynomial* ps[1 ] = {p};
444
+ nlsat::literal lit = m_nlsat->mk_ineq_literal (nlsat::atom::kind::EQ, 1 , ps, is_even);
445
445
m_nlsat->mk_clause (1 , &lit, a);
446
446
}
447
447
448
-
449
448
void add_lb (lp::impq const & b, unsigned w, nlsat::assumption a = nullptr ) {
450
449
polynomial::manager& pm = m_nlsat->pm ();
451
450
polynomial::polynomial_ref p (pm.mk_polynomial (w), pm);
452
451
add_lb (b, p, a);
453
452
}
454
-
453
+
455
454
void add_ub (lp::impq const & b, unsigned w, nlsat::assumption a = nullptr ) {
456
455
polynomial::manager& pm = m_nlsat->pm ();
457
456
polynomial::polynomial_ref p (pm.mk_polynomial (w), pm);
@@ -473,8 +472,8 @@ struct solver::imp {
473
472
polynomial::manager& pm = m_nlsat->pm ();
474
473
polynomial::polynomial_ref p2 (pm.mk_const (bound), pm);
475
474
polynomial::polynomial_ref p (pm.sub (p1, p2), pm);
476
- polynomial::polynomial* ps[1 ] = { p };
477
- bool is_even[1 ] = { false };
475
+ polynomial::polynomial* ps[1 ] = {p };
476
+ bool is_even[1 ] = {false };
478
477
nlsat::literal lit = m_nlsat->mk_ineq_literal (k, 1 , ps, is_even);
479
478
if (neg)
480
479
lit.neg ();
@@ -486,10 +485,10 @@ struct solver::imp {
486
485
polynomial::polynomial_ref p1 (pm.mk_polynomial (w), pm);
487
486
add_bound (bound, p1, neg, k, a);
488
487
}
489
-
488
+
490
489
polynomial::polynomial* pdd2polynomial (dd::pdd const & p) {
491
490
polynomial::manager& pm = m_nlsat->pm ();
492
- if (p.is_val ())
491
+ if (p.is_val ())
493
492
return pm.mk_const (p.val ());
494
493
polynomial::polynomial_ref lo (pdd2polynomial (p.lo ()), pm);
495
494
polynomial::polynomial_ref hi (pdd2polynomial (p.hi ()), pm);
@@ -502,7 +501,9 @@ struct solver::imp {
502
501
polynomial::polynomial_ref mp (pm.mul (vp, hi), pm);
503
502
return pm.add (lo, mp);
504
503
}
505
-
504
+
505
+
506
+
506
507
bool is_int (lp::var_index v) {
507
508
return lra.var_is_int (v);
508
509
}
@@ -521,7 +522,7 @@ struct solver::imp {
521
522
//
522
523
void add_term (unsigned term_column) {
523
524
lp::tv ti = lp::tv::raw (lra.column_to_reported_index (term_column));
524
- const lp::lar_term& t = lra.get_term (ti);
525
+ const lp::lar_term& t = lra.get_term (ti);
525
526
// code that creates a polynomial equality between the linear coefficients and
526
527
// variable representing the term.
527
528
svector<polynomial::var> vars;
@@ -531,17 +532,17 @@ struct solver::imp {
531
532
den = lcm (den, denominator (kv.coeff ()));
532
533
}
533
534
vars.push_back (lp2nl (term_column));
534
-
535
+
535
536
vector<rational> coeffs;
536
537
for (auto kv : t) {
537
538
coeffs.push_back (den * kv.coeff ());
538
539
}
539
540
coeffs.push_back (-den);
540
541
polynomial::manager& pm = m_nlsat->pm ();
541
542
polynomial::polynomial_ref p (pm.mk_linear (coeffs.size (), coeffs.data (), vars.data (), rational (0 )), pm);
542
- polynomial::polynomial* ps[1 ] = { p };
543
- bool is_even[1 ] = { false };
544
- nlsat::literal lit = m_nlsat->mk_ineq_literal (nlsat::atom::kind::EQ, 1 , ps, is_even);
543
+ polynomial::polynomial* ps[1 ] = {p };
544
+ bool is_even[1 ] = {false };
545
+ nlsat::literal lit = m_nlsat->mk_ineq_literal (nlsat::atom::kind::EQ, 1 , ps, is_even);
545
546
m_nlsat->mk_clause (1 , &lit, nullptr );
546
547
}
547
548
0 commit comments