3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-23 09:05:31 +00:00

add facility to solve for a linear term over API

This commit is contained in:
Nikolaj Bjorner 2024-11-30 09:34:27 -08:00
parent d2411567b5
commit 05e053247d
14 changed files with 109 additions and 6 deletions

View file

@ -4654,6 +4654,15 @@ namespace smt {
return false;
return th->get_value(n, value);
}
bool context::solve_for(enode * n, expr_ref & term) {
sort * s = n->get_sort();
family_id fid = s->get_family_id();
theory * th = get_theory(fid);
if (th == nullptr)
return false;
return th->solve_for(n, term);
}
bool context::update_model(bool refinalize) {
final_check_status fcs = FC_DONE;

View file

@ -1375,11 +1375,6 @@ namespace smt {
bool can_propagate() const;
// Retrieve arithmetic values.
bool get_arith_lo(expr* e, rational& lo, bool& strict);
bool get_arith_up(expr* e, rational& up, bool& strict);
bool get_arith_value(expr* e, rational& value);
// -----------------------------------
//
// Model checking... (must be improved)
@ -1388,6 +1383,8 @@ namespace smt {
public:
bool get_value(enode * n, expr_ref & value);
bool solve_for(enode* n, expr_ref& term);
// -----------------------------------
//
// Pretty Printing

View file

@ -213,8 +213,15 @@ namespace smt {
return out;
}
bool kernel::solve_for(expr* e, expr_ref& term) {
smt::enode* n = m_imp->m_kernel.find_enode(e);
if (!n)
return false;
return m_imp->m_kernel.solve_for(n, term);
}
expr* kernel::congruence_root(expr * e) {
smt::enode* n = m_imp->m_kernel.find_enode(e);
smt::enode* n = m_imp->m_kernel.find_enode(e);
if (!n)
return e;
return n->get_root()->get_expr();

View file

@ -246,6 +246,7 @@ namespace smt {
expr* congruence_root(expr* e);
bool solve_for(expr* e, expr_ref& term);
/**
\brief retrieve depth of variables from decision stack.

View file

@ -337,6 +337,7 @@ namespace {
expr* congruence_next(expr* e) override { return m_context.congruence_next(e); }
expr* congruence_root(expr* e) override { return m_context.congruence_root(e); }
bool solve_for(expr* e, expr_ref& term) override { return m_context.solve_for(e, term); }
expr_ref_vector cube(expr_ref_vector& vars, unsigned cutoff) override {

View file

@ -605,6 +605,8 @@ namespace smt {
virtual char const * get_name() const { return "unknown"; }
virtual bool solve_for(enode* n, expr_ref& r) { return false; }
// -----------------------------------
//
// Return a fresh new instance of the given theory.

View file

@ -3627,7 +3627,21 @@ public:
lpvar vi = get_lpvar(v);
u_dependency* dep = nullptr;
return lp().has_upper_bound(vi, dep, val, is_strict);
}
bool solve_for(enode* n, expr_ref& term) {
theory_var v = n->get_th_var(get_id());
if (!is_registered_var(v))
return false;
lpvar vi = get_lpvar(v);
lp::lar_term t;
rational coeff;
if (!lp().solve_for(vi, t, coeff))
return false;
term = mk_term(t, is_int(v));
if (coeff != 0)
term = a.mk_add(a.mk_numeral(coeff, is_int(v)), term);
return true;
}
bool get_upper(enode* n, expr_ref& r) {
@ -4140,6 +4154,10 @@ bool theory_lra::get_lower(enode* n, rational& r, bool& is_strict) {
bool theory_lra::get_upper(enode* n, rational& r, bool& is_strict) {
return m_imp->get_upper(n, r, is_strict);
}
bool theory_lra::solve_for(enode* n, expr_ref& r) {
return m_imp->solve_for(n, r);
}
void theory_lra::display(std::ostream & out) const {
m_imp->display(out);
}

View file

@ -93,6 +93,7 @@ namespace smt {
bool get_upper(enode* n, expr_ref& r);
bool get_lower(enode* n, rational& r, bool& is_strict);
bool get_upper(enode* n, rational& r, bool& is_strict);
bool solve_for(enode* n, expr_ref& r) override;
void display(std::ostream & out) const override;