mirror of
https://github.com/Z3Prover/z3
synced 2025-04-24 01:25:31 +00:00
fixing 2267
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
16af728fbe
commit
28ce701e17
15 changed files with 174 additions and 48 deletions
|
@ -34,11 +34,7 @@ namespace smt {
|
|||
|
||||
void theory_array_base::found_unsupported_op(expr * n) {
|
||||
if (!get_context().get_fparams().m_array_fake_support && !m_found_unsupported_op) {
|
||||
//array_util autil(get_manager());
|
||||
//func_decl* f = 0;
|
||||
//if (autil.is_as_array(n, f) && f->is_skolem()) return;
|
||||
TRACE("array", tout << mk_ll_pp(n, get_manager()) << "\n";);
|
||||
|
||||
TRACE("array", tout << mk_ll_pp(n, get_manager()) << "\n";);
|
||||
get_context().push_trail(value_trail<context, bool>(m_found_unsupported_op));
|
||||
m_found_unsupported_op = true;
|
||||
}
|
||||
|
@ -266,10 +262,7 @@ namespace smt {
|
|||
|
||||
m_array_value.reset();
|
||||
// populate m_array_value if the select(a, i) parent terms of r1
|
||||
enode_vector::const_iterator it = r1->begin_parents();
|
||||
enode_vector::const_iterator end = r1->end_parents();
|
||||
for (; it != end; ++it) {
|
||||
enode* parent = *it;
|
||||
for (enode* parent : r1->get_const_parents()) {
|
||||
if (parent->is_cgr() &&
|
||||
ctx.is_relevant(parent) &&
|
||||
is_select(parent->get_owner()) &&
|
||||
|
@ -278,10 +271,7 @@ namespace smt {
|
|||
}
|
||||
}
|
||||
// traverse select(a, i) parent terms of r2 trying to find a match.
|
||||
it = r2->begin_parents();
|
||||
end = r2->end_parents();
|
||||
for (; it != end; ++it) {
|
||||
enode * parent = *it;
|
||||
for (enode * parent : r2->get_const_parents()) {
|
||||
enode * other;
|
||||
if (parent->is_cgr() &&
|
||||
ctx.is_relevant(parent) &&
|
||||
|
@ -712,10 +702,7 @@ namespace smt {
|
|||
for (theory_var v = 0; v < num_vars; ++v) {
|
||||
enode * r = get_enode(v)->get_root();
|
||||
if (is_representative(v) && get_context().is_relevant(r)) {
|
||||
enode_vector::iterator it = r->begin_parents();
|
||||
enode_vector::iterator end = r->end_parents();
|
||||
for (; it != end; ++it) {
|
||||
enode * parent = *it;
|
||||
for (enode * parent : r->get_const_parents()) {
|
||||
if (parent->get_cg() == parent &&
|
||||
get_context().is_relevant(parent) &&
|
||||
is_select(parent) &&
|
||||
|
@ -735,10 +722,7 @@ namespace smt {
|
|||
if (!get_context().is_relevant(r)) {
|
||||
return;
|
||||
}
|
||||
ptr_vector<enode>::const_iterator it = r->begin_parents();
|
||||
ptr_vector<enode>::const_iterator end = r->end_parents();
|
||||
for (; it != end; ++it) {
|
||||
enode * parent = *it;
|
||||
for (enode * parent : r->get_const_parents()) {
|
||||
if (get_context().is_relevant(parent) &&
|
||||
is_store(parent) &&
|
||||
parent->get_arg(0)->get_root() == r) {
|
||||
|
@ -770,10 +754,7 @@ namespace smt {
|
|||
|
||||
void theory_array_base::propagate_selects_to_store_parents(enode * r, enode_pair_vector & todo) {
|
||||
select_set * sel_set = get_select_set(r);
|
||||
select_set::iterator it2 = sel_set->begin();
|
||||
select_set::iterator end2 = sel_set->end();
|
||||
for (; it2 != end2; ++it2) {
|
||||
enode * sel = *it2;
|
||||
for (enode* sel : *sel_set) {
|
||||
SASSERT(is_select(sel));
|
||||
propagate_select_to_store_parents(r, sel, todo);
|
||||
}
|
||||
|
@ -781,10 +762,7 @@ namespace smt {
|
|||
|
||||
void theory_array_base::propagate_selects() {
|
||||
enode_pair_vector todo;
|
||||
enode_vector::const_iterator it = m_selects_domain.begin();
|
||||
enode_vector::const_iterator end = m_selects_domain.end();
|
||||
for (; it != end; ++it) {
|
||||
enode * r = *it;
|
||||
for (enode * r : m_selects_domain) {
|
||||
propagate_selects_to_store_parents(r, todo);
|
||||
}
|
||||
for (unsigned qhead = 0; qhead < todo.size(); qhead++) {
|
||||
|
@ -901,6 +879,10 @@ namespace smt {
|
|||
}
|
||||
};
|
||||
|
||||
bool theory_array_base::include_func_interp(func_decl* f) {
|
||||
return is_decl_of(f, get_id(), OP_ARRAY_EXT);
|
||||
}
|
||||
|
||||
model_value_proc * theory_array_base::mk_value(enode * n, model_generator & m) {
|
||||
SASSERT(get_context().is_relevant(n));
|
||||
theory_var v = n->get_th_var(get_id());
|
||||
|
@ -948,10 +930,7 @@ namespace smt {
|
|||
m_selects.find(n->get_root(), sel_set);
|
||||
if (sel_set != nullptr) {
|
||||
ptr_buffer<enode> args;
|
||||
select_set::iterator it = sel_set->begin();
|
||||
select_set::iterator end = sel_set->end();
|
||||
for (; it != end; ++it) {
|
||||
enode * select = *it;
|
||||
for (enode * select : *sel_set) {
|
||||
args.reset();
|
||||
unsigned num = select->get_num_args();
|
||||
for (unsigned j = 1; j < num; ++j)
|
||||
|
@ -963,10 +942,8 @@ namespace smt {
|
|||
TRACE("array",
|
||||
tout << mk_pp(n->get_root()->get_owner(), get_manager()) << "\n";
|
||||
if (sel_set) {
|
||||
select_set::iterator it = sel_set->begin();
|
||||
select_set::iterator end = sel_set->end();
|
||||
for (; it != end; ++it) {
|
||||
tout << "#" << (*it)->get_root()->get_owner()->get_id() << " " << mk_pp((*it)->get_owner(), get_manager()) << "\n";
|
||||
for (enode* s : *sel_set) {
|
||||
tout << "#" << s->get_root()->get_owner()->get_id() << " " << mk_pp(s->get_owner(), get_manager()) << "\n";
|
||||
}
|
||||
}
|
||||
if (else_val_n) {
|
||||
|
|
|
@ -194,7 +194,7 @@ namespace smt {
|
|||
select_set * get_select_set(enode * n);
|
||||
void finalize_model(model_generator & m) override;
|
||||
model_value_proc * mk_value(enode * n, model_generator & m) override;
|
||||
|
||||
bool include_func_interp(func_decl* f) override;
|
||||
public:
|
||||
theory_array_base(ast_manager & m);
|
||||
~theory_array_base() override { restore_sorts(0); }
|
||||
|
|
|
@ -13,7 +13,76 @@ Author:
|
|||
|
||||
Nikolaj Bjorner (nbjorner) 2015-6-12
|
||||
|
||||
Revision History:
|
||||
Outline:
|
||||
|
||||
A cascading sequence of solvers:
|
||||
|
||||
- simplify_and_solve_eqs
|
||||
- canonize equality
|
||||
- solve_unit_eq: x = t, where x not in t.
|
||||
- solve_binary_eq: xa = bx -> a = b, xa = bx
|
||||
- solve_nth_eq: x = unit(nth(x,0)).unit(nth(x,1)).unit(nth(x,2)...unit(nth(x,n-1))
|
||||
- solve_itos: itos(i) = "" -> i < 0
|
||||
|
||||
- check_contains
|
||||
- (f,dep) = canonize(contains(a, b))
|
||||
lit := |b| > |a|
|
||||
f := true -> conflict
|
||||
f := false -> solved
|
||||
value(lit) = l_true -> solved
|
||||
f := s = t -> dep -> s != t
|
||||
f := f1 & f2 -> dep -> ~f1 | ~f2
|
||||
f := f1 | f2 -> dep -> ~f1 & ~f2
|
||||
|
||||
- solve_nqs
|
||||
- s_i = t_i, d_i <- solve(s = t)
|
||||
- create literals for s_i = t_i
|
||||
- if one of created literals is false, done.
|
||||
- conflict if all created literals are true
|
||||
|
||||
- fixed_length
|
||||
- len(s) = k -> s = unit(nth(0,s)).unit(nth(1,s))....unit(nth(n-1,s))
|
||||
|
||||
- len_based_split
|
||||
s = x.xs t = y.ys, len(x) = len(y) -> x = y & xs = ys
|
||||
s = x.xs t = y.ys, len(x) = len(y) + offset -> y = x*Z, Z*xs = ys
|
||||
s = x.x'.xs, t = y.y'.ys, len(xs) = len(ys) -> xs = ys
|
||||
|
||||
- check_int_string
|
||||
e := itos(n), len(e) = v, v > 0 ->
|
||||
n := stoi(e), len(e) = v, v > 0 ->
|
||||
- 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
|
||||
|
||||
- reduce_length_eq
|
||||
x1...xn = y1...ym, len(x1...xk) = len(y1...yj) -> x1...xk = y1..yj, x{k+1}..xn = y{j+1}..ym
|
||||
|
||||
- branch_unit_variable
|
||||
len(x) = n -> x = unit(a1)unit(a2)...unit(a_n)
|
||||
|
||||
- branch_binary_variable
|
||||
x ++ units1 = units2 ++ y -> x is prefix of units2 or x = units2 ++ y1, y = y1 ++ y2, y2 = units2
|
||||
|
||||
- branch_variable
|
||||
- branch_variable_mb
|
||||
s = xs, t = ys, each x_i, y_j has a length.
|
||||
based on length comparisons decompose into smaller equalities.
|
||||
|
||||
- branch_variable_eq
|
||||
cycle through branch options
|
||||
|
||||
- branch_ternary_variable1
|
||||
|
||||
- branch_ternary_variable2
|
||||
|
||||
- check_length_coherence
|
||||
len(e) >= lo => e = unit(nth(0,e)).unit(nth(1,e))....unit(nth(lo-1,e)).seq
|
||||
len(e) <= lo => seq = empty
|
||||
len(e) <= hi => len(seq) <= hi - lo
|
||||
|
||||
- check_extensionality
|
||||
|
||||
|
||||
--*/
|
||||
|
@ -454,8 +523,6 @@ bool theory_seq::is_unit_eq(expr_ref_vector const& ls, expr_ref_vector const& rs
|
|||
if (ls.empty() || !is_var(ls[0])) {
|
||||
return false;
|
||||
}
|
||||
//std::function<bool(expr*)> is_unit = [&](expr* elem) { return m_util.str.is_unit(elem); }
|
||||
//return rs.forall(is_unit);
|
||||
|
||||
for (auto const& elem : rs) {
|
||||
if (!m_util.str.is_unit(elem)) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue