mirror of
https://github.com/Z3Prover/z3
synced 2025-06-23 06:13:40 +00:00
integrate lambda expressions
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
bf4edef761
commit
520ce9a5ee
139 changed files with 2243 additions and 1506 deletions
|
@ -76,16 +76,16 @@ namespace smt {
|
|||
\brief Instantiation sets are the S_{k,j} sets in the Complete quantifier instantiation paper.
|
||||
*/
|
||||
class instantiation_set {
|
||||
ast_manager & m_manager;
|
||||
ast_manager & m;
|
||||
obj_map<expr, unsigned> m_elems; // and the associated generation
|
||||
obj_map<expr, expr *> m_inv;
|
||||
expr_mark m_visited;
|
||||
public:
|
||||
instantiation_set(ast_manager & m):m_manager(m) {}
|
||||
instantiation_set(ast_manager & m):m(m) {}
|
||||
|
||||
~instantiation_set() {
|
||||
for (auto const& kv : m_elems) {
|
||||
m_manager.dec_ref(kv.m_key);
|
||||
m.dec_ref(kv.m_key);
|
||||
}
|
||||
m_elems.reset();
|
||||
}
|
||||
|
@ -95,10 +95,10 @@ namespace smt {
|
|||
void insert(expr * n, unsigned generation) {
|
||||
if (m_elems.contains(n) || contains_model_value(n))
|
||||
return;
|
||||
TRACE("model_finder", tout << mk_pp(n, m_manager) << "\n";);
|
||||
m_manager.inc_ref(n);
|
||||
TRACE("model_finder", tout << mk_pp(n, m) << "\n";);
|
||||
m.inc_ref(n);
|
||||
m_elems.insert(n, generation);
|
||||
SASSERT(!m_manager.is_model_value(n));
|
||||
SASSERT(!m.is_model_value(n));
|
||||
}
|
||||
|
||||
void remove(expr * n) {
|
||||
|
@ -106,16 +106,16 @@ namespace smt {
|
|||
SASSERT(m_elems.contains(n));
|
||||
SASSERT(m_inv.empty());
|
||||
m_elems.erase(n);
|
||||
m_manager.dec_ref(n);
|
||||
m.dec_ref(n);
|
||||
}
|
||||
|
||||
void display(std::ostream & out) const {
|
||||
for (auto const& kv : m_elems) {
|
||||
out << mk_bounded_pp(kv.m_key, m_manager) << " [" << kv.m_value << "]\n";
|
||||
out << mk_bounded_pp(kv.m_key, m) << " [" << kv.m_value << "]\n";
|
||||
}
|
||||
out << "inverse:\n";
|
||||
for (auto const& kv : m_inv) {
|
||||
out << mk_bounded_pp(kv.m_key, m_manager) << " -> " << mk_bounded_pp(kv.m_value, m_manager) << "\n";
|
||||
out << mk_bounded_pp(kv.m_key, m) << " -> " << mk_bounded_pp(kv.m_value, m) << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -138,7 +138,7 @@ namespace smt {
|
|||
unsigned gen = kv.m_value;
|
||||
expr * t_val = ev.eval(t, true);
|
||||
if (!t_val) break;
|
||||
TRACE("model_finder", tout << mk_pp(t, m_manager) << " " << mk_pp(t_val, m_manager) << "\n";);
|
||||
TRACE("model_finder", tout << mk_pp(t, m) << " " << mk_pp(t_val, m) << "\n";);
|
||||
|
||||
expr * old_t = nullptr;
|
||||
if (m_inv.find(t_val, old_t)) {
|
||||
|
@ -161,13 +161,13 @@ namespace smt {
|
|||
|
||||
struct is_model_value {};
|
||||
void operator()(expr *n) {
|
||||
if (m_manager.is_model_value(n)) {
|
||||
if (m.is_model_value(n)) {
|
||||
throw is_model_value();
|
||||
}
|
||||
}
|
||||
|
||||
bool contains_model_value(expr* n) {
|
||||
if (m_manager.is_model_value(n)) {
|
||||
if (m.is_model_value(n)) {
|
||||
return true;
|
||||
}
|
||||
if (is_app(n) && to_app(n)->get_num_args() == 0) {
|
||||
|
@ -393,6 +393,7 @@ namespace smt {
|
|||
ast_manager & m;
|
||||
arith_util m_arith;
|
||||
bv_util m_bv;
|
||||
array_util m_array;
|
||||
ptr_vector<node> m_nodes;
|
||||
unsigned m_next_node_id;
|
||||
key2node m_uvars;
|
||||
|
@ -427,16 +428,16 @@ namespace smt {
|
|||
m_eval_cache_range.reset();
|
||||
}
|
||||
|
||||
node * mk_node(key2node & m, ast * n, unsigned i, sort * s) {
|
||||
node * mk_node(key2node & map, ast * n, unsigned i, sort * s) {
|
||||
node * r = nullptr;
|
||||
ast_idx_pair k(n, i);
|
||||
if (m.find(k, r)) {
|
||||
if (map.find(k, r)) {
|
||||
SASSERT(r->get_sort() == s);
|
||||
return r;
|
||||
}
|
||||
r = alloc(node, m_next_node_id, s);
|
||||
m_next_node_id++;
|
||||
m.insert(k, r);
|
||||
map.insert(k, r);
|
||||
m_nodes.push_back(r);
|
||||
return r;
|
||||
}
|
||||
|
@ -468,6 +469,7 @@ namespace smt {
|
|||
m(m),
|
||||
m_arith(m),
|
||||
m_bv(m),
|
||||
m_array(m),
|
||||
m_next_node_id(0),
|
||||
m_context(nullptr),
|
||||
m_ks(m),
|
||||
|
@ -651,6 +653,7 @@ namespace smt {
|
|||
a set of values.
|
||||
*/
|
||||
app * get_k_for(sort * s) {
|
||||
TRACE("model_finder", tout << sort_ref(s, m) << "\n";);
|
||||
SASSERT(is_infinite(s));
|
||||
app * r = nullptr;
|
||||
if (m_sort2k.find(s, r))
|
||||
|
@ -709,6 +712,7 @@ namespace smt {
|
|||
}
|
||||
|
||||
void set_projection_else(node * n) {
|
||||
TRACE("model_finder", n->display(tout, m););
|
||||
SASSERT(n->is_root());
|
||||
SASSERT(!n->is_mono_proj());
|
||||
instantiation_set const * s = n->get_instantiation_set();
|
||||
|
@ -856,7 +860,6 @@ namespace smt {
|
|||
bool is_signed = n->is_signed_proj();
|
||||
unsigned sz = values.size();
|
||||
SASSERT(sz > 0);
|
||||
func_decl * p = m.mk_fresh_func_decl(1, &s, s);
|
||||
expr * pi = values[sz - 1];
|
||||
expr_ref var(m);
|
||||
var = m.mk_var(0, s);
|
||||
|
@ -872,11 +875,14 @@ namespace smt {
|
|||
}
|
||||
func_interp * rpi = alloc(func_interp, m, 1);
|
||||
rpi->set_else(pi);
|
||||
func_decl * p = m.mk_fresh_func_decl(1, &s, s);
|
||||
TRACE("model_finder", tout << expr_ref(pi, m) << "\n";);
|
||||
m_model->register_aux_decl(p, rpi);
|
||||
n->set_proj(p);
|
||||
}
|
||||
|
||||
void mk_simple_proj(node * n) {
|
||||
TRACE("model_finder", n->display(tout, m););
|
||||
set_projection_else(n);
|
||||
ptr_buffer<expr> values;
|
||||
get_instantiation_set_values(n, values);
|
||||
|
@ -887,7 +893,7 @@ namespace smt {
|
|||
if (n->get_else()) {
|
||||
expr * else_val = eval(n->get_else(), true);
|
||||
pi->set_else(else_val);
|
||||
}
|
||||
}
|
||||
for (expr * v : values) {
|
||||
pi->insert_new_entry(&v, v);
|
||||
}
|
||||
|
@ -972,9 +978,8 @@ namespace smt {
|
|||
}
|
||||
}
|
||||
expr_ref_vector trail(m);
|
||||
for (unsigned i = 0; i < need_fresh.size(); ++i) {
|
||||
for (node * n : need_fresh) {
|
||||
expr * e;
|
||||
node* n = need_fresh[i];
|
||||
sort* s = n->get_sort();
|
||||
if (!sort2elems.find(s, e)) {
|
||||
e = m.mk_fresh_const("elem", s);
|
||||
|
@ -1173,10 +1178,7 @@ namespace smt {
|
|||
|
||||
void populate_inst_sets(quantifier * q, auf_solver & s, context * ctx) override {
|
||||
node * A_f_i = s.get_A_f_i(m_f, m_arg_i);
|
||||
enode_vector::const_iterator it = ctx->begin_enodes_of(m_f);
|
||||
enode_vector::const_iterator end = ctx->end_enodes_of(m_f);
|
||||
for (; it != end; it++) {
|
||||
enode * n = *it;
|
||||
for (enode * n : ctx->enodes_of(m_f)) {
|
||||
if (ctx->is_relevant(n)) {
|
||||
// Remark: it is incorrect to use
|
||||
// n->get_arg(m_arg_i)->get_root()
|
||||
|
@ -1203,10 +1205,7 @@ namespace smt {
|
|||
instantiation_set * s = uvar_inst_sets[m_var_j];
|
||||
SASSERT(s != 0);
|
||||
|
||||
enode_vector::const_iterator it = ctx->begin_enodes_of(m_f);
|
||||
enode_vector::const_iterator end = ctx->end_enodes_of(m_f);
|
||||
for (; it != end; it++) {
|
||||
enode * n = *it;
|
||||
for (enode * n : ctx->enodes_of(m_f)) {
|
||||
if (ctx->is_relevant(n)) {
|
||||
enode * e_arg = n->get_arg(m_arg_i);
|
||||
expr * arg = e_arg->get_owner();
|
||||
|
@ -1255,10 +1254,7 @@ namespace smt {
|
|||
// there is no finite fixpoint... we just copy the i-th arguments of A_f_i - m_offset
|
||||
// hope for the best...
|
||||
node * S_j = s.get_uvar(q, m_var_j);
|
||||
enode_vector::const_iterator it = ctx->begin_enodes_of(m_f);
|
||||
enode_vector::const_iterator end = ctx->end_enodes_of(m_f);
|
||||
for (; it != end; it++) {
|
||||
enode * n = *it;
|
||||
for (enode * n : ctx->enodes_of(m_f)) {
|
||||
if (ctx->is_relevant(n)) {
|
||||
arith_rewriter arith_rw(ctx->get_manager());
|
||||
bv_util bv(ctx->get_manager());
|
||||
|
@ -1375,7 +1371,7 @@ namespace smt {
|
|||
|
||||
class select_var : public qinfo {
|
||||
protected:
|
||||
ast_manager & m_manager;
|
||||
ast_manager & m;
|
||||
array_util m_array;
|
||||
app * m_select; // It must satisfy is_auf_select... see bool is_auf_select(expr * t) const
|
||||
unsigned m_arg_i;
|
||||
|
@ -1384,6 +1380,7 @@ namespace smt {
|
|||
app * get_array() const { return to_app(m_select->get_arg(0)); }
|
||||
|
||||
func_decl * get_array_func_decl(app * ground_array, auf_solver & s) {
|
||||
TRACE("model_evaluator", tout << expr_ref(ground_array, m) << "\n";);
|
||||
expr * ground_array_interp = s.eval(ground_array, false);
|
||||
if (ground_array_interp != nullptr && m_array.is_as_array(ground_array_interp))
|
||||
return m_array.get_as_array_func_decl(ground_array_interp);
|
||||
|
@ -1391,7 +1388,7 @@ namespace smt {
|
|||
}
|
||||
|
||||
public:
|
||||
select_var(ast_manager & m, app * s, unsigned i, unsigned j):m_manager(m), m_array(m), m_select(s), m_arg_i(i), m_var_j(j) {}
|
||||
select_var(ast_manager & m, app * s, unsigned i, unsigned j):m(m), m_array(m), m_select(s), m_arg_i(i), m_var_j(j) {}
|
||||
~select_var() override {}
|
||||
|
||||
char const * get_kind() const override {
|
||||
|
@ -1406,7 +1403,7 @@ namespace smt {
|
|||
}
|
||||
|
||||
void display(std::ostream & out) const override {
|
||||
out << "(" << mk_bounded_pp(m_select, m_manager) << ":" << m_arg_i << " -> v!" << m_var_j << ")";
|
||||
out << "(" << mk_bounded_pp(m_select, m) << ":" << m_arg_i << " -> v!" << m_var_j << ")";
|
||||
}
|
||||
|
||||
void process_auf(quantifier * q, auf_solver & s, context * ctx) override {
|
||||
|
@ -1415,7 +1412,7 @@ namespace smt {
|
|||
TRACE("select_var",
|
||||
tout << "enodes matching: "; display(tout); tout << "\n";
|
||||
for (enode* n : arrays) {
|
||||
tout << "#" << n->get_owner()->get_id() << "\n" << mk_pp(n->get_owner(), m_manager) << "\n";
|
||||
tout << "#" << n->get_owner()->get_id() << "\n" << mk_pp(n->get_owner(), m) << "\n";
|
||||
});
|
||||
node * n1 = s.get_uvar(q, m_var_j);
|
||||
for (enode* n : arrays) {
|
||||
|
@ -1574,10 +1571,7 @@ namespace smt {
|
|||
// For uninterpreted sorts, we add all terms in the context.
|
||||
// See Section 4.1 in the paper "Complete Quantifier Instantiation"
|
||||
node * S_q_i = slv.get_uvar(q, m_var_i);
|
||||
ptr_vector<enode>::const_iterator it = ctx->begin_enodes();
|
||||
ptr_vector<enode>::const_iterator end = ctx->end_enodes();
|
||||
for (; it != end; ++it) {
|
||||
enode * n = *it;
|
||||
for (enode * n : ctx->enodes()) {
|
||||
if (ctx->is_relevant(n) && get_sort(n->get_owner()) == s) {
|
||||
S_q_i->insert(n->get_owner(), n->get_generation());
|
||||
}
|
||||
|
@ -1623,7 +1617,7 @@ namespace smt {
|
|||
|
||||
class cond_macro {
|
||||
protected:
|
||||
ast_manager & m_manager;
|
||||
ast_manager & m;
|
||||
func_decl * m_f;
|
||||
expr * m_def;
|
||||
expr * m_cond;
|
||||
|
@ -1633,7 +1627,7 @@ namespace smt {
|
|||
unsigned m_weight;
|
||||
public:
|
||||
cond_macro(ast_manager & m, func_decl * f, expr * def, expr * cond, bool ineq, bool satisfy_atom, bool hint, unsigned weight):
|
||||
m_manager(m),
|
||||
m(m),
|
||||
m_f(f),
|
||||
m_def(def),
|
||||
m_cond(cond),
|
||||
|
@ -1641,14 +1635,14 @@ namespace smt {
|
|||
m_satisfy_atom(satisfy_atom),
|
||||
m_hint(hint),
|
||||
m_weight(weight) {
|
||||
m_manager.inc_ref(m_def);
|
||||
m_manager.inc_ref(m_cond);
|
||||
m.inc_ref(m_def);
|
||||
m.inc_ref(m_cond);
|
||||
SASSERT(!m_hint || m_cond == 0);
|
||||
}
|
||||
|
||||
~cond_macro() {
|
||||
m_manager.dec_ref(m_def);
|
||||
m_manager.dec_ref(m_cond);
|
||||
m.dec_ref(m_def);
|
||||
m.dec_ref(m_cond);
|
||||
}
|
||||
|
||||
func_decl * get_f() const { return m_f; }
|
||||
|
@ -1657,7 +1651,7 @@ namespace smt {
|
|||
|
||||
expr * get_cond() const { return m_cond; }
|
||||
|
||||
bool is_unconditional() const { return m_cond == nullptr || m_manager.is_true(m_cond); }
|
||||
bool is_unconditional() const { return m_cond == nullptr || m.is_true(m_cond); }
|
||||
|
||||
bool satisfy_atom() const { return m_satisfy_atom; }
|
||||
|
||||
|
@ -1668,11 +1662,11 @@ namespace smt {
|
|||
}
|
||||
|
||||
void display(std::ostream & out) const {
|
||||
out << "[" << m_f->get_name() << " -> " << mk_bounded_pp(m_def, m_manager, 6);
|
||||
out << "[" << m_f->get_name() << " -> " << mk_bounded_pp(m_def, m, 6);
|
||||
if (m_hint)
|
||||
out << " *hint*";
|
||||
else
|
||||
out << " when " << mk_bounded_pp(m_cond, m_manager, 6);
|
||||
out << " when " << mk_bounded_pp(m_cond, m, 6);
|
||||
out << "] weight: " << m_weight;
|
||||
}
|
||||
|
||||
|
@ -1739,7 +1733,7 @@ namespace smt {
|
|||
m_has_x_eq_y(false),
|
||||
m_the_one(nullptr),
|
||||
m_uvar_inst_sets(nullptr) {
|
||||
if (has_quantifiers(q->get_expr())) {
|
||||
if (has_quantifiers(q->get_expr()) && !m.is_lambda_def(q)) {
|
||||
static bool displayed_flat_msg = false;
|
||||
if (!displayed_flat_msg) {
|
||||
// [Leo]: This warning message is not useful.
|
||||
|
@ -1758,7 +1752,7 @@ namespace smt {
|
|||
}
|
||||
CTRACE("model_finder_bug", has_quantifiers(m_flat_q->get_expr()),
|
||||
tout << mk_pp(q, m) << "\n" << mk_pp(m_flat_q, m) << "\n";);
|
||||
SASSERT(!has_quantifiers(m_flat_q->get_expr()));
|
||||
SASSERT(m.is_lambda_def(q) || !has_quantifiers(m_flat_q->get_expr()));
|
||||
}
|
||||
|
||||
~quantifier_info() {
|
||||
|
@ -1787,7 +1781,6 @@ namespace smt {
|
|||
|
||||
ptr_vector<cond_macro> const& macros() const { return m_cond_macros; }
|
||||
|
||||
|
||||
void set_the_one(func_decl * m) {
|
||||
m_the_one = m;
|
||||
}
|
||||
|
@ -1880,7 +1873,7 @@ namespace smt {
|
|||
*/
|
||||
class quantifier_analyzer {
|
||||
model_finder& m_mf;
|
||||
ast_manager & m_manager;
|
||||
ast_manager & m;
|
||||
macro_util m_mutil;
|
||||
array_util m_array_util;
|
||||
arith_util m_arith_util;
|
||||
|
@ -1909,7 +1902,7 @@ namespace smt {
|
|||
|
||||
bool is_var_plus_ground(expr * n, var * & v, expr_ref & t) {
|
||||
bool inv;
|
||||
TRACE("is_var_plus_ground", tout << mk_pp(n, m_manager) << "\n";
|
||||
TRACE("is_var_plus_ground", tout << mk_pp(n, m) << "\n";
|
||||
tout << "is_var_plus_ground: " << is_var_plus_ground(n, inv, v, t) << "\n";
|
||||
tout << "inv: " << inv << "\n";);
|
||||
return is_var_plus_ground(n, inv, v, t) && !inv;
|
||||
|
@ -1953,7 +1946,7 @@ namespace smt {
|
|||
|
||||
bool is_var_and_ground(expr * lhs, expr * rhs, var * & v, expr_ref & t, bool & inv) {
|
||||
inv = false; // true if invert the sign
|
||||
TRACE("is_var_and_ground", tout << "is_var_and_ground: " << mk_ismt2_pp(lhs, m_manager) << " " << mk_ismt2_pp(rhs, m_manager) << "\n";);
|
||||
TRACE("is_var_and_ground", tout << "is_var_and_ground: " << mk_ismt2_pp(lhs, m) << " " << mk_ismt2_pp(rhs, m) << "\n";);
|
||||
if (is_var(lhs) && is_ground(rhs)) {
|
||||
v = to_var(lhs);
|
||||
t = rhs;
|
||||
|
@ -1967,7 +1960,7 @@ namespace smt {
|
|||
return true;
|
||||
}
|
||||
else {
|
||||
expr_ref tmp(m_manager);
|
||||
expr_ref tmp(m);
|
||||
if (is_var_plus_ground(lhs, inv, v, tmp) && is_ground(rhs)) {
|
||||
if (inv)
|
||||
mk_sub(tmp, rhs, t);
|
||||
|
@ -1994,7 +1987,7 @@ namespace smt {
|
|||
bool is_x_eq_t_atom(expr * n, var * & v, expr_ref & t) {
|
||||
if (!is_app(n))
|
||||
return false;
|
||||
if (m_manager.is_eq(n))
|
||||
if (m.is_eq(n))
|
||||
return is_var_and_ground(to_app(n)->get_arg(0), to_app(n)->get_arg(1), v, t);
|
||||
return false;
|
||||
}
|
||||
|
@ -2030,7 +2023,7 @@ namespace smt {
|
|||
}
|
||||
|
||||
bool is_x_eq_y_atom(expr * n, var * & v1, var * & v2) {
|
||||
return m_manager.is_eq(n) && is_var_and_var(to_app(n)->get_arg(0), to_app(n)->get_arg(1), v1, v2);
|
||||
return m.is_eq(n) && is_var_and_var(to_app(n)->get_arg(0), to_app(n)->get_arg(1), v1, v2);
|
||||
}
|
||||
|
||||
bool is_x_gle_y_atom(expr * n, var * & v1, var * & v2) {
|
||||
|
@ -2042,28 +2035,28 @@ namespace smt {
|
|||
return false;
|
||||
if (sign) {
|
||||
bool r = is_le_ge(atom) && is_var_and_ground(to_app(atom)->get_arg(0), to_app(atom)->get_arg(1), v, t);
|
||||
CTRACE("is_x_gle_t", r, tout << "is_x_gle_t: " << mk_ismt2_pp(atom, m_manager) << "\n--->\n"
|
||||
<< mk_ismt2_pp(v, m_manager) << " " << mk_ismt2_pp(t, m_manager) << "\n";
|
||||
CTRACE("is_x_gle_t", r, tout << "is_x_gle_t: " << mk_ismt2_pp(atom, m) << "\n--->\n"
|
||||
<< mk_ismt2_pp(v, m) << " " << mk_ismt2_pp(t, m) << "\n";
|
||||
tout << "sign: " << sign << "\n";);
|
||||
return r;
|
||||
}
|
||||
else {
|
||||
if (is_le_ge(atom)) {
|
||||
expr_ref tmp(m_manager);
|
||||
expr_ref tmp(m);
|
||||
bool le = is_le(atom);
|
||||
bool inv = false;
|
||||
if (is_var_and_ground(to_app(atom)->get_arg(0), to_app(atom)->get_arg(1), v, tmp, inv)) {
|
||||
if (inv)
|
||||
le = !le;
|
||||
sort * s = m_manager.get_sort(tmp);
|
||||
expr_ref one(m_manager);
|
||||
sort * s = m.get_sort(tmp);
|
||||
expr_ref one(m);
|
||||
one = mk_one(s);
|
||||
if (le)
|
||||
mk_add(tmp, one, t);
|
||||
else
|
||||
mk_sub(tmp, one, t);
|
||||
TRACE("is_x_gle_t", tout << "is_x_gle_t: " << mk_ismt2_pp(atom, m_manager) << "\n--->\n"
|
||||
<< mk_ismt2_pp(v, m_manager) << " " << mk_ismt2_pp(t, m_manager) << "\n";
|
||||
TRACE("is_x_gle_t", tout << "is_x_gle_t: " << mk_ismt2_pp(atom, m) << "\n--->\n"
|
||||
<< mk_ismt2_pp(v, m) << " " << mk_ismt2_pp(t, m) << "\n";
|
||||
tout << "sign: " << sign << "\n";);
|
||||
return true;
|
||||
}
|
||||
|
@ -2113,9 +2106,9 @@ namespace smt {
|
|||
}
|
||||
|
||||
var * v;
|
||||
expr_ref k(m_manager);
|
||||
expr_ref k(m);
|
||||
if (is_var_plus_ground(arg, v, k)) {
|
||||
insert_qinfo(alloc(f_var_plus_offset, m_manager, t->get_decl(), i, v->get_idx(), k.get()));
|
||||
insert_qinfo(alloc(f_var_plus_offset, m, t->get_decl(), i, v->get_idx(), k.get()));
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -2157,7 +2150,7 @@ namespace smt {
|
|||
for (unsigned i = 1; i < num_args; i++) {
|
||||
expr * arg = t->get_arg(i);
|
||||
if (is_var(arg)) {
|
||||
insert_qinfo(alloc(select_var, m_manager, t, i, to_var(arg)->get_idx()));
|
||||
insert_qinfo(alloc(select_var, m, t, i, to_var(arg)->get_idx()));
|
||||
}
|
||||
else {
|
||||
SASSERT(is_ground(arg));
|
||||
|
@ -2174,7 +2167,7 @@ namespace smt {
|
|||
void process_app(app * t) {
|
||||
SASSERT(!is_ground(t));
|
||||
|
||||
if (t->get_family_id() != m_manager.get_basic_family_id()) {
|
||||
if (t->get_family_id() != m.get_basic_family_id()) {
|
||||
m_info->m_ng_decls.insert(t->get_decl());
|
||||
}
|
||||
|
||||
|
@ -2191,7 +2184,7 @@ namespace smt {
|
|||
expr * curr = m_ttodo.back();
|
||||
m_ttodo.pop_back();
|
||||
|
||||
if (m_manager.is_bool(curr)) {
|
||||
if (m.is_bool(curr)) {
|
||||
// formula nested in a term.
|
||||
visit_formula(curr, POS);
|
||||
visit_formula(curr, NEG);
|
||||
|
@ -2212,30 +2205,30 @@ namespace smt {
|
|||
}
|
||||
|
||||
void process_literal(expr * atom, bool sign) {
|
||||
CTRACE("model_finder_bug", is_ground(atom), tout << mk_pp(atom, m_manager) << "\n";);
|
||||
CTRACE("model_finder_bug", is_ground(atom), tout << mk_pp(atom, m) << "\n";);
|
||||
SASSERT(!is_ground(atom));
|
||||
SASSERT(m_manager.is_bool(atom));
|
||||
SASSERT(m.is_bool(atom));
|
||||
|
||||
if (is_var(atom)) {
|
||||
if (sign) {
|
||||
// atom (not X) can be viewed as X != true
|
||||
insert_qinfo(alloc(x_neq_t, m_manager, to_var(atom)->get_idx(), m_manager.mk_true()));
|
||||
insert_qinfo(alloc(x_neq_t, m, to_var(atom)->get_idx(), m.mk_true()));
|
||||
}
|
||||
else {
|
||||
// atom X can be viewed as X != false
|
||||
insert_qinfo(alloc(x_neq_t, m_manager, to_var(atom)->get_idx(), m_manager.mk_false()));
|
||||
insert_qinfo(alloc(x_neq_t, m, to_var(atom)->get_idx(), m.mk_false()));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_app(atom)) {
|
||||
var * v, * v1, * v2;
|
||||
expr_ref t(m_manager);
|
||||
expr_ref t(m);
|
||||
if (is_x_eq_t_atom(atom, v, t)) {
|
||||
if (sign)
|
||||
insert_qinfo(alloc(x_neq_t, m_manager, v->get_idx(), t));
|
||||
insert_qinfo(alloc(x_neq_t, m, v->get_idx(), t));
|
||||
else
|
||||
insert_qinfo(alloc(x_eq_t, m_manager, v->get_idx(), t));
|
||||
insert_qinfo(alloc(x_eq_t, m, v->get_idx(), t));
|
||||
}
|
||||
else if (is_x_eq_y_atom(atom, v1, v2)) {
|
||||
if (sign)
|
||||
|
@ -2252,7 +2245,7 @@ namespace smt {
|
|||
insert_qinfo(alloc(x_leq_y, v1->get_idx(), v2->get_idx()));
|
||||
}
|
||||
else if (is_x_gle_t_atom(atom, sign, v, t)) {
|
||||
insert_qinfo(alloc(x_gle_t, m_manager, v->get_idx(), t));
|
||||
insert_qinfo(alloc(x_gle_t, m, v->get_idx(), t));
|
||||
}
|
||||
else {
|
||||
process_app(to_app(atom));
|
||||
|
@ -2299,7 +2292,7 @@ namespace smt {
|
|||
polarity pol = e.second;
|
||||
m_ftodo.pop_back();
|
||||
if (is_app(curr)) {
|
||||
if (to_app(curr)->get_family_id() == m_manager.get_basic_family_id() && m_manager.is_bool(curr)) {
|
||||
if (to_app(curr)->get_family_id() == m.get_basic_family_id() && m.is_bool(curr)) {
|
||||
switch (static_cast<basic_op_kind>(to_app(curr)->get_decl_kind())) {
|
||||
case OP_IMPLIES:
|
||||
case OP_XOR:
|
||||
|
@ -2316,7 +2309,7 @@ namespace smt {
|
|||
process_ite(to_app(curr), pol);
|
||||
break;
|
||||
case OP_EQ:
|
||||
if (m_manager.is_bool(to_app(curr)->get_arg(0))) {
|
||||
if (m.is_bool(to_app(curr)->get_arg(0))) {
|
||||
process_iff(to_app(curr));
|
||||
}
|
||||
else {
|
||||
|
@ -2333,7 +2326,7 @@ namespace smt {
|
|||
}
|
||||
}
|
||||
else if (is_var(curr)) {
|
||||
SASSERT(m_manager.is_bool(curr));
|
||||
SASSERT(m.is_bool(curr));
|
||||
process_literal(curr, pol);
|
||||
}
|
||||
else {
|
||||
|
@ -2344,32 +2337,32 @@ namespace smt {
|
|||
}
|
||||
|
||||
void process_formula(expr * n) {
|
||||
SASSERT(m_manager.is_bool(n));
|
||||
SASSERT(m.is_bool(n));
|
||||
visit_formula(n, POS);
|
||||
}
|
||||
|
||||
void process_clause(expr * cls) {
|
||||
SASSERT(is_clause(m_manager, cls));
|
||||
unsigned num_lits = get_clause_num_literals(m_manager, cls);
|
||||
SASSERT(is_clause(m, cls));
|
||||
unsigned num_lits = get_clause_num_literals(m, cls);
|
||||
for (unsigned i = 0; i < num_lits; i++) {
|
||||
expr * lit = get_clause_literal(m_manager, cls, i);
|
||||
SASSERT(is_literal(m_manager, lit));
|
||||
expr * lit = get_clause_literal(m, cls, i);
|
||||
SASSERT(is_literal(m, lit));
|
||||
expr * atom;
|
||||
bool sign;
|
||||
get_literal_atom_sign(m_manager, lit, atom, sign);
|
||||
get_literal_atom_sign(m, lit, atom, sign);
|
||||
if (!is_ground(atom))
|
||||
process_literal(atom, sign);
|
||||
}
|
||||
}
|
||||
|
||||
void collect_macro_candidates(quantifier * q) {
|
||||
macro_util::macro_candidates candidates(m_manager);
|
||||
macro_util::macro_candidates candidates(m);
|
||||
m_mutil.collect_macro_candidates(q, candidates);
|
||||
unsigned num_candidates = candidates.size();
|
||||
for (unsigned i = 0; i < num_candidates; i++) {
|
||||
cond_macro * m = alloc(cond_macro, m_manager, candidates.get_f(i), candidates.get_def(i), candidates.get_cond(i),
|
||||
cond_macro * mc = alloc(cond_macro, m, candidates.get_f(i), candidates.get_def(i), candidates.get_cond(i),
|
||||
candidates.ineq(i), candidates.satisfy_atom(i), candidates.hint(i), q->get_weight());
|
||||
m_info->insert_macro(m);
|
||||
m_info->insert_macro(mc);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2377,7 +2370,7 @@ namespace smt {
|
|||
public:
|
||||
quantifier_analyzer(model_finder& mf, ast_manager & m):
|
||||
m_mf(mf),
|
||||
m_manager(m),
|
||||
m(m),
|
||||
m_mutil(m),
|
||||
m_array_util(m),
|
||||
m_arith_util(m),
|
||||
|
@ -2389,13 +2382,14 @@ namespace smt {
|
|||
void operator()(quantifier_info * d) {
|
||||
m_info = d;
|
||||
quantifier * q = d->get_flat_q();
|
||||
if (m.is_lambda_def(q)) return;
|
||||
expr * e = q->get_expr();
|
||||
SASSERT(!has_quantifiers(e));
|
||||
reset_cache();
|
||||
SASSERT(m_ttodo.empty());
|
||||
SASSERT(m_ftodo.empty());
|
||||
|
||||
if (is_clause(m_manager, e)) {
|
||||
if (is_clause(m, e)) {
|
||||
process_clause(e);
|
||||
}
|
||||
else {
|
||||
|
@ -2419,7 +2413,7 @@ namespace smt {
|
|||
*/
|
||||
class base_macro_solver {
|
||||
protected:
|
||||
ast_manager & m_manager;
|
||||
ast_manager & m;
|
||||
obj_map<quantifier, quantifier_info *> const & m_q2info;
|
||||
proto_model * m_model;
|
||||
|
||||
|
@ -2434,18 +2428,18 @@ namespace smt {
|
|||
SASSERT(f_else != 0);
|
||||
func_interp * fi = m_model->get_func_interp(f);
|
||||
if (fi == nullptr) {
|
||||
fi = alloc(func_interp, m_manager, f->get_arity());
|
||||
fi = alloc(func_interp, m, f->get_arity());
|
||||
m_model->register_decl(f, fi);
|
||||
}
|
||||
fi->set_else(f_else);
|
||||
TRACE("model_finder", tout << f->get_name() << " " << mk_pp(f_else, m_manager) << "\n";);
|
||||
TRACE("model_finder", tout << f->get_name() << " " << mk_pp(f_else, m) << "\n";);
|
||||
}
|
||||
|
||||
virtual bool process(ptr_vector<quantifier> const & qs, ptr_vector<quantifier> & new_qs, ptr_vector<quantifier> & residue) = 0;
|
||||
|
||||
public:
|
||||
base_macro_solver(ast_manager & m, obj_map<quantifier, quantifier_info *> const & q2i):
|
||||
m_manager(m),
|
||||
m(m),
|
||||
m_q2info(q2i),
|
||||
m_model(nullptr) {
|
||||
}
|
||||
|
@ -2647,7 +2641,7 @@ namespace smt {
|
|||
|
||||
bool is_candidate(quantifier * q) const {
|
||||
quantifier_info * qi = get_qinfo(q);
|
||||
for (cond_macro * m : qi->macros()) {
|
||||
for (cond_macro* m : qi->macros()) {
|
||||
if (m->satisfy_atom() && !m_forbidden.contains(m->get_f()))
|
||||
return true;
|
||||
}
|
||||
|
@ -2708,7 +2702,7 @@ namespace smt {
|
|||
|
||||
void display_qcandidates(std::ostream & out, ptr_vector<quantifier> const & qcandidates) const {
|
||||
for (quantifier * q : qcandidates) {
|
||||
out << q->get_qid() << " ->\n" << mk_pp(q, m_manager) << "\n";
|
||||
out << q->get_qid() << " ->\n" << mk_pp(q, m) << "\n";
|
||||
quantifier_info * qi = get_qinfo(q);
|
||||
qi->display(out);
|
||||
out << "------\n";
|
||||
|
@ -2724,7 +2718,7 @@ namespace smt {
|
|||
func_decl * f = kv.get_key1();
|
||||
expr * def = kv.get_key2();
|
||||
quantifier_set * s = kv.get_value();
|
||||
out << f->get_name() << " " << mk_pp(def, m_manager) << " ->\n"; display_quantifier_set(out, s);
|
||||
out << f->get_name() << " " << mk_pp(def, m) << " ->\n"; display_quantifier_set(out, s);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2846,7 +2840,7 @@ namespace smt {
|
|||
|
||||
m_satisfied.push_scope();
|
||||
m_residue.push_scope();
|
||||
TRACE("model_finder", tout << f->get_name() << " " << mk_pp(def, m_manager) << "\n";);
|
||||
TRACE("model_finder", tout << f->get_name() << " " << mk_pp(def, m) << "\n";);
|
||||
m_fs.insert(f, def);
|
||||
|
||||
if (update_satisfied_residue(f, def)) {
|
||||
|
@ -3023,7 +3017,7 @@ namespace smt {
|
|||
qi_params const * m_qi_params;
|
||||
|
||||
bool add_macro(func_decl * f, expr * f_else) {
|
||||
TRACE("model_finder", tout << "trying to add macro for " << f->get_name() << "\n" << mk_pp(f_else, m_manager) << "\n";);
|
||||
TRACE("model_finder", tout << "trying to add macro for " << f->get_name() << "\n" << mk_pp(f_else, m) << "\n";);
|
||||
func_decl_set * s = m_dependencies.mk_func_decl_set();
|
||||
m_dependencies.collect_ng_func_decls(f_else, s);
|
||||
if (!m_dependencies.insert(f, s)) {
|
||||
|
@ -3092,23 +3086,23 @@ namespace smt {
|
|||
}
|
||||
|
||||
void process(func_decl * f, ptr_vector<quantifier> const & qs, obj_hashtable<quantifier> & removed) {
|
||||
expr_ref fi_else(m_manager);
|
||||
expr_ref fi_else(m);
|
||||
ptr_buffer<quantifier> to_remove;
|
||||
for (quantifier * q : qs) {
|
||||
if (removed.contains(q))
|
||||
continue;
|
||||
cond_macro * m = get_macro_for(f, q);
|
||||
if (!m)
|
||||
cond_macro * cm = get_macro_for(f, q);
|
||||
if (!cm)
|
||||
continue;
|
||||
SASSERT(!m->is_hint());
|
||||
if (m->is_unconditional())
|
||||
SASSERT(!cm->is_hint());
|
||||
if (cm->is_unconditional())
|
||||
return; // f is part of a full macro... ignoring it.
|
||||
to_remove.push_back(q);
|
||||
if (fi_else.get() == nullptr) {
|
||||
fi_else = m->get_def();
|
||||
fi_else = cm->get_def();
|
||||
}
|
||||
else {
|
||||
fi_else = m_manager.mk_ite(m->get_cond(), m->get_def(), fi_else);
|
||||
fi_else = m.mk_ite(cm->get_cond(), cm->get_def(), fi_else);
|
||||
}
|
||||
}
|
||||
if (fi_else.get() != nullptr && add_macro(f, fi_else)) {
|
||||
|
@ -3166,7 +3160,7 @@ namespace smt {
|
|||
// -----------------------------------
|
||||
|
||||
model_finder::model_finder(ast_manager & m):
|
||||
m_manager(m),
|
||||
m(m),
|
||||
m_context(nullptr),
|
||||
m_analyzer(alloc(quantifier_analyzer, *this, m)),
|
||||
m_auf_solver(alloc(auf_solver, m)),
|
||||
|
@ -3206,8 +3200,8 @@ namespace smt {
|
|||
}
|
||||
|
||||
void model_finder::register_quantifier(quantifier * q) {
|
||||
TRACE("model_finder", tout << "registering:\n" << mk_pp(q, m_manager) << "\n";);
|
||||
quantifier_info * new_info = alloc(quantifier_info, *this, m_manager, q);
|
||||
TRACE("model_finder", tout << "registering:\n" << mk_pp(q, m) << "\n";);
|
||||
quantifier_info * new_info = alloc(quantifier_info, *this, m, q);
|
||||
m_q2info.insert(q, new_info);
|
||||
m_quantifiers.push_back(q);
|
||||
m_analyzer->operator()(new_info);
|
||||
|
@ -3261,9 +3255,9 @@ namespace smt {
|
|||
}
|
||||
}
|
||||
|
||||
void model_finder::process_auf(ptr_vector<quantifier> const & qs, proto_model * m) {
|
||||
void model_finder::process_auf(ptr_vector<quantifier> const & qs, proto_model * mdl) {
|
||||
m_auf_solver->reset();
|
||||
m_auf_solver->set_model(m);
|
||||
m_auf_solver->set_model(mdl);
|
||||
|
||||
for (quantifier * q : qs) {
|
||||
quantifier_info * qi = get_quantifier_info(q);
|
||||
|
@ -3280,7 +3274,7 @@ namespace smt {
|
|||
for (quantifier * q : qs) {
|
||||
quantifier_info * qi = get_quantifier_info(q);
|
||||
quantifier * fq = qi->get_flat_q();
|
||||
tout << "#" << fq->get_id() << " ->\n" << mk_pp(fq, m_manager) << "\n";
|
||||
tout << "#" << fq->get_id() << " ->\n" << mk_pp(fq, m) << "\n";
|
||||
}
|
||||
m_auf_solver->display_nodes(tout););
|
||||
}
|
||||
|
@ -3310,11 +3304,8 @@ namespace smt {
|
|||
\brief Clean leftovers from previous invocations to fix_model.
|
||||
*/
|
||||
void model_finder::cleanup_quantifier_infos(ptr_vector<quantifier> const & qs) {
|
||||
ptr_vector<quantifier>::const_iterator it = qs.begin();
|
||||
ptr_vector<quantifier>::const_iterator end = qs.end();
|
||||
for (; it != end; ++it) {
|
||||
quantifier_info * qi = get_quantifier_info(*it);
|
||||
qi->reset_the_one();
|
||||
for (quantifier* q : qs) {
|
||||
get_quantifier_info(q)->reset_the_one();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3356,7 +3347,7 @@ namespace smt {
|
|||
quantifier * flat_q = get_flat_quantifier(q);
|
||||
SASSERT(flat_q->get_num_decls() >= q->get_num_decls());
|
||||
instantiation_set const * r = m_auf_solver->get_uvar_inst_set(flat_q, flat_q->get_num_decls() - q->get_num_decls() + i);
|
||||
TRACE("model_finder", tout << "q: #" << q->get_id() << "\n" << mk_pp(q,m_manager) << "\nflat_q: " << mk_pp(flat_q, m_manager)
|
||||
TRACE("model_finder", tout << "q: #" << q->get_id() << "\n" << mk_pp(q,m) << "\nflat_q: " << mk_pp(flat_q, m)
|
||||
<< "\ni: " << i << " " << flat_q->get_num_decls() - q->get_num_decls() + i << "\n";);
|
||||
if (r != nullptr)
|
||||
return r;
|
||||
|
@ -3365,7 +3356,6 @@ namespace smt {
|
|||
quantifier_info * qinfo = get_quantifier_info(q);
|
||||
SASSERT(qinfo);
|
||||
SASSERT(qinfo->get_the_one() != 0);
|
||||
|
||||
return qinfo->get_macro_based_inst_set(i, m_context, *(m_auf_solver.get()));
|
||||
}
|
||||
|
||||
|
@ -3415,15 +3405,13 @@ namespace smt {
|
|||
if (inv.empty())
|
||||
continue; // nothing to do
|
||||
ptr_buffer<expr> eqs;
|
||||
obj_map<expr, expr *>::iterator it = inv.begin();
|
||||
obj_map<expr, expr *>::iterator end = inv.end();
|
||||
for (; it != end; ++it) {
|
||||
expr * val = (*it).m_key;
|
||||
eqs.push_back(m_manager.mk_eq(sk, val));
|
||||
for (auto const& kv : inv) {
|
||||
expr * val = kv.m_key;
|
||||
eqs.push_back(m.mk_eq(sk, val));
|
||||
}
|
||||
expr_ref new_cnstr(m_manager);
|
||||
new_cnstr = m_manager.mk_or(eqs.size(), eqs.c_ptr());
|
||||
TRACE("model_finder", tout << "assert_restriction:\n" << mk_pp(new_cnstr, m_manager) << "\n";);
|
||||
expr_ref new_cnstr(m);
|
||||
new_cnstr = m.mk_or(eqs.size(), eqs.c_ptr());
|
||||
TRACE("model_finder", tout << "assert_restriction:\n" << mk_pp(new_cnstr, m) << "\n";);
|
||||
aux_ctx->assert_expr(new_cnstr);
|
||||
asserted_something = true;
|
||||
}
|
||||
|
@ -3435,7 +3423,7 @@ namespace smt {
|
|||
if (sz > 0) {
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
expr * c = m_new_constraints.get(i);
|
||||
TRACE("model_finder_bug_detail", tout << "asserting new constraint: " << mk_pp(c, m_manager) << "\n";);
|
||||
TRACE("model_finder_bug_detail", tout << "asserting new constraint: " << mk_pp(c, m) << "\n";);
|
||||
m_context->internalize(c, true);
|
||||
literal l(m_context->get_literal(c));
|
||||
m_context->mark_as_relevant(l);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue