mirror of
https://github.com/Z3Prover/z3
synced 2025-04-24 01:25:31 +00:00
Merge branch 'master' of https://github.com/Z3Prover/z3
This commit is contained in:
commit
2c40da23a2
33 changed files with 424 additions and 401 deletions
|
@ -102,7 +102,7 @@ namespace smt {
|
|||
theory_array_full& th;
|
||||
arith_util m_arith;
|
||||
array_util m_autil;
|
||||
array_rewriter m_rw;
|
||||
th_rewriter m_rw;
|
||||
arith_value m_arith_value;
|
||||
ast_ref_vector m_pinned;
|
||||
obj_map<app, sz_info*> m_sizeof;
|
||||
|
@ -204,26 +204,29 @@ namespace smt {
|
|||
return l_true;
|
||||
}
|
||||
|
||||
lbool ensure_disjoint(app* sz1, app* sz2) {
|
||||
bool ensure_disjoint(app* sz1, app* sz2) {
|
||||
sz_info& i1 = *m_sizeof[sz1];
|
||||
sz_info& i2 = *m_sizeof[sz2];
|
||||
SASSERT(i1.m_is_leaf);
|
||||
SASSERT(i2.m_is_leaf);
|
||||
expr* s = sz1->get_arg(0);
|
||||
expr* t = sz2->get_arg(0);
|
||||
if (m.get_sort(s) != m.get_sort(t)) {
|
||||
return true;
|
||||
}
|
||||
enode* r1 = get_root(s);
|
||||
enode* r2 = get_root(t);
|
||||
if (r1 == r2) {
|
||||
return l_true;
|
||||
return true;
|
||||
}
|
||||
if (!ctx().is_diseq(r1, r2) && ctx().assume_eq(r1, r2)) {
|
||||
return l_false;
|
||||
return false;
|
||||
}
|
||||
if (do_intersect(i1.m_selects, i2.m_selects)) {
|
||||
add_disjoint(sz1, sz2);
|
||||
return l_false;
|
||||
return false;
|
||||
}
|
||||
return l_true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool do_intersect(obj_map<enode, expr*> const& s, obj_map<enode, expr*> const& t) const {
|
||||
|
@ -265,11 +268,15 @@ namespace smt {
|
|||
}
|
||||
|
||||
expr_ref mk_subtract(expr* t, expr* s) {
|
||||
return m_rw.mk_set_difference(t, s);
|
||||
expr_ref d(m_autil.mk_setminus(t, s), m);
|
||||
m_rw(d);
|
||||
return d;
|
||||
}
|
||||
|
||||
expr_ref mk_intersect(expr* t, expr* s) {
|
||||
return m_rw.mk_set_intersect(t, s);
|
||||
expr_ref i(m_autil.mk_intersection(t, s), m);
|
||||
m_rw(i);
|
||||
return i;
|
||||
}
|
||||
|
||||
void propagate(expr* assumption, expr* conseq) {
|
||||
|
@ -436,6 +443,15 @@ namespace smt {
|
|||
reset();
|
||||
}
|
||||
|
||||
void internalize_term(app* term) {
|
||||
if (th.is_set_has_size(term)) {
|
||||
internalize_size(term);
|
||||
}
|
||||
else if (th.is_set_card(term)) {
|
||||
internalize_card(term);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Size(S, n) => n >= 0, default(S) = false
|
||||
*/
|
||||
|
@ -458,6 +474,17 @@ namespace smt {
|
|||
ctx().push_trail(remove_sz(m_sizeof, term));
|
||||
}
|
||||
|
||||
/**
|
||||
\brief whenever there is a cardinality function, it includes an axiom
|
||||
that entails the set is finite.
|
||||
*/
|
||||
void internalize_card(app* term) {
|
||||
SASSERT(ctx().e_internalized(term));
|
||||
app_ref has_size(m_autil.mk_has_size(term->get_arg(0), term), m);
|
||||
literal lit = mk_literal(has_size);
|
||||
ctx().assign(lit, nullptr);
|
||||
}
|
||||
|
||||
final_check_status final_check() {
|
||||
lbool r = ensure_functional();
|
||||
if (r == l_true) update_indices();
|
||||
|
@ -494,7 +521,7 @@ namespace smt {
|
|||
|
||||
theory_array_bapa::~theory_array_bapa() { dealloc(m_imp); }
|
||||
|
||||
void theory_array_bapa::internalize_size(app* term) { m_imp->internalize_size(term); }
|
||||
void theory_array_bapa::internalize_term(app* term) { m_imp->internalize_term(term); }
|
||||
|
||||
final_check_status theory_array_bapa::final_check() { return m_imp->final_check(); }
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ namespace smt {
|
|||
public:
|
||||
theory_array_bapa(theory_array_full& th);
|
||||
~theory_array_bapa();
|
||||
void internalize_size(app* term);
|
||||
void internalize_term(app* term);
|
||||
final_check_status final_check();
|
||||
void init_model();
|
||||
};
|
||||
|
|
|
@ -43,6 +43,7 @@ namespace smt {
|
|||
bool is_array_sort(sort const* s) const { return s->is_sort_of(get_id(), ARRAY_SORT); }
|
||||
bool is_array_sort(app const* n) const { return is_array_sort(get_manager().get_sort(n)); }
|
||||
bool is_set_has_size(app const* n) const { return n->is_app_of(get_id(), OP_SET_HAS_SIZE); }
|
||||
bool is_set_card(app const* n) const { return n->is_app_of(get_id(), OP_SET_CARD); }
|
||||
|
||||
bool is_store(enode const * n) const { return is_store(n->get_owner()); }
|
||||
bool is_map(enode const* n) const { return is_map(n->get_owner()); }
|
||||
|
@ -52,6 +53,7 @@ namespace smt {
|
|||
bool is_default(enode const* n) const { return is_default(n->get_owner()); }
|
||||
bool is_array_sort(enode const* n) const { return is_array_sort(n->get_owner()); }
|
||||
bool is_set_has_size(enode const* n) const { return is_set_has_size(n->get_owner()); }
|
||||
bool is_set_carde(enode const* n) const { return is_set_card(n->get_owner()); }
|
||||
|
||||
|
||||
app * mk_select(unsigned num_args, expr * const * args);
|
||||
|
|
|
@ -250,7 +250,7 @@ namespace smt {
|
|||
return theory_array::internalize_term(n);
|
||||
}
|
||||
|
||||
if (!is_const(n) && !is_default(n) && !is_map(n) && !is_as_array(n) && !is_set_has_size(n)) {
|
||||
if (!is_const(n) && !is_default(n) && !is_map(n) && !is_as_array(n) && !is_set_has_size(n) && !is_set_card(n)) {
|
||||
if (!is_array_ext(n))
|
||||
found_unsupported_op(n);
|
||||
return false;
|
||||
|
@ -274,11 +274,11 @@ namespace smt {
|
|||
mk_var(arg0);
|
||||
}
|
||||
}
|
||||
else if (is_set_has_size(n)) {
|
||||
else if (is_set_has_size(n) || is_set_card(n)) {
|
||||
if (!m_bapa) {
|
||||
m_bapa = alloc(theory_array_bapa, *this);
|
||||
}
|
||||
m_bapa->internalize_size(n);
|
||||
m_bapa->internalize_term(n);
|
||||
}
|
||||
|
||||
enode* node = ctx.get_enode(n);
|
||||
|
|
|
@ -3576,7 +3576,7 @@ expr_ref theory_seq::digit2int(expr* ch) {
|
|||
// n >= 0 & len(e) >= i + 1 => is_digit(e_i) for i = 0..k-1
|
||||
// n >= 0 & len(e) = k => n = sum 10^i*digit(e_i)
|
||||
// n < 0 & len(e) = k => \/_i ~is_digit(e_i) for i = 0..k-1
|
||||
// 10^k <= n < 10^{k+1}-1 => len(e) = k
|
||||
// 10^k <= n < 10^{k+1}-1 => len(e) => k
|
||||
|
||||
void theory_seq::add_si_axiom(expr* e, expr* n, unsigned k) {
|
||||
context& ctx = get_context();
|
||||
|
@ -3618,15 +3618,9 @@ void theory_seq::add_si_axiom(expr* e, expr* n, unsigned k) {
|
|||
rational ub = power(rational(10), k) - 1;
|
||||
arith_util& a = m_autil;
|
||||
literal lbl = mk_literal(a.mk_ge(n, a.mk_int(lb)));
|
||||
literal ubl = mk_literal(a.mk_le(n, a.mk_int(ub)));
|
||||
literal ge_k = mk_literal(a.mk_ge(len, a.mk_int(k)));
|
||||
literal le_k = mk_literal(a.mk_le(len, a.mk_int(k)));
|
||||
// n >= lb => len(s) >= k
|
||||
// n >= 0 & len(s) >= k => n >= lb
|
||||
// 0 <= n <= ub => len(s) <= k
|
||||
add_axiom(~lbl, ge_k);
|
||||
add_axiom(~ge0, lbl, ~ge_k);
|
||||
add_axiom(~ge0, ~ubl, le_k);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -117,6 +117,7 @@ namespace smt {
|
|||
}
|
||||
if (u.is_seq(s, ch)) {
|
||||
expr* v = m_model.get_fresh_value(ch);
|
||||
if (!v) return nullptr;
|
||||
return u.str.mk_unit(v);
|
||||
}
|
||||
UNREACHABLE();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue