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

integrate lambda expressions

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2018-06-26 07:23:04 -07:00
parent bf4edef761
commit 520ce9a5ee
139 changed files with 2243 additions and 1506 deletions

View file

@ -2269,8 +2269,7 @@ namespace qe {
bound.push_back(m.mk_fresh_const("bound", fv[i]));
}
var_subst subst(m);
subst(fml, bound.size(), bound.c_ptr(), tmp);
fml = tmp;
fml = subst(fml, bound.size(), bound.c_ptr());
}
}
@ -2291,7 +2290,7 @@ namespace qe {
}
expr* const* exprs = (expr* const*)(vars.c_ptr());
var_subst subst(m);
subst(new_body, vars.size(), exprs, tmp);
tmp = subst(new_body, vars.size(), exprs);
inv_var_shifter shift(m);
shift(tmp, vars.size(), new_body);
}
@ -2337,13 +2336,18 @@ namespace qe {
case AST_QUANTIFIER: {
app_ref_vector vars(m);
quantifier* q = to_quantifier(e);
bool is_fa = q->is_forall();
tmp = q->get_expr();
extract_vars(q, tmp, vars);
elim(tmp);
init_qe();
m_qe->set_assumption(m_assumption);
m_qe->eliminate(is_fa, vars.size(), vars.c_ptr(), tmp);
if (is_lambda(q)) {
tmp = e;
}
else {
bool is_fa = is_forall(q);
tmp = q->get_expr();
extract_vars(q, tmp, vars);
elim(tmp);
init_qe();
m_qe->set_assumption(m_assumption);
m_qe->eliminate(is_fa, vars.size(), vars.c_ptr(), tmp);
}
m_trail.push_back(tmp);
m_visited.insert(e, tmp);
todo.pop_back();
@ -2593,6 +2597,9 @@ namespace qe {
)
{
if (is_lambda(old_q)) {
return false;
}
// bool is_forall = old_q->is_forall();
app_ref_vector vars(m);
TRACE("qe", tout << "simplifying" << mk_pp(new_body, m) << "\n";);
@ -2600,11 +2607,11 @@ namespace qe {
extract_vars(old_q, result, vars);
TRACE("qe", tout << "variables extracted" << mk_pp(result, m) << "\n";);
if (old_q->is_forall()) {
if (is_forall(old_q)) {
result = mk_not(m, result);
}
m_ctx.solve(result, vars);
if (old_q->is_forall()) {
if (is_forall(old_q)) {
expr* e = nullptr;
result = m.is_not(result, e)?e:mk_not(m, result);
}
@ -2619,7 +2626,7 @@ namespace qe {
names.push_back(vars[i]->get_decl()->get_name());
}
if (!vars.empty()) {
result = m.mk_quantifier(old_q->is_forall(), vars.size(), sorts.c_ptr(), names.c_ptr(), result, 1);
result = m.mk_quantifier(old_q->get_kind(), vars.size(), sorts.c_ptr(), names.c_ptr(), result, 1);
}
result_pr = nullptr;
return true;

View file

@ -327,8 +327,8 @@ namespace eq {
void flatten_args(quantifier* q, unsigned& num_args, expr*const*& args) {
expr * e = q->get_expr();
if ((q->is_forall() && m.is_or(e)) ||
(q->is_exists() && m.is_and(e))) {
if ((is_forall(q) && m.is_or(e)) ||
(is_exists(q) && m.is_and(e))) {
num_args = to_app(e)->get_num_args();
args = to_app(e)->get_args();
}
@ -356,27 +356,29 @@ namespace eq {
}
expr_ref t(m);
if (q->is_forall()) {
switch (q->get_kind()) {
case forall_k:
rw.mk_or(m_new_args.size(), m_new_args.c_ptr(), t);
}
else {
break;
case exists_k:
rw.mk_and(m_new_args.size(), m_new_args.c_ptr(), t);
break;
default:
t = e;
break;
}
expr_ref new_e(m);
m_subst(t, new_e);
expr_ref new_e = m_subst(t, m_subst_map.size(), m_subst_map.c_ptr());
// don't forget to update the quantifier patterns
expr_ref_buffer new_patterns(m);
expr_ref_buffer new_no_patterns(m);
for (unsigned j = 0; j < q->get_num_patterns(); j++) {
expr_ref new_pat(m);
m_subst(q->get_pattern(j), new_pat);
expr_ref new_pat = m_subst(q->get_pattern(j), m_subst_map.size(), m_subst_map.c_ptr());
new_patterns.push_back(new_pat);
}
for (unsigned j = 0; j < q->get_num_no_patterns(); j++) {
expr_ref new_nopat(m);
m_subst(q->get_no_pattern(j), new_nopat);
expr_ref new_nopat = m_subst(q->get_no_pattern(j), m_subst_map.size(), m_subst_map.c_ptr());
new_no_patterns.push_back(new_nopat);
}
@ -390,12 +392,17 @@ namespace eq {
set_is_variable_proc(is_v);
unsigned num_args = 1;
expr* const* args = &e;
if (is_lambda(q)) {
r = q;
pr = 0;
return;
}
flatten_args(q, num_args, args);
unsigned def_count = 0;
unsigned largest_vinx = 0;
find_definitions(num_args, args, q->is_exists(), def_count, largest_vinx);
find_definitions(num_args, args, is_exists(q), def_count, largest_vinx);
if (def_count > 0) {
get_elimination_order();
@ -423,7 +430,7 @@ namespace eq {
if (is_quantifier(r)) {
quantifier * q = to_quantifier(r);
::elim_unused_vars(m, q, m_params, r);
r = ::elim_unused_vars(m, q, m_params);
if (m.proofs_enabled()) {
proof * p1 = m.mk_elim_unused_vars(q, r);
pr = m.mk_transitivity(pr, p1);
@ -624,7 +631,7 @@ namespace eq {
expr_ref r(m), new_r(m);
r = m.mk_and(conjs.size(), conjs.c_ptr());
create_substitution(largest_vinx + 1);
m_subst(r, new_r);
new_r = m_subst(r, m_subst_map.size(), m_subst_map.c_ptr());
m_rewriter(new_r);
conjs.reset();
flatten_and(new_r, conjs);
@ -1756,16 +1763,12 @@ namespace fm {
// x_cost_lt is not a total order on variables
std::stable_sort(x_cost_vector.begin(), x_cost_vector.end(), x_cost_lt(m_is_int));
TRACE("qe_lite",
svector<x_cost>::iterator it2 = x_cost_vector.begin();
svector<x_cost>::iterator end2 = x_cost_vector.end();
for (; it2 != end2; ++it2) {
tout << "(" << mk_ismt2_pp(m_var2expr.get(it2->first), m) << " " << it2->second << ") ";
for (auto const& kv : x_cost_vector) {
tout << "(" << mk_ismt2_pp(m_var2expr.get(kv.first), m) << " " << kv.second << ") ";
}
tout << "\n";);
svector<x_cost>::iterator it2 = x_cost_vector.begin();
svector<x_cost>::iterator end2 = x_cost_vector.end();
for (; it2 != end2; ++it2) {
xs.push_back(it2->first);
for (auto const& kv : x_cost_vector) {
xs.push_back(kv.first);
}
}
@ -1802,11 +1805,9 @@ namespace fm {
void analyze(constraints const & cs, var x, bool & all_int, bool & unit_coeff) const {
all_int = true;
unit_coeff = true;
constraints::const_iterator it = cs.begin();
constraints::const_iterator end = cs.end();
for (; it != end; ++it) {
for (constraint const* c : cs) {
bool curr_unit_coeff;
analyze(*(*it), x, all_int, curr_unit_coeff);
analyze(*c, x, all_int, curr_unit_coeff);
if (!all_int)
return;
if (!curr_unit_coeff)
@ -1830,10 +1831,8 @@ namespace fm {
}
void copy_constraints(constraints const & s, clauses & t) {
constraints::const_iterator it = s.begin();
constraints::const_iterator end = s.end();
for (; it != end; ++it) {
app * c = to_expr(*(*it));
for (constraint const* cns : s) {
app * c = to_expr(*cns);
t.push_back(c);
}
}
@ -1842,10 +1841,8 @@ namespace fm {
void save_constraints(var x) { }
void mark_constraints_dead(constraints const & cs) {
constraints::const_iterator it = cs.begin();
constraints::const_iterator end = cs.end();
for (; it != end; ++it)
(*it)->m_dead = true;
for (constraint* c : cs)
c->m_dead = true;
}
void mark_constraints_dead(var x) {
@ -2094,14 +2091,8 @@ namespace fm {
}
void copy_remaining(vector<constraints> & v2cs) {
vector<constraints>::iterator it = v2cs.begin();
vector<constraints>::iterator end = v2cs.end();
for (; it != end; ++it) {
constraints & cs = *it;
constraints::iterator it2 = cs.begin();
constraints::iterator end2 = cs.end();
for (; it2 != end2; ++it2) {
constraint * c = *it2;
for (constraints& cs : v2cs) {
for (constraint* c : cs) {
if (!c->m_dead) {
c->m_dead = true;
expr * new_f = to_expr(*c);
@ -2170,11 +2161,8 @@ namespace fm {
}
void display_constraints(std::ostream & out, constraints const & cs) const {
constraints::const_iterator it = cs.begin();
constraints::const_iterator end = cs.end();
for (; it != end; ++it) {
out << " ";
display(out, *(*it));
for (constraint const* c : cs) {
display(out << " ", *c);
out << "\n";
}
}
@ -2215,7 +2203,9 @@ public:
for (unsigned i = 0; i < q->get_num_decls(); ++i) {
indices.insert(i);
}
m_imp(indices, true, result);
if (q->get_kind() != lambda_k) {
m_imp(indices, true, result);
}
if (is_forall(q)) {
result = push_not(result);
}
@ -2295,7 +2285,7 @@ public:
tmp = to_quantifier(tmp)->get_expr();
used.process(tmp);
var_subst vs(m, true);
vs(tmp, vars.size(), (expr*const*)vars.c_ptr(), fml);
fml = vs(tmp, vars.size(), (expr*const*)vars.c_ptr());
// collect set of variables that were used.
unsigned j = 0;
for (unsigned i = 0; i < vars.size(); ++i) {

View file

@ -31,6 +31,7 @@ Revision History:
#include "qe/qe_arrays.h"
#include "qe/qe_datatypes.h"
#include "qe/qe_lite.h"
#include "model/model_pp.h"
#include "model/model_evaluator.h"
@ -616,7 +617,7 @@ public:
qe::array_project_plugin ap(m);
ap(mdl, array_vars, fml, vars, m_reduce_all_selects);
SASSERT (array_vars.empty ());
m_rw(fml);
m_rw (fml);
SASSERT (!m.is_false (fml));
TRACE ("qe",
@ -650,9 +651,9 @@ public:
// substitute any remaining other vars
if (!m_dont_sub && !other_vars.empty ()) {
subst_vars (eval, other_vars, fml);
TRACE ("qe", tout << "After substituting remaining other vars:\n" << fml << "\n";);
// an extra round of simplification because subst_vars is not simplifying
m_rw(fml);
TRACE ("qe", tout << "After substituting remaining other vars:\n" << fml << "\n";);
other_vars.reset();
}

View file

@ -989,9 +989,10 @@ namespace qe {
break;
}
case AST_QUANTIFIER: {
SASSERT(!is_lambda(e));
app_ref_vector vars(m);
quantifier* q = to_quantifier(e);
bool is_fa = q->is_forall();
bool is_fa = ::is_forall(q);
tmp = q->get_expr();
extract_vars(q, tmp, vars);
TRACE("qe", tout << vars << " " << mk_pp(q, m) << " " << tmp << "\n";);
@ -1235,6 +1236,9 @@ namespace qe {
fml = push_not(fml);
}
hoist(fml);
if (!is_ground(fml)) {
throw tactic_exception("formula is not hoistable");
}
m_pred_abs.abstract_atoms(fml, defs);
fml = m_pred_abs.mk_abstract(fml);
m_ex.assert_expr(mk_and(defs));