Algorithm Search⌘K

Proofs: GLL parsing

These are the human proofs of GLL parsing, at full length.

Correctness of the GLL recognizer full

This proof shows: correctness.

Setting. G=(V,Σ,P,S)G = (V, \Sigma, P, S) is any context-free grammar and w=a1⋯anw = a_1 \cdots a_n the input; w[j:i]=aj+1⋯aiw[j:i] = a_{j+1} \cdots a_i for j≤ij \le i. A GSS node other than the root u0u_0 is a pair v=(B→γX⋅δ,k)v = (B \to \gamma X \cdot \delta, k) with X∈VX \in V; we say that vv calls XX at kk. The root calls SS at 0. A configuration (A→α⋅β,u,i)(A \to \alpha \cdot \beta, u, i) is visited if it is a descriptor taken from RR at line L2, or is obtained from a visited configuration by one match of line L3. Every descriptor added to UU is also put in RR, and the loop runs until RR is empty, so every descriptor in UU is eventually taken, and every visited configuration is followed by lines L3 to L5 from it.

Soundness

Invariants. At every moment of the run:

  • (I1) If (A→α⋅β,u,i)(A \to \alpha \cdot \beta, u, i) is visited or in UU, then uu calls AA at some jj and α⇒∗w[j:i]\alpha \Rightarrow^* w[j:i].
  • (I2) If the edge v→uv \to u exists with v=(B→γX⋅δ,k)v = (B \to \gamma X \cdot \delta, k), then the configuration (B→γ⋅Xδ,u,k)(B \to \gamma \cdot X \delta, u, k) has been visited.
  • (I3) If (v,i)∈P(v, i) \in P and vv calls XX at kk, then X⇒∗w[k:i]X \Rightarrow^* w[k:i]; if ii was recorded at line L10, then S⇒∗w[0:i]S \Rightarrow^* w[0:i].

Proof. All three hold at the start, when everything is empty. We check every step that adds to one of the sets.

  • Line L1 adds (S→⋅γ,u0,0)(S \to \cdot \gamma, u_0, 0): u0u_0 calls SS at 0 and ε⇒∗w[0:0]\varepsilon \Rightarrow^* w[0:0].
  • Line L3 turns a visited (A→α⋅aβ,u,i)(A \to \alpha \cdot a \beta, u, i) with ai+1=aa_{i+1} = a into (A→αa⋅β,u,i+1)(A \to \alpha a \cdot \beta, u, i + 1); by I1, αa⇒∗w[j:i] ai+1=w[j:i+1]\alpha a \Rightarrow^* w[j:i]\, a_{i+1} = w[j:i+1].
  • Line L4 processes a visited (A→α⋅Bβ,u,i)(A \to \alpha \cdot B \beta, u, i), with uu calling AA at jj and α⇒∗w[j:i]\alpha \Rightarrow^* w[j:i]. CREATE makes v=(A→αB⋅β,i)v = (A \to \alpha B \cdot \beta, i), which calls BB at ii. A new edge v→uv \to u satisfies I2 because the configuration just processed is the one I2 asks for. A replay at line L8 adds (A→αB⋅β,u,k)(A \to \alpha B \cdot \beta, u, k) for (v,k)∈P(v, k) \in P; by I3, B⇒∗w[i:k]B \Rightarrow^* w[i:k], so αB⇒∗w[j:k]\alpha B \Rightarrow^* w[j:k], and uu calls AA at jj, which is I1. The descriptors (B→⋅γ,v,i)(B \to \cdot \gamma, v, i) satisfy I1 since vv calls BB at ii.
  • Line L5 processes a visited (A→α⋅,u,i)(A \to \alpha \cdot, u, i), so A→αA \to \alpha is a production and, with uu calling AA at jj, A⇒α⇒∗w[j:i]A \Rightarrow \alpha \Rightarrow^* w[j:i]. If u=u0u = u_0, then A=SA = S and j=0j = 0, and line L10 records ii correctly. Otherwise line L11 may add (u,i)(u, i) to PP, which satisfies I3. For each edge u→v′u \to v', with u=(B→γA⋅δ,j)u = (B \to \gamma A \cdot \delta, j), invariant I2 says (B→γ⋅Aδ,v′,j)(B \to \gamma \cdot A \delta, v', j) was visited, so by I1 v′v' calls BB at some j′j' with γ⇒∗w[j′:j]\gamma \Rightarrow^* w[j':j]. The added descriptor (B→γA⋅δ,v′,i)(B \to \gamma A \cdot \delta, v', i) then has γA⇒∗w[j′:i]\gamma A \Rightarrow^* w[j':i], which is I1.

No other step changes UU, the edges or PP. □\square

In particular, if line L10 records nn then S⇒∗wS \Rightarrow^* w, so every accepted input is in L(G)L(G), and every span reported from PP is derived.

Termination

A slot is a production and a dot position, so there are s≤∣G∣s \le |G| of them. GSS nodes are pairs of a slot and a position in 0,…,n0, \dots, n, so there are at most s(n+1)+1s (n + 1) + 1 of them with the root, and descriptors are triples of a slot, a node and a position, so UU is finite. Line L12 puts each descriptor into RR at most once, so the main loop takes at most ∣U∣|U| descriptors. Processing one is finite: line L3 advances the dot at most ∣G∣|G| times, line L4 loops over the finitely many productions of BB, and the loops of lines L8 and L11 run over the finite sets PP and the edges of one node. So the run terminates on every grammar and input, including grammars with cycles A⇒+AA \Rightarrow^+ A.

Completeness

For a derivation tree, its size is the number of its internal nodes (nodes labelled by nonterminals). For a sequence η=X1⋯Xm\eta = X_1 \cdots X_m and a derivation η⇒∗w[k:i]\eta \Rightarrow^* w[k:i], its size is the sum of the sizes of the trees of X1,…,XmX_1, \dots, X_m, where a terminal has a tree of size 0.

Lemma A. Let (C→α⋅Xβ,v,i)(C \to \alpha \cdot X \beta, v, i) be visited, and let X⇒∗w[i:j]X \Rightarrow^* w[i:j] by a tree of size tt (t=0t = 0 when XX is a terminal). Then (C→αX⋅β,v,j)(C \to \alpha X \cdot \beta, v, j) is visited.

Lemma B. Let (C→⋅η,v,k)(C \to \cdot \eta, v, k) be visited, and let η⇒∗w[k:i]\eta \Rightarrow^* w[k:i] with size tt. Then (C→η⋅,v,i)(C \to \eta \cdot, v, i) is visited.

Proof of both, by strong induction on tt. We prove Lemma A for size tt assuming Lemma B for sizes less than tt, and Lemma B for size tt assuming Lemma A for sizes at most tt.

Lemma A, XX a terminal. Then t=0t = 0, j=i+1j = i + 1 and ai+1=Xa_{i+1} = X, so line L3 matches and (C→αX⋅β,v,i+1)(C \to \alpha X \cdot \beta, v, i + 1) is visited by definition.

Lemma A, XX a nonterminal. The root of the tree uses a production X→ηX \to \eta and η⇒∗w[i:j]\eta \Rightarrow^* w[i:j] with size t−1t - 1. Processing the visited configuration reaches line L4, which makes the node x=(C→αX⋅β,i)x = (C \to \alpha X \cdot \beta, i), ensures the edge x→vx \to v, and adds (X→⋅η,x,i)(X \to \cdot \eta, x, i) unless it is already in UU; either way it is in UU, hence taken from RR and visited. By Lemma B for size t−1t - 1, (X→η⋅,x,j)(X \to \eta \cdot, x, j) is visited, and processing it calls POP(x,j)(x, j) at line L5. Since x≠u0x \ne u_0, after that call (x,j)∈P(x, j) \in P. Now compare the moments TeT_e, when the edge x→vx \to v was added, and TpT_p, when (x,j)(x, j) was added to PP; they are different steps. If Te<TpT_e < T_p, then at TpT_p line L11 runs over the edges of xx, which include x→vx \to v, and adds (C→αX⋅β,v,j)(C \to \alpha X \cdot \beta, v, j). If Tp<TeT_p < T_e, then at TeT_e line L8 runs over the entries of PP for xx, which include (x,j)(x, j), and adds the same descriptor. In both cases it is in UU, hence visited.

Lemma B. Write η=X1⋯Xm\eta = X_1 \cdots X_m and split w[k:i]w[k:i] as w[k0:k1]⋯w[km−1:km]w[k_0:k_1] \cdots w[k_{m-1}:k_m] with k0=kk_0 = k, km=ik_m = i, and Xr⇒∗w[kr−1:kr]X_r \Rightarrow^* w[k_{r-1}:k_r] by a tree of size tr≤tt_r \le t. If m=0m = 0 the claim is the hypothesis. Otherwise apply Lemma A mm times: from the visited (C→X1⋯Xr−1⋅Xr⋯Xm,v,kr−1)(C \to X_1 \cdots X_{r-1} \cdot X_r \cdots X_m, v, k_{r-1}) it gives the visited (C→X1⋯Xr⋅Xr+1⋯Xm,v,kr)(C \to X_1 \cdots X_r \cdot X_{r+1} \cdots X_m, v, k_r), and after mm steps (C→η⋅,v,i)(C \to \eta \cdot, v, i). □\square

Theorem. The recognizer accepts ww if and only if S⇒∗wS \Rightarrow^* w. Moreover, for every GSS node vv that calls XX at kk and every jj with X⇒∗w[k:j]X \Rightarrow^* w[k:j], the pair (v,j)(v, j) is in PP.

Proof. If the input is accepted, line L10 recorded nn, and by invariant I3 S⇒∗wS \Rightarrow^* w. Conversely, let S⇒η⇒∗wS \Rightarrow \eta \Rightarrow^* w. Line L1 adds (S→⋅η,u0,0)(S \to \cdot \eta, u_0, 0), which is then visited, and Lemma B gives that (S→η⋅,u0,n)(S \to \eta \cdot, u_0, n) is visited; processing it calls POP(u0,n)(u_0, n) at line L5, so line L10 records nn and line L6 accepts. For the second claim, the node v=(C→αX⋅β,k)v = (C \to \alpha X \cdot \beta, k) was created at line L4 while processing a visited (C→α⋅Xβ,u,k)(C \to \alpha \cdot X \beta, u, k), and the argument in the proof of Lemma A, with x=vx = v, shows that (v,j)∈P(v, j) \in P for every derivation X⇒∗w[k:j]X \Rightarrow^* w[k:j]. □\square

Remark on the order. The proofs never use the order in which descriptors are taken from RR. Read the steps as rules: line L4 turns a configuration into a node, an edge and call descriptors; line L5 turns a configuration and an edge, or a configuration at the root, into a descriptor or a recorded end; and so on. Every member of the final sets was produced by a rule from members present earlier, and the final sets are closed under every rule, because each rule fires when the last of its premises appears (this is what lines L8 and L11 ensure for the pair of an edge and an entry of PP). So the final sets are the least sets closed under the rules, whatever the order. ∎

Back to GLL parsing