mirror of
https://github.com/Z3Prover/z3
synced 2025-08-18 09:12:16 +00:00
move to get_sort as method, add opt_lns pass, disable xor simplification unless configured, fix perf bug in model converter update trail
This commit is contained in:
parent
c623e2db28
commit
4455f6caf8
36 changed files with 391 additions and 90 deletions
|
@ -297,11 +297,11 @@ public:
|
|||
bool is_power0(expr const * n) const { return is_app_of(n, m_afid, OP_POWER0); }
|
||||
|
||||
bool is_int(sort const * s) const { return is_sort_of(s, m_afid, INT_SORT); }
|
||||
bool is_int(expr const * n) const { return is_int(get_sort(n)); }
|
||||
bool is_int(expr const * n) const { return is_int(n->get_sort()); }
|
||||
bool is_real(sort const * s) const { return is_sort_of(s, m_afid, REAL_SORT); }
|
||||
bool is_real(expr const * n) const { return is_real(get_sort(n)); }
|
||||
bool is_real(expr const * n) const { return is_real(n->get_sort()); }
|
||||
bool is_int_real(sort const * s) const { return s->get_family_id() == m_afid; }
|
||||
bool is_int_real(expr const * n) const { return is_int_real(get_sort(n)); }
|
||||
bool is_int_real(expr const * n) const { return is_int_real(n->get_sort()); }
|
||||
|
||||
bool is_sin(expr const* n) const { return is_app_of(n, m_afid, OP_SIN); }
|
||||
bool is_cos(expr const* n) const { return is_app_of(n, m_afid, OP_COS); }
|
||||
|
|
|
@ -144,7 +144,7 @@ public:
|
|||
array_recognizers(family_id fid):m_fid(fid) {}
|
||||
family_id get_family_id() const { return m_fid; }
|
||||
bool is_array(sort* s) const { return is_sort_of(s, m_fid, ARRAY_SORT);}
|
||||
bool is_array(expr* n) const { return is_array(get_sort(n)); }
|
||||
bool is_array(expr* n) const { return is_array(n->get_sort()); }
|
||||
bool is_select(expr* n) const { return is_app_of(n, m_fid, OP_SELECT); }
|
||||
bool is_store(expr* n) const { return is_app_of(n, m_fid, OP_STORE); }
|
||||
bool is_const(expr* n) const { return is_app_of(n, m_fid, OP_CONST_ARRAY); }
|
||||
|
|
|
@ -420,14 +420,14 @@ quantifier::quantifier(unsigned num_decls, sort * const * decl_sorts, symbol con
|
|||
//
|
||||
// -----------------------------------
|
||||
|
||||
sort * get_sort(expr const * n) {
|
||||
switch(n->get_kind()) {
|
||||
sort* expr::get_sort() const {
|
||||
switch (get_kind()) {
|
||||
case AST_APP:
|
||||
return to_app(n)->get_decl()->get_range();
|
||||
return to_app(this)->get_decl()->get_range();
|
||||
case AST_VAR:
|
||||
return to_var(n)->get_sort();
|
||||
return to_var(this)->_get_sort();
|
||||
case AST_QUANTIFIER:
|
||||
return to_quantifier(n)->get_sort();
|
||||
return to_quantifier(this)->_get_sort();
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return nullptr;
|
||||
|
@ -2513,7 +2513,7 @@ quantifier * ast_manager::mk_quantifier(quantifier_kind k, unsigned num_decls, s
|
|||
sort* s = nullptr;
|
||||
if (k == lambda_k) {
|
||||
array_util autil(*this);
|
||||
s = autil.mk_array_sort(num_decls, decl_sorts, ::get_sort(body));
|
||||
s = autil.mk_array_sort(num_decls, decl_sorts, body->get_sort());
|
||||
}
|
||||
else {
|
||||
s = mk_bool_sort();
|
||||
|
@ -2541,7 +2541,7 @@ quantifier * ast_manager::mk_lambda(unsigned num_decls, sort * const * decl_sort
|
|||
unsigned sz = quantifier::get_obj_size(num_decls, 0, 0);
|
||||
void * mem = allocate_node(sz);
|
||||
array_util autil(*this);
|
||||
sort* s = autil.mk_array_sort(num_decls, decl_sorts, ::get_sort(body));
|
||||
sort* s = autil.mk_array_sort(num_decls, decl_sorts, body->get_sort());
|
||||
quantifier * new_node = new (mem) quantifier(num_decls, decl_sorts, decl_names, body, s);
|
||||
quantifier * r = register_node(new_node);
|
||||
if (m_trace_stream && r == new_node) {
|
||||
|
|
|
@ -668,6 +668,8 @@ protected:
|
|||
|
||||
expr(ast_kind k):ast(k) {}
|
||||
public:
|
||||
|
||||
sort* get_sort() const;
|
||||
};
|
||||
|
||||
// -----------------------------------
|
||||
|
@ -719,6 +721,7 @@ public:
|
|||
unsigned get_size() const { return get_obj_size(get_num_args()); }
|
||||
expr * const * begin() const { return m_args; }
|
||||
expr * const * end() const { return m_args + m_num_args; }
|
||||
sort * _get_sort() const { return get_decl()->get_range(); }
|
||||
|
||||
unsigned get_depth() const { return flags()->m_depth; }
|
||||
bool is_ground() const { return flags()->m_ground; }
|
||||
|
@ -807,7 +810,7 @@ class var : public expr {
|
|||
var(unsigned idx, sort * s):expr(AST_VAR), m_idx(idx), m_sort(s) {}
|
||||
public:
|
||||
unsigned get_idx() const { return m_idx; }
|
||||
sort * get_sort() const { return m_sort; }
|
||||
sort * _get_sort() const { return m_sort; }
|
||||
unsigned get_size() const { return get_obj_size(); }
|
||||
};
|
||||
|
||||
|
@ -863,7 +866,7 @@ public:
|
|||
symbol const & get_decl_name(unsigned idx) const { return get_decl_names()[idx]; }
|
||||
expr * get_expr() const { return m_expr; }
|
||||
|
||||
sort * get_sort() const { return m_sort; }
|
||||
sort * _get_sort() const { return m_sort; }
|
||||
|
||||
unsigned get_depth() const { return m_depth; }
|
||||
|
||||
|
@ -1391,14 +1394,13 @@ inline bool has_labels(expr const * n) {
|
|||
else return false;
|
||||
}
|
||||
|
||||
sort * get_sort(expr const * n);
|
||||
|
||||
class basic_recognizers {
|
||||
family_id m_fid;
|
||||
public:
|
||||
basic_recognizers(family_id fid):m_fid(fid) {}
|
||||
bool is_bool(sort const * s) const { return is_sort_of(s, m_fid, BOOL_SORT); }
|
||||
bool is_bool(expr const * n) const { return is_bool(get_sort(n)); }
|
||||
bool is_bool(expr const * n) const { return is_bool(n->get_sort()); }
|
||||
bool is_or(expr const * n) const { return is_app_of(n, m_fid, OP_OR); }
|
||||
bool is_implies(expr const * n) const { return is_app_of(n, m_fid, OP_IMPLIES); }
|
||||
bool is_and(expr const * n) const { return is_app_of(n, m_fid, OP_AND); }
|
||||
|
@ -1733,7 +1735,7 @@ protected:
|
|||
}
|
||||
|
||||
public:
|
||||
sort * get_sort(expr const * n) const { return ::get_sort(n); }
|
||||
sort * get_sort(expr const * n) const { return n->get_sort(); }
|
||||
void check_sort(func_decl const * decl, unsigned num_args, expr * const * args) const;
|
||||
void check_sorts_core(ast const * n) const;
|
||||
bool check_sorts(ast const * n) const;
|
||||
|
|
|
@ -300,7 +300,7 @@ public:
|
|||
bool is_zero(expr const * e) const;
|
||||
bool is_one(expr const* e) const;
|
||||
bool is_bv_sort(sort const * s) const;
|
||||
bool is_bv(expr const* e) const { return is_bv_sort(get_sort(e)); }
|
||||
bool is_bv(expr const* e) const { return is_bv_sort(e->get_sort()); }
|
||||
|
||||
bool is_concat(expr const * e) const { return is_app_of(e, get_fid(), OP_CONCAT); }
|
||||
bool is_extract(func_decl const * f) const { return is_decl_of(f, get_fid(), OP_EXTRACT); }
|
||||
|
|
|
@ -43,6 +43,8 @@ struct enum2bv_rewriter::imp {
|
|||
ast_manager& m;
|
||||
datatype_util m_dt;
|
||||
bv_util m_bv;
|
||||
bool m_enable_unate { false };
|
||||
unsigned m_unate_bound { 30 };
|
||||
|
||||
rw_cfg(imp& i, ast_manager & m) :
|
||||
m_imp(i),
|
||||
|
@ -51,6 +53,38 @@ struct enum2bv_rewriter::imp {
|
|||
m_bv(m)
|
||||
{}
|
||||
|
||||
bool is_unate(sort* s) {
|
||||
if (!m_enable_unate)
|
||||
return false;
|
||||
unsigned nc = m_dt.get_datatype_num_constructors(s);
|
||||
return 1 < nc && nc <= m_unate_bound;
|
||||
}
|
||||
|
||||
expr* value2bv(unsigned idx, sort* s) {
|
||||
unsigned bv_size = get_bv_size(s);
|
||||
sort_ref bv_sort(m_bv.mk_sort(bv_size), m);
|
||||
if (is_unate(s))
|
||||
return m_bv.mk_numeral(rational((1 << idx) - 1), bv_sort);
|
||||
else
|
||||
return m_bv.mk_numeral(rational(idx), bv_sort);
|
||||
}
|
||||
|
||||
void constrain_domain(expr* x, sort* s, sort* bv_sort) {
|
||||
unsigned domain_size = m_dt.get_datatype_num_constructors(s);
|
||||
if (is_unate(s)) {
|
||||
expr_ref one(m_bv.mk_numeral(rational::one(), 1), m);
|
||||
for (unsigned i = 0; i + 2 < domain_size; ++i) {
|
||||
m_imp.m_bounds.push_back(m.mk_implies(m.mk_eq(one, m_bv.mk_extract(i + 1, i + 1, x)),
|
||||
m.mk_eq(one, m_bv.mk_extract(i, i, x))));
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!is_power_of_two(domain_size) || domain_size == 1) {
|
||||
m_imp.m_bounds.push_back(m_bv.mk_ule(x, value2bv(domain_size - 1, s)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
br_status reduce_app(func_decl * f, unsigned num, expr * const * args, expr_ref & result, proof_ref & result_pr) {
|
||||
expr_ref a0(m), a1(m);
|
||||
expr_ref_vector _args(m);
|
||||
|
@ -65,7 +99,7 @@ struct enum2bv_rewriter::imp {
|
|||
}
|
||||
else if (m_dt.is_recognizer(f) && reduce_arg(args[0], a0)) {
|
||||
unsigned idx = m_dt.get_recognizer_constructor_idx(f);
|
||||
a1 = m_bv.mk_numeral(rational(idx), get_sort(a0));
|
||||
a1 = value2bv(idx, a0->get_sort());
|
||||
result = m.mk_eq(a0, a1);
|
||||
return BR_DONE;
|
||||
}
|
||||
|
@ -92,7 +126,7 @@ struct enum2bv_rewriter::imp {
|
|||
|
||||
void check_for_fd(unsigned n, expr* const* args) {
|
||||
for (unsigned i = 0; i < n; ++i) {
|
||||
if (m_imp.is_fd(get_sort(args[i]))) {
|
||||
if (m_imp.is_fd(args[i]->get_sort())) {
|
||||
throw_non_fd(args[i]);
|
||||
}
|
||||
}
|
||||
|
@ -100,11 +134,12 @@ struct enum2bv_rewriter::imp {
|
|||
|
||||
bool reduce_arg(expr* a, expr_ref& result) {
|
||||
|
||||
sort* s = get_sort(a);
|
||||
sort* s = a->get_sort();
|
||||
if (!m_imp.is_fd(s)) {
|
||||
return false;
|
||||
}
|
||||
unsigned bv_size = get_bv_size(s);
|
||||
sort_ref bv_sort(m_bv.mk_sort(bv_size), m);
|
||||
|
||||
if (is_var(a)) {
|
||||
result = m.mk_var(to_var(a)->get_idx(), m_bv.mk_sort(bv_size));
|
||||
|
@ -114,7 +149,7 @@ struct enum2bv_rewriter::imp {
|
|||
func_decl* f = to_app(a)->get_decl();
|
||||
if (m_dt.is_constructor(f)) {
|
||||
unsigned idx = m_dt.get_constructor_idx(f);
|
||||
result = m_bv.mk_numeral(idx, bv_size);
|
||||
result = value2bv(idx, s);
|
||||
}
|
||||
else if (is_uninterp_const(a)) {
|
||||
func_decl* f_fresh;
|
||||
|
@ -125,17 +160,14 @@ struct enum2bv_rewriter::imp {
|
|||
|
||||
// create a fresh variable, add bounds constraints for it.
|
||||
unsigned nc = m_dt.get_datatype_num_constructors(s);
|
||||
result = m.mk_fresh_const(f->get_name(), m_bv.mk_sort(bv_size));
|
||||
result = m.mk_fresh_const(f->get_name(), bv_sort);
|
||||
f_fresh = to_app(result)->get_decl();
|
||||
if (!is_power_of_two(nc) || nc == 1) {
|
||||
m_imp.m_bounds.push_back(m_bv.mk_ule(result, m_bv.mk_numeral(nc-1, bv_size)));
|
||||
}
|
||||
constrain_domain(result, s, bv_sort);
|
||||
expr_ref f_def(m);
|
||||
ptr_vector<func_decl> const& cs = *m_dt.get_datatype_constructors(s);
|
||||
f_def = m.mk_const(cs[nc-1]);
|
||||
for (unsigned i = nc - 1; i > 0; ) {
|
||||
--i;
|
||||
f_def = m.mk_ite(m.mk_eq(result, m_bv.mk_numeral(i,bv_size)), m.mk_const(cs[i]), f_def);
|
||||
for (unsigned i = nc - 1; i-- > 0; ) {
|
||||
f_def = m.mk_ite(m.mk_eq(result, value2bv(i, s)), m.mk_const(cs[i]), f_def);
|
||||
}
|
||||
m_imp.m_enum2def.insert(f, f_def);
|
||||
m_imp.m_enum2bv.insert(f, f_fresh);
|
||||
|
@ -169,11 +201,10 @@ struct enum2bv_rewriter::imp {
|
|||
sort* s = q->get_decl_sort(i);
|
||||
if (m_imp.is_fd(s)) {
|
||||
unsigned bv_size = get_bv_size(s);
|
||||
m_sorts.push_back(m_bv.mk_sort(bv_size));
|
||||
unsigned nc = m_dt.get_datatype_num_constructors(s);
|
||||
if (!is_power_of_two(nc) || nc == 1) {
|
||||
bounds.push_back(m_bv.mk_ule(m.mk_var(q->get_num_decls()-i-1, m_sorts[i]), m_bv.mk_numeral(nc-1, bv_size)));
|
||||
}
|
||||
sort* bv_sort = m_bv.mk_sort(bv_size);
|
||||
m_sorts.push_back(bv_sort);
|
||||
expr_ref var(m.mk_var(q->get_num_decls()-i-1, bv_sort), m);
|
||||
constrain_domain(var, s, bv_sort);
|
||||
found = true;
|
||||
}
|
||||
else {
|
||||
|
@ -209,6 +240,8 @@ struct enum2bv_rewriter::imp {
|
|||
|
||||
unsigned get_bv_size(sort* s) {
|
||||
unsigned nc = m_dt.get_datatype_num_constructors(s);
|
||||
if (is_unate(s))
|
||||
return nc - 1;
|
||||
unsigned bv_size = 1;
|
||||
while ((unsigned)(1 << bv_size) < nc) {
|
||||
++bv_size;
|
||||
|
|
|
@ -874,7 +874,7 @@ void seq_util::str::get_concat_units(expr* e, expr_ref_vector& es) const {
|
|||
}
|
||||
|
||||
app* seq_util::str::mk_is_empty(expr* s) const {
|
||||
return m.mk_eq(s, mk_empty(get_sort(s)));
|
||||
return m.mk_eq(s, mk_empty(s->get_sort()));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -229,11 +229,11 @@ public:
|
|||
bool is_seq(sort* s) const { return is_sort_of(s, m_fid, SEQ_SORT); }
|
||||
bool is_re(sort* s) const { return is_sort_of(s, m_fid, RE_SORT); }
|
||||
bool is_re(sort* s, sort*& seq) const { return is_sort_of(s, m_fid, RE_SORT) && (seq = to_sort(s->get_parameter(0).get_ast()), true); }
|
||||
bool is_seq(expr* e) const { return is_seq(m.get_sort(e)); }
|
||||
bool is_seq(expr* e) const { return is_seq(e->get_sort()); }
|
||||
bool is_seq(sort* s, sort*& seq) const { return is_seq(s) && (seq = to_sort(s->get_parameter(0).get_ast()), true); }
|
||||
bool is_re(expr* e) const { return is_re(m.get_sort(e)); }
|
||||
bool is_re(expr* e, sort*& seq) const { return is_re(m.get_sort(e), seq); }
|
||||
bool is_char(expr* e) const { return is_char(m.get_sort(e)); }
|
||||
bool is_re(expr* e) const { return is_re(e->get_sort()); }
|
||||
bool is_re(expr* e, sort*& seq) const { return is_re(e->get_sort(), seq); }
|
||||
bool is_char(expr* e) const { return is_char(e->get_sort()); }
|
||||
bool is_const_char(expr* e, unsigned& c) const;
|
||||
bool is_const_char(expr* e) const { unsigned c; return is_const_char(e, c); }
|
||||
bool is_char_le(expr const* e) const;
|
||||
|
@ -344,12 +344,11 @@ public:
|
|||
bool is_to_code(expr const* n) const { return is_app_of(n, m_fid, OP_STRING_FROM_CODE); }
|
||||
|
||||
bool is_string_term(expr const * n) const {
|
||||
sort * s = get_sort(n);
|
||||
return u.is_string(s);
|
||||
return u.is_string(n->get_sort());
|
||||
}
|
||||
|
||||
bool is_non_string_sequence(expr const * n) const {
|
||||
sort * s = get_sort(n);
|
||||
sort * s = n->get_sort();
|
||||
return (u.is_seq(s) && !u.is_string(s));
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue