mirror of
https://github.com/Z3Prover/z3
synced 2025-04-23 17:15:31 +00:00
Api (#7097)
* rename ul_pair to column Signed-off-by: Lev Nachmanson <levnach@hotmail.com> * t Signed-off-by: Lev Nachmanson <levnach@hotmail.com> * simple test passed * remove an assert * relax an assertion * remove an obsolete function Signed-off-by: Lev Nachmanson <levnach@hotmail.com> * access a term by the term column * remove the column index from colunm.h * remove an unused method * remove debug code * fix the build of lp_tst Signed-off-by: Lev Nachmanson <levnach@hotmail.com> --------- Signed-off-by: Lev Nachmanson <levnach@hotmail.com> Co-authored-by: Lev Nachmanson <levnach@hotmail.com>
This commit is contained in:
parent
133546625c
commit
bdb9106f99
45 changed files with 587 additions and 973 deletions
|
@ -45,8 +45,7 @@ namespace arith {
|
|||
}
|
||||
unsigned nv = get_num_vars();
|
||||
for (unsigned v = 0; v < nv; ++v) {
|
||||
auto t = get_tv(v);
|
||||
auto vi = lp().external_to_column_index(v);
|
||||
auto vi = lp().external_to_local(v);
|
||||
out << "v" << v << " ";
|
||||
if (is_bool(v)) {
|
||||
euf::enode* n = var2enode(v);
|
||||
|
@ -57,10 +56,10 @@ namespace arith {
|
|||
}
|
||||
}
|
||||
else {
|
||||
if (t.is_null())
|
||||
if (vi == lp::null_lpvar)
|
||||
out << "null";
|
||||
else
|
||||
out << (t.is_term() ? "t" : "j") << vi;
|
||||
out << (lp().column_has_term(vi) ? "t" : "j") << vi;
|
||||
if (m_nla && m_nla->use_nra_model() && is_registered_var(v)) {
|
||||
scoped_anum an(m_nla->am());
|
||||
m_nla->am().display(out << " = ", nl_value(v, an));
|
||||
|
|
|
@ -507,11 +507,11 @@ namespace arith {
|
|||
}
|
||||
else {
|
||||
vi = lp().add_term(m_left_side, v);
|
||||
SASSERT(lp::tv::is_term(vi));
|
||||
SASSERT(lp().column_has_term(vi));
|
||||
TRACE("arith_verbose",
|
||||
tout << "v" << v << " := " << mk_pp(term, m)
|
||||
<< " slack: " << vi << " scopes: " << m_scopes.size() << "\n";
|
||||
lp().print_term(lp().get_term(lp::tv::raw(vi)), tout) << "\n";);
|
||||
lp().print_term(lp().get_term(vi), tout) << "\n";);
|
||||
}
|
||||
}
|
||||
return v;
|
||||
|
@ -541,8 +541,6 @@ namespace arith {
|
|||
rational const& r = m_columns[var];
|
||||
if (!r.is_zero()) {
|
||||
auto vi = register_theory_var_in_lar_solver(var);
|
||||
if (lp::tv::is_term(vi))
|
||||
vi = lp().map_term_index_to_column_index(vi);
|
||||
m_left_side.push_back(std::make_pair(r, vi));
|
||||
m_columns[var].reset();
|
||||
}
|
||||
|
@ -625,9 +623,6 @@ namespace arith {
|
|||
return lp().external_to_local(v);
|
||||
}
|
||||
|
||||
lp::tv solver::get_tv(theory_var v) const {
|
||||
return lp::tv::raw(get_lpvar(v));
|
||||
}
|
||||
|
||||
/**
|
||||
\brief We must redefine this method, because theory of arithmetic contains
|
||||
|
|
|
@ -59,18 +59,10 @@ namespace arith {
|
|||
int64_t val = 0;
|
||||
lp::lar_term const& term = s.lp().get_term(t);
|
||||
for (lp::lar_term::ival const& arg : term) {
|
||||
auto t2 = s.lp().column2tv(arg.column());
|
||||
auto w = s.lp().local_to_external(t2.id());
|
||||
auto t2 = arg.j();
|
||||
auto w = s.lp().local_to_external(t2);
|
||||
val += to_numeral(arg.coeff()) * m_vars[w].m_best_value;
|
||||
}
|
||||
if (v == 52) {
|
||||
verbose_stream() << "update v" << v << " := " << val << "\n";
|
||||
for (lp::lar_term::ival const& arg : term) {
|
||||
auto t2 = s.lp().column2tv(arg.column());
|
||||
auto w = s.lp().local_to_external(t2.id());
|
||||
verbose_stream() << "v" << w << " := " << m_vars[w].m_best_value << " * " << to_numeral(arg.coeff()) << "\n";
|
||||
}
|
||||
}
|
||||
m_vars[v].m_best_value = val;
|
||||
}
|
||||
|
||||
|
@ -81,12 +73,12 @@ namespace arith {
|
|||
continue;
|
||||
int64_t new_value = m_vars[v].m_best_value;
|
||||
s.ensure_column(v);
|
||||
lp::column_index vj = s.lp().to_column_index(v);
|
||||
SASSERT(!vj.is_null());
|
||||
if (!s.lp().is_base(vj.index())) {
|
||||
lp::lpvar vj = s.lp().external_to_local(v);
|
||||
SASSERT(vj != lp::null_lpvar);
|
||||
if (!s.lp().is_base(vj)) {
|
||||
rational new_value_(new_value, rational::i64());
|
||||
lp::impq val(new_value_, rational::zero());
|
||||
s.lp().set_value_for_nbasic_column(vj.index(), val);
|
||||
s.lp().set_value_for_nbasic_column(vj, val);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -460,18 +452,18 @@ namespace arith {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void sls::add_args(sat::bool_var bv, ineq& ineq, lp::tv t, theory_var v, int64_t sign) {
|
||||
if (t.is_term()) {
|
||||
void sls::add_args(sat::bool_var bv, ineq& ineq, lp::lpvar t, theory_var v, int64_t sign) {
|
||||
if (s.lp().column_has_term(t)) {
|
||||
lp::lar_term const& term = s.lp().get_term(t);
|
||||
m_terms.push_back({t,v});
|
||||
for (lp::lar_term::ival arg : term) {
|
||||
auto t2 = s.lp().column2tv(arg.column());
|
||||
auto w = s.lp().local_to_external(t2.id());
|
||||
auto t2 = arg.j();
|
||||
auto w = s.lp().local_to_external(t2);
|
||||
add_arg(bv, ineq, sign * to_numeral(arg.coeff()), w);
|
||||
}
|
||||
}
|
||||
else
|
||||
add_arg(bv, ineq, sign, s.lp().local_to_external(t.id()));
|
||||
add_arg(bv, ineq, sign, s.lp().local_to_external(t));
|
||||
}
|
||||
|
||||
void sls::init_bool_var(sat::bool_var bv) {
|
||||
|
@ -480,7 +472,7 @@ namespace arith {
|
|||
api_bound* b = nullptr;
|
||||
s.m_bool_var2bound.find(bv, b);
|
||||
if (b) {
|
||||
auto t = b->tv();
|
||||
auto t = b->column_index();
|
||||
rational bound = b->get_value();
|
||||
bool should_minus = false;
|
||||
sls::ineq_kind op;
|
||||
|
@ -503,8 +495,8 @@ namespace arith {
|
|||
if (e && m.is_eq(e, l, r) && s.a.is_int_real(l)) {
|
||||
theory_var u = s.get_th_var(l);
|
||||
theory_var v = s.get_th_var(r);
|
||||
lp::tv tu = s.get_tv(u);
|
||||
lp::tv tv = s.get_tv(v);
|
||||
lp::lpvar tu = s.get_column(u);
|
||||
lp::lpvar tv = s.get_column(v);
|
||||
auto& ineq = new_ineq(sls::ineq_kind::EQ, 0);
|
||||
add_args(bv, ineq, tu, u, 1);
|
||||
add_args(bv, ineq, tv, v, -1);
|
||||
|
|
|
@ -105,7 +105,7 @@ namespace arith {
|
|||
config m_config;
|
||||
scoped_ptr_vector<ineq> m_bool_vars;
|
||||
vector<var_info> m_vars;
|
||||
svector<std::pair<lp::tv, euf::theory_var>> m_terms;
|
||||
svector<std::pair<lp::lpvar, euf::theory_var>> m_terms;
|
||||
bool m_dscore_mode = false;
|
||||
|
||||
|
||||
|
@ -140,7 +140,7 @@ namespace arith {
|
|||
void add_vars();
|
||||
sls::ineq& new_ineq(ineq_kind op, int64_t const& bound);
|
||||
void add_arg(sat::bool_var bv, ineq& ineq, int64_t const& c, var_t v);
|
||||
void add_args(sat::bool_var bv, ineq& ineq, lp::tv t, euf::theory_var v, int64_t sign);
|
||||
void add_args(sat::bool_var bv, ineq& ineq, lp::lpvar j, euf::theory_var v, int64_t sign);
|
||||
void init_bool_var(sat::bool_var v);
|
||||
void init_bool_var_assignment(sat::bool_var v);
|
||||
|
||||
|
|
|
@ -370,7 +370,7 @@ namespace arith {
|
|||
|
||||
void solver::refine_bound(theory_var v, const lp::implied_bound& be) {
|
||||
lpvar vi = be.m_j;
|
||||
if (lp::tv::is_term(vi))
|
||||
if (lp().column_has_term(vi))
|
||||
return;
|
||||
expr_ref w(var2expr(v), m);
|
||||
if (a.is_add(w) || a.is_numeral(w) || m.is_ite(w))
|
||||
|
@ -418,7 +418,7 @@ namespace arith {
|
|||
++m_stats.m_assert_upper;
|
||||
inf_rational value = b.get_value(is_true);
|
||||
if (propagate_eqs() && value.is_rational())
|
||||
propagate_eqs(b.tv(), ci, k, b, value.get_rational());
|
||||
propagate_eqs(b.column_index(), ci, k, b, value.get_rational());
|
||||
#if 0
|
||||
if (propagation_mode() != BP_NONE)
|
||||
lp().add_column_rows_to_touched_rows(b.tv().id());
|
||||
|
@ -426,30 +426,29 @@ namespace arith {
|
|||
|
||||
}
|
||||
|
||||
void solver::propagate_eqs(lp::tv t, lp::constraint_index ci1, lp::lconstraint_kind k, api_bound& b, rational const& value) {
|
||||
void solver::propagate_eqs(lp::lpvar t, lp::constraint_index ci1, lp::lconstraint_kind k, api_bound& b, rational const& value) {
|
||||
u_dependency* dep;
|
||||
auto& dm = lp().dep_manager();
|
||||
if (k == lp::GE && set_lower_bound(t, ci1, value) && has_upper_bound(t.index(), dep, value)) {
|
||||
if (k == lp::GE && set_lower_bound(t, ci1, value) && has_upper_bound(t, dep, value)) {
|
||||
fixed_var_eh(b.get_var(), dm.mk_join(dm.mk_leaf(ci1), dep), value);
|
||||
}
|
||||
else if (k == lp::LE && set_upper_bound(t, ci1, value) && has_lower_bound(t.index(), dep, value)) {
|
||||
else if (k == lp::LE && set_upper_bound(t, ci1, value) && has_lower_bound(t, dep, value)) {
|
||||
fixed_var_eh(b.get_var(), dm.mk_join(dm.mk_leaf(ci1), dep), value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool solver::set_bound(lp::tv tv, lp::constraint_index ci, rational const& v, bool is_lower) {
|
||||
if (tv.is_term()) {
|
||||
lpvar ti = tv.id();
|
||||
bool solver::set_bound(lp::lpvar tv, lp::constraint_index ci, rational const& v, bool is_lower) {
|
||||
if (lp().column_has_term(tv)) {
|
||||
auto& vec = is_lower ? m_lower_terms : m_upper_terms;
|
||||
if (vec.size() <= ti) {
|
||||
vec.resize(ti + 1, constraint_bound(UINT_MAX, rational()));
|
||||
if (vec.size() <= tv) {
|
||||
vec.resize(tv + 1, constraint_bound(UINT_MAX, rational()));
|
||||
}
|
||||
constraint_bound& b = vec[ti];
|
||||
constraint_bound& b = vec[tv];
|
||||
if (b.first == UINT_MAX || (is_lower ? b.second < v : b.second > v)) {
|
||||
TRACE("arith", tout << "tighter bound " << tv.to_string() << "\n";);
|
||||
m_history.push_back(vec[ti]);
|
||||
ctx.push(history_trail<constraint_bound>(vec, ti, m_history));
|
||||
TRACE("arith", tout << "tighter bound " << tv << "\n";);
|
||||
m_history.push_back(vec[tv]);
|
||||
ctx.push(history_trail<constraint_bound>(vec, tv, m_history));
|
||||
b.first = ci;
|
||||
b.second = v;
|
||||
}
|
||||
|
@ -461,10 +460,10 @@ namespace arith {
|
|||
rational b;
|
||||
u_dependency* dep = nullptr;
|
||||
if (is_lower) {
|
||||
return lp().has_lower_bound(tv.id(), dep, b, is_strict) && !is_strict && b == v;
|
||||
return lp().has_lower_bound(tv, dep, b, is_strict) && !is_strict && b == v;
|
||||
}
|
||||
else {
|
||||
return lp().has_upper_bound(tv.id(), dep, b, is_strict) && !is_strict && b == v;
|
||||
return lp().has_upper_bound(tv, dep, b, is_strict) && !is_strict && b == v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -772,7 +771,7 @@ namespace arith {
|
|||
bool solver::has_lower_bound(lpvar vi, u_dependency*& ci, rational const& bound) { return has_bound(vi, ci, bound, true); }
|
||||
|
||||
bool solver::has_bound(lpvar vi, u_dependency*& dep, rational const& bound, bool is_lower) {
|
||||
if (lp::tv::is_term(vi)) {
|
||||
if (lp().column_has_term(vi)) {
|
||||
theory_var v = lp().local_to_external(vi);
|
||||
rational val;
|
||||
TRACE("arith", tout << lp().get_variable_name(vi) << " " << v << "\n";);
|
||||
|
@ -782,9 +781,8 @@ namespace arith {
|
|||
}
|
||||
|
||||
auto& vec = is_lower ? m_lower_terms : m_upper_terms;
|
||||
lpvar ti = lp::tv::unmask_term(vi);
|
||||
if (vec.size() > ti) {
|
||||
auto& [ci, coeff] = vec[ti];
|
||||
if (vec.size() > vi) {
|
||||
auto& [ci, coeff] = vec[vi];
|
||||
if (ci == UINT_MAX)
|
||||
return false;
|
||||
dep = lp().dep_manager().mk_leaf(ci);
|
||||
|
@ -876,11 +874,16 @@ namespace arith {
|
|||
|
||||
lp::impq solver::get_ivalue(theory_var v) const {
|
||||
SASSERT(is_registered_var(v));
|
||||
return m_solver->get_tv_ivalue(get_tv(v));
|
||||
return m_solver->get_column_value(get_column(v));
|
||||
}
|
||||
|
||||
lp::lpvar solver::get_column(theory_var v) const {
|
||||
SASSERT(is_registered_var(v));
|
||||
return m_solver->external_to_local(v);
|
||||
}
|
||||
|
||||
rational solver::get_value(theory_var v) const {
|
||||
return is_registered_var(v) ? m_solver->get_tv_value(get_tv(v)) : rational::zero();
|
||||
return is_registered_var(v) ? m_solver->get_value(get_column(v)) : rational::zero();
|
||||
}
|
||||
|
||||
void solver::random_update() {
|
||||
|
@ -895,18 +898,18 @@ namespace arith {
|
|||
if (is_bool(v))
|
||||
continue;
|
||||
ensure_column(v);
|
||||
lp::column_index vj = lp().to_column_index(v);
|
||||
SASSERT(!vj.is_null());
|
||||
lp::lpvar vj = lp().external_to_local(v);
|
||||
SASSERT(vj != lp::null_lpvar);
|
||||
theory_var other = m_model_eqs.insert_if_not_there(v);
|
||||
if (is_equal(v, other))
|
||||
continue;
|
||||
if (!lp().is_fixed(vj))
|
||||
vars.push_back(vj.index());
|
||||
if (!lp().column_is_fixed(vj))
|
||||
vars.push_back(vj);
|
||||
else if (!m_tmp_var_set.contains(other)) {
|
||||
lp::column_index other_j = lp().to_column_index(other);
|
||||
if (!lp().is_fixed(other_j)) {
|
||||
lp::lpvar other_j = lp().external_to_local(other);
|
||||
if (!lp().column_is_fixed(other_j)) {
|
||||
m_tmp_var_set.insert(other);
|
||||
vars.push_back(other_j.index());
|
||||
vars.push_back(other_j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1068,14 +1071,14 @@ namespace arith {
|
|||
nlsat::anum const& solver::nl_value(theory_var v, scoped_anum& r) const {
|
||||
SASSERT(m_nla);
|
||||
SASSERT(m_nla->use_nra_model());
|
||||
auto t = get_tv(v);
|
||||
if (!t.is_term()) {
|
||||
m_nla->am().set(r, m_nla->am_value(t.id()));
|
||||
auto t = get_column(v);
|
||||
if (!lp().column_has_term(t)) {
|
||||
m_nla->am().set(r, m_nla->am_value(t));
|
||||
}
|
||||
else {
|
||||
m_todo_terms.push_back(std::make_pair(t, rational::one()));
|
||||
TRACE("nl_value", tout << "v" << v << " " << t.to_string() << "\n";);
|
||||
TRACE("nl_value", tout << "v" << v << " := w" << t.to_string() << "\n";
|
||||
TRACE("nl_value", tout << "v" << v << " " << t << "\n";);
|
||||
TRACE("nl_value", tout << "v" << v << " := w" << t << "\n";
|
||||
lp().print_term(lp().get_term(t), tout) << "\n";);
|
||||
|
||||
m_nla->am().set(r, 0);
|
||||
|
@ -1090,14 +1093,14 @@ namespace arith {
|
|||
m_nla->am().set(r1, c1.to_mpq());
|
||||
m_nla->am().add(r, r1, r);
|
||||
for (lp::lar_term::ival arg : term) {
|
||||
auto wi = lp().column2tv(arg.column());
|
||||
auto wi = arg.j();
|
||||
c1 = arg.coeff() * wcoeff;
|
||||
if (wi.is_term()) {
|
||||
if (lp().column_has_term(wi)) {
|
||||
m_todo_terms.push_back(std::make_pair(wi, c1));
|
||||
}
|
||||
else {
|
||||
m_nla->am().set(r1, c1.to_mpq());
|
||||
m_nla->am().mul(m_nla->am_value(wi.id()), r1, r1);
|
||||
m_nla->am().mul(m_nla->am_value(wi), r1, r1);
|
||||
m_nla->am().add(r1, r, r);
|
||||
}
|
||||
}
|
||||
|
@ -1393,17 +1396,17 @@ namespace arith {
|
|||
TRACE("arith", lp().print_term(term, tout) << "\n";);
|
||||
for (lp::lar_term::ival ti : term) {
|
||||
theory_var w;
|
||||
auto tv = lp().column2tv(ti.column());
|
||||
if (tv.is_term()) {
|
||||
auto tv = ti.j();
|
||||
if (lp().column_has_term(tv)) {
|
||||
lp::lar_term const& term1 = lp().get_term(tv);
|
||||
rational coeff2 = coeff * ti.coeff();
|
||||
term2coeffs(term1, coeffs, coeff2);
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
w = lp().local_to_external(tv.id());
|
||||
w = lp().local_to_external(tv);
|
||||
SASSERT(w >= 0);
|
||||
TRACE("arith", tout << (tv.id()) << ": " << w << "\n";);
|
||||
TRACE("arith", tout << tv << ": " << w << "\n";);
|
||||
}
|
||||
rational c0(0);
|
||||
coeffs.find(w, c0);
|
||||
|
|
|
@ -38,7 +38,7 @@ namespace euf {
|
|||
namespace arith {
|
||||
|
||||
typedef ptr_vector<lp_api::bound<sat::literal>> lp_bounds;
|
||||
typedef lp::var_index lpvar;
|
||||
typedef lp::lpvar lpvar;
|
||||
typedef euf::theory_var theory_var;
|
||||
typedef euf::theory_id theory_id;
|
||||
typedef euf::enode enode;
|
||||
|
@ -245,7 +245,7 @@ namespace arith {
|
|||
symbol m_farkas;
|
||||
std_vector<lp::implied_bound> m_implied_bounds;
|
||||
lp::lp_bound_propagator<solver> m_bp;
|
||||
mutable vector<std::pair<lp::tv, rational>> m_todo_terms;
|
||||
mutable vector<std::pair<lp::lpvar, rational>> m_todo_terms;
|
||||
|
||||
// lemmas
|
||||
lp::explanation m_explanation;
|
||||
|
@ -306,7 +306,7 @@ namespace arith {
|
|||
bool reflect(expr* n) const;
|
||||
|
||||
lpvar get_lpvar(theory_var v) const;
|
||||
lp::tv get_tv(theory_var v) const;
|
||||
lp::lpvar get_column(theory_var v) const;
|
||||
|
||||
// axioms
|
||||
void mk_div_axiom(expr* p, expr* q);
|
||||
|
@ -348,7 +348,7 @@ namespace arith {
|
|||
iterator end,
|
||||
bool& found_compatible);
|
||||
|
||||
void propagate_eqs(lp::tv t, lp::constraint_index ci, lp::lconstraint_kind k, api_bound& b, rational const& value);
|
||||
void propagate_eqs(lp::lpvar t, lp::constraint_index ci, lp::lconstraint_kind k, api_bound& b, rational const& value);
|
||||
void propagate_basic_bounds(unsigned qhead);
|
||||
void propagate_bounds_with_lp_solver();
|
||||
void propagate_bound(literal lit, api_bound& b);
|
||||
|
@ -362,9 +362,9 @@ namespace arith {
|
|||
api_bound* mk_var_bound(sat::literal lit, theory_var v, lp_api::bound_kind bk, rational const& bound);
|
||||
lp::lconstraint_kind bound2constraint_kind(bool is_int, lp_api::bound_kind bk, bool is_true);
|
||||
void fixed_var_eh(theory_var v1, u_dependency* dep, rational const& bound);
|
||||
bool set_upper_bound(lp::tv t, lp::constraint_index ci, rational const& v) { return set_bound(t, ci, v, false); }
|
||||
bool set_lower_bound(lp::tv t, lp::constraint_index ci, rational const& v) { return set_bound(t, ci, v, true); }
|
||||
bool set_bound(lp::tv tv, lp::constraint_index ci, rational const& v, bool is_lower);
|
||||
bool set_upper_bound(lp::lpvar t, lp::constraint_index ci, rational const& v) { return set_bound(t, ci, v, false); }
|
||||
bool set_lower_bound(lp::lpvar t, lp::constraint_index ci, rational const& v) { return set_bound(t, ci, v, true); }
|
||||
bool set_bound(lp::lpvar tv, lp::constraint_index ci, rational const& v, bool is_lower);
|
||||
|
||||
typedef std::pair<lp::constraint_index, rational> constraint_bound;
|
||||
vector<constraint_bound> m_lower_terms;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue