A finite simple type can describe one list cell, two list cells, or any other fixed number of cells. It cannot describe the type of all finite lists by repeating itself finitely many times. The equation 𝐿≅𝟏+(ℕ×𝐿) says what is missing: the type being defined occurs in its own description. Such a self-referential type expression is a recursive type. One programming interpretation makes the crossing between a recursive type and one unfolding of its body observable. The equi-recursive alternative in section 24.2 instead identifies their regular unfoldings.
Crossing a recursive equation explicitly
The calculus 𝜆𝗂𝗌𝗈𝜇 is the eager simply typed calculus with 𝟏, 𝟐, ℕ, products, sums, arrows, and the two term forms 𝖿𝗈𝗅𝖽𝜇𝑋.𝐴𝑒 and 𝗎𝗇𝖿𝗈𝗅𝖽𝑒. Type variables are bound only by 𝜇. It is an iso-recursive calculus: crossing the recursive equation requires an explicit fold or unfold term.
The complete type and term grammars are 𝐴,𝐵::=𝟏∣𝟐∣ℕ∣𝑋∣𝐴→𝐵∣𝐴×𝐵∣𝐴+𝐵∣𝜇𝑋.𝐴,𝑒::=𝑥∣𝗎𝗇𝗂𝗍∣𝗍𝗍∣𝖿𝖿∣𝑛∣𝜆𝑥:𝐴.𝑒∣𝑒1𝑒2∣𝗂𝖿(𝑒;𝑒1;𝑒2)∣⟨𝑒1,𝑒2⟩∣𝖿𝗌𝗍𝑒∣𝗌𝗇𝖽𝑒∣𝗂𝗇𝗅𝑒∣𝗂𝗇𝗋𝑒∣𝖼𝖺𝗌𝖾𝑒𝗈𝖿{𝗂𝗇𝗅𝑥↦𝑒0;𝗂𝗇𝗋𝑦↦𝑒1}∣𝖿𝗈𝗅𝖽𝜇𝑋.𝐴𝑒∣𝗎𝗇𝖿𝗈𝗅𝖽𝑒. Types are identified up to alpha-renaming, but 𝜇𝑋.𝐴 is not judgmentally equal to 𝐴[𝜇𝑋.𝐴/𝑋]. The type formers have their syntax-directed formation rules. Recursive types are formed by
Δ,𝑋⊢𝐴𝗍𝗒𝗉𝖾
Δ⊢𝜇𝑋.𝐴𝗍𝗒𝗉𝖾
Mu-F
Rule Mu-F requires the body to be a type under the bound type variable. Term typing is the least judgment containing the following rules: 𝑥:𝐴∈ΓΓ⊢𝑥:𝐴,Γ⊢𝗎𝗇𝗂𝗍:𝟏,Γ⊢𝗍𝗍:𝟐,Γ⊢𝖿𝖿:𝟐,Γ⊢𝑛:ℕ,Γ,𝑥:𝐴⊢𝑒:𝐵Γ⊢𝜆𝑥:𝐴.𝑒:𝐴→𝐵,Γ⊢𝑒1:𝐴→𝐵Γ⊢𝑒2:𝐴Γ⊢𝑒1𝑒2:𝐵,Γ⊢𝑒:𝟐Γ⊢𝑒1:𝐴Γ⊢𝑒2:𝐴Γ⊢𝗂𝖿(𝑒;𝑒1;𝑒2):𝐴,Γ⊢𝑒1:𝐴Γ⊢𝑒2:𝐵Γ⊢⟨𝑒1,𝑒2⟩:𝐴×𝐵,Γ⊢𝑒:𝐴×𝐵Γ⊢𝖿𝗌𝗍𝑒:𝐴,Γ⊢𝑒:𝐴×𝐵Γ⊢𝗌𝗇𝖽𝑒:𝐵,Γ⊢𝑒:𝐴Γ⊢𝗂𝗇𝗅𝑒:𝐴+𝐵,Γ⊢𝑒:𝐵Γ⊢𝗂𝗇𝗋𝑒:𝐴+𝐵,Γ⊢𝑒:𝐴+𝐵Γ,𝑥:𝐴⊢𝑒0:𝐶Γ,𝑦:𝐵⊢𝑒1:𝐶Γ⊢𝖼𝖺𝗌𝖾𝑒𝗈𝖿{𝗂𝗇𝗅𝑥↦𝑒0;𝗂𝗇𝗋𝑦↦𝑒1}:𝐶. The recursive introduction and elimination rules are
Γ⊢𝑒:𝐴[𝜇𝑋.𝐴/𝑋]
Γ⊢𝖿𝗈𝗅𝖽𝜇𝑋.𝐴𝑒:𝜇𝑋.𝐴
T-Fold
Γ⊢𝑒:𝜇𝑋.𝐴
Γ⊢𝗎𝗇𝖿𝗈𝗅𝖽𝑒:𝐴[𝜇𝑋.𝐴/𝑋]
T-Unfold
The type context Δ is used only for formation; every term judgment has well-formed types under the ambient Δ, suppressed when empty.
Values and call-by-value evaluation contexts are exactly 𝑣::=𝗎𝗇𝗂𝗍∣𝗍𝗍∣𝖿𝖿∣𝑛∣𝜆𝑥:𝐴.𝑒∣⟨𝑣1,𝑣2⟩∣𝗂𝗇𝗅𝑣∣𝗂𝗇𝗋𝑣∣𝖿𝗈𝗅𝖽𝜇𝑋.𝐴𝑣,𝐸::=[]∣𝐸𝑒∣𝑣𝐸∣𝗂𝖿(𝐸;𝑒1;𝑒2)∣⟨𝐸,𝑒⟩∣⟨𝑣,𝐸⟩∣𝖿𝗌𝗍𝐸∣𝗌𝗇𝖽𝐸∣𝗂𝗇𝗅𝐸∣𝗂𝗇𝗋𝐸∣𝖼𝖺𝗌𝖾𝐸𝗈𝖿{𝗂𝗇𝗅𝑥↦𝑒0;𝗂𝗇𝗋𝑦↦𝑒1}∣𝖿𝗈𝗅𝖽𝜇𝑋.𝐴𝐸∣𝗎𝗇𝖿𝗈𝗅𝖽𝐸. The compatible closure uses precisely these root contractions:
(𝜆𝑥:𝐴.𝑒)𝑣⟼𝑒[𝑣/𝑥]
E-Beta
𝗂𝖿(𝗍𝗍;𝑒1;𝑒2)⟼𝑒1
E-IfTrue
𝗂𝖿(𝖿𝖿;𝑒1;𝑒2)⟼𝑒2
E-IfFalse
𝖿𝗌𝗍⟨𝑣1,𝑣2⟩⟼𝑣1
E-Fst
𝗌𝗇𝖽⟨𝑣1,𝑣2⟩⟼𝑣2
E-Snd
𝖼𝖺𝗌𝖾(𝗂𝗇𝗅𝑣)𝗈𝖿{𝗂𝗇𝗅𝑥↦𝑒0;𝗂𝗇𝗋𝑦↦𝑒1}⟼𝑒0[𝑣/𝑥]
E-CaseL
𝖼𝖺𝗌𝖾(𝗂𝗇𝗋𝑣)𝗈𝖿{𝗂𝗇𝗅𝑥↦𝑒0;𝗂𝗇𝗋𝑦↦𝑒1}⟼𝑒1[𝑣/𝑦]
E-CaseR
𝗎𝗇𝖿𝗈𝗅𝖽(𝖿𝗈𝗅𝖽𝜇𝑋.𝐴𝑣)⟼𝑣
E-UnfoldFold
In particular, the payload of a fold is evaluated before the folded term is a value. No other root or evaluation-context form belongs to this calculus.
Put 𝖫𝗂𝗌𝗍𝖭𝖺𝗍:=𝜇𝑋.(𝟏+ℕ×𝑋). Its two constructors are ordinary terms: 𝗇𝗂𝗅:=𝖿𝗈𝗅𝖽𝖫𝗂𝗌𝗍𝖭𝖺𝗍(𝗂𝗇𝗅𝗎𝗇𝗂𝗍),𝖼𝗈𝗇𝗌:=𝜆𝑛:ℕ.𝜆𝑥𝑠:𝖫𝗂𝗌𝗍𝖭𝖺𝗍.𝖿𝗈𝗅𝖽𝖫𝗂𝗌𝗍𝖭𝖺𝗍(𝗂𝗇𝗋⟨𝑛,𝑥𝑠⟩). Rule T-Fold checks the first payload at 𝟏+ℕ×𝖫𝗂𝗌𝗍𝖭𝖺𝗍, and it checks the second at the same type through its right summand. A list case is an abbreviation: 𝖼𝖺𝗌𝖾𝖫𝗂𝗌𝗍𝑒𝗈𝖿{𝗇𝗂𝗅↦𝑒0;𝖼𝗈𝗇𝗌(𝑛,𝑥𝑠)↦𝑒1} is defined by the sum case 𝖼𝖺𝗌𝖾(𝗎𝗇𝖿𝗈𝗅𝖽𝑒;𝑢.𝑒0;𝑧.𝑒1[(𝖿𝗌𝗍𝑧)/𝑛][(𝗌𝗇𝖽𝑧)/𝑥𝑠]), where 𝑢 and 𝑧 are fresh. The cons branch projects 𝑛 and 𝑥𝑠 from the ordinary product. If the branch uses only 𝑥𝑠, substitution leaves only the 𝗌𝗇𝖽 projection. Put 𝑝=𝗂𝗇𝗋⟨3,𝗇𝗂𝗅⟩. Then 𝖼𝖺𝗌𝖾𝖫𝗂𝗌𝗍(𝖼𝗈𝗇𝗌3𝗇𝗂𝗅)𝗈𝖿{𝗇𝗂𝗅↦𝗇𝗂𝗅;𝖼𝗈𝗇𝗌(𝑛,𝑥𝑠)↦𝑥𝑠}𝑡𝑤𝑜𝛽𝑠𝑡𝑒𝑝𝑠𝑓𝑜𝑟𝖼𝗈𝗇𝗌⟼2𝖼𝖺𝗌𝖾(𝗎𝗇𝖿𝗈𝗅𝖽(𝖿𝗈𝗅𝖽𝖫𝗂𝗌𝗍𝖭𝖺𝗍𝑝);𝑢.𝗇𝗂𝗅;𝑧.𝗌𝗇𝖽𝑧)𝐸−𝑈𝑛𝑓𝑜𝑙𝑑𝐹𝑜𝑙𝑑⟼𝖼𝖺𝗌𝖾(𝑝;𝑢.𝗇𝗂𝗅;𝑧.𝗌𝗇𝖽𝑧)𝑟𝑖𝑔ℎ𝑡𝑠𝑢𝑚−𝛽⟼𝗌𝗇𝖽⟨3,𝗇𝗂𝗅⟩𝗌𝗇𝖽−𝛽⟼𝗇𝗂𝗅. For a numeral 𝑛 and term 𝑒, write 𝖼𝖾𝗅𝗅(𝑛,𝑒):=𝖿𝗈𝗅𝖽𝖫𝗂𝗌𝗍𝖭𝖺𝗍(𝗂𝗇𝗋⟨𝑛,𝑒⟩). The term 𝖼𝖾𝗅𝗅(𝑛,𝑣) is a canonical list value when 𝑣 is one. By contrast, the curried term 𝖼𝗈𝗇𝗌𝑛𝑣 takes two beta steps to that value.
Finite unfolding does not solve the original problem. If 𝐿0=𝟏 and 𝐿𝑘+1=𝟏+ℕ×𝐿𝑘, then 𝐿𝑘 represents at most 𝑘 cons cells. The constructor for a (𝑘+1)-st cell expects 𝐿𝑘, not 𝐿𝑘+1, so no fixed member of this sequence is closed under lists of arbitrary finite length. The fold packages all finite unfoldings behind one type.
Safety survives the equation
The recursive-type binder requires type substitution; lambda and branch binders require term substitution.
If 𝑋≠𝑌 and 𝑌∉FV(𝐵), then (𝐸[𝐷/𝑌])[𝐵/𝑋]=𝐸[𝐵/𝑋][𝐷[𝐵/𝑋]/𝑌]. The equation holds for every type expression 𝐸 after alpha-renaming its bound variables away from 𝐵 and 𝐷.
Proof of Lemma 24.2 — Composition of distinct type substitutions
Proof. Induct on 𝐸. At a variable, the cases 𝐸=𝑋, 𝐸=𝑌, and 𝐸∉{𝑋,𝑌} are the two substitution definitions; the side condition 𝑌∉FV(𝐵) closes the case 𝐸=𝑋. Arrows, products, and sums apply the induction hypotheses componentwise. For 𝐸=𝜇𝑍.𝐶, choose 𝑍∉FV(𝐵)∪FV(𝐷)∪{𝑋,𝑌}, apply the induction hypothesis to 𝐶, and restore the same 𝜇𝑍 binder. ◻
Proof. Items 1 and 2 are simultaneous inductions on formation and typing. The new formation case is 𝜇𝑌.𝐶. Choose 𝑌≠𝑋 fresh for 𝐵; the induction hypothesis forms 𝐶[𝐵/𝑋] under the substituted context extended by 𝑌, then Mu-F forms 𝜇𝑌.𝐶[𝐵/𝑋]. For T-Fold, the induction hypothesis gives Γ[𝐵/𝑋]⊢𝑒[𝐵/𝑋]:(𝐶[𝜇𝑌.𝐶/𝑌])[𝐵/𝑋]. By lemma 24.2, with 𝐷=𝜇𝑌.𝐶 and the chosen 𝑌≠𝑋, the required equation is (𝐶[𝜇𝑌.𝐶/𝑌])[𝐵/𝑋]=𝐶[𝐵/𝑋][𝜇𝑌.𝐶[𝐵/𝑋]/𝑌], which is exactly the premise of the substituted T-Fold. The T-Unfold case uses this equation in the opposite direction. All inherited binders use the same alpha-renaming convention.
Item 3 is induction on the typing derivation. Fold and unfold do not bind term variables. Apply the induction hypothesis to their premises and restore the same last rule. The lambda case is the inherited capture-avoiding case. ◻
Proof. Inspect the value forms. Unit, numerals, lambdas, pairs, and injections have different outer type constructors by inversion of their introduction rules. The only remaining value form is a fold. Inverting its typing derivation gives the payload judgment. There is no subsumption rule in 𝜆𝗂𝗌𝗈𝜇, so no final rule hides the constructor. ◻
Proof of Theorem 24.5 — Preservation, progress, and safety
Proof. Preservation is induction on the reduction derivation. The inherited beta, projection, and case roots use lemma 24.3, item 3. Compatible steps restore the corresponding typing rule. The only new root has a typing derivation ending ⋅⊢𝑣:𝐴[𝜇𝑋.𝐴/𝑋]⋅⊢𝖿𝗈𝗅𝖽𝜇𝑋.𝐴𝑣:𝜇𝑋.𝐴T−Fold⋅⊢𝗎𝗇𝖿𝗈𝗅𝖽(𝖿𝗈𝗅𝖽𝜇𝑋.𝐴𝑣):𝐴[𝜇𝑋.𝐴/𝑋]T−Unfold. The reduct is 𝑣, and the inner premise types it at 𝐴[𝜇𝑋.𝐴/𝑋].
Progress is induction on typing. In the fold case, the payload either steps, with that step lifted by the fold context, or is a value, making the whole fold a value. In the unfold case, the scrutinee either takes a lifted step or is a value. In the latter alternative, lemma 24.4 writes it as a folded value, and E-UnfoldFold applies. The inherited eliminators use their ordinary canonical-form clauses from lemma 2.22; the product, sum, Boolean, and natural-number extensions use the identical rule-inversion schema for their introduction forms. Item 3 follows by induction on the length of a finite evaluation, alternating items 1 and 2. ◻
★☆☆ Redo the E-UnfoldFold preservation case when the recursive body is ℕ×𝑋+𝟏. Display the substitution instance in the premise and explain why no type equality rule is used.
Let 𝐷:=𝜇𝑋.(𝑋→ℕ),𝛿:=𝜆𝑥:𝐷.(𝗎𝗇𝖿𝗈𝗅𝖽𝑥)𝑥. Because 𝐷 unfolds to 𝐷→ℕ, 𝛿:𝐷→ℕ, and 𝖿𝗈𝗅𝖽𝐷𝛿:𝐷. Thus Ω𝐷:=𝛿(𝖿𝗈𝗅𝖽𝐷𝛿):ℕ. Its evaluation repeats a two-step cycle: 𝛿(𝖿𝗈𝗅𝖽𝐷𝛿)⟼(𝗎𝗇𝖿𝗈𝗅𝖽(𝖿𝗈𝗅𝖽𝐷𝛿))(𝖿𝗈𝗅𝖽𝐷𝛿)⟼𝛿(𝖿𝗈𝗅𝖽𝐷𝛿). The term is safe by theorem 24.5 and does not normalize. The negative occurrence of 𝑋 in 𝑋→ℕ, not recursive syntax by itself, enables the loop. The decisive point is local: ⋅⊢𝛿(𝖿𝗈𝗅𝖽𝐷𝛿):ℕ follows from T-Fold, T-Unfold, and T-App. No dynamic cast, blame rule, or gradual calculus is used.
More generally, put 𝐷𝐴=𝜇𝑋.(𝑋→𝐴),𝛿𝑓=𝜆𝑥:𝐷𝐴.𝑓((𝗎𝗇𝖿𝗈𝗅𝖽𝑥)𝑥),𝖥𝗂𝗑𝐴=𝜆𝑓:𝐴→𝐴.𝛿𝑓(𝖿𝗈𝗅𝖽𝐷𝐴𝛿𝑓). Then 𝖥𝗂𝗑𝐴:(𝐴→𝐴)→𝐴. For every closed function value 𝑣:𝐴→𝐴, its call-by-value unfolding reaches 𝖥𝗂𝗑𝐴𝑣𝛽⟶𝛿𝑣(𝖿𝗈𝗅𝖽𝐷𝐴𝛿𝑣)𝛽⟶𝑣((𝗎𝗇𝖿𝗈𝗅𝖽(𝖿𝗈𝗅𝖽𝐷𝐴𝛿𝑣))(𝖿𝗈𝗅𝖽𝐷𝐴𝛿𝑣))𝐸−𝑈𝑛𝑓𝑜𝑙𝑑𝐹𝑜𝑙𝑑⟶𝑣(𝛿𝑣(𝖿𝗈𝗅𝖽𝐷𝐴𝛿𝑣)). The three roots leave the recursive subterm 𝛿𝑣(𝖿𝗈𝗅𝖽𝐷𝐴𝛿𝑣) in argument position. The hypothesis that 𝑣 is a closed function value is operationally necessary in this eager calculus: an open variable in operator position would be stuck, and a reducible closed operator must first evaluate. More importantly, this is only a compatible-beta fixed point. In call by value, 𝖥𝗂𝗑𝐴𝑣 diverges for every closed function value 𝑣. Indeed, put 𝑟=(𝗎𝗇𝖿𝗈𝗅𝖽(𝖿𝗈𝗅𝖽𝐷𝐴𝛿𝑣))(𝖿𝗈𝗅𝖽𝐷𝐴𝛿𝑣). Then 𝑟⟼2𝑣𝑟; evaluation of 𝑣𝑟 must evaluate 𝑟 before the beta step can run, and repeats the same demand forever. Thus 𝖥𝗂𝗑𝐴 is not a call-by-value programming recursion operator. The eta-delayed repair 𝖹, which returns a lambda before demanding its recursive argument, is given explicitly in definition 24.48 and used in the list-copy example. If types are read as propositions and the empty type is included, then 𝖥𝗂𝗑𝟎(𝜆𝑥:𝟎.𝑥):𝟎 is a closed inhabitant. It diverges rather than producing an empty-type value, but inhabitation alone already invalidates the usual normalization-based consistency argument. Operational type safety and proof-theoretic consistency are different claims. Here the bold glyph 𝟎 is the empty type; the upright 0 in the operational examples is the natural-number numeral.
★★☆ Give the full typing derivation of Ω𝐷, and prove by induction on 𝑘 that it has a reduction sequence of length 2𝑘 returning to its original syntax. Then derive the type and unfolding equation of 𝖥𝗂𝗑𝐴 at a closed function value.
Equi-recursive equality compares the infinite regular trees generated by two closed contractive type graphs. It changes no fold/unfold typing or reduction rule in 𝜆𝗂𝗌𝗈𝜇.
A contractive recursive type is one in which every occurrence of the variable bound by 𝜇𝑋.𝐴 lies strictly below a product, sum, or arrow constructor. In particular, 𝜇𝑋.𝑋 is rejected. Represent a closed type by a finite directed graph: constructor nodes carry their ordered children, and a recursive occurrence points back to its binder’s body node. Unfolding that graph yields a possibly infinite regular tree. For a raw graph node 𝑎, write expose(𝑎)=(𝜅;𝑎1,…,𝑎𝑛) when following zero or more recursive back-edges first reaches the constructor 𝜅, whose ordered children are 𝑎1,…,𝑎𝑛. By contractiveness, every back-edge path reaches a constructor, so expose is total. The unfolded tree rooted at 𝑎 has root 𝜅, and its 𝑖-th subtree is rooted at 𝑎𝑖. Thus expose maps raw graph nodes to constructor observations; the two sets are distinct.
Define a bisimulation to be a relation on positions of two unfolded trees such that related positions have the same constructor and every pair of corresponding children is again related. Write 𝐴≡𝜇𝐵 when some bisimulation relates the two roots. Equivalently, bisimilarity is the greatest fixed point of this closure clause; proofs may therefore use coinduction by exhibiting such a relation. Arrow children are compared in their written order; this is equality, not subtyping.
Given roots 𝑎,𝑏 in finite contractive type graphs, maintain a worklist 𝑊 of node pairs and a visited set 𝑉. Initially 𝑊=[(𝑎,𝑏)] and 𝑉=∅. Repeatedly remove a pair:
if it belongs to 𝑉, continue;
otherwise add it to 𝑉, compute expose(𝑎)=(𝜅;𝑎1,…,𝑎𝑛) and expose(𝑏)=(𝜅′;𝑏1,…,𝑏𝑚), and reject if 𝜅≠𝜅′ or 𝑛≠𝑚;
for matching heads, append every pair of corresponding children.
Accept when the worklist is empty. Contractiveness guarantees that following back-edges reaches a constructor before revisiting the same binder.
Proof of Theorem 24.8 — Decision of contractive regular equality
Proof. Let 𝑁𝐴,𝑁𝐵 be the finite node sets. A pair is expanded only on its first visit. Hence at most |𝑁𝐴||𝑁𝐵| iterations expand a pair. Every constructor has arity at most two, so those expansions enqueue at most 2|𝑁𝐴||𝑁𝐵| pairs in addition to the initial pair; duplicate-removal iterations are therefore finite as well. Contractiveness bounds each head exposure by the finite path to its next constructor, so the whole run terminates.
For soundness, let 𝑉𝑓 be the final visited set of raw graph-node pairs in an accepting run. If (𝑎,𝑏)∈𝑉𝑓, then expose(𝑎)=(𝜅;𝑎1,…,𝑎𝑛) and expose(𝑏)=(𝜅;𝑏1,…,𝑏𝑛), and every child pair (𝑎𝑖,𝑏𝑖) was queued and hence lies in 𝑉𝑓 at termination. Consequently the relation between the unfolded tree positions rooted at pairs in 𝑉𝑓 is a bisimulation containing the root pair. The unfolded trees are bisimilar.
For completeness, let 𝑅 be a tree bisimulation containing the roots. Maintain the following invariant: for every queued node pair (𝑐,𝑑), there are positions 𝑝,𝑞 in the two unfolded trees such that (𝑝,𝑞)∈𝑅 and the subtrees at 𝑝,𝑞 are rooted by the graph nodes 𝑐,𝑑. The initial root pair has these witnesses. When (𝑐,𝑑) is expanded, bisimulation gives equal constructor heads at 𝑝,𝑞 and relates every pair of corresponding child positions. Those child positions witness the invariant for every enqueued pair. Removing a duplicate changes no remaining witness. The head test therefore never rejects, and termination forces acceptance. ◻
Any fixed fuel bound on textual unfolding can reject equal regular types whose finite graph comparison needs more head exposures than that bound permits. The worklist instead terminates because it expands at most |𝑁𝐴||𝑁𝐵| distinct node pairs.
★☆☆ Run the worklist algorithm on 𝜇𝑋.(ℕ×𝑋+𝟏)andℕ×𝜇𝑋.(ℕ×𝑋+𝟏)+𝟏. List the visited pairs. Then replace the right-hand ℕ by 𝟐 and identify the first rejecting pair.
The restriction is load bearing. For 𝜇𝑋.𝑋, head exposure chases the same back-edge without revealing a constructor, so neither the algorithm nor the regular-tree construction of definition 24.6 yields a constructor-headed regular tree. No decidability claim for unrestricted recursive type expressions follows.
A call-by-name language with general recursion
Programming Computable Functions 𝖯𝖢𝖥𝗇 evaluates only the operator of an application; it has no argument evaluation context. We write its step as ⟼, reserving ⟼ for the eager fold calculus.
The grammar is 𝐴,𝐵::=ℕ∣𝐴→𝐵,𝑒::=𝑥∣𝑛∣𝗌𝗎𝖼𝖼𝑒∣𝗂𝖿𝗓𝑒𝗍𝗁𝖾𝗇𝑒0𝖾𝗅𝗌𝖾𝑥.𝑒𝑠∣𝜆𝑥:𝐴.𝑒∣𝑒𝑒∣𝖿𝗂𝗑𝑥:𝐴.𝑒. The successor branch binds the predecessor to 𝑥. Typing consists of the ordinary variable, numeral, abstraction, and application rules together with
Γ⊢𝑒:ℕ
Γ⊢𝗌𝗎𝖼𝖼𝑒:ℕ
P-Succ
Γ⊢𝑒:ℕΓ⊢𝑒0:𝐴Γ,𝑥:ℕ⊢𝑒𝑠:𝐴
Γ⊢𝗂𝖿𝗓𝑒𝗍𝗁𝖾𝗇𝑒0𝖾𝗅𝗌𝖾𝑥.𝑒𝑠:𝐴
P-Ifz
Γ,𝑥:𝐴⊢𝑒:𝐴
Γ⊢𝖿𝗂𝗑𝑥:𝐴.𝑒:𝐴
P-Fix
Values are numerals and abstractions. Evaluation contexts are 𝐸::=[]∣𝐸𝑒∣𝗌𝗎𝖼𝖼𝐸∣𝗂𝖿𝗓𝐸𝗍𝗁𝖾𝗇𝑒0𝖾𝗅𝗌𝖾𝑥.𝑒𝑠. There is no argument context 𝑣𝐸. The root rules are
(𝜆𝑥:𝐴.𝑒)𝑑⟼𝑒[𝑑/𝑥]
P-Beta
𝗌𝗎𝖼𝖼𝑛⟼𝑛+1
P-SuccN
𝗂𝖿𝗓0𝗍𝗁𝖾𝗇𝑒0𝖾𝗅𝗌𝖾𝑥.𝑒𝑠⟼𝑒0
P-IfZ
𝗂𝖿𝗓(𝑛+1)𝗍𝗁𝖾𝗇𝑒0𝖾𝗅𝗌𝖾𝑥.𝑒𝑠⟼𝑒𝑠[𝑛/𝑥]
P-IfS
𝖿𝗂𝗑𝑥:𝐴.𝑒⟼𝑒[𝖿𝗂𝗑𝑥:𝐴.𝑒/𝑥]
P-Unroll
Compatible closure under 𝐸 is the one-step relation. Write 𝑒⇓𝑛 when 𝑒⟼∗𝑛. Write 𝑒⟼𝜔 when there is an infinite sequence 𝑒=𝑒0⟼𝑒1⟼𝑒2⟼⋯.
Every closed nonvalue PCF term has at most one decomposition 𝐸[𝑟], where 𝐸 is an evaluation context of definition 24.10 and 𝑟 is one of its five root redexes. Consequently it has at most one one-step reduct.
Proof of Lemma 24.11 — Unique call-by-name decomposition
Proof. Induct on the term. An application selects its operator until that operator is a lambda, after which the whole application is the unique beta root; there is no argument context. Successor and zero test select their unique scrutinee until it is a numeral, at which point exactly one arithmetic or zero-test root matches. A fixpoint is always the unique unrolling root. Variables cannot occur in a closed term, and values have no decomposition. The context and root alternatives are disjoint in every case. ◻
The predecessor binder keeps recursive arithmetic readable. Define 𝗉𝗅𝗎𝗌:=𝖿𝗂𝗑𝑓:ℕ→ℕ→ℕ.𝜆𝑚:ℕ.𝜆𝑛:ℕ.𝗂𝖿𝗓𝑚𝗍𝗁𝖾𝗇𝑛𝖾𝗅𝗌𝖾𝑘.𝗌𝗎𝖼𝖼(𝑓𝑘𝑛). Write 𝑃 for this closed fixed-point term and abbreviate 𝐵(𝑚,𝑛):=𝗂𝖿𝗓𝑚𝗍𝗁𝖾𝗇𝑛𝖾𝗅𝗌𝖾𝑘.𝗌𝗎𝖼𝖼(𝑃𝑘𝑛). Call by name substitutes an argument before evaluating it: 𝑃21⟼(𝜆𝑚.𝜆𝑛.𝐵(𝑚,𝑛))21𝑃−𝑈𝑛𝑟𝑜𝑙𝑙⟼(𝜆𝑛.𝐵(2,𝑛))1𝑃−𝐵𝑒𝑡𝑎⟼𝐵(2,1)𝑃−𝐵𝑒𝑡𝑎⟼𝗌𝗎𝖼𝖼(𝑃11)𝑃−𝐼𝑓𝑆⟼𝗌𝗎𝖼𝖼((𝜆𝑚.𝜆𝑛.𝐵(𝑚,𝑛))11)𝑃−𝑈𝑛𝑟𝑜𝑙𝑙⟼𝗌𝗎𝖼𝖼((𝜆𝑛.𝐵(1,𝑛))1)𝑃−𝐵𝑒𝑡𝑎⟼𝗌𝗎𝖼𝖼(𝐵(1,1))𝑃−𝐵𝑒𝑡𝑎⟼𝗌𝗎𝖼𝖼(𝗌𝗎𝖼𝖼(𝑃01))𝑃−𝐼𝑓𝑆⟼𝗌𝗎𝖼𝖼(𝗌𝗎𝖼𝖼((𝜆𝑚.𝜆𝑛.𝐵(𝑚,𝑛))01))𝑃−𝑈𝑛𝑟𝑜𝑙𝑙⟼𝗌𝗎𝖼𝖼(𝗌𝗎𝖼𝖼((𝜆𝑛.𝐵(0,𝑛))1))𝑃−𝐵𝑒𝑡𝑎⟼𝗌𝗎𝖼𝖼(𝗌𝗎𝖼𝖼(𝐵(0,1)))𝑃−𝐵𝑒𝑡𝑎⟼𝗌𝗎𝖼𝖼(𝗌𝗎𝖼𝖼1)𝑃−𝐼𝑓𝑍⟼𝗌𝗎𝖼𝖼2𝑃−𝑆𝑢𝑐𝑐𝑁⟼3.𝑃−𝑆𝑢𝑐𝑐𝑁 Each successor branch decreases the first argument and adds one surrounding 𝗌𝗎𝖼𝖼; the zero branch returns the second argument. Thus the trace reaches 3. By contrast, Ωℕ=𝖿𝗂𝗑𝑥:ℕ.𝑥⟼𝖿𝗂𝗑𝑥:ℕ.𝑥 diverges in one repeated step.
Proof of Lemma 24.12 — PCF structural and safety properties
Proof. Substitution is induction on typing. In P-Ifz, alpha-rename the predecessor binder away from 𝑥 and the free variables of 𝑑, then use the three induction hypotheses. In P-Fix, alpha-rename its binder and apply the induction hypothesis under the extended context. The other cases are the simply typed cases.
Preservation is induction on reduction. Rules P-Beta, P-IfS, and P-Unroll use substitution; the other roots retain the type by inversion. Contexts restore the last typing rule. For progress, inspect the typing derivation. An application first evaluates its function; a closed function value is a lambda, so P-Beta applies without evaluating the argument. Successor and zero test first evaluate their numeral scrutinee. Fix always uses P-Unroll. Unique decomposition is lemma 24.11. Inspecting the value grammar and inverting the last typing rule gives the final natural canonical form. ◻
★★☆ Repeat the displayed calculation for 𝗉𝗅𝗎𝗌12, naming every root rule and checking that four beta steps occur. Then evaluate (𝜆𝑥:ℕ.0)Ωℕ under the displayed call-by-name contexts. If an argument context 𝑣𝐸 is added and P-Beta is restricted to value arguments for call by value, prove that the same application takes infinitely many steps instead of reaching 0.
A finite evaluator can observe the first 𝑘 unfoldings of a recursive program. A denotation orders these observations by ⊑𝖣 and takes their least upper bound. The order ⊑𝖣 compares definedness inside one domain; it is not a cross-language precision relation.
A poset has a reflexive, transitive, antisymmetric order. An omega-chain is a sequence 𝑑0⊑𝖣𝑑1⊑𝖣⋯. An omega-cpo has a least upper bound ⨆𝑛𝑑𝑛 for every omega-chain. A pointed omega-cpo is an omega-cpo with a least element ⊥; a domain here is a pointed omega-cpo.
A monotone function𝑓:𝐷⟶𝐸 satisfies 𝑑⊑𝖣𝑑′ implies 𝑓(𝑑)⊑𝖣𝑓(𝑑′). It is a continuous function when it is monotone and 𝑓⎛⎜
⎜
⎜⎝⨆𝑛𝑑𝑛⎞⎟
⎟
⎟⎠=⨆𝑛𝑓(𝑑𝑛) for every omega-chain. Write [𝐷⟶𝐸]𝑐 for the continuous functions, ordered pointwise.
An element 𝑐∈𝐷 is compact when, for every omega-chain (𝑑𝑖), 𝑐⊑𝖣⨆𝑖𝑑𝑖⟹𝑐⊑𝖣𝑑𝑗forsome𝑗. Thus a compact observation below a chain lub already occurs at a finite stage.
Only omega-chains are required. For a monotone countable grid (𝑎𝑖,𝑗), its diagonal is cofinal—every grid entry lies below a diagonal entry—because 𝑎𝑖,𝑗⊑𝖣𝑎𝑘,𝑘 whenever 𝑘≥𝑖,𝑗.
The flat natural domain adjoins bottom to the discrete set of natural numbers: ℕ⊥={⊥}∪ℕ,⊥⊑𝖣𝑛, with no order between distinct naturals. Every chain is either constantly bottom or has indices 𝑖 and 𝑛 such that every member from index 𝑖 onward is 𝑛; its lub is ⊥ or 𝑛, respectively.
The recursive list equation also uses products, separated sums (different tags are incomparable), and a fresh bottom. We fix their orders before using the equation. Let {∗} be the singleton poset, and give ℕ the discrete order, in which only equal elements are comparable. The ambient domains determine the omitted order subscripts: (𝑑,𝑒)⊑𝖣(𝑑′,𝑒′)⟺𝑑⊑𝖣𝑑′and𝑒⊑𝖣𝑒′,𝗂𝗇𝗅𝑑⊑𝖣𝗂𝗇𝗅𝑑′⟺𝑑⊑𝖣𝑑′,𝗂𝗇𝗋𝑒⊑𝖣𝗂𝗇𝗋𝑒′⟺𝑒⊑𝖣𝑒′, with no comparison between the two sum tags. The lifting 𝐷⊥={⊥}∪{↑𝑑∣𝑑∈𝐷} has ⊥⊑𝖣𝑧,↑𝑑⊑𝖣↑𝑑′⟺𝑑⊑𝖣𝑑′.
If 𝐷 and 𝐸 are omega-cpos, then so are 𝐷×𝐸, 𝐷+𝐸, and 𝐷⊥. Their chain lubs are respectively componentwise, within the unique sum tag, and ⨆𝑖𝑧𝑖={⊥,𝑧𝑖=⊥forevery𝑖,↑(⨆𝑖≥𝑗𝑑𝑖),𝑧𝑖=↑𝑑𝑖fromsomestage𝑗. The bottom of a lifting is compact. Compact elements are preserved by pairing, either sum injection, and nonbottom lifting; the element of {∗} and every element of discrete ℕ is compact.
Proof of Lemma 24.14 — Orders used by the recursive equation
Proof. A chain of pairs projects to two chains, and the pair of their lubs has exactly the required upper-bound property. A chain in a separated sum can never change tags: elements with different tags are incomparable. Its lub is therefore the injection of the lub of its payload chain. A lifting chain is either constantly bottom or, after its first nonbottom member, consists of lifted elements; the stated lub equation is then forced by the upper-bound property. These calculations prove the omega-cpo assertions.
For compactness of a pair (𝑐,𝑑), suppose (𝑐,𝑑)⊑𝖣⨆𝑖(𝑥𝑖,𝑦𝑖). By compactness of 𝑐 and 𝑑, choose 𝑟,𝑠 with 𝑐⊑𝖣𝑥𝑟 and 𝑑⊑𝖣𝑦𝑠; the stage max(𝑟,𝑠) contains both observations. The sum and nonbottom-lifting claims reduce to compactness of the payload after the chain has entered the matching tag. Bottom lies below stage zero of every lifting chain. A chain in a discrete poset is constant, so its lub is already one of its members. ◻
If 𝐷 and 𝐸 are omega-cpos, then [𝐷⟶𝐸]𝑐 is an omega-cpo. The least upper bound of a chain (𝑓𝑛) is the pointwise map 𝑓(𝑑)=⨆𝑛𝑓𝑛(𝑑). If 𝐸 is pointed, its constant-bottom map is the least element.
Proof. Pointwise monotonicity of 𝑓 follows from monotonicity of every 𝑓𝑛. For a chain (𝑑𝑚), continuity of the 𝑓𝑛 and monotonicity of the doubly indexed family give 𝑓(⨆𝑚𝑑𝑚)=⨆𝑛𝑓𝑛(⨆𝑚𝑑𝑚)=⨆𝑛⨆𝑚𝑓𝑛(𝑑𝑚)=⨆𝑚⨆𝑛𝑓𝑛(𝑑𝑚)=⨆𝑚𝑓(𝑑𝑚). The middle exchange is valid because both iterated joins are the least upper bound of the same monotone doubly indexed grid: any upper bound of all 𝑓𝑛(𝑑𝑚) bounds either iterated join. Pointwise leastness proves that 𝑓 is the function-space join. The constant-bottom assertion is immediate. ◻
Identity maps and composites of continuous maps are continuous. Finite products of omega-cpos have componentwise lubs; the empty product is the one-point omega-cpo.
Projections are continuous, and continuous 𝑓:𝑃⟶𝐷 and 𝑔:𝑃⟶𝐸 have continuous pairing 𝑝↦(𝑓(𝑝),𝑔(𝑝)).
Evaluation 𝖾𝗏:[𝐷⟶𝐸]𝑐×𝐷⟶𝐸,(𝑓,𝑑)↦𝑓(𝑑), is continuous.
If ℎ:𝑃×𝐷⟶𝐸 is continuous, then every section 𝑑↦ℎ(𝑝,𝑑) is continuous and 𝖼𝗎𝗋𝗋𝗒(ℎ):𝑃⟶[𝐷⟶𝐸]𝑐,𝑝↦(𝑑↦ℎ(𝑝,𝑑)), is continuous.
Proof of Lemma 24.16 — Continuous pairing, evaluation, and currying
Proof. Identities preserve every chain lub. If 𝑓 and 𝑔 are continuous, then 𝑔(𝑓(⨆𝑖𝑑𝑖))=𝑔(⨆𝑖𝑓(𝑑𝑖))=⨆𝑖𝑔(𝑓(𝑑𝑖)), proving closure under composition. Induction on the number of factors, using the binary-product construction of lemma 24.14, gives finite products; the empty case has one element and its only possible order. The same product lub calculation proves item 2 componentwise. For a chain (𝑓𝑖,𝑑𝑖), continuity of each 𝑓𝑖, followed by cofinality of the diagonal in the grid, gives 𝖾𝗏(⨆𝑖(𝑓𝑖,𝑑𝑖))=(⨆𝑖𝑓𝑖)(⨆𝑗𝑑𝑗)=⨆𝑖⨆𝑗𝑓𝑖(𝑑𝑗)=⨆𝑘𝑓𝑘(𝑑𝑘)=⨆𝑘𝖾𝗏(𝑓𝑘,𝑑𝑘). Monotonicity is the same two-coordinate comparison, so evaluation is continuous.
For item 4, fixing one coordinate sends a chain in the other coordinate to a chain in the product, and therefore gives a continuous section. For a chain (𝑝𝑖), pointwise function-space lubs and continuity of ℎ give, for every 𝑑, (⨆𝑖𝖼𝗎𝗋𝗋𝗒(ℎ)(𝑝𝑖))(𝑑)=⨆𝑖ℎ(𝑝𝑖,𝑑)=ℎ(⨆𝑖𝑝𝑖,𝑑). This is the required equality of continuous functions. Monotonicity follows from monotonicity of ℎ. ◻
Let 𝐷 be a pointed omega-cpo and let 𝐹:𝐷⟶𝐷 be continuous. Then lfp(𝐹):=⨆𝑛≥0𝐹𝑛(⊥) is a fixed point of 𝐹, and it lies below every pre-fixed point 𝑑 satisfying 𝐹(𝑑)⊑𝖣𝑑.
Proof. Monotonicity gives the chain ⊥⊑𝖣𝐹⊥⊑𝖣𝐹2⊥⊑𝖣⋯. Continuity and deletion of its first, least member give 𝐹(lfp𝐹)𝑐𝑜𝑛𝑡𝑖𝑛𝑢𝑖𝑡𝑦=⨆𝑛𝐹𝑛+1⊥𝑑𝑒𝑙𝑒𝑡𝑒𝑡ℎ𝑒𝑙𝑒𝑎𝑠𝑡𝑓𝑖𝑟𝑠𝑡𝑚𝑒𝑚𝑏𝑒𝑟=⨆𝑛𝐹𝑛⊥𝑑𝑒𝑓𝑖𝑛𝑖𝑡𝑖𝑜𝑛𝑜𝑓lfp=lfp𝐹. If 𝐹(𝑑)⊑𝖣𝑑, induction gives 𝐹𝑛⊥⊑𝖣𝑑 for every 𝑛: the base uses bottom, and the step uses monotonicity followed by the pre-fixed-point premise. Least-upper-bound minimality then gives lfp𝐹⊑𝖣𝑑. ◻
Knaster–Tarski obtains a least fixed point for a monotone endomap of a complete lattice. Theorem 24.17 assumes only a pointed omega-cpo rather than all joins, pays for that weaker carrier with Scott continuity, and gains the explicit approximation formula ⨆𝑛𝐹𝑛⊥. Only the latter omega-chain construction is used in this chapter.
Let strict multiplication send ⊥ to ⊥, and define the continuous functional on [ℕ⊥⟶ℕ⊥]𝑐 by Φ(𝑓)(⊥)=⊥,Φ(𝑓)(0)=1,Φ(𝑓)(𝑚+1)=(𝑚+1)⋅𝑓(𝑚). Writing ⊥𝑓 for the everywhere-bottom map, its first approximants are 0123Φ0⊥𝑓⊥⊥⊥⊥Φ1⊥𝑓1⊥⊥⊥Φ2⊥𝑓11⊥⊥Φ3⊥𝑓112⊥Φ4⊥𝑓1126 In general Φ𝑛⊥𝑓(𝑚)=𝑚! exactly when 𝑚<𝑛, and is ⊥ otherwise. The pointwise supremum is the total factorial function. This calculation is why the continuous function space is ordered pointwise: each iteration adds one more defined input without changing earlier answers.
Proof of Lemma 24.20 — Continuity of the least-fixed-point operator
Proof. Let 𝐹0⊑𝖣𝐹1⊑𝖣⋯ and put 𝐺=⨆𝑖𝐹𝑖, using the pointwise function-space join of lemma 24.15. For every 𝑛, 𝐺𝑛⊥=⨆𝑖𝐹𝑛𝑖⊥. First, if 𝐹⊑𝖣𝐹′, then 𝐹𝑛⊥⊑𝖣(𝐹′)𝑛⊥ for every 𝑛: induction on 𝑛 uses the pointwise inequality at 𝐹𝑛⊥ and monotonicity of 𝐹′. Hence (𝐹𝑛𝑖⊥)𝑖 is an omega-chain and the displayed lub exists. The displayed equation is proved by induction on 𝑛. The zero case is the constant bottom chain. For the step, continuity of 𝐺 and its pointwise definition give the double join ⨆𝑖⨆𝑗𝐹𝑗(𝐹𝑛𝑖⊥). The diagonal terms 𝐹𝑘(𝐹𝑛𝑘⊥) are cofinal: for any 𝑖,𝑗, take 𝑘≥𝑖,𝑗 and use monotonicity of both the chain of maps and 𝐹𝑘. The double join is therefore ⨆𝑘𝐹𝑛+1𝑘⊥, as required.
Now exchange the two omega-chain joins. Both iterated joins are the least upper bound of the same monotone doubly indexed grid, by the common-upper-bound argument used for function spaces: lfp(𝐺)=⨆𝑛⨆𝑖𝐹𝑛𝑖⊥=⨆𝑖⨆𝑛𝐹𝑛𝑖⊥=⨆𝑖lfp(𝐹𝑖). Thus 𝗅𝖿𝗉𝐷 preserves omega-chain lubs; monotonicity follows from the same iterate comparison. ◻
Let 𝑃 be an omega-cpo, let 𝐷 be a pointed omega-cpo, and let Φ:𝑃×𝐷⟶𝐷 be continuous. For 𝑝∈𝑃, put 𝐹𝑝(𝑑)=Φ(𝑝,𝑑),𝜇Φ(𝑝)=lfp(𝐹𝑝). Then every 𝐹𝑝 is continuous and 𝜇Φ:𝑃⟶𝐷 is continuous.
Proof of Lemma 24.21 — Parameterized least fixed points
Proof. The section 𝐹𝑝 is continuous by lemma 24.16. Monotonicity of 𝜇Φ follows by induction on the Kleene iterates: if 𝑝⊑𝖣𝑞, then 𝐹𝑛𝑝⊥⊑𝖣𝐹𝑛𝑞⊥ for every 𝑛, and taking lubs preserves the inequality.
Let 𝑝0⊑𝖣𝑝1⊑𝖣⋯, put 𝑝=⨆𝑖𝑝𝑖, and write 𝑎𝑖,𝑛=𝐹𝑛𝑝𝑖⊥. Induction on 𝑛 proves 𝐹𝑛𝑝⊥=⨆𝑖𝑎𝑖,𝑛. The zero case is the constant-bottom chain. For the successor case, the pairs (𝑝𝑖,𝑎𝑖,𝑛) form a chain: monotonicity in 𝑖 was proved in the preceding paragraph. Continuity of Φ and the induction hypothesis now give 𝐹𝑛+1𝑝⊥=Φ⎛⎜
⎜
⎜⎝⨆𝑖𝑝𝑖,⨆𝑖𝑎𝑖,𝑛⎞⎟
⎟
⎟⎠=⨆𝑖Φ(𝑝𝑖,𝑎𝑖,𝑛)=⨆𝑖𝑎𝑖,𝑛+1. The family 𝑎𝑖,𝑛 is increasing in both indices. Hence its two iterated lubs are the least upper bound of the same set of elements. Using the displayed equality, 𝜇Φ(𝑝)=⨆𝑛⨆𝑖𝑎𝑖,𝑛=⨆𝑖⨆𝑛𝑎𝑖,𝑛=⨆𝑖𝜇Φ(𝑝𝑖). Thus 𝜇Φ preserves omega-chain lubs and is continuous. ◻
Let 𝐷 be a pointed omega-cpo, let 𝐹:𝐷⟶𝐷 be continuous, and let 𝑃⊆𝐷 contain ⊥, be closed under lubs of omega-chains, and satisfy 𝑑∈𝑃⇒𝐹𝑑∈𝑃. A subset containing bottom and closed under omega-chain lubs is called admissible. Then lfp𝐹∈𝑃.
Proof of Lemma 24.22 — Admissible fixed-point induction
Proof. Induction gives 𝐹𝑛⊥∈𝑃 for every 𝑛. Closure under the chain’s least upper bound gives the conclusion. ◻
Continuity cannot be weakened to monotonicity in Kleene’s calculation. On the chain 0⊑𝖣1⊑𝖣⋯⊑𝖣𝜔, define 𝐻(𝑛)=0(𝑛<𝜔),𝐻(𝜔)=1. This map is monotone, but 𝐻⎛⎜
⎜
⎜⎝⨆𝑛𝑛⎞⎟
⎟
⎟⎠=1≠0=⨆𝑛𝐻(𝑛). Thus the step that moves 𝐹 through the lub genuinely uses continuity.
★★☆ Assume 𝐹(𝑑)=𝑑. Without citing the leastness conclusion of theorem 24.17, prove by induction that 𝐹𝑛⊥⊑𝖣𝑑 for every 𝑛, and then use the defining least-upper-bound property to derive lfp(𝐹)⊑𝖣𝑑. Then find a monotone but discontinuous map on an omega-cpo for which the displayed continuity calculation fails. For the second part, use the chain 0⊑𝖣1⊑𝖣⋯⊑𝖣𝜔 and test whether an input has reached its limit.
Finite eager lists are not closed under chain lubs. Their increasingly defined prefixes form the chain ⊥⊑𝖣𝖼𝗈𝗇𝗌(0,⊥)⊑𝖣𝖼𝗈𝗇𝗌(0,𝖼𝗈𝗇𝗌(0,⊥))⊑𝖣⋯, but no eager finite list is its least upper bound: every finite candidate reveals only a bounded prefix or ends in 𝗇𝗂𝗅. Completing the order forces the infinite all-zero sequence. More generally, compatible prefixes determine one natural number at each revealed position, hence an infinite limit sequence. The carrier must therefore contain finite holed words, finite nil-terminated words, and infinite sequences.
Let L consist of finite natural-number words ending in a hole ⊥, finite words ending in 𝗇𝗂𝗅, and infinite natural-number sequences. Write the first two forms recursively as ⊥, 𝗇𝗂𝗅, and 𝖼𝗈𝗇𝗌(𝑛,𝑑). A finite holed word is below every finite or infinite extension with the same revealed prefix. A finite word ending in 𝗇𝗂𝗅 and an infinite word are comparable only with themselves and their holed prefixes. Equivalently, the order is generated by ⊥⊑𝖣𝑑,𝖼𝗈𝗇𝗌(𝑛,𝑑)⊑𝖣𝖼𝗈𝗇𝗌(𝑛,𝑑′)when𝑑⊑𝖣𝑑′, and contains no further pairs.
For 𝑘∈ℕ, the depth-𝑘 observation is 𝑑↾0=⊥,⊥↾(𝑘+1)=⊥,𝗇𝗂𝗅↾(𝑘+1)=𝗇𝗂𝗅,𝖼𝗈𝗇𝗌(𝑛,𝑑)↾(𝑘+1)=𝖼𝗈𝗇𝗌(𝑛,𝑑↾𝑘). The last clause also defines the finite observation of an infinite sequence.
Proof of Lemma 24.24 — Finite observations determine the partial-list order
Proof. Monotonicity is induction on 𝑘 followed by inspection of the two generating order clauses. A second induction on 𝑘, with a case split on 𝑑, gives 𝑑↾𝑘⊑𝖣𝑑: the successor case applies the induction hypothesis beneath the common 𝖼𝗈𝗇𝗌 head. Transitivity then proves the forward implication.
Conversely, if 𝑑 is finite, choose 𝑘 beyond its last cons cell. Whether 𝑑 ends in 𝗇𝗂𝗅 or in ⊥, one has 𝑑↾𝑘=𝑑, so the hypothesis directly gives 𝑑⊑𝖣𝑢. If 𝑑 is infinite and 𝑢 were finite, choose 𝑘 beyond the final constructor of 𝑢; the longer word 𝑑↾𝑘 could not lie below 𝑢 by either generating order clause. Hence 𝑢 is infinite. For every depth 𝑘, the inequality 𝑑↾𝑘⊑𝖣𝑢 forces the first 𝑘 heads of 𝑢 to equal those of 𝑑. The two infinite sequences therefore have every component equal, so 𝑢=𝑑. ◻
Proof. The hole is least. Let 𝑑0⊑𝖣𝑑1⊑𝖣⋯ be an arbitrary chain. For each fixed 𝑘, there is an index 𝑖𝑘 after which the finite observations 𝑑𝑖↾𝑘 are constant. Prove this by induction on 𝑘. At depth zero there is nothing to prove. At depth 𝑘+1, the chain either remains bottom, reaches 𝗇𝗂𝗅 and stays there, or reaches a first cons. In the cons case all later heads are the same numeral and the tails form a chain, whose depth-𝑘 observations stabilize by induction.
The stable observations are compatible: truncating the stable depth-(𝑘+1) observation gives the stable depth-𝑘 one. If some observation ends in 𝗇𝗂𝗅, the compatible family describes that finite total list. If the number of revealed cons cells is bounded but nil never appears, it describes a finite holed word. Otherwise it describes the unique infinite sequence with those heads. Call the result 𝑑. Every 𝑑𝑖⊑𝖣𝑑, since each finite observation of 𝑑𝑖 occurs in the compatible family. If 𝑢 bounds the chain, monotonicity in lemma 24.24 puts every stable finite observation of 𝑑 below 𝑢; the converse direction of that lemma gives 𝑑⊑𝖣𝑢. Thus 𝑑=⨆𝑖𝑑𝑖. ◻
Proof. Every finite word 𝑐 is compact. If 𝑐⊑𝖣⨆𝑖𝑑𝑖, choose 𝑘 beyond its last cons cell. The construction of the lub makes truncation commute with it at depth 𝑘: for some stabilization stage 𝑗, (⨆𝑖𝑑𝑖)↾𝑘=𝑑𝑗↾𝑘. Since 𝑐=𝑐↾𝑘, monotonicity and lemma 24.24 give the complete chain 𝑐=𝑐↾𝑘⊑𝖣(⨆𝑖𝑑𝑖)↾𝑘=𝑑𝑗↾𝑘⊑𝖣𝑑𝑗. Thus 𝑐 is compact. An infinite 𝑑 is not compact: the increasing chain 𝑑↾0⊑𝖣𝑑↾1⊑𝖣⋯ has lub 𝑑, but 𝑑 lies below no finite member. This proves the compactness classification. ◻
Proof of Lemma 24.27 — The lazy-list unfolding isomorphism
Proof. Define 𝗈𝗎𝗍(⊥)=⊥,𝗂𝗇(⊥)=⊥,𝗈𝗎𝗍(𝗇𝗂𝗅)=↑(𝗂𝗇𝗅∗),𝗂𝗇(↑(𝗂𝗇𝗅∗))=𝗇𝗂𝗅,𝗈𝗎𝗍(𝖼𝗈𝗇𝗌(𝑛,𝑑))=↑(𝗂𝗇𝗋(𝑛,𝑑)),𝗂𝗇(↑(𝗂𝗇𝗋(𝑛,𝑑)))=𝖼𝗈𝗇𝗌(𝑛,𝑑). The target is an omega-cpo by lemma 24.14. The defining clauses show by cases that both maps are monotone and are inverse. An order isomorphism preserves chain lubs: 𝗈𝗎𝗍(⨆𝑖𝑑𝑖) is an upper bound of the 𝗈𝗎𝗍(𝑑𝑖). If 𝑧 is another such upper bound, then 𝗈𝗎𝗍(𝑑𝑖)⊑𝖣𝑧, so monotonicity of 𝗂𝗇 gives 𝑑𝑖=𝗂𝗇(𝗈𝗎𝗍(𝑑𝑖))⊑𝖣𝗂𝗇(𝑧). Hence ⨆𝑖𝑑𝑖⊑𝖣𝗂𝗇(𝑧); applying 𝗈𝗎𝗍 gives 𝗈𝗎𝗍(⨆𝑖𝑑𝑖)⊑𝖣𝑧. The argument for 𝗂𝗇 is symmetric. Hence both maps are continuous and the equation is an isomorphism of pointed omega-cpos, not merely a set bijection. ◻
The poset L is a pointed omega-cpo. Its compact elements are exactly its finite words, whether they end in ⊥ or in 𝗇𝗂𝗅. There are continuous inverse maps L𝗈𝗎𝗍⇄𝗂𝗇({∗}+ℕ×L)⊥.
The compactness classification makes finite observation exact: whenever a finite list prefix lies below the limit of an increasing computation, that entire prefix is already present at one finite stage. This is the order-theoretic form of finite observability for recursive list programs.
For a closed 𝖫𝗂𝗌𝗍𝖭𝖺𝗍 value, the operational embedding is 𝜄(𝗇𝗂𝗅)=𝗇𝗂𝗅,𝜄(𝖼𝖾𝗅𝗅(𝑛,𝑣))=𝖼𝗈𝗇𝗌(𝑛,𝜄(𝑣)). On unfolded payload values, put 𝜄+(𝗂𝗇𝗅𝗎𝗇𝗂𝗍)=𝗂𝗇𝗅∗,𝜄+(𝗂𝗇𝗋⟨𝑛,𝑣⟩)=𝗂𝗇𝗋(𝑛,𝜄(𝑣)). Recall that ↑ is the nonbottom injection into a lifting; here its codomain is the lifted sum.
If ⋅⊢𝑣:𝖫𝗂𝗌𝗍𝖭𝖺𝗍 is a value and 𝗎𝗇𝖿𝗈𝗅𝖽𝑣⟼𝑝, then 𝜄(𝑣) is a hole-free finite compact element of L and 𝗈𝗎𝗍(𝜄(𝑣))=↑𝜄+(𝑝). Conversely, every hole-free finite element of L is 𝜄(𝑣) for a unique canonical list value 𝑣.
Proof of Proposition 24.29 — Finite operational lists commute with out
Proof. Folded canonical forms write 𝑣=𝖿𝗈𝗅𝖽𝖫𝗂𝗌𝗍𝖭𝖺𝗍𝑝. Sum and product canonical forms give either 𝑝=𝗂𝗇𝗅𝗎𝗇𝗂𝗍 or 𝑝=𝗂𝗇𝗋⟨𝑛,𝑣′⟩ with 𝑣′:𝖫𝗂𝗌𝗍𝖭𝖺𝗍. Rule E-UnfoldFold yields 𝑝, and the defining clause of 𝗈𝗎𝗍 gives the equation in either case. Induction on the finite payload tree shows that 𝜄(𝑣) has no hole. It is compact by proposition 24.28. The same induction reconstructs the unique nested fold/injection syntax from a hole-free finite domain list. Infinite and holed elements are deliberately outside this correspondence. ◻
The chain ⊥⊑𝖣𝖼𝗈𝗇𝗌(0,⊥)⊑𝖣𝖼𝗈𝗇𝗌(0,𝖼𝗈𝗇𝗌(0,⊥))⊑𝖣⋯ has the infinite all-zero list as its lub. Consequently L is not the set of eager finite 𝖫𝗂𝗌𝗍𝖭𝖺𝗍 values from the opening calculus. The two objects solve related equations for different purposes.
★★★ Prove directly that 𝗈𝗎𝗍 preserves the displayed all-zero chain’s lub. Then classify chains that reveal 𝗇𝗂𝗅 at a finite stage, and use the classification to give an alternative, clause-by-clause proof of continuity of 𝗂𝗇, rather than reusing the order-isomorphism argument in proposition 24.28.
Interpret ℕ by ℕ⊥ and arrows by continuous function spaces: [[ℕ]]=ℕ⊥,[[𝐴→𝐵]]=[[[𝐴]]⟶[[𝐵]]]𝑐. Induction on 𝐴, using lemma 24.15 at arrows, proves that every [[𝐴]] is a pointed omega-cpo. For Γ=𝑥1:𝐴1,…,𝑥𝑟:𝐴𝑟, put [[Γ]]=𝑟∏𝑖=1[[𝐴𝑖]] with the componentwise order. An environment 𝜂 is an element of this finite product.
A map of pointed omega-cpos is strict when it preserves bottom. Fix a pointed omega-cpo 𝐷. Define 𝗌𝗎𝖼𝖼⊥(⊥)=⊥,𝗌𝗎𝖼𝖼⊥(𝑛)=𝑛+1,𝖼𝖺𝗌𝖾𝐷(⊥,𝑑,ℎ)=⊥𝐷,𝖼𝖺𝗌𝖾𝐷(0,𝑑,ℎ)=𝑑,𝖼𝖺𝗌𝖾𝐷(𝑛+1,𝑑,ℎ)=ℎ(𝑛). Here 𝖼𝖺𝗌𝖾𝐷:ℕ⊥×𝐷×[ℕ⊥⟶𝐷]𝑐⟶𝐷. At a successor 𝑛+1, the third argument receives its predecessor 𝑛.
Proof of Lemma 24.31 — Continuity of the strict natural operations
Proof. A chain in ℕ⊥ either remains bottom or reaches one numeral and is constant thereafter. In the first case the defining strictness equation sends every chain member to bottom. In the second, there are 𝑖,𝑛 such that every image member from index 𝑖 onward is 𝗌𝗎𝖼𝖼(𝑛), which is its lub.
For a chain (𝑠𝑖,𝑑𝑖,ℎ𝑖), if every 𝑠𝑖=⊥, both sides of the continuity equation for 𝖼𝖺𝗌𝖾𝐷 are bottom. Otherwise the scrutinee is a fixed numeral from some stage onward. At zero, the result tail is (𝑑𝑖) and has lub ⨆𝑖𝑑𝑖. At 𝑛+1, the result tail is (ℎ𝑖(𝑛)); the pointwise-lub clause of lemma 24.15 states ⨆𝑖ℎ𝑖(𝑛)=(⨆𝑖ℎ𝑖)(𝑛). These are exactly the zero and successor clauses at the componentwise lub. The same cases prove monotonicity. ◻
Define the interpretation simultaneously by the following clauses. Lemma 24.33 proves that the lambda and fixed-point clauses land in the indicated continuous function spaces. [[𝑥]]𝜂=𝜂(𝑥),[[𝑛]]𝜂=𝑛,[[𝜆𝑥:𝐴.𝑒]]𝜂=(𝑑↦[[𝑒]]𝜂[𝑥↦𝑑]),[[𝑒1𝑒2]]𝜂=[[𝑒1]]𝜂([[𝑒2]]𝜂),[[𝗌𝗎𝖼𝖼𝑒]]𝜂=𝗌𝗎𝖼𝖼⊥([[𝑒]]𝜂),[[𝗂𝖿𝗓𝑒𝗍𝗁𝖾𝗇𝑒0𝖾𝗅𝗌𝖾𝑥.𝑒𝑠]]𝜂=𝖼𝖺𝗌𝖾[[𝐴]]([[𝑒]]𝜂,[[𝑒0]]𝜂,𝑑↦[[𝑒𝑠]]𝜂[𝑥↦𝑑]),[[𝖿𝗂𝗑𝑥:𝐴.𝑒]]𝜂=lfp(𝑑↦[[𝑒]]𝜂[𝑥↦𝑑]). In the zero-test clause, 𝐴 is the common type of the two branches.
Give the environments for a finite context Γ the pointwise omega-cpo structure. If Γ⊢𝑒:𝐴, then 𝜂↦[[𝑒]]𝜂 is a continuous map from the environment cpo into [[𝐴]]. In particular every clause of definition 24.32 is well defined.
Proof of Lemma 24.33 — Semantic typing and continuity
Proof. Identify [[Γ,𝑥:𝐴]] with [[Γ]]×[[𝐴]]; environment extension is this product pairing. Induct on the typing derivation. Variables are projections and numerals are constant maps.
For abstraction, the body induction hypothesis is a continuous map ℎ:[[Γ]]×[[𝐴]]⟶[[𝐵]]. Its curry is continuous by lemma 24.16, and is exactly the stated lambda clause. For application, pair the two continuous induction hypotheses and compose with continuous evaluation from the same lemma.
For successor, compose with 𝗌𝗎𝖼𝖼⊥. For a zero test, the three induction hypotheses give continuous maps for the scrutinee, the zero branch, and the successor body. Curry the successor-body map to obtain 𝜂↦(𝑑↦[[𝑒𝑠]]𝜂[𝑥↦𝑑]). Pair these three maps and compose with 𝖼𝖺𝗌𝖾[[𝐴]], which is continuous by lemma 24.31.
In P-Fix the body induction hypothesis gives a continuous map Φ:[[Γ]]×[[𝐴]]⟶[[𝐴]],Φ(𝜂,𝑑)=[[𝑒]]𝜂[𝑥↦𝑑]. The fixed-point clause is the parameterized map 𝜂↦lfp(𝑑↦Φ(𝜂,𝑑)), continuous by lemma 24.21. Hence each typing rule determines a well-defined continuous denotation of its conclusion. ◻
Proof of Lemma 24.34 — Semantic substitution and reduction invariance
Proof. The first claim is induction on 𝑒, alpha-renaming the lambda, predecessor, and fixed-point binders. In the fixed-point case choose the recursive binder 𝑦∉FV(𝑑)∪{𝑥}; the denotation of 𝑑 is then unchanged when the environment is extended at 𝑦. The two continuous functionals are pointwise equal by the induction hypothesis, so their Kleene chains and least fixed points coincide.
For reduction invariance, inspect the five roots. Beta and the successor branch of the zero test use semantic substitution. Zero and successor compute by the defining clauses of 𝖼𝖺𝗌𝖾𝐷. For P-Unroll, fixedness from theorem 24.17 gives lfp𝐹=𝐹(lfp𝐹)=[[𝑒[𝖿𝗂𝗑𝑥:𝐴.𝑒/𝑥]]]𝜂. Context cases follow from compositionality. ◻
For a closed term, write [[𝑒]] for its denotation at the unique empty environment. Operational convergence implies the expected denotation: if 𝑒⇓𝑛, repeated use of reduction invariance gives [[𝑒]]=𝑛. The converse is the substantive direction. A denotation could otherwise predict a numeral that no evaluation reaches.
Adequacy by logical approximation
A family of relations defined by recursion on types, with the arrow case testing all related arguments, is called logical. Here it connects semantic approximations to operational programs. Typing preserves this connection, and its instance at ℕ turns a numeral denotation into an operational evaluation to that numeral.
Bare induction on the typing derivation is too weak at application. Separate hypotheses saying only that 𝑒1 and 𝑒2 approximate their denotations do not say how the denotation of 𝑒1 acts on the argument denotation: 𝑑1𝑅𝐴→𝐵𝑒1,𝑑2𝑅𝐴𝑒2⟹̸𝑑1(𝑑2)𝑅𝐵𝑒1𝑒2 for an unstructured family 𝑅. The repair is to define the arrow clause by testing every related argument. The fixpoint proof also begins at bottom, so ⊥ must relate to every natural-number computation.
Proof. Induct on 𝐴. At naturals, compose the prefix 𝑒⟼∗𝑒′ with the reduction required by the relation: if 𝑑=𝑛, then 𝑒′⇓𝑛, hence 𝑒⇓𝑛; the bottom case is immediate. At an arrow 𝐴=𝐶→𝐵, for arbitrary 𝑑0R𝐶𝑎, lift 𝑒⟼∗𝑒′ to 𝑒𝑎⟼∗𝑒′𝑎 and apply the codomain induction hypothesis to 𝑑(𝑑0)R𝐵𝑒′𝑎. ◻
Proof of Lemma 24.37 — Admissibility of logical approximation
Proof. Induct on 𝐴. At ℕ, bottom is related by definition. If ⨆𝑖𝑑𝑖=𝑛, flatness implies that some 𝑑𝑗=𝑛; otherwise every member would be bottom and so would the lub. The premise for 𝑑𝑗 gives 𝑒⇓𝑛.
At 𝐴→𝐵, bottom is the constant-bottom map and the induction hypothesis at 𝐵 gives ⊥R𝐵𝑒𝑎 for every 𝑑R𝐴𝑎. For a chain (𝑓𝑖), take arbitrary 𝑑R𝐴𝑎. The sequence (𝑓𝑖(𝑑)) is a chain, each member is related to 𝑒𝑎, and the codomain induction hypothesis gives ⨆𝑖𝑓𝑖(𝑑)R𝐵𝑒𝑎. Pointwise function-space lubs satisfy ⨆𝑖𝑓𝑖(𝑑)=(⨆𝑖𝑓𝑖)(𝑑). ◻
An environment 𝜂 and a closing substitution 𝛾 are related at Γ, written 𝜂RΓ𝛾, when 𝜂(𝑥)R𝐴𝛾(𝑥) for every 𝑥:𝐴∈Γ.
Proof of Theorem 24.38 — Fundamental approximation
Proof. Induct on the typing derivation. For a variable 𝑥, the premise is 𝜂(𝑥)R𝐴𝛾(𝑥); a numeral evaluates to itself. In an application, the operator induction hypothesis is quantified over every related argument, so instantiate it with the argument induction hypothesis. For lambda, take arbitrary 𝑑R𝐴𝑎, extend both environments by 𝑥↦𝑑 and 𝑥↦𝑎, and apply the body induction hypothesis to the closed body. The beta step (𝜆𝑥.𝑒[𝛾])𝑎⟼𝑒[𝛾,𝑎/𝑥] and lemma 24.36 give the arrow clause.
For successor, the bottom semantic case is immediate. In the numeral case, the scrutinee induction hypothesis gives evaluation to 𝑛, after which P-SuccN gives 𝑛+1. The zero-test case splits the semantic scrutinee. At bottom, the conclusion follows uniformly because bottom is related at every type by lemma 24.37. At zero use the first branch induction hypothesis and P-IfZ; at 𝑛+1, extend the environments by the related predecessor 𝑛 and use P-IfS.
For P-Fix, let 𝐹(𝑑)=[[𝑒]]𝜂[𝑥↦𝑑],𝑞=𝖿𝗂𝗑𝑥:𝐴.𝑒[𝛾]. We prove 𝐹𝑘⊥R𝐴𝑞 by induction on 𝑘. The base is bottom. For the step, extend the semantic environment by 𝑥↦𝐹𝑘⊥ and the term substitution by 𝑥↦𝑞. The body induction hypothesis gives 𝐹𝑘+1⊥R𝐴𝑒[𝛾,𝑞/𝑥]. Rule P-Unroll takes 𝑞 to that term, so anti-reduction relates the same element to 𝑞. Finally, lemma 24.37 closes the chain and relates ⨆𝑘𝐹𝑘⊥=lfp𝐹 to 𝑞. This is the only place where ordinary induction on term syntax is insufficient; admissibility turns all finite unfoldings into the recursive result. ◻
Proof of Theorem 24.39 — Computational adequacy for closed naturals
Proof. For (⇒), use lemma 24.34’s reduction-invariance clause along every step of 𝑒⟼∗𝑛, obtaining [[𝑒]]=[[𝑛]]=𝑛. For (⇐), use the fundamental approximation theorem, theorem 24.38, with empty environments. If the denotation is 𝑛, the base clause is exactly 𝑛Rℕ𝑒⟺𝑒⇓𝑛.
By lemma 24.12, a closed natural term either evaluates to a unique numeral or has an infinite reduction. The established equivalence is [[𝑒]]=𝑛⟺𝑒⇓𝑛. Since every element of ℕ⊥ is ⊥ or a numeral, [[𝑒]]=⊥ is therefore equivalent to 𝑒⟼𝜔. ◻
★★☆ Reprove only the P-Fix case of theorem 24.38. State the relation between the semantic and term environments at each finite iterate, identify the use of anti-reduction, and name the admissibility hypothesis used at the limit.
Recursive reasoning one finite observation at a time
The denotational proof handles a fixed point by finite approximants. The same well-founded idea can compare values at a recursive type directly. A naive definition 𝖿𝗈𝗅𝖽𝑣≈𝜇𝑋.𝐴𝖿𝗈𝗅𝖽𝑤iff𝑣≈𝐴[𝜇𝑋.𝐴/𝑋]𝑤 is circular. An observation index changes the recursive call from 𝑛+1 to 𝑛.
Step-indexed equivalence uses the eager fold calculus without Booleans. The retained terms are variables, unit, numerals, lambdas and application, pairs and projections, sums and case, and fold and unfold. Their evaluation contexts are 𝐾::=[]∣𝐾𝑒∣𝑣𝐾∣⟨𝐾,𝑒⟩∣⟨𝑣,𝐾⟩∣𝖿𝗌𝗍𝐾∣𝗌𝗇𝖽𝐾∣𝗂𝗇𝗅𝐾∣𝗂𝗇𝗋𝐾∣𝖼𝖺𝗌𝖾𝐾𝗈𝖿{𝗂𝗇𝗅𝑥↦𝑒0;𝗂𝗇𝗋𝑦↦𝑒1}∣𝖿𝗈𝗅𝖽𝜇𝑋.𝐴𝐾∣𝗎𝗇𝖿𝗈𝗅𝖽𝐾. The root contractions are call-by-value beta, the two projections, the two sum cases, and E-UnfoldFold. These contexts evaluate an application operator, then its argument, and then contract beta.
For closed, equally typed terms of the fragment in convention 24.40, define value relations 𝑣≈𝐴𝑛𝑤 and term relations 𝑒E𝐴𝑛𝑑 simultaneously. At index zero every pair of closed well-typed values is related. At 𝑛+1, the value clauses are 𝗎𝗇𝗂𝗍≈𝟏𝑛+1𝗎𝗇𝗂𝗍always,𝑘≈ℕ𝑛+1ℓ⟺𝑘=ℓ,⟨𝑣1,𝑣2⟩≈𝐴×𝐵𝑛+1⟨𝑤1,𝑤2⟩⟺𝑣1≈𝐴𝑛+1𝑤1and𝑣2≈𝐵𝑛+1𝑤2,𝗂𝗇𝗅𝑣≈𝐴+𝐵𝑛+1𝗂𝗇𝗅𝑤⟺𝑣≈𝐴𝑛+1𝑤,𝗂𝗇𝗋𝑣≈𝐴+𝐵𝑛+1𝗂𝗇𝗋𝑤⟺𝑣≈𝐵𝑛+1𝑤. Values with different sum tags are not related. At arrows, 𝑓≈𝐴→𝐵𝑛+1𝑔 when for every 𝑗≤𝑛+1 and 𝑣≈𝐴𝑗𝑤, 𝑓𝑣E𝐵𝑗𝑔𝑤. The only circular-looking clause consumes an index: 𝖿𝗈𝗅𝖽𝜇𝑋.𝐴𝑣≈𝜇𝑋.𝐴𝑛+1𝖿𝗈𝗅𝖽𝜇𝑋.𝐴𝑤⟺𝑣≈𝐴[𝜇𝑋.𝐴/𝑋]𝑛𝑤. To verify that the simultaneous definition is well founded, let |𝐴| count one node for each base or type constructor: |ℕ|=|𝟏|=|𝑋|=1,|𝐴∘𝐵|=1+|𝐴|+|𝐵|(∘∈{→,×,+}),|𝜇𝑋.𝐴|=1+|𝐴|. Put 𝜌=0 for value relations and 𝜌=1 for term relations. Order recursive calls lexicographically by (𝑛,|𝐴|,𝜌). The recursive-type clause changes 𝑛+1 to 𝑛. In the arrow clause, a test at 𝑗<𝑛+1 lowers the index; a test at 𝑗=𝑛+1 recurses on the proper component 𝐴 or 𝐵. At a zero-step endpoint, the term relation calls the value relation at the same index and type, which lowers the phase. Thus every recursive call strictly decreases the lexicographic measure. The quantifier 𝑗≤𝑛+1 ranges over every smaller observation index required by the arrow clause.
Write 𝑒⟼𝑗𝑣 for exactly 𝑗 steps to a value. Then 𝑒E𝐴𝑛𝑑 iff both of the following hold for every 𝑗<𝑛: 𝑒⟼𝑗𝑣⟹∃𝑤.𝑑⟼∗𝑤and𝑣≈𝐴𝑛−𝑗𝑤,𝑑⟼𝑗𝑤⟹∃𝑣.𝑒⟼∗𝑣and𝑣≈𝐴𝑛−𝑗𝑤. All quantified endpoints 𝑣,𝑤 are values. For a context Γ, write 𝛾≈Γ𝑛𝛿 when the two closing substitutions map every 𝑥:𝐴∈Γ to values related by ≈𝐴𝑛.
Every closed, well-typed nonvalue in the indexed fragment has a unique decomposition 𝐾[𝑟], where 𝐾 is an evaluation context from convention 24.40 and 𝑟 is one of that convention’s root redexes. Consequently it has exactly one one-step reduct.
Proof of Lemma 24.42 — Unique indexed decomposition
Proof. Proceed by the outer syntax. An application first selects a nonvalue operator, then a nonvalue argument once the operator is a value, and otherwise has a beta root; closed canonical forms force an arrow-typed operator value to be a lambda. A pair selects its left component before its right. A projection or case selects only its scrutinee; once that scrutinee is a value, product or sum canonical forms select exactly one root rule. Injections, folds, and unfolds each select their sole payload, except that an unfold of a folded value is the E-UnfoldFold root. These cases are disjoint, and the induction hypothesis makes the selected subterm decomposition unique. Existence is the progress clause of theorem 24.5; disjoint context positions and root patterns supply uniqueness. ◻
Reduction in the indexed fragment is deterministic. Every terminating trace has the decomposition forced by its outer constructor. In particular:
if 𝑒1𝑒2⟼𝑟𝑣, then uniquely 𝑒1⟼𝑟1𝜆𝑥:𝐴.𝑏,𝑒2⟼𝑟2𝑢,𝑏[𝑢/𝑥]⟼𝑟3𝑣,𝑟=𝑟1+𝑟2+1+𝑟3;
a trace from ⟨𝑒1,𝑒2⟩ to a value consists of 𝑒1⟼𝑟1𝑣1, followed by 𝑒2⟼𝑟2𝑣2, and has length 𝑟1+𝑟2;
a projection trace first reaches a pair and then takes its one root step; a sum-case trace first reaches one injection, takes its one root step, and continues in the selected substituted branch;
a fold trace evaluates only its payload, while an unfold trace first reaches a folded value and then takes its one E-UnfoldFold step.
Injection traces have the same one-payload form as folds.
Proof of Lemma 24.43 — Terminating-trace decomposition
Proof. One-step reduction is deterministic by lemma 24.42. Induct on the length of a terminating trace. For an application, steps stay in the operator until it is a lambda, then stay in the argument until it is a value, then take the unique beta step; all remaining steps are in the substituted body. This gives item 1 and its length equation. Pair contexts first select the left component and then the right, giving item 2. Projection and case contexts select only the scrutinee before their root step, while fold, unfold, and injection contexts select only their payload. The grammar of convention 24.40 assigns each constructor exactly one of these decompositions. ◻
Proof of Lemma 24.44 — Indexed downward closure and anti-reduction
Proof.Downward closure. For downward closure, use the lexicographic measure (𝑛,|𝐴|,𝜌) established in definition 24.41, with value phase 𝜌=0 and term phase 𝜌=1. Products and sums recurse on proper component types. At a recursive type, the payload relation is at the smaller index. At an arrow, every test index allowed at 𝑚 is already allowed at 𝑛. For terms, 𝑗<𝑚 implies 𝑗<𝑛, and downward closure of values changes the residual relation from 𝑛−𝑗 to 𝑚−𝑗.
Values and anti-reduction. At index zero the term relation is vacuous. At a positive index a value has only its zero-step terminating trace, so 𝑣≈𝐴𝑛𝑤 gives 𝑣E𝐴𝑛𝑤.
For anti-reduction, suppose 𝑒⟼𝑟𝑒′ and 𝑒⟼𝑗𝑣, where 𝑗<𝑛. Determinism from lemma 24.43 gives 𝑗≥𝑟 and 𝑒′⟼𝑗−𝑟𝑣. From 𝑒′E𝐴𝑛𝑑′, obtain a value reachable from 𝑑′ and related to 𝑣 at index 𝑛−(𝑗−𝑟). Downward closure changes that index to 𝑛−𝑗, and the prefix 𝑑⟼∗𝑑′ gives the required trace from 𝑑. Interchanging the two terms proves the other observation clause. ◻
Proof. Use downward closure, value inclusion, and anti-reduction from lemma 24.44. The only budget calculation not immediate from a constructor is application.
Application budget. Suppose a left application reaches a value in 𝑟<𝑛 steps. Its unique trace decomposition has lengths 𝑟=𝑟1+𝑟2+1+𝑟3 for operator evaluation, argument evaluation, beta, and body evaluation. By the first implication in the operator term relation, the right operator reaches a lambda related to the left lambda at 𝑞=𝑛−𝑟1. Since 𝑟2+1+𝑟3<𝑞, the first implication in the argument term relation gives a reachable right argument value; downward closure relates the argument values at 𝑠=𝑞−𝑟2. The arrow clause at 𝑞 applies at 𝑠≤𝑞. The left beta redex then takes 1+𝑟3<𝑠 steps, leaving the result index 𝑠−(1+𝑟3)=𝑛−𝑟. Thus 𝑟=𝑟1+𝑟2+1+𝑟3<𝑛,𝑞=𝑛−𝑟1,𝑠=𝑞−𝑟2,1+𝑟3<𝑠≤𝑞,𝑠−(1+𝑟3)=𝑛−𝑟. Prepending the matching operator and argument traces gives the right application trace. The symmetric calculation gives the other observation clause.
Other constructors. For a pair trace of length 𝑟1+𝑟2<𝑛, the first component is matched at 𝑛−𝑟1, then lowered to 𝑛−𝑟1−𝑟2; the second is matched directly at that final index. The product value clause combines them. An injection is the one-component calculation. A fold payload matched at 𝑛−𝑟>0 is lowered once for the recursive-value clause; at index zero every pair of folded values is related.
A projection or unfold spends one root step after its scrutinee trace. If the scrutinees are pairs related at 𝑞, their selected components are related at 𝑞, hence at 𝑞−1 by downward closure. If they are folds related at 𝑞, the recursive-value clause relates their payloads at 𝑞−1. A case trace spends its root step and then 𝑟𝑏 steps in a branch. Matching injections have payloads related at 𝑞; downward closure derives their relation at 𝑞−1, and the branch relation leaves 𝑞−1−𝑟𝑏, the index required by the whole trace. Each calculation is symmetric in the two terms.
Related substitution. For related substitution, induct on typing with the index universally quantified in every induction hypothesis. A variable selects its related pair from 𝛾≈Γ𝑛𝛿; unit and numerals are related values. Applying the product, sum, fold/unfold, projection, and application budget equations to the corresponding induction hypotheses derives their term relations at index 𝑛.
For a lambda at index 𝑛+1, choose 𝑗≤𝑛+1 and values 𝑣≈𝐴𝑗𝑤. Downward closure derives 𝛾≈Γ𝑗𝛿; extending by 𝑥↦𝑣 and 𝑥↦𝑤 gives related substitutions for the body, whose induction hypothesis relates the two closed bodies at 𝑗. The use is valid even when 𝑗=𝑛+1: the induction decreases the body typing derivation, not the index. One beta step on each side and anti-reduction therefore relate the applications at 𝑗, which is the arrow value clause. Value inclusion gives the required term relation.
For a sum case, the scrutinee calculation gives equal injection tags and a payload relation at the remaining index. Extending the substitutions by those payloads satisfies the selected branch hypothesis; one case root step and anti-reduction give the required term relation. The unselected branch is not evaluated. ◻
Proof of Lemma 24.46 — Indexed evaluation-context compatibility
Proof.Evaluation contexts. For evaluation contexts, induct on 𝐾. The hole is the identity case. In 𝐾𝑒0 and 𝑣𝐾, the fixed operand is self-related by lemma 24.45, and the application calculation composes it with the hole relation. Pair, injection, and fold contexts use their payload calculations; projection and unfold use their one-scrutinee calculations. A case context uses the case calculation with each fixed branch self-related under its payload binder. Thus every context constructor composes the hole relation without changing the outer index 𝑛. ◻
For types 𝐴,𝐵, put 𝑅𝐴,𝐵:=𝜇𝑋.(𝑋→𝐴→𝐵),𝜃𝑓:=𝜆𝑥:𝑅𝐴,𝐵.𝜆𝑦:𝐴.𝑓((𝗎𝗇𝖿𝗈𝗅𝖽𝑥)𝑥)𝑦,𝖹𝐴,𝐵:=𝜆𝑓:(𝐴→𝐵)→𝐴→𝐵.𝜃𝑓(𝖿𝗈𝗅𝖽𝑅𝐴,𝐵𝜃𝑓). Thus 𝖹𝐴,𝐵:((𝐴→𝐵)→𝐴→𝐵)→𝐴→𝐵. For a closed value 𝑓, evaluation of 𝖹𝐴,𝐵𝑓 reaches a lambda before evaluating its recursive call: 𝖹𝐴,𝐵𝑓⟼∗𝜆𝑦:𝐴.𝑓((𝗎𝗇𝖿𝗈𝗅𝖽(𝖿𝗈𝗅𝖽𝜃𝑓))(𝖿𝗈𝗅𝖽𝜃𝑓))𝑦. When evaluation of the body demands the recursive function, the parenthesized term takes two steps back to the same lambda. Eta-delay, absent from 𝖥𝗂𝗑𝐴, is the load-bearing call-by-value repair.
Let 𝑓:(𝐴→𝐵)→𝐴→𝐵 and 𝑎:𝐴 be closed values. Then 𝖹𝐴,𝐵𝑓𝑎and𝑓(𝖹𝐴,𝐵𝑓)𝑎 reduce to a common term. At function type the corresponding contextual-equivalence statement can fail.
Proof of Proposition 24.49 — The eta-delayed equation is pointwise
Proof. Put ℎ=𝖿𝗈𝗅𝖽𝑅𝐴,𝐵𝜃𝑓 and 𝑔=𝜆𝑦:𝐴.𝑓((𝗎𝗇𝖿𝗈𝗅𝖽ℎ)ℎ)𝑦. Then 𝖹𝐴,𝐵𝑓⟼∗𝑔,(𝗎𝗇𝖿𝗈𝗅𝖽ℎ)ℎ⟼2𝑔. The left term reduces through 𝑔𝑎, then uses (𝗎𝗇𝖿𝗈𝗅𝖽ℎ)ℎ⟼2𝑔 to reach 𝑓𝑔𝑎. The right term first evaluates its argument 𝖹𝐴,𝐵𝑓 to 𝑔, and reaches the same term.
For the qualification, recall the two-step loop at an arbitrary type: 𝐷𝐶=𝜇𝑋.(𝑋→𝐶),𝛿𝐶=𝜆𝑥:𝐷𝐶.(𝗎𝗇𝖿𝗈𝗅𝖽𝑥)𝑥,Ω𝐶=𝛿𝐶(𝖿𝗈𝗅𝖽𝐷𝐶𝛿𝐶):𝐶. Take 𝐶=𝐴→𝐵 and 𝑓=𝜆𝑐:𝐴→𝐵.Ω𝐶. Then 𝖹𝐴,𝐵𝑓 reaches the value 𝑔, while 𝑓(𝖹𝐴,𝐵𝑓) reaches Ω𝐶 and diverges. The closing context (𝜆ℎ:𝐴→𝐵.0)[−] evaluates its hole under call by value, so it distinguishes the two function terms. ◻
Define a recursive list copier inside the eager calculus by 𝖼𝗈𝗉𝗒:=𝜃𝖼𝗈𝗉𝗒𝖡𝗈𝖽𝗒(𝖿𝗈𝗅𝖽𝑅𝖫𝗂𝗌𝗍𝖭𝖺𝗍,𝖫𝗂𝗌𝗍𝖭𝖺𝗍𝜃𝖼𝗈𝗉𝗒𝖡𝗈𝖽𝗒),𝖼𝗈𝗉𝗒𝖡𝗈𝖽𝗒:=𝜆𝑐:𝖫𝗂𝗌𝗍𝖭𝖺𝗍→𝖫𝗂𝗌𝗍𝖭𝖺𝗍.𝜆𝑥𝑠:𝖫𝗂𝗌𝗍𝖭𝖺𝗍.𝖼𝖺𝗌𝖾𝖫𝗂𝗌𝗍𝑥𝑠𝗈𝖿{𝗇𝗂𝗅↦𝗇𝗂𝗅;𝖼𝗈𝗇𝗌(𝑛,𝑦𝑠)↦𝖼𝗈𝗇𝗌𝑛(𝑐𝑦𝑠)}. This is the first beta reduct of 𝖹𝖫𝗂𝗌𝗍𝖭𝖺𝗍,𝖫𝗂𝗌𝗍𝖭𝖺𝗍𝖼𝗈𝗉𝗒𝖡𝗈𝖽𝗒; in the cons branch, 𝑛:ℕ and 𝑦𝑠:𝖫𝗂𝗌𝗍𝖭𝖺𝗍.
Proof of Lemma 24.50 — Structural convergence of the copier
Proof. Write 𝜃=𝜃𝖼𝗈𝗉𝗒𝖡𝗈𝖽𝗒,ℎ=𝖿𝗈𝗅𝖽𝑅𝖫𝗂𝗌𝗍𝖭𝖺𝗍,𝖫𝗂𝗌𝗍𝖭𝖺𝗍𝜃,𝑟=(𝗎𝗇𝖿𝗈𝗅𝖽ℎ)ℎ, and put 𝑔=𝜆𝑥𝑠:𝖫𝗂𝗌𝗍𝖭𝖺𝗍.𝖼𝗈𝗉𝗒𝖡𝗈𝖽𝗒𝑟𝑥𝑠. Abbreviate the body after its two binders by 𝐶(𝑐,𝑥𝑠):=𝖼𝖺𝗌𝖾𝖫𝗂𝗌𝗍𝑥𝑠𝗈𝖿{𝗇𝗂𝗅↦𝗇𝗂𝗅;𝖼𝗈𝗇𝗌(𝑛,𝑦𝑠)↦𝖼𝗈𝗇𝗌𝑛(𝑐𝑦𝑠)}. The recursive argument has the two explicit steps 𝑟=(𝗎𝗇𝖿𝗈𝗅𝖽ℎ)ℎ𝐸−𝑈𝑛𝑓𝑜𝑙𝑑𝐹𝑜𝑙𝑑⟼𝜃ℎ𝛽⟼𝑔,𝖼𝗈𝗉𝗒=𝜃ℎ𝛽⟼𝑔.
We prove 𝑔𝑣⟼∗𝑣 by structural induction on the canonical list value 𝑣. Folded, sum, and product canonical forms give 𝗇𝗂𝗅 or 𝖼𝖾𝗅𝗅(𝑘,𝑦𝑠). The nil trace is 𝑔𝗇𝗂𝗅𝛽⟼𝖼𝗈𝗉𝗒𝖡𝗈𝖽𝗒𝑟𝗇𝗂𝗅𝐸−𝑈𝑛𝑓𝑜𝑙𝑑𝐹𝑜𝑙𝑑⟼𝖼𝗈𝗉𝗒𝖡𝗈𝖽𝗒(𝜃ℎ)𝗇𝗂𝗅𝛽⟼𝖼𝗈𝗉𝗒𝖡𝗈𝖽𝗒𝑔𝗇𝗂𝗅𝛽⟼(𝜆𝑥𝑠.𝐶(𝑔,𝑥𝑠))𝗇𝗂𝗅𝛽⟼𝐶(𝑔,𝗇𝗂𝗅)=𝖼𝖺𝗌𝖾(𝗎𝗇𝖿𝗈𝗅𝖽(𝖿𝗈𝗅𝖽𝖫𝗂𝗌𝗍𝖭𝖺𝗍(𝗂𝗇𝗅𝗎𝗇𝗂𝗍));𝑢.𝗇𝗂𝗅;𝑧.𝖼𝗈𝗇𝗌(𝖿𝗌𝗍𝑧)(𝑔(𝗌𝗇𝖽𝑧)))𝐸−𝑈𝑛𝑓𝑜𝑙𝑑𝐹𝑜𝑙𝑑⟼𝖼𝖺𝗌𝖾(𝗂𝗇𝗅𝗎𝗇𝗂𝗍;𝑢.𝗇𝗂𝗅;𝑧.𝖼𝗈𝗇𝗌(𝖿𝗌𝗍𝑧)(𝑔(𝗌𝗇𝖽𝑧)))𝑙𝑒𝑓𝑡𝑠𝑢𝑚−𝛽⟼𝗇𝗂𝗅. For 𝑝=⟨𝑘,𝑦𝑠⟩, the cons prefix is 𝑔𝖼𝖾𝗅𝗅(𝑘,𝑦𝑠)𝛽⟼𝖼𝗈𝗉𝗒𝖡𝗈𝖽𝗒𝑟𝖼𝖾𝗅𝗅(𝑘,𝑦𝑠)𝐸−𝑈𝑛𝑓𝑜𝑙𝑑𝐹𝑜𝑙𝑑⟼𝖼𝗈𝗉𝗒𝖡𝗈𝖽𝗒(𝜃ℎ)𝖼𝖾𝗅𝗅(𝑘,𝑦𝑠)𝛽⟼𝖼𝗈𝗉𝗒𝖡𝗈𝖽𝗒𝑔𝖼𝖾𝗅𝗅(𝑘,𝑦𝑠)𝛽⟼(𝜆𝑥𝑠.𝐶(𝑔,𝑥𝑠))𝖼𝖾𝗅𝗅(𝑘,𝑦𝑠)𝛽⟼𝐶(𝑔,𝖼𝖾𝗅𝗅(𝑘,𝑦𝑠)). Put ℓ𝑘=𝜆𝑧𝑠:𝖫𝗂𝗌𝗍𝖭𝖺𝗍.𝖼𝖾𝗅𝗅(𝑘,𝑧𝑠),𝐵𝑔(𝑧)=𝖼𝗈𝗇𝗌(𝖿𝗌𝗍𝑧)(𝑔(𝗌𝗇𝖽𝑧)). The remaining steps are 𝐶(𝑔,𝖼𝖾𝗅𝗅(𝑘,𝑦𝑠))=𝖼𝖺𝗌𝖾(𝗎𝗇𝖿𝗈𝗅𝖽(𝖿𝗈𝗅𝖽𝖫𝗂𝗌𝗍𝖭𝖺𝗍(𝗂𝗇𝗋𝑝));𝑢.𝗇𝗂𝗅;𝑧.𝐵𝑔(𝑧))𝐸−𝑈𝑛𝑓𝑜𝑙𝑑𝐹𝑜𝑙𝑑⟼𝖼𝖺𝗌𝖾(𝗂𝗇𝗋𝑝;𝑢.𝗇𝗂𝗅;𝑧.𝐵𝑔(𝑧))𝑟𝑖𝑔ℎ𝑡𝑠𝑢𝑚−𝛽⟼𝐵𝑔(𝑝)=𝖼𝗈𝗇𝗌(𝖿𝗌𝗍𝑝)(𝑔(𝗌𝗇𝖽𝑝))𝖿𝗌𝗍−𝛽⟼𝖼𝗈𝗇𝗌𝑘(𝑔(𝗌𝗇𝖽𝑝))𝛽𝑓𝑜𝑟𝖼𝗈𝗇𝗌𝑘⟼ℓ𝑘(𝑔(𝗌𝗇𝖽𝑝))𝗌𝗇𝖽−𝛽⟼ℓ𝑘(𝑔𝑦𝑠)𝑖𝑛𝑑𝑢𝑐𝑡𝑖𝑜𝑛ℎ𝑦𝑝𝑜𝑡ℎ𝑒𝑠𝑖𝑠⟼∗ℓ𝑘𝑦𝑠𝛽⟼𝖼𝖾𝗅𝗅(𝑘,𝑦𝑠). Therefore 𝖼𝗈𝗉𝗒𝑣⟼𝑔𝑣⟼∗𝑣. ◻
For every closed value 𝑣:𝖫𝗂𝗌𝗍𝖭𝖺𝗍 and every 𝑛, 𝖼𝗈𝗉𝗒𝑣E𝖫𝗂𝗌𝗍𝖭𝖺𝗍𝑛𝑣. Consequently, for every closing well-typed evaluation context 𝐾[−] of natural result type and every numeral 𝑚, 𝐾[𝖼𝗈𝗉𝗒𝑣]⟼∗𝑚⟺𝐾[𝑣]⟼∗𝑚. The equivalence does not assert that either plugged term converges.
Proof. Item 3 of lemma 24.47, with equal empty substitutions, gives 𝑣E𝖫𝗂𝗌𝗍𝖭𝖺𝗍𝑛𝑣. Lemma 24.50 gives 𝖼𝗈𝗉𝗒𝑣⟼∗𝑣; indexed anti-reduction, item 2 of the same package, gives 𝖼𝗈𝗉𝗒𝑣E𝖫𝗂𝗌𝗍𝖭𝖺𝗍𝑛𝑣.
Item 4 lifts this relation through 𝐾[−]. If either plugged term reaches a numeral in 𝑗 steps, choose 𝑛>𝑗. The corresponding observation clause gives a numeral on the other side related at positive index 𝑛−𝑗. The natural-number value clause relates only identical numerals, so the other result is 𝑚. Apply the symmetric observation clause for the reverse implication. If the context diverges before producing a natural value, neither observation antecedent holds; no convergence claim follows. ◻
★★☆ Prove downward closure for the 𝜇-value and arrow clauses. Then expand the 𝖼𝗈𝗇𝗌 trace in lemma 24.50: name the two reductions 𝑟⟼2𝑔, the right sum-case root, and the exact point where the structural induction hypothesis is lifted through the cons contexts. Finally, use indexed anti-reduction to derive 𝖼𝗈𝗉𝗒𝑣E𝑛𝑣 at an arbitrary 𝑛.
The term Ω𝐷 is safe and has an infinite eager reduction. The all-zero infinite element of L is productive and lies outside the image of the finite eager-list embedding. For all numerals 𝑚,𝑛, 𝗉𝗅𝗎𝗌𝑚𝑛⇓𝑚+𝑛, so closed addition is total for the mathematical-sum postcondition. Partial correctness alone entails none of these termination or productivity claims.
Proof of Proposition 24.54 — The five notions separate
Proof. Safety of Ω𝐷 is theorem 24.5; iterating its two-step cycle gives an infinite reduction. If 𝑧 is the all-zero infinite element, then 𝗈𝗎𝗍(𝑧)=↑(𝗂𝗇𝗋(0,𝑧)). Induction on 𝑘, using Obs-Zero and Obs-Cons, gives 𝑧𝑘⇝𝑧; hence 𝑧 is productive. It is not in the image of the finite embedding of proposition 24.29.
For addition, induct on 𝑚. At zero, one unrolling, two beta steps, and the zero root select the zero branch and return 𝑛. At 𝑚+1, the successor branch reduces to 𝗌𝗎𝖼𝖼(𝗉𝗅𝗎𝗌𝑚𝑛); the induction hypothesis and P-SuccN give 𝑚+𝑛+1. Any diverging well-typed term is partially correct for the false postcondition vacuously, showing why partial correctness entails no termination fact. ◻
★☆☆ Classify the following claims as safety, partial correctness, termination, productivity, or totality: the type of Ω𝐷 is preserved; a division routine returns the quotient if it returns and its divisor is nonzero; every recursive call to 𝗉𝗅𝗎𝗌 returns; each observation of the all-zero lazy list reveals a cons; and 𝗉𝗅𝗎𝗌 returns the mathematical sum for all inputs. Justify each classification by the definitions in this chapter.
Suppose simple types are read as propositions and include an empty type 𝟎, with no introduction rule. The unrestricted recursion extension adds, at every proposition 𝑃,
Γ,𝑝:𝑃⊢𝑒:𝑃
Γ⊢𝖿𝗂𝗑𝑝:𝑃.𝑒:𝑃
Pr-Fix
𝖿𝗂𝗑𝑝:𝑃.𝑒⇝0𝑒[𝖿𝗂𝗑𝑝:𝑃.𝑒/𝑝]
Pr-Unroll
The propositions-as-types reading counts every closed inhabitant ⋅⊢𝑞:𝑃 as a proof of 𝑃; it cannot inspect whether 𝑞 later terminates.
In the extension of definition 24.55, every proposition 𝑃 has a closed inhabitant 𝜔𝑃:=𝖿𝗂𝗑𝑝:𝑃.𝑝:𝑃. Moreover 𝜔𝑃⇝0𝜔𝑃. In particular, 𝜔𝟎:𝟎 refutes the syntactic-consistency statement that the empty type has no closed inhabitant, even though no empty-type value is produced.
Proof of Theorem 24.56 — Unrestricted recursion is not a total proof principle
Proof. Under 𝑝:𝑃, the variable rule derives 𝑝:𝑃; Pr-Fix therefore derives ⋅⊢𝜔𝑃:𝑃. Substituting 𝜔𝑃 for 𝑝 in the body 𝑝, rule Pr-Unroll gives the one-step self-loop. Specializing to 𝑃=𝟎 gives a closed inhabitant of the empty type. Preservation may still retain its type and progress may still give its successor step, so operational safety does not repair the failed proof reading. ◻
★☆☆ Prove preservation for the single root Pr-Unroll using term substitution. Then explain, using theorem 24.56, why that preservation proof does not establish either normalization or consistency-as-uninhabited-𝟎.
General recursion therefore defines partial computations, not total proofs. A propositions-as-types core must reject Pr-Fix, restrict it by a termination argument, or segregate partial programs from proof terms. No dependent repair is being assumed here.
★★☆ Let 𝑣0=𝗇𝗂𝗅,𝑣1=𝖼𝖾𝗅𝗅(0,𝗇𝗂𝗅),𝑣2=𝖼𝖾𝗅𝗅(1,𝗇𝗂𝗅), and 𝑣3=𝖼𝖾𝗅𝗅(0,𝖼𝖾𝗅𝗅(1,𝗇𝗂𝗅)),𝑣4=𝖼𝖾𝗅𝗅(0,𝖼𝖾𝗅𝗅(2,𝗇𝗂𝗅)). For the pairs (𝑣0,𝑣1), (𝑣1,𝑣2), and (𝑣3,𝑣4), determine the least positive index at which the two members are not related by ≈𝖫𝗂𝗌𝗍𝖭𝖺𝗍𝑛. Display the fold, sum, product, and natural-number clauses traversed by the calculation.
★★☆ Define a continuous map Φ:ℕ⊥×ℕ⊥⟶ℕ⊥ by Φ(𝑝,𝑑)=𝖼𝖺𝗌𝖾ℕ⊥(𝑝,0,𝑛↦𝗌𝗎𝖼𝖼⊥(𝑑)). Compute every Kleene iterate of 𝐹𝑝(𝑑)=Φ(𝑝,𝑑) for 𝑝=⊥, 𝑝=0, and 𝑝=𝑘+1. Hence compute 𝜇Φ(𝑝) in all three cases and verify directly the continuity conclusion of lemma 24.21.
★☆☆ Let 𝐾[−]=(𝜆𝑥𝑠:𝖫𝗂𝗌𝗍𝖭𝖺𝗍.Ω𝐷)[−]. Show that both 𝐾[𝑣] and 𝐾[𝖼𝗈𝗉𝗒𝑣] diverge for every closed list value 𝑣. Explain why this example satisfies the biconditional in theorem 24.51 but refutes the stronger assertion that both plugged terms must converge.
★☆☆ Calculate the denotation of Ωℕ=𝖿𝗂𝗑𝑥:ℕ.𝑥 from the Kleene chain of the identity map. Then use each direction of theorem 24.39 separately to recover the operational facts about Ωℕ and about the displayed run 𝗉𝗅𝗎𝗌21⇓3.
★★☆ For 𝐿=𝜇𝑋.(𝟏+ℕ×𝑋), let 𝑝:𝟏+ℕ×𝐿 be a closed value. Write the explicit iso-recursive typing and reduction of 𝗎𝗇𝖿𝗈𝗅𝖽(𝖿𝗈𝗅𝖽𝐿𝑝). Then run the equi-recursive worklist on 𝐿 and 𝟏+ℕ×𝐿. State precisely which step is an operational contraction and which is a type-equality decision; do not use one as a premise for the other.
★★★Practical project.recursion-bisimulation-lab Implement an explicit fold/unfold evaluator and a separate regular-tree equality worklist. Maintain the invariant that operational roots are never consumed as type-equality evidence and that each equality-cache entry records a pair of unfolded regular nodes. Test a nil observation, a nonempty-list observation, one fold/unfold root, equal and unequal regular trees, and a fuel-bounded PCF run. Then disable guardedness, conflate fold reduction with type equality, and treat fuel exhaustion as convergence in three independent variants; each variant must falsify its corresponding case. The PCF fuel result is an observation, not a proof of divergence. Appendix E records the acceptance commands, and appendix F develops both machines.
Harper gives the fold/unfold and fixed-point mechanisms for FPC in Chapter 20, printed pp. 177–183, and PCF in Chapter 19, printed pp. 168–176 [Har16]. The eager list encoding and the terms Ω𝐷, 𝖥𝗂𝗑𝐴, and 𝖹𝐴,𝐵 instantiate those mechanisms at, respectively, ℕ, (𝐴→𝐴)→𝐴, and ((𝐴→𝐵)→𝐴→𝐵)→𝐴→𝐵.
Abramsky and Jung define directed completeness and continuity in Definitions 2.1.13 and 2.1.17, prove continuity of function spaces and the fixed-point operator in Proposition 2.1.18 and Theorem 2.1.19, state admissible induction in Lemma 2.1.20, and define compactness in Definition 2.2.1, printed pp. 15–18 [AJ94]. The omega-chain calculations in theorem 24.17, proposition 24.28 give the fixed point and list equation used here.
Amadio and Cardelli give tree expansion and the trail algorithm in Sections 3.3–4.3, printed pp. 11–24 [AC93]. The worklist in definition 24.7 is its closed, contractive equality specialization.