#include "nlsat/nlsat_assignment.h"
#include "nlsat/nlsat_interval_set.h"
#include "nlsat/nlsat_evaluator.h"
#include "nlsat/nlsat_solver.h"
#include "nlsat/levelwise.h"
#include "util/util.h"
#include "nlsat/nlsat_explain.h"
#include "math/polynomial/polynomial_cache.h"
#include "util/rlimit.h"
#include <iostream>
#include <vector>
static bool is_point_inside_cell(
anum_manager& am,
polynomial::manager& pm,
std_vector<nlsat::levelwise::root_function_interval> const& cell,
nlsat::assignment const& counter_as,
bool verbose = true)
{
for (unsigned level = 0; level < cell.size(); ++level) {
auto const& interval = cell[level];
if (!interval.is_section() && interval.l_inf() && interval.u_inf())
continue;
if (!counter_as.is_assigned(level))
continue;
scoped_anum counter_val(am);
am.set(counter_val, counter_as.value(level));
nlsat::assignment partial_as(am);
for (unsigned j = 0; j < level; ++j) {
if (counter_as.is_assigned(j)) {
scoped_anum v(am);
am.set(v, counter_as.value(j));
partial_as.set(j, v);
}
}
if (interval.is_section()) {
polynomial_ref section_p(interval.l, pm);
scoped_anum_vector roots(am);
am.isolate_roots(section_p, nlsat::undef_var_assignment(partial_as, level), roots);
if (roots.size() >= interval.l_index) {
bool at_root = am.eq(counter_val, roots[interval.l_index - 1]);
if (!at_root) {
if (verbose) {
std::cout << " Level " << level << ": OUTSIDE (not at section root)\n";
std::cout << " Section root = ";
am.display_decimal(std::cout, roots[interval.l_index - 1], 6);
std::cout << ", counter = ";
am.display_decimal(std::cout, counter_val, 6);
std::cout << "\n";
}
return false;
}
}
} else {
if (!interval.l_inf()) {
polynomial_ref lower_p(interval.l, pm);
scoped_anum_vector lower_roots(am);
am.isolate_roots(lower_p, nlsat::undef_var_assignment(partial_as, level), lower_roots);
if (lower_roots.size() >= interval.l_index) {
int cmp = am.compare(counter_val, lower_roots[interval.l_index - 1]);
if (cmp <= 0) { if (verbose) {
std::cout << " Level " << level << ": OUTSIDE (at or below lower bound)\n";
std::cout << " Lower bound = ";
am.display_decimal(std::cout, lower_roots[interval.l_index - 1], 6);
std::cout << ", counter = ";
am.display_decimal(std::cout, counter_val, 6);
std::cout << "\n";
}
return false;
}
}
}
if (!interval.u_inf()) {
polynomial_ref upper_p(interval.u, pm);
scoped_anum_vector upper_roots(am);
am.isolate_roots(upper_p, nlsat::undef_var_assignment(partial_as, level), upper_roots);
if (upper_roots.size() >= interval.u_index) {
int cmp = am.compare(counter_val, upper_roots[interval.u_index - 1]);
if (cmp >= 0) { if (verbose) {
std::cout << " Level " << level << ": OUTSIDE (at or above upper bound)\n";
std::cout << " Upper bound = ";
am.display_decimal(std::cout, upper_roots[interval.u_index - 1], 6);
std::cout << ", counter = ";
am.display_decimal(std::cout, counter_val, 6);
std::cout << "\n";
}
return false;
}
}
}
}
}
if (verbose) {
std::cout << " Point is INSIDE the cell (all constraints satisfied)\n";
}
return true;
}
static bool has_different_sign(
anum_manager& am,
polynomial::manager& pm,
polynomial_ref_vector const& polys,
nlsat::assignment const& sample_as,
nlsat::assignment const& counter_as)
{
for (unsigned i = 0; i < polys.size(); ++i) {
polynomial_ref p(polys.get(i), pm);
polynomial::var mv = pm.max_var(p);
if (mv == polynomial::null_var) continue;
if (!sample_as.is_assigned(mv) || !counter_as.is_assigned(mv))
continue;
sign s_sign = am.eval_sign_at(p, sample_as);
sign c_sign = am.eval_sign_at(p, counter_as);
if (s_sign != c_sign) {
std::cout << " p" << i << " has different sign: sample=" << s_sign
<< ", counter=" << c_sign << "\n";
return true;
}
}
return false;
}
nlsat::interval_set_ref tst_interval(nlsat::interval_set_ref const & s1,
nlsat::interval_set_ref const & s2,
unsigned expected_num_intervals,
bool check_num_intervals = true) {
nlsat::interval_set_manager & ism = s1.m();
nlsat::interval_set_ref r(ism);
std::cout << "s1: " << s1 << "\n";
std::cout << "s2: " << s2 << "\n";
r = ism.mk_union(s1, s2);
std::cout << "union(s1, s2): " << r << std::endl;
ENSURE(!check_num_intervals || ism.num_intervals(r) == expected_num_intervals);
ENSURE(ism.subset(s1, r));
ENSURE(ism.subset(s2, r));
if (ism.set_eq(s1, s2)) {
ENSURE(ism.set_eq(s1, r));
ENSURE(ism.set_eq(s2, r));
}
else {
ENSURE(ism.subset(s1, s2) || !ism.subset(r, s2));
ENSURE(ism.subset(s2, s1) || !ism.subset(r, s1));
}
nlsat::interval_set_ref r2(ism);
r2 = ism.mk_union(s2, s1);
ENSURE(ism.set_eq(r, r2));
anum zero;
nlsat::interval_set_ref full(ism);
nlsat::literal dummy(131, false);
full = ism.mk(true, true, zero, true, true, zero, dummy, nullptr);
ENSURE(ism.set_eq(r, full) == ism.is_full(r));
return r;
}
static void tst3() {
reslimit rl;
unsynch_mpq_manager qm;
anum_manager am(rl, qm);
small_object_allocator allocator;
nlsat::interval_set_manager ism(am, allocator);
scoped_anum sqrt2(am), m_sqrt2(am), two(am), m_two(am), three(am), one(am), zero(am);
am.set(two, 2);
am.set(m_two, -2);
am.set(one, 1);
am.root(two, 2, sqrt2);
am.set(m_sqrt2, sqrt2);
am.neg(m_sqrt2);
am.set(three, 3);
nlsat::literal p1(1, false);
nlsat::literal p2(2, false);
nlsat::literal p3(3, false);
nlsat::literal p4(4, false);
nlsat::literal np2(2, true);
nlsat::interval_set_ref s1(ism), s2(ism), s3(ism), s4(ism);
s1 = ism.mk_empty();
std::cout << "s1: " << s1 << "\n";
s2 = ism.mk(true, true, zero, false, false, sqrt2, np2, nullptr);
std::cout << "s2: " << s2 << "\n";
s3 = ism.mk(false, false, zero, false, false, two, p1, nullptr);
std::cout << "s3: " << s3 << "\n";
s4 = ism.mk_union(s2, s3);
std::cout << "s4: " << s4 << "\n";
s1 = ism.mk(false, false, zero, false, false, two, p1, nullptr);
s2 = ism.mk(false, false, zero, false, false, two, p2, nullptr);
tst_interval(s1, s2, 1);
s1 = ism.mk(false, false, zero, false, false, two, p1, nullptr);
s2 = ism.mk(false, false, m_sqrt2, false, false, one, p2, nullptr);
s3 = ism.mk_union(s1, s2);
tst_interval(s1, s2, 2);
s1 = ism.mk(false, false, m_sqrt2, false, false, one, p1, nullptr);
s2 = ism.mk(false, false, zero, false, false, two, p2, nullptr);
tst_interval(s1, s2, 2);
s1 = ism.mk(false, false, m_sqrt2, false, false, one, p1, nullptr);
s2 = ism.mk(false, false, two, false, false, three, p2, nullptr);
tst_interval(s1, s2, 2);
s1 = ism.mk(false, false, m_sqrt2, false, false, three, p1, nullptr);
s2 = ism.mk(false, false, zero, false, false, two, p2, nullptr);
tst_interval(s1, s2, 1);
s1 = ism.mk(false, false, m_two, false, false, two, p1, nullptr);
s2 = ism.mk(false, false, m_sqrt2, false, false, zero, p2, nullptr);
s3 = ism.mk(false, false, one, false, false, three, p2, nullptr);
s2 = ism.mk_union(s2, s3);
tst_interval(s1, s2, 2);
s1 = ism.mk(false, false, m_two, false, false, two, p1, nullptr);
s2 = ism.mk(false, false, two, false, false, three, p2, nullptr);
tst_interval(s1, s2, 2);
s2 = ism.mk(true, false, two, false, false, three, p2, nullptr);
tst_interval(s1, s2, 2);
s2 = ism.mk(true, false, two, false, false, three, p1, nullptr);
tst_interval(s1, s2, 1);
s1 = ism.mk(false, false, m_two, true, false, two, p1, nullptr);
tst_interval(s1, s2, 2);
s1 = ism.mk(false, false, two, false, false, two, p1, nullptr);
s2 = ism.mk(false, false, two, false, false, three, p2, nullptr);
tst_interval(s1, s2, 1);
s1 = ism.mk(false, false, m_two, false, false, zero, p1, nullptr);
s3 = ism.mk(false, false, one, false, false, three, p1, nullptr);
s1 = ism.mk_union(s1, s3);
s2 = ism.mk(true, true, zero, false, false, m_sqrt2, p2, nullptr);
tst_interval(s1, s2, 3);
s3 = ism.mk(false, false, one, false, false, sqrt2, p2, nullptr);
s2 = ism.mk_union(s2, s3);
s3 = ism.mk(false, false, two, true, true, zero, p2, nullptr);
s2 = ism.mk_union(s2, s3);
tst_interval(s1, s2, 4);
s1 = ism.mk(true, true, zero, false, false, one, p1, nullptr);
s2 = ism.mk(true, false, one, true, true, zero, p2, nullptr);
tst_interval(s1, s2, 2);
s2 = ism.mk(true, false, one, false, false, two, p2, nullptr);
s3 = ism.mk(false, false, two, true, true, zero, p1, nullptr);
s2 = ism.mk_union(s2, s3);
tst_interval(s1, s2, 3);
}
static nlsat::interval_set_ref mk_random(nlsat::interval_set_manager & ism, anum_manager & am, int range, int space, int tries, bool minus_inf, bool plus_inf,
nlsat::literal lit) {
static random_gen gen;
ENSURE(range > 0);
ENSURE(space > 0);
nlsat::interval_set_ref r(ism), curr(ism);
scoped_anum lower(am);
scoped_anum upper(am);
int prev = -range + (gen() % (space*4));
if (gen() % 3 == 0 && minus_inf) {
int next = prev + (gen() % space);
bool open = gen() % 2 == 0;
am.set(upper, next);
r = ism.mk(true, true, lower, open, false, upper, lit, nullptr);
prev = next;
}
for (int i = 0; i < tries; ++i) {
int l = prev + (gen() % space);
int u = l + (gen() % space);
bool lower_open = gen() % 2 == 0;
bool upper_open = gen() % 2 == 0;
if ((lower_open || upper_open) && l == u)
u++;
am.set(lower, l);
am.set(upper, u);
curr = ism.mk(lower_open, false, lower, upper_open, false, upper, lit, nullptr);
r = ism.mk_union(r, curr);
prev = u;
}
if (gen() % 3 == 0 && plus_inf) {
int next = prev + (gen() % space);
bool open = gen() % 2 == 0;
am.set(lower, next);
curr = ism.mk(open, false, lower, true, true, upper, lit, nullptr);
r = ism.mk_union(r, curr);
}
return r;
}
static void check_subset_result(nlsat::interval_set_ref const & s1,
nlsat::interval_set_ref const & s2,
nlsat::interval_set_ref const & r,
nlsat::literal l1,
nlsat::literal l2) {
nlsat::interval_set_manager ism(s1.m());
nlsat::interval_set_ref tmp(ism);
unsigned num = ism.num_intervals(r);
nlsat::literal_vector lits;
ptr_vector<nlsat::clause> clauses;
ism.get_justifications(r, lits, clauses);
ENSURE(lits.size() <= 2);
for (unsigned i = 0; i < num; ++i) {
tmp = ism.get_interval(r, i);
ism.get_justifications(tmp, lits, clauses);
ENSURE(lits.size() == 1);
if (lits[0] == l1) {
ENSURE(ism.subset(tmp, s1));
}
else {
ENSURE(lits[0] == l2);
ENSURE(ism.subset(tmp, s2));
}
}
}
static void tst4() {
reslimit rl;
unsynch_mpq_manager qm;
anum_manager am(rl, qm);
small_object_allocator allocator;
nlsat::interval_set_manager ism(am, allocator);
nlsat::interval_set_ref s1(ism), s2(ism), r(ism);
nlsat::literal l1(1, false);
nlsat::literal l2(2, false);
for (unsigned i = 0; i < 100; ++i) {
s1 = mk_random(ism, am, 20, 3, 10, true, true, l1);
s2 = mk_random(ism, am, 20, 3, 10, true, true, l2);
r = tst_interval(s1, s2, 0, false);
check_subset_result(s1, s2, r, l1, l2);
}
for (unsigned i = 0; i < 100; ++i) {
s1 = mk_random(ism, am, 200, 100, 20, true, true, l1);
s2 = mk_random(ism, am, 200, 100, 20, true, true, l2);
r = tst_interval(s1, s2, 0, false);
check_subset_result(s1, s2, r, l1, l2);
}
}
static void tst5() {
params_ref ps;
reslimit rlim;
nlsat::solver s(rlim, ps, false);
anum_manager & am = s.am();
nlsat::pmanager & pm = s.pm();
nlsat::assignment as(am);
small_object_allocator allocator;
nlsat::interval_set_manager ism(am, allocator);
nlsat::evaluator ev(s, as, pm, allocator);
nlsat::var x0, x1;
x0 = pm.mk_var();
x1 = pm.mk_var();
polynomial_ref p(pm);
polynomial_ref _x0(pm), _x1(pm);
_x0 = pm.mk_polynomial(x0);
_x1 = pm.mk_polynomial(x1);
p = (_x0^2) + (_x1^2) - 2;
nlsat::poly * _p[1] = { p.get() };
bool is_even[1] = { false };
nlsat::bool_var b = s.mk_ineq_atom(nlsat::atom::GT, 1, _p, is_even);
nlsat::atom * a = s.bool_var2atom(b);
ENSURE(a != nullptr);
scoped_anum zero(am);
am.set(zero, 0);
as.set(0, zero);
auto i = ev.infeasible_intervals(a, true, nullptr);
std::cout << "1) " << i << "\n";
as.set(1, zero);
auto i2 = ev.infeasible_intervals(a, true, nullptr);
std::cout << "2) " << i2 << "\n";
}
static void project(nlsat::solver& s, nlsat::explain& ex, nlsat::var x, unsigned num, nlsat::literal const* lits) {
std::cout << "Project ";
s.display(std::cout, num, lits);
nlsat::scoped_literal_vector result(s);
ex.project(x, num, lits, result);
s.display(std::cout << "\n==>\n", result.size(), result.data());
std::cout << "\n";
}
static nlsat::scoped_literal_vector project_fa(nlsat::solver& s, nlsat::explain& ex, nlsat::var x, unsigned num, nlsat::literal const* lits) {
std::cout << "Project ";
nlsat::scoped_literal_vector result(s);
ex.compute_conflict_explanation(num, lits, result);
std::cout << "(or";
for (auto l : result) {
s.display(std::cout << " ", l);
}
for (unsigned i = 0; i < num; ++i) {
s.display(std::cout << " ", ~lits[i]);
}
std::cout << ")\n";
return result;
}
static nlsat::literal mk_gt(nlsat::solver& s, nlsat::poly* p) {
nlsat::poly * _p[1] = { p };
bool is_even[1] = { false };
return s.mk_ineq_literal(nlsat::atom::GT, 1, _p, is_even);
}
static nlsat::literal mk_lt(nlsat::solver& s, nlsat::poly* p) {
nlsat::poly * _p[1] = { p };
bool is_even[1] = { false };
return s.mk_ineq_literal(nlsat::atom::LT, 1, _p, is_even);
}
static nlsat::literal mk_eq(nlsat::solver& s, nlsat::poly* p) {
nlsat::poly * _p[1] = { p };
bool is_even[1] = { false };
return s.mk_ineq_literal(nlsat::atom::EQ, 1, _p, is_even);
}
static nlsat::literal mk_root_eq(nlsat::solver& s, nlsat::poly* p, nlsat::var x, unsigned i) {
nlsat::bool_var b = s.mk_root_atom(nlsat::atom::ROOT_EQ, x, i, p);
return nlsat::literal(b, false);
}
static bool contains_var(nlsat::var_vector const& vars, nlsat::var x) {
for (auto v : vars) {
if (v == x)
return true;
}
return false;
}
static bool clause_contains_root_dependency(
nlsat::solver& s,
nlsat::scoped_literal_vector const& result,
nlsat::atom::kind kind,
nlsat::var target,
unsigned root_index,
nlsat::var dep1,
nlsat::var dep2,
nlsat::var dep3) {
nlsat::pmanager& pm = s.pm();
nlsat::var_vector vars;
for (auto l : result) {
nlsat::atom* a = s.bool_var2atom(l.var());
if (!a || !a->is_root_atom() || a->get_kind() != kind)
continue;
nlsat::root_atom* ra = nlsat::to_root_atom(a);
if (ra->x() != target || ra->i() != root_index || pm.max_var(ra->p()) != target)
continue;
s.vars(l, vars);
if (contains_var(vars, dep1) && contains_var(vars, dep2) && contains_var(vars, dep3))
return true;
}
return false;
}
static void set_assignment_value(nlsat::assignment& as, anum_manager& am, nlsat::var v, rational const& val) {
scoped_anum tmp(am);
am.set(tmp, val.to_mpq());
as.set(v, tmp);
}
static void tst_12() {
params_ref ps;
reslimit rlim;
nlsat::solver s(rlim, ps, false);
nlsat::pmanager& pm = s.pm();
anum_manager & am = s.am();
nlsat::assignment as(am);
scoped_anum zero(am), one(am), two(am), three(am);
nlsat::explain& ex = s.get_explain();
nlsat::var x0 = s.mk_var(false);
nlsat::var x1 = s.mk_var(false);
nlsat::var x2 = s.mk_var(false);
am.set(one, 1);
am.set(two, 2);
as.set(x0, one);
as.set(x1, two);
as.set(x2, three);
polynomial_ref _x0(pm), _x1(pm), _x2(pm);
_x0 = pm.mk_polynomial(x0);
_x1 = pm.mk_polynomial(x1);
_x2 = pm.mk_polynomial(x2);
polynomial_ref x0_sq(pm), x1_sq(pm), x2_sq(pm);
x0_sq = _x0 * _x0;
x1_sq = _x1 * _x1;
x2_sq = _x2 * _x2;
polynomial_ref vandermonde_flat(pm);
vandermonde_flat =
(_x1 * x2_sq) -
(x1_sq * _x2) +
(_x0 * x1_sq) -
(x0_sq * _x1) +
(x0_sq * _x2) -
(_x0 * x2_sq);
polynomial_ref vandermonde_factored(pm);
vandermonde_factored = (_x1 - _x0) * (_x2 - _x0) * (_x2 - _x1);
std::cout << "vandermonde_factored:" << vandermonde_factored << "\n";
polynomial_ref diff(pm);
diff = vandermonde_flat - vandermonde_factored;
ENSURE(pm.is_zero(diff.get()));
pm.display(std::cout << "vandermonde(flat): ", vandermonde_flat);
std::cout << "\n";
nlsat::scoped_literal_vector lits(s);
lits.push_back(mk_gt(s, vandermonde_flat));
s.set_rvalues(as);
project(s, ex, x2, lits.size(), lits.data());
as.set(x2, (one + two)/2);
std::cout << am.eval_sign_at(vandermonde_flat, as) << "\n";
;}
static void tst6() {
params_ref ps;
reslimit rlim;
nlsat::solver s(rlim, ps, false);
anum_manager & am = s.am();
nlsat::pmanager & pm = s.pm();
nlsat::assignment as(am);
nlsat::explain& ex = s.get_explain();
nlsat::var x0, x1, x2, a, b, c, d;
a = s.mk_var(false);
b = s.mk_var(false);
c = s.mk_var(false);
d = s.mk_var(false);
x0 = s.mk_var(false);
x1 = s.mk_var(false);
x2 = s.mk_var(false);
polynomial_ref p1(pm), p2(pm), p3(pm), p4(pm), p5(pm);
polynomial_ref _x0(pm), _x1(pm), _x2(pm);
polynomial_ref _a(pm), _b(pm), _c(pm), _d(pm);
_x0 = pm.mk_polynomial(x0);
_x1 = pm.mk_polynomial(x1);
_x2 = pm.mk_polynomial(x2);
_a = pm.mk_polynomial(a);
_b = pm.mk_polynomial(b);
_c = pm.mk_polynomial(c);
_d = pm.mk_polynomial(d);
p1 = (_a*(_x0^2)) + _x2 + 2;
p2 = (_b*_x1) - (2*_x2) - _x0 + 8;
nlsat::scoped_literal_vector lits(s);
lits.push_back(mk_gt(s, p1));
lits.push_back(mk_gt(s, p2));
lits.push_back(mk_gt(s, (_c*_x0) + _x2 + 1));
lits.push_back(mk_gt(s, (_d*_x0) - _x1 + 5*_x2));
scoped_anum zero(am), one(am), two(am);
am.set(zero, 0);
am.set(one, 1);
am.set(two, 2);
as.set(0, one);
as.set(1, one);
as.set(2, two);
as.set(3, two);
as.set(4, two);
as.set(5, one);
as.set(6, one);
s.set_rvalues(as);
project(s, ex, x0, 2, lits.data());
project(s, ex, x1, 3, lits.data());
project(s, ex, x2, 3, lits.data());
project(s, ex, x2, 2, lits.data());
project(s, ex, x2, 4, lits.data());
project(s, ex, x2, 3, lits.data()+1);
}
static void tst7() {
params_ref ps;
reslimit rlim;
nlsat::solver s(rlim, ps, false);
nlsat::pmanager & pm = s.pm();
nlsat::var x0, x1, x2, a, b, c, d;
a = s.mk_var(false);
b = s.mk_var(false);
c = s.mk_var(false);
d = s.mk_var(false);
x0 = s.mk_var(false);
x1 = s.mk_var(false);
x2 = s.mk_var(false);
polynomial_ref p1(pm), p2(pm), p3(pm), p4(pm), p5(pm);
polynomial_ref _x0(pm), _x1(pm), _x2(pm);
polynomial_ref _a(pm), _b(pm), _c(pm), _d(pm);
_x0 = pm.mk_polynomial(x0);
_x1 = pm.mk_polynomial(x1);
_x2 = pm.mk_polynomial(x2);
_a = pm.mk_polynomial(a);
_b = pm.mk_polynomial(b);
_c = pm.mk_polynomial(c);
_d = pm.mk_polynomial(d);
p1 = _x0 + _x1;
p2 = _x2 - _x0;
p3 = (-1*_x0) - _x1;
nlsat::scoped_literal_vector lits(s);
lits.push_back(mk_gt(s, p1));
lits.push_back(mk_gt(s, p2));
lits.push_back(mk_gt(s, p3));
nlsat::literal_vector litsv(lits.size(), lits.data());
lbool res = s.check(litsv);
VERIFY(res == l_false);
for (unsigned i = 0; i < litsv.size(); ++i) {
s.display(std::cout, litsv[i]);
std::cout << " ";
}
std::cout << "\n";
litsv.reset();
litsv.append(2, lits.data());
res = s.check(litsv);
ENSURE(res == l_true);
s.display(std::cout);
s.am().display(std::cout, s.value(x0)); std::cout << "\n";
s.am().display(std::cout, s.value(x1)); std::cout << "\n";
s.am().display(std::cout, s.value(x2)); std::cout << "\n";
}
static void tst8() {
params_ref ps;
reslimit rlim;
nlsat::solver s(rlim, ps, false);
anum_manager & am = s.am();
nlsat::pmanager & pm = s.pm();
nlsat::assignment as(am);
nlsat::explain& ex = s.get_explain();
nlsat::var x0, x1, x2, a, b, c, d;
a = s.mk_var(false);
b = s.mk_var(false);
c = s.mk_var(false);
d = s.mk_var(false);
x0 = s.mk_var(false);
x1 = s.mk_var(false);
x2 = s.mk_var(false);
polynomial_ref p1(pm), p2(pm), p3(pm), p4(pm), p5(pm);
polynomial_ref _x0(pm), _x1(pm), _x2(pm);
polynomial_ref _a(pm), _b(pm), _c(pm), _d(pm);
_x0 = pm.mk_polynomial(x0);
_x1 = pm.mk_polynomial(x1);
_x2 = pm.mk_polynomial(x2);
_a = pm.mk_polynomial(a);
_b = pm.mk_polynomial(b);
_c = pm.mk_polynomial(c);
_d = pm.mk_polynomial(d);
scoped_anum zero(am), one(am), two(am), six(am);
am.set(zero, 0);
am.set(one, 1);
am.set(two, 2);
am.set(six, 6);
as.set(0, two); as.set(1, one); as.set(2, six); as.set(3, zero); as.set(4, zero); as.set(5, zero); as.set(6, two); s.set_rvalues(as);
nlsat::scoped_literal_vector lits(s);
lits.push_back(mk_eq(s, (_a*_x2*_x2) - (_b*_x2) - _c));
project(s, ex, x2, 1, lits.data());
}
static void tst9() {
params_ref ps;
reslimit rlim;
nlsat::solver s(rlim, ps, false);
anum_manager & am = s.am();
nlsat::pmanager & pm = s.pm();
nlsat::assignment as(am);
nlsat::explain& ex = s.get_explain();
int num_lo = 4;
int num_hi = 5;
svector<nlsat::var> los, his;
for (int i = 0; i < num_lo; ++i) {
los.push_back(s.mk_var(false));
scoped_anum num(am);
am.set(num, - i - 1);
as.set(i, num);
}
for (int i = 0; i < num_hi; ++i) {
his.push_back(s.mk_var(false));
scoped_anum num(am);
am.set(num, i + 1);
as.set(num_lo + i, num);
}
nlsat::var _z = s.mk_var(false);
nlsat::var _x = s.mk_var(false);
polynomial_ref x(pm), z(pm);
x = pm.mk_polynomial(_x);
scoped_anum val(am);
am.set(val, 0);
as.set(num_lo + num_hi, val);
as.set(num_lo + num_hi + 1, val);
s.set_rvalues(as);
nlsat::scoped_literal_vector lits(s);
for (int i = 0; i < num_lo; ++i) {
polynomial_ref y(pm);
y = pm.mk_polynomial(los[i]);
lits.push_back(mk_gt(s, x - y));
}
for (int i = 0; i < num_hi; ++i) {
polynomial_ref y(pm);
y = pm.mk_polynomial(his[i]);
lits.push_back(mk_gt(s, y - x));
}
z = pm.mk_polynomial(_z);
lits.push_back(mk_eq(s, x - z));
#define TEST_ON_OFF() \
std::cout << "Off "; \
project(s, ex, _x, lits.size()-1, lits.data()); \
std::cout << "On "; \
project(s, ex, _x, lits.size()-1, lits.data()); \
std::cout << "Off "; \
project(s, ex, _x, lits.size(), lits.data()); \
std::cout << "On "; \
project(s, ex, _x, lits.size(), lits.data()) \
TEST_ON_OFF();
lits.reset();
polynomial_ref u(pm);
u = pm.mk_polynomial(his[1]);
for (int i = 0; i < num_lo; ++i) {
polynomial_ref y(pm);
y = pm.mk_polynomial(los[i]);
lits.push_back(mk_gt(s, u*x - y));
}
for (int i = 0; i < num_hi; ++i) {
polynomial_ref y(pm);
y = pm.mk_polynomial(his[i]);
lits.push_back(mk_gt(s, y - u*x));
}
z = pm.mk_polynomial(_z);
lits.push_back(mk_eq(s, u*x - z));
TEST_ON_OFF();
lits.reset();
u = pm.mk_polynomial(los[1]);
for (int i = 0; i < num_lo; ++i) {
polynomial_ref y(pm);
y = pm.mk_polynomial(los[i]);
lits.push_back(mk_gt(s, u*x - y));
}
for (int i = 0; i < num_hi; ++i) {
polynomial_ref y(pm);
y = pm.mk_polynomial(his[i]);
lits.push_back(mk_gt(s, y - u*x));
}
z = pm.mk_polynomial(_z);
lits.push_back(mk_eq(s, x - z));
TEST_ON_OFF();
}
#if 0#endif
static void test_root_literal(nlsat::solver& s, nlsat::explain& ex, nlsat::var x, nlsat::atom::kind k, unsigned i, nlsat::poly* p) {
nlsat::scoped_literal_vector result(s);
ex.test_root_literal(k, x, 1, p, result);
nlsat::bool_var b = s.mk_root_atom(k, x, i, p);
s.display(std::cout, nlsat::literal(b, false));
s.display(std::cout << " ==> ", result.size(), result.data());
std::cout << "\n";
}
static bool satisfies_root(nlsat::solver& s, nlsat::atom::kind k, nlsat::poly* p) {
nlsat::pmanager & pm = s.pm();
anum_manager & am = s.am();
nlsat::assignment as(am);
s.get_rvalues(as);
polynomial_ref pr(p, pm);
switch (k) {
case nlsat::atom::ROOT_EQ: return am.eval_sign_at(pr, as) == 0;
case nlsat::atom::ROOT_LE: return am.eval_sign_at(pr, as) <= 0;
case nlsat::atom::ROOT_LT: return am.eval_sign_at(pr, as) < 0;
case nlsat::atom::ROOT_GE: return am.eval_sign_at(pr, as) >= 0;
case nlsat::atom::ROOT_GT: return am.eval_sign_at(pr, as) > 0;
default:
UNREACHABLE();
return false;
}
}
static void tst10() {
params_ref ps;
reslimit rlim;
nlsat::solver s(rlim, ps, false);
anum_manager & am = s.am();
nlsat::pmanager & pm = s.pm();
nlsat::assignment as(am);
nlsat::explain& ex = s.get_explain();
nlsat::var _a = s.mk_var(false);
nlsat::var _b = s.mk_var(false);
nlsat::var _c = s.mk_var(false);
nlsat::var _x = s.mk_var(false);
polynomial_ref x(pm), a(pm), b(pm), c(pm), p(pm);
x = pm.mk_polynomial(_x);
a = pm.mk_polynomial(_a);
b = pm.mk_polynomial(_b);
c = pm.mk_polynomial(_c);
p = a*x*x + b*x + c;
scoped_anum one(am), two(am), three(am), mone(am), mtwo(am), mthree(am), zero(am), one_a_half(am);
am.set(zero, 0);
am.set(one, 1);
am.set(two, 2);
am.set(three, 3);
am.set(mone, -1);
am.set(mtwo, -2);
am.set(mthree, -3);
rational oah(1,2);
am.set(one_a_half, oah.to_mpq());
scoped_anum_vector nums(am);
nums.push_back(one);
nums.push_back(two);
nums.push_back(one_a_half);
nums.push_back(mone);
nums.push_back(three);
as.set(_a, one);
as.set(_b, mthree);
as.set(_c, two);
for (unsigned i = 0; i < nums.size(); ++i) {
as.set(_x, nums[i]);
s.set_rvalues(as);
std::cout << p << "\n";
as.display(std::cout);
for (unsigned k = nlsat::atom::ROOT_EQ; k <= nlsat::atom::ROOT_GE; ++k) {
if (satisfies_root(s, (nlsat::atom::kind) k, p)) {
test_root_literal(s, ex, _x, (nlsat::atom::kind) k, 1, p);
}
}
}
as.set(_a, mone);
as.set(_b, three);
as.set(_c, mtwo);
for (unsigned i = 0; i < nums.size(); ++i) {
as.set(_x, nums[i]);
s.set_rvalues(as);
std::cout << p << "\n";
as.display(std::cout);
for (unsigned k = nlsat::atom::ROOT_EQ; k <= nlsat::atom::ROOT_GE; ++k) {
if (satisfies_root(s, (nlsat::atom::kind) k, p)) {
test_root_literal(s, ex, _x, (nlsat::atom::kind) k, 1, p);
}
}
}
std::cout << "\n";
}
void tst_13() {
params_ref ps;
reslimit rlim;
nlsat::solver s(rlim, ps, false);
anum_manager & am = s.am();
nlsat::pmanager & pm = s.pm();
nlsat::assignment assignment(am);
nlsat::explain& ex = s.get_explain();
tst_12();
return;
nlsat::var x0 = s.mk_var(false);
nlsat::var x1 = s.mk_var(false);
polynomial_ref _x0(pm), _x1(pm);
_x0 = pm.mk_polynomial(x0);
_x1 = pm.mk_polynomial(x1);
polynomial_ref x0_sq(pm), x0_cu(pm), x0_4(pm), x0_5(pm);
x0_sq = _x0 * _x0;
x0_cu = x0_sq * _x0;
x0_4 = x0_cu * _x0;
x0_5 = x0_4 * _x0;
polynomial_ref x1_sq(pm), x1_cu(pm), x1_4(pm), x1_5(pm);
x1_sq = _x1 * _x1;
x1_cu = x1_sq * _x1;
x1_4 = x1_cu * _x1;
x1_5 = x1_4 * _x1;
polynomial_ref root_arg(pm);
root_arg =
x1_5 +
(_x0 * x1_4) -
(18 * x1_4) -
(2 * x0_sq * x1_cu) -
(2 * x0_cu * x1_sq) +
(36 * x0_sq * x1_sq) +
(1296 * _x0 * x1_sq) +
(864 * x1_sq) +
(x0_4 * _x1) +
(1296 * x0_sq * _x1) +
(6048 * _x0 * _x1) +
x0_5 -
(18 * x0_4) +
(864 * x0_sq);
std::cout << "big poly:" << root_arg << std::endl;
nlsat::literal x1_gt_0 = mk_gt(s, _x1);
nlsat::bool_var root_gt = s.mk_root_atom(nlsat::atom::ROOT_GT, x1, 3, root_arg.get());
nlsat::literal x1_gt_root(root_gt, false);
nlsat::scoped_literal_vector lits(s);
lits.push_back(x1_gt_0);
lits.push_back(~x1_gt_root);
scoped_anum one(am), one_dup(am);
am.set(one, 1);
assignment.set(x0, one);
s.set_rvalues(assignment);
nlsat::scoped_literal_vector result(s);
ex.compute_conflict_explanation(lits.size(), lits.data(), result);
std::cout << "main_operator root regression core:\n";
s.display(std::cout, lits.size(), lits.data());
s.display(std::cout << "\n==>\n", result.size(), result.data());
std::cout << "\n";
am.set(one_dup, 1);
assignment.set(x1, one_dup);
s.set_rvalues(assignment);
small_object_allocator allocator;
nlsat::evaluator eval(s, assignment, pm, allocator);
std::cout << "input literal values at x0 = 1, x1 = 1:\n";
for (nlsat::literal l : lits) {
nlsat::atom* a = s.bool_var2atom(l.var());
if (!a) {
std::cout << "conversion bug\n";
}
bool value = a ? eval.eval(a, l.sign()) : false;
s.display(std::cout << " ", l);
std::cout << " -> " << (value ? "true" : "false") << "\n";
}
std::cout << "new literal values at x0 = 1, x1 = 1:\n";
for (nlsat::literal l : result) {
nlsat::atom* a = s.bool_var2atom(l.var());
bool value = a ? eval.eval(a, l.sign()) : false;
if (!a) {
std::cout << "conversion bug\n";
}
s.display(std::cout << " ", l);
std::cout << " -> " << (value ? "true" : "false") << "\n";
}
std::cout << "\n";
}
static void tst11() {
params_ref ps;
reslimit rlim;
nlsat::solver s(rlim, ps, false);
anum_manager & am = s.am();
nlsat::pmanager & pm = s.pm();
nlsat::assignment as(am);
nlsat::explain& ex = s.get_explain();
nlsat::var x, y, z;
y = s.mk_var(false);
z = s.mk_var(false);
x = s.mk_var(false);
polynomial_ref p1(pm), p2(pm), _x(pm), _y(pm), _z(pm);
_x = pm.mk_polynomial(x);
_y = pm.mk_polynomial(y);
_z = pm.mk_polynomial(z);
nlsat::scoped_literal_vector lits(s);
scoped_anum zero(am), one(am), five(am);
am.set(zero, 0);
am.set(one, 1);
am.set(five, 5);
as.set(z, zero);
as.set(y, five);
as.set(x, five);
s.set_rvalues(as);
p1 = (_x - _y);
p2 = ((_x*_x) - (_x*_y) - _z);
lits.reset();
lits.push_back(mk_gt(s, p1));
lits.push_back(mk_eq(s, p2));
project_fa(s, ex, x, 2, lits.data());
p1 = ((_x * _x) - (2 * _y * _x) - _z + (_y *_y));
p2 = _x + _y;
as.set(_x, one);
as.set(_y, zero);
as.set(_z, one);
lits.reset();
lits.push_back(mk_lt(s, p1));
lits.push_back(mk_eq(s, p2));
project_fa(s, ex, x, 2, lits.data());
return;
as.set(z, zero);
as.set(y, five);
as.set(x, five);
p1 = (_x - _y);
p2 = ((_x*_x) - (_x*_y));
lits.reset();
lits.push_back(mk_gt(s, p1));
lits.push_back(mk_eq(s, p2));
project_fa(s, ex, x, 2, lits.data());
#if 0#endif
}
static void tst_14() {
params_ref ps;
reslimit rlim;
nlsat::solver s(rlim, ps, false);
nlsat::pmanager& pm = s.pm();
polynomial::cache cache(pm);
nlsat::var x = s.mk_var(false);
polynomial_ref x_poly(pm);
x_poly = pm.mk_polynomial(x);
polynomial_ref p(pm);
p = 2 * x_poly;
pm.display(std::cout, p);
std::cout << "\n";
ENSURE(!cache.contains(p.get()));
polynomial::polynomial* unique_p = cache.mk_unique(p.get());
ENSURE(unique_p != nullptr);
ENSURE(cache.contains(unique_p));
pm.display(std::cout, unique_p);
std::cout << "\n";
polynomial_ref p_again(pm);
p_again = 2 * x_poly;
ENSURE(cache.mk_unique(p_again.get()) == unique_p);
polynomial_ref p_neg(pm);
p_neg = -2 * x_poly;
ENSURE(!cache.contains(p_neg.get()));
polynomial::polynomial* unique_p_neg = cache.mk_unique(p_neg.get());
ENSURE(unique_p_neg != nullptr);
ENSURE(unique_p_neg != unique_p);
ENSURE(cache.contains(unique_p_neg));
polynomial_ref p_neg_again(pm);
p_neg_again = -2 * x_poly;
ENSURE(cache.mk_unique(p_neg_again.get()) == unique_p_neg);
polynomial_ref ca(p, pm), cb(p_neg, pm);
pm.primitive(ca, x, ca);
pm.primitive(cb, x, cb);
pm.display(std::cout << "ca:", ca) << "\n";
pm.display(std::cout << "cb:", cb) << "\n";
}
static void tst_15() {
params_ref ps;
reslimit rlim;
nlsat::solver s(rlim, ps, false);
nlsat::pmanager & pm = s.pm();
anum_manager & am = s.am();
polynomial::cache cache(pm);
nlsat::var x0 = s.mk_var(false);
nlsat::var x1 = s.mk_var(false);
nlsat::var x2 = s.mk_var(false);
nlsat::var x3 = s.mk_var(false);
ENSURE(x0 < x1 && x1 < x2);
polynomial_ref _x0(pm), _x1(pm), _x2(pm), _x3(pm);
_x0 = pm.mk_polynomial(x0);
_x1 = pm.mk_polynomial(x1);
_x2 = pm.mk_polynomial(x2);
_x3 = pm.mk_polynomial(x3);
polynomial_ref p1(pm), p2(pm);
p1 = _x2 * _x1;
p2 = _x0;
p1 = p1 + p2;
p2 = _x3;
polynomial_ref_vector polys(pm);
polys.push_back(p1);
polys.push_back(p2);
nlsat::assignment as(am);
scoped_anum zero(am);
am.set(zero, 0);
as.set(x0, zero);
as.set(x1, zero);
as.set(x2, zero);
as.set(x3, zero);
s.set_rvalues(as);
unsigned max_x = 0;
for (unsigned i = 0; i < polys.size(); ++i) {
unsigned lvl = pm.max_var(polys.get(i));
if (lvl > max_x)
max_x = lvl;
}
ENSURE(max_x == x3);
nlsat::levelwise lws(s, polys, max_x, s.sample(), pm, am, cache);
auto cell = lws.single_cell();
}
static void tst_16() {
auto run_test = [](bool use_lws) {
std::cout << "=== tst_16: " << (use_lws ? "Levelwise" : "Standard") << " projection (lws=" << use_lws << ") ===\n";
params_ref ps;
ps.set_bool("lws", use_lws);
reslimit rlim;
nlsat::solver s(rlim, ps, false);
anum_manager & am = s.am();
nlsat::pmanager & pm = s.pm();
nlsat::assignment as(am);
nlsat::explain& ex = s.get_explain();
nlsat::var x0 = s.mk_var(false);
nlsat::var x1 = s.mk_var(false);
nlsat::var x2 = s.mk_var(false);
nlsat::var x3 = s.mk_var(false);
nlsat::var x4 = s.mk_var(false);
nlsat::var x5 = s.mk_var(false);
nlsat::var x6 = s.mk_var(false);
nlsat::var x7 = s.mk_var(false);
nlsat::var x8 = s.mk_var(false);
nlsat::var x9 = s.mk_var(false);
nlsat::var x10 = s.mk_var(false);
nlsat::var x11 = s.mk_var(false);
nlsat::var x12 = s.mk_var(false);
nlsat::var x13 = s.mk_var(false);
polynomial_ref _x0(pm), _x1(pm), _x2(pm), _x3(pm), _x4(pm), _x5(pm), _x6(pm);
polynomial_ref _x7(pm), _x8(pm), _x9(pm), _x10(pm), _x11(pm), _x12(pm), _x13(pm);
_x0 = pm.mk_polynomial(x0);
_x1 = pm.mk_polynomial(x1);
_x2 = pm.mk_polynomial(x2);
_x3 = pm.mk_polynomial(x3);
_x4 = pm.mk_polynomial(x4);
_x5 = pm.mk_polynomial(x5);
_x6 = pm.mk_polynomial(x6);
_x7 = pm.mk_polynomial(x7);
_x8 = pm.mk_polynomial(x8);
_x9 = pm.mk_polynomial(x9);
_x10 = pm.mk_polynomial(x10);
_x11 = pm.mk_polynomial(x11);
_x12 = pm.mk_polynomial(x12);
_x13 = pm.mk_polynomial(x13);
polynomial_ref p0(pm);
p0 = _x13;
polynomial_ref p1(pm);
p1 = (170 * _x8 * _x13) +
(_x10 * _x11 * _x12) -
(_x11 * _x12) -
(_x7 * _x8 * _x12) +
(_x5 * _x10 * _x11) +
(184 * _x1 * _x10 * _x11) -
(_x0 * _x10 * _x11) -
(_x5 * _x11) -
(184 * _x1 * _x11) +
(_x0 * _x11) -
(_x3 * _x8 * _x10) +
(_x2 * _x8 * _x10) -
(2 * _x10) -
(184 * _x1 * _x7 * _x8) -
(_x2 * _x8) +
2;
std::cout << "p0: " << p0 << "\n";
std::cout << "p1: " << p1 << "\n";
scoped_anum val(am);
am.set(val, -1); as.set(x0, val);
am.set(val, -1); as.set(x1, val);
am.set(val, 0); as.set(x2, val);
am.set(val, -1); as.set(x3, val);
am.set(val, 0); as.set(x4, val);
am.set(val, 0); as.set(x5, val);
am.set(val, 0); as.set(x6, val);
am.set(val, 0); as.set(x7, val);
am.set(val, 2); as.set(x8, val);
am.set(val, 0); as.set(x9, val);
am.set(val, 0); as.set(x10, val);
am.set(val, 0); as.set(x11, val);
am.set(val, 2); as.set(x12, val);
am.set(val, 1); as.set(x13, val);
s.set_rvalues(as);
nlsat::scoped_literal_vector lits(s);
lits.push_back(mk_gt(s, p0.get())); lits.push_back(mk_gt(s, p1.get()));
auto result = project_fa(s, ex, x13, lits.size(), lits.data());
std::cout << "\n";
ENSURE(clause_contains_root_dependency(s, result, nlsat::atom::ROOT_EQ, x11, 1, x7, x8, x10));
};
run_test(false); run_test(true); }
static void tst_17() {
std::cout << "=== tst_17 ===\n";
params_ref ps;
ps.set_bool("lws", true);
reslimit rlim;
nlsat::solver s(rlim, ps, false);
anum_manager & am = s.am();
nlsat::pmanager & pm = s.pm();
nlsat::assignment sample_as(am);
nlsat::assignment counter_as(am);
polynomial::cache cache(pm);
nlsat::var x0 = s.mk_var(false);
nlsat::var x1 = s.mk_var(false);
nlsat::var x2 = s.mk_var(false);
nlsat::var x3 = s.mk_var(false);
polynomial_ref _x0(pm), _x1(pm), _x2(pm), _x3(pm);
_x0 = pm.mk_polynomial(x0);
_x1 = pm.mk_polynomial(x1);
_x2 = pm.mk_polynomial(x2);
_x3 = pm.mk_polynomial(x3);
polynomial_ref p0(pm);
p0 = _x3 + _x0;
polynomial_ref p1(pm);
p1 = _x1;
polynomial_ref p2(pm);
p2 = 9 * (_x1^2) * (_x3^2)
- 6 * _x0 * _x1 * _x2 * _x3
+ 3 * _x0 * (_x1^2) * _x3
- 12 * (_x1^2) * _x3
+ (_x0^2) * (_x2^2)
- (_x0^2) * _x1 * _x2
- 4 * _x0 * _x1 * _x2
+ 2 * _x0 * (_x1^2)
+ 4 * (_x1^2);
polynomial_ref p3(pm);
p3 = 9 * (_x1^2) * (_x3^2)
- 6 * _x0 * _x1 * _x2 * _x3
+ 6 * _x0 * (_x1^2) * _x3
- 12 * (_x1^2) * _x3
+ (_x0^2) * (_x2^2)
- 2 * (_x0^2) * _x1 * _x2
- 4 * _x0 * _x1 * _x2
+ (_x0^2) * (_x1^2)
+ 4 * _x0 * (_x1^2)
+ 4 * (_x1^2);
polynomial_ref p4(pm);
p4 = _x3 + _x1 + _x0;
scoped_anum val(am);
am.set(val, -7); sample_as.set(x0, val);
am.set(val, -1); sample_as.set(x1, val);
am.set(val, 1); sample_as.set(x2, val);
am.set(val, 8); sample_as.set(x3, val);
am.set(val, -4); counter_as.set(x0, val);
am.set(val, -8); counter_as.set(x1, val);
am.set(val, 5); counter_as.set(x2, val);
am.set(val, 6); counter_as.set(x3, val);
s.set_rvalues(sample_as);
polynomial_ref_vector polys(pm);
polys.push_back(p0);
polys.push_back(p1);
polys.push_back(p2);
polys.push_back(p3);
polys.push_back(p4);
unsigned max_x = x3;
nlsat::levelwise lws(s, polys, max_x, s.sample(), pm, am, cache);
auto cell = lws.single_cell();
ENSURE(has_different_sign(am, pm, polys, sample_as, counter_as));
ENSURE(!is_point_inside_cell(am, pm, cell, counter_as));
std::cout << "=== END tst_17 ===\n\n";
}
static void tst_18() {
std::cout << "=== tst_18 ===\n";
params_ref ps;
ps.set_bool("lws", true);
reslimit rlim;
nlsat::solver s(rlim, ps, false);
anum_manager & am = s.am();
nlsat::pmanager & pm = s.pm();
nlsat::assignment sample_as(am);
nlsat::assignment counter_as(am);
polynomial::cache cache(pm);
nlsat::var x0 = s.mk_var(false);
nlsat::var x1 = s.mk_var(false);
nlsat::var x2 = s.mk_var(false);
nlsat::var x3 = s.mk_var(false);
nlsat::var x4 = s.mk_var(false);
nlsat::var x5 = s.mk_var(false);
nlsat::var x6 = s.mk_var(false);
nlsat::var x7 = s.mk_var(false);
polynomial_ref _x0(pm), _x1(pm), _x2(pm), _x3(pm), _x4(pm), _x5(pm), _x6(pm), _x7(pm);
_x0 = pm.mk_polynomial(x0);
_x1 = pm.mk_polynomial(x1);
_x2 = pm.mk_polynomial(x2);
_x3 = pm.mk_polynomial(x3);
_x4 = pm.mk_polynomial(x4);
_x5 = pm.mk_polynomial(x5);
_x6 = pm.mk_polynomial(x6);
_x7 = pm.mk_polynomial(x7);
(void)_x1;
polynomial_ref p0(pm);
p0 = _x2;
polynomial_ref p1(pm);
p1 = _x2 * (_x6^2) + _x0 * _x5 * _x6 + _x2 * _x4 * _x6 + _x2 * _x3 * _x6 - _x0 * _x6 - _x0 * _x4;
polynomial_ref p2(pm);
p2 = _x2 * (_x6^2) * _x7 + _x0 * _x5 * _x6 * _x7 + _x2 * _x4 * _x6 * _x7
+ _x2 * _x3 * _x6 * _x7 - _x0 * _x6 * _x7 - _x0 * _x4 * _x7
+ 2 * _x6 + 2 * _x4;
polynomial_ref p3(pm);
p3 = _x6;
polynomial_ref p4(pm);
p4 = _x2 * _x6 * _x7 - 2;
scoped_anum val(am);
rational q(7, 8);
am.set(val, 1); sample_as.set(x0, val);
am.set(val, 2); sample_as.set(x1, val);
am.set(val, 1); sample_as.set(x2, val);
am.set(val, -1); sample_as.set(x3, val);
am.set(val, -1); sample_as.set(x4, val);
am.set(val, 1); sample_as.set(x5, val);
am.set(val, q.to_mpq()); sample_as.set(x6, val);
am.set(val, 1); counter_as.set(x0, val);
am.set(val, 0); counter_as.set(x1, val);
am.set(val, 1); counter_as.set(x2, val);
am.set(val, 0); counter_as.set(x3, val);
am.set(val, -9); counter_as.set(x4, val);
am.set(val, 0); counter_as.set(x5, val);
am.set(val, 5); counter_as.set(x6, val);
am.set(val, 0); counter_as.set(x7, val);
s.set_rvalues(sample_as);
polynomial_ref_vector polys(pm);
polys.push_back(p0);
polys.push_back(p1);
polys.push_back(p2);
polys.push_back(p3);
polys.push_back(p4);
nlsat::var max_x = x7;
nlsat::levelwise lws(s, polys, max_x, s.sample(), pm, am, cache);
auto cell = lws.single_cell();
ENSURE(cell.size() > 4);
ENSURE(cell[4].section);
ENSURE(has_different_sign(am, pm, polys, sample_as, counter_as));
ENSURE(!is_point_inside_cell(am, pm, cell, counter_as));
std::cout << "=== END tst_18 ===\n\n";
}
static void tst_19() {
std::cout << "=== tst_19 ===\n";
params_ref ps;
ps.set_bool("lws", true);
reslimit rlim;
nlsat::solver s(rlim, ps, false);
anum_manager & am = s.am();
nlsat::pmanager & pm = s.pm();
nlsat::assignment sample_as(am);
nlsat::assignment counter_as(am);
polynomial::cache cache(pm);
nlsat::var x0 = s.mk_var(false);
nlsat::var x1 = s.mk_var(false);
nlsat::var x2 = s.mk_var(false);
nlsat::var x3 = s.mk_var(false);
nlsat::var x4 = s.mk_var(false);
nlsat::var x5 = s.mk_var(false);
polynomial_ref _x0(pm), _x1(pm), _x2(pm), _x3(pm), _x4(pm), _x5(pm);
_x0 = pm.mk_polynomial(x0);
_x1 = pm.mk_polynomial(x1);
_x2 = pm.mk_polynomial(x2);
_x3 = pm.mk_polynomial(x3);
_x4 = pm.mk_polynomial(x4);
_x5 = pm.mk_polynomial(x5);
polynomial_ref p0(pm);
p0 = _x0;
polynomial_ref p1(pm);
p1 = 2 * _x0 * (_x4^2) + 2 * _x3 * _x4 - _x0 * _x4 - 2 * _x3;
polynomial_ref p2(pm);
p2 = 2 * _x0 * (_x4^2) * _x5
+ 2 * _x3 * _x4 * _x5
- _x0 * _x4 * _x5
- 2 * _x3 * _x5
+ 4 * _x3 * (_x4^2)
+ 9 * _x0 * _x3 * _x4
- 26 * _x3 * _x4
- 3 * _x0 * _x4;
polynomial_ref p3(pm);
p3 = _x5 - 9;
scoped_anum val(am);
am.set(val, 4); sample_as.set(x0, val);
am.set(val, 5); sample_as.set(x1, val);
rational q(7, 2); am.set(val, q.to_mpq()); sample_as.set(x2, val);
am.set(val, -8); sample_as.set(x3, val);
am.set(val, 5); sample_as.set(x4, val);
am.set(val, 5); counter_as.set(x0, val);
am.set(val, 5); counter_as.set(x1, val);
am.set(val, q.to_mpq()); counter_as.set(x2, val);
am.set(val, 3); counter_as.set(x3, val);
am.set(val, 0); counter_as.set(x4, val);
am.set(val, 0); counter_as.set(x5, val);
nlsat::assignment sample_full(am);
am.set(val, 4); sample_full.set(x0, val);
am.set(val, 5); sample_full.set(x1, val);
am.set(val, q.to_mpq()); sample_full.set(x2, val);
am.set(val, -8); sample_full.set(x3, val);
am.set(val, 5); sample_full.set(x4, val);
am.set(val, 0); sample_full.set(x5, val);
s.set_rvalues(sample_as);
polynomial_ref_vector polys(pm);
polys.push_back(p0);
polys.push_back(p1);
polys.push_back(p2);
polys.push_back(p3);
unsigned max_x = x5;
nlsat::levelwise lws(s, polys, max_x, s.sample(), pm, am, cache);
auto cell = lws.single_cell();
ENSURE(has_different_sign(am, pm, polys, sample_full, counter_as));
ENSURE(!is_point_inside_cell(am, pm, cell, counter_as));
std::cout << "=== END tst_19 ===\n\n";
}
static void tst_20() {
std::cout << "=== tst_20 ===\n";
params_ref ps;
ps.set_bool("lws", true);
reslimit rlim;
nlsat::solver s(rlim, ps, false);
anum_manager & am = s.am();
nlsat::pmanager & pm = s.pm();
nlsat::assignment sample_as(am);
nlsat::assignment counter_as(am);
polynomial::cache cache(pm);
nlsat::var x0 = s.mk_var(false);
nlsat::var x1 = s.mk_var(false);
nlsat::var x2 = s.mk_var(false);
nlsat::var x3 = s.mk_var(false);
polynomial_ref _x0(pm), _x1(pm), _x2(pm), _x3(pm);
_x0 = pm.mk_polynomial(x0);
_x1 = pm.mk_polynomial(x1);
_x2 = pm.mk_polynomial(x2);
_x3 = pm.mk_polynomial(x3);
(void)_x0;
polynomial_ref p0(pm);
p0 = -(_x2^3) + (_x1^3) * _x2 - (_x1^4);
polynomial_ref p1(pm);
p1 = -(_x2^3) * _x3 + (_x1^3) * _x2 * _x3 - (_x1^4) * _x3
- (_x2^3) + (_x1^3) * (_x2^2) + 4 * (_x1^4) * _x2 - (_x1^3) * _x2 - (_x1^5) - (_x1^4);
polynomial_ref p2(pm);
p2 = _x3;
std::cout << "Input polynomials:\n";
std::cout << " p0: " << p0 << "\n";
std::cout << " p1: " << p1 << "\n";
std::cout << " p2: " << p2 << "\n\n";
scoped_anum val(am);
am.set(val, 1); sample_as.set(x0, val);
am.set(val, 1); sample_as.set(x1, val);
am.set(val, 1); sample_as.set(x2, val);
std::cout << "Sample point: x0=1, x1=1, x2=1\n";
am.set(val, 1); counter_as.set(x0, val);
am.set(val, 12); counter_as.set(x1, val);
am.set(val, 16); counter_as.set(x2, val);
am.set(val, 0); counter_as.set(x3, val);
std::cout << "Counterexample: x1=12, x2=16, x3=0\n\n";
s.set_rvalues(sample_as);
polynomial_ref_vector polys(pm);
polys.push_back(p0);
polys.push_back(p1);
polys.push_back(p2);
nlsat::var max_x = x3;
std::cout << "Running levelwise with max_x = x3...\n";
nlsat::levelwise lws(s, polys, max_x, s.sample(), pm, am, cache);
auto cell = lws.single_cell();
std::cout << "Cell intervals:\n";
for (unsigned i = 0; i < cell.size(); ++i) {
std::cout << " Level " << i << ": ";
nlsat::display(std::cout, s, cell[i]) << "\n";
}
std::cout << "\n--- LEMMA from levelwise ---\n";
for (unsigned i = 0; i < cell.size(); ++i) {
auto const& interval = cell[i];
if (interval.section) {
std::cout << "!(x" << i << " = root[" << interval.l_index << "](";
pm.display(std::cout, interval.l) << "))\n";
} else {
if (!interval.l_inf()) {
std::cout << "!(x" << i << " > root[" << interval.l_index << "](";
pm.display(std::cout, interval.l) << "))\n";
}
if (!interval.u_inf()) {
std::cout << "!(x" << i << " < root[" << interval.u_index << "](";
pm.display(std::cout, interval.u) << "))\n";
}
}
}
std::cout << "--- END LEMMA ---\n\n";
std::cout << "=== Checking sign of p0 (projection poly) ===\n";
sign p0_sample = am.eval_sign_at(p0, sample_as);
sign p0_counter = am.eval_sign_at(p0, counter_as);
std::cout << " p0 at sample (x1=1, x2=1): " << p0_sample << "\n";
std::cout << " p0 at counter (x1=12, x2=16): " << p0_counter << "\n";
std::cout << " Signs " << (p0_sample == p0_counter ? "match" : "DIFFER") << "\n";
std::cout << "\n=== Checking if counterexample is in the cell ===\n";
bool counter_outside = false;
std::cout << "Level 0: (-oo, +oo) -> counter inside\n";
{
auto const& interval = cell[1];
if (!interval.l_inf()) {
polynomial_ref lower_p(interval.l, pm);
scoped_anum_vector lower_roots(am);
nlsat::assignment partial_as(am);
scoped_anum val0(am);
am.set(val0, 1); partial_as.set(x0, val0);
am.isolate_roots(lower_p, nlsat::undef_var_assignment(partial_as, 1), lower_roots);
if (lower_roots.size() >= interval.l_index) {
scoped_anum counter_x1(am);
am.set(counter_x1, 12);
int cmp = am.compare(counter_x1, lower_roots[interval.l_index - 1]);
std::cout << "Level 1 lower bound: root[" << interval.l_index << "] of poly, counter x1=12 is "
<< (cmp > 0 ? "ABOVE" : (cmp < 0 ? "BELOW" : "AT")) << " lower bound\n";
if (cmp <= 0) counter_outside = true;
}
}
if (!interval.u_inf()) {
polynomial_ref upper_p(interval.u, pm);
scoped_anum_vector upper_roots(am);
nlsat::assignment partial_as(am);
scoped_anum val0(am);
am.set(val0, 1); partial_as.set(x0, val0);
am.isolate_roots(upper_p, nlsat::undef_var_assignment(partial_as, 1), upper_roots);
if (upper_roots.size() >= interval.u_index) {
scoped_anum counter_x1(am);
am.set(counter_x1, 12);
int cmp = am.compare(counter_x1, upper_roots[interval.u_index - 1]);
std::cout << "Level 1 upper bound: root[" << interval.u_index << "] of poly, counter x1=12 is "
<< (cmp > 0 ? "ABOVE" : (cmp < 0 ? "BELOW" : "AT")) << " upper bound\n";
if (cmp >= 0) counter_outside = true;
}
}
}
ENSURE(has_different_sign(am, pm, polys, sample_as, counter_as));
if (p0_sample != p0_counter) {
std::cout << "\nPoly signs differ between sample and counter.\n";
std::cout << "For cell to be sound, counter must be OUTSIDE the cell.\n";
std::cout << "Counter is " << (counter_outside ? "OUTSIDE" : "INSIDE") << " the cell.\n";
ENSURE(counter_outside); } else {
std::cout << "\nPoly signs match - cell is trivially sound.\n";
}
std::cout << "\n=== END tst_20 ===\n\n";
}
static void tst_21() {
std::cout << "=== tst_21 ===\n";
params_ref ps;
ps.set_bool("lws", true);
reslimit rlim;
nlsat::solver s(rlim, ps, false);
anum_manager & am = s.am();
nlsat::pmanager & pm = s.pm();
polynomial::cache cache(pm);
nlsat::var vars[25];
polynomial_ref xvars[25] = {
polynomial_ref(pm), polynomial_ref(pm), polynomial_ref(pm), polynomial_ref(pm), polynomial_ref(pm),
polynomial_ref(pm), polynomial_ref(pm), polynomial_ref(pm), polynomial_ref(pm), polynomial_ref(pm),
polynomial_ref(pm), polynomial_ref(pm), polynomial_ref(pm), polynomial_ref(pm), polynomial_ref(pm),
polynomial_ref(pm), polynomial_ref(pm), polynomial_ref(pm), polynomial_ref(pm), polynomial_ref(pm),
polynomial_ref(pm), polynomial_ref(pm), polynomial_ref(pm), polynomial_ref(pm), polynomial_ref(pm)
};
for (unsigned i = 0; i < 25; i++) {
vars[i] = s.mk_var(false);
xvars[i] = pm.mk_polynomial(vars[i]);
}
polynomial_ref &x2 = xvars[2], &x4 = xvars[4], &x5 = xvars[5];
polynomial_ref &x9 = xvars[9], &x10 = xvars[10], &x11 = xvars[11];
polynomial_ref &x12 = xvars[12], &x13 = xvars[13], &x15 = xvars[15];
polynomial_ref &x16 = xvars[16], &x19 = xvars[19], &x24 = xvars[24];
polynomial_ref p0(pm);
p0 = x16 + x9;
polynomial_ref p1(pm);
p1 = x16 * x24 + x9 * x24 + x13 * x19 + x5 * x19 + x12 * x15 + x10 * x15 - 2;
polynomial_ref p2(pm);
p2 = x4;
polynomial_ref p3(pm);
p3 = x4 * x24 + x2 * x19 + x11 * x15;
std::cout << "Input polynomials:\n";
std::cout << " p0: " << p0 << "\n";
std::cout << " p1: " << p1 << "\n";
std::cout << " p2: " << p2 << "\n";
std::cout << " p3: " << p3 << "\n\n";
int sample_vals[24] = {1, 1, -1, -1, 1, -1, 1, 2, 1, 1, -1, 1, -2, -2, -2, 0, 2, 0, 0, 0, 0, 0, 0, 0};
scoped_anum val(am);
nlsat::assignment sample_as(am);
for (unsigned i = 0; i < 24; i++) {
am.set(val, sample_vals[i]);
sample_as.set(vars[i], val);
}
s.set_rvalues(sample_as);
std::cout << "Sample point (x0..x23):\n";
for (unsigned i = 0; i < 24; i++) {
std::cout << " x" << i << " -> " << sample_vals[i] << "\n";
}
std::cout << "\n";
am.set(val, 0);
sample_as.set(vars[24], val);
std::cout << "Polynomial signs at sample (x24=0):\n";
std::cout << " p0 sign: " << am.eval_sign_at(p0, sample_as) << "\n";
std::cout << " p1 sign: " << am.eval_sign_at(p1, sample_as) << "\n";
std::cout << " p2 sign: " << am.eval_sign_at(p2, sample_as) << "\n";
std::cout << " p3 sign: " << am.eval_sign_at(p3, sample_as) << "\n\n";
nlsat::assignment counter_as(am);
am.set(val, -1); counter_as.set(vars[2], val);
am.set(val, 1); counter_as.set(vars[4], val);
am.set(val, 0); counter_as.set(vars[5], val);
am.set(val, 0); counter_as.set(vars[9], val);
am.set(val, 0); counter_as.set(vars[10], val);
am.set(val, -1); counter_as.set(vars[11], val);
am.set(val, -1); counter_as.set(vars[12], val);
am.set(val, -2); counter_as.set(vars[13], val);
am.set(val, 3); counter_as.set(vars[15], val);
am.set(val, 2); counter_as.set(vars[16], val);
am.set(val, 0); counter_as.set(vars[19], val);
am.set(val, 3); counter_as.set(vars[24], val);
std::cout << "Counterexample point:\n";
std::cout << " x2=-1, x4=1, x5=0, x9=0, x10=0, x11=-1, x12=-1, x13=-2, x15=3, x16=2, x19=0, x24=3\n\n";
std::cout << "Polynomial signs at counterexample:\n";
std::cout << " p0 sign: " << am.eval_sign_at(p0, counter_as) << "\n";
std::cout << " p1 sign: " << am.eval_sign_at(p1, counter_as) << "\n";
std::cout << " p2 sign: " << am.eval_sign_at(p2, counter_as) << "\n";
std::cout << " p3 sign: " << am.eval_sign_at(p3, counter_as) << "\n\n";
polynomial_ref_vector polys(pm);
polys.push_back(p0);
polys.push_back(p1);
polys.push_back(p2);
polys.push_back(p3);
unsigned max_x = vars[24];
std::cout << "Running levelwise with max_x = x24...\n";
nlsat::levelwise lws(s, polys, max_x, s.sample(), pm, am, cache);
auto cell = lws.single_cell();
std::cout << "Levelwise succeeded\n";
std::cout << "--- LEMMA from levelwise ---\n";
for (unsigned i = 0; i < cell.size(); i++) {
auto const& interval = cell[i];
std::cout << "Level x" << i << ": ";
if (interval.is_section()) {
std::cout << "section at root[" << interval.l_index << "] of " << interval.l << "\n";
} else {
if (interval.l_inf())
std::cout << "(-oo, ";
else
std::cout << "(root[" << interval.l_index << "] of " << interval.l << ", ";
if (interval.u_inf())
std::cout << "+oo)";
else
std::cout << "root[" << interval.u_index << "] of " << interval.u << ")";
std::cout << "\n";
}
std::cout << "--- END LEMMA ---\n\n";
ENSURE(has_different_sign(am, pm, polys, sample_as, counter_as));
std::cout << "\nChecking if counterexample is inside cell:\n";
bool inside = is_point_inside_cell(am, pm, cell, counter_as);
ENSURE(!inside);
std::cout << "SUCCESS: Counterexample is OUTSIDE the cell (cell is sound)\n";
}
std::cout << "=== END tst_21 ===\n\n";
}
static void tst_22() {
std::cout << "=== tst_22 ===\n";
auto run_test = [](bool use_lws) {
std::cout << "\n--- Running with lws=" << (use_lws ? "true" : "false") << " ---\n";
params_ref ps;
ps.set_bool("lws", use_lws);
reslimit rlim;
nlsat::solver s(rlim, ps, false);
anum_manager& am = s.am();
nlsat::pmanager& pm = s.pm();
nlsat::explain& ex = s.get_explain();
nlsat::var x0 = s.mk_var(false);
nlsat::var x1 = s.mk_var(false);
nlsat::var x2 = s.mk_var(false);
nlsat::var x3 = s.mk_var(false);
nlsat::var x4 = s.mk_var(false);
nlsat::var x5 = s.mk_var(false);
nlsat::var x6 = s.mk_var(false);
(void)x0; (void)x2; (void)x3; (void)x4;
polynomial_ref _x1(pm), _x5(pm), _x6(pm);
_x1 = pm.mk_polynomial(x1);
_x5 = pm.mk_polynomial(x5);
_x6 = pm.mk_polynomial(x6);
polynomial_ref p_main(pm);
p_main = 4*_x6*_x6*_x6 + 4*_x5*_x6*_x6 - 4*_x1*_x6*_x6 + 4*_x6*_x6 - 4*_x1*_x5*_x6 - 4*_x1*_x6;
polynomial_ref p_diff(pm);
p_diff = _x6 - _x1;
polynomial_ref p_root1(pm);
p_root1 = 1024*_x1*_x1*_x1 + 6144*_x1*_x1 + 6144*_x1;
polynomial_ref p_root2(pm);
p_root2 = 2048*_x1*_x1*_x1 + 6144*_x1*_x1 + 4096*_x1;
polynomial_ref p_x1_eq(pm);
p_x1_eq = 1024*_x1;
polynomial_ref p_x1_gt(pm);
p_x1_gt = _x1 + 1;
polynomial_ref p_x1_eq2(pm);
p_x1_eq2 = 2048*_x1*_x1 + 4096*_x1;
std::cout << "p_main: " << p_main << "\n";
std::cout << "p_diff: " << p_diff << "\n";
std::cout << "p_root1: " << p_root1 << "\n";
std::cout << "p_root2: " << p_root2 << "\n";
nlsat::assignment sample_as(am);
scoped_anum val(am);
am.set(val, -1); sample_as.set(x0, val);
am.set(val, 0); sample_as.set(x1, val);
am.set(val, 0); sample_as.set(x2, val);
am.set(val, -1); sample_as.set(x3, val);
am.set(val, 0); sample_as.set(x4, val);
am.set(val, -1); sample_as.set(x5, val);
am.set(val, 0); sample_as.set(x6, val);
s.set_rvalues(sample_as);
nlsat::scoped_literal_vector lits(s);
lits.push_back(mk_gt(s, p_diff.get())); lits.push_back(mk_lt(s, p_main.get()));
lits.push_back(mk_eq(s, p_x1_eq.get())); lits.push_back(mk_gt(s, p_x1_gt.get())); lits.push_back(mk_eq(s, p_x1_eq2.get())); lits.push_back(mk_root_eq(s, p_root1.get(), x1, 3)); lits.push_back(mk_root_eq(s, p_root2.get(), x1, 3)); lits.push_back(mk_eq(s, _x1.get()));
std::cout << "Input literals:\n";
s.display(std::cout, lits.size(), lits.data());
std::cout << "\n";
nlsat::scoped_literal_vector result(s);
ex.compute_conflict_explanation(lits.size(), lits.data(), result);
std::cout << "Result lemma (lws=" << (use_lws ? "true" : "false") << "):\n";
std::cout << "(or";
for (auto l : result) {
s.display(std::cout << "\n ", l);
}
for (unsigned i = 0; i < lits.size(); ++i) {
s.display(std::cout << "\n ", ~lits[i]);
}
std::cout << "\n)\n";
nlsat::assignment counter_as(am);
am.set(val, -1); counter_as.set(x0, val);
am.set(val, 0); counter_as.set(x1, val);
am.set(val, 0); counter_as.set(x2, val);
am.set(val, -1); counter_as.set(x3, val);
am.set(val, 0); counter_as.set(x4, val);
am.set(val, 0); counter_as.set(x5, val); mpq half; am.qm().set(half, -1, 2); am.set(val, half); counter_as.set(x6, val);
std::cout << "\nEvaluating at counterexample (x1=0, x5=0, x6=-0.5):\n";
small_object_allocator allocator;
nlsat::evaluator eval(s, counter_as, pm, allocator);
bool all_false = true;
for (auto l : result) {
nlsat::atom* a = s.bool_var2atom(l.var());
if (a) {
bool value = eval.eval(a, l.sign());
s.display(std::cout << " ", l);
std::cout << " -> " << (value ? "TRUE" : "FALSE") << "\n";
if (value) all_false = false;
}
}
for (unsigned i = 0; i < lits.size(); ++i) {
nlsat::literal nl = ~lits[i];
nlsat::atom* a = s.bool_var2atom(nl.var());
if (a) {
bool value = eval.eval(a, nl.sign());
s.display(std::cout << " ", nl);
std::cout << " -> " << (value ? "TRUE" : "FALSE") << "\n";
if (value) all_false = false;
}
}
if (all_false)
std::cout << "*** ALL literals FALSE at counterexample - LEMMA IS UNSOUND! ***\n";
else
std::cout << "At least one literal is TRUE - lemma is sound at this point\n";
ENSURE(!all_false);
};
run_test(false); run_test(true);
std::cout << "\n=== END tst_22 ===\n\n";
}
static void tst_23() {
std::cout << "=== tst_23 ===\n";
params_ref ps;
ps.set_bool("lws", true);
reslimit rlim;
nlsat::solver s(rlim, ps, false);
anum_manager & am = s.am();
nlsat::pmanager & pm = s.pm();
nlsat::assignment sample_as(am);
nlsat::assignment counter_as(am);
polynomial::cache cache(pm);
nlsat::var x0 = s.mk_var(false);
nlsat::var x1 = s.mk_var(false);
nlsat::var x2 = s.mk_var(false);
nlsat::var x3 = s.mk_var(false);
nlsat::var x4 = s.mk_var(false);
nlsat::var x5 = s.mk_var(false);
nlsat::var x6 = s.mk_var(false);
polynomial_ref _x2(pm), _x3(pm), _x4(pm), _x5(pm), _x6(pm);
_x2 = pm.mk_polynomial(x2);
_x3 = pm.mk_polynomial(x3);
_x4 = pm.mk_polynomial(x4);
_x5 = pm.mk_polynomial(x5);
_x6 = pm.mk_polynomial(x6);
polynomial_ref p0(pm), p1(pm), p2(pm);
p0 = -_x6 + _x3 * _x5 + 1;
p1 = -_x2;
p2 = -2 * _x2 * (_x6^2) + 2 * _x3 * _x5 * _x6 - 2 * _x2 * _x5 * _x6
+ _x4 * (_x5^3) + 2 * _x3 * (_x5^2);
std::cout << " p0: " << p0 << "\n p1: " << p1 << "\n p2: " << p2 << "\n";
scoped_anum val(am);
rational five_half(5, 2);
am.set(val, 4); sample_as.set(x0, val);
am.set(val, 1); sample_as.set(x1, val);
am.set(val, 1); sample_as.set(x2, val);
am.set(val, five_half.to_mpq()); sample_as.set(x3, val);
am.set(val, 0); sample_as.set(x4, val);
am.set(val, 1); sample_as.set(x5, val);
am.set(val, 4); counter_as.set(x0, val);
am.set(val, 1); counter_as.set(x1, val);
am.set(val, 4); counter_as.set(x2, val);
am.set(val, -3); counter_as.set(x3, val);
am.set(val, 0); counter_as.set(x4, val);
am.set(val, 1); counter_as.set(x5, val);
am.set(val, -1); counter_as.set(x6, val);
s.set_rvalues(sample_as);
polynomial_ref_vector polys(pm);
polys.push_back(p0);
polys.push_back(p1);
polys.push_back(p2);
nlsat::levelwise lws(s, polys, x6, s.sample(), pm, am, cache);
auto cell = lws.single_cell();
std::cout << "Cell intervals:\n";
for (unsigned i = 0; i < cell.size(); ++i)
nlsat::display(std::cout << " Level " << i << ": ", s, cell[i]) << "\n";
bool inside = is_point_inside_cell(am, pm, cell, counter_as);
ENSURE(!inside);
std::cout << "=== END tst_23 ===\n\n";
}
static void tst_24() {
std::cout << "=== tst_24 ===\n";
params_ref ps;
ps.set_bool("lws", true);
reslimit rlim;
nlsat::solver s(rlim, ps, false);
anum_manager & am = s.am();
nlsat::pmanager & pm = s.pm();
nlsat::assignment sample_as(am);
nlsat::assignment counter_as(am);
polynomial::cache cache(pm);
nlsat::var x0 = s.mk_var(false);
nlsat::var x1 = s.mk_var(false);
nlsat::var x2 = s.mk_var(false);
nlsat::var x3 = s.mk_var(false);
nlsat::var x4 = s.mk_var(false);
nlsat::var x5 = s.mk_var(false);
nlsat::var x6 = s.mk_var(false);
polynomial_ref _x0(pm), _x1(pm), _x2(pm), _x3(pm), _x4(pm), _x5(pm), _x6(pm);
_x0 = pm.mk_polynomial(x0);
_x1 = pm.mk_polynomial(x1);
_x2 = pm.mk_polynomial(x2);
_x3 = pm.mk_polynomial(x3);
_x4 = pm.mk_polynomial(x4);
_x5 = pm.mk_polynomial(x5);
_x6 = pm.mk_polynomial(x6);
polynomial_ref p0(pm), p1(pm), p2(pm), p3(pm), p4(pm);
p0 = _x2;
p1 = _x5 + _x4;
p2 = (_x2^2) * _x5 * _x6 + (_x2^2) * _x4 * _x6
+ 2 * (_x2^2) * _x3 * _x5 + _x0 * (_x2^2) * _x5
- 3 * _x0 * _x1 * _x2 * _x5 - 2 * _x0 * (_x1^2) * _x5
+ 2 * (_x2^2) * _x3 * _x4 + 2 * _x0 * (_x2^2) * _x4;
p3 = _x5;
p4 = _x2 * _x5 * _x6 - _x0 * _x1 * _x5 - _x0 * _x5 + _x0 * _x2 * _x4;
std::cout << " p0: " << p0 << "\n p1: " << p1 << "\n p2: " << p2
<< "\n p3: " << p3 << "\n p4: " << p4 << "\n";
scoped_anum val(am);
rational three_quarter(3, 4);
am.set(val, 1); sample_as.set(x0, val);
am.set(val, 0); sample_as.set(x1, val);
am.set(val, -1); sample_as.set(x2, val);
am.set(val, 0); sample_as.set(x3, val);
am.set(val, three_quarter.to_mpq()); sample_as.set(x4, val);
am.set(val, 1); sample_as.set(x5, val);
am.set(val, 1); counter_as.set(x0, val);
am.set(val, -1); counter_as.set(x1, val);
am.set(val, -1); counter_as.set(x2, val);
am.set(val, 2); counter_as.set(x3, val);
am.set(val, 1); counter_as.set(x4, val);
am.set(val, 1); counter_as.set(x5, val);
am.set(val, -2); counter_as.set(x6, val);
s.set_rvalues(sample_as);
polynomial_ref_vector polys(pm);
polys.push_back(p0);
polys.push_back(p1);
polys.push_back(p2);
polys.push_back(p3);
polys.push_back(p4);
nlsat::levelwise lws(s, polys, x6, s.sample(), pm, am, cache);
auto cell = lws.single_cell();
std::cout << "Cell intervals:\n";
for (unsigned i = 0; i < cell.size(); ++i)
nlsat::display(std::cout << " Level " << i << ": ", s, cell[i]) << "\n";
bool inside = is_point_inside_cell(am, pm, cell, counter_as);
ENSURE(!inside);
std::cout << "=== END tst_24 ===\n\n";
}
static void tst_25() {
std::cout << "=== tst_25 ===\n";
params_ref ps;
ps.set_bool("lws", true);
reslimit rlim;
nlsat::solver s(rlim, ps, false);
anum_manager & am = s.am();
nlsat::pmanager & pm = s.pm();
nlsat::assignment sample_as(am);
nlsat::assignment counter_as(am);
nlsat::var x0 = s.mk_var(false);
nlsat::var x1 = s.mk_var(false);
nlsat::var x2 = s.mk_var(false);
nlsat::var x3 = s.mk_var(false);
nlsat::var x4 = s.mk_var(false);
nlsat::var x5 = s.mk_var(false);
nlsat::var x6 = s.mk_var(false);
nlsat::var x7 = s.mk_var(false);
nlsat::var x8 = s.mk_var(false);
nlsat::var x9 = s.mk_var(false);
nlsat::var x10 = s.mk_var(false);
nlsat::var x11 = s.mk_var(false);
nlsat::var x12 = s.mk_var(false);
nlsat::var x13 = s.mk_var(false);
nlsat::var x14 = s.mk_var(false);
nlsat::var x15 = s.mk_var(false);
polynomial_ref _x0(pm), _x3(pm), _x4(pm), _x5(pm), _x6(pm);
polynomial_ref _x9(pm), _x10(pm), _x11(pm), _x13(pm), _x14(pm), _x15(pm);
_x0 = pm.mk_polynomial(x0);
_x3 = pm.mk_polynomial(x3);
_x4 = pm.mk_polynomial(x4);
_x5 = pm.mk_polynomial(x5);
_x6 = pm.mk_polynomial(x6);
_x9 = pm.mk_polynomial(x9);
_x10 = pm.mk_polynomial(x10);
_x11 = pm.mk_polynomial(x11);
_x13 = pm.mk_polynomial(x13);
_x14 = pm.mk_polynomial(x14);
_x15 = pm.mk_polynomial(x15);
polynomial_ref p1(pm);
p1 = -_x9 * _x15 - _x10 * _x14 + _x5 * _x11 * _x13 + _x3 * _x4 * _x11 + 2;
polynomial_ref p2(pm);
p2 = _x15 + _x6 * _x13 + _x0 * _x4;
nlsat::bool_var root_lt_bvar = s.mk_root_atom(nlsat::atom::ROOT_LT, x15, 1, p1.get());
s.inc_ref(root_lt_bvar);
nlsat::literal jst_lit0(root_lt_bvar, true);
nlsat::literal gt_lit = mk_gt(s, p2.get());
s.inc_ref(gt_lit);
nlsat::literal jst_lit1 = ~gt_lit;
nlsat::literal jst_lits[2] = { jst_lit0, jst_lit1 };
scoped_anum val(am);
rational half(1, 2);
set_assignment_value(sample_as, am, x0, rational(1));
set_assignment_value(sample_as, am, x1, rational(-1));
set_assignment_value(sample_as, am, x2, rational(1));
set_assignment_value(sample_as, am, x3, rational(-1));
set_assignment_value(sample_as, am, x4, rational(2));
set_assignment_value(sample_as, am, x5, rational(0));
set_assignment_value(sample_as, am, x6, rational(0));
set_assignment_value(sample_as, am, x7, rational(0));
set_assignment_value(sample_as, am, x8, rational(0));
set_assignment_value(sample_as, am, x9, rational(1));
set_assignment_value(sample_as, am, x10, rational(0));
set_assignment_value(sample_as, am, x11, half);
set_assignment_value(sample_as, am, x12, rational(1));
set_assignment_value(sample_as, am, x13, rational(-4));
set_assignment_value(sample_as, am, x14, rational(2));
s.set_rvalues(sample_as);
nlsat::explain& ex = s.get_explain();
nlsat::scoped_literal_vector result(s);
ex.compute_conflict_explanation(2, jst_lits, result);
nlsat::literal_vector lemma;
for (unsigned i = 0; i < result.size(); ++i)
lemma.push_back(result[i]);
lemma.push_back(~jst_lits[0]); lemma.push_back(~jst_lits[1]);
std::cout << "Lemma (" << lemma.size() << " literals):\n";
s.display(std::cout << " ", lemma.size(), lemma.data()) << "\n";
set_assignment_value(counter_as, am, x0, rational(0));
set_assignment_value(counter_as, am, x1, rational(-1));
set_assignment_value(counter_as, am, x2, rational(1));
set_assignment_value(counter_as, am, x3, rational(-1));
set_assignment_value(counter_as, am, x4, rational(1));
set_assignment_value(counter_as, am, x5, rational(0));
set_assignment_value(counter_as, am, x6, rational(0));
set_assignment_value(counter_as, am, x7, rational(0));
set_assignment_value(counter_as, am, x8, rational(0));
set_assignment_value(counter_as, am, x9, rational(1));
set_assignment_value(counter_as, am, x10, rational(0));
set_assignment_value(counter_as, am, x11, rational(3));
set_assignment_value(counter_as, am, x12, rational(1));
set_assignment_value(counter_as, am, x13, rational(0));
set_assignment_value(counter_as, am, x14, rational(0));
set_assignment_value(counter_as, am, x15, rational(0));
s.set_rvalues(counter_as);
nlsat::evaluator& ev = s.get_evaluator();
bool some_true = false;
for (unsigned i = 0; i < lemma.size(); ++i) {
nlsat::literal lit = lemma[i];
nlsat::atom* a = s.bool_var2atom(lit.var());
if (a == nullptr)
continue;
bool v = ev.eval(a, lit.sign());
std::cout << " lit[" << i << "]: ";
s.display(std::cout, lit) << " = " << (v ? "true" : "false") << "\n";
if (v)
some_true = true;
}
ENSURE(some_true);
s.dec_ref(root_lt_bvar);
s.dec_ref(gt_lit);
std::cout << "=== END tst_25 ===\n\n";
}
void tst_nlsat() {
tst_22();
std::cout << "------------------\n";
tst_25();
std::cout << "------------------\n";
tst_20();
std::cout << "------------------\n";
tst_24();
std::cout << "------------------\n";
tst_23();
std::cout << "------------------\n";
tst_21();
std::cout << "------------------\n";
tst_18();
std::cout << "------------------\n";
tst_19();
std::cout << "------------------\n";
tst_17();
std::cout << "------------------\n";
tst_16();
std::cout << "------------------\n";
tst_14();
std::cout << "------------------\n";
tst_15();
std::cout << "------------------\n";
tst11();
std::cout << "------------------\n";
tst10();
std::cout << "------------------\n";
tst9();
std::cout << "------------------\n";
tst8();
std::cout << "------------------\n";
tst7();
std::cout << "------------------\n";
tst6();
std::cout << "------------------\n";
tst5();
std::cout << "------------------\n";
tst4();
std::cout << "------------------\n";
tst3();
}