mirror of
https://github.com/Z3Prover/z3
synced 2025-04-23 00:55:31 +00:00
mb-skolem for arithmetic with model repair
The contract is that users of mb-skolem ensure that interface equalities are preserved (by adding a sufficient set of disequalities, such as a chain x1 < x2 < x3 .., to force that solutions for x_i does not clash). Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
a0af3383db
commit
baa96909cc
5 changed files with 34 additions and 13 deletions
|
@ -360,7 +360,7 @@ namespace qe {
|
|||
|
||||
ptr_vector<expr> index2expr;
|
||||
for (auto& kv : tids) {
|
||||
index2expr.setx(kv.m_value, kv.m_key, 0);
|
||||
index2expr.setx(kv.m_value, kv.m_key, nullptr);
|
||||
}
|
||||
|
||||
j = 0;
|
||||
|
@ -454,6 +454,8 @@ namespace qe {
|
|||
else if (!d.m_div.is_one() && !is_int) {
|
||||
t = a.mk_div(t, a.mk_numeral(d.m_div, is_int));
|
||||
}
|
||||
update_model(model, to_app(x), eval(t));
|
||||
|
||||
SASSERT(eval(t) == eval(x));
|
||||
result.push_back(def(expr_ref(x, m), t));
|
||||
}
|
||||
|
@ -461,6 +463,22 @@ namespace qe {
|
|||
return result;
|
||||
}
|
||||
|
||||
void update_model(model& mdl, app* x, expr_ref const& val) {
|
||||
if (is_uninterp_const(x)) {
|
||||
mdl.register_decl(x->get_decl(), val);
|
||||
}
|
||||
else {
|
||||
func_interp* fi = mdl.get_func_interp(x->get_decl());
|
||||
if (!fi) return;
|
||||
model_evaluator eval(mdl);
|
||||
expr_ref_vector args(m);
|
||||
for (expr* arg : *x) {
|
||||
args.push_back(eval(arg));
|
||||
}
|
||||
fi->insert_entry(args.c_ptr(), val);
|
||||
}
|
||||
}
|
||||
|
||||
expr_ref mk_add(expr_ref_vector const& ts) {
|
||||
switch (ts.size()) {
|
||||
case 0:
|
||||
|
|
|
@ -259,7 +259,7 @@ namespace qe {
|
|||
app_ref_vector& m_vars;
|
||||
arith_util arith;
|
||||
obj_hashtable<func_decl> m_exclude;
|
||||
is_arith_var_proc(app_ref_vector& vars, func_decl_ref_vector const& shared):
|
||||
is_arith_var_proc(app_ref_vector& vars, func_decl_ref_vector const& shared):
|
||||
m(vars.m()), m_vars(vars), arith(m) {
|
||||
for (func_decl* f : shared) m_exclude.insert(f);
|
||||
}
|
||||
|
@ -484,7 +484,7 @@ namespace qe {
|
|||
return l_true, mbp of local, mdl of local & blocked
|
||||
else if !is_sat(local & lits) then
|
||||
return l_false, mbp of local, nullptr
|
||||
else // is_sat(local & lits) && !is_sat(local & lits & blocked)
|
||||
else if is_sat(local & lits) && !is_sat(local & lits & blocked)
|
||||
MISSING CASE
|
||||
MUST PRODUCE AN IMPLICANT OF LOCAL that is inconsistent with lits & blocked
|
||||
in this case !is_sat(local & lits & mdl) and is_sat(mdl, blocked)
|
||||
|
|
|
@ -35,6 +35,7 @@ namespace qe {
|
|||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace is_pure_ns {
|
||||
struct found{};
|
||||
struct proc {
|
||||
|
@ -776,7 +777,7 @@ namespace qe {
|
|||
for (auto &kv : val2rep) {
|
||||
expr *rep = kv.m_value;
|
||||
if (!m.is_unique_value(rep))
|
||||
reps.push_back(kv.m_value);
|
||||
reps.push_back(kv.m_value);
|
||||
}
|
||||
|
||||
if (reps.size() <= 1) return;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue