NFA: support multiple transitions in transition function

This commit is contained in:
Yuri Tatishchev 2025-02-27 17:12:11 -08:00
parent 0831b6c5ec
commit bbfa3cad87
Signed by: CaZzzer
GPG Key ID: E0EBF441EA424369

View File

@ -20,34 +20,34 @@ pub type NFAError {
} }
pub type NFA { pub type NFA {
NFA(states: Set(State), alphabet: Set(AlphabetChar), transition_func: fn(State, AlphabetChar) -> Result(State, NFAError), init_state: State, accepting_states: Set(State)) NFA(states: Set(State), alphabet: Set(AlphabetChar), transition_func: fn(Set(State), AlphabetChar) -> Set(State), init_state: State, accepting_states: Set(State))
} }
//pub type DFAViolation { //pub type DFAViolation {
// NotAllTransitionsDefined // NotAllTransitionsDefined(state: State, missing_chars: Set(AlphabetChar))
// MultiplePossibleTransitions // MultiplePossibleTransitions(state: State, duplicate_chars: Set(AlphabetChar))
//} //}
pub fn check_string(automaton: NFA, input: String) -> Bool { pub fn check_string(nfa: NFA, input: String) -> Bool {
let result = input let final_states = input
|> string.to_graphemes |> string.to_graphemes
|> list.try_fold(automaton.init_state, automaton.transition_func) |> list.fold(set.from_list([nfa.init_state]), nfa.transition_func)
case result { !set.is_disjoint(nfa.accepting_states, final_states)
Ok(state) -> set.contains(automaton.accepting_states, state)
Error(_) -> False
}
} }
pub fn even_a() -> NFA { pub fn even_a() -> NFA {
let states = set.from_list([0, 1]) let states = set.from_list([0, 1])
let alphabet = set.from_list(["a"]) let alphabet = set.from_list(["a"])
let transition_func = fn (state: State, char: AlphabetChar) -> Result(State, NFAError) { let transition_func = fn (states, char) {
case state, char { states
0, "a" -> Ok(1) |> set.fold(set.new(), fn(n_states, state) {
1, "a" -> Ok(0) case state, char {
_, _ -> Error(NoTransition) 0, "a" -> set.insert(n_states, 1)
} 1, "a" -> set.insert(n_states, 0)
_, _ -> n_states
}
})
} }
let init_state = 0 let init_state = 0
let accepting_states = set.from_list([0]) let accepting_states = set.from_list([0])