Kleene's algorithm

In theoretical computer science, in particular in formal language theory, Kleene's algorithm transforms a given nondeterministic finite automaton (NFA) into a regular expression. Together with other conversion algorithms, it establishes the equivalence of several description formats for regular languages. Alternative presentations of the same method include the "elimination method" attributed to Brzozowski and McCluskey, the algorithm of McNaughton and Yamada, and the use of Arden's lemma.

Algorithm description
According to Gross and Yellen (2004), the algorithm can be traced back to Kleene (1956). A presentation of the algorithm in the case of deterministic finite automata (DFAs) is given in Hopcroft and Ullman (1979). The presentation of the algorithm for NFAs below follows Gross and Yellen (2004).

Given a nondeterministic finite automaton M = (Q, Σ, δ, q0, F), with Q = { q0,...,qn } its set of states, the algorithm computes
 * the sets R$k ij$ of all strings that take M from state qi to qj without going through any state numbered higher than k.

Here, "going through a state" means entering and leaving it, so both i and j may be higher than k, but no intermediate state may. Each set R$k ij$ is represented by a regular expression; the algorithm computes them step by step for k = -1, 0, ..., n. Since there is no state numbered higher than n, the regular expression R$n 0j$ represents the set of all strings that take M from its start state q0 to qj. If F = { q1,...,qf } is the set of accept states, the regular expression R$n 01$ | ... | R$n 0f$ represents the language accepted by M.

The initial regular expressions, for k = -1, are computed as follows for i≠j:
 * R$−1 ij$ = a1 | ... | am      where qj ∈ δ(qi,a1), ..., qj ∈ δ(qi,am)

and as follows for i=j:
 * R$−1 ii$ = a1 | ... | am | ε      where qi ∈ δ(qi,a1), ..., qi ∈ δ(qi,am)

In other words, R$−1 ij$ mentions all letters that label a transition from i to j, and we also include ε in the case where i=j.

After that, in each step the expressions R$k ij$ are computed from the previous ones by
 * R$k ij$ = R$k-1 ik$ (R$k-1 kk$)* R$k-1 kj$ | R$k-1 ij$

Another way to understand the operation of the algorithm is as an "elimination method", where the states from 0 to n are successively removed: when state k is removed, the regular expression R$k-1 ij$, which describes the words that label a path from state i>k to state j>k, is rewritten into R$k ij$ so as to take into account the possibility of going via the "eliminated" state k.

By induction on k, it can be shown that the length of each expression R$k ij$ is at most $1⁄3$(4k+1(6s+7) - 4) symbols, where s denotes the number of characters in Σ. Therefore, the length of the regular expression representing the language accepted by M is at most $1⁄3$(4n+1(6s+7)f - f - 3) symbols, where f denotes the number of final states. This exponential blowup is inevitable, because there exist families of DFAs for which any equivalent regular expression must be of exponential size.

In practice, the size of the regular expression obtained by running the algorithm can be very different depending on the order in which the states are considered by the procedure, i.e., the order in which they are numbered from 0 to n.

Example


The automaton shown in the picture can be described as M = (Q, Σ, δ, q0, F) with
 * the set of states Q = { q0, q1, q2 },
 * the input alphabet Σ = { a, b },
 * the transition function δ with δ(q0,a)=q0,  δ(q0,b)=q1,   δ(q1,a)=q2,   δ(q1,b)=q1,   δ(q2,a)=q1, and δ(q2,b)=q1,
 * the start state q0, and
 * set of accept states F = { q1 }.

Kleene's algorithm computes the initial regular expressions as


 * R$−1 00$
 * | = a | ε
 * R$−1 01$
 * | = b
 * R$−1 02$
 * R$−1 10$
 * R$−1 11$
 * | = b | ε
 * R$−1 12$
 * | = a
 * R$−1 20$
 * R$−1 21$
 * | = a | b
 * R$−1 22$
 * | = ε
 * }
 * R$k ij$
 * | = a
 * R$k-1 ij$
 * R$0 00$
 * | = a | b
 * R$−1 00$
 * | = ε
 * }
 * R$−1 00$
 * | = ε
 * }
 * }

After that, the R$−1 00$ are computed from the R$−1 00$ step by step for k = 0, 1, 2. Kleene algebra equalities are used to simplify the regular expressions as much as possible.


 * Step 0


 * R$0 01$
 * | = R$−1 00$ (R$−1 00$)* R$−1 01$ | R$−1 01$
 * | = (a | ε)
 * |  (a | ε)*
 * |  (a | ε)
 * |  | a | ε
 * | = a*
 * R$0 02$
 * | = R$−1 00$ (R$−1 00$)* R$−1 02$ | R$−1 02$
 * | = (a | ε)
 * |  (a | ε)*
 * |  b
 * |  | b
 * | = a* b
 * R$0 10$
 * | = R$−1 10$ (R$−1 00$)* R$−1 00$ | R$−1 10$
 * | = (a | ε)
 * |  (a | ε)*
 * R$0 11$
 * | = R$−1 10$ (R$−1 00$)* R$−1 01$ | R$−1 11$
 * |  (a | ε)*
 * |  (a | ε)
 * R$0 12$
 * | = R$−1 10$ (R$−1 00$)* R$−1 02$ | R$−1 12$
 * |  (a | ε)*
 * |  b
 * |  | b | ε
 * | = b | ε
 * R$0 20$
 * | = R$−1 20$ (R$−1 00$)* R$−1 00$ | R$−1 20$
 * |  (a | ε)*
 * |  | a
 * | = a
 * R$0 21$
 * | = R$−1 20$ (R$−1 00$)* R$−1 01$ | R$−1 21$
 * |  (a | ε)*
 * |  (a | ε)
 * R$0 22$
 * | = R$−1 20$ (R$−1 00$)* R$−1 02$ | R$−1 22$
 * |  (a | ε)*
 * |  b
 * |  | a | b
 * | = a | b
 * R$1 00$
 * | = R$0 01$ (R$0 11$)* R$0 10$ | R$0 00$
 * |  (a | ε)*
 * |  | ε
 * | = ε
 * }
 * R$1 01$
 * | = R$0 01$ (R$0 11$)* R$0 11$ | R$0 01$
 * |  (a | ε)*
 * |  (a | ε)
 * R$1 02$
 * | = R$0 01$ (R$0 11$)* R$0 12$ | R$0 02$
 * |  (a | ε)*
 * |  b
 * |  | a | b
 * | = a | b
 * R$1 10$
 * | = R$0 11$ (R$0 11$)* R$0 10$ | R$0 10$
 * |  (a | ε)*
 * |  | ε
 * | = ε
 * }
 * R$1 11$
 * | = R$0 11$ (R$0 11$)* R$0 11$ | R$0 11$
 * |  (a | ε)*
 * |  | ε
 * | = ε
 * }
 * | = ε
 * }


 * Step 1


 * R$1 12$
 * | = R$0 11$ (R$0 11$)* R$0 12$ | R$0 12$
 * | = a*b
 * |  (b | ε)*
 * |  | a*
 * | = a*
 * R$1 20$
 * | = R$0 21$ (R$0 11$)* R$0 10$ | R$0 20$
 * | = a*b
 * |  (b | ε)*
 * |  (b | ε)
 * |  | a* b
 * | = a* b* b
 * R$1 21$
 * | = R$0 21$ (R$0 11$)* R$0 11$ | R$0 21$
 * | = a*b
 * |  (b | ε)*
 * |  a
 * | = a* b* ba
 * R$1 22$
 * | = R$0 21$ (R$0 11$)* R$0 12$ | R$0 22$
 * | = (b | ε)
 * |  (b | ε)*
 * R$2 00$
 * | = R$1 02$ (R$1 22$)* R$1 20$ | R$1 00$
 * | = (b | ε)
 * |  (b | ε)*
 * |  (b | ε)
 * |  | b | ε
 * | = b*
 * R$2 01$
 * | = R$1 02$ (R$1 22$)* R$1 21$ | R$1 01$
 * | = (b | ε)
 * |  (b | ε)*
 * |  a
 * |  | a
 * | = b* a
 * R$2 02$
 * | = R$1 02$ (R$1 22$)* R$1 22$ | R$1 02$
 * | = (a | b)
 * |  (b | ε)*
 * R$2 10$
 * | = R$1 12$ (R$1 22$)* R$1 20$ | R$1 10$
 * | = (a | b)
 * |  (b | ε)*
 * |  (b | ε)
 * |  | a | b
 * | = (a | b) b*
 * R$2 11$
 * | = R$1 12$ (R$1 22$)* R$1 21$ | R$1 11$
 * | = (a | b)
 * |  (b | ε)*
 * |  a
 * |  | ε
 * | = (a | b) b* a | ε
 * }
 * R$2 12$
 * | = R$1 12$ (R$1 22$)* R$1 22$ | R$1 12$
 * | = (a | b)
 * |  (b | ε)*
 * |  (b | ε)
 * |  | a | b
 * | = (a | b) b*
 * R$2 20$
 * | = R$1 22$ (R$1 22$)* R$1 20$ | R$1 20$
 * | = (a | b)
 * |  (b | ε)*
 * |  a
 * |  | ε
 * | = (a | b) b* a | ε
 * }
 * | = (a | b) b* a | ε
 * }


 * Step 2


 * R$2 21$
 * | = R$1 22$ (R$1 22$)* R$1 21$ | R$1 21$
 * | = a*b*ba
 * |  ((a|b)b*a | ε)*
 * |  | a*
 * | = a*
 * R$2 22$
 * | = R$1 22$ (R$1 22$)* R$1 22$ | R$1 22$
 * | = a*b*ba
 * |  ((a|b)b*a | ε)*
 * |  (a|b)b*
 * |  | a* b* b
 * | = a* b (a (a | b) | b)*
 * R$2 01$
 * | = R⇭⇭⇭ (R⇭⇭⇭)* R⇭⇭⇭ | R⇭⇭⇭
 * | = a*b*ba
 * |  ((a|b)b*a | ε)*
 * |  ((a|b)b*a | ε)
 * |  | a* b* ba
 * | = a* b* b (a (a | b) b*)* a
 * R⇭⇭⇭
 * | = R⇭⇭⇭ (R⇭⇭⇭)* R⇭⇭⇭ | R⇭⇭⇭
 * | = b* a
 * |  ((a|b)b*a | ε)*
 * R⇭⇭⇭
 * | = R⇭⇭⇭ (R⇭⇭⇭)* R⇭⇭⇭ | R⇭⇭⇭
 * | = b* a
 * |  ((a|b)b*a | ε)*
 * |  (a|b)b*
 * |  | b*
 * | = (a (a | b) | b)*
 * R⇭⇭⇭
 * | = R⇭⇭⇭ (R⇭⇭⇭)* R⇭⇭⇭ | R⇭⇭⇭
 * | = b* a
 * |  ((a|b)b*a | ε)*
 * |  ((a|b)b*a | ε)
 * |  | b* a
 * | = (a (a | b) | b)* a
 * R⇭⇭⇭
 * | = R⇭⇭⇭ (R⇭⇭⇭)* R⇭⇭⇭ | R⇭⇭⇭
 * | = ((a|b)b*a | ε)
 * |  ((a|b)b*a | ε)*
 * R⇭⇭⇭
 * | = R⇭⇭⇭ (R⇭⇭⇭)* R⇭⇭⇭ | R⇭⇭⇭
 * | = ((a|b)b*a | ε)
 * |  ((a|b)b*a | ε)*
 * |  (a|b)b*
 * |  | (a | b) b*
 * | = (a | b) (a (a | b) | b)*
 * R⇭⇭⇭
 * | = R⇭⇭⇭ (R⇭⇭⇭)* R⇭⇭⇭ | R⇭⇭⇭
 * | = ((a|b)b*a | ε)
 * |  ((a|b)b*a | ε)*
 * |  ((a|b)b*a | ε)
 * |  | (a | b) b* a | ε
 * | = ((a | b) b* a)*
 * }
 * R⇭⇭⇭
 * | = R⇭⇭⇭ (R⇭⇭⇭)* R⇭⇭⇭ | R⇭⇭⇭
 * | = ((a|b)b*a | ε)
 * |  ((a|b)b*a | ε)*
 * |  (a|b)b*
 * |  | (a | b) b*
 * | = (a | b) (a (a | b) | b)*
 * R⇭⇭⇭
 * | = R⇭⇭⇭ (R⇭⇭⇭)* R⇭⇭⇭ | R⇭⇭⇭
 * | = ((a|b)b*a | ε)
 * |  ((a|b)b*a | ε)*
 * |  ((a|b)b*a | ε)
 * |  | (a | b) b* a | ε
 * | = ((a | b) b* a)*
 * }
 * }

Since q0 is the start state and q1 is the only accept state, the regular expression R⇭⇭⇭ denotes the set of all strings accepted by the automaton.