3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2026-03-21 20:18:50 +00:00

add a hook to add new multiplication definitions in nla_core

This commit is contained in:
Lev Nachmanson 2025-09-30 16:47:49 -07:00
parent d79d43355f
commit 1adfa94823
4 changed files with 34 additions and 14 deletions

View file

@ -1577,7 +1577,10 @@ lbool core::check() {
lp_settings().stats().m_nra_calls++;
}
if (ret == l_undef && !no_effect() && m_reslim.inc())
if (ret == l_undef)
return l_undef;
if (!no_effect() && m_reslim.inc())
ret = l_false;
lp_settings().stats().m_nla_lemmas += m_lemmas.size();

View file

@ -94,6 +94,8 @@ class core {
emonics m_emons;
svector<lpvar> m_add_buffer;
mutable indexed_uint_set m_active_var_set;
// hook installed by theory_lra for creating a multiplication definition
std::function<lpvar(unsigned, lpvar const*)> m_add_mul_def_hook;
reslimit m_nra_lim;
@ -208,6 +210,8 @@ public:
void add_idivision(lpvar q, lpvar x, lpvar y) { m_divisions.add_idivision(q, x, y); }
void add_rdivision(lpvar q, lpvar x, lpvar y) { m_divisions.add_rdivision(q, x, y); }
void add_bounded_division(lpvar q, lpvar x, lpvar y) { m_divisions.add_bounded_division(q, x, y); }
void set_add_mul_def_hook(std::function<lpvar(unsigned, lpvar const*)> const& f) { m_add_mul_def_hook = f; }
lpvar add_mul_def(unsigned sz, lpvar const* vs) { SASSERT(m_add_mul_def_hook); lpvar v = m_add_mul_def_hook(sz, vs); add_monic(v, sz, vs); return v; }
void set_relevant(std::function<bool(lpvar)>& is_relevant) { m_relevant = is_relevant; }
bool is_relevant(lpvar v) const { return !m_relevant || m_relevant(v); }

View file

@ -289,17 +289,9 @@ struct solver::imp {
if (mon)
v = mon->var();
else {
NOT_IMPLEMENTED_YET();
// this one is for Lev Nachmanson: lar_solver relies on internal variables
// to have terms from outside. The solver doesn't get to create
// its own monomials.
// v = ...
// It is not a use case if the nlsat solver only provides linear
// polynomials so punt for now.
m_nla_core.add_monic(v, vars.size(), vars.data());
v = m_nla_core.add_mul_def(vars.size(), vars.data());
}
TRACE(nra,
tout << "process_polynomial_check_assignment:";
tout << " vars=";
for (auto _w : vars) tout << _w << ' ';
tout << " s=" << s
@ -323,9 +315,8 @@ struct solver::imp {
IF_VERBOSE(1, verbose_stream() << "nra::solver::check_assignment\n";);
setup_solver();
lbool r = l_undef;
statistics &st = m_nla_core.lp_settings().stats().m_st;
nlsat::literal_vector clause;
polynomial::manager &pm = m_nlsat->pm();
statistics &st = m_nla_core.lp_settings().stats().m_st;
nlsat::literal_vector clause;
try {
nlsat::assignment rvalues(m_nlsat->am());
for (auto [j, x] : m_lp2nl) {
@ -373,7 +364,10 @@ struct solver::imp {
SASSERT(!a->is_root_atom());
SASSERT(a->is_ineq_atom());
auto &ia = *to_ineq_atom(a);
VERIFY(ia.size() == 1); // deal with factored polynomials later
if (ia.size() != 1) {
return l_undef; // levnach: not sure what to do here
}
// VERIFY(ia.size() == 1); // deal with factored polynomials later
// a is an inequality atom, i.e., p > 0, p < 0, or p = 0.
polynomial::polynomial const *p = ia.p(0);
TRACE(nra, tout << "polynomial: "; pm.display(tout, p); tout << "\n";);
@ -404,6 +398,7 @@ struct solver::imp {
lemma |= inq;
}
IF_VERBOSE(1, verbose_stream() << "linear lemma: " << lemma << "\n");
this->m_nla_core.m_check_feasible = true;
return l_false;
}