Lectures onType Theory
Chapter 24
Chapter 24Core route

Recursive Types, Domains, and General Recursion

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 L1+(N×L) 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 λμiso is the eager simply typed calculus with 1, 2, N, products, sums, arrows, and the two term forms foldμX.Ae and unfolde. Type variables are bound only by μ. It is an iso-recursive calculus: crossing the recursive equation requires an explicit fold or unfold term.

Definition 24.1 — The eager iso-recursive calculus

The complete type and term grammars are A,B::=12NXABA×BA+BμX.A,e::=xunitttffnλx:A.ee1e2if(e;e1;e2)e1,e2fstesndeinleinrecase e of {inlxe0; inrye1}foldμX.Aeunfolde. Types are identified up to alpha-renaming, but μX.A is not judgmentally equal to A[μX.A/X]. The type formers have their syntax-directed formation rules. Recursive types are formed by

Δ,XA type
ΔμX.A type
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: x:AΓΓx:A,Γunit:1,Γtt:2,Γff:2,Γn:N,Γ,x:Ae:BΓλx:A.e:AB,Γe1:ABΓe2:AΓe1e2:B,Γe:2Γe1:AΓe2:AΓif(e;e1;e2):A,Γe1:AΓe2:BΓe1,e2:A×B,Γe:A×BΓfste:A,Γe:A×BΓsnde:B,Γe:AΓinle:A+B,Γe:BΓinre:A+B,Γe:A+BΓ,x:Ae0:CΓ,y:Be1:CΓcase e of {inlxe0; inrye1}:C. The recursive introduction and elimination rules are

Γe:A[μX.A/X]
ΓfoldμX.Ae:μX.A
T-Fold
Γe:μX.A
Γunfolde:A[μX.A/X]
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 v::=unitttffnλx:A.ev1,v2inlvinrvfoldμX.Av,E::=[]EevEif(E;e1;e2)E,ev,EfstEsndEinlEinrEcase E of {inlxe0; inrye1}foldμX.AEunfoldE. The compatible closure uses precisely these root contractions:

(λx:A.e)ve[v/x]
E-Beta
if(tt;e1;e2)e1
E-IfTrue
if(ff;e1;e2)e2
E-IfFalse
fstv1,v2v1
E-Fst
sndv1,v2v2
E-Snd
case (inlv) of {inlxe0; inrye1}e0[v/x]
E-CaseL
case (inrv) of {inlxe0; inrye1}e1[v/y]
E-CaseR
unfold(foldμX.Av)v
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 ListNat:=μX.(1+N×X). Its two constructors are ordinary terms: nil:=foldListNat(inlunit),cons:=λn:N.λxs:ListNat.foldListNat(inrn,xs). Rule T-Fold checks the first payload at 1+N×ListNat, and it checks the second at the same type through its right summand. A list case is an abbreviation: caseList e of {nile0;cons(n,xs)e1} is defined by the sum case case(unfolde;u.e0;z.e1[(fstz)/n][(sndz)/xs]), where u and z are fresh. The cons branch projects n and xs from the ordinary product. If the branch uses only xs, substitution leaves only the snd projection. Put p=inr3,nil. Then caseList (cons3nil) of {nilnil;cons(n,xs)xs}2twoβstepsforconscase(unfold(foldListNatp);u.nil;z.sndz)EUnfoldFoldcase(p;u.nil;z.sndz)rightsumβsnd3,nilsndβnil. For a numeral n and term e, write cell(n,e):=foldListNat(inrn,e). The term cell(n,v) is a canonical list value when v is one. By contrast, the curried term consnv takes two beta steps to that value.

Exercise 24.1

★☆☆ Draw the complete typing derivation for cons3nil, then write every reduction in the displayed list case. Name the unique use of E-UnfoldFold.

Finite unfolding does not solve the original problem. If L0=1 and Lk+1=1+N×Lk, then Lk represents at most k cons cells. The constructor for a (k+1)-st cell expects Lk, not Lk+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.

Lemma 24.2 — Composition of distinct type substitutions

If XY and YFV(B), then (E[D/Y])[B/X]=E[B/X][D[B/X]/Y]. The equation holds for every type expression E after alpha-renaming its bound variables away from B and D.

Proof of Lemma 24.2 — Composition of distinct type substitutions

Proof. Induct on E. At a variable, the cases E=X, E=Y, and E{X,Y} are the two substitution definitions; the side condition YFV(B) closes the case E=X. Arrows, products, and sums apply the induction hypotheses componentwise. For E=μZ.C, choose ZFV(B)FV(D){X,Y}, apply the induction hypothesis to C, and restore the same μZ binder. ◻

Lemma 24.3 — Type and term substitution

The following hold, after alpha-renaming bound variables away from the substituend.

  1. If Δ0,X,Δ1A type and Δ0B type, then Δ0,Δ1A[B/X] type.

  2. If Δ0,X,Δ1;Γe:A and Δ0B type, then Δ0,Δ1;Γ[B/X]e[B/X]:A[B/X].

  3. If Γ,x:Ae:B and Γv:A, then Γe[v/x]:B.

Proof of Lemma 24.3 — Type and term substitution

Proof. Items 1 and 2 are simultaneous inductions on formation and typing. The new formation case is μY.C. Choose YX fresh for B; the induction hypothesis forms C[B/X] under the substituted context extended by Y, then Mu-F forms μY.C[B/X]. For T-Fold, the induction hypothesis gives Γ[B/X]e[B/X]:(C[μY.C/Y])[B/X]. By lemma 24.2, with D=μY.C and the chosen YX, the required equation is (C[μY.C/Y])[B/X]=C[B/X][μY.C[B/X]/Y], 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. ◻

Lemma 24.4 — Folded canonical forms

If v:μX.A, then v=foldμX.Awandw:A[μX.A/X] for some value w.

Proof of Lemma 24.4 — Folded canonical forms

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 λμiso, so no final rule hides the constructor. ◻

Theorem 24.5 — Preservation, progress, and safety

For λμiso:

  1. if e:A and ee, then e:A;

  2. if e:A, then e is a value or some e satisfies ee;

  3. consequently, every finite evaluation of a closed well-typed term ends in a value or can take another step.

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 v:A[μX.A/X]foldμX.Av:μX.ATFoldunfold(foldμX.Av):A[μX.A/X]TUnfold. The reduct is v, and the inner premise types it at A[μX.A/X].

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. ◻

Exercise 24.2

★☆☆ Redo the E-UnfoldFold preservation case when the recursive body is N×X+1. Display the substitution instance in the premise and explain why no type equality rule is used.

Safety is not normalization

Let D:=μX.(XN),δ:=λx:D.(unfoldx)x. Because D unfolds to DN, δ:DN, and foldDδ:D. Thus ΩD:=δ(foldDδ):N. Its evaluation repeats a two-step cycle: δ(foldDδ)(unfold(foldDδ))(foldDδ)δ(foldDδ). The term is safe by theorem 24.5 and does not normalize. The negative occurrence of X in XN, not recursive syntax by itself, enables the loop. The decisive point is local: δ(foldDδ):N follows from T-Fold, T-Unfold, and T-App. No dynamic cast, blame rule, or gradual calculus is used.

More generally, put DA=μX.(XA),δf=λx:DA.f((unfoldx)x),FixA=λf:AA.δf(foldDAδf). Then FixA:(AA)A. For every closed function value v:AA, its call-by-value unfolding reaches FixAvβδv(foldDAδv)βv((unfold(foldDAδv))(foldDAδv))EUnfoldFoldv(δv(foldDAδv)). The three roots leave the recursive subterm δv(foldDAδv) in argument position. The hypothesis that v 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, FixAv diverges for every closed function value v. Indeed, put r=(unfold(foldDAδv))(foldDAδv). Then r2vr; evaluation of vr must evaluate r before the beta step can run, and repeats the same demand forever. Thus FixA is not a call-by-value programming recursion operator. The eta-delayed repair Z, 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 Fix0(λx:0.x):0 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 0 is the empty type; the upright 0 in the operational examples is the natural-number numeral.

Exercise 24.3

★★☆ Give the full typing derivation of ΩD, and prove by induction on k that it has a reduction sequence of length 2k returning to its original syntax. Then derive the type and unfolding equation of FixA at a closed function value.

Equality of regular recursive descriptions

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 λμiso.

Definition 24.6 — Contractive regular types and tree equality

A contractive recursive type is one in which every occurrence of the variable bound by μX.A lies strictly below a product, sum, or arrow constructor. In particular, μX.X 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 a, write expose(a)=(κ;a1,,an) when following zero or more recursive back-edges first reaches the constructor κ, whose ordered children are a1,,an. By contractiveness, every back-edge path reaches a constructor, so expose is total. The unfolded tree rooted at a has root κ, and its i-th subtree is rooted at ai. 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 AμB 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.

For example, μX.(1+N×X)μ1+N×μX.(1+N×X), whereas replacing N by 2 fails at the first product reached after the right injection.

Definition 24.7 — Worklist equality algorithm

Given roots a,b in finite contractive type graphs, maintain a worklist W of node pairs and a visited set V. Initially W=[(a,b)] and V=. Repeatedly remove a pair:

  1. if it belongs to V, continue;

  2. otherwise add it to V, compute expose(a)=(κ;a1,,an) and expose(b)=(κ;b1,,bm), and reject if κκ or nm;

  3. 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.

Theorem 24.8 — Decision of contractive regular equality

For closed contractive regular types A,B, the worklist algorithm terminates and accepts exactly when AμB.

Proof of Theorem 24.8 — Decision of contractive regular equality

Proof. Let NA,NB be the finite node sets. A pair is expanded only on its first visit. Hence at most |NA||NB| iterations expand a pair. Every constructor has arity at most two, so those expansions enqueue at most 2|NA||NB| 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 Vf be the final visited set of raw graph-node pairs in an accepting run. If (a,b)Vf, then expose(a)=(κ;a1,,an) and expose(b)=(κ;b1,,bn), and every child pair (ai,bi) was queued and hence lies in Vf at termination. Consequently the relation between the unfolded tree positions rooted at pairs in Vf is a bisimulation containing the root pair. The unfolded trees are bisimilar.

For completeness, let R be a tree bisimulation containing the roots. Maintain the following invariant: for every queued node pair (c,d), there are positions p,q in the two unfolded trees such that (p,q)R and the subtrees at p,q are rooted by the graph nodes c,d. The initial root pair has these witnesses. When (c,d) is expanded, bisimulation gives equal constructor heads at p,q 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. ◻

Remark 24.9

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 |NA||NB| distinct node pairs.

Exercise 24.4

★☆☆ Run the worklist algorithm on μX.(N×X+1)andN×μX.(N×X+1)+1. List the visited pairs. Then replace the right-hand N by 2 and identify the first rejecting pair.

The restriction is load bearing. For μX.X, 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 PCFn evaluates only the operator of an application; it has no argument evaluation context. We write its step as , reserving for the eager fold calculus.

Definition 24.10 — Call-by-name PCF

The grammar is A,B::=NAB,e::=xnsucceifz e then e0 else x.esλx:A.eeefix x:A.e. The successor branch binds the predecessor to x. Typing consists of the ordinary variable, numeral, abstraction, and application rules together with

Γe:N
Γsucce:N
P-Succ
Γe:NΓe0:AΓ,x:Nes:A
Γifz e then e0 else x.es:A
P-Ifz
Γ,x:Ae:A
Γfix x:A.e:A
P-Fix

Values are numerals and abstractions. Evaluation contexts are E::=[]EesuccEifz E then e0 else x.es. There is no argument context vE. The root rules are

(λx:A.e)de[d/x]
P-Beta
succnn+1
P-SuccN
ifz 0 then e0 else x.ese0
P-IfZ
ifz (n+1) then e0 else x.eses[n/x]
P-IfS
fix x:A.ee[fix x:A.e/x]
P-Unroll

Compatible closure under E is the one-step relation. Write en when en. Write eω when there is an infinite sequence e=e0e1e2.

The eager calculus uses ; call-by-name PCFn uses .

Lemma 24.11 — Unique call-by-name decomposition

