Lectures onType Theory
Chapter 11
Chapter 11Core route

Type Operators, Kinds, and System F-omega

System F quantifies over types but cannot abstract over a type constructor.

A container operation that cannot be typed

For the examples in this chapter we extend System F by a primitive base N and primitive binary products: A,B::=uNABA×Bu.A. Consider the mapping operation of a container: for the “diagonal” container that stores two elements of the same type, it is the function that applies f:ab to both components of a pair. For lists it is the usual map, for trees the relabeling of every node. We would like one type that all of these mapping operations share, quantified over the container itself: c.a.b.(ab)cacb. The attempt fails already at formation. In System F the judgment ΔA type is derived by one rule per production of the grammar above, and the subexpression ca matches none of them: there is no production applying one type expression to another. The stuck attempt is

no applicable formation rule
Δ,c,a,bca type
?

and no rule has a conclusion of the form ca type. The variable c is being used as a function on types, while System F’s type variables stand only for types. The repair is the same one that distinguishes numbers from functions on numbers: classify type expressions, and let the classification include function classifications. The classifications of type expressions are called kinds.

Definition 7.1 — Kinds

Kinds are generated by the grammar κ::=Tyκ1κ2. The kind Ty classifies types, the type expressions that classify terms. The kind κ1κ2 classifies operators taking an argument of kind κ1 to a result of kind κ2. Kinds contain no variables, binders, or reduction. The kind arrow classifies constructor functions, whereas AB is itself a constructor of kind Ty.

The container variable c of (7.1) will receive kind TyTy. Since type expressions of higher kind are no longer types, we rename the syntactic class: its elements are constructors, and the constructors of kind Ty are the types.

Definition 7.2 — Constructors of F_ω

The judgment ΔA::κ is read “constructor A has kind κ.” Accordingly, the binder u::κ declares that u has kind κ; this double colon is not the grammar symbol ::=. Constructors are generated by the grammar A,B,C::=uNABA×Bu::κ.Au::κ.Aλu::κ.AAB, where u ranges over constructor variables. We identify generated trees up to alpha-renaming, following chapter 1. A concrete checker must therefore compare normal forms modulo renaming of bound variables. Constructor application binds more tightly than , and a quantifier body extends maximally to the right; arrows associate to the right.

A kind context Δ=u1::κ1,,un::κn declares finitely many distinct constructor variables with their kinds. Formation is an explicit judgment:

 kctx
KCtx-Empty
Δ kctxudom(Δ)
Δ,u::κ kctx
KCtx-Ext

The kinding judgment is defined only over a formed kind context and is inductively generated by:

Δ kctx(u::κ)Δ
Δu::κ
K-Var
Δ kctx
ΔN::Ty
K-Nat
ΔA::TyΔB::Ty
ΔAB::Ty
K-Arr
ΔA::TyΔB::Ty
ΔA×B::Ty
K-Prod
Δ,u::κ kctxΔ,u::κA::Ty
Δu::κ.A::Ty
K-All
Δ,u::κ kctxΔ,u::κA::Ty
Δu::κ.A::Ty
K-Some
Δ,u::κ1 kctxΔ,u::κ1A::κ2
Δλu::κ1.A::κ1κ2
K-Abs
ΔA::κ1κ2ΔB::κ1
ΔAB::κ2
K-App

The existential former u::κ.A participates in constructor formation, conversion, and normalization. The term grammar studied here has no package introduction or elimination form. It is present so that the next chapter can add package terms while reusing this constructor language and its kinding, substitution, normalization, and conversion metatheory without redefining them.

For example, K-Some is used in the derivation u::Ty kctxu::Tyu×u::Tyu::Ty.u×u::TyKSome.

The variable, abstraction, and application fragment of kinding is precisely the simply typed λ-calculus of chapter 2, moved up one level: kinds play the role of simple types, Ty is the base kind, and K-Var, K-Abs, K-App correspond to Var, Lam, App. The nullary and binary former rules add constants at the base kind. The binding formers and are separate syntax and are not silently encoded as constants. Constructor binders and term binders therefore use the same freshness and renaming discipline while inhabiting different judgments.

Define the mapping-type operator and the diagonal container: Map:=λc::TyTy.a::Ty.b::Ty.(ab)cacb,P:=λu::Ty.u×u.

Example 7.3 — Kinding derivation

Put Δc:=c::TyTy and Δ0:=Δc,a::Ty,b::Ty. The complete bottom-up derivation of the body of Map is the following list; each line uses only earlier lines on the list. Δ0c::TyTyKVar,Δ0a::Ty,b::TyKVar,Δ0ca::Ty,cb::TyKApp,Δ0ab::TyKArr,Δ0cacb::TyKArr,Δ0(ab)cacb::TyKArr,Δc,a::Tyb::Ty.(ab)cacb::TyKAll,Δca::Ty.b::Ty.(ab)cacb::TyKAll. Rule K-Abs now gives Map::(TyTy)Ty. Likewise K-Var, K-Prod, and K-Abs give P::TyTy, after which K-App gives MapP::Ty. The row labelled K-App is exactly the use of a type variable that System F could not form.

Composition of unary constructors is Comp:=λc::TyTy.λd::TyTy.λa::Ty.c(da).

Exercise 7.1

★☆☆ Derive Comp::(TyTy)(TyTy)TyTy, displaying every rule instance.

Type-level computation and the conversion rule

A type such as MapP classifies terms, but no typing rule stated so far connects it with its unfolding. A term of type MapP ought to be exactly a term of type a.b.(ab)(a×a)(b×b): the two types differ only by performing the substitution that K-Abs and K-App promise. We therefore equip the constructor level with computation, and the term level with a rule transporting typing across it.

Definition 7.4 — Type-level reduction

Type-level reduction is the one-step relation AβA on constructors, inductively defined by the axiom

(λu::κ.A)BβA[B/u]
TR-Beta

together with the complete congruence family

AβA
ABβAB
TR-App_1
BβB
ABβAB
TR-App_2
AβA
(AB)β(AB)
TR-Arr_1
BβB
(AB)β(AB)
TR-Arr_2
AβA
A×BβA×B
TR-Prod_1
BβB
A×BβA×B
TR-Prod_2
AβA
λu::κ.Aβλu::κ.A
TR-Abs
AβA
u::κ.Aβu::κ.A
TR-All
AβA
u::κ.Aβu::κ.A
TR-Some

There are no other one-step reductions. We write β for the reflexive–transitive closure. A normal constructor admits no β step; a neutral constructor is not a λ-abstraction. This arrow reduces constructors. It is distinct from the term-level beta reduction of chapter 5, despite the shared historical subscript.

This is the constructor-level specialization of “not an introduction form.” For constructor beta reduction the only introduction that can create a root redex under application is a constructor lambda. Thus arrows, products, and quantifiers count as neutral here even though they are type formers. In particular a beta redex is neutral: its outer constructor is application. This is the use of (CR3) in lemma 7.18.

For example, MapPβa::Ty.b::Ty.(ab)PaPbβa::Ty.b::Ty.(ab)(a×a)(b×b), and the last constructor is normal. By contrast ca, with c a variable, is neutral and normal: computation is stuck on it. The decision procedure of section 7.5 must therefore retain, rather than unfold, this application.

Constructor equality is the congruence generated by this computation. We record it as a judgment so that derivations can cite it.

Definition 7.5 — Constructor equality

The judgment ΔAB::κ is inductively defined by:

ΔA::κ
ΔAA::κ
Q-Refl
ΔAB::κ
ΔBA::κ
Q-Sym
ΔAB::κΔBC::κ
ΔAC::κ
Q-Trans
ΔA1B1::TyΔA2B2::Ty
ΔA1A2B1B2::Ty
Q-Arr
ΔA1B1::TyΔA2B2::Ty
ΔA1×A2B1×B2::Ty
Q-Prod
Δ,u::κAB::Ty
Δu::κ.Au::κ.B::Ty
Q-All
Δ,u::κAB::Ty
Δu::κ.Au::κ.B::Ty
Q-Some
Δ,u::κ1AB::κ2
Δλu::κ1.Aλu::κ1.B::κ1κ2
Q-Abs
ΔA1B1::κ1κ2ΔA2B2::κ1
ΔA1A2B1B2::κ2
Q-App
Δ,u::κ1A::κ2ΔB::κ1
Δ(λu::κ1.A)BA[B/u]::κ2
Q-Beta

This chapter freezes constructor conversion at β-conversion. It does not add the constructor η-law λu::κ.AuA when ufv(A). Adding that law would require βη-normal forms and a corresponding extension of the common-reduct characterization below; the present theorem 7.25 is stated only for β.

Definition 7.6 — Terms and typing of F_ω

Terms are generated by e::=xλx:A.ee1e2Λu::κ.ee[C](e1,e2)pr1epr2e0suc(e), This is the term grammar of Fω used here; in particular, it has no package form. A term context Γ=x1:A1,,xk:Ak declares distinct term variables at types; the judgment Δ;Γe:A presupposes ΔAi::Ty for each declaration and ΔA::Ty. Write ΔΓ ctx for that presupposition, generated by

Δ kctx
Δ ctx
Ctx-Empty
ΔΓ ctxΔA::Tyxdom(Γ)
ΔΓ,x:A ctx
Ctx-Ext

The term typing rules are:

(x:A)Γ
Δ;Γx:A
T-Var
ΔA::TyΔ;Γ,x:Ae:B
Δ;Γλx:A.e:AB
T-Lam
Δ;Γe1:ABΔ;Γe2:A
Δ;Γe1e2:B
T-App
udom(Δ)fv(Γ)Δ,u::κ;Γe:A
Δ;ΓΛu::κ.e:u::κ.A
T-TLam
Δ;Γe:u::κ.AΔC::κ
Δ;Γe[C]:A[C/u]
T-TApp
Δ;Γe1:A1Δ;Γe2:A2
Δ;Γ(e1,e2):A1×A2
T-Pair
Δ;Γe:A1×A2
Δ;Γprie:Ai
T-Prj
Δ;Γ0:N
T-Zero
Δ;Γe:N
Δ;Γsuc(e):N
T-Suc
Δ;Γe:AΔAB::Ty
Δ;Γe:B
T-Conv

The function rules correspond to F-Var, F-Arr-I, and F-Arr-E of chapter 5; T-TLam and T-TApp correspond to F-All-I and F-All-E. Their local names expose the term forms. In T-TLam freshness is printed as a premise rather than left to the formation presupposition. Rule T-Conv is the sole point at which constructor equality enters term typing; everything proved about in section 7.4, section 7.5 exists to keep this one rule checkable.

Constructor reduction computes inside types. Programs use a separate weak, left-to-right call-by-value relation.

Definition 11.7 — Pure call-by-value evaluation

The values of the package-free term grammar are v::=λx:A.eΛu::κ.e(v1,v2)0suc(v). The one-step relation ee is generated by the three root contractions

(λx:A.e)ve[v/x]
E-Beta
(Λu::κ.e)[C]e[C/u]
E-TBeta
i{1,2}
pri(v1,v2)vi
E-PrjPair

and the complete congruence family

e1e1
e1e2e1e2
E-App_1
e2e2
v1e2v1e2
E-App_2
ee
e[C]e[C]
E-TApp
e1e1
(e1,e2)(e1,e2)
E-Pair_1
e2e2
(v1,e2)(v1,e2)
E-Pair_2
ee
prieprie
E-Prj
ee
suc(e)suc(e)
E-Suc

There is no reduction under λ or Λ. In particular, E-App2 and E-Pair2 become available only after the left subterm is a value. Write for the reflexive–transitive closure of .

The type-beta root substitutes a constructor into every annotation and type argument in the body. It is term evaluation, not a β step between constructors.

Example 11.8 — A complete pure evaluation

Let idω:=Λa::Ty.λx:a.x. Then idω[N](suc(0))(λx:N.x)(suc(0))suc(0). The first step is E-TBeta; the second is E-Beta. By contrast, 00 is closed and stuck, but T-App cannot type it because N does not convert to an arrow. Safety will exclude stuck nonvalues from the well-typed closed fragment.

Example 7.7 — A mapping term, typed through conversion

Define dmap:=Λa::Ty.Λb::Ty.λf:ab.λp:a×a.(f(pr1p),f(pr2p)). Writing Δ1:=a::Ty,b::Ty and Γ1:=f:ab, p:a×a, rules T-Var and T-Prj give Δ1;Γ1prip:a for i=1,2, rule T-App then Δ1;Γ1f(prip):b, and rule T-Pair Δ1;Γ1(f(pr1p),f(pr2p)):b×b, and two uses of T-Lam and two of T-TLam give ;dmap:a::Ty.b::Ty.(ab)(a×a)(b×b). This is not yet the type MapP. The bridge is a constructor-equality derivation: Q-Beta gives Paa×a and Pbb×b; Q-Arr, Q-All, and one more Q-Beta for the outer redex MapP, chained by Q-Sym and Q-Trans, yield a::Ty.b::Ty.(ab)(a×a)(b×b)MapP::Ty, and T-Conv concludes ;dmap:MapP. The conversion step is not bureaucracy: without it, this outer T-TLam derivation stops at the unfolded universal type. It cannot assign dmap the syntactically application-headed type MapP.

Exercise 7.2

★☆☆ Compute the normal form of CompPPN, displaying each β step, and confirm that it is (N×N)×(N×N).

Structural properties of the type level

The metatheory of kinding repeats, one level up, the metatheory of simple typing developed in chapter 2. We nevertheless copy the short inductions here, because their binder decompositions determine the substitutions used throughout the chapter.

Constructor substitution is determined by u[C/u]=C,v[C/u]=v(vu),N[C/u]=N,(AB)[C/u]=A[C/u]B[C/u],(AB)[C/u]=A[C/u]B[C/u],(v::κ.A)[C/u]=v::κ.A[C/u](vu, vfv(C)), where {,×} and {λ,,}; first rename the binder when the freshness condition fails. Substitution through a term acts on every type annotation and type argument. Its binding clauses include (λx:A.e)[C/u]=λx:A[C/u].e[C/u],(e[A])[C/u]=(e[C/u])[A[C/u]]. The binder of Λv::κ.e is renamed away from fv(C){u} before substitution continues into e; if v=u, the substitution stops at the binder. On the remaining new term forms it is componentwise: (e1,e2)[C/u]=(e1[C/u],e2[C/u]),(prie)[C/u]=pri(e[C/u]),0[C/u]=0,suc(e)[C/u]=suc(e[C/u]). Together with the term-substitution clauses of chapter 5, these equations define capture-avoiding substitution for the entire term grammar.

A finite simultaneous constructor substitution θ maps constructor variables to constructors and acts in one pass: u[θ]={θ(u)udom(θ),uudom(θ). It has homomorphic clauses for application and every former. Before entering u::κ.A, alpha-rename u away from the free variables of every image of θ, then remove u from the domain. The same operation on terms changes every type annotation and type argument. Extension θ,uB agrees with θ away from u and sends u to B. Thus simultaneous substitution is one operation, not an unspecified sequence of single substitutions. We reserve θ for constructor substitution; σ continues to denote simultaneous term substitution as in definition 5.33.

Lemma 7.8 — Weakening and substitution for kinding

  1. If Δ1,Δ2A::κ and udom(Δ1)dom(Δ2), then Δ1,u::κ,Δ2A::κ.

  2. If Δ1B::κ and Δ1,u::κ,Δ2A::κ, then Δ1,Δ2A[B/u]::κ.

Proof of Lemma 7.8 — Weakening and substitution for kinding

Proof. For weakening, induct on the displayed kinding derivation. In K-Var, the declaration used by the premise is still present after insertion. For K-App, K-Arr, and K-Prod, weaken every premise and reapply the same rule; K-Nat has no premises. In a binder rule, say K-Abs, first choose its bound variable v fresh for the inserted declaration. Its premise has context Δ1,Δ2,v::κ0; apply the induction hypothesis at this longer suffix and reapply K-Abs. The K-All and K-Some cases are identical.

For substitution, again induct on the final rule. If K-Var selects u, replace that leaf by the given derivation of B and weaken it through Δ2; if it selects another variable, keep the leaf. For K-App, K-Arr, and K-Prod, apply the induction hypothesis to every premise and rebuild the same rule; K-Nat is unchanged. In a binder rule, choose the displayed binder v distinct from u and fresh for B. For example, the K-All premise is Δ1,u::κ,Δ2,v::κ0A0::Ty. The induction hypothesis, with suffix Δ2,v::κ0, gives Δ1,Δ2,v::κ0A0[B/u]::Ty. Rule K-All concludes with subject v::κ0.A0[B/u]. The binder clause of constructor substitution gives v::κ0.A0[B/u]=(v::κ0.A0)[B/u]. Replacing K-All by K-Abs or K-Some gives the other two binder cases. ◻

Exercise 11.3

★☆☆ Instantiate the substitution part of lemma 7.8 at the constructor v::Ty.uv. Use B=N×N, state the freshness choice for v, and display the complete kinding derivation of the substituted constructor.

Lemma 7.9 — Kinding inversion and uniqueness

The outer form of a constructor selects exactly one kinding rule. Consequently, if ΔA::κ and ΔA::κ, then κ=κ, and the two derivations are identical.

Proof of Lemma 7.9 — Kinding inversion and uniqueness

Proof. Rule selection is read off the table: the eight rules have subjects of eight distinct outer forms. This does not yet assert that an application’s intermediate domain kind is unique. Uniqueness of the conclusion kind is a structural induction on A. For u the context determines κ, declarations being distinct by KCtx-Ext. For N, arrows, products, and both quantifiers the kind is Ty in every derivation. For λu::κ1.A0, inversion gives κ=κ1κ2 and κ=κ1κ2 with both κ2,κ2 kinds of A0 in Δ,u::κ1; the induction hypothesis gives κ2=κ2. Note that the domain kind is read off the annotation—this is where Church-style annotation is used, exactly as in lemma 2.19. For A1A2, the inductive hypothesis for A1 equates the two arrow kinds, and injectivity of the kind grammar equates their codomains. For derivation uniqueness, the outer constructor first selects its kinding rule. In the application case it selects K-App; kind uniqueness just proved fixes the intermediate domain kind, and the induction hypotheses uniquely determine the derivations of ΔA1::κ1κ2 and ΔA2::κ1, so the reconstructed K-App node is unique. For a variable, the unique context declaration fixes the leaf; K-Nat is the unique premise-free leaf. Arrow and product nodes have two premise derivations, each fixed by its induction hypothesis. Universal, existential, and abstraction nodes have one body premise under the binder, again fixed by the induction hypothesis. These cases exhaust the rule table. ◻

Lemma 11.12 — Term regularity

If ΔΓ ctx and Δ;Γe:A, then ΔA::Ty.

Proof of Lemma 11.12 — Term regularity

Proof. Induct on the typing derivation. At T-Var, context formation gives the declared type’s kind. The lambda, pair, and natural cases rebuild K-Arr, K-Prod, or K-Nat from the induction hypotheses. In an application or projection, lemma 7.9 inverts the kinding of the premise’s arrow or product type to obtain the required component. The T-TLam case uses K-All. The T-TApp case uses constructor substitution, lemma 7.8, on the body formation obtained by inverting K-All. Finally, the equality premise of T-Conv already forms its right endpoint at Ty. ◻

Lemma 7.10 — Subject reduction for kinding

If ΔA::κ and AβA, then ΔA::κ.

Proof of Lemma 7.10 — Subject reduction for kinding

Proof. Induction on the derivation of the step. For TR-Beta, the subject is (λu::κ1.A0)B. Inversion (lemma 7.9) gives Δλu::κ1.A0::κ1κ and ΔB::κ1, and inverting again, Δ,u::κ1A0::κ. Substitution (lemma 7.8) yields ΔA0[B/u]::κ. Each congruence case applies the inductive hypothesis to the stepped premise of the inverted rule and reapplies the rule. ◻

Lemma 7.11 — Equality regularity

If ΔAB::κ, then ΔA::κ and ΔB::κ.

Proof of Lemma 7.11 — Equality regularity

Proof. Rule induction. Q-Refl and the congruence rules are immediate from their premises and the corresponding kinding rules; Q-Sym and Q-Trans rearrange inductive hypotheses; Q-Beta kinds its left side by K-Abs and K-App and its right side by lemma 7.8. ◻

Lemma 7.12 — Reduction is included in equality

If ΔA::κ and AβA, then ΔAA::κ; likewise for β.

Proof of Lemma 7.12 — Reduction is included in equality

Proof. Induction on the step. At a redex, inversion gives Δ,u::κ1A0::κ2 and ΔB::κ1, exactly the premises of Q-Beta. A congruence step in an argument position uses the inductive hypothesis there, Q-Refl at the unchanged positions, and the matching congruence rule Q-Arr, …, Q-App. The starred form follows by Q-Refl and Q-Trans, using lemma 7.10 to keep each intermediate constructor kinded. ◻

Normalization at the type level

Rule T-Conv obliges a type checker to decide ΔAB::κ. Every kinded constructor is strongly normalizing, and local confluence gives it a unique beta-normal form; therefore equality holds exactly when the two normal forms agree. The normalization proof lifts the reducibility construction of chapter 2 to constructors: at Ty reducibility is strong normalization, while at κ1κ2 it means mapping every member of Redκ1 into Redκ2. The three required closure properties are normalization, reduction closure, and neutral expansion, the clauses (CR1)–(CR3) of definition 5.25. The clause names are reused by analogy only: here they classify constructors, and SN below means constructor strong normalization rather than either System F term set.

Definition 7.13 — Strong normalization

A constructor A is strongly normalizing, written ASN, if there is no infinite sequence AβA1βA2β.

Lemma 7.14 — Finite branching and reduction height

Every constructor has finitely many one-step reducts. Hence for ASN the length of a longest reduction sequence from A is a finite number ν(A), and AβA implies ν(A)<ν(A).

Proof of Lemma 7.14 — Finite branching and reduction height

Proof. Finite branching is a structural induction: a step is either TR-Beta at the root, possible in at most one way, or a step in one of finitely many argument positions, each finitely branching by the inductive hypothesis. For the second claim, consider the tree whose root is A and whose children of any node are its one-step reducts; it is finitely branching, and every branch is finite because ASN. If the branch lengths were unbounded, we could choose at the root a child whose subtree has unbounded branch lengths (some child must, as there are finitely many), and repeat, producing an infinite branch—a contradiction. So branch lengths are bounded, and ν(A) is their maximum; a reduct’s subtree is a subtree of A’s, giving the strict decrease. ◻

Remark 11.18 — Proof height is not an implementation

The number ν(A) is a classical proof device extracted from finite branching and the strong-normalization hypothesis; it is not a computable function on raw constructors supplied to the checker. A direct formalization of this argument recurses on accessibility for β, so its normalizer receives strong-normalization evidence. An executable development may instead prove termination for a separately defined normalizer, for example normalization by evaluation. Later uses of ν in this section are proof inductions, not pseudocode.

At arrow kind, the required invariant is explicit: a reducible constructor of kind κ1κ2 maps every reducible argument of kind κ1 to a reducible result of kind κ2.

The bare invariant ASN fails at K-App: from A,BSN one cannot conclude ABSN, because beta substitution can expose redexes not present in either reduction tree. The untyped shape (λu.uu)(λu.uu) makes the missing applicative hypothesis visible. The repair is to require an arrow-kind constructor to send every reducible argument to a reducible result.

Definition 7.15 — Reducibility

For each kind κ, the set Redκ of constructors is defined by induction on κ: RedTy:=SN;Redκ1κ2:={AABRedκ2 for every BRedκ1}. This recursion is well founded on the syntax of the kind: in the arrow clause both κ1 and κ2 are proper subkinds of κ1κ2. This is an untyped proof predicate on unkinded constructors. Membership in Redκ does not itself assert kindability at κ; lemma 7.20 assumes a kinding derivation before proving membership in the corresponding predicate. This distinction is why the same raw variable may serve as a neutral test at several kinds without contradicting kind uniqueness. The distinction is used immediately in the arrow-kind proof of (CR1), where a fresh raw variable is tested at κ1 without consulting any declared kind.

Lemma 7.16 — Properties of reducibility

For every kind κ:

  1. RedκSN;

  2. if ARedκ and AβA, then ARedκ;

  3. if A is neutral and every one-step reduct of A lies in Redκ, then ARedκ.

In particular every variable u lies in every Redκ, being neutral with no reducts.

Proof of Lemma 7.16 — Properties of reducibility

Proof. The outer simultaneous induction is on κ and proves (CR1)–(CR3) together. In the arrow-kind (CR3) case a second induction on the natural number ν(B) controls reductions in the argument. No third induction is implicit.

Base kind. (CR1) is the definition. (CR2): a suffix of an infinite reduction from A would extend to one from A. (CR3): any infinite sequence from A has a first step, landing in some reduct, which is in SN by hypothesis; contradiction. (Neutrality is not needed at the base kind.)

Arrow kind κ1κ2. (CR1): let ARedκ1κ2 and pick a variable u; by the inductive (CR3) at κ1, uRedκ1, so AuRedκ2SN by the inductive (CR1). An infinite reduction from A would, under the application congruence, give one from Au; so ASN. (CR2): for BRedκ1 we have ABRedκ2 and ABβAB, so ABRedκ2 by the inductive (CR2). (CR3): let A be neutral with all reducts in Redκ1κ2, and let BRedκ1; then BSN by the inductive (CR1), and we show ABRedκ2 by a side induction on ν(B). The constructor AB is neutral, so by the inductive (CR3) at κ2 it suffices that all its one-step reducts are in Redκ2. A reduct is either AB with AβA—then ARedκ1κ2 by hypothesis, so ABRedκ2—or AB with BβB—then BRedκ1 by the inductive (CR2) and ν(B)<ν(B), so the side induction applies—or a root β-step, impossible since A is neutral, hence not an abstraction. ◻

Exercise 11.4

★★☆ Fill the arrow-kind (CR3) argument for one neutral application AB. Classify every possible one-step reduct, identify the induction hypothesis used in each case, and explain why a root β-step is impossible.

Two substitution facts about reduction are needed next and again in section 7.5; we isolate them.

Lemma 7.17 — Substitution and reduction

  1. For distinct uv with v not free in C: A[B/v][C/u]=A[C/u][B[C/u]/v].

  2. If AβA, then A[C/u]βA[C/u].

  3. If CβC, then A[C/u]βA[C/u].

  4. If u is fresh for θ, meaning that it is outside both dom(θ) and the free variables of its images, then (A[θ])[B/u]=A[θ,uB].

Proof of Lemma 7.17 — Substitution and reduction

Proof. (1) Structural induction on A over representatives whose binders avoid u,v and the free variables of B,C. For A=v: both sides are B[C/u]. For A=u: the left side is C, the right side is C[B[C/u]/v]=C since v is not free in C. Other variables give themselves on both sides, and every composite form distributes both substitutions to its arguments, where the inductive hypothesis applies.

(2) Induction on the step. For TR-Beta: ((λv::κ.A0)B)[C/u]=substitutionclauses(λv::κ.A0[C/u])(B[C/u])βTRBetaA0[C/u][B[C/u]/v]=claim(1)(A0[B/v])[C/u]. Congruence steps substitute in an argument position and use the inductive hypothesis under the same congruence rule.

(3) Structural induction on A. At A=u use the single step CβC; another variable takes no steps. Application, arrow, and product concatenate the induction-hypothesis sequences in their argument positions through the corresponding congruence rules. At v::κ.A0, for {λ,,}, first freshen v away from u,C,C, apply the induction hypothesis to A0, and lift its sequence under the binder congruence.

(4) Structural induction on A, choosing every binder fresh for θ,B,u. At A=u, both sides are B. At another variable v, freshness ensures that substituting u into θ(v) leaves it unchanged. For an arrow A1A2, apply the two induction hypotheses and rebuild the arrow. For v::κ.A0, choose v fresh for θ,B,u, apply the body hypothesis, and reattach the binder. Product and existential formers are the corresponding binary and binder cases. ◻

Lemma 7.18 — Abstraction

If A[B/u]Redκ2 for every BRedκ1, then λu::κ1.ARedκ1κ2.

Proof of Lemma 7.18 — Abstraction

Proof. Fix BRedκ1; we must show (λu::κ1.A)BRedκ2. Variables are reducible by lemma 7.16; taking the variable u itself for B in the hypothesis gives A=A[u/u]Redκ2, so ASN by (CR1), and BSN likewise. We argue by complete induction on ν(A)+ν(B), generalized over both A and B and over the hypothesis that A[B0/u]Redκ2 for every B0Redκ1. Thus the induction hypothesis remains available after replacing A by a reduct A or B by a reduct B. The application is neutral, so by (CR3) it suffices that each one-step reduct lies in Redκ2. The reducts are:

  • A[B/u], in Redκ2 by hypothesis;

  • (λu::κ1.A)B with AβA: for every B0Redκ1, A[B0/u]βA[B0/u] by lemma 7.17(2), so A[B0/u]Redκ2 by (CR2); since ν(A)<ν(A), the inductive hypothesis applies;

  • (λu::κ1.A)B with BβB: then BRedκ1 by (CR2) and ν(B)<ν(B), so the inductive hypothesis applies.

By (CR3), (λu::κ1.A)BRedκ2, and as B was arbitrary, λu::κ1.ARedκ1κ2. ◻

Lemma 7.19 — Formers preserve normalization

If A,BSN, then ABSN and A×BSN; if ASN, then u::κ.ASN and u::κ.ASN.

Proof of Lemma 7.19 — Formers preserve normalization

Proof. No reduction rule has an arrow at the root of its redex, so every reduct of A1A2 is A1A2 or A1A2 with the indicated component stepped. An infinite sequence from AB therefore steps one of the two components infinitely often, and selecting those steps yields an infinite reduction of A or of B. The product case is identical with the other binary former. A quantifier has one unary position: every reduct of u::κ.A is u::κ.A with AβA. ◻

Lemma 7.20 — Fundamental lemma for kinding

Let ΔA::κ with Δ=u1::κ1,,un::κn, and let θ be a constructor substitution with θ(ui)Redκi for each i. Then A[θ]Redκ.

Proof of Lemma 7.20 — Fundamental lemma for kinding

Proof. Rule induction on the kinding derivation.

Case K-Var: A=ui and A[θ]=θ(ui)Redκi by assumption.

Case K-Nat: N has no reducts, so NSN=RedTy.

Cases K-Arr, K-Prod: the inductive hypotheses put both substituted components in RedTy=SN, and lemma 7.19 concludes, since (A1A2)[θ]=A1[θ]A2[θ].

Cases K-All, K-Some: choose the bound variable u fresh for θ, so (u::κ0.A0)[θ]=u::κ0.(A0[θ,uu]). The extended substitution sends u to a variable, which is reducible by lemma 7.16, so the inductive hypothesis gives A0[θ,uu]RedTy=SN, and lemma 7.19 concludes.

Case K-Abs: A=λu::κ1.A0 with Δ,u::κ1A0::κ2, and with u fresh for θ, A[θ]=λu::κ1.A0[θ]. For any BRedκ1, freshness gives (A0[θ])[B/u]=A0[θ,uB] by lemma 7.17(4), which is in Redκ2 by the inductive hypothesis at the extended substitution. Lemma 7.18 concludes A[θ]Redκ1κ2.

Case K-App: the inductive hypotheses give A1[θ]Redκ1κ and A2[θ]Redκ1, and the definition of Redκ1κ applies to the application. ◻

Theorem 7.21 — Type-level strong normalization

If ΔA::κ, then ASN. In particular every kinded constructor reduces to a normal form.

Proof of Theorem 7.21 — Type-level strong normalization

Proof. Apply lemma 7.20 with the identity substitution, which is reducible because variables are (lemma 7.16); then A=A[id]RedκSN by (CR1). A normal form is reached by reducing anywhere until no step applies, which must happen within ν(A) steps (lemma 7.14). ◻

Confluence and the decision of conversion

Normalization alone does not yet let a checker compare normal forms: perhaps a constructor reaches two different normal forms along different reduction orders, and perhaps relates constructors whose normal forms differ. The obstruction sits in rule Q-Trans: knowing that A and B reduce to a common constructor, and that B and C do, one must merge two reduction diagrams that share only B. Confluence is exactly the merging principle, and with strong normalization already proved, it follows from a local check.

Lemma 7.22 — Local confluence

If AβA1 and AβA2, then there is B with A1βB and A2βB.

Proof of Lemma 7.22 — Local confluence

Proof. Induction on A, with cases on how the two steps are derived.

If both steps are TR-Beta at the root, then A1=A2.

If both are congruence steps in the same argument position, the inductive hypothesis for that argument yields a common reduct, and the congruence rules transport it. If they are congruence steps in different argument positions, the two steps act on disjoint subterms and commute: performing the other step on each side reaches the same constructor in one step each.

The remaining case is a root TR-Beta on A=(λu::κ.A0)B0, with the other step inside. If the other step is in the body, A2=(λu::κ.A0)B0 with A0βA0; then A1=A0[B0/u]βA0[B0/u] by lemma 7.17(2), and A2βA0[B0/u] by TR-Beta. If the other step is in the argument, A2=(λu::κ.A0)B0 with B0βB0; then A1=A0[B0/u]βA0[B0/u] by lemma 7.17(3), and A2βA0[B0/u]. ◻

Exercise 11.5

★★☆ Close the local-confluence peak in which (λu::κ.A0)B0 contracts at the root on one side and reduces B0βB0 on the other. Give the common reduct and name the substitution–reduction clause that reaches it from the root reduct.

Theorem 7.23 — Confluence on normalizing constructors

Let ASN. If AβA1 and AβA2, then there is B with A1βB and A2βB.

Proof of Theorem 7.23 — Confluence on normalizing constructors

Proof. This is the standard well-founded proof of Newman’s lemma: local confluence plus termination implies confluence. Complete induction on ν(A) (lemma 7.14). If either given reduction is empty, its endpoint is A and the other endpoint closes the diagram. Otherwise AβA1βA1 and AβA2βA2. By lemma 7.22 there is C with A1βC and A2βC. Since ν(A1)<ν(A), the inductive hypothesis for A1 applied to the reductions to A1 and to C gives D with A1βD and CβD. Since ν(A2)<ν(A), the inductive hypothesis for A2 applies to the two displayed reductions A2βA2,A2βCβD, and gives B with A2βB and DβB; then also A1βDβB. ◻

Corollary 7.24 — Unique normal forms

Every kinded constructor A has exactly one normal form, written nf(A), and Aβnf(A).

Proof of Corollary 7.24 — Unique normal forms

Proof. Existence is theorem 7.21. If A reduces to normal forms N1 and N2, confluence joins them; normality forces both joining reductions to be empty, so N1=N2. ◻

Theorem 7.25 — Conversion is common reduction

Suppose ΔA::κ and ΔB::κ. The following are equivalent:

  1. ΔAB::κ;

  2. AβC and BβC for some C;

  3. nf(A)=nf(B).

Proof of Theorem 7.25 — Conversion is common reduction

Proof. (2)(3): the common reduct C reduces to its normal form, which both A and B then reach; uniqueness of normal forms (corollary 7.24) gives nf(A)=nf(C)=nf(B). (3)(2): take C=nf(A)=nf(B). (2)(1): by lemma 7.12, ΔAC and ΔBC at kind κ; Q-Sym and Q-Trans conclude.

(1)(2) is a rule induction on the equality derivation. Q-Refl: take C=A. Q-Beta: the left side steps to the right side. Q-Sym: symmetric hypothesis. Congruence rules: the inductive hypotheses join each argument, and the congruence rules applied step by step join the composites; for instance if AiβCi and BiβCi, then (A1A2)β(C1C2)and(B1B2)β(C1C2). The decisive case is Q-Trans: the hypotheses give C1 joining A,B and C2 joining B,C. Both C1 and C2 are reducts of B, which is kinded by lemma 7.11 and hence in SN by theorem 7.21; confluence (theorem 7.23) joins C1 and C2 at some C3, which then joins A and C. ◻

Definition 11.30 — Deterministic constructor normalization

Enumerate redex occurrences by a preorder traversal of the constructor tree. Visit the root first. Then visit application, arrow, and product children from left to right; visit the body of each λ, , and binder; variables and N have no children. An occurrence is a redex exactly when it is an application whose left child is a constructor abstraction. If the list is nonempty, contract its first occurrence, renaming its binder before capture-avoiding substitution when necessary, and repeat. Here outermost means the shortest earliest preorder path, and traversal descends under every binder.

Exercise 11.6

★☆☆ Run definition 11.30 on ((λc::TyTy.λa::Ty.ca)P)NandN×N. Record the preorder path chosen at each step and decide their constructor equality using corollary 7.26.

Corollary 7.26 — The conversion facts required by term checking

For kinded constructors over a fixed Δ:

  1. Conversion is decidable: first infer the unique kinds of A and B; then normalize by definition 11.30; finally compare the two normal forms up to renaming of bound variables.

  2. Head constructors are injective: if ΔA1A2B1B2::Ty, then ΔAiBi::Ty for i=1,2; likewise for ×. If Δu::κ.A0u::κ.B0::Ty, then κ=κ and, after opening both binders with one fresh u, Δ,u::κA0B0::Ty; likewise for .

  3. Distinct heads never convert: no two of N, A1A2, A1×A2, u::κ.A0, u::κ.A0, and a variable u are related by a formed judgment ΔAB::Ty.

Proof of Corollary 7.26 — The conversion facts required by term checking

Proof. For claim 1, kind inference follows the unique rule determined by the outer constructor: it recursively infers premise kinds, rejects a mismatched application or former, and returns the forced conclusion kind. To decide conversion, repeatedly reduce the first constructor redex in the preorder of definition 11.30 until none remains. Strong normalization proves termination, and confluence proves the normal form strategy independent. The redex scan is a finite syntax traversal. Each contraction strictly lowers ν, so the loop terminates; its endpoint is normal, and alpha-comparison is decidable by simultaneously opening corresponding binders with one fresh variable. Correctness is theorem 7.25(3). For claims 2 and 3, observe as in lemma 7.19 that reduction preserves the outermost former of an arrow, product, quantifier, variable, or N, reducing only the arguments; hence nf(A1A2)=nf(A1)nf(A2), and correspondingly for the other formers, while nf(u)=u and nf(N)=N. Equality of the normal forms (theorem 7.25) then forces equality of the components’ normal forms in claim 2—in the quantifier case after opening both bodies with one common fresh variable, as in corollary 2.11—and is impossible in claim 3 because the outermost formers differ. ◻

Claim 1 gives the equality test used by T-Conv; claims 2 and 3 give the head injectivity and disjointness used by lemma 7.29, theorem 11.42.

The normalize-both procedure is a decision proof, not a production cost model. Materializing two normal forms may duplicate subterms whose heads already decide the comparison. A practical checker should weak-head normalize only until each head is visible, compare matching heads, and recurse on their components while caching repeated reductions. This changes the amount of work performed on many inputs without changing the decision procedure proved correct above.

Lemma 7.27 — Constructor equality respects substitution

If Δ0,u::κ,Δ1AB::κandΔ0C::κ, then Δ0,Δ1A[C/u]B[C/u]::κ.

Proof of Lemma 7.27 — Constructor equality respects substitution

Proof. By theorem 7.25, choose D with AβD and BβD. Repeated use of lemma 7.17(2) gives reductions of A[C/u] and B[C/u] to D[C/u]. Kinding substitution (lemma 7.8) forms all three constructors in the target context, so the common-reduct direction of theorem 7.25 concludes. ◻

Lemma 11.33 — Constructor equality weakening

If Δ0,Δ1AB::κ and udom(Δ0,Δ1), then Δ0,u::κ,Δ1AB::κ.

Proof of Lemma 11.33 — Constructor equality weakening

Proof. By theorem 7.25, choose a common reduct C of A and B. Inserting an unused declaration changes neither reduction; kinding weakening from lemma 7.8(1) forms the three constructors in the larger context. The common-reduct direction of theorem 7.25 concludes. ◻

Lemma 11.34 — Structural properties of F_ω term typing

The following four interfaces hold for the judgment of definition 7.6.

  1. Term-context weakening. If Δ;Γ0,Γ1e:A and x is fresh, then Δ;Γ0,x:B,Γ1e:A, provided ΔB::Ty.

  2. Constructor-context weakening. If Δ0,Δ1;Γe:A and u is fresh, then Δ0,u::κ,Δ1;Γe:A.

  3. Term substitution. If Δ;Γ0,x:B,Γ1e:A and Δ;Γ0v:B, then Δ;Γ0,Γ1e[v/x]:A.

  4. Constructor substitution. If Δ0,u::κ,Δ1;Γe:A and Δ0C::κ, then Δ0,Δ1;Γ[C/u]e[C/u]:A[C/u].

Proof of Lemma 11.34 — Structural properties of F_ω term typing

Proof. Each claim is an induction on the displayed typing derivation, after freshening term and constructor binders away from the inserted declaration or substituend. Variable leaves use context membership; every composite term rule applies the induction hypotheses to its premises and then reapplies the same rule. Term substitution replaces the selected T-Var leaf by the given derivation and leaves every other leaf intact.

For the constructor-substitution interface, the T-TLam case moves both constructor and term contexts. Write its binder as v and freshen it away from u,C,Δ0,Δ1,Γ. Its premise is Δ0,u::κ,Δ1,v::κv;Γe:A. The induction hypothesis, taking Δ1,v::κv as the suffix, gives Δ0,Δ1,v::κv;Γ[C/u]e[C/u]:A[C/u]. The original freshness premise and the choice of v imply vfv(Γ[C/u]), so T-TLam reconstructs Δ0,Δ1;Γ[C/u]Λv::κv.e[C/u]:v::κv.A[C/u]. These term and type expressions are exactly the constructor substitutions of the original conclusion, by the binder clauses.

The only cases absent from the System F structural lemmas lemma 5.5, lemma 5.6, lemma 5.7 are products, naturals, and T-Conv. Products and naturals are componentwise or nullary. For constructor-context weakening at T-Conv, weaken its equality premise with lemma 11.33; for constructor substitution, substitute in that premise with lemma 7.27. The corresponding kinding premises use lemma 7.8. Term substitution does not alter the equality premise. These observations also preserve every formation presupposition in Ctx-Ext, so all four reconstructed derivations are well formed. ◻

Final T-Conv rules can hide the syntax-directed last rule. The next lemma removes that conversion suffix before lemma 7.29 uses the exposed rule.

Lemma 7.28 — Stripping final conversions

For every derivation Δ;Γe:A, there are a type A0 and a derivation of Δ;Γe:A0 whose final rule is not T-Conv, together with ΔA0A::Ty.

Proof of Lemma 7.28 — Stripping final conversions

Proof. Induct on the derivation. If the final rule is not T-Conv, take A0=A and Q-Refl. If it is T-Conv, apply the induction hypothesis to its typing premise and compose the resulting equality with the conversion premise by Q-Trans. ◻

The value grammar and constructor conversion meet in the canonical-forms lemma. The component equalities in its statement are needed because a final T-Conv may change the spelling of a value’s type without changing the value.

Lemma 11.36 — Canonical forms for pure F_ω

Let v be a value and suppose Δ;v:A.

  1. If A=A1A2, then there are x,C,e,D such that v=λx:C.e,Δ;x:Ce:D,ΔCA1::Ty,ΔDA2::Ty.

  2. If A=u::κ.A0, then, after opening both binders with the same fresh u, there are e and B such that v=Λu::κ.e,Δ,u::κ;e:B,Δ,u::κBA0::Ty.

  3. If A=A1×A2, then there are values v1,v2 and types C1,C2 such that v=(v1,v2),Δ;vi:Ci,ΔCiAi::Ty(i{1,2}).

  4. If A=N, then v=0, or v=suc(w) for a value w with Δ;w:N.

Proof of Lemma 11.36 — Canonical forms for pure F_ω

Proof. Apply lemma 7.28. The exposed derivation ends in the unique introduction rule permitted by the syntax of v: T-Lam, T-TLam, T-Pair, T-Zero, or T-Suc. Its result type has, respectively, head , , ×, or N. Distinct-head disjointness in corollary 7.26(3) excludes every value form whose result head differs from the requested head.

For an arrow, the exposed T-Lam derivation supplies Δ;x:Ce:D, and arrow injectivity in corollary 7.26(2) gives the two component equalities. The universal case uses quantifier-head injectivity, which also equates the binder kinds and permits one common fresh binder name. The product case uses product injectivity on the two premise types. At N, the two remaining value rules are T-Zero and T-Suc; the latter’s premise has type N before the stripped conversion. These cases exhaust the value grammar. ◻

Theorem 11.37 — Pure-term preservation

If Δ;Γe:A and ee, then Δ;Γe:A.

Proof of Theorem 11.37 — Pure-term preservation

Proof. Induct on the derivation of ee. At each case, first use lemma 7.28 on the typing of the whole source. Its exposed last rule is forced by the source term’s outer syntax. Rebuild that rule after the step and restore the stripped result conversion with T-Conv.

For E-Beta, the exposed outer rule is T-App. Suppose its operator premise has type A0B0 and its argument premise types v at A0. Strip conversions from the typing of the displayed abstraction. Its T-Lam premise has the form Δ;Γ,x:Ce0:D,ΔCDA0B0::Ty. Arrow injectivity gives CA0 and DB0. Symmetry and T-Conv type v at C; term substitution from lemma 11.34(3) types e0[v/x] at D; a final conversion gives B0.

For E-TBeta, the exposed outer rule is T-TApp. Stripping the typing of the type abstraction and applying universal-head injectivity gives, after one alpha-renaming, Δ,u::κ;Γe0:B,Δ,u::κBA0::Ty. Constructor substitution from lemma 11.34(4) gives Δ;Γ[C/u]e0[C/u]:B[C/u]. The freshness premise of T-TLam gives ufv(Γ), so Γ[C/u]=Γ. Equality substitution from lemma 7.27 converts the result type to A0[C/u], as required by T-TApp.

For E-PrjPair, strip the pair’s typing. Product-head injectivity converts the selected component premise to the component type demanded by the exposed T-Prj rule.

Each congruence rule has one stepping premise. Apply the induction hypothesis to the matching typing premise and rebuild T-App, T-TApp, T-Pair, T-Prj, or T-Suc. In the right-hand application and pair cases, the value side condition changes no typing premise. The three root cases and these seven congruence cases are the complete relation of definition 11.7. ◻

Theorem 11.38 — Pure-term progress

If Δ;e:A, then e is a value or there is an e such that ee.

Proof of Theorem 11.38 — Pure-term progress

Proof. Induct on the typing derivation. The variable case is impossible because the term context is empty. A final T-Conv uses the induction hypothesis for its typing premise. Term abstractions, type abstractions, and 0 are values.

For T-App, apply the operator induction hypothesis. An operator step gives E-App1. If the operator is a value, apply the argument induction hypothesis. An argument step gives E-App2. If both are values, lemma 11.36(1) makes the operator a term abstraction, so E-Beta applies. The T-TApp case first steps its operator by E-TApp; otherwise lemma 11.36(2) makes that value a type abstraction, so E-TBeta applies.

For T-Pair, step the first nonvalue component by E-Pair1 or E-Pair2; if both components are values, the pair is a value. For T-Prj, step the operand by E-Prj; if it is a value, lemma 11.36(3) makes it a pair and E-PrjPair applies. Finally, T-Suc either uses E-Suc on the premise step or forms the value suc(v). These cases cover every term typing rule. ◻

Corollary 11.39 — Pure-term safety

If Δ;e:A and ee, then e is a value or takes another step. Thus a term closed in term variables cannot evaluate to a stuck nonvalue; the constructor context Δ may remain open.

Proof of Corollary 11.39 — Pure-term safety

Proof. Induct on the step sequence and apply theorem 11.37 at each step. The endpoint remains typed at A, so theorem 11.38 gives the stated alternative. ◻

Lemma 7.29 — Unicity of typing up to conversion

For a term in the package-free grammar displayed in definition 7.6, if Δ;Γe:A and Δ;Γe:A, then ΔAA::Ty.

Proof of Lemma 7.29 — Unicity of typing up to conversion

Proof. Strip both final conversion chains with lemma 7.28. We compare the two non-conversion conclusions by induction on the common term subject, then compose with the two stripped equalities.

For x, both rules read the same unique declaration from Γ. For 0 and suc(e), both conclusions are N; the latter also invokes the induction hypothesis on the premise. For λx:C.e, the annotation C is literally the same in both derivations; the induction hypothesis in Γ,x:C equates the two body types, and Q-Arr equates the result types. For e1e2, the two operator premises have types CD and CD. Their induction hypothesis and arrow injectivity give DD. For a pair, apply the two component induction hypotheses and Q-Prod; for prie, apply the premise induction hypothesis and product injectivity to the selected component.

For Λu::κ.e, the kind annotation is literally shared; apply the induction hypothesis under u::κ and then Q-All. Finally consider e[C]. Its two operator premises have types u::κ.D and v::κ.D. The type argument C has a unique kind, so κ=κ; alpha-open both quantifiers with one fresh u. The operator induction hypothesis and universal injectivity give DD in the extended context, and lemma 7.27 gives D[C/u]D[C/u], the two syntax-directed result types. ◻

This result and lemma 7.30 concern the package-free grammar of definition 7.6. They assert neither unicity nor a failure of unicity for an extension with packages.

Definition 11.41 — Syntax-directed term inference

For formed Δ;Γ, define the partial function inferΔ;Γ(e) by structural recursion on e.

  1. A variable returns its unique declared type. Zero returns N.

  2. λ(x:A).e first checks ΔA::Ty, infers B for the body under Γ,x:A, and returns AB.

  3. For e1e2, infer C and A. Normalize C; it must have form DB, and conversion must accept A against D. Return B.

  4. A type abstraction checks the printed freshness premise, infers its body type A under Δ,u::κ;Γ, and returns u::κ.A.

  5. For e[C], infer and normalize the operator type. It must have form u::κ.A; infer the unique kind of C, require κ, and return A[C/u].

  6. A pair infers both components and returns their product. A projection infers and normalizes its argument type, requires a product head, and returns the selected component.

  7. For suc(e), infer the argument type, require conversion with N, and return N.

Every requirement invokes the kind and conversion decisions proved in corollary 7.26. A failed requirement rejects the term. The cases cover variables, abstractions, applications, type abstractions, type applications, pairs, projections, and successors: exactly the term grammar. Thus the definition specifies every possible conversion test.

Theorem 11.42 — Correctness of syntax-directed term inference

For formed Δ;Γ:

  1. if inferΔ;Γ(e)=B, then Δ;Γe:B;

  2. if Δ;Γe:A, inference succeeds with some B such that ΔBA::Ty.

Consequently an explicitly annotated checking request e:A is accepted exactly when inference returns B and conversion accepts B against A.

Proof of Theorem 11.42 — Correctness of syntax-directed term inference

Proof. For soundness, induct over the recursive call. At application, type application, and projection, the computed normal head is convertible to the inferred premise type by theorem 7.25; insert T-Conv at that premise and apply the matching syntax rule. The argument checks insert one further T-Conv. Every other case applies its displayed typing rule directly.

For completeness, induct on the term after stripping the final conversion with lemma 7.28. The exposed syntax rule determines the recursive premises. The induction hypothesis for each premise Δ;Γe:A is the conjunction inferΔ;Γ(e)=Bfor some B, andΔBA::Ty.

For application, the stripped derivation has premises e1:CD and e2:C. The first induction hypothesis returns some ECD. By the conversion characterization, the normal form of E has shape CD; head injectivity gives CC and DD. The second induction hypothesis returns E2C, so transitivity gives E2C and the argument guard succeeds. Inference returns D, which is convertible to the stripped conclusion D and hence, after composing with the stripped final conversion, to the original requested type.

For type application e[C], the exposed operator premise has type u::κ.A. Its induction hypothesis returns an E convertible to that universal, so normalization exposes u::κ.A with AA after opening the binders; kind uniqueness validates the printed argument C, and equality substitution gives A[C/u]A[C/u] for the returned type. For prie, the exposed premise types e at C1×C2. Its induction hypothesis returns an E whose normal form is C1×C2; product injectivity gives CiCi, so the selected returned component is convertible to the declarative result.

At a lambda, the printed domain is formed by the typing premise, the body induction hypothesis succeeds, and Q-Arr relates the returned arrow to the declarative one. At a type abstraction, the printed freshness premise is the one in the exposed T-TLam rule; the body induction hypothesis and Q-All relate the returned universal type. A pair uses its two induction hypotheses and Q-Prod. Zero returns N. For a successor, the induction hypothesis returns a type convertible to N, so its guard succeeds and it returns N. These cases exhaust the term grammar. The final statement is the two directions followed by one conversion comparison. ◻

Lemma 7.30 — Closed normal types

If A::Ty with A closed and normal, then A is N, A1A2, A1×A2, u::κ.A0, or u::κ.A0, with normal components.

Proof of Lemma 7.30 — Closed normal types

Proof. Invert the kinding derivation while following the left spine of a putative normal application. Its head cannot be a constructor abstraction, for then the application would be a TR-Beta redex. Nor can the head be N, an arrow, a product, or either quantifier: each has kind Ty, whereas every applied head must have an arrow kind. By kind uniqueness, the only remaining possible head is a variable. Closedness excludes that case. Thus a closed normal constructor of kind Ty is not an application or abstraction. Inverting its outer kinding rule leaves exactly the five listed forms, and normality of the whole constructor implies normality of every component. ◻

Exercise 7.5

★☆☆ Decide, by computing normal forms, whether Map(CompPP)MapP::Ty holds, with Map, P, Comp as above.

Sources.

The kind and constructor discipline is the Church-style Fω presentation of [Har16], extended here by the primitive data used in the examples and by the existential former in the displayed constructor grammar. The normalization, confluence, conversion decision, and pure call-by-value safety proofs are reproduced locally rather than imported from that presentation. Package values and package reduction are not part of this chapter’s safety theorem; the package chapter adds them as a conservative term-language extension. Cardelli and Wegner’s parametric type operators supply the historical higher-kinded boundary [CW85]. Equirecursive Fωμ has a different equality and safety signature, with decidable type checking stated only for its first-order-recursive fragment [CGO16]; none of that recursive extension is inherited here. Finite-rank reconstruction is likewise a separate problem. Kfoury and Tiuryn’s Theorem 20 decides whether a pure term, under a supplied environment of closed rank-one types, has an extending environment and a rank-two result type in their second-order system [KT92]. It does not supply inference for the Church-style calculus developed in this chapter.

Constructor reduction is normalizing and confluent. Hence constructor conversion is decidable, and T-Conv has an effective equality test. The separate term relation preserves typing, and every closed well-typed pure term is a value or takes a call-by-value step.

Suggested first pass.

Begin with exercise 7.3, then implement exercise 11.9; use exercise 7.4 to audit the normalization invariant.

Exercise 7.3

★☆☆ Delete the annotation, so that abstraction is written λu.A with the rule premise Δ,u::κ1A::κ2 for an arbitrary κ1. Give two kinding derivations assigning the single constructor λu.u the distinct kinds TyTy and (TyTy)(TyTy), showing that lemma 7.9 fails in Curry style.

Exercise 11.9

★★★ Practical project.fomega-checker Implement kind inference, constructor normalization, and explicit term checking for definition 7.2, definition 7.6, definition 11.41. Preserve the invariant that every normalized constructor retains its inferred kind, and handle T-Conv by comparing alpha-equivalent normal forms. The acceptance test must infer the kind of Map, normalize CompPPN, accept dmap at its application-headed type, reject the failed ca formation attempt without a higher kind for c, and reject two distinct normal head constructors as nonconvertible.

Exercise 7.4

★★☆ Suppose the base reducibility set RedTy were changed from strongly normalizing constructors to constructors having at least one terminating reduction sequence. Show first that (CR1) already fails, and then identify the subsidiary (CR3) induction that consequently loses its reduction-height measure. Use the unkinded constructor shape (λx::Ty.N)((λu::Ty.uu)(λu::Ty.uu)) to explain why one terminating path does not bound all congruence-closed paths. State why reducibility is defined on unkinded constructors before kinding selects the well-formed ones.

Search the book

Type to search the local edition.