Proofs: Thompson's construction
These are the human proofs of Thompson's construction, at full length.
Thompson's construction accepts exactly the language of the expression, with at most 2m states full
This proof shows: correctness.
Statement. Let be a regular expression of size and let be the output of THOMPSON on the postfix form of . Then , has at most states and moves, and each state has at most two outgoing moves.
Setup. Each token of the postfix form is a node of the syntax tree of , and the step that handles pushes one fragment . Let be the set of states created while the tokens of the subtree of were handled. The tokens of a subtree form a contiguous block of the postfix form that ends with , so is the disjoint union of the sets of the children of and the states created at itself. We say that a move exists at time when it was added at or before step ; moves are never removed. A path reads when the symbols on its moves, in order, spell .
Lemma 1. At the moment the fragment of is pushed: (a) every move that leaves a state of ends in ; (b) has no outgoing move; (c) has no incoming move.
Proof. By induction on the syntax tree. For a leaf, lines L4 to L6 create with at most the move , and no other move touches them. For a union, by the induction hypothesis the children satisfy (a) to (c) when they are pushed. Between the push of a child and the step of , the only steps are those of tokens of the other child, which create new states and add moves only out of new states and out of exits of fragments of that other subtree; these touch no state of the first child, whose sets are disjoint. At line L10 the moves added leave (to ) and leave (to ). So (a) holds, is new so (b) holds, and is new and gets no incoming move, so (c) holds. A star is the same, with the moves of line L15 all inside . For a concatenation, line L12 adds only , inside ; had no outgoing move and gets none; had no incoming move and gets none.
Lemma 2. After the fragment of is pushed, no state of gains an outgoing move.
Proof. A later step adds moves out of new states, which are not in , and out of the exits of fragments that it pops. Let be such a fragment with . The sets of a parse tree are nested or disjoint, and is pushed after , so , and lies in the subtree of . The exit is a state created at , unless is a concatenation, in which case is the exit of its right child. Following right children of concatenations down from , we reach a node whose exit was created at that node. The state lies in only if is on this chain, and then .
Lemma 3. At any time after the fragment of is pushed, let be a path that starts at , ends at , and visits only at its end. Then every state of is in and every move of existed when the fragment was pushed.
Proof. Every move of leaves a state other than . By induction along : the first state is in ; if the current state is in , then by Lemma 2 its outgoing moves all existed at the push, and by Lemma 1(a) they end in .
Call a path as in Lemma 3 a clean path of . Since moves are never removed, the clean paths of are the same at every time after the push.
Lemma 4. For every node and string , a clean path of reads if and only if .
Proof. By induction on the syntax tree.
- Leaves. The fragment of has only , so the only clean path reads . The fragment of has only , which reads . The fragment of has no move, and , so it has no clean path.
- Union . A clean path starts with or , say , since has no other move. From , as long as has not reached , Lemmas 2 and 1(a) for keep it in . It must reach , because the only move into comes from or , and . The only move out of is . So where is a clean path of . By the induction hypothesis reads a string of , so reads a string of . Conversely, a clean path of reading , with the moves and added, is a clean path of that reads ; the same holds for .
- Concatenation . A clean path from stays in until it reaches , by the argument of case 2, and it must reach , because . The first visit to ends a clean path of . The only move out of is , and the rest of the path is a path from to that visits only at its end, that is, a clean path of . It cannot return to , since by Lemma 1(c) has no incoming moves and the other states of are entered only from . So reads with and . Conversely, two such clean paths joined by form a clean path of .
- Star . A clean path either is the single move , which reads , or starts with . In the second case, cut the path at each visit to . Each piece from to the next visit of is a clean path of by the argument of case 2, and after each visit the path takes and starts a new piece, or takes and ends. So reads with and each , which is in . Conversely, is read by , and for and , the clean paths of for the , joined by and framed by and , form a clean path of .
Theorem. .
Proof. Line L16 returns the fragment of the root , with start and the one accepting state , which has no outgoing move by Lemma 1(b). A string is in if and only if some path from to reads . Such a path ends at its first visit to , because has no outgoing move, so it is a clean path of . By Lemma 4 this holds if and only if .
Size. Lines L4, L9 and L14 create two states for each leaf, union and star, and line L12 creates none, so . A leaf adds at most one move, a union four, a concatenation one and a star four, so there are at most moves. An entry created at line L9 or L14 gets exactly two moves at its creation; an entry created at line L4 gets at most one. An exit gets outgoing moves only when a fragment with that exit is popped. After the pop, the new fragment's exit is a new state (lines L10 and L15) or (line L12, when the popped exit was ), so the popped exit is never again the exit of a fragment on the stack. Hence each exit gets moves once, one or two of them, and every state has at most two outgoing moves.