mirror of
https://github.com/Z3Prover/z3
synced 2025-04-23 09:05:31 +00:00
fix model generation for tc/po
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
551d72b294
commit
6fee9b90cb
13 changed files with 117 additions and 177 deletions
|
@ -50,7 +50,7 @@ namespace recfun {
|
|||
}
|
||||
|
||||
def::def(ast_manager &m, family_id fid, symbol const & s,
|
||||
unsigned arity, sort* const * domain, sort* range)
|
||||
unsigned arity, sort* const * domain, sort* range, bool is_generated)
|
||||
: m(m), m_name(s),
|
||||
m_domain(m, arity, domain),
|
||||
m_range(range, m), m_vars(m), m_cases(),
|
||||
|
@ -59,7 +59,8 @@ namespace recfun {
|
|||
m_fid(fid)
|
||||
{
|
||||
SASSERT(arity == get_arity());
|
||||
func_decl_info info(fid, OP_FUN_DEFINED);
|
||||
parameter p(is_generated);
|
||||
func_decl_info info(fid, OP_FUN_DEFINED, 1, &p);
|
||||
m_decl = m.mk_func_decl(s, arity, domain, range, info);
|
||||
}
|
||||
|
||||
|
@ -315,8 +316,8 @@ namespace recfun {
|
|||
util::~util() {
|
||||
}
|
||||
|
||||
def * util::decl_fun(symbol const& name, unsigned n, sort *const * domain, sort * range) {
|
||||
return alloc(def, m(), m_fid, name, n, domain, range);
|
||||
def * util::decl_fun(symbol const& name, unsigned n, sort *const * domain, sort * range, bool is_generated) {
|
||||
return alloc(def, m(), m_fid, name, n, domain, range, is_generated);
|
||||
}
|
||||
|
||||
|
||||
|
@ -386,15 +387,15 @@ namespace recfun {
|
|||
return *(m_util.get());
|
||||
}
|
||||
|
||||
promise_def plugin::mk_def(symbol const& name, unsigned n, sort *const * params, sort * range) {
|
||||
def* d = u().decl_fun(name, n, params, range);
|
||||
promise_def plugin::mk_def(symbol const& name, unsigned n, sort *const * params, sort * range, bool is_generated) {
|
||||
def* d = u().decl_fun(name, n, params, range, is_generated);
|
||||
SASSERT(!m_defs.contains(d->get_decl()));
|
||||
m_defs.insert(d->get_decl(), d);
|
||||
return promise_def(&u(), d);
|
||||
}
|
||||
|
||||
promise_def plugin::ensure_def(symbol const& name, unsigned n, sort *const * params, sort * range) {
|
||||
def* d = u().decl_fun(name, n, params, range);
|
||||
promise_def plugin::ensure_def(symbol const& name, unsigned n, sort *const * params, sort * range, bool is_generated) {
|
||||
def* d = u().decl_fun(name, n, params, range, is_generated);
|
||||
def* d2 = nullptr;
|
||||
if (m_defs.find(d->get_decl(), d2)) {
|
||||
dealloc(d2);
|
||||
|
|
|
@ -108,7 +108,7 @@ namespace recfun {
|
|||
expr_ref m_rhs; //!< definition
|
||||
family_id m_fid;
|
||||
|
||||
def(ast_manager &m, family_id fid, symbol const & s, unsigned arity, sort *const * domain, sort* range);
|
||||
def(ast_manager &m, family_id fid, symbol const & s, unsigned arity, sort *const * domain, sort* range, bool is_generated);
|
||||
|
||||
// compute cases for a function, given its RHS (possibly containing `ite`).
|
||||
void compute_cases(replace& subst, is_immediate_pred &,
|
||||
|
@ -147,6 +147,7 @@ namespace recfun {
|
|||
class plugin : public decl_plugin {
|
||||
typedef obj_map<func_decl, def*> def_map;
|
||||
typedef obj_map<func_decl, case_def*> case_def_map;
|
||||
|
||||
|
||||
mutable scoped_ptr<util> m_util;
|
||||
def_map m_defs; // function->def
|
||||
|
@ -171,9 +172,9 @@ namespace recfun {
|
|||
func_decl * mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters,
|
||||
unsigned arity, sort * const * domain, sort * range) override;
|
||||
|
||||
promise_def mk_def(symbol const& name, unsigned n, sort *const * params, sort * range);
|
||||
promise_def mk_def(symbol const& name, unsigned n, sort *const * params, sort * range, bool is_generated = false);
|
||||
|
||||
promise_def ensure_def(symbol const& name, unsigned n, sort *const * params, sort * range);
|
||||
promise_def ensure_def(symbol const& name, unsigned n, sort *const * params, sort * range, bool is_generated = false);
|
||||
|
||||
void set_definition(replace& r, promise_def & d, unsigned n_vars, var * const * vars, expr * rhs);
|
||||
|
||||
|
@ -216,6 +217,7 @@ namespace recfun {
|
|||
bool is_case_pred(expr * e) const { return is_app_of(e, m_fid, OP_FUN_CASE_PRED); }
|
||||
bool is_defined(expr * e) const { return is_app_of(e, m_fid, OP_FUN_DEFINED); }
|
||||
bool is_defined(func_decl* f) const { return is_decl_of(f, m_fid, OP_FUN_DEFINED); }
|
||||
bool is_generated(func_decl* f) const { return is_defined(f) && f->get_parameter(0).get_int() == 1; }
|
||||
bool is_depth_limit(expr * e) const { return is_app_of(e, m_fid, OP_DEPTH_LIMIT); }
|
||||
bool owns_app(app * e) const { return e->get_family_id() == m_fid; }
|
||||
|
||||
|
@ -223,7 +225,7 @@ namespace recfun {
|
|||
bool has_defs() const { return m_plugin->has_defs(); }
|
||||
|
||||
//<! add a function declaration
|
||||
def * decl_fun(symbol const & s, unsigned n_args, sort *const * args, sort * range);
|
||||
def * decl_fun(symbol const & s, unsigned n_args, sort *const * args, sort * range, bool is_generated);
|
||||
|
||||
def& get_def(func_decl* f) {
|
||||
SASSERT(m_plugin->has_def(f));
|
||||
|
|
|
@ -24,6 +24,7 @@ void bool_rewriter::updt_params(params_ref const & _p) {
|
|||
bool_rewriter_params p(_p);
|
||||
m_flat = p.flat();
|
||||
m_elim_and = p.elim_and();
|
||||
m_elim_ite = p.elim_ite();
|
||||
m_local_ctx = p.local_ctx();
|
||||
m_local_ctx_limit = p.local_ctx_limit();
|
||||
m_blast_distinct = p.blast_distinct();
|
||||
|
@ -797,48 +798,52 @@ br_status bool_rewriter::mk_ite_core(expr * c, expr * t, expr * e, expr_ref & re
|
|||
result = c;
|
||||
return BR_DONE;
|
||||
}
|
||||
mk_or(c, e, result);
|
||||
return BR_DONE;
|
||||
if (m_elim_ite) {
|
||||
mk_or(c, e, result);
|
||||
return BR_DONE;
|
||||
}
|
||||
}
|
||||
if (m().is_false(t)) {
|
||||
if (m().is_true(e)) {
|
||||
mk_not(c, result);
|
||||
return BR_DONE;
|
||||
}
|
||||
expr_ref tmp(m());
|
||||
mk_not(c, tmp);
|
||||
mk_and(tmp, e, result);
|
||||
return BR_DONE;
|
||||
if (m_elim_ite) {
|
||||
expr_ref tmp(m());
|
||||
mk_not(c, tmp);
|
||||
mk_and(tmp, e, result);
|
||||
return BR_DONE;
|
||||
}
|
||||
}
|
||||
if (m().is_true(e)) {
|
||||
if (m().is_true(e) && m_elim_ite) {
|
||||
expr_ref tmp(m());
|
||||
mk_not(c, tmp);
|
||||
mk_or(tmp, t, result);
|
||||
return BR_DONE;
|
||||
}
|
||||
if (m().is_false(e)) {
|
||||
if (m().is_false(e) && m_elim_ite) {
|
||||
mk_and(c, t, result);
|
||||
return BR_DONE;
|
||||
}
|
||||
if (c == e) {
|
||||
if (c == e && m_elim_ite) {
|
||||
mk_and(c, t, result);
|
||||
return BR_DONE;
|
||||
}
|
||||
if (c == t) {
|
||||
if (c == t && m_elim_ite) {
|
||||
mk_or(c, e, result);
|
||||
return BR_DONE;
|
||||
}
|
||||
if (m().is_complement_core(t, e)) { // t = not(e)
|
||||
if (m().is_complement_core(t, e) && m_elim_ite) { // t = not(e)
|
||||
mk_eq(c, t, result);
|
||||
return BR_DONE;
|
||||
}
|
||||
if (m().is_complement_core(e, t)) { // e = not(t)
|
||||
if (m().is_complement_core(e, t) && m_elim_ite) { // e = not(t)
|
||||
mk_eq(c, t, result);
|
||||
return BR_DONE;
|
||||
}
|
||||
}
|
||||
|
||||
if (m().is_ite(t) && m_ite_extra_rules) {
|
||||
if (m().is_ite(t) && m_ite_extra_rules && m_elim_ite) {
|
||||
// (ite c1 (ite c2 t1 t2) t1) ==> (ite (and c1 (not c2)) t2 t1)
|
||||
if (e == to_app(t)->get_arg(1)) {
|
||||
expr_ref not_c2(m());
|
||||
|
@ -891,7 +896,7 @@ br_status bool_rewriter::mk_ite_core(expr * c, expr * t, expr * e, expr_ref & re
|
|||
}
|
||||
}
|
||||
|
||||
if (m().is_ite(e) && m_ite_extra_rules) {
|
||||
if (m().is_ite(e) && m_ite_extra_rules && m_elim_ite) {
|
||||
// (ite c1 t1 (ite c2 t1 t2)) ==> (ite (or c1 c2) t1 t2)
|
||||
if (t == to_app(e)->get_arg(1)) {
|
||||
expr_ref new_c(m());
|
||||
|
|
|
@ -59,6 +59,7 @@ class bool_rewriter {
|
|||
bool m_ite_extra_rules;
|
||||
unsigned m_local_ctx_limit;
|
||||
unsigned m_local_ctx_cost;
|
||||
bool m_elim_ite;
|
||||
|
||||
br_status mk_flat_and_core(unsigned num_args, expr * const * args, expr_ref & result);
|
||||
br_status mk_flat_or_core(unsigned num_args, expr * const * args, expr_ref & result);
|
||||
|
|
|
@ -4,6 +4,7 @@ def_module_params(module_name='rewriter',
|
|||
params=(("ite_extra_rules", BOOL, False, "extra ite simplifications, these additional simplifications may reduce size locally but increase globally"),
|
||||
("flat", BOOL, True, "create nary applications for and,or,+,*,bvadd,bvmul,bvand,bvor,bvxor"),
|
||||
("elim_and", BOOL, False, "conjunctions are rewritten using negation and disjunctions"),
|
||||
('elim_ite', BOOL, True, "eliminate ite in favor of and/or"),
|
||||
("local_ctx", BOOL, False, "perform local (i.e., cheap) context simplifications"),
|
||||
("local_ctx_limit", UINT, UINT_MAX, "limit for applying local context simplifier"),
|
||||
("blast_distinct", BOOL, False, "expand a distinct predicate into a quadratic number of disequalities"),
|
||||
|
|
|
@ -45,7 +45,7 @@ func_decl * special_relations_decl_plugin::mk_func_decl(
|
|||
if (!range) {
|
||||
range = m_manager->mk_bool_sort();
|
||||
}
|
||||
if (!m_manager->is_bool(range) && k != OP_SPECIAL_RELATION_NEXT) {
|
||||
if (!m_manager->is_bool(range)) {
|
||||
m_manager->raise_exception("range type is expected to be Boolean for special relations");
|
||||
}
|
||||
func_decl_info info(m_family_id, k, num_parameters, parameters);
|
||||
|
@ -57,7 +57,6 @@ func_decl * special_relations_decl_plugin::mk_func_decl(
|
|||
case OP_SPECIAL_RELATION_TO: name = m_to; break;
|
||||
case OP_SPECIAL_RELATION_TC: name = m_tc; break;
|
||||
case OP_SPECIAL_RELATION_TRC: name = m_trc; break;
|
||||
case OP_SPECIAL_RELATION_NEXT: name = symbol("next"); break;
|
||||
}
|
||||
return m_manager->mk_func_decl(name, arity, domain, range, info);
|
||||
}
|
||||
|
@ -70,8 +69,6 @@ void special_relations_decl_plugin::get_op_names(svector<builtin_name> & op_name
|
|||
op_names.push_back(builtin_name(m_to.bare_str(), OP_SPECIAL_RELATION_TO));
|
||||
op_names.push_back(builtin_name(m_tc.bare_str(), OP_SPECIAL_RELATION_TC));
|
||||
op_names.push_back(builtin_name(m_trc.bare_str(), OP_SPECIAL_RELATION_TRC));
|
||||
// next is an internal skolem function used for unfolding a relation R to satisfy a relation that
|
||||
// is asserted for the transitive closure of R.
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -83,7 +80,6 @@ sr_property special_relations_util::get_property(func_decl* f) const {
|
|||
case OP_SPECIAL_RELATION_TO: return sr_to;
|
||||
case OP_SPECIAL_RELATION_TC: return sr_tc;
|
||||
case OP_SPECIAL_RELATION_TRC: return sr_trc;
|
||||
case OP_SPECIAL_RELATION_NEXT: return sr_none;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return sr_po;
|
||||
|
|
|
@ -30,7 +30,6 @@ enum special_relations_op_kind {
|
|||
OP_SPECIAL_RELATION_TO,
|
||||
OP_SPECIAL_RELATION_TC,
|
||||
OP_SPECIAL_RELATION_TRC,
|
||||
OP_SPECIAL_RELATION_NEXT,
|
||||
LAST_SPECIAL_RELATIONS_OP
|
||||
};
|
||||
|
||||
|
@ -95,12 +94,6 @@ public:
|
|||
func_decl* mk_lo_decl(func_decl* f) { return mk_rel_decl(f, OP_SPECIAL_RELATION_LO); }
|
||||
func_decl* mk_tc_decl(func_decl* f) { return mk_rel_decl(f, OP_SPECIAL_RELATION_TC); }
|
||||
func_decl* mk_trc_decl(func_decl* f) { return mk_rel_decl(f, OP_SPECIAL_RELATION_TRC); }
|
||||
func_decl* mk_next(func_decl* f) {
|
||||
sort* s = f->get_domain(0);
|
||||
sort* domain[2] = { s, s };
|
||||
parameter p(f); SASSERT(f->get_arity() == 2);
|
||||
return m.mk_func_decl(m_fid, OP_SPECIAL_RELATION_NEXT, 1, &p, 2, domain, s);
|
||||
}
|
||||
|
||||
bool is_lo(expr const * e) const { return is_app_of(e, m_fid, OP_SPECIAL_RELATION_LO); }
|
||||
bool is_po(expr const * e) const { return is_app_of(e, m_fid, OP_SPECIAL_RELATION_PO); }
|
||||
|
@ -108,7 +101,6 @@ public:
|
|||
bool is_to(expr const * e) const { return is_app_of(e, m_fid, OP_SPECIAL_RELATION_TO); }
|
||||
bool is_tc(expr const * e) const { return is_app_of(e, m_fid, OP_SPECIAL_RELATION_TC); }
|
||||
bool is_trc(expr const * e) const { return is_app_of(e, m_fid, OP_SPECIAL_RELATION_TRC); }
|
||||
bool is_next(expr const * e) const { return is_app_of(e, m_fid, OP_SPECIAL_RELATION_NEXT); }
|
||||
|
||||
app * mk_lo (expr * arg1, expr * arg2) { return m.mk_app( m_fid, OP_SPECIAL_RELATION_LO, arg1, arg2); }
|
||||
app * mk_po (expr * arg1, expr * arg2) { return m.mk_app( m_fid, OP_SPECIAL_RELATION_PO, arg1, arg2); }
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue