31 Jan 11:30 AM
CSCI 5100
\[ M_1 = (Q_1, \Sigma, \delta_1, q_1, F_1) \land M_2 = (Q_2, \Sigma, \delta_2, q_2, F_2) \implies \]
\[ \exists M_3 : L(M_3) = L(M_1) \cdot L(M_2) = L(M_1)L(M_2) = A_1A_2 \]
0
appear in odd-length substrings \(\{0\}^{2n+1}\).0
appear in even-length substrings \(\{0\}^{2n}\).0
after a 1
Deterministic Finite Automata (DFA)
Nondeterministic Finite Automata (NFA)
Find a string accepted by the NFA that is rejected by the DFA.
Computational: Fork new parallel thread and accept if any thread leads to an accept state.
Mathematical: Tree with branches. Accept if any branch leads to an accept state.
Magical: Guess at each nondeterministic step which way to go. Machine always makes the right guess that leads to accepting, if possible.
# setup
state : str
letter : str
dfa : tuple
nfa : tuple
def q_next_dfa(m:dfa, q:state, a:letter) -> state:
d = m[2] # dict of state:dict of letter:state
return d[q][a]
def q_next_nfa(m:nfa, qs:set, a:letter) -> set:
d = m[2] # dict of state:dict of letter:set of state
return {q_n for q in d[q][a] for q in qs}
lambda
(which I’d prefer) but then we lose type hints.Or put the lambdas in the *FA
\[ \forall M_{NFA}: \exists M_{DFA} : L(M_{NFA})) = L(M_{DFA})) \]
Proof
\[ \begin{aligned} M_{NFA}(&Q, \Sigma, \delta, q_1, F_1) = \\ M_{DFA}(&\mathcal{P} (Q), \Sigma, \delta, \{q_1\}, \\ & \{ R \in \mathcal{P} (Q) | R \cap F \neq \varnothing \})\blacksquare \end{aligned} \]