Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 15 additions & 6 deletions src/nfa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,22 +44,19 @@ pub enum StateOrdering {
impl Nfa {
/// checks if the nfa is complete:
/// every state has an outgoing transition for every letter in the alphabet
///
/// TODO: this uses equality on (sorted) vectors. Are HashSets better?
pub fn is_complete(&self) -> bool {
// get the alphabet
let mut letters = self.get_alphabet();
letters.sort();
// for each state, check if it has a transition for each letter in the alphabet
for state in 0..self.nb_states() {
let mut state_actions = self
let state_actions = self
.transitions
.iter()
.filter(|t| t.from == state)
.map(|t| t.label.clone())
.collect::<Vec<_>>();
state_actions.sort();
if state_actions != letters {
.collect::<std::collections::BTreeSet<_>>();
if !letters.iter().all(|l| state_actions.contains(*l)) {
return false;
}
}
Expand Down Expand Up @@ -563,6 +560,18 @@ mod test {
assert!(nfa.is_complete());
}
#[test]
fn is_complete3() {
let mut nfa = Nfa::from_size(2);
nfa.add_transition_by_index1(0, 1, 'a');
nfa.add_transition_by_index1(0, 1, 'b');
nfa.add_transition_by_index1(1, 0, 'a');
nfa.add_transition_by_index1(1, 0, 'b');

// in addition, we add a second a-edge from state 0.
nfa.add_transition_by_index1(0, 0, 'a');
assert!(nfa.is_complete());
}
#[test]
fn complete_to_selfloops() {
// this NFA is missing a 'b'-strep from state 1.
// after completion, there should be a step 1 -b-> 1.
Expand Down
Loading