Every closed nonvalue PCF term has at most one decomposition E[r], where E is an evaluation context of definition 24.10 and r 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 plus:=fix f:NNN.λm:N.λn:N.ifz m then n else k.succ(fkn). Write P for this closed fixed-point term and abbreviate B(m,n):=ifz m then n else k.succ(Pkn). Call by name substitutes an argument before evaluating it: P21(λm.λn.B(m,n))21PUnroll(λn.B(2,n))1PBetaB(2,1)PBetasucc(P11)PIfSsucc((λm.λn.B(m,n))11)PUnrollsucc((λn.B(1,n))1)PBetasucc(B(1,1))PBetasucc(succ(P01))PIfSsucc(succ((λm.λn.B(m,n))01))PUnrollsucc(succ((λn.B(0,n))1))PBetasucc(succ(B(0,1)))PBetasucc(succ1)PIfZsucc2PSuccN3.PSuccN Each successor branch decreases the first argument and adds one surrounding succ; the zero branch returns the second argument. Thus the trace reaches 3. By contrast, ΩN=fix x:N.xfix x:N.x diverges in one repeated step.

Lemma 24.12 — PCF structural and safety properties

The following hold for PCFn.

  1. If Γ,x:Ae:B and Γd:A, then Γe[d/x]:B.

  2. If Γe:A and ee, then Γe:A.

  3. If e:A, then e is a value or there is a unique e with ee. A closed value of type N is a numeral.

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 x and the free variables of d, 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. ◻

Exercise 24.5

★★☆ Repeat the displayed calculation for plus12, naming every root rule and checking that four beta steps occur. Then evaluate (λx:N.0)ΩN under the displayed call-by-name contexts. If an argument context vE 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.

Approximation as an ordered object

A finite evaluator can observe the first k unfoldings of a recursive program. A denotation orders these observations by D and takes their least upper bound. The order D compares definedness inside one domain; it is not a cross-language precision relation.

Definition 24.13 — Pointed omega-cpos and continuity

A poset has a reflexive, transitive, antisymmetric order. An omega-chain is a sequence d0Dd1D. An omega-cpo has a least upper bound ndn 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 f:DE satisfies dDd implies f(d)Df(d). It is a continuous function when it is monotone and f(ndn)=nf(dn) for every omega-chain. Write [DE]c for the continuous functions, ordered pointwise.

An element cD is compact when, for every omega-chain (di), cDidicDdjfor some j. Thus a compact observation below a chain lub already occurs at a finite stage.

Only omega-chains are required. For a monotone countable grid (ai,j), its diagonal is cofinal—every grid entry lies below a diagonal entry—because ai,jDak,k whenever ki,j.

The flat natural domain adjoins bottom to the discrete set of natural numbers: N={}N,Dn, with no order between distinct naturals. Every chain is either constantly bottom or has indices i and n such that every member from index i onward is n; its lub is or n, 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 N the discrete order, in which only equal elements are comparable. The ambient domains determine the omitted order subscripts: (d,e)D(d,e)dDd and eDe,inldDinlddDd,inreDinreeDe, with no comparison between the two sum tags. The lifting D={}{ddD} has Dz,dDddDd.

Lemma 24.14 — Orders used by the recursive equation

If D and E are omega-cpos, then so are D×E, D+E, and D. Their chain lubs are respectively componentwise, within the unique sum tag, and izi={,zi= for every i,(ijdi),zi=di from some stage j. 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 N 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 (c,d), suppose (c,d)Di(xi,yi). By compactness of c and d, choose r,s with cDxr and dDys; the stage max(r,s) 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. ◻

Lemma 24.15 — Continuous function spaces

If D and E are omega-cpos, then [DE]c is an omega-cpo. The least upper bound of a chain (fn) is the pointwise map f(d)=nfn(d). If E is pointed, its constant-bottom map is the least element.

Proof of Lemma 24.15 — Continuous function spaces

Proof. Pointwise monotonicity of f follows from monotonicity of every fn. For a chain (dm), continuity of the fn and monotonicity of the doubly indexed family give f(mdm)=nfn(mdm)=nmfn(dm)=mnfn(dm)=mf(dm). 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 fn(dm) bounds either iterated join. Pointwise leastness proves that f is the function-space join. The constant-bottom assertion is immediate. ◻

Lemma 24.16 — Continuous pairing, evaluation, and currying

Let P,D,E be omega-cpos.

  1. 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.

  2. Projections are continuous, and continuous f:PD and g:PE have continuous pairing p(f(p),g(p)).

  3. Evaluation ev:[DE]c×DE,(f,d)f(d), is continuous.

  4. If h:P×DE is continuous, then every section dh(p,d) is continuous and curry(h):P[DE]c,p(dh(p,d)), is continuous.

Proof of Lemma 24.16 — Continuous pairing, evaluation, and currying

Proof. Identities preserve every chain lub. If f and g are continuous, then g(f(idi))=g(if(di))=ig(f(di)), 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 (fi,di), continuity of each fi, followed by cofinality of the diagonal in the grid, gives ev(i(fi,di))=(ifi)(jdj)=ijfi(dj)=kfk(dk)=kev(fk,dk). 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 (pi), pointwise function-space lubs and continuity of h give, for every d, (icurry(h)(pi))(d)=ih(pi,d)=h(ipi,d). This is the required equality of continuous functions. Monotonicity follows from monotonicity of h. ◻

Theorem 24.17 — Kleene least fixed point

Let D be a pointed omega-cpo and let F:DD be continuous. Then lfp(F):=n0Fn() is a fixed point of F, and it lies below every pre-fixed point d satisfying F(d)Dd.

Proof of Theorem 24.17 — Kleene least fixed point

Proof. Monotonicity gives the chain DFDF2D. Continuity and deletion of its first, least member give F(lfpF)=continuitynFn+1=deletetheleastfirstmembernFn=definitionoflfplfpF. If F(d)Dd, induction gives FnDd for every n: the base uses bottom, and the step uses monotonicity followed by the pre-fixed-point premise. Least-upper-bound minimality then gives lfpFDd. ◻

Remark 24.18

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 nFn. Only the latter omega-chain construction is used in this chapter.

Example 24.19

Let strict multiplication send to , and define the continuous functional on [NN]c by Φ(f)()=,Φ(f)(0)=1,Φ(f)(m+1)=(m+1)f(m). Writing f for the everywhere-bottom map, its first approximants are 0123Φ0fΦ1f1Φ2f11Φ3f112Φ4f1126 In general Φnf(m)=m! exactly when m<n, 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.

Lemma 24.20 — Continuity of the least-fixed-point operator

For a pointed omega-cpo D, the map lfpD:[DD]cD,Flfp(F), is continuous.

Proof of Lemma 24.20 — Continuity of the least-fixed-point operator

Proof. Let F0DF1D and put G=iFi, using the pointwise function-space join of lemma 24.15. For every n, Gn=iFin. First, if FDF, then FnD(F)n for every n: induction on n uses the pointwise inequality at Fn and monotonicity of F. Hence (Fin)i is an omega-chain and the displayed lub exists. The displayed equation is proved by induction on n. The zero case is the constant bottom chain. For the step, continuity of G and its pointwise definition give the double join ijFj(Fin). The diagonal terms Fk(Fkn) are cofinal: for any i,j, take ki,j and use monotonicity of both the chain of maps and Fk. The double join is therefore kFkn+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(G)=niFin=inFin=ilfp(Fi). Thus lfpD preserves omega-chain lubs; monotonicity follows from the same iterate comparison. ◻

Lemma 24.21 — Parameterized least fixed points

Let P be an omega-cpo, let D be a pointed omega-cpo, and let Φ:P×DD be continuous. For pP, put Fp(d)=Φ(p,d),μΦ(p)=lfp(Fp). Then every Fp is continuous and μΦ:PD is continuous.

Proof of Lemma 24.21 — Parameterized least fixed points

Proof. The section Fp is continuous by lemma 24.16. Monotonicity of μΦ follows by induction on the Kleene iterates: if pDq, then FpnDFqn for every n, and taking lubs preserves the inequality.

Let p0Dp1D, put p=ipi, and write ai,n=Fpin. Induction on n proves Fpn=iai,n. The zero case is the constant-bottom chain. For the successor case, the pairs (pi,ai,n) form a chain: monotonicity in i was proved in the preceding paragraph. Continuity of Φ and the induction hypothesis now give Fpn+1=Φ(ipi,iai,n)=iΦ(pi,ai,n)=iai,n+1. The family ai,n 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, μΦ(p)=niai,n=inai,n=iμΦ(pi). Thus μΦ preserves omega-chain lubs and is continuous. ◻

Lemma 24.22 — Admissible fixed-point induction

Let D be a pointed omega-cpo, let F:DD be continuous, and let PD contain , be closed under lubs of omega-chains, and satisfy dPFdP. A subset containing bottom and closed under omega-chain lubs is called admissible. Then lfpFP.

Proof of Lemma 24.22 — Admissible fixed-point induction

Proof. Induction gives FnP for every n. Closure under the chain’s least upper bound gives the conclusion. ◻

Continuity cannot be weakened to monotonicity in Kleene’s calculation. On the chain 0D1DDω, define H(n)=0(n<ω),H(ω)=1. This map is monotone, but H(nn)=10=nH(n). Thus the step that moves F through the lub genuinely uses continuity.

Exercise 24.6

★★☆ Assume F(d)=d. Without citing the leastness conclusion of theorem 24.17, prove by induction that FnDd for every n, and then use the defining least-upper-bound property to derive lfp(F)Dd. 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 0D1DDω and test whether an input has reached its limit.

One recursive domain equation

Finite eager lists are not closed under chain lubs. Their increasingly defined prefixes form the chain Dcons(0,)Dcons(0,cons(0,))D, but no eager finite list is its least upper bound: every finite candidate reveals only a bounded prefix or ends in nil. 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.

Definition 24.23 — The partial-list order

Let L consist of finite natural-number words ending in a hole , finite words ending in nil, and infinite natural-number sequences. Write the first two forms recursively as , nil, and cons(n,d). A finite holed word is below every finite or infinite extension with the same revealed prefix. A finite word ending in nil and an infinite word are comparable only with themselves and their holed prefixes. Equivalently, the order is generated by Dd,cons(n,d)Dcons(n,d)when dDd, and contains no further pairs.

For kN, the depth-k observation is d0=,(k+1)=,nil(k+1)=nil,cons(n,d)(k+1)=cons(n,dk). The last clause also defines the finite observation of an infinite sequence.

Lemma 24.24 — Finite observations determine the partial-list order

For every k, truncation ddk is monotone, and dDudkDu for every k.

Proof of Lemma 24.24 — Finite observations determine the partial-list order

Proof. Monotonicity is induction on k followed by inspection of the two generating order clauses. A second induction on k, with a case split on d, gives dkDd: the successor case applies the induction hypothesis beneath the common cons head. Transitivity then proves the forward implication.

Conversely, if d is finite, choose k beyond its last cons cell. Whether d ends in nil or in , one has dk=d, so the hypothesis directly gives dDu. If d is infinite and u were finite, choose k beyond the final constructor of u; the longer word dk could not lie below u by either generating order clause. Hence u is infinite. For every depth k, the inequality dkDu forces the first k heads of u to equal those of d. The two infinite sequences therefore have every component equal, so u=d. ◻

Lemma 24.25 — The lazy-list omega-cpo

The poset L is a pointed omega-cpo.

Proof of Lemma 24.25 — The lazy-list omega-cpo

Proof. The hole is least. Let d0Dd1D be an arbitrary chain. For each fixed k, there is an index ik after which the finite observations dik are constant. Prove this by induction on k. At depth zero there is nothing to prove. At depth k+1, the chain either remains bottom, reaches nil 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-k observations stabilize by induction.

The stable observations are compatible: truncating the stable depth-(k+1) observation gives the stable depth-k one. If some observation ends in nil, 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 d. Every diDd, since each finite observation of di occurs in the compatible family. If u bounds the chain, monotonicity in lemma 24.24 puts every stable finite observation of d below u; the converse direction of that lemma gives dDu. Thus d=idi. ◻

Lemma 24.26 — Compact lazy lists

The compact elements of L are exactly its finite words, whether they end in or in nil.

Proof of Lemma 24.26 — Compact lazy lists

Proof. Every finite word c is compact. If cDidi, choose k beyond its last cons cell. The construction of the lub makes truncation commute with it at depth k: for some stabilization stage j, (idi)k=djk. Since c=ck, monotonicity and lemma 24.24 give the complete chain c=ckD(idi)k=djkDdj. Thus c is compact. An infinite d is not compact: the increasing chain d0Dd1D has lub d, but d lies below no finite member. This proves the compactness classification. ◻

Lemma 24.27 — The lazy-list unfolding isomorphism

There are continuous inverse maps Loutin({}+N×L).

Proof of Lemma 24.27 — The lazy-list unfolding isomorphism

Proof. Define out()=,in()=,out(nil)=(inl),in((inl))=nil,out(cons(n,d))=(inr(n,d)),in((inr(n,d)))=cons(n,d). 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: out(idi) is an upper bound of the out(di). If z is another such upper bound, then out(di)Dz, so monotonicity of in gives di=in(out(di))Din(z). Hence idiDin(z); applying out gives out(idi)Dz. The argument for in is symmetric. Hence both maps are continuous and the equation is an isomorphism of pointed omega-cpos, not merely a set bijection. ◻

Proposition 24.28 — The lazy list solution

The poset L is a pointed omega-cpo. Its compact elements are exactly its finite words, whether they end in or in nil. There are continuous inverse maps Loutin({}+N×L).

Proof of Proposition 24.28 — The lazy list solution

Proof. Combine lemma 24.25, lemma 24.26, lemma 24.27. ◻

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 ListNat value, the operational embedding is ι(nil)=nil,ι(cell(n,v))=cons(n,ι(v)). On unfolded payload values, put ι+(inlunit)=inl,ι+(inrn,v)=inr(n,ι(v)). Recall that is the nonbottom injection into a lifting; here its codomain is the lifted sum.

Proposition 24.29 — Finite operational lists commute with out

If v:ListNat is a value and unfoldvp, then ι(v) is a hole-free finite compact element of L and out(ι(v))=↑ι+(p). Conversely, every hole-free finite element of L is ι(v) for a unique canonical list value v.

Proof of Proposition 24.29 — Finite operational lists commute with out

Proof. Folded canonical forms write v=foldListNatp. Sum and product canonical forms give either p=inlunit or p=inrn,v with v:ListNat. Rule E-UnfoldFold yields p, and the defining clause of out gives the equation in either case. Induction on the finite payload tree shows that ι(v) 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 Dcons(0,)Dcons(0,cons(0,))D has the infinite all-zero list as its lub. Consequently L is not the set of eager finite ListNat values from the opening calculus. The two objects solve related equations for different purposes.

Exercise 24.7

★★★ Prove directly that out preserves the displayed all-zero chain’s lub. Then classify chains that reveal nil at a finite stage, and use the classification to give an alternative, clause-by-clause proof of continuity of in, rather than reusing the order-isomorphism argument in proposition 24.28.

The Scott interpretation of PCF

Interpret N by N and arrows by continuous function spaces: [[N]]=N,[[AB]]=[[[A]][[B]]]c. Induction on A, using lemma 24.15 at arrows, proves that every [[A]] is a pointed omega-cpo. For Γ=x1:A1,,xr:Ar, put [[Γ]]=i=1r[[Ai]] with the componentwise order. An environment η is an element of this finite product.

Definition 24.30 — Strict natural operations

A map of pointed omega-cpos is strict when it preserves bottom. Fix a pointed omega-cpo D. Define succ()=,succ(n)=n+1,caseD(,d,h)=D,caseD(0,d,h)=d,caseD(n+1,d,h)=h(n). Here caseD:N×D×[ND]cD. At a successor n+1, the third argument receives its predecessor n.

Lemma 24.31 — Continuity of the strict natural operations

The maps succ and caseD of definition 24.30 are continuous.

Proof of Lemma 24.31 — Continuity of the strict natural operations

Proof. A chain in N 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 i,n such that every image member from index i onward is succ(n), which is its lub.

For a chain (si,di,hi), if every si=, both sides of the continuity equation for caseD are bottom. Otherwise the scrutinee is a fixed numeral from some stage onward. At zero, the result tail is (di) and has lub idi. At n+1, the result tail is (hi(n)); the pointwise-lub clause of lemma 24.15 states ihi(n)=(ihi)(n). These are exactly the zero and successor clauses at the componentwise lub. The same cases prove monotonicity. ◻

Definition 24.32 — PCF denotation

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. [[x]]η=η(x),[[n]]η=n,[[λx:A.e]]η=(d[[e]]η[xd]),[[e1e2]]η=[[e1]]η([[e2]]η),[[succe]]η=succ([[e]]η),[[ifz e then e0 else x.es]]η=case[[A]]([[e]]η,[[e0]]η,d[[es]]η[xd]),[[fix x:A.e]]η=lfp(d[[e]]η[xd]). In the zero-test clause, A is the common type of the two branches.

Lemma 24.33 — Semantic typing and continuity

Give the environments for a finite context Γ the pointwise omega-cpo structure. If Γe:A, then η[[e]]η is a continuous map from the environment cpo into [[A]]. In particular every clause of definition 24.32 is well defined.

Proof of Lemma 24.33 — Semantic typing and continuity

Proof. Identify [[Γ,x:A]] with [[Γ]]×[[A]]; 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 h:[[Γ]]×[[A]][[B]]. 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 succ. 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 η(d[[es]]η[xd]). Pair these three maps and compose with case[[A]], which is continuous by lemma 24.31.

In P-Fix the body induction hypothesis gives a continuous map Φ:[[Γ]]×[[A]][[A]],Φ(η,d)=[[e]]η[xd]. The fixed-point clause is the parameterized map ηlfp(dΦ(η,d)), continuous by lemma 24.21. Hence each typing rule determines a well-defined continuous denotation of its conclusion. ◻

Lemma 24.34 — Semantic substitution and reduction invariance

If Γ,x:Ae:B, Γd:A, and η[[Γ]], then [[e[d/x]]]η=[[e]]η[x[[d]]η]. If Γe:A and ee, then [[e]]η=[[e]]η.

Proof of Lemma 24.34 — Semantic substitution and reduction invariance

Proof. The first claim is induction on e, alpha-renaming the lambda, predecessor, and fixed-point binders. In the fixed-point case choose the recursive binder yFV(d){x}; the denotation of d is then unchanged when the environment is extended at y. 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 caseD. For P-Unroll, fixedness from theorem 24.17 gives lfpF=F(lfpF)=[[e[fix x:A.e/x]]]η. Context cases follow from compositionality. ◻

For a closed term, write [[e]] for its denotation at the unique empty environment. Operational convergence implies the expected denotation: if en, repeated use of reduction invariance gives [[e]]=n. 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 N 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 e1 and e2 approximate their denotations do not say how the denotation of e1 acts on the argument denotation: d1RABe1,d2RAe2⟹̸d1(d2)RBe1e2 for an unstructured family R. 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.

Definition 24.35 — Logical approximation

For a semantic element d[[A]] and a closed PCF term e:A, define dRAe by induction on A: RNealways,nRNeiffen,fRABeifffor every dRAa, f(d)RBea.

Lemma 24.36 — Finite anti-reduction

If ee and dRAe, then dRAe.

Proof of Lemma 24.36 — Finite anti-reduction

Proof. Induct on A. At naturals, compose the prefix ee with the reduction required by the relation: if d=n, then en, hence en; the bottom case is immediate. At an arrow A=CB, for arbitrary d0RCa, lift ee to eaea and apply the codomain induction hypothesis to d(d0)RBea. ◻

Lemma 24.37 — Admissibility of logical approximation

For fixed closed e:A, the predicate ddRAe contains bottom and is closed under least upper bounds of omega-chains.

Proof of Lemma 24.37 — Admissibility of logical approximation

Proof. Induct on A. At N, bottom is related by definition. If idi=n, flatness implies that some dj=n; otherwise every member would be bottom and so would the lub. The premise for dj gives en.

At AB, bottom is the constant-bottom map and the induction hypothesis at B gives RBea for every dRAa. For a chain (fi), take arbitrary dRAa. The sequence (fi(d)) is a chain, each member is related to ea, and the codomain induction hypothesis gives ifi(d)RBea. Pointwise function-space lubs satisfy ifi(d)=(ifi)(d). ◻

An environment η and a closing substitution γ are related at Γ, written ηRΓγ, when η(x)RAγ(x) for every x:AΓ.

Theorem 24.38 — Fundamental approximation

If Γe:A and ηRΓγ, then [[e]]ηRAe[γ].

Proof of Theorem 24.38 — Fundamental approximation

Proof. Induct on the typing derivation. For a variable x, the premise is η(x)RAγ(x); 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 dRAa, extend both environments by xd and xa, and apply the body induction hypothesis to the closed body. The beta step (λx.e[γ])ae[γ,a/x] 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 n, after which P-SuccN gives n+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 n+1, extend the environments by the related predecessor n and use P-IfS.

For P-Fix, let F(d)=[[e]]η[xd],q=fix x:A.e[γ]. We prove FkRAq by induction on k. The base is bottom. For the step, extend the semantic environment by xFk and the term substitution by xq. The body induction hypothesis gives Fk+1RAe[γ,q/x]. Rule P-Unroll takes q to that term, so anti-reduction relates the same element to q. Finally, lemma 24.37 closes the chain and relates kFk=lfpF to q. This is the only place where ordinary induction on term syntax is insufficient; admissibility turns all finite unfoldings into the recursive result. ◻

Theorem 24.39 — Computational adequacy for closed naturals

If e:N, then for every numeral n, en[[e]]=n. Moreover, [[e]]= exactly when eω.

Proof of Theorem 24.39 — Computational adequacy for closed naturals

Proof. For (), use lemma 24.34’s reduction-invariance clause along every step of en, obtaining [[e]]=[[n]]=n. For (), use the fundamental approximation theorem, theorem 24.38, with empty environments. If the denotation is n, the base clause is exactly nRNeen.

By lemma 24.12, a closed natural term either evaluates to a unique numeral or has an infinite reduction. The established equivalence is [[e]]=nen. Since every element of N is or a numeral, [[e]]= is therefore equivalent to eω. ◻

Exercise 24.8

★★☆ 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 foldvμX.AfoldwiffvA[μX.A/X]w is circular. An observation index changes the recursive call from n+1 to n.

Convention 24.40 — The indexed call-by-value fragment

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 K::=[]KevKK,ev,KfstKsndKinlKinrKcase K of {inlxe0; inrye1}foldμX.AKunfoldK. 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.

Definition 24.41 — Step-indexed equivalence

For closed, equally typed terms of the fragment in convention 24.40, define value relations vnAw and term relations eEnAd simultaneously. At index zero every pair of closed well-typed values is related. At n+1, the value clauses are unitn+11unitalways,kn+1Nk=,v1,v2n+1A×Bw1,w2v1n+1Aw1 and v2n+1Bw2,inlvn+1A+Binlwvn+1Aw,inrvn+1A+Binrwvn+1Bw. Values with different sum tags are not related. At arrows, fn+1ABg when for every jn+1 and vjAw, fvEjBgw. The only circular-looking clause consumes an index: foldμX.Avn+1μX.AfoldμX.AwvnA[μX.A/X]w. To verify that the simultaneous definition is well founded, let |A| count one node for each base or type constructor: |N|=|1|=|X|=1,|AB|=1+|A|+|B|({,×,+}),|μX.A|=1+|A|. Put ρ=0 for value relations and ρ=1 for term relations. Order recursive calls lexicographically by (n,|A|,ρ). The recursive-type clause changes n+1 to n. In the arrow clause, a test at j<n+1 lowers the index; a test at j=n+1 recurses on the proper component A or B. 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 jn+1 ranges over every smaller observation index required by the arrow clause.

Write ejv for exactly j steps to a value. Then eEnAd iff both of the following hold for every j<n: ejvw. dw and vnjAw,djwv. ev and vnjAw. All quantified endpoints v,w are values. For a context Γ, write γnΓδ when the two closing substitutions map every x:AΓ to values related by nA.

Lemma 24.42 — Unique indexed decomposition

Every closed, well-typed nonvalue in the indexed fragment has a unique decomposition K[r], where K is an evaluation context from convention 24.40 and r 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. ◻

Lemma 24.43 — Terminating-trace decomposition

Reduction in the indexed fragment is deterministic. Every terminating trace has the decomposition forced by its outer constructor. In particular:

  1. if e1e2rv, then uniquely e1r1λx:A.b,e2r2u,b[u/x]r3v,r=r1+r2+1+r3;

  2. a trace from e1,e2 to a value consists of e1r1v1, followed by e2r2v2, and has length r1+r2;

  3. 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;

  4. 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. ◻

Lemma 24.44 — Indexed downward closure and anti-reduction

The following hold for the relations of definition 24.41.

  1. If mn, either relation at n implies the corresponding relation at m.

  2. If vnAw, then vEnAw. If ee, dd, and eEnAd, then eEnAd.

Proof of Lemma 24.44 — Indexed downward closure and anti-reduction

Proof. Downward closure. For downward closure, use the lexicographic measure (n,|A|,ρ) 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 m is already allowed at n. For terms, j<m implies j<n, and downward closure of values changes the residual relation from nj to mj.

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 vnAw gives vEnAw.

For anti-reduction, suppose ere and ejv, where j<n. Determinism from lemma 24.43 gives jr and ejrv. From eEnAd, obtain a value reachable from d and related to v at index n(jr). Downward closure changes that index to nj, and the prefix dd gives the required trace from d. Interchanging the two terms proves the other observation clause. ◻

Lemma 24.45 — Indexed fundamental lemma

If Γe:A and γnΓδ, then e[γ]EnAe[δ].

Proof of Lemma 24.45 — Indexed fundamental lemma

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 r<n steps. Its unique trace decomposition has lengths r=r1+r2+1+r3 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 q=nr1. Since r2+1+r3<q, the first implication in the argument term relation gives a reachable right argument value; downward closure relates the argument values at s=qr2. The arrow clause at q applies at sq. The left beta redex then takes 1+r3<s steps, leaving the result index s(1+r3)=nr. Thus r=r1+r2+1+r3<n,q=nr1,s=qr2,1+r3<sq,s(1+r3)=nr. 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 r1+r2<n, the first component is matched at nr1, then lowered to nr1r2; 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 nr>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 q, their selected components are related at q, hence at q1 by downward closure. If they are folds related at q, the recursive-value clause relates their payloads at q1. A case trace spends its root step and then rb steps in a branch. Matching injections have payloads related at q; downward closure derives their relation at q1, and the branch relation leaves q1rb, 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 γnΓδ; 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 n.

For a lambda at index n+1, choose jn+1 and values vjAw. Downward closure derives γjΓδ; extending by xv and xw gives related substitutions for the body, whose induction hypothesis relates the two closed bodies at j. The use is valid even when j=n+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 j, 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. ◻

Lemma 24.46 — Indexed evaluation-context compatibility

If K[] is a well-typed closing evaluation context from A to B and eEnAd, then K[e]EnBK[d].

Proof of Lemma 24.46 — Indexed evaluation-context compatibility

Proof. Evaluation contexts. For evaluation contexts, induct on K. The hole is the identity case. In Ke0 and vK, 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 n. ◻

Lemma 24.47 — Indexed structural package

The following hold for the relations of definition 24.41.

  1. If mn, either relation at n implies the corresponding relation at m.

  2. If vnAw, then vEnAw. If ee, dd, and eEnAd, then eEnAd.

  3. If Γe:A and γnΓδ, then e[γ]EnAe[δ].

  4. If K[] is a well-typed closing evaluation context from A to B and eEnAd, then K[e]EnBK[d].

Proof of Lemma 24.47 — Indexed structural package

Proof. Clauses 1–2 are lemma 24.44; clause 3 is lemma 24.45; clause 4 is lemma 24.46. ◻

Definition 24.48 — An eta-delayed call-by-value fixed point

For types A,B, put RA,B:=μX.(XAB),θf:=λx:RA,B.λy:A.f((unfoldx)x)y,ZA,B:=λf:(AB)AB.θf(foldRA,Bθf). Thus ZA,B:((AB)AB)AB. For a closed value f, evaluation of ZA,Bf reaches a lambda before evaluating its recursive call: ZA,Bfλy:A.f((unfold(foldθf))(foldθf))y. When evaluation of the body demands the recursive function, the parenthesized term takes two steps back to the same lambda. Eta-delay, absent from FixA, is the load-bearing call-by-value repair.

Proposition 24.49 — The eta-delayed equation is pointwise

Let f:(AB)AB and a:A be closed values. Then ZA,Bfaandf(ZA,Bf)a 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 h=foldRA,Bθf and g=λy:A.f((unfoldh)h)y. Then ZA,Bfg,(unfoldh)h2g. The left term reduces through ga, then uses (unfoldh)h2g to reach fga. The right term first evaluates its argument ZA,Bf to g, and reaches the same term.

For the qualification, recall the two-step loop at an arbitrary type: DC=μX.(XC),δC=λx:DC.(unfoldx)x,ΩC=δC(foldDCδC):C. Take C=AB and f=λc:AB.ΩC. Then ZA,Bf reaches the value g, while f(ZA,Bf) reaches ΩC and diverges. The closing context (λh:AB.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 copy:=θcopyBody(foldRListNat,ListNatθcopyBody),copyBody:=λc:ListNatListNat.λxs:ListNat.caseList xs of{nilnil; cons(n,ys)consn(cys)}. This is the first beta reduct of ZListNat,ListNatcopyBody; in the cons branch, n:N and ys:ListNat.

Lemma 24.50 — Structural convergence of the copier

For every closed value v:ListNat, copyvv.

Proof of Lemma 24.50 — Structural convergence of the copier

Proof. Write θ=θcopyBody,h=foldRListNat,ListNatθ,r=(unfoldh)h, and put g=λxs:ListNat.copyBodyrxs. Abbreviate the body after its two binders by C(c,xs):=caseList xs of {nilnil; cons(n,ys)consn(cys)}. The recursive argument has the two explicit steps r=(unfoldh)hEUnfoldFoldθhβg,copy=θhβg.

We prove gvv by structural induction on the canonical list value v. Folded, sum, and product canonical forms give nil or cell(k,ys). The nil trace is gnilβcopyBodyrnilEUnfoldFoldcopyBody(θh)nilβcopyBodygnilβ(λxs.C(g,xs))nilβC(g,nil)=case(unfold(foldListNat(inlunit));u.nil;z.cons(fstz)(g(sndz)))EUnfoldFoldcase(inlunit;u.nil;z.cons(fstz)(g(sndz)))leftsumβnil. For p=k,ys, the cons prefix is gcell(k,ys)βcopyBodyrcell(k,ys)EUnfoldFoldcopyBody(θh)cell(k,ys)βcopyBodygcell(k,ys)β(λxs.C(g,xs))cell(k,ys)βC(g,cell(k,ys)). Put k=λzs:ListNat.cell(k,zs),Bg(z)=cons(fstz)(g(sndz)). The remaining steps are C(g,cell(k,ys))=case(unfold(foldListNat(inrp));u.nil;z.Bg(z))EUnfoldFoldcase(inrp;u.nil;z.Bg(z))rightsumβBg(p)=cons(fstp)(g(sndp))fstβconsk(g(sndp))βforconskk(g(sndp))sndβk(gys)inductionhypothesiskysβcell(k,ys). Therefore copyvgvv. ◻

Theorem 24.51 — Recursive list copy

For every closed value v:ListNat and every n, copyvEnListNatv. Consequently, for every closing well-typed evaluation context K[] of natural result type and every numeral m, K[copyv]mK[v]m. The equivalence does not assert that either plugged term converges.

Proof of Theorem 24.51 — Recursive list copy

Proof. Item 3 of lemma 24.47, with equal empty substitutions, gives vEnListNatv. Lemma 24.50 gives copyvv; indexed anti-reduction, item 2 of the same package, gives copyvEnListNatv.

Item 4 lifts this relation through K[]. If either plugged term reaches a numeral in j steps, choose n>j. The corresponding observation clause gives a numeral on the other side related at positive index nj. The natural-number value clause relates only identical numerals, so the other result is m. 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. ◻

Exercise 24.9

★★☆ Prove downward closure for the μ-value and arrow clauses. Then expand the cons trace in lemma 24.50: name the two reductions r2g, 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 copyvEnv at an arbitrary n.

Safety, correctness, termination, productivity, and totality

These five guarantees have different witnesses: finite reduction prefixes, returned numerals, and finite observations of a domain element.

Definition 24.52 — Finite tail observation

For d,dL, the judgment dkd says that k consecutive cons cells can be observed and leave tail d. It is generated by

d0d
Obs-Zero
out(d)=(inr(n,d1))d1kd
dk+1d
Obs-Cons

In particular, neither a hole nor nil admits an Obs-Cons step.

Definition 24.53 — Safety, correctness, termination, productivity, totality

For the deterministic closed calculi of this chapter:

  1. a term is safe at A when every finite reduct remains typed at A, and every irreducible reduct is a value;

  2. a natural computation is partially correct for Q when the PCF judgment en implies Q(n);

  3. it terminates when the PCF judgment en holds for some n;

  4. an element dL is productive when, for every k, some dk satisfies dkdk according to definition 24.52; and

  5. a natural computation is total for Q when it terminates and is partially correct for Q.

The productivity clause is a property of the lazy-list domain developed here, not a claim that an eager term returns an infinite value.

Proposition 24.54 — The five notions separate

The term ΩD 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 m,n, plusmnm+n, 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 ΩD is theorem 24.5; iterating its two-step cycle gives an infinite reduction. If z is the all-zero infinite element, then out(z)=(inr(0,z)). Induction on k, using Obs-Zero and Obs-Cons, gives zkz; hence z is productive. It is not in the image of the finite embedding of proposition 24.29.

For addition, induct on m. At zero, one unrolling, two beta steps, and the zero root select the zero branch and return n. At m+1, the successor branch reduces to succ(plusmn); the induction hypothesis and P-SuccN give m+n+1. Any diverging well-typed term is partially correct for the false postcondition vacuously, showing why partial correctness entails no termination fact. ◻

Exercise 24.10

★☆☆ Classify the following claims as safety, partial correctness, termination, productivity, or totality: the type of ΩD is preserved; a division routine returns the quotient if it returns and its divisor is nonzero; every recursive call to plus returns; each observation of the all-zero lazy list reveals a cons; and plus returns the mathematical sum for all inputs. Justify each classification by the definitions in this chapter.

Definition 24.55 — The unrestricted proof-recursion extension

Suppose simple types are read as propositions and include an empty type 0, with no introduction rule. The unrestricted recursion extension adds, at every proposition P,

Γ,p:Pe:P
Γfix p:P.e:P
Pr-Fix
fix p:P.e0e[fix p:P.e/p]
Pr-Unroll

The propositions-as-types reading counts every closed inhabitant q:P as a proof of P; it cannot inspect whether q later terminates.

Theorem 24.56 — Unrestricted recursion is not a total proof principle

In the extension of definition 24.55, every proposition P has a closed inhabitant ωP:=fix p:P.p:P. Moreover ωP0ωP. In particular, ω0:0 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 p:P, the variable rule derives p:P; Pr-Fix therefore derives ωP:P. Substituting ωP for p in the body p, rule Pr-Unroll gives the one-step self-loop. Specializing to P=0 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. ◻

Exercise 24.11

★☆☆ 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-0.

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.

Suggested first pass.

Begin with exercise 24.12, exercise 24.13, exercise 24.14; then use the remaining problems to reconstruct adequacy and compare explicit with equi-recursive reasoning.

Exercise 24.12

★★☆ Let v0=nil,v1=cell(0,nil),v2=cell(1,nil), and v3=cell(0,cell(1,nil)),v4=cell(0,cell(2,nil)). For the pairs (v0,v1), (v1,v2), and (v3,v4), determine the least positive index at which the two members are not related by nListNat. Display the fold, sum, product, and natural-number clauses traversed by the calculation.

Exercise 24.13

★★☆ Define a continuous map Φ:N×NN by Φ(p,d)=caseN(p,0,nsucc(d)). Compute every Kleene iterate of Fp(d)=Φ(p,d) for p=, p=0, and p=k+1. Hence compute μΦ(p) in all three cases and verify directly the continuity conclusion of lemma 24.21.

Exercise 24.14

★☆☆ Let K[]=(λxs:ListNat.ΩD)[]. Show that both K[v] and K[copyv] diverge for every closed list value v. Explain why this example satisfies the biconditional in theorem 24.51 but refutes the stronger assertion that both plugged terms must converge.

Exercise 24.15

★☆☆ Calculate the denotation of ΩN=fix x:N.x from the Kleene chain of the identity map. Then use each direction of theorem 24.39 separately to recover the operational facts about ΩN and about the displayed run plus213.

Exercise 24.16

★★☆ For L=μX.(1+N×X), let p:1+N×L be a closed value. Write the explicit iso-recursive typing and reduction of unfold(foldLp). Then run the equi-recursive worklist on L and 1+N×L. 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.

Exercise 24.17

★★★ 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.

Sources.

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 ΩD, FixA, and ZA,B instantiate those mechanisms at, respectively, N, (AA)A, and ((AB)AB)AB.

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.

Search the book

Type to search the local edition.