3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-23 17:15:31 +00:00
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2015-12-24 12:01:59 -08:00
parent 1bbf7813b0
commit 65d147106e
4 changed files with 163 additions and 48 deletions

View file

@ -78,8 +78,6 @@ private:
unsigned m_init;
uint_set m_final_set;
unsigned_vector m_final_states;
bool m_is_epsilon_free;
bool m_is_deterministic;
// local data-structures
@ -91,9 +89,7 @@ public:
// The empty automaton:
automaton(M& m):
m(m),
m_init(0),
m_is_epsilon_free(true),
m_is_deterministic(true)
m_init(0)
{
m_delta.push_back(moves());
m_delta_inv.push_back(moves());
@ -102,8 +98,6 @@ public:
// create an automaton from initial state, final states, and moves
automaton(M& m, unsigned init, unsigned_vector const& final, moves const& mvs): m(m) {
m_is_epsilon_free = true;
m_is_deterministic = true;
m_init = init;
for (unsigned i = 0; i < final.size(); ++i) {
m_final_states.push_back(final[i]);
@ -118,17 +112,13 @@ public:
}
m_delta[mv.src()].push_back(mv);
m_delta_inv[mv.dst()].push_back(mv);
m_is_deterministic &= m_delta[mv.src()].size() < 2;
m_is_epsilon_free &= !mv.is_epsilon();
}
}
// create an automaton that accepts a sequence.
automaton(M& m, ptr_vector<T> const& seq):
m(m),
m_init(0),
m_is_epsilon_free(true),
m_is_deterministic(true) {
m_init(0) {
m_delta.resize(seq.size()+1, moves());
m_delta_inv.resize(seq.size()+1, moves());
for (unsigned i = 0; i < seq.size(); ++i) {
@ -157,9 +147,7 @@ public:
m_delta_inv(other.m_delta_inv),
m_init(other.m_init),
m_final_set(other.m_final_set),
m_final_states(other.m_final_states),
m_is_epsilon_free(other.m_is_epsilon_free),
m_is_deterministic(other.m_is_deterministic)
m_final_states(other.m_final_states)
{}
// create the automaton that accepts the empty string only.
@ -187,8 +175,8 @@ public:
unsigned_vector final;
unsigned offset1 = 1;
unsigned offset2 = a.num_states() + 1;
mvs.push_back(move(m, 0, a.init() + offset1, 0));
mvs.push_back(move(m, 0, b.init() + offset2, 0));
mvs.push_back(move(m, 0, a.init() + offset1));
mvs.push_back(move(m, 0, b.init() + offset2));
append_moves(offset1, a, mvs);
append_moves(offset2, b, mvs);
append_final(offset1, a, final);
@ -196,6 +184,23 @@ public:
return alloc(automaton, m, 0, final, mvs);
}
static automaton* mk_opt(automaton const& a) {
M& m = a.m;
moves mvs;
unsigned_vector final;
unsigned offset = 0;
unsigned init = a.init();
if (!a.initial_state_is_source()) {
offset = 1;
init = 0;
mvs.push_back(move(m, 0, a.init() + offset));
}
mvs.push_back(move(m, init, a.final_state() + offset));
append_moves(offset, a, mvs);
append_final(offset, a, final);
return alloc(automaton, m, init, final, mvs);
}
// concatenate accepting languages
static automaton* mk_concat(automaton const& a, automaton const& b) {
SASSERT(&a.m == &b.m);
@ -276,6 +281,7 @@ public:
// remove states that only have epsilon transitions.
void compress() {
// TBD
}
@ -309,8 +315,23 @@ public:
moves const& get_moves_to(unsigned state) const { return m_delta_inv[state]; }
bool initial_state_is_source() const { return m_delta_inv[m_init].empty(); }
bool is_final_state(unsigned s) const { return m_final_set.contains(s); }
bool is_epsilon_free() const { return m_is_epsilon_free; }
bool is_deterministic() const { return m_is_deterministic; }
bool is_epsilon_free() const {
for (unsigned i = 0; i < m_delta.size(); ++i) {
moves const& mvs = m_delta[i];
for (unsigned j = 0; j < mvs.size(); ++j) {
if (!mvs[j].t()) return false;
}
}
return true;
}
bool is_deterministic() const {
for (unsigned i = 0; i < m_delta.size(); ++i) {
if (m_delta[i].size() >= 2) return false;
}
return true;
}
bool is_empty() const { return m_final_states.empty(); }
unsigned final_state() const { return m_final_states[0]; }
bool has_single_final_sink() const { return m_final_states.size() == 1 && m_delta[final_state()].empty(); }