Skip to content

Commit 945eef7

Browse files
committed
work on well-orientedness
Signed-off-by: Lev Nachmanson <[email protected]>
1 parent b2f0170 commit 945eef7

File tree

9 files changed

+557
-324
lines changed

9 files changed

+557
-324
lines changed

src/nlsat/nlsat_clause.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ namespace nlsat {
6464
assumption_set assumptions() const { return m_assumptions; }
6565
};
6666

67-
typedef ptr_vector<clause> clause_vector;
67+
typedef std_vector<clause*> clause_vector;
6868

6969
};
7070

src/nlsat/nlsat_evaluator.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -463,10 +463,12 @@ namespace nlsat {
463463
svector<sign> & signs = m_add_signs_tmp;
464464
roots.reset();
465465
signs.reset();
466-
TRACE(nlsat_evaluator, tout << "x: " << x << " max_var(p): " << m_pm.max_var(p) << "\n";);
466+
TRACE(nlsat_evaluator, m_solver.display(tout << "p: ", polynomial_ref(p, m_pm)) << "\n";tout << "x: " << x << " max_var(p): " << m_pm.max_var(p) << "\n";);
467467
// Note: I added undef_var_assignment in the following statement, to allow us to obtain the infeasible interval sets
468468
// even when the maximal variable is assigned. I need this feature to minimize conflict cores.
469-
m_am.isolate_roots(polynomial_ref(p, m_pm), undef_var_assignment(m_assignment, x), roots, signs);
469+
auto pr = polynomial_ref(p, m_pm);
470+
auto uass = undef_var_assignment(m_assignment, x);
471+
m_am.isolate_roots(pr, uass, roots, signs);
470472
t.add(roots, signs);
471473
}
472474
}

src/nlsat/nlsat_explain.cpp

