mirror of
https://github.com/Z3Prover/z3
synced 2026-07-06 07:16:13 +00:00
hoist functionality
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
5f5a0ffbd8
commit
9a29a0fc24
2 changed files with 34 additions and 27 deletions
|
|
@ -42,9 +42,7 @@ NSB review:
|
||||||
|
|
||||||
namespace seq {
|
namespace seq {
|
||||||
|
|
||||||
void deps_to_lits(dep_tracker const& deps,
|
void deps_to_lits(dep_tracker const &deps, svector<enode_pair> &eqs, svector<sat::literal> &lits) {
|
||||||
svector<enode_pair>& eqs,
|
|
||||||
svector<sat::literal>& lits) {
|
|
||||||
vector<dep_source, false> vs;
|
vector<dep_source, false> vs;
|
||||||
dep_manager::s_linearize(deps, vs);
|
dep_manager::s_linearize(deps, vs);
|
||||||
for (dep_source const &d : vs) {
|
for (dep_source const &d : vs) {
|
||||||
|
|
@ -69,24 +67,29 @@ namespace seq {
|
||||||
// fwd=true -> left-to-right (prefix/head)
|
// fwd=true -> left-to-right (prefix/head)
|
||||||
// fwd=false -> right-to-left (suffix/tail)
|
// fwd=false -> right-to-left (suffix/tail)
|
||||||
static euf::snode *dir_token(euf::snode *s, bool fwd) {
|
static euf::snode *dir_token(euf::snode *s, bool fwd) {
|
||||||
if (!s) return nullptr;
|
if (!s)
|
||||||
|
return nullptr;
|
||||||
return fwd ? s->first() : s->last();
|
return fwd ? s->first() : s->last();
|
||||||
}
|
}
|
||||||
|
|
||||||
static euf::snode *dir_drop(euf::sgraph &sg, euf::snode *s, unsigned count, bool fwd) {
|
static euf::snode *dir_drop(euf::sgraph &sg, euf::snode *s, unsigned count, bool fwd) {
|
||||||
if (!s || count == 0) return s;
|
if (!s || count == 0)
|
||||||
|
return s;
|
||||||
return fwd ? sg.drop_left(s, count) : sg.drop_right(s, count);
|
return fwd ? sg.drop_left(s, count) : sg.drop_right(s, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
static euf::snode *dir_concat(euf::sgraph &sg, euf::snode *a, euf::snode *b, bool fwd) {
|
static euf::snode *dir_concat(euf::sgraph &sg, euf::snode *a, euf::snode *b, bool fwd) {
|
||||||
if (!a) return b;
|
if (!a)
|
||||||
if (!b) return a;
|
return b;
|
||||||
|
if (!b)
|
||||||
|
return a;
|
||||||
return fwd ? sg.mk_concat(a, b) : sg.mk_concat(b, a);
|
return fwd ? sg.mk_concat(a, b) : sg.mk_concat(b, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void collect_tokens_dir(euf::snode *s, bool fwd, euf::snode_vector &toks) {
|
static void collect_tokens_dir(euf::snode *s, bool fwd, euf::snode_vector &toks) {
|
||||||
toks.reset();
|
toks.reset();
|
||||||
if (!s) return;
|
if (!s)
|
||||||
|
return;
|
||||||
s->collect_tokens(toks);
|
s->collect_tokens(toks);
|
||||||
if (!fwd)
|
if (!fwd)
|
||||||
toks.reverse();
|
toks.reverse();
|
||||||
|
|
@ -127,8 +130,7 @@ namespace seq {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool str_eq::is_trivial() const {
|
bool str_eq::is_trivial() const {
|
||||||
return m_lhs == m_rhs ||
|
return m_lhs == m_rhs || (m_lhs && m_rhs && m_lhs->is_empty() && m_rhs->is_empty());
|
||||||
(m_lhs && m_rhs && m_lhs->is_empty() && m_rhs->is_empty());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool str_eq::contains_var(euf::snode *var) const {
|
bool str_eq::contains_var(euf::snode *var) const {
|
||||||
|
|
@ -166,6 +168,10 @@ namespace seq {
|
||||||
return m_str && m_regex && m_str->is_empty() && m_regex->is_nullable();
|
return m_str && m_regex && m_str->is_empty() && m_regex->is_nullable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool str_mem::is_contradiction() const {
|
||||||
|
return (m_str && m_regex && m_str->is_empty() && !m_regex->is_nullable());
|
||||||
|
}
|
||||||
|
|
||||||
bool str_mem::contains_var(euf::snode* var) const {
|
bool str_mem::contains_var(euf::snode* var) const {
|
||||||
SASSERT(var);
|
SASSERT(var);
|
||||||
if (m_str) {
|
if (m_str) {
|
||||||
|
|
@ -1173,8 +1179,7 @@ namespace seq {
|
||||||
|
|
||||||
// check for regex memberships that are immediately infeasible
|
// check for regex memberships that are immediately infeasible
|
||||||
for (str_mem& mem : m_str_mem) {
|
for (str_mem& mem : m_str_mem) {
|
||||||
SASSERT(mem.m_str && mem.m_regex);
|
if (mem.is_contradiction()) {
|
||||||
if (mem.m_str->is_empty() && !mem.m_regex->is_nullable()) {
|
|
||||||
m_is_general_conflict = true;
|
m_is_general_conflict = true;
|
||||||
m_reason = backtrack_reason::regex;
|
m_reason = backtrack_reason::regex;
|
||||||
return simplify_result::conflict;
|
return simplify_result::conflict;
|
||||||
|
|
|
||||||
|
|
@ -407,6 +407,8 @@ namespace seq {
|
||||||
|
|
||||||
bool is_trivial() const;
|
bool is_trivial() const;
|
||||||
|
|
||||||
|
bool is_contradiction() const;
|
||||||
|
|
||||||
// check if the constraint contains a given variable
|
// check if the constraint contains a given variable
|
||||||
bool contains_var(euf::snode* var) const;
|
bool contains_var(euf::snode* var) const;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue