3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-06-06 22:23:22 +00:00

share some equalities

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2020-01-19 15:58:17 -06:00
parent 9179deb746
commit c816d45a7d
4 changed files with 43 additions and 20 deletions

View file

@ -872,22 +872,9 @@ public:
void execute(cmd_context & ctx) override { void execute(cmd_context & ctx) override {
ast_manager& m = ctx.m(); ast_manager& m = ctx.m();
qe::interpolator mbi(m); qe::interpolator mbi(m);
expr_ref a(m_a, m);
expr_ref b(m_b, m);
expr_ref itp(m); expr_ref itp(m);
solver_factory& sf = ctx.get_solver_factory(); lbool res = mbi.pogo(ctx.get_solver_factory(), m_a, m_b, itp);
params_ref p; ctx.regular_stream() << itp << "\n";
solver_ref sA = sf(m, p, false /* no proofs */, true, true, symbol::null);
solver_ref sB = sf(m, p, false /* no proofs */, true, true, symbol::null);
solver_ref sNotA = sf(m, p, false /* no proofs */, true, true, symbol::null);
sA->assert_expr(a);
sB->assert_expr(b);
qe::uflia_mbi pA(sA.get(), sNotA.get());
qe::prop_mbi_plugin pB(sB.get());
pA.set_shared(a, b);
pB.set_shared(a, b);
lbool res = mbi.pogo(pA, pB, itp);
ctx.regular_stream() << res << " " << itp << "\n";
} }
}; };

View file

@ -33,6 +33,7 @@ Notes:
#include "ast/for_each_expr.h" #include "ast/for_each_expr.h"
#include "ast/rewriter/expr_safe_replace.h" #include "ast/rewriter/expr_safe_replace.h"
#include "ast/rewriter/bool_rewriter.h" #include "ast/rewriter/bool_rewriter.h"
#include "ast/rewriter/th_rewriter.h"
#include "ast/arith_decl_plugin.h" #include "ast/arith_decl_plugin.h"
#include "model/model_evaluator.h" #include "model/model_evaluator.h"
#include "solver/solver.h" #include "solver/solver.h"
@ -307,11 +308,17 @@ namespace qe {
auto avars = get_arith_vars(lits); auto avars = get_arith_vars(lits);
vector<def> defs = arith_project(mdl, avars, alits); vector<def> defs = arith_project(mdl, avars, alits);
for (auto const& d : defs) uflits.push_back(m.mk_eq(d.var, d.term)); for (auto const& d : defs) uflits.push_back(m.mk_eq(d.var, d.term));
TRACE("qe", tout << "uflits: " << uflits << "\n";);
project_euf(mdl, uflits); project_euf(mdl, uflits);
lits.reset(); lits.reset();
lits.append(alits); lits.append(alits);
lits.append(uflits); lits.append(uflits);
IF_VERBOSE(10, verbose_stream() << "projection : " << lits << "\n"); IF_VERBOSE(10, verbose_stream() << "projection : " << lits << "\n");
TRACE("qe",
tout << "projection: " << lits << "\n";
tout << "avars: " << avars << "\n";
tout << "alits: " << lits << "\n";
tout << "uflits: " << uflits << "\n";);
} }
void uflia_mbi::split_arith(expr_ref_vector const& lits, void uflia_mbi::split_arith(expr_ref_vector const& lits,
@ -334,6 +341,9 @@ namespace qe {
uflits.push_back(lit); uflits.push_back(lit);
} }
} }
TRACE("qe",
tout << "alits: " << alits << "\n";
tout << "uflits: " << uflits << "\n";);
} }
@ -341,9 +351,6 @@ namespace qe {
/** /**
\brief add difference certificates to formula. \brief add difference certificates to formula.
First version just uses an Ackerman reduction.
It should be replaced by DCert.
*/ */
void uflia_mbi::add_dcert(model_ref& mdl, expr_ref_vector& lits) { void uflia_mbi::add_dcert(model_ref& mdl, expr_ref_vector& lits) {
term_graph tg(m); term_graph tg(m);
@ -462,14 +469,14 @@ namespace qe {
return l_true; return l_true;
case l_false: case l_false:
a.block(lits); a.block(lits);
itps.push_back(mk_not(mk_and(lits))); itps.push_back(mk_and(lits));
break; break;
case l_undef: case l_undef:
return l_undef; return l_undef;
} }
break; break;
case l_false: case l_false:
itp = mk_and(itps); itp = mk_or(itps);
return l_false; return l_false;
case l_undef: case l_undef:
return l_undef; return l_undef;
@ -477,4 +484,22 @@ namespace qe {
} }
} }
lbool interpolator::pogo(solver_factory& sf, expr* _a, expr* _b, expr_ref& itp) {
params_ref p;
expr_ref a(_a, m), b(_b, m);
th_rewriter rewrite(m);
rewrite(a);
rewrite(b);
solver_ref sA = sf(m, p, false /* no proofs */, true, true, symbol::null);
solver_ref sB = sf(m, p, false /* no proofs */, true, true, symbol::null);
solver_ref sNotA = sf(m, p, false /* no proofs */, true, true, symbol::null);
sA->assert_expr(a);
sB->assert_expr(b);
uflia_mbi pA(sA.get(), sNotA.get());
prop_mbi_plugin pB(sB.get());
pA.set_shared(a, b);
pB.set_shared(a, b);
return pogo(pA, pB, itp);
}
}; };

View file

@ -146,6 +146,7 @@ namespace qe {
interpolator(ast_manager& m):m(m) {} interpolator(ast_manager& m):m(m) {}
lbool pingpong(mbi_plugin& a, mbi_plugin& b, expr_ref& itp); lbool pingpong(mbi_plugin& a, mbi_plugin& b, expr_ref& itp);
lbool pogo(mbi_plugin& a, mbi_plugin& b, expr_ref& itp); lbool pogo(mbi_plugin& a, mbi_plugin& b, expr_ref& itp);
lbool pogo(solver_factory& sf, expr* a, expr* b, expr_ref& itp);
}; };
}; };

View file

@ -1264,6 +1264,16 @@ namespace qe {
} }
} }
} }
for (auto const& terms : partitions) {
expr* a = nullptr;
for (expr* b : terms) {
if (is_uninterp(b))
if (a)
result.push_back(m.mk_eq(a, b));
else
a = b;
}
}
TRACE("qe", tout << result << "\n";); TRACE("qe", tout << result << "\n";);
return result; return result;
} }