3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-12 12:08:18 +00:00

bild on gcc #376

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2015-12-13 23:47:45 -08:00
parent 72883df134
commit f3d94db889
5 changed files with 77 additions and 37 deletions

View file

@ -597,7 +597,7 @@ bool seq_rewriter::reduce_eq(expr* l, expr* r, expr_ref_vector& lhs, expr_ref_ve
if (head1 == m_lhs.size() || head2 == m_rhs.size()) { if (head1 == m_lhs.size() || head2 == m_rhs.size()) {
break; break;
} }
SASSERT(head1 < m_lhs.size() && head2 == m_rhs.size()); SASSERT(head1 < m_lhs.size() && head2 < m_rhs.size());
expr* l = m_lhs[head1]; expr* l = m_lhs[head1];
expr* r = m_rhs[head2]; expr* r = m_rhs[head2];

View file

@ -192,6 +192,7 @@ public:
bool is_re(sort* s) const { return is_sort_of(s, m_fid, RE_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_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(m.get_sort(e)); }
bool is_seq(sort* s, sort*& seq) { 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) 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_re(expr* e, sort*& seq) const { return is_re(m.get_sort(e), seq); }
@ -225,6 +226,7 @@ public:
app* mk_prefix(expr* a, expr* b) { expr* es[2] = { a, b }; return m.mk_app(m_fid, OP_SEQ_PREFIX, 2, es); } app* mk_prefix(expr* a, expr* b) { expr* es[2] = { a, b }; return m.mk_app(m_fid, OP_SEQ_PREFIX, 2, es); }
app* mk_suffix(expr* a, expr* b) { expr* es[2] = { a, b }; return m.mk_app(m_fid, OP_SEQ_SUFFIX, 2, es); } app* mk_suffix(expr* a, expr* b) { expr* es[2] = { a, b }; return m.mk_app(m_fid, OP_SEQ_SUFFIX, 2, es); }
app* mk_index(expr* a, expr* b, expr* i) { expr* es[3] = { a, b, i}; return m.mk_app(m_fid, OP_SEQ_INDEX, 3, es); } app* mk_index(expr* a, expr* b, expr* i) { expr* es[3] = { a, b, i}; return m.mk_app(m_fid, OP_SEQ_INDEX, 3, es); }
app* mk_unit(expr* u) { return m.mk_app(m_fid, OP_SEQ_UNIT, 1, &u); }
bool is_string(expr const * n) const { return is_app_of(n, m_fid, OP_STRING_CONST); } bool is_string(expr const * n) const { return is_app_of(n, m_fid, OP_STRING_CONST); }

View file

@ -161,18 +161,26 @@ final_check_status theory_seq::final_check_eh() {
return FC_CONTINUE; return FC_CONTINUE;
} }
if (branch_variable()) { if (branch_variable()) {
TRACE("seq", tout << "branch\n";);
return FC_CONTINUE; return FC_CONTINUE;
} }
if (split_variable()) { if (split_variable()) {
TRACE("seq", tout << "split_variable\n";);
return FC_CONTINUE; return FC_CONTINUE;
} }
if (ctx.inconsistent()) { if (ctx.inconsistent()) {
return FC_CONTINUE; return FC_CONTINUE;
} }
if (!check_length_coherence()) { if (!check_length_coherence()) {
TRACE("seq", tout << "check_length_coherence\n";);
return FC_CONTINUE; return FC_CONTINUE;
} }
if (!check_length_coherence_tbd()) {
TRACE("seq", tout << "check_length_coherence\n";);
return FC_GIVEUP;
}
if (is_solved()) { if (is_solved()) {
TRACE("seq", tout << "is_solved\n";);
return FC_DONE; return FC_DONE;
} }
@ -192,7 +200,7 @@ bool theory_seq::check_ineqs() {
return false; return false;
} }
else if (!m.is_false(b)) { else if (!m.is_false(b)) {
TRACE("seq", tout << "equality is undetermined: " << mk_pp(a, m) << " " << b << "\n";); TRACE("seq", tout << "Disequality is undetermined: " << mk_pp(a, m) << " " << b << "\n";);
} }
} }
return true; return true;
@ -200,7 +208,6 @@ bool theory_seq::check_ineqs() {
bool theory_seq::branch_variable() { bool theory_seq::branch_variable() {
context& ctx = get_context(); context& ctx = get_context();
TRACE("seq", ctx.display(tout););
unsigned sz = m_eqs.size(); unsigned sz = m_eqs.size();
ptr_vector<expr> ls, rs; ptr_vector<expr> ls, rs;
for (unsigned i = 0; i < sz; ++i) { for (unsigned i = 0; i < sz; ++i) {
@ -266,11 +273,11 @@ bool theory_seq::assume_equality(expr* l, expr* r) {
} }
else { else {
TRACE("seq", tout << mk_pp(l, m) << " = " << mk_pp(r, m) << "\n";); TRACE("seq", tout << mk_pp(l, m) << " = " << mk_pp(r, m) << "\n";);
if (!ctx.e_internalized(l)) ctx.internalize(l, false); enode* n1 = ensure_enode(l);
if (!ctx.e_internalized(r)) ctx.internalize(r, false); enode* n2 = ensure_enode(r);
ctx.mark_as_relevant(ctx.get_enode(l)); ctx.mark_as_relevant(n1);
ctx.mark_as_relevant(ctx.get_enode(r)); ctx.mark_as_relevant(n2);
ctx.assume_eq(ctx.get_enode(l), ctx.get_enode(r)); ctx.assume_eq(n1, n2);
return true; return true;
} }
} }
@ -282,7 +289,6 @@ bool theory_seq::split_variable() {
bool theory_seq::check_length_coherence() { bool theory_seq::check_length_coherence() {
if (!m_has_length) return true; if (!m_has_length) return true;
return false;
context& ctx = get_context(); context& ctx = get_context();
bool coherent = true; bool coherent = true;
for (unsigned i = 0; i < m_eqs.size(); ++i) { for (unsigned i = 0; i < m_eqs.size(); ++i) {
@ -290,38 +296,54 @@ bool theory_seq::check_length_coherence() {
expr_ref v1(m), v2(m), l(m_eqs[i].m_lhs), r(m_eqs[i].m_rhs); expr_ref v1(m), v2(m), l(m_eqs[i].m_lhs), r(m_eqs[i].m_rhs);
expr_ref len1(m_util.str.mk_length(l), m); expr_ref len1(m_util.str.mk_length(l), m);
expr_ref len2(m_util.str.mk_length(r), m); expr_ref len2(m_util.str.mk_length(r), m);
if (!ctx.e_internalized(len1)) ctx.internalize(len1, false); enode* n1 = ensure_enode(len1);
if (!ctx.e_internalized(len2)) ctx.internalize(len2, false); enode* n2 = ensure_enode(len2);
enode* n1 = get_enode(len1);
enode* n2 = get_enode(len2);
if (n1->get_root() != n2->get_root()) { if (n1->get_root() != n2->get_root()) {
TRACE("seq", tout << len1 << " = " << len2 << "\n";);
propagate_eq(m_eqs[i].m_dep, n1, n2); propagate_eq(m_eqs[i].m_dep, n1, n2);
coherent = false; coherent = false;
} }
} }
return coherent;
}
bool theory_seq::check_length_coherence_tbd() {
if (!m_has_length) return true;
context& ctx = get_context();
bool coherent = true;
// each variable that canonizes to itself can have length 0. // each variable that canonizes to itself can have length 0.
unsigned sz = get_num_vars(); unsigned sz = get_num_vars();
for (unsigned i = 0; i < sz; ++i) { for (unsigned i = 0; i < sz; ++i) {
enode* n = get_enode(i); enode* n = get_enode(i);
expr* e = n->get_owner(); expr* e = n->get_owner();
if (!m_util.is_seq(e)) { if (m_util.is_re(e)) {
continue; continue;
} }
SASSERT(m_util.is_seq(e));
// extend length of variables. // extend length of variables.
enode_pair_dependency* dep = 0; enode_pair_dependency* dep = 0;
if (is_var(m_rep.find(e, dep))) { expr* f = m_rep.find(e, dep);
if (is_var(f) && f == e) {
expr_ref emp(m_util.str.mk_empty(m.get_sort(e)), m); expr_ref emp(m_util.str.mk_empty(m.get_sort(e)), m);
TRACE("seq", tout << "Unsolved " << mk_pp(e, m) << "\n";);
#if 0
if (!assume_equality(e, emp)) { if (!assume_equality(e, emp)) {
// e = emp \/ e = head*tail & head = unit(v) // e = emp \/ e = head*tail & head = unit(v)
// add_axiom(mk_eq(e, emp, false), mk_eq(e, m_util.mk_concat(x, y), e)); sort* char_sort = 0;
// add_axiom(mk_eq(e, emp, false), mk_eq(x, unit_x)); VERIFY(m_util.is_seq(m.get_sort(e), char_sort));
expr_ref tail(mk_skolem(symbol("seq.tail"), e), m);
expr_ref v(mk_skolem(symbol("seq.head.elem"), e, 0, 0, char_sort), m);
expr_ref head(m_util.str.mk_unit(v), m);
expr_ref conc(m_util.str.mk_concat(head, tail), m);
literal e_eq_emp(mk_eq(e, emp, false));
add_axiom(e_eq_emp, mk_eq(e, conc, false));
} }
#endif
coherent = false; coherent = false;
} }
} }
return coherent; return coherent;
} }
bool theory_seq::check_ineq_coherence() { bool theory_seq::check_ineq_coherence() {
bool all_false = true; bool all_false = true;
@ -418,7 +440,14 @@ bool theory_seq::simplify_eq(expr* l, expr* r, enode_pair_dependency* deps) {
} }
SASSERT(lhs.size() == rhs.size()); SASSERT(lhs.size() == rhs.size());
for (unsigned i = 0; i < lhs.size(); ++i) { for (unsigned i = 0; i < lhs.size(); ++i) {
m_eqs.push_back(eq(expr_ref(lhs[i].get(), m), expr_ref(rhs[i].get(), m), deps)); expr_ref l(lhs[i].get(), m);
expr_ref r(rhs[i].get(), m);
if (m_util.is_seq(l) || m_util.is_re(l)) {
m_eqs.push_back(eq(l, r, deps));
}
else {
propagate_eq(deps, ensure_enode(l), ensure_enode(r));
}
} }
TRACE("seq", TRACE("seq",
tout << mk_pp(l, m) << " = " << mk_pp(r, m) << " => "; tout << mk_pp(l, m) << " = " << mk_pp(r, m) << " => ";
@ -552,10 +581,7 @@ bool theory_seq::internalize_term(app* term) {
unsigned num_args = term->get_num_args(); unsigned num_args = term->get_num_args();
for (unsigned i = 0; i < num_args; i++) { for (unsigned i = 0; i < num_args; i++) {
expr* arg = term->get_arg(i); expr* arg = term->get_arg(i);
ctx.internalize(arg, false); mk_var(ensure_enode(arg));
if (ctx.e_internalized(arg)) {
mk_var(ctx.get_enode(arg));
}
} }
if (m.is_bool(term)) { if (m.is_bool(term)) {
bool_var bv = ctx.mk_bool_var(term); bool_var bv = ctx.mk_bool_var(term);
@ -738,7 +764,8 @@ expr_ref theory_seq::expand(expr* e, enode_pair_dependency*& eqs) {
else { else {
result = e; result = e;
} }
m_rep.add_cache(e, expr_dep(result, deps)); expr_dep edr(result, deps);
m_rep.add_cache(e, edr);
eqs = m_dm.mk_join(eqs, deps); eqs = m_dm.mk_join(eqs, deps);
return result; return result;
} }
@ -977,6 +1004,15 @@ expr* theory_seq::mk_sub(expr* a, expr* b) {
return m_autil.mk_add(a, m_autil.mk_mul(m_autil.mk_int(-1), b)); return m_autil.mk_add(a, m_autil.mk_mul(m_autil.mk_int(-1), b));
} }
enode* theory_seq::ensure_enode(expr* e) {
context& ctx = get_context();
if (!ctx.e_internalized(e)) {
ctx.internalize(e, false);
ctx.mark_as_relevant(ctx.get_enode(e));
}
return ctx.get_enode(e);
}
/* /*
TBD: check semantics of extract. TBD: check semantics of extract.
@ -1043,7 +1079,7 @@ void theory_seq::add_at_axiom(expr* e) {
literal theory_seq::mk_literal(expr* _e) { literal theory_seq::mk_literal(expr* _e) {
expr_ref e(_e, m); expr_ref e(_e, m);
context& ctx = get_context(); context& ctx = get_context();
ctx.internalize(e, false); ensure_enode(e);
return ctx.get_literal(e); return ctx.get_literal(e);
} }
@ -1059,10 +1095,14 @@ void theory_seq::add_axiom(literal l1, literal l2, literal l3, literal l4) {
} }
expr_ref theory_seq::mk_skolem(symbol const& name, expr* e1, expr* e2, expr* e3) { expr_ref theory_seq::mk_skolem(symbol const& name, expr* e1,
expr* e2, expr* e3, sort* range) {
expr* es[3] = { e1, e2, e3 }; expr* es[3] = { e1, e2, e3 };
unsigned len = e3?3:(e2?2:1); unsigned len = e3?3:(e2?2:1);
return expr_ref(m_util.mk_skolem(name, len, es, m.get_sort(e1)), m); if (!range) {
range = m.get_sort(e1);
}
return expr_ref(m_util.mk_skolem(name, len, es, range), m);
} }
void theory_seq::propagate_eq(bool_var v, expr* e1, expr* e2) { void theory_seq::propagate_eq(bool_var v, expr* e1, expr* e2) {
@ -1071,10 +1111,9 @@ void theory_seq::propagate_eq(bool_var v, expr* e1, expr* e2) {
tout << mk_pp(ctx.bool_var2enode(v)->get_owner(), m) << " => " tout << mk_pp(ctx.bool_var2enode(v)->get_owner(), m) << " => "
<< mk_pp(e1, m) << " = " << mk_pp(e2, m) << "\n";); << mk_pp(e1, m) << " = " << mk_pp(e2, m) << "\n";);
ctx.internalize(e1, false);
SASSERT(ctx.e_internalized(e2)); SASSERT(ctx.e_internalized(e2));
enode* n1 = ctx.get_enode(e1); enode* n1 = ensure_enode(e1);
enode* n2 = ctx.get_enode(e2); enode* n2 = ensure_enode(e2);
literal lit(v); literal lit(v);
justification* js = justification* js =
ctx.mk_justification( ctx.mk_justification(
@ -1110,10 +1149,6 @@ void theory_seq::assign_eq(bool_var v, bool is_true) {
else if (m_util.str.is_in_re(e, e1, e2)) { else if (m_util.str.is_in_re(e, e1, e2)) {
// TBD // TBD
} }
else if (m.is_eq(e, e1, e2)) {
new_eq_eh(ctx.get_enode(e1)->get_th_var(get_id()),
ctx.get_enode(e1)->get_th_var(get_id()));
}
else { else {
UNREACHABLE(); UNREACHABLE();
} }

View file

@ -165,6 +165,7 @@ namespace smt {
bool split_variable(); // split a variable bool split_variable(); // split a variable
bool is_solved(); bool is_solved();
bool check_length_coherence(); bool check_length_coherence();
bool check_length_coherence_tbd();
bool check_ineq_coherence(); bool check_ineq_coherence();
bool pre_process_eqs(bool simplify_or_solve); bool pre_process_eqs(bool simplify_or_solve);
@ -209,8 +210,9 @@ namespace smt {
literal mk_literal(expr* n); literal mk_literal(expr* n);
void tightest_prefix(expr* s, expr* x, literal lit, literal lit2 = null_literal); void tightest_prefix(expr* s, expr* x, literal lit, literal lit2 = null_literal);
expr* mk_sub(expr* a, expr* b); expr* mk_sub(expr* a, expr* b);
enode* ensure_enode(expr* a);
expr_ref mk_skolem(symbol const& s, expr* e1, expr* e2 = 0, expr* e3 = 0); expr_ref mk_skolem(symbol const& s, expr* e1, expr* e2 = 0, expr* e3 = 0, sort* range = 0);
void set_incomplete(app* term); void set_incomplete(app* term);

View file

@ -94,7 +94,8 @@ public:
void pop_back() { void pop_back() {
SASSERT(m_size > 0); SASSERT(m_size > 0);
if (m_size == m_elems.size() && m_size > m_elems_start) { if (m_index[m_size-1] == m_elems.size()-1 &&
m_elems.size() > m_elems_start) {
m_elems.pop_back(); m_elems.pop_back();
} }
--m_size; --m_size;