3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-14 21:08:46 +00:00
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2015-12-28 18:15:48 -08:00
parent 739043e273
commit e2fab0a555
4 changed files with 170 additions and 124 deletions

View file

@ -296,6 +296,10 @@ public:
// src0 - t -> src - e -> dst => src0 - t -> dst
// out_degree(dst) = 1, final(dst) => final(src), dst != dst1
// src - e -> dst - t -> dst1 => src - t -> dst1
// Generalized:
// Src - E -> dst - t -> dst1 => Src - t -> dst1 if dst is final => each Src is final
//
void compress() {
for (unsigned i = 0; i < m_delta.size(); ++i) {
for (unsigned j = 0; j < m_delta[i].size(); ++j) {
@ -329,7 +333,24 @@ public:
}
add(move(m, src, dst1, t));
remove(dst, dst1, t);
}
else if (false && 1 == out_degree(dst) && all_epsilon_in(dst) && init() != dst && !is_final_state(dst)) {
move const& mv = m_delta[dst][0];
T* t = mv.t();
unsigned dst1 = mv.dst();
unsigned_vector src0s;
moves const& mvs = m_delta_inv[dst];
for (unsigned k = 0; k < mvs.size(); ++k) {
SASSERT(mvs[k].is_epsilon());
src0s.push_back(mvs[k].src());
}
for (unsigned k = 0; k < src0s.size(); ++k) {
remove(src0s[k], dst, 0);
add(move(m, src0s[i], dst1, t));
}
remove(dst, dst1, t);
--j;
continue;
}
else {
continue;
@ -392,9 +413,10 @@ public:
return true;
}
bool is_deterministic() const {
for (unsigned i = 0; i < m_delta.size(); ++i) {
if (m_delta[i].size() >= 2) return false;
bool all_epsilon_in(unsigned s) {
moves const& mvs = m_delta_inv[s];
for (unsigned j = 0; j < mvs.size(); ++j) {
if (mvs[j].t()) return false;
}
return true;
}

View file

@ -59,6 +59,10 @@ void theory_seq::solution_map::add_trail(map_update op, expr* l, expr* r, enode_
m_deps.push_back(d);
}
bool theory_seq::solution_map::is_root(expr* e) const {
return !m_map.contains(e);
}
expr* theory_seq::solution_map::find(expr* e, enode_pair_dependency*& d) {
std::pair<expr*, enode_pair_dependency*> value;
d = 0;
@ -181,31 +185,31 @@ final_check_status theory_seq::final_check_eh() {
context & ctx = get_context();
TRACE("seq", display(tout););
if (!check_ineqs()) {
TRACE("seq", tout << "check_ineqs\n";);
TRACE("seq", tout << ">>check_ineqs\n";);
return FC_CONTINUE;
}
if (simplify_and_solve_eqs()) {
TRACE("seq", tout << "solve_eqs\n";);
TRACE("seq", tout << ">>solve_eqs\n";);
return FC_CONTINUE;
}
if (solve_nqs()) {
TRACE("seq", tout << "solve_nqs\n";);
TRACE("seq", tout << ">>solve_nqs\n";);
return FC_CONTINUE;
}
if (branch_variable()) {
TRACE("seq", tout << "branch_variable\n";);
TRACE("seq", tout << ">>branch_variable\n";);
return FC_CONTINUE;
}
if (!check_length_coherence()) {
TRACE("seq", tout << "check_length_coherence\n";);
TRACE("seq", tout << ">>check_length_coherence\n";);
return FC_CONTINUE;
}
if (propagate_automata()) {
TRACE("seq", tout << "propagate_automata\n";);
TRACE("seq", tout << ">>propagate_automata\n";);
return FC_CONTINUE;
}
if (is_solved()) {
TRACE("seq", tout << "is_solved\n";);
TRACE("seq", tout << ">>is_solved\n";);
return FC_DONE;
}
@ -307,6 +311,39 @@ bool theory_seq::assume_equality(expr* l, expr* r) {
}
}
bool theory_seq::propagate_length_coherence(expr* e) {
expr_ref head(m), tail(m), emp(m);
rational lo, hi;
TRACE("seq", tout << "Unsolved " << mk_pp(e, m);
if (!lower_bound(e, lo)) lo = -rational::one();
if (!upper_bound(e, hi)) hi = -rational::one();
tout << " lo: " << lo << " hi: " << hi << "\n";
);
if (!lower_bound(e, lo) || !lo.is_pos() || lo >= rational(2048)) {
return false;
}
literal low(mk_literal(m_autil.mk_ge(m_util.str.mk_length(e), m_autil.mk_numeral(lo, true))));
expr_ref seq(e, m);
expr_ref_vector elems(m);
unsigned _lo = lo.get_unsigned();
for (unsigned j = 0; j < _lo; ++j) {
mk_decompose(seq, emp, head, tail);
elems.push_back(head);
seq = tail;
}
elems.push_back(seq);
tail = m_util.str.mk_concat(elems.size(), elems.c_ptr());
// len(e) >= low => e = tail
add_axiom(~low, mk_eq(e, tail, false));
assume_equality(tail, e);
if (upper_bound(e, hi)) {
expr_ref high1(m_autil.mk_le(m_util.str.mk_length(e), m_autil.mk_numeral(hi, true)), m);
expr_ref high2(m_autil.mk_le(m_util.str.mk_length(seq), m_autil.mk_numeral(hi-lo, true)), m);
add_axiom(~mk_literal(high1), mk_literal(high2));
}
return true;
}
bool theory_seq::check_length_coherence() {
if (m_length.empty()) return true;
@ -315,42 +352,13 @@ bool theory_seq::check_length_coherence() {
obj_hashtable<expr>::iterator it = m_length.begin(), end = m_length.end();
for (; it != end; ++it) {
expr* e = *it;
enode_pair_dependency* dep = 0;
expr* f = m_rep.find(e, dep);
if (is_var(f) && f == e) {
if (is_var(e) && m_rep.is_root(e)) {
expr_ref emp(m_util.str.mk_empty(m.get_sort(e)), m);
expr_ref head(m), tail(m);
rational lo, hi;
TRACE("seq", tout << "Unsolved " << mk_pp(e, m);
if (!lower_bound(e, lo)) lo = -rational::one();
if (!upper_bound(e, hi)) hi = -rational::one();
tout << " lo: " << lo << " ";
tout << "hi: " << hi << " ";
tout << "\n";
ctx.display(tout);
);
if (lower_bound(e, lo) && lo.is_pos() && lo < rational(512)) {
literal low(mk_literal(m_autil.mk_ge(m_util.str.mk_length(e), m_autil.mk_numeral(lo, true))));
expr_ref seq(e, m);
expr_ref_vector elems(m);
unsigned _lo = lo.get_unsigned();
for (unsigned j = 0; j < _lo; ++j) {
mk_decompose(seq, emp, head, tail);
elems.push_back(head);
seq = tail;
}
elems.push_back(seq);
tail = m_util.str.mk_concat(elems.size(), elems.c_ptr());
// len(e) >= low => e = tail
add_axiom(~low, mk_eq(e, tail, false));
assume_equality(tail, e);
if (upper_bound(e, hi)) {
expr_ref high1(m_autil.mk_le(m_util.str.mk_length(e), m_autil.mk_numeral(hi, true)), m);
expr_ref high2(m_autil.mk_le(m_util.str.mk_length(seq), m_autil.mk_numeral(hi-lo, true)), m);
add_axiom(~mk_literal(high1), mk_literal(high2));
}
if (propagate_length_coherence(e)) {
//m_replay_length_coherence.push_back(e);
//m_replay_length_coherence_qhead = m_replay_length_coherence.size();
}
else if (!assume_equality(e, emp)) {
mk_decompose(e, emp, head, tail);
@ -365,14 +373,18 @@ bool theory_seq::check_length_coherence() {
return coherent;
}
expr_ref theory_seq::mk_nth(expr* s, expr* idx) {
sort* char_sort = 0;
VERIFY(m_util.is_seq(m.get_sort(s), char_sort));
return mk_skolem(m_nth, s, idx, 0, char_sort);
}
void theory_seq::mk_decompose(expr* e, expr_ref& emp, expr_ref& head, expr_ref& tail) {
expr* e1, *e2;
sort* char_sort = 0;
zstring s;
VERIFY(m_util.is_seq(m.get_sort(e), char_sort));
emp = m_util.str.mk_empty(m.get_sort(e));
if (m_util.str.is_empty(e)) {
head = m_util.str.mk_unit(mk_skolem(m_nth, e, m_autil.mk_int(0), 0, char_sort));
head = m_util.str.mk_unit(mk_nth(e, m_autil.mk_int(0)));
tail = e;
}
else if (m_util.str.is_string(e, s)) {
@ -393,11 +405,11 @@ void theory_seq::mk_decompose(expr* e, expr_ref& emp, expr_ref& head, expr_ref&
expr* s = a->get_arg(0);
VERIFY (m_autil.is_numeral(a->get_arg(1), r));
expr* idx = m_autil.mk_int(r.get_unsigned() + 1);
head = m_util.str.mk_unit(mk_skolem(m_nth, s, idx, 0, char_sort));
head = m_util.str.mk_unit(mk_nth(s, idx));
tail = mk_skolem(m_tail, s, idx);
}
else {
head = m_util.str.mk_unit(mk_skolem(m_nth, e, m_autil.mk_int(0), 0, char_sort));
head = m_util.str.mk_unit(mk_nth(e, m_autil.mk_int(0)));
tail = mk_skolem(m_tail, e, m_autil.mk_int(0));
}
}
@ -750,7 +762,6 @@ bool theory_seq::internalize_term(app* term) {
bool_var bv = ctx.mk_bool_var(term);
ctx.set_var_theory(bv, get_id());
ctx.mark_as_relevant(bv);
TRACE("seq", tout << mk_pp(term, m) << ": " << bv << "\n";);
}
else {
enode* e = 0;
@ -1064,8 +1075,13 @@ void theory_seq::propagate() {
void theory_seq::enque_axiom(expr* e) {
TRACE("seq", tout << "add axioms for: " << mk_pp(e, m) << "\n";);
m_trail_stack.push(push_back_vector<theory_seq, expr_ref_vector>(m_axioms));
m_axioms.push_back(e);
if (!m_axiom_set.contains(e)) {
m_axioms.push_back(e);
m_axiom_set.insert(e);
m_trail_stack.push(push_back_vector<theory_seq, expr_ref_vector>(m_axioms));
m_trail_stack.push(insert_obj_trail<theory_seq, expr>(m_axiom_set, e));;
}
}
void theory_seq::deque_axiom(expr* n) {
@ -1284,17 +1300,19 @@ void theory_seq::propagate_in_re(expr* n, bool is_true) {
eautomaton* a = get_automaton(e2);
if (!a) return;
if (m_util.str.is_empty(e1)) return;
// if (m_util.str.is_empty(e1)) return;
context& ctx = get_context();
expr_ref emp(m_util.str.mk_empty(m.get_sort(e1)), m);
expr_ref len(m_util.str.mk_length(e1), m);
for (unsigned i = 0; i < a->num_states(); ++i) {
literal acc = mk_accept(emp, e2, i);
literal rej = mk_reject(emp, e2, i);
literal acc = mk_accept(e1, len, e2, i);
literal rej = mk_reject(e1, len, e2, i);
add_axiom(a->is_final_state(i)?acc:~acc);
add_axiom(a->is_final_state(i)?~rej:rej);
}
expr_ref zero(m_autil.mk_int(0), m);
unsigned_vector states;
a->get_epsilon_closure(a->init(), states);
literal_vector lits;
@ -1304,11 +1322,11 @@ void theory_seq::propagate_in_re(expr* n, bool is_true) {
}
for (unsigned i = 0; i < states.size(); ++i) {
if (is_true) {
lits.push_back(mk_accept(e1, e2, states[i]));
lits.push_back(mk_accept(e1, zero, e2, states[i]));
}
else {
literal nlit = ~lit;
propagate_lit(0, 1, &nlit, mk_reject(e1, e2, states[i]));
propagate_lit(0, 1, &nlit, mk_reject(e1, zero, e2, states[i]));
}
}
if (is_true) {
@ -1316,7 +1334,7 @@ void theory_seq::propagate_in_re(expr* n, bool is_true) {
propagate_lit(0, 1, &lit, lits[1]);
}
else {
TRACE("seq", ctx.display_literals_verbose(tout, lits.size(), lits.c_ptr()););
TRACE("seq", ctx.display_literals_verbose(tout, lits.size(), lits.c_ptr()); tout << "\n";);
ctx.mk_th_axiom(get_id(), lits.size(), lits.c_ptr());
}
}
@ -1474,18 +1492,14 @@ void theory_seq::add_at_axiom(expr* e) {
}
/**
step(s, tail, re, i, j, t) -> s = t ++ tail
step(s, idx, re, i, j, t) -> nth(s, idx) == t
*/
void theory_seq::propagate_step(bool_var v, expr* step) {
context& ctx = get_context();
expr* re, *t, *s, *tail, *i, *j;
VERIFY(is_step(step, s, tail, re, i, j, t));
expr_ref conc(m_util.str.mk_concat(m_util.str.mk_unit(t), tail), m);
expr_ref sr(s, m);
propagate_eq(v, s, conc);
enode* n1 = ensure_enode(step);
enode* n2 = ctx.get_enode(m.mk_true());
m_eqs.push_back(eq(sr, conc, m_dm.mk_leaf(enode_pair(n1, n2))));
expr* re, *t, *s, *idx, *i, *j;
VERIFY(is_step(step, s, idx, re, i, j, t));
expr_ref nth = mk_nth(s, idx);
propagate_eq(v, t, nth);
}
@ -1698,19 +1712,24 @@ eautomaton* theory_seq::get_automaton(expr* re) {
return result;
}
literal theory_seq::mk_accept(expr* s, expr* re, expr* state) {
return mk_literal(mk_skolem(m_accept, s, re, state, m.mk_bool_sort()));
literal theory_seq::mk_accept(expr* s, expr* idx, expr* re, expr* state) {
expr_ref_vector args(m);
args.push_back(s).push_back(idx).push_back(re).push_back(state);
return mk_literal(m_util.mk_skolem(m_accept, args.size(), args.c_ptr(), m.mk_bool_sort()));
}
literal theory_seq::mk_reject(expr* s, expr* re, expr* state) {
return mk_literal(mk_skolem(m_reject, s, re, state, m.mk_bool_sort()));
literal theory_seq::mk_reject(expr* s, expr* idx, expr* re, expr* state) {
expr_ref_vector args(m);
args.push_back(s).push_back(idx).push_back(re).push_back(state);
return mk_literal(m_util.mk_skolem(m_reject, args.size(), args.c_ptr(), m.mk_bool_sort()));
}
bool theory_seq::is_acc_rej(symbol const& ar, expr* e, expr*& s, expr*& re, unsigned& i, eautomaton*& aut) {
bool theory_seq::is_acc_rej(symbol const& ar, expr* e, expr*& s, expr*& idx, expr*& re, unsigned& i, eautomaton*& aut) {
if (is_skolem(ar, e)) {
rational r;
s = to_app(e)->get_arg(0);
re = to_app(e)->get_arg(1);
VERIFY(m_autil.is_numeral(to_app(e)->get_arg(2), r));
idx = to_app(e)->get_arg(1);
re = to_app(e)->get_arg(2);
VERIFY(m_autil.is_numeral(to_app(e)->get_arg(3), r));
SASSERT(r.is_unsigned());
i = r.get_unsigned();
aut = m_re2aut[re];
@ -1725,10 +1744,10 @@ bool theory_seq::is_step(expr* e) const {
return is_skolem(m_aut_step, e);
}
bool theory_seq::is_step(expr* e, expr*& s, expr*& tail, expr*& re, expr*& i, expr*& j, expr*& t) const {
bool theory_seq::is_step(expr* e, expr*& s, expr*& idx, expr*& re, expr*& i, expr*& j, expr*& t) const {
if (is_step(e)) {
s = to_app(e)->get_arg(0);
tail = to_app(e)->get_arg(1);
idx = to_app(e)->get_arg(1);
re = to_app(e)->get_arg(2);
i = to_app(e)->get_arg(3);
j = to_app(e)->get_arg(4);
@ -1740,11 +1759,9 @@ bool theory_seq::is_step(expr* e, expr*& s, expr*& tail, expr*& re, expr*& i, ex
}
}
expr_ref theory_seq::mk_step(expr* s, expr* tail, expr* re, unsigned i, unsigned j, expr* t) {
expr_ref theory_seq::mk_step(expr* s, expr* idx, expr* re, unsigned i, unsigned j, expr* t) {
expr_ref_vector args(m);
args.push_back(s);
args.push_back(tail);
args.push_back(re);
args.push_back(s).push_back(idx).push_back(re);
args.push_back(m_autil.mk_int(i));
args.push_back(m_autil.mk_int(j));
args.push_back(t);
@ -1753,33 +1770,32 @@ expr_ref theory_seq::mk_step(expr* s, expr* tail, expr* re, unsigned i, unsigned
/**
acc & s != emp -> \/ step_i_t_j
acc(s, idx, re, i) -> \/ step(s, idx, re, i, j, t) if i is non-final
acc(s, idx, re, i) -> len(s) <= idx \/ step(s, idx, re, i, j, t) if i is final
acc(s, idx, re, i) -> len(s) >= idx
*/
void theory_seq::add_accept2step(expr* acc) {
context& ctx = get_context();
SASSERT(ctx.get_assignment(acc) == l_true);
expr* e, *re;
expr *e, * idx, *re;
expr_ref step(m);
unsigned src;
eautomaton* aut = 0;
VERIFY(is_accept(acc, e, re, src, aut));
if (!aut) return;
if (m_util.str.is_empty(e)) return;
VERIFY(is_accept(acc, e, idx, re, src, aut));
if (!aut || m_util.str.is_length(idx)) return;
SASSERT(m_autil.is_numeral(idx));
eautomaton::moves mvs;
aut->get_moves_from(src, mvs);
expr_ref head(m), tail(m), emp(m), step(m);
mk_decompose(e, emp, head, tail);
if (!m_util.is_skolem(e)) {
expr_ref conc(m_util.str.mk_concat(head, tail), m);
add_axiom(mk_eq(e, emp, false), mk_eq(e, conc, false));
}
expr_ref len(m_util.str.mk_length(e), m);
literal_vector lits;
lits.push_back(~ctx.get_literal(acc));
if (aut->is_final_state(src)) {
lits.push_back(mk_eq(emp, e, false));
lits.push_back(mk_literal(m_autil.mk_le(len, idx)));
}
for (unsigned i = 0; i < mvs.size(); ++i) {
eautomaton::move mv = mvs[i];
step = mk_step(e, tail, re, src, mv.dst(), mv.t());
step = mk_step(e, idx, re, src, mv.dst(), mv.t());
lits.push_back(mk_literal(step));
}
TRACE("seq", ctx.display_literals_verbose(tout, lits.size(), lits.c_ptr()); tout << "\n";);
@ -1787,50 +1803,53 @@ void theory_seq::add_accept2step(expr* acc) {
ctx.mark_as_relevant(lits[i]);
}
ctx.mk_th_axiom(get_id(), lits.size(), lits.c_ptr());
add_axiom(~ctx.get_literal(acc), mk_literal(m_autil.mk_ge(len, idx)));
}
/**
acc(s, re, i) & step(head, tail, re, i, j, t) => acc(tail, re, j)
acc(s, idx, re, i) & step(s, idx, re, i, j, t) => acc(s, idx + 1, re, j)
*/
void theory_seq::add_step2accept(expr* step) {
context& ctx = get_context();
SASSERT(ctx.get_assignment(step) == l_true);
expr* re, *t, *s, *tail, *i, *j;
VERIFY(is_step(step, s, tail, re, i, j, t));
literal acc1 = mk_accept(s, re, i);
literal acc2 = mk_accept(tail, re, j);
rational r;
expr* re, *t, *s, *idx, *i, *j;
VERIFY(is_step(step, s, idx, re, i, j, t));
VERIFY(m_autil.is_numeral(idx, r) && r.is_unsigned());
expr_ref idx1(m_autil.mk_int(r.get_unsigned() + 1), m);
literal acc1 = mk_accept(s, idx, re, i);
literal acc2 = mk_accept(s, idx1, re, j);
add_axiom(~acc1, ~ctx.get_literal(step), acc2);
}
/*
rej(s, re, i) & s = t ++ tail => rej(tail, re, j)
rej(s, idx, re, i) & nth(s,idx) = t & idx < len(s) => rej(s, idx + 1 re, j)
rej(s, idx, re, i) => idx <= len(s)
*/
void theory_seq::add_reject2reject(expr* rej) {
context& ctx = get_context();
SASSERT(ctx.get_assignment(rej) == l_true);
expr* e, *re;
expr* e, *idx, *re;
unsigned src;
rational r;
eautomaton* aut = 0;
VERIFY(is_reject(rej, e, re, src, aut));
if (!aut) return;
if (m_util.str.is_empty(e)) return;
VERIFY(is_reject(rej, e, idx, re, src, aut));
if (!aut || m_util.str.is_length(idx)) return;
VERIFY(m_autil.is_numeral(idx, r) && r.is_unsigned());
expr_ref idx1(m_autil.mk_int(r.get_unsigned() + 1), m);
eautomaton::moves mvs;
aut->get_moves_from(src, mvs);
expr_ref head(m), tail(m), emp(m), conc(m);
mk_decompose(e, emp, head, tail);
if (!m_util.is_skolem(e)) {
expr_ref conc(m_util.str.mk_concat(head, tail), m);
add_axiom(mk_eq(e, emp, false), mk_eq(e, conc, false));
}
literal rej1 = ctx.get_literal(rej);
expr_ref len(m_util.str.mk_length(e), m);
add_axiom(~rej1, mk_literal(m_autil.mk_ge(len, idx)));
for (unsigned i = 0; i < mvs.size(); ++i) {
eautomaton::move const& mv = mvs[i];
conc = m_util.str.mk_concat(m_util.str.mk_unit(mv.t()), tail);
literal rej2 = mk_reject(tail, re, m_autil.mk_int(mv.dst()));
add_axiom(~rej1, ~mk_eq(e, conc, false), rej2);
expr_ref nth = mk_nth(e, idx);
literal rej2 = mk_reject(e, idx1, re, m_autil.mk_int(mv.dst()));
add_axiom(~rej1, ~mk_eq(nth, mv.t(), false), ~mk_literal(m_autil.mk_ge(len, idx)), rej2);
}
}

View file

@ -72,6 +72,7 @@ namespace smt {
void add_cache(expr* v, expr_dep& r) { m_cache.insert(v, r); }
bool find_cache(expr* v, expr_dep& r) { return m_cache.find(v, r); }
expr* find(expr* e, enode_pair_dependency*& d);
bool is_root(expr* e) const;
void cache(expr* e, expr* r, enode_pair_dependency* d);
void reset_cache() { m_cache.reset(); }
void push_scope() { m_limit.push_back(m_updates.size()); }
@ -256,6 +257,7 @@ namespace smt {
expr_ref_vector m_ineqs; // inequalities to check solution against
exclusion_table m_exclude; // set of asserted disequalities.
expr_ref_vector m_axioms; // list of axioms to add.
obj_hashtable<expr> m_axiom_set;
unsigned m_axioms_head; // index of first axiom to add.
unsigned m_branch_variable_head; // index of first equation to examine.
bool m_incomplete; // is the solver (clearly) incomplete for the fragment.
@ -305,7 +307,8 @@ namespace smt {
bool branch_variable(); // branch on a variable
bool split_variable(); // split a variable
bool is_solved();
bool check_length_coherence();
bool check_length_coherence();
bool propagate_length_coherence(expr* e);
bool check_ineq_coherence();
bool pre_process_eqs(bool simplify_or_solve, bool& propagated);
@ -368,6 +371,7 @@ namespace smt {
void mk_decompose(expr* e, expr_ref& emp, expr_ref& head, expr_ref& tail);
expr_ref mk_skolem(symbol const& s, expr* e1, expr* e2 = 0, expr* e3 = 0, sort* range = 0);
expr_ref mk_nth(expr* s, expr* idx);
bool is_skolem(symbol const& s, expr* e) const;
void set_incomplete(app* term);
@ -375,19 +379,19 @@ namespace smt {
// automata utilities
void propagate_in_re(expr* n, bool is_true);
eautomaton* get_automaton(expr* e);
literal mk_accept(expr* s, expr* re, expr* state);
literal mk_accept(expr* s, expr* re, unsigned i) { return mk_accept(s, re, m_autil.mk_int(i)); }
literal mk_accept(expr* s, expr* idx, expr* re, expr* state);
literal mk_accept(expr* s, expr* idx, expr* re, unsigned i) { return mk_accept(s, idx, re, m_autil.mk_int(i)); }
bool is_accept(expr* acc) const { return is_skolem(m_accept, acc); }
bool is_accept(expr* acc, expr*& s, expr*& re, unsigned& i, eautomaton*& aut) {
return is_acc_rej(m_accept, acc, s, re, i, aut);
bool is_accept(expr* acc, expr*& s, expr*& idx, expr*& re, unsigned& i, eautomaton*& aut) {
return is_acc_rej(m_accept, acc, s, idx, re, i, aut);
}
literal mk_reject(expr* s, expr* re, expr* state);
literal mk_reject(expr* s, expr* re, unsigned i) { return mk_reject(s, re, m_autil.mk_int(i)); }
literal mk_reject(expr* s, expr* idx, expr* re, expr* state);
literal mk_reject(expr* s, expr* idx, expr* re, unsigned i) { return mk_reject(s, idx, re, m_autil.mk_int(i)); }
bool is_reject(expr* rej) const { return is_skolem(m_reject, rej); }
bool is_reject(expr* rej, expr*& s, expr*& re, unsigned& i, eautomaton*& aut) {
return is_acc_rej(m_reject, rej, s, re, i, aut);
bool is_reject(expr* rej, expr*& s, expr*& idx, expr*& re, unsigned& i, eautomaton*& aut) {
return is_acc_rej(m_reject, rej, s, idx, re, i, aut);
}
bool is_acc_rej(symbol const& ar, expr* e, expr*& s, expr*& re, unsigned& i, eautomaton*& aut);
bool is_acc_rej(symbol const& ar, expr* e, expr*& s, expr*& idx, expr*& re, unsigned& i, eautomaton*& aut);
expr_ref mk_step(expr* s, expr* tail, expr* re, unsigned i, unsigned j, expr* t);
bool is_step(expr* e, expr*& s, expr*& tail, expr*& re, expr*& i, expr*& j, expr*& t) const;
bool is_step(expr* e) const;

View file

@ -89,9 +89,10 @@ public:
m_nodes.shrink(sz);
}
void push_back(T * n) {
ref_vector_core& push_back(T * n) {
inc_ref(n);
m_nodes.push_back(n);
return *this;
}
void pop_back() {