Lectures onType Theory
Chapter 165
Chapter 165Optional

Sized Copattern Recursion and Mixed Induction–Coinduction

Prerequisites. Direct starred prerequisites: none. No later core chapter depends on this route.

A stream processor reads finitely many elements from an input stream before it writes one element to the output stream, and then continues. Its states form the type SP  νX.μY.((AY)+(B×X)), a least fixed point nested inside a greatest one: the inner μ bounds the number of reads between two writes, and the outer ν allows infinitely many writes. The program that runs a processor on a stream is run(getf)(v,vs)=run(fv)vs,run(put(w,sp))vs=(w, runspvs). Both checkers of chapter 33, chapter 124 reject it, and for opposite reasons.

A structural-recursion checker looks for an argument that decreases at every recursive call. In the second clause the call runspvs occurs under the pair constructor and its first argument sp is not a subterm of put(w,sp) in any order that also decreases in the first clause, where the first argument passes from getf to fv: the two clauses decrease at different components, and neither component decreases at both.

A guarded-corecursion checker looks for every recursive call to occur directly under a constructor of the coinductive result type. In the second clause it does, since runspvs sits under a pair. In the first clause it does not: the call run(fv)vs is the whole right-hand side and produces no output before recurring.

The two rejections point at the same missing datum. The first clause terminates because a finite quantity — the number of remaining reads — decreases; the second is productive because a coinductive observation is emitted. A checker that inspects the position of a call sees neither. This chapter presents a calculus in which both quantities are indices in the type, so that the two clauses are typed by a single rule with a lexicographic measure.

Sizes

Definition 165.1 — Sizes, measures, size contexts

Fix a countable set of size variables i,j,. A size expression is a,b::=i+n+n(nN), where the offset n is omitted when it is 0. An extended size expression is a+::=an, and a measure is a finite tuple m::=a+,m of extended size expressions. A size context is Ψ::=Ψ,i:π(<a), a finite map from size variables to a polarity π and a bound a. We write a for <(a+1), and size for , and abbreviate i:(<a) to i<a.

Definition 165.2 — Size comparison

The judgments Ψa, Ψa<b and Ψab are generated by

Ψ+n
S-Inf
Ψi<a
Ψi+n
S-Var
(i:π(<a))Ψπ+
Ψi<a
S-Bound
n<m
Ψ+n<+m
S-InfInf
n<m
Ψi+n<i+m
S-Off
Ψi<
Ψi+n<+m
S-VarInf
Ψa+nb
Ψa<b+1
S-Weak

and Ψm<m is the lexicographic order on measures of the same length. We write a for the normalized successor: (i+n):=i+n+1 and (+n):=.

The clause (+n)= is what makes a fixed point of the successor and is used at every place where a construction at size must be closed under the introduction rule; lemma 165.10 makes that use explicit.

Definition 165.3 — Consistent extension

A valuation η is a finite map from size variables to natural numbers; η satisfies Ψ when η(i)<η(a) for every (i<a)Ψ. We write ΨΨ when every valuation satisfying Ψ extends to one satisfying Ψ,Ψ.

Example 165.4 — A context that is consistent but not a consistent extension

The context i, j<i is consistent: take η(i)=1, η(j)=0. But i(j<i) fails, because the valuation η(i)=0 satisfies i and no value of j satisfies j<0. The judgment of definition 165.3 is therefore strictly stronger than consistency of the concatenation, and definition 165.14 will require it of every clause.

Exercise 165.1

★☆☆ Decide each of the following in the context i, j<i, giving a derivation or naming the rule that fails: j<i; j+1i; i<; i+2<+1; |i,j+1|<|i,+1|; and |i,0|<|i,j|.

Kinds, variances, and type constructors

Definition 165.5 — Simple kinds, kinds, variances

Simple kinds are ι::=oιι, where classifies proper types and o classifies size expressions. Kinds refine them with size bounds and variance: κ::=<aπκκ,π::=+. The variances are ordered π and composed by π=,π= (π),+π=π,=+, with composition commutative. A type variable context is Δ::=Δ,X:πκ, and πΔ multiplies every declared variance by π.

Read π as what is known about the direction in which a constructor moves its argument: + covariant, contravariant, constant, and nothing known. The order is by information content, so is the least informative and is the default.

Definition 165.6 — Type constructors

K::=aX1×κκF,G,A,B::=KλX:ι.FFGμaSνaRS::=c1:F1;;cn:FnR::={d1:F1;;dn:Fn} A variant row S maps constructor labels to type constructors and a record row R maps destructor labels to type constructors; both are abstracted over the recursive occurrence, so that a stream is written νa{head:λX.A; tail:λX.X} rather than νaX.{head:A;tail:X}. We write A×B and AB for the two binary formers, X:κ.A for κ(λX.A), and i<a.A for <a(λi:o.A).

A measured type is A^::=Δ.mA and a constrained type is A::=Ψ.cA with c::=m<m. A constrained type is not a type: a variable of constrained type may be used only when applied to size arguments satisfying the constraint.

Definition 165.7 — Subtyping

Write ΔFπF for the π-directed comparison of type constructors, with + ordinary subtyping, its converse, equality and the total relation. The clauses that concern sizes are ΔabΔμaS+μbS,ΔabΔνbR+νaR, so an inductive type is covariant and a coinductive type is contravariant in its size index.

Lemma 165.8 — The two size variances are forced

Let A be a type with Δab. If μaS+μbS failed, the constructor rule of definition 165.9 would not type cat at μbS for ab; and if νbR+νaR failed, the destructor rule would not allow a b-deep observation of an a-deep object for ab.

Proof of Lemma 165.8 — The two size variances are forced

Proof. For the first, cat:μaS by definition 165.9, and typing it at μbS requires μaSμbS, which is the displayed clause with ab from ab. For the second, an object of νbR admits observations at every j<b by definition 165.9; a use of it at νaR demands observations only at j<a, and ab makes that a subset. ◻

Definition 165.9 — Sized inductive and coinductive types

For b<a the derived rules are

Δ;Γtj<a.Sc(μjS)
Δ;ΓctμaS
Mu-I
Δ;ΓrνaR
Δ;Γr.dj<a.Rd(νjR)
Nu-E

Both rules move one step: a constructor at size a packages a value at some strictly smaller size, and a destructor at size a delivers a value at any strictly smaller size. The asymmetry between the existential in Mu-I and the universal in Nu-E is the difference between building and observing.

Lemma 165.10 — The fixed points at ∞

μS is closed under its constructors and νR under its destructors: if Δ;ΓtSc(μS) then Δ;ΓctμS, and if Δ;ΓrνR then Δ;Γr.dRd(νR).

Proof of Lemma 165.10 — The fixed points at ∞

Proof. By definition 165.1, =. For the constructor, < fails, but <+1= holds after bound normalization, so the witness j:= satisfies the premise of Mu-I and j<.Sc(μjS) is inhabited by the pair t. For the destructor, instantiate the universal of Nu-E at j:=, again using <. ◻

Terms, copatterns, and reduction

Definition 165.11 — Syntax

r,s,t::=uvλ.Dtermv::=()(t1,t2)ctGtintroductionu::=xfreapplicative terme::=tG.deliminationp::=x()(p1,p2)cpXppatternq::=pX.dcopatternD::={qt}clauseD::={D1;;Dn}clauses An object λ.D subsumes abstraction and record formation: λ.{xt} is λx.t, and λ.{.fstt1;.sndt2} is a lazy pair.

Definition 165.12 — Matching and reduction

Matching t/p & τ;σ of a term against a pattern, and e/q & τ;σ of an elimination spine against a copattern spine, produce a type substitution τ and a term substitution σ; the clauses are the evident ones, with t/x & ;t/x at a variable pattern and .d/.d & ; at a projection copattern. Weak head contraction is e/qk & τ;σλ.{qt}ee0tkτσe,(f:A=D)Σλ.De0tfe0t, and is the compatible closure of 0 over all subterms, including the bodies of clauses. Clauses may overlap and need not cover; an unmatched spine leaves the term stuck.

Two features of definition 165.12 are used throughout the normalization proof and are worth naming now. A whole copattern spine is matched at once, so a partially applied object such as λ.{xyt}s is stuck but may become unstuck when a further argument arrives. And a function symbol unfolds to its clauses without any guard, so the termination argument cannot rely on a syntactic restriction on unfolding.

Definition 165.13 — Declarations and programs

A declaration is f:A^=D with A^ a measured type; a mutual block is mutualmδ^, a sequence of declarations sharing a lexicographic measure of length m; a program is a sequence of blocks followed by an applicative entry point.

Definition 165.14 — Clause typing

Δ;ΓAΔqCΔΔΔ,Δ;Γ,ΓtC
Δ;Γ{qt}A
Clause
Δ;ΓDkA for all k
Δ;ΓDA
Clauses

where pattern spine typing Δ;ΓAΔ0qC eliminates A along q, binding the type variables and pattern variables of q in Δ and Γ, and its two clauses for the sized formers are Δ;Γj<a.Rd(νjR)Δ0qCΔ;ΓνaRΔ0.dqC,Δ;ΓΔ0pj<a.Sc(μjS)Δ;ΓΔ0cpμaS.

Definition 165.15 — Measured recursion

Let A^=Δ.mA be the measured type of f in a mutual block. While checking the clauses of f in a context where Δ’s variables are in scope, each recursive occurrence of any g of the block, with measured type Δg.mgAg, is given the constrained type Ag^<m:=Δg. mg<mAg, where Δg,mg,Ag rename the variables of Δg apart. A variable of constrained type must be applied to size arguments a satisfying both Δg and the condition mg[a]<m before it can be used.

The condition mg<m is the entire termination discipline of the calculus. It is checked once per recursive occurrence, by comparing two measures in the size order of definition 165.2; no inspection of the position of the occurrence takes place.

The stream processor, typed and reduced

Definition 165.16 — The types of eq:sc-sp

Fix types A and B and set SPμiX:=μiget:λY.AY; put:λY.B×X,SPνi:=νi{out:λX.SPμX},StriA:=νi{force:λX.A×X}.

The inner type is used at size inside the outer one: an arbitrary finite number of reads is allowed between two writes, and the outer size counts writes. Definition 165.9 then gives the derived rules, for b<a: f:ASPμbXgetbf:SPμaX,w:Bsp:Xputb(w,sp):SPμaX,sp:SPνasp.outb:SPμSPνb. For streams, define hdis:=pr1(s.forcei):i. Stri+1AA,tlis:=pr2(s.forcei):i. Stri+1AStriA, whose instances at have types StrAA and StrAStrA by lemma 165.10.

Construction 165.17 — The program of eq:sc-run

runμ: ij. |i,j+1|SPμj(SPνi)StrAB×StriBrunμ i j (getjf) vs= runμ i j (f(hdvs))(tlvs)runμ i j (putj(w,sp)) vs= (w, runν i sp vs)runν: i. |i,0|SPνiStrAStriBrunν i sp vs .force i= runμ i  (sp.outi) vs

Proposition 165.18 — The block type-checks

The two declarations of construction 165.17 form a mutual block with lexicographic measure of length two, and every recursive occurrence satisfies the condition of definition 165.15.

Proof of Proposition 165.18 — The block type-checks

Proof. There are three recursive occurrences; we check each against definition 165.15, displaying the two measures being compared.

runμ calls runμ. The clause matches the pattern getjf against SPμj(), so by the second clause of definition 165.14 the pattern binds j<j, that is jj; and f has type ASPμj(SPνi). The call is at |i,j+1| and the condition is |i,j+1|<|i,j+1|, which holds because the first components agree and j<j; the pattern in fact binds j<j, and the constrained type of the recursive occurrence requires the strict inequality, so the clause is accepted exactly when the matched size is strictly smaller.

runμ calls runν. The condition is |i,0|<|i,j+1|, which holds because the first components agree and 0<j+1.

runν calls runμ. The copattern .forcei eliminates StriB and by definition 165.14 binds i<i; the call is at |i,+1| and the condition is |i,+1|<|i,0|, which holds because i<i in the first component, so the second components are not compared.

Well-typedness of the right-hand sides is then read off the derived rules above: in the first clause f(hdvs) has type SPμj(SPνi) and tlvs has type StrA; in the second, w:B and runνispvs:StriB, so the pair has the required type B×StriB; in the third, sp.outi:SPμSPνi and the result type after the copattern is B×StriB, which is what runμi delivers. ◻

Example 165.19 — One reduction, in full

