Algorithm Search⌘K

Proofs: Substitution tree

These are the human proofs of Substitution tree, at full length.

Substitution tree operations keep the invariant and retrieval is exact full

This proof shows: correctness.

We use the pseudocode and the invariant (S1) to (S4) of the page, and the notation of the term rewriting pages: terms T(Σ,V)T(\Sigma, V) and substitutions applied on the right. For a node xx with path x1,…,xkx_1, \ldots, x_k below the top, term(x)=∗0 σx1⋯σxkterm(x) = *0\, \sigma_{x_1} \cdots \sigma_{x_k}, and open(x)open(x) is the set of indicator variables in term(x)term(x); for the top, term=∗0term = *0 and open={∗0}open = \{*0\}. For a stored term ll, l^\hat l is its normal form, whose variables are #1,#2,…\#1, \#2, \ldots.

Lemma 0 (open variables). If cc is a child of xx, then open(c)=(open(x)∖dom σc)∪Icopen(c) = (open(x) \setminus dom\, \sigma_c) \cup I_c, where IcI_c is the set of indicator variables in the range of σc\sigma_c, and IcI_c is disjoint from open(x)open(x) and from the domains on the path to xx.

Proof. term(c)=term(x)σcterm(c) = term(x)\sigma_c, and dom σc⊆open(x)dom\, \sigma_c \subseteq open(x) by (S2). Each variable of dom σcdom\, \sigma_c occurs in term(x)term(x) and is replaced; by (S3) each variable of IcI_c occurs only once in all ranges, so it is not in the range of an ancestor, and it is not ∗0*0 or in term(x)term(x), whose indicator variables come from those ranges. It is not in an ancestor's domain either, since by (S2) such domains are open at that ancestor, hence come from earlier ranges or are ∗0*0. □\square

Insertion

Loop invariant. At line L2, τ\tau has domain open(x)open(x), its values have no indicator variables, and term(x)τ=l^term(x)\tau = \hat l.

Initially xx is the top, τ={∗0↦l^}\tau = \{*0 \mapsto \hat l\}, and term=∗0term = *0. At line L3, ρ\rho binds exactly the variables of IcI_c: matching walks every position of σc(y)\sigma_c(y) against τ(y)\tau(y), and each variable of IcI_c occurs once, so it gets one binding, to a subterm of a value of τ\tau, which has no indicator variables. Line L4 sets τ′=(τ∖dom σc)∪ρ\tau' = (\tau \setminus dom\, \sigma_c) \cup \rho, whose domain is open(c)open(c) by Lemma 0. For y∈dom σcy \in dom\, \sigma_c, yσcτ′=σc(y)ρ=τ(y)y\sigma_c\tau' = \sigma_c(y)\rho = \tau(y), because σc(y)\sigma_c(y) contains only variables of IcI_c besides stored variables; for other y∈open(x)y \in open(x), yσcτ′=τ(y)y\sigma_c\tau' = \tau(y). Hence term(c)τ′=term(x)σcτ′=term(x)τ=l^term(c)\tau' = term(x)\sigma_c\tau' = term(x)\tau = \hat l.

Line L5. If τ\tau is empty, open(x)open(x) is empty. Then xx is not the top, and by (S1) and (S2) it is a leaf, since an inner node has open variables. So term(x)=l^term(x) = \hat l, and adding the entry there keeps (S1). The other parts of the invariant do not change.

Line L8. Here τ\tau is not empty and no child matches. For y∈dom σcy \in dom\, \sigma_c, GENERALIZE walks σc(y)\sigma_c(y) and τ(y)\tau(y) in parallel. At equal function symbols it descends; at an equal stored variable it keeps it; at an indicator variable ww of σc\sigma_c it keeps ww and sets β(w)\beta(w) to the subterm of τ(y)\tau(y); elsewhere it puts a fresh zz with α(z)\alpha(z) and β(z)\beta(z) the two subterms. By induction on the walk, μ(y)α=σc(y)\mu(y)\alpha = \sigma_c(y) and μ(y)β=τ(y)\mu(y)\beta = \tau(y), where α\alpha leaves the kept variables ww alone. Let MM be the new node, c′c' the old child with substitution α\alpha, and LL the new leaf with ρL=(τ∖dom μ)∪β\rho_L = (\tau \setminus dom\, \mu) \cup \beta.

  • Terms below c′c'. term(c′)=term(x)μαterm(c') = term(x)\mu\alpha, and μα\mu\alpha agrees with σc\sigma_c on dom σcdom\, \sigma_c and is the identity elsewhere on open(x)open(x), so term(c′)=term(c)term(c') = term(c). All nodes below cc keep their terms, and (S1) holds for them.
  • The new leaf. term(L)=term(x)μρLterm(L) = term(x)\mu\rho_L. For y∈dom μy \in dom\, \mu, μ(y)ρL=μ(y)β=τ(y)\mu(y)\rho_L = \mu(y)\beta = \tau(y), because the variables of μ(y)\mu(y) are fresh variables, kept variables and stored variables, and β\beta binds the first two. For other y∈open(x)y \in open(x), yρL=τ(y)y\rho_L = \tau(y). So term(L)=term(x)τ=l^term(L) = term(x)\tau = \hat l, which has no indicator variables, and LL is a leaf with one entry.
  • (S2) and (S3). dom μ=dom σcdom\, \mu = dom\, \sigma_c, which is open at xx. The range of μ\mu has the fresh variables, each once, and the kept variables of IcI_c, which leave the range of σc\sigma_c: the range of α\alpha consists of subterms of σc\sigma_c at the positions of fresh variables, which do not contain the kept variables. So every indicator variable still occurs once in all ranges. dom αdom\, \alpha is the set of fresh variables and dom ρLdom\, \rho_L is (open(x)∖dom μ)(open(x) \setminus dom\, \mu) plus the fresh and kept variables, all open at MM by Lemma 0. Both are nonempty: α\alpha is checked at line L7, and ρL⊇β\rho_L \supseteq \beta, which is nonempty because a μ\mu with no fresh or kept variable would equal τ\tau on the domain, and then cc would have matched at line L3.
  • (S4). MM has two children, and the number of children of xx does not change.

Line L9. The new leaf has domain open(x)open(x), nonempty, and term=term(x)τ=l^term = term(x)\tau = \hat l; its range has no indicator variables. xx is the top or an inner node, since a leaf has no open variables, so (S4) still holds. ■\blacksquare

Retrieval

Let q′q' be the renamed query, with variables ?x?x disjoint from all stored and indicator variables. Let RR be the set of rigid variables of the mode: the query variables for generalizations, the stored variables for instances, none for unifiable terms. For a node xx with path x1,…,xkx_1, \ldots, x_k, let E(x)E(x) be the set of equations ∗0=q′*0 = q' and y=σxi(y)y = \sigma_{x_i}(y) for i≤ki \le k and y∈dom σxiy \in dom\, \sigma_{x_i}. A solution of E(x)E(x) is a substitution θ\theta that binds no variable of RR and makes both sides of each equation equal.

Lemma 1. For a leaf xx, E(x)E(x) has a solution iff there is a θ\theta that binds no variable of RR with term(x)θ=q′θterm(x)\theta = q'\theta.

Proof. Let θ\theta solve E(x)E(x). By induction on ii, ∗0θ=∗0 σx1⋯σxiθ*0\theta = *0\, \sigma_{x_1} \cdots \sigma_{x_i}\theta: the step replaces each variable yy of dom σxi+1dom\, \sigma_{x_{i+1}} by σxi+1(y)\sigma_{x_{i+1}}(y), and yθ=σxi+1(y)θy\theta = \sigma_{x_{i+1}}(y)\theta. So term(x)θ=∗0θ=q′θterm(x)\theta = *0\theta = q'\theta. Conversely, let term(x)θ=q′θterm(x)\theta = q'\theta. Change θ\theta on the indicator variables, which occur in neither term(x)term(x) nor q′q': for each yy bound on the path at xix_i, set yθ′=y σxi+1⋯σxkθy\theta' = y\,\sigma_{x_{i+1}} \cdots \sigma_{x_k}\theta, and ∗0θ′=term(x)θ*0\theta' = term(x)\theta. Then ∗0θ′=q′θ=q′θ′*0\theta' = q'\theta = q'\theta', and yθ′=σxi(y)σxi+1⋯σxkθ=σxi(y)θ′y\theta' = \sigma_{x_i}(y)\sigma_{x_{i+1}} \cdots \sigma_{x_k}\theta = \sigma_{x_i}(y)\theta' by the same definition applied to the variables of σxi(y)\sigma_{x_i}(y), which are bound later on the path or are not indicator variables. □\square

Lemma 2. When line L13 processes a node xx, it succeeds iff E(x)E(x) has a solution, and then θ\theta is a most general such solution.

Proof. Induction on the depth of xx. Before xx, θ\theta is a most general solution of E(parent)E(parent), by induction, or {∗0↦q′}\{*0 \mapsto q'\} for a child of the top, the bindings of other branches having been removed at lines L12 and L16. Robinson's algorithm with rigid variables treated as constants, started from a most general solution θ0\theta_0 of a set E0E_0 and given new equations E1E_1, succeeds iff E0∪E1E_0 \cup E_1 has a solution, and returns a most general one: every solution of E0∪E1E_0 \cup E_1 is an instance of θ0\theta_0, so it solves E1θ0E_1\theta_0, and the algorithm is complete for that problem. □\square

Theorem. SUBST-RETRIEVE outputs each entry (l,v)(l, v) exactly once if it satisfies the query, and no other entry.

Proof. The stack visits each node at most once, and visits the children of a node iff its equations succeed, so by Lemma 2 it reaches a leaf xx and line L15 outputs its entries iff E(x)E(x) has a solution, since EE grows along the path. By Lemma 1 and (S1), this holds iff l^θ=q′θ\hat l\theta = q'\theta for some θ\theta with no rigid binding. For generalizations the query variables are rigid, so q′θ=q′q'\theta = q' and θ\theta restricted to the stored variables is a matcher of l^\hat l onto q′q', and so of ll onto qq after renaming. For instances the stored variables are rigid, so l^=q′θ\hat l = q'\theta. For unifiable terms, l^\hat l and q′q' have disjoint variables, and θ\theta is a unifier of the renamed terms. Each entry is at exactly one leaf by (S1). ■\blacksquare

Deletion

Line L17 follows from the top every child that matches, with the same loop invariant as insertion, and a leaf xx is reached with τ\tau empty iff term(x)=l^term(x) = \hat l: if term(x)=l^term(x) = \hat l, then at every node on its path σc(y)ρ=τ(y)\sigma_c(y)\rho = \tau(y) holds with ρ\rho the bindings that the rest of the path gives, so the path is followed; the converse is the loop invariant. By (S1) the entry, if present, is at such a leaf, and line L18 removes one copy. A leaf left without entries is removed at line L19, which keeps (S1) to (S3) for the other nodes.

Line L21 merges a node pp, other than the top, with its only child cc. Let IpI_p be the indicator variables in the range of σp\sigma_p. The merged substitution ν\nu maps y∈dom σpy \in dom\, \sigma_p to σp(y)σc\sigma_p(y)\sigma_c and y∈dom σc∖Ipy \in dom\, \sigma_c \setminus I_p to σc(y)\sigma_c(y). For a variable yy of open(parent)open(parent), yσpσc=yνy\sigma_p\sigma_c = y\nu: if y∈dom σpy \in dom\, \sigma_p this is the definition, and otherwise yσp=yy\sigma_p = y and yσc=yνy\sigma_c = y\nu. So termterm of the merged node equals term(c)term(c), and every node below keeps its term. The domain of ν\nu is dom σpdom\, \sigma_p and the part of dom σcdom\, \sigma_c open at the parent of pp, so (S2) holds. Each indicator variable of the range of ν\nu comes from the range of σp\sigma_p or σc\sigma_c, and a variable of IpI_p bound by σc\sigma_c disappears, so (S3) holds. The merged node has the children and entries of cc, so (S4) holds again, and the parent of pp keeps its number of children. ■\blacksquare

Back to Substitution tree