Lines changed: 76 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ namespace nlsat {
9494
\brief Remove the maximal polynomials from the set and store
9595
them in max_polys. Return the maximal variable
9696
*/
97-
var remove_max_polys(polynomial_ref_vector & max_polys) {
97+
var extract_max_polys(polynomial_ref_vector & max_polys) {
9898
max_polys.reset();
9999
var x = max_var();
100100
pmanager & pm = m_set.m();
@@ -333,7 +333,6 @@ namespace nlsat {
333333
polynomial_ref lc(m_pm);
334334
polynomial_ref reduct(m_pm);
335335
while (true) {
336-
TRACE(nlsat_explain, tout << "elim vanishing x" << x << " k:" << k << " " << p << "\n";);
337336
if (is_const(p))
338337
return;
339338
if (k == 0) {
@@ -342,33 +341,31 @@ namespace nlsat {
342341
SASSERT(x != null_var);
343342
k = degree(p, x);
344343
}
345-
#if 0
346-
anum const & x_val = m_assignment.value(x);
347-
if (m_am.is_zero(x_val)) {
348-
// add_zero_assumption(lc);
349-
lc = m_pm.coeff(p, x, k, reduct);
350-
k--;
351-
p = reduct;
352-
continue;
353-
}
354-
#endif
355344
if (m_pm.nonzero_const_coeff(p, x, k)) {
356345
TRACE(nlsat_explain, tout << "nonzero const x" << x << "\n";);
357346
return; // lc is a nonzero constant
358347
}
359348
lc = m_pm.coeff(p, x, k, reduct);
360349
TRACE(nlsat_explain, tout << "lc: " << lc << " reduct: " << reduct << "\n";);
361350
if (!is_zero(lc)) {
362-
if (!::is_zero(sign(lc)))
351+
if (!::is_zero(sign(lc))) {
352+
TRACE(nlsat_explain, tout << "lc does no vaninsh\n";);
363353
return;
354+
}
355+
TRACE(nlsat_explain, tout << "got a zero sign on lc\n";);
356+
357+
364358
// lc is not the zero polynomial, but it vanished in the current interpretation.
365359
// so we keep searching...
360+
TRACE(nlsat_explain, tout << "adding zero assumption for var:"; m_solver.display_var(tout, x); tout << ", degree k:" << k << ", p:" ; display(tout, p) << "\n";);
361+
366362
add_zero_assumption(lc);
367363
}
368364
if (k == 0) {
369365
// all coefficients of p vanished in the current interpretation,
370366
// and were added as assumptions.
371367
p = m_pm.mk_zero();
368+
TRACE(nlsat_explain, tout << "all coefficients of p vanished\n";);
372369
return;
373370
}
374371
k--;
@@ -621,25 +618,57 @@ namespace nlsat {
621618
}
622619
}
623620

624-
void add_sample_coeff(polynomial_ref_vector &ps, var x){
625-
polynomial_ref p(m_pm);
626-
polynomial_ref lc(m_pm);
627-
unsigned sz = ps.size();
628-
for (unsigned i = 0; i < sz; i++){
629-
p = ps.get(i);
630-
unsigned k = degree(p, x);
631-
SASSERT(k > 0);
632-
TRACE(nlsat_explain, tout << "add_lc, x: "; display_var(tout, x); tout << "\nk: " << k << "\n"; display(tout, p); tout << "\n";);
633-
for(; k > 0; k--){
634-
lc = m_pm.coeff(p, x, k);
635-
add_factors(lc);
636-
if (m_pm.nonzero_const_coeff(p, x, k)){
637-
TRACE(nlsat_explain, tout << "constant coefficient, skipping...\n";);
621+
bool is_well_oriented(polynomial_ref_vector &ps, var x) {
622+
polynomial_ref p_poly(m_pm);
623+
polynomial_ref lc_poly(m_pm);
624+
polynomial_ref disc_poly(m_pm);
625+
polynomial_ref current_coeff_poly(m_pm);
626+
627+
for (unsigned i = 0; i < ps.size(); i++) {
628+
p_poly = ps.get(i);
629+
unsigned k_deg = m_pm.degree(p_poly, x);
630+
if (k_deg == 0)
631+
continue;
632+
// p_poly depends on x
633+
lc_poly = m_pm.coeff(p_poly, x, k_deg);
634+
if (sign(lc_poly) == 0) { // LC is zero
635+
TRACE(nlsat_explain, tout << "Global !WO: LC of poly is zero. Poly: "; display(tout, p_poly); tout << " LC: "; display(tout, lc_poly) << "\\n";);
636+
return false;
637+
}
638+
639+
disc_poly = discriminant(p_poly, x); // Use global helper
640+
if (sign(disc_poly) == 0) { // Discriminant is zero
641+
TRACE(nlsat_explain, tout << "Global !WO: Discriminant of poly is zero. Poly: "; display(tout, p_poly); tout << " Disc: "; display(tout, disc_poly) << "\\n";);
642+
return false;
643+
}
644+
645+
}
646+
return true;
647+
}
648+
649+
// For each p in ps add the leading or all the coefficients of p to the projection,
650+
// depending on the well-orientedness of ps.
651+
void add_lcs(polynomial_ref_vector &ps, var x) {
652+
polynomial_ref p_poly(m_pm);
653+
polynomial_ref coeff(m_pm);
654+
polynomial_ref disc_poly(m_pm);
655+
656+
bool wo = is_well_oriented(ps, x);
657+
// Add coefficients based on well-orientedness
658+
for (unsigned i = 0; i < ps.size(); i++) {
659+
p_poly = ps.get(i);
660+
unsigned k_deg = m_pm.degree(p_poly, x);
661+
if (k_deg == 0) continue;
662+
// p_poly depends on x
663+
TRACE(nlsat_explain, tout << "processing poly of degree " << k_deg << " w.r.t x" << x << ": "; display(tout, p_poly); tout << (wo ? " (wo)" : " (!wo)") << "\\n";);
664+
for (unsigned j_coeff_deg = k_deg; j_coeff_deg >= 1; j_coeff_deg--) {
665+
coeff = m_pm.coeff(p_poly, x, j_coeff_deg);
666+
TRACE(nlsat_explain, tout << " coeff deg " << j_coeff_deg << ": "; display(tout, coeff) << "\\n";);
667+
add_factors(coeff);
668+
if (wo)
638669
break;
639-
}
640670
}
641-
SASSERT(sign(lc) != 0);
642-
SASSERT(!is_const(lc));
671+
643672
}
644673
}
645674

@@ -659,35 +688,6 @@ namespace nlsat {
659688
}
660689
}
661690

662-
663-
/**
664-
\brief Add leading coefficients of the polynomials in ps.
665-
666-
\pre all polynomials in ps contain x
667-
668-
Remark: the leading coefficients do not vanish in the current model,
669-
since all polynomials in ps were pre-processed using elim_vanishing.
670-
*/
671-
void add_lc(polynomial_ref_vector & ps, var x) {
672-
polynomial_ref p(m_pm);
673-
polynomial_ref lc(m_pm);
674-
unsigned sz = ps.size();
675-
for (unsigned i = 0; i < sz; i++) {
676-
p = ps.get(i);
677-
unsigned k = degree(p, x);
678-
SASSERT(k > 0);
679-
TRACE(nlsat_explain, tout << "add_lc, x: "; display_var(tout, x); tout << "\nk: " << k << "\n"; display(tout, p); tout << "\n";);
680-
if (m_pm.nonzero_const_coeff(p, x, k)) {
681-
TRACE(nlsat_explain, tout << "constant coefficient, skipping...\n";);
682-
continue;
683-
}
684-
lc = m_pm.coeff(p, x, k);
685-
SASSERT(sign(lc) != 0);
686-
SASSERT(!is_const(lc));
687-
add_factors(lc);
688-
}
689-
}
690-
691691
void add_zero_assumption_on_factor(polynomial_ref& f) {
692692
display(std::cout << "zero factors \n", f);
693693
}
@@ -1198,7 +1198,7 @@ namespace nlsat {
11981198
for (poly* p : ps) {
11991199
m_todo.insert(p);
12001200
}
1201-
var x = m_todo.remove_max_polys(ps);
1201+
var x = m_todo.extract_max_polys(ps);
12021202
// Remark: after vanishing coefficients are eliminated, ps may not contain max_x anymore
12031203
if (x < max_x)
12041204
add_cell_lits(ps, x);
@@ -1207,14 +1207,15 @@ namespace nlsat {
12071207
m_todo.reset();
12081208
break;
12091209
}
1210-
TRACE(nlsat_explain, tout << "project loop, processing var "; display_var(tout, x); tout << "\npolynomials\n";
1210+
TRACE(nlsat_explain, tout << "project loop, processing var "; display_var(tout, x);
1211+
tout << "\npolynomials\n";
12111212
display(tout, ps); tout << "\n";);
1212-
add_lc(ps, x);
1213+
add_lcs(ps, x);
12131214
psc_discriminant(ps, x);
12141215
psc_resultant(ps, x);
12151216
if (m_todo.empty())
12161217
break;
1217-
x = m_todo.remove_max_polys(ps);
1218+
x = m_todo.extract_max_polys(ps);
12181219
add_cell_lits(ps, x);
12191220
}
12201221
}
@@ -1229,12 +1230,12 @@ namespace nlsat {
12291230
void project_cdcac(polynomial_ref_vector & ps, var max_x) {
12301231
if (ps.empty())
12311232
return;
1232-
bool first = true;
1233+
12331234
m_todo.reset();
12341235
for (poly* p : ps) {
12351236
m_todo.insert(p);
12361237
}
1237-
var x = m_todo.remove_max_polys(ps);
1238+
var x = m_todo.extract_max_polys(ps);
12381239
// Remark: after vanishing coefficients are eliminated, ps may not contain max_x anymore
12391240

12401241
polynomial_ref_vector samples(m_pm);
@@ -1251,23 +1252,13 @@ namespace nlsat {
12511252
}
12521253
TRACE(nlsat_explain, tout << "project loop, processing var "; display_var(tout, x); tout << "\npolynomials\n";
12531254
display(tout, ps); tout << "\n";);
1254-
1255-
if (first) {
1256-
add_lc(ps, x);
1257-
psc_discriminant(ps, x);
1258-
psc_resultant(ps, x);
1259-
first = false;
1260-
}
1261-
else {
1262-
add_lc(ps, x);
1263-
// add_sample_coeff(ps, x);
1264-
psc_discriminant(ps, x);
1265-
psc_resultant_sample(ps, x, samples);
1266-
}
1255+
add_lcs(ps, x);
1256+
psc_discriminant(ps, x);
1257+
psc_resultant(ps, x);
12671258

12681259
if (m_todo.empty())
12691260
break;
1270-
x = m_todo.remove_max_polys(ps);
1261+
x = m_todo.extract_max_polys(ps);
12711262
cac_add_cell_lits(ps, x, samples);
12721263
}
12731264
}
@@ -1426,12 +1417,10 @@ namespace nlsat {
14261417
// If the leading coefficient is not a constant, we must store this information as an extra assumption.
14271418
if (d % 2 == 0 || // d is even
14281419
is_even || // rewriting a factor of even degree, sign flip doesn't matter
1429-
_a->get_kind() == atom::EQ) { // rewriting an equation, sign flip doesn't matter
1420+
_a->get_kind() == atom::EQ) // rewriting an equation, sign flip doesn't matter
14301421
info.add_lc_diseq();
1431-
}
1432-
else {
1422+
else
14331423
info.add_lc_ineq();
1434-
}
14351424
}
14361425
if (s < 0 && !is_even) {
14371426
atom_sign = -atom_sign;
@@ -1444,12 +1433,10 @@ namespace nlsat {
14441433
if (!info.m_lc_const) {
14451434
if (d % 2 == 0 || // d is even
14461435
is_even || // rewriting a factor of even degree, sign flip doesn't matter
1447-
_a->get_kind() == atom::EQ) { // rewriting an equation, sign flip doesn't matter
1436+
_a->get_kind() == atom::EQ) // rewriting an equation, sign flip doesn't matter
14481437
info.add_lc_diseq();
1449-
}
1450-
else {
1438+
else
14511439
info.add_lc_ineq();
1452-
}
14531440
}
14541441
}
14551442
}
@@ -1755,7 +1742,7 @@ namespace nlsat {
17551742
TRACE(nlsat_explain,
17561743
tout << "[explain] set of literals is infeasible in the current interpretation\n";
17571744
display(tout, num, ls) << "\n";
1758-
m_assignment.display(tout);
1745+
m_solver.display_assignment(tout);
17591746
);
17601747
m_result = &result;
17611748
process(num, ls);
@@ -2140,7 +2127,7 @@ namespace nlsat {
21402127
m_imp->m_signed_project = f;
21412128
}
21422129

2143-
void explain::operator()(unsigned n, literal const * ls, scoped_literal_vector & result) {
2130+
void explain::main_operator(unsigned n, literal const * ls, scoped_literal_vector & result) {
21442131
(*m_imp)(n, ls, result);
21452132
}
21462133

@@ -2157,7 +2144,6 @@ namespace nlsat {
21572144
}
21582145

21592146
};
2160-
21612147
#ifdef Z3DEBUG
21622148
#include <iostream>
21632149
void pp(nlsat::explain::imp & ex, unsigned num, nlsat::literal const * ls) {

src/nlsat/nlsat_explain.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ namespace nlsat {
6363
- s_1, ..., s_m do not contain variable x.
6464
- s_1, ..., s_m are false in the current interpretation
6565
*/
66-
void operator()(unsigned n, literal const * ls, scoped_literal_vector & result);
66+
void main_operator(unsigned n, literal const * ls, scoped_literal_vector & result);
6767

6868

6969
/**

src/nlsat/nlsat_params.pyg

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ def_module_params('nlsat',
99
('lazy', UINT, 0, "how lazy the solver is."),
1010
('reorder', BOOL, True, "reorder variables."),
1111
('log_lemmas', BOOL, False, "display lemmas as self-contained SMT formulas"),
12+
('dump_mathematica', BOOL, False, "display lemmas as matematica"),
1213
('check_lemmas', BOOL, False, "check lemmas on the fly using an independent nlsat solver"),
1314
('simplify_conflicts', BOOL, True, "simplify conflicts using equalities before resolving them in nlsat solver."),
1415
('minimize_conflicts', BOOL, False, "minimize conflicts"),
@@ -17,5 +18,6 @@ def_module_params('nlsat',
1718
('shuffle_vars', BOOL, False, "use a random variable order."),
1819
('inline_vars', BOOL, False, "inline variables that can be isolated from equations (not supported in incremental mode)"),
1920
('seed', UINT, 0, "random seed."),
20-
('factor', BOOL, True, "factor polynomials produced during conflict resolution.")
21+
('factor', BOOL, True, "factor polynomials produced during conflict resolution."),
22+
('known_sat_assignment_file_name', STRING, "", "the file name of a known solution: used for debugging only")
2123
))

src/nlsat/nlsat_simplify.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ namespace nlsat {
3030
// then promote learned to main.
3131
for (auto c : m_learned)
3232
s.del_clause(c);
33-
m_learned.reset();
33+
m_learned.clear();
3434

3535
IF_VERBOSE(3, s.display(verbose_stream() << "before\n"));
3636
unsigned sz = m_clauses.size();
@@ -342,7 +342,7 @@ namespace nlsat {
342342
else
343343
m_clauses[j++] = c;
344344
}
345-
m_clauses.shrink(j);
345+
m_clauses.resize(j);
346346
return j < sz;
347347
}
348348

0 commit comments

Comments
 (0)