Let A=B=N, let vs be a stream with hdvs=0, and let sp0:=λ.{.outkget(λv.put(v,sp0))}. Then sp0:SPν, and the first forced observation of runνsp0vs reduces as follows. (runνsp0vs).force0runμ(sp0.out)vsrunμ(get(λv.put(v,sp0)))vs0runμ(put(0,sp0))(tlvs)0(0, runνsp0(tlvs)). Three contractions produce one output element, and the residual is again a runν call, at the same outer size and on the tail of the input. The measure that fell was the inner one, +1 to 0, at the second contraction; the outer measure did not fall, and by lemma 165.10 it does not have to at .

Exercise 165.2

★★☆ Repeat example 165.19 with a processor that reads twice before writing, that is with get(λv.get(λv.put(v,sp0))) in place of the body.

  1. List the contractions and mark, for each, which of the two measure components falls.

  2. Replace the inner size by a variable j and give the size annotations that make the clause of runμ type-check twice in a row.

  3. Now write a processor that never writes, and state exactly which hypothesis of proposition 165.18 it fails.

Exercise 165.3

★★☆ Exchange the two components of the measures in construction 165.17, giving runμ the measure |j+1,i| and runν the measure |0,i|. Check each of the three conditions of proposition 165.18 again and identify the one that now fails, naming the clause of definition 165.2 that would be needed.

Reducibility candidates

The normalization proof interprets a type as a set of strongly normalizing terms. Two features of definition 165.12 force a modification of Girard’s usual conditions. Clauses may overlap, so reduction is not deterministic and not confluent; and a function symbol unfolds to its clauses, so a semantic type must contain a symbol whenever it contains the object it unfolds to.

Definition 165.20 — Neutral and terminally stuck

Write SN for the set of strongly normalizing terms, Intro for the introduction terms of definition 165.11, and r for the set of one-step reducts of r. An applicative term u is terminally stuck when ue is not a redex for any elimination spine e. A term r is neutral, written rNe, when it is a redex or terminally stuck. Write rr when r simulates the terms r, meaning that every contraction of r is a contraction of some rk: this holds for λ.Dλ.D1,,λ.Dn and for fλ.D when (f:A=D)Σ.

The restriction to terminally stuck terms is needed. The partial application λ.{xyxx}δ with δ:=λ.{xxx} is stuck and in normal form, but supplying one further argument makes it reduce to δδ, which diverges. If it counted as neutral, condition CR3 below would place it in every candidate, including semantic function types, and the interpretation would contain a divergent term.

Definition 165.21 — Reducibility candidate

A set A of terms is a reducibility candidate, ACR, when

CR1

ASN;

CR2

tA implies (t)A;

CR3

tNe and (t)A imply tA;

CR4

tIntro, (t)A and tt with tA imply tA.

For ASN closed under reduction, write A for the least candidate containing A, generated inductively by the three clauses “tA”, “t is neutral with all reducts in A” and “t is not an introduction, all its reducts are in A, and it simulates terms of A”.

Condition CR4 is the one added for this calculus. It is what puts λ.D and f into a candidate, and its proof of usefulness is the next lemma.

Lemma 165.22 — Multi-clause objects and symbols

Let ACR.

  1. If λ.D1,,λ.DnA then λ.DA.

  2. If (f:A=D)Σ and λ.DA then fA.

Proof of Lemma 165.22 — Multi-clause objects and symbols

Proof. For the first claim, argue by induction on DSN. Since λ.Dλ.D1,,λ.Dn, condition CR4 applies once we show that every reduct of λ.D lies in A. A contraction λ.D0t is a contraction λ.Dk0t for some k by definition 165.12, and λ.DkA gives tA by CR2. Otherwise the reduction is inside a body, so the reduct is λ.D with DD, and the induction hypothesis applies.

For the second claim, fIntro and fλ.D by definition 165.20, and every reduct of f is a reduct of λ.D, hence in A by CR2. Apply CR4. ◻

Definition 165.23 — Semantic type formers

For candidates A,B, an index set K, a family FKCR and a proposition P, set AB:={rSNsA. rsB},KF:={rSNGK. rGF(G)},1:={()},A1×A2:={(t1,t2)t1A1, t2A2},KF:={GtGK. tF(G)},PA:={rrA if P}. The conditional PA is a candidate only when P holds; otherwise it is the set of all expressions, which is why constrained types are not types.

Lemma 165.24 — The function space is a candidate

If VarASN and BCR, then ABCR.

Proof of Lemma 165.24 — The function space is a candidate

Proof. CR1: for rAB and a variable xA we get rxBSN, hence rSN.

CR2: if rr and sA then rsrs, and rsB gives rsB by CR2 for B.

CR3: let rNe with all reducts in AB, and let sA. Then rsNe by definition 165.20, so by CR3 for B it suffices to place every reduct of rs in B; argue by induction on r,sSN. Because r is neutral, a reduct is rs or rs, and each is handled by the induction hypothesis.

CR4: let rIntro with all reducts in AB and rr with rAB, and let sA. Then rsIntro and rsr1s,,rnsB, so CR4 for B applies once every reduct of rs is in B. By induction on r,sSN: the cases rs and rs are the induction hypothesis; a contraction rs0t is a contraction rks0t for some k, and rksB gives tB by CR2. ◻

Definition 165.25 — Semantic sized fixed points

Let S map constructor labels and R destructor labels to operators on candidates. For an ordinal α define μαS:={ctcdom(S), tβ<αSc(μβS)},ναR:={rSNddom(R). r.dβ<αRd(νβR)}. This is inflationary iteration for μ and deflationary iteration for ν: no monotonicity of S or R is needed for the chains =μ0Sμ1S,SN=ν0Rν1R to be monotone and antitone respectively. Both chains are subsets of the countable set of expressions, so both become stationary; write for an ordinal at which every such chain of the calculus is stationary, and α:=+1 for α and α:=α otherwise.

Lemma 165.26 — Pre- and post-fixed points

  1. If tβSc(μβS) then ctμS.

  2. If rνR then r.dβRd(νβR).

Proof of Lemma 165.26 — Pre- and post-fixed points

Proof. For the first, μ+1S=μS by stationarity, and ctμ+1S is the definition. For the second, rν+1R=νR, and the definition at +1 is the displayed statement. Neither direction uses monotonicity of S or R. ◻

Lemma 165.27 — Fixed points

If every Sc and every Rd is monotone, then μS={cbtcdom(S), tSc(μS)},νR={rd,b. r.dbRd(νR)}.

Proof of Lemma 165.27 — Fixed points

Proof. For μ it suffices to prove the inclusion from left to right, that is that μS is a post-fixed point. By definition 165.25, μS=β<{cbtcdom(S), tSc(μβS)}, and μβSμS, so monotonicity of Sc and of the closure operator give the inclusion.

For ν it suffices to prove that νR is a pre-fixed point: if r.dbRd(νR) for every d and b, then r.dbRd(νβR) for every β< by monotonicity of Rd together with νRνβR, which is the definition of rνR. ◻

Lemma 165.27 is the exact place where variance is load-bearing. The hypothesis is monotonicity of every row component, and the kinding discipline of definition 165.5 is what guarantees it: a row component declared at variance + denotes a monotone operator, and definition 165.7 then makes the size index of μ covariant and of ν contravariant. Without the hypothesis, lemma 165.26 still holds in the two displayed directions and no more.

Strong normalization

Proof structure. The obstruction is that a function symbol unfolds without a guard, so nothing syntactic bounds the number of unfoldings. The construction that overcomes it is the measured type: a symbol is admitted into its semantic type only relative to an ordinal tuple, and its recursive occurrences are admitted only at strictly smaller tuples. Three statements carry the argument. Theorem 165.29 interprets each typing rule, with the symbol’s type read off the signature. Theorem 165.30 discharges a mutual block by lexicographic induction on the measure. Corollary 165.31 assembles them; the desired conclusion, that the entry point is strongly normalizing, appears there.

Definition 165.28 — Semantic judgments

Let [[ι]] interpret simple kinds by [[]]:=CR, [[o]]:=O the set of ordinals below +ω, and [[ιι]]:=[[ι]][[ι]]; let [[κ]] refine it by requiring the declared monotonicity behaviour for each variance and the bound for each <a. For a type variable context Δ write D:=[[Δ]] for the set of valuations ρ, and for a typing context Γ write E(ρ):=[[Γ]]ρ for the set of substitutions σ sending each x:A to an element of [[A]]ρ. Write D;EtC for: for all ρD and σE(ρ), tσC(ρ). Write Sound(Σ) when every declaration (f:A=D)Σ satisfies f[[A]].

Theorem 165.29 — Soundness of expression typing

Assume Sound(Σ), and let Δ, ΔΓ, ΔC, with D=[[Δ]], E(ρ)=[[Γ]]ρ and C(ρ)=[[C]]ρ. Then

  1. Δ;ΓrC implies D;ErC;

  2. Δ;ΓtC implies D;EtC;

  3. Δ;ΓDC implies D;Eλ.DC.

Proof of Theorem 165.29 — Soundness of expression typing

Proof. Simultaneously by induction on the typing derivation. We display one case per mechanism; the remaining cases are the same computation with the corresponding clause of definition 165.23 in place of the one shown, and are listed at the end.

Function symbol. The rule is Δ;ΓfΣ(f), and the conclusion is f[[Σ(f)]], which is the hypothesis Sound(Σ).

Application. From Δ;ΓrAB and Δ;ΓsA, the induction hypotheses give rσ[[A]]ρ[[B]]ρ and sσ[[A]]ρ, so (rs)σ[[B]]ρ by definition 165.23.

Constructor. From Δ;Γtj<a.Sc(μjS) the induction hypothesis gives tσβ<[[a]]ρSc(μβS), and definition 165.25 then places ctσ in μ[[a]]ρS. When [[a]]ρ this is lemma 165.26(1).

Destructor. From Δ;ΓrνaR the induction hypothesis gives rσν[[a]]ρR, and definition 165.25 gives rσ.dβ<[[a]]ρRd(νβR); lemma 165.26(2) covers [[a]]ρ=.

Clause. The rule is Clause of definition 165.14. Its first premise is discharged by soundness of pattern spine typing: whenever an elimination spine e matches q with substitutions τ;σ and the components of e lie in the semantic types assigned by the spine judgment, the resulting τ,σ lie in the semantic contexts D,E. Its second premise, ΔΔ of definition 165.3, guarantees that D is nonempty over every ρD, so the third premise may be instantiated. The induction hypothesis for the body then places tτσ in C.

Object. From Δ;ΓDA, the previous case gives λ.Dkσ[[A]]ρ for each k, and lemma 165.22(1) gives λ.Dσ[[A]]ρ.

Remaining cases. Variables, the unit, pairs, type application, type abstraction, existential introduction, subsumption and type ascription are the computation displayed in the application case with the corresponding clause of definition 165.23; subsumption in addition uses that ΔAC implies [[A]]ρ[[C]]ρ, which is proved by induction on the subtyping derivation, with the two size clauses of definition 165.7 discharged by the monotonicity and antitonicity recorded in definition 165.25. The case of a variable of constrained type uses that PA is A when P holds, and the rule requires exactly that the size arguments make the condition hold. ◻

Theorem 165.30 — Soundness of block typing

Let Sound(Σ). If β in Σ then Sound(Σ,β), where erases measures from the declarations of β.

Proof of Theorem 165.30 — Soundness of block typing

Proof. Single declaration. For let f:A=D, put A:=[[A]]. Theorem 165.29(3) gives λ.DA, and fλ.D gives fA by lemma 165.22(2).

Mutual block. Let the block have n declarations δ^k=(fk:Ak^=Dk) with Ak^=Ψk.mkAk and a measure of length m. Write Soundα(δ^δ^k) for the statement that δ^k is semantically sound at the ordinal tuple α provided every fl of the block inhabits [[Al^]]<α, the semantic type restricted to tuples strictly below α.

Argue by lexicographic induction on α in the set Om of m-tuples of ordinals. Fix α and k and show Soundα(δ^k). The induction hypothesis gives Soundβ(δ^) for every β<α. To apply Soundα(δ^δ^k), it must be shown that fl[[Al^]]<α for every l; so let ρ[[Ψl]] with [[ml]]ρ<α, let b instantiate Ψl, and show flb[[Al]]ρ. This is the induction hypothesis at β:=[[ml]]ρ, which is strictly below α by assumption.

The statement Soundα(δ^δ^k) itself is theorem 165.29(3) applied in the signature extended with the constrained types of definition 165.15: each recursive occurrence of fl has type Al^<mk, and the typing rule for a variable of constrained type forces the size arguments to satisfy ml<mk, which is exactly the hypothesis just discharged.

Finally, fkλ.Dk and lemma 165.22(2) put fk into its semantic type. ◻

Corollary 165.31 — Strong normalization

If Sound(Σ) and β in Σ then Sound(Σ,β). If β;t then tSN in the signature β.

Proof of Corollary 165.31 — Strong normalization

Proof. The first claim is theorem 165.30 applied to each block in turn. For the second, the entry point t is typed in the resulting signature, so theorem 165.29 places it in [[C]] for its type C, and [[C]] is a candidate, hence contained in SN by CR1. ◻

Corollary 165.32 — Termination and productivity of the stream processor

In the signature of construction 165.17:

  1. every term runμabspvs with sp:SPμb(SPνa) and vs:StrA is strongly normalizing;

  2. for every k, the kth forced observation of runνspvs reduces to a pair whose first component is a term of type B in normal form.

Proof of Corollary 165.32 — Termination and productivity of the stream processor

Proof. The first claim is corollary 165.31 applied to the entry point runμabspvs, using proposition 165.18 for well-typedness of the block.

For the second, iterate. The term (runνspvs).force has type B×StrB by definition 165.16, and is strongly normalizing by the first claim, so it has a normal form; that normal form is in a semantic product type, hence by definition 165.23 it is a pair or a neutral term. It is not neutral: by proposition 165.18 the clause of runν matches the copattern .force, so the term is a redex and reduces, and the reduct is runμ(sp.out) applied to vs, whose clauses match a get or a put. Repeating on the second component of the pair gives the observation at k+1. ◻

Corollary 165.32(2) is the productivity statement that the two checkers of the opening could not supply. It is a consequence of strong normalization together with the typing of construction 165.17; no separate productivity argument is made.

Two neighbouring disciplines

Remark 165.33 — Mendler recursion

Mendler’s scheme replaces the size index by a type variable that stands for the recursive occurrence and is abstract in the body. Its recursor for an inductive type has the form MRec:X:((XC)S(X)C)μSC, in which the recursive call is the argument XC and X is bound in the step, so the body cannot inspect the recursive occurrence. The two disciplines differ on what they can express.

  1. Mendler’s scheme has no index, so it cannot state a lexicographic measure; the two clauses of (165.2) decrease at different components and cannot be presented as one Mendler step.

  2. Definition 165.15 needs the variance discipline of definition 165.5 to make lemma 165.27 apply; Mendler’s scheme needs none, because abstraction over X replaces monotonicity.

  3. The counterexample separating them is a program whose recursive argument decreases only after a coinductive observation: runν calls runμ at |i,+1|, larger in the second component than the caller’s |i,0|, and admissible only because i<i. No Mendler step types that call, since runν’s abstract variable would have to be instantiated at the larger second component.

Remark 165.34 — Guarded clocks

A guarded calculus indexes the recursive occurrence by a modality rather than a size, and its fixed-point rule requires the recursion variable to have a modal type. The comparison is a comparison of rules, not a transfer of theorems.

  1. A guarded fixed-point rule types a recursive occurrence whose type is A and admits any number of them; definition 165.15 types a recursive occurrence whose measure has fallen and admits any type.

  2. A guarded calculus makes the first clause of (165.2) untypable: the call run(fv)vs produces no observation, so its result type carries no . The sized calculus types it because the inner size fell.

  3. Conversely, a guarded calculus types a definition whose recursive occurrence is passed to an arbitrary function of -type, with no index to decrease. Nothing above types such a definition without first assigning a size to the function’s argument.

No theorem of either route is a premise of any statement in this chapter.

Boundary

The calculus of section 165.1section 165.3 has size expressions i+n and +n only. There is no type of sizes, no quantifier ranging over a large collection of sizes, and no rule that commutes such a quantifier with a type former. Consequently nothing above constructs an initial algebra or a final coalgebra as an object of the calculus: lemma 165.27 is a statement about semantic candidates, in the metatheory.

No consistency theorem is proved. Corollary 165.31 is strong normalization of typed programs; it does not say that the type system is a logic, and there is no realizability model of a large size type here. The size annotations are erasable: they occur only at the type level, and corollary 165.31 concerns terms after erasure.

Coverage is not required. Definition 165.12 allows overlapping and incomplete clause sets, and definition 165.21 was framed with CR4 and the terminally-stuck restriction precisely so that the normalization proof survives their absence. A coverage checker would be a separate development.

Suggested first pass.

Problems exercise 165.5, exercise 165.4, and exercise 165.7 form the suggested first pass. None of these problems is a prerequisite for a later chapter.

Exercise 165.4

★★★ Lemma 165.24 verified the four conditions for AB. Verify them for the other formers.

  1. Show that A1×A2 and KF of definition 165.23 are candidates, saying at each step why the closure operator is needed and why it adds no introduction term.

  2. Show that KF is a candidate, and explain why the clause rSN cannot be dropped there although it can be dropped from AB.

  3. Show that μαS and ναR are candidates for every α, and identify the one place where ν0R=SN is used.

Exercise 165.5

★★★ A breadth-first labelling of an infinite binary tree consumes a stream of label streams and returns a tree together with the remaining streams. Set SSi:=Stri(StrV),Treei:=νi{label:λX.V; left:λX.X; right:λX.X},Resulti:=ν{tree:λX.Treei; rest:λX.SSi}.

  1. Explain why Resulti is a lazy product rather than a genuinely coinductive type, and why a record is needed rather than a pair.

  2. Write the five clauses of a function bfs:i. |i|SSiResulti, one for each of the five components of the informal equation bfs(cons(consvvs)vss)=(nodevlr, consvsvss).

  3. Check the measure condition of definition 165.15 at each recursive occurrence, displaying the two measures compared.

  4. State what corollary 165.31 gives for this program and what it does not: in particular, say why it does not by itself establish that the labelling is the intended one.

Exercise 165.6

★★☆ Definition 165.20 admits only terminally stuck applicative terms as neutral.

  1. Let δ:=λ.{xxx} and r:=λ.{xyxx}δ. Show that r is in normal form, that rδ is not strongly normalizing, and hence that admitting r as neutral would violate CR1 for AB.

  2. Show that a variable is terminally stuck, and that terminally stuck terms are closed under application to an arbitrary elimination.

  3. Identify the step of lemma 165.24 that uses the second fact, and say what would go wrong without it.

Exercise 165.7

★★★ Practical project.sized-copattern-checker Implement, in Kappa, a checker for the mutual-block discipline of definition 165.15 and an evaluator for definition 165.12, and run them on the programs of this chapter.

Calculus to implement. The size expressions, measures and comparison of definition 165.1, definition 165.2; the sized formers μaS and νaR of definition 165.9 with rows; terms, copatterns and clauses of definition 165.11; copattern matching and reduction of definition 165.12; and the clause and pattern-spine typing of definition 165.14 restricted to the fragment used by construction 165.17. Copattern matching must be implemented as a single match of the whole spine, and the evaluator must leave a partially applied object stuck rather than reducing it.

Invariant. Every recursive occurrence must be checked against the constrained type of definition 165.15, and the check must consist of one lexicographic comparison in the order of definition 165.2; the checker must never inspect the position of the occurrence. The evaluator must maintain, for every reduction step it performs, that the step is a contraction of a matched clause or a congruence, and it must count contractions so that a bounded run reports either a normal form or the bound.

Concrete result. For a program, a report giving the accept or reject verdict for each recursive occurrence, with the two measures compared, and for a named entry point the sequence of contractions up to a bound, with the normal form when reached.

Acceptance test. The block of construction 165.17 must be accepted, with the three comparisons printed exactly as in proposition 165.18. The measure-swapped variant of exercise 165.3 must be rejected, naming the offending occurrence. The reduction of example 165.19 must be reproduced contraction by contraction, and the three-contraction count must match. The processor that never writes, from exercise 165.2, must be rejected. Finally, the term λ.{xyxx}δ of exercise 165.6 must be reported as stuck but not normal in the sense of the checker, and the same term applied to δ must exhaust the contraction bound. Produce three mutations that still run — compare measures componentwise instead of lexicographically, allow a non-strict comparison, and match copatterns one at a time — and confirm that each accepts a program the unchanged checker rejects. State explicitly that the program illustrates corollary 165.31 on finitely many inputs and does not prove it.

Search the book

Type to search the local edition.