Lectures onType Theory
Chapter 20
Chapter 20Core route

Intersection, Union, and Semantic Subtyping

Suppose one function returns its argument unchanged. The same function satisfies both typings NatNatandBoolBool. An intersection type records several typings of one value. A single arrow with domain NatBool is also too weak if it forgets which result corresponds to which input. The useful type is therefore (NatNat)(BoolBool). The same obstruction appears after control flow. If one branch returns a natural and another a Boolean, neither branch type is above the other. Their least set-theoretic join is the union type NatBool, whose values may come from either branch.

Chapter 8 ordered the types built from the ordinary constructors, using a declarative relation <:; joins and meets were properties of that order, not syntax. Here we change the language: ,,¬ are type constructors. Its semantic order is literal inclusion of type interpretations. The two orders obey familiar laws, but no unstated identification between them is used.

The notation suggests sets, but that suggestion is not yet a definition. For products, unions, and complements, ordinary sets suffice. For arrows, “the set of all functions between two sets” creates two problems. Write D for the set of values we are trying to build. A function value would then be a set of input-output pairs drawn from D itself, so the defining equation contains D on both sides; Cantor’s theorem also forbids the resulting full-powerset equation. The required domain must therefore admit finite observable graphs without containing its full powerset, and its definition must be stratified so that every graph mentions only values from smaller ranks.

One value, two specifications

Fix three nonempty, pairwise disjoint sets of constants, with basic types Nat, Bool, and Unit. We use constants zero,succ(zero),, true,false, and unit.

Definition 9.4 — Finite types and atoms

Types are finite trees generated by A,B::=0bA×BABAB¬A. Define 1:=¬0, AB:=¬(¬A¬B), and AB:=A¬B. An atom is a basic type, a product type, or an arrow type. Boolean connectives may occur inside the two components of product and arrow atoms. There are no infinite or recursive type trees.

Call the finite annotated calculus developed in this chapter λFG, for “finite graphs.”

This spelling keeps term constants distinct from the empty type 0 and universal type 1:=¬0.

An overloaded abstraction carries a nonempty interface: λ(A1B1;;AnBn)x.e. The annotation says that the same body must meet every arrow specification. The immediate obligation is to state when all of these arrow specifications may be assigned to one abstraction.

Definition 9.1 — Interface, intersection, and application rules

Write I=(A1B1;;AnBn) for a nonempty written interface. A well-shaped interface has n=1, or, when overloaded, has only test types—the Boolean shape tests generated by the grammar below—as its domains. Here 0 and 1 are the empty and universal types, written Bot and Top in chapter 8. A test type is generated by U,V::=01bFunU×VUVUV¬U, where the only arrow form is the universal function test Fun=01. The terms in this fragment are generated by e::=xλIx.e; the abstraction binds x in e. The interface well-shapedness condition belongs to abstraction introduction. The intersection-introduction fragment has three rules:

x:AΓ
Γx:A
T-Var
Γ,x:Aie:Bi(1in)
ΓλIx.e:i=1n(AiBi)
T-Abs
Γe:AΓe:B
Γe:AB
T-Inter

Rule T-Abs carries the interface side condition. These rules contain no subtyping premise. They state only that one annotated body checks at every written arrow and that the resulting term may retain more than one independently derived type.

Take e=x. The complete abstraction derivation is x:Natx:Natx:Natx:NatTVarx:Boolx:Boolx:Boolx:BoolTVarλ(NatNat;BoolBool)x.x:(NatNat)(BoolBool)TAbs. Define the one-body overloaded identity in this derivation as same; it has type (9.1) without relying on an undeclared primitive operation.

An intersection is not a product. A value of A×B is a pair, and projection selects a component. A value of AB is one value accepted at both types. There is no intersection constructor and no projection from an intersection. Rule T-Inter reuses both the expression and its context.

Intersection also has a resource-sensitive, non-idempotent meaning: repeated copies of a type record repeated uses rather than collapsing by AA=A. One representative comparison rule is Γe:AΔe:BΓΔe:AB. Here is multiset sum: multiplicities from both premises are added. We write only inside this comparison so that its resource-sensitive connective remains visibly distinct from the idempotent and from meta-level set intersection. The two contexts are multisets and therefore record two uses. Such systems can measure normalization, but those results do not transfer to the idempotent rule above, whose premises deliberately share Γ. We use intersection only as a set-theoretic specification connective here.

Exercise 9.2

★☆☆ Give a closed value at (NatNat)(BoolBool) which is not a pair. Explain why replacing by × changes both the value and its use.

The finite set-theoretic model

The finite model interprets the type grammar of definition 9.4: ,, and ¬ become Boolean operations on sets, while arrows become finite graphs.

For any candidate carrier D, put DΩ=D{Ω}, where ΩD. Trying to solve D=C+D2+P(D×DΩ) is impossible: the full powerset is strictly larger than D. Finite graphs remove that obstruction.

Omitting Ω creates a different failure. If graphs contained only edges in D×D, then the empty graph would vacuously satisfy every arrow atom and there would be no finite witness that a graph is undefined on one chosen input. In particular the counterexample edge {(d,Ω)} needed to refute an arrow membership could not be formed. The extra output marker records precisely this finite failure observation.

Definition 9.5 — Universal finite-graph domain

Let C be the disjoint union of the basic constants. The domain D is the universal finite-graph domain: the set of finite terms d::=c(d1,d2){(d1,δ1),,(dn,δn)},δ::=dΩ, including the empty graph. Equivalently, it is the initial solution of D=C+D2+Pf(D×DΩ). The three summands are disjoint and are called the basic, product, and function shapes. This use of shape classification is unrelated to the kinds that classify type operators in chapter 9.

Equivalently, rank a constant and the empty graph by zero, rank a pair one above the maximum rank of its components, and rank a nonempty graph one above the maximum rank of every input and non-Ω output occurring in it. If Dn is the set of terms of rank at most n, then D=nNDn. This cumulative presentation is the well-founded construction meant by “initial solution”; no cardinal fixed-point assumption is hidden in the notation.

The symbol Ω records that a graph may fail on an input. It is not a denotation of the empty type and belongs to no subset of D.

Definition 9.6 — Interpretation

Fix once and for all a finite family of basic type names b, nonempty pairwise disjoint tag sets Bb, and C=bBb. Every semantic judgment in this chapter is relative to this standing assignment. Define [[A]]D by structural recursion on the finite type tree A: [[0]]=,[[b]]=Bb,[[AB]]=[[A]][[B]],[[¬A]]=D[[A]],[[A×B]]=[[A]]×[[B]],[[AB]]={RPf(D×DΩ)(d,δ)Rd[[A]]δ[[B]]}. Semantic subtyping is inclusion of interpretations, and semantic equivalence is mutual inclusion: AB[[A]][[B]],A=DBABBA. 1

The interpretation [[]] is defined only for types. Term typing and reduction remain syntactic, and the typecase test inspects the exact finite shape of a value. No adequacy theorem relating abstractions to graph elements is assumed.

Consequently, this chapter does not identify AB with the coarser claim that every closed value typable at A is typable at B. The graph order deliberately contains failure edges (d,Ω) used by arrow inversion and callability; a value-only order would erase those witnesses and would require a different completeness argument. No agreement between the two orders is needed for the syntactic safety theorem.

No recursion on d is needed for these finite types: every denotation clause mentions only strict type subtrees. The rank recursion constructs the nested graph elements of the ambient domain D, while type denotation is structural recursion on finite types. The definition also shows why 11 is not the type of every graph: an edge (d,Ω) violates it. Every graph does inhabit 01, since there is no input in [[0]] on which it can fail.

Proposition 9.7 — Boolean laws and variance

The types modulo =D form a Boolean algebra. Products are covariant in both arguments. Arrows are contravariant in their domain and covariant in their codomain: AABB(AB)(AB). Moreover, ((AC)(BD))(AB)(CD), and (AB)(CD)(AC)(BD).

Proof of Proposition 9.7 — Boolean laws and variance

Proof. The Boolean and product claims are the corresponding set identities. For variance, a graph constrained on every A input is constrained on the smaller set A, and every permitted B output is a B output. For (9.4), an entry whose input is in AB satisfies at least one arrow constraint, so its output lies in CD. Formula (9.5) follows twice by variance. ◻

Neither inclusion is generally an equality. With disjoint nonempty A,B,C,D, a graph mapping an A input to a D output inhabits (AB)(CD) but not AC, disproving the converse of (9.4). A graph mapping an A input to C and a B input to D inhabits (AC)(BD) but not (AB)(CD), disproving the converse of (9.5). The empty graph inhabits every arrow; cardinality arguments about total mathematical functions therefore do not describe this model.

Corollary 9.8 — Subtyping is emptiness

For all finite types, AB[[A¬B]]=.

Proof of Corollary 9.8 — Subtyping is emptiness

Proof. [[A¬B]]=[[A]][[B]]. ◻

Exercise 9.5

★★☆ Prove (9.4) directly from graph membership. Then use four pairwise-disjoint nonempty types, for example Nat, Bool, Unit, and Nat×Nat, to construct a counterexample to its converse.

Exercise 9.6

★☆☆ Give a one-edge graph in 01 but not in 11. Explain the role of Ω.

Deciding emptiness

Set inclusion is transitive, but deciding AB requires a finite procedure on type syntax. We reduce the query to emptiness of A¬B.

Definition 9.9 — Disjunctive normal form

A normal form τ is a finite set of pairs (P,N) of finite sets of atoms. Its interpretation is [[τ]]=(P,N)τ(aP[[a]]aN[[a]]). Empty intersections denote D. Define mutually recursive functions N and N by N(0)=,N(a)={({a},)},N(AB)=N(A)N(B),N(¬A)=N(A),N(0)={(,)},N(a)={(,{a})},N(¬A)=N(A). For union on the negative side, define N(AB)={(P1P2,N1N2)(P1,N1)N(A), (P2,N2)N(B)}.

Lemma 9.10 — DNF correctness

For every type A, [[A]]=[[N(A)]],D[[A]]=[[N(A)]]. Both normal forms are computable.

Proof of Lemma 9.10 — DNF correctness

Proof. Simultaneous induction on A. For A=0, take the empty family of clauses; for an atom, the singleton clause has exactly the atom’s denotation. Union on the positive side is set union. On the negative side, clause pairing is justified by the explicit identity (P1N1)(P2N2)=(P1P2)(N1N2). Taking the union over all pairs of clauses gives the required complement of a union. Complement exchanges the two simultaneous induction hypotheses. ◻

Exercise 9.7

★☆☆ Compute N(a1(a2¬a3)) from the mutually recursive definition.

It remains to decide whether a single clause is empty. If its positive atoms have two different shapes, it is empty because the three summands of D are disjoint. Otherwise each possible runtime shape yields one obligation.

For fixed finite sets P,N of product atoms and NN, write L(P,N)=A×BPAA×BN¬A,R(P,N,N)=A×BPBA×BNN¬B.

Lemma 9.11 — Product decomposition

For finite sets P,N of product atoms, their clause is empty at product shape exactly when for every NN,L(P,N)=D0orR(P,N,N)=D0.

Proof of Lemma 9.11 — Product decomposition

Proof. For sets Xi,Yi use iP(Xi×Yi)iN(Xi×Yi)=NN(PXiNXi)×(PYiNNYi). A finite union of products is empty exactly when every product has an empty component. Interpreting the two components gives (9.7). ◻

For a concrete trace, normalize (Nat×Bool)¬(Nat×Nat). Here P={Nat×Bool} and N={Nat×Nat}. For N= the two components are Nat and Bool¬Nat=DBool, so neither is empty. For N=N the left component is Nat¬Nat=D0. Because the condition of lemma 9.11 fails at the first subset, the whole type is nonempty; (zero,true) is a witness. This is the complete product calculation before the additional failure edge Ω enters the arrow case.

Exercise 9.8

★★☆ Use (9.7) to prove (A×B)¬(C×D)=D0 exactly when A=D0, or B=D0, or both AC and BD.

For arrows, let P and N be finite sets of arrow atoms. Fix a negative arrow A0B0N. For PP put DomOb(P)=A0ABP¬A,CodOb(P)=¬B0ABPPB.

Lemma 9.12 — Arrow decomposition

The function-shape clause determined by P,N is empty exactly when there is an A0B0N such that, for every PP, DomOb(P)=D0or(PP and CodOb(P)=D0).

Proof of Lemma 9.12 — Arrow decomposition

Proof. An arrow denotes the finite powerset of the complement, taken inside D×DΩ, of [[A]]×(DΩ[[B]]). For finite families, iPPf(Xi)jNPf(Xj)some jN satisfies iPXiXj. If some j works, the right-hand inclusion immediately implies the left. Conversely, if no j works, choose one witness outside each Xj; the finite set of witnesses belongs to every Pf(Xi) but to none of the Pf(Xj), contradicting the left-hand inclusion. Expanding the chosen inclusion says that every bad edge for A0B0 must be bad for some positive arrow: [[A0]]×(DΩ[[B0]])AiBiP[[Ai]]×(DΩ[[Bi]]). Suppose an edge (d,δ) is uncovered, and define its exact miss set M={AiBiPd[[Ai]]}. Then d[[DomOb(M)]]. If MP, the uncoveredness condition forces δ to be an ordinary output in every Bi with iM, so δ[[CodOb(M)]]. If M=P, the obligation at P=P is only DomOb(P)=D0, and d refutes it; no codomain witness is required. Equivalently, pairing d with Ω supplies an uncovered edge because Ω belongs to no positive codomain.

Conversely, fix any PP. A witness d for its domain obligation misses every positive arrow in P. When PP, an ordinary witness δ for its codomain obligation belongs to every remaining positive codomain. Hence no positive arrow covers (d,δ). For P=P, pair d with Ω, which belongs to no positive codomain. In either case the edge violates (9.11). Thus the cover holds exactly when every P has empty DomOb(P), or has PP and empty CodOb(P), which is (9.9). ◻

Exercise 9.9 — *

★★☆ Specialize (9.9) to prove (A1B1)(A2B2)AB exactly when all four subset rows induced by P{1,2} close. State the rows explicitly; the row P={1,2} has only a domain obligation.

Lemma 20.11 — Basic-shape emptiness

Let P,N be finite sets of basic atoms. Their clause is empty at basic shape exactly when bPBbbNBb, where the empty positive intersection is the basic summand C, not the whole domain D. This condition is decidable.

Proof of Lemma 20.11 — Basic-shape emptiness

Proof. Intersecting the positive basic denotations and removing the union of the negative ones is empty exactly when the displayed inclusion holds. The fixed family of basic tags is finite and pairwise disjoint, so the inclusion reduces to a finite tag-membership test. ◻

The algorithm is memoized downward recursion. The equivalent finite-simulation presentation gives a table containing all mutually dependent emptiness obligations rather than only those reached from one query.

Definition 9.13 — Finite simulations

Let Q contain every atom occurring in a query normal form, including atoms nested inside product and arrow atoms. It is finite. Let NF(Q)=Pf(Pf(Q)×Pf(Q)). For a shape k, let Qk be the atoms of Q having shape k. For SNF(Q), say that a clause (P,N) is S-empty at a shape as follows.

  1. At basic shape, the intersection of the positive tag sets is covered by the negative tag sets. With no positive basic atom, the intersection here is the whole basic summand C=bBb, not the whole domain D. The family of tag names is finite and disjoint, and tag coverage is decidable even when a tag contains infinitely many constants.

  2. At product shape, every NN satisfies N(L(P,N))S or N(R(P,N,N))S.

  3. At function shape, some A0B0N satisfies, for every PP, either N(DomOb(P))S, or PP and N(CodOb(P))S.

A normal form τ is an immediate consequence of S when, for each clause (P,N)τ and each shape k, either P contains an atom of a different shape or (P,NQk) is S-empty at shape k. A set S is a simulation when every member of S is an immediate consequence of S.

A simulation is a finite table of claims that normal forms are empty. A row may justify itself only through component claims already in the table. For example, the singleton table {N(Nat¬Nat)} is a simulation: its one basic-shape row is closed by tag coverage. The greatest simulation is exactly the set of empty normal forms: soundness excludes an element from every row, while completeness places each empty component obligation back in the table.

Every component obligation uses an atom in Q. Closing Q under the atoms nested in products and arrows therefore keeps the simulation table finite and closed under its own recursive obligations.

Lemma 9.14 — Simulation soundness

If S is a simulation and τS, then [[τ]]=.

Proof of Lemma 9.14 — Simulation soundness

Proof. It is enough to prove that no dD belongs to a member of S. Induct on the finite construction of d. For a constant, the basic coverage condition excludes it. For (d1,d2), product decomposition selects, for every allocation of negative atoms, a component normal form in S; the induction hypothesis excludes d1 or d2. For a finite graph, clause (iii) gives an index j and negative arrow CjDj. If the graph satisfies it, that negative atom excludes the graph. Otherwise an edge violates it. Apply (9.9) to that edge; the induction hypothesis excludes its strictly smaller input or output from the corresponding normal form. If the output is Ω, the codomain alternative is automatically excluded. Thus every runtime shape is absent from every clause. ◻

Lemma 9.15 — Simulation completeness

If [[τ]]=, there is a simulation SNF(Q) containing τ.

Proof of Lemma 9.15 — Simulation completeness

Proof. Take S0={σNF(Q)[[σ]]=}. It contains τ. Basic coverage and the two exact decomposition lemmas show that every clause in every σS0 satisfies the corresponding immediate-consequence condition with component normal forms again in S0. Shapes are disjoint, so a positive atom of another shape closes the remaining cases. Hence S0 is a simulation. ◻

Theorem 9.16 — Emptiness and semantic subtyping are decidable

There is a total procedure deciding [[A]]= and AB for finite types.

Proof of Theorem 9.16 — Emptiness and semantic subtyping are decidable

Proof. Compute τ=N(A) and use the following memoized recursive test on its clauses. A clause is empty when it is empty at every runtime shape. For a candidate shape k, the clause is immediately empty at k if it contains a positive atom whose shape is not k. At basic shape, apply lemma 20.11, restricting negative atoms to the basic shape and using C for an empty positive family. At product shape, enumerate NN and recursively test whether N(L(P,N)) or N(R(P,N,N)) is empty. At function shape, try each negative arrow and, for every PP, recursively test the domain obligation or the permitted codomain obligation from (9.9). A normal form is empty exactly when all of its clauses are empty. Cache answers by normalized syntax.

Every recursive obligation strictly decreases the multiset of depths of its nested product or arrow atoms, so this is a total procedure on finite type trees. Basic coverage and the exact product and arrow decomposition lemmas prove its soundness and completeness by induction on that multiset. Equivalently, its accepted memo table is contained in a finite simulation by lemma 9.14, lemma 9.15. Decide AB by testing A¬B and using corollary 9.8. ◻

If q=|Q|, there are at most 4q clauses and 24q normal forms over Q. Materializing the whole greatest- simulation table therefore gives only a finite decision proof, not a practical implementation. The memoized downward test above visits only obligations reached from the query, although its subset branching can still be exponential.

The overload inclusion from the opening can now be decided without guessing a graph. The following trace exhibits every recursive obligation made by the arrow clause.

Example 9.17 — A complete subtype-decision trace

Put Nt=Nat, Bt=Bool, and St=NtBt. To decide (NtNt)(BtBt)StSt, normalize the difference between the two sides. It is the one function-shape clause P={NtNt,BtBt},N={StSt}. Its nested-atom closure is Q={Nt,Bt,NtNt,BtBt,StSt}. The sole negative arrow fixes A0=B0=St. Choose PP. Then lemma 9.12 asks whether DomOb(P) is empty or, when PP, whether CodOb(P) is empty. The four calculations are PDomOb(P)CodOb(P)St¬StNtBt=D0{NtNt}Bt¬StBt=D0{BtBt}Nt¬StNt=D0PSt¬Nt¬Bt=D0not available. The first row closes because NtBt=D0; the next two close because BtSt and NtSt, respectively; the final row closes on its domain component. The difference is empty, so the requested inclusion holds. If both component obligations in one row are nonempty, choose an uncovered input and output; their one-edge graph is a finite counterexample.

Exercise 9.10

★★☆ Use the trace of example 9.17 to decide (NatNat)(BoolBool)(NatBool)Nat. Identify the first row in which neither component is empty, and construct the one-edge graph witnessing failure of the inclusion.

The call-by-value calculus

The semantic relation can safely drive application, but only with an explicit callability premise. The function-shape top 01 alone is not enough: it contains graphs that fail with Ω on every nonempty domain.

Definition 9.18 — Test types, terms, and admissible interfaces

Runtime tests contain no precise arrow atoms: U,V::=01bFunU×VUVUV¬U,Fun:=01. Terms and values are e::=cx(e,e)πieλ(A1B1;;AnBn)x.eeecaseType e as x in Uee,v::=c(v,v)λ(A1B1;;AnBn)x.e. Interfaces are nonempty and denote I=i(AiBi). The grammar above makes the well-shapedness condition of definition 9.1 syntactic: an interface has one arbitrary domain, or all its domains are test types. This admits the single-arrow self-application example and the multi-arrow Nat/Bool overload while keeping finite branch selection structural.

The restriction excludes the tempting two-arrow interface whose domains are 11 and ¬(11). Although Fun(11)¬(11), a lambda known only at Fun need be typable at neither arm. For that interface, neither branch judgment required by beta preservation is derivable. The tautology Fun1 proves only membership in the universal type, not either proposed arm.

The phrase “the value passes the test” must not hide a semantic oracle. Tests inspect only the finite value already obtained.

Definition 9.19 — Structural test

The decidable judgment vU, read “v passes test U,” is defined by the following exhaustive clauses: v0never,v1always,vbv=c and cBb,vFunv=λIx.e,vU×Vv=(v1,v2), v1U, and v2V,vUVvU or vV,vUVvU and vV,v¬UvU. The shape equations make a pair fail every basic and Fun test, a constant fail every product and Fun test, and an abstraction fail every basic and product test.

For example, zeroBNat and trueBBool, so the membership derivation is zeroBNatzeroNatMBasictrueBBooltrueBoolMBasic(zero,true)Nat×BoolMPair. The labels M-Basic and M-Pair name the basic-constant and pair instances of the structural equations; they are decision clauses, not typing rules.

Definition 9.20 — Weak call-by-value reduction

Evaluation contexts are E::=[ ](E,e)(v,E)πiEEevEcaseType E as x in Ue1e2. The basic reductions are (λIx.e)ve[v/x],πi(v1,v2)vi,caseType v as x in Ue1e2e1[v/x]if vU,e2[v/x]if vU. Context closure gives weak left-to-right call-by-value reduction.

Consequently the selected branch is determined before substitution, and the complete root trace is caseType (zero,true) as x inNat×Boolπ1xfalseπ1(zero,true)zero. No typing derivation is consulted by either step.

The role of Ω is exact. An edge (d,Ω) records failure on d and excludes its graph from AB when d[[A]]. On Ω-free graphs every A1 constraint permits every result; on all graphs, 01 is the function-shape top. We therefore define a function type F to be callable on a static argument type S when FS1. Callability determines whether application is safe. Its least result type requires a separate calculation from the DNF clauses of F. For example, 01S1 when S is nonempty.

The application calculation needs one closure fact about negative arrows.

Lemma 9.21 — Strong disjunction for a function clause

Let K=iPc(AiBi)jNc¬(CjDj) be a nonempty function-shape clause, and put K+=iPc(AiBi). For every arrow SR, KSRK+SR.

Proof of Lemma 9.21 — Strong disjunction for a function clause

Proof. The right-to-left implication is subsumption because KK+. Conversely, suppose KSR but choose a finite graph G[[K+]][[SR]]. Since K is nonempty, choose H[[K]]. The union GH still satisfies every positive arrow: those conditions are universal over edges. For each negative arrow in the clause, H already has an edge that violates it, and adjoining edges cannot remove that witness. Thus GH[[K]]. The edge by which G violates SR also remains, so GH[[SR]], a contradiction. ◻

Definition 9.22 — Least application output

Assume F01. Normalize F(01) to function-shape clauses. The conjunct 01 forces every surviving clause into the function shape, so the domain and output constructions below never face a basic or product clause. It does not otherwise refine F, because the premise already gives F=DF(01). For a nonempty clause with positive-arrow set Pc={AiBiiKc} put Domc(Pc)=iKcAi,ρc(Pc)={(iKAi,iKcKBi)|KKc}. For a finite union of clauses, define Dom(F) by intersecting the Domc types of the nonempty clauses, and define ρ(F) by uniting their ρc sets. The empty union has Dom(0)=1 and ρ(0)=. When FS1, define FS=(U,V)ρ(F), SUV. The circle is an operation on types; it does not compose terms. Negative arrow atoms affect whether a clause is empty, but lemma 9.21 shows that they do not change its arrow supertypes once the clause is known nonempty.

Lemma 9.23 — Application-output characterization

If F01 and FS1, then FSBFSB. The operation FS is computable.

Proof of Lemma 9.23 — Application-output characterization

Proof. Fix a nonempty clause c. By lemma 9.21, its negative arrows may be discarded when checking the supertype SB. Apply lemma 9.12 to the remaining positive arrows and the one negative arrow SB. At a subset KKc, its two emptiness tests translate exactly as SiK¬Ai=D0SiKAi,¬BiKcKBi=D0iKcKBiB. For K=Kc, arrow decomposition permits only the first test; this is SDomc(Pc). The proper subsets give precisely the pairs in ρc(Pc). Finally, FSB holds exactly when every nonempty clause has this property. Intersecting their domain types and uniting their proper-subset pairs therefore gives FSBSDom(F)  (U,V)ρ(F). SU  VB. The callability premise is precisely the domain conjunct. The remaining finite family says that every V whose U fails to cover S is below B, which is equivalent to their union (9.13) being below B. DNF, emptiness, and every comparison are computable by theorem 9.16. ◻

Let I=(NatNat)(BoolBool). Because I01, the normalized conjunct I(01) is equivalent to I; we use this simplified representative. Its one positive-arrow clause has index set Kc={N,B}. The three proper subsets of Kc give ρ(I)={(0,NatBool),(Nat,Bool),(Bool,Nat)}. The basic tags are disjoint, so the first output is 0. Applying (9.13) three times yields INat=ρrow(Bool,Nat)Nat,IBool=ρrow(Nat,Bool)Bool,I(NatBool)=bothsingletonrowsNatBool. Thus a precise argument retains its corresponding promise, while an imprecise argument returns exactly the union of the two results.

Projection has a simpler clausewise definition. Normalize A×(1×1) and consider one nonempty product-shape clause with positive product atoms Pc and negative product atoms Nc. Using (9.6), we make the construction explicit.

Definition 9.24 — Least projection outputs

For one nonempty product-shape clause define out1(Pc,Nc)=NNcR(Pc,Nc,N)D0L(Pc,N), out2(Pc,Nc)=NNcL(Pc,N)D0R(Pc,Nc,N). The empty join is 0. Let proji(A×) be the union of outi over all nonempty clauses.

Lemma 9.25 — Projection-output characterization

If A×1×1, both projection outputs are computable and A×A×1proj1(A×)A,A×1×Aproj2(A×)A.

Proof of Lemma 9.25 — Projection-output characterization

Proof. The product decomposition writes each clause as the union, over NNc, of the rectangles L(Pc,N)×R(Pc,Nc,N). Its first-coordinate image is therefore the union of the left components whose right component is nonempty, exactly out1; the second-coordinate statement is symmetric. Inclusion of that finite union in A is equivalent to inclusion of the whole clause in A×1. Taking the union over clauses proves both equivalences. Every emptiness test and finite union is computable by theorem 9.16. ◻

Definition 9.26 — Declarative typing

The typing relation is generated by the three rules of definition 9.1, the following application and subsumption rules, and four rules for constants, pairs, projections, and typecase. Each abstraction interface must be well shaped in the sense of definition 9.1. Contexts are lists of pairwise distinct term variables, and extending Γ by x:A presupposes xdom(Γ). A judgment Γe:A is formed only when fv(e)dom(Γ), treating the abstraction and typecase binders as binders.

Γe1:FΓe2:SFSB
Γe1e2:B
T-App
Γe:AAB
Γe:B
T-Sub
cBb
Γc:b
T-Const
Γe1:AΓe2:B
Γ(e1,e2):A×B
T-Pair
Γe:A×A×1×1
Γπie:proji(A×)
T-Proj
Γe:Sxdom(Γ)fv(e+)fv(e)dom(Γ){x}SUD0Γ,x:SUe+:B+S¬UD0Γ,x:S¬Ue:BSU=D0B+=0S¬U=D0B=0
ΓcaseType e as x in Ue+e:B+B
T-Case

The two explicit scope premises in T-Case remain mandatory even when an empty refinement suppresses a branch’s typing premise. Each implication in T-Case is a decidable rule schema. When its antecedent is true, the consequent is an ordinary premise and a rule-induction proof receives an induction hypothesis for it; when false, there is no such premise. Thus an empty refinement suppresses only its branch-typing premise, not the explicit scope check on the branch syntax. There is no general principle that arbitrary syntax becomes typable merely because a context contains an empty assumption.

For I=(A1B1;;AnBn), rule T-Abs concludes exactly i(AiBi); no negative arrow occurs in its conclusion. Thus intersection introduction and least-type synthesis use the same positive interface. By lemma 9.23, the least conclusion of T-App is FS: its premise FSB implies both F01 and FS1, and the characterization then gives FSB. Every other conclusion follows from the least one by subsumption.

Lemma 9.27 — Structural rules

The following transformations are admissible for the typing judgment of definition 9.26: whenever their premises are derivable, so are their conclusions.

  1. If Γ has the same domain as Γ and Γ(x)Γ(x) pointwise, every judgment under Γ remains derivable under Γ.

  2. If Γe:B and ydom(Γ), then Γ,y:Ce:B.

  3. If Γ,x:A,Δe:B and Γv:A, then Γ,Δe[v/x]:B. The usual substitution statement is the case Δ=.

Proof of Lemma 9.27 — Structural rules

Proof. Each clause is an induction on its typing derivation.

For narrowing, the induction hypothesis says that each immediate typing premise remains derivable after replacing the outer context by its pointwise smaller context. In the variable case, if y:CΓ and Γ(y)=CC, then T-Var gives Γy:C and T-Sub gives Γy:C. Constants have no typing premise. Pair, projection, application, intersection, and subsumption reapply their rule to the induction hypotheses; their semantic side conditions mention types, not the context. For T-Abs, extend both contexts by the same x:Ai and apply the induction hypothesis separately to each body derivation. For T-Case, extend both contexts by the same x:SU or x:S¬U. The nonemptiness tests and the two scope premises are unchanged because the domains of Γ and Γ agree. Thus narrowing preserves both branch derivations of T-Case, including their nonemptiness and scope premises.

For weakening, induct again on the last rule. Constants and variables reapply their rules in the extended context, and each nonbinding constructor uses the induction hypotheses for its immediate subterms. Before an abstraction or typecase case, alpha-rename its binder away from the fresh variable y; then apply the induction hypothesis under the extended binder. The scope premise for a typecase remains true because its permitted domain has only grown.

For substitution, the induction hypothesis is the exact assertion Γ,x:A,Δe:C,Γv:AΓ,Δe[v/x]:C, where all types are unchanged because this calculus has no type variables. If e=x, use the assumed derivation Γv:A; if e=yx, reapply T-Var to the unchanged declaration of y. Constants are unchanged. Pair, projection, application, intersection, and subsumption apply the induction hypothesis to each term premise and then reapply the same rule.

For an abstraction with binder z, alpha-rename so that zx and zfv(v). Apply the induction hypothesis directly with suffix Δ,z:Ai; its value premise remains the assumed Γv:A, and its conclusion has context Γ,Δ,z:Ai. Then T-Abs rebuilds the abstraction. The typecase binder is handled identically, once under z:SU and once under z:S¬U. Its conditional branch premises are unchanged because substitution does not alter S or U. Finally, the elementary scope-substitution fact fv(e)dom(Γ){x}fv(e[v/x])dom(Γ) preserves both explicit branch-scope premises. Thus Γ,x:A,Δe:C and Γv:A imply Γ,Δe[v/x]:C. ◻

For preservation we need to recover what a value’s outer constructor actually introduced, before subsumption obscured it.

Definition 9.28 — Exact introduction type of a value

For a value whose annotations and bodies typecheck, define vt(c):=bc,vt((v1,v2)):=vt(v1)×vt(v2),vt(λIx.e):=I, where the disjoint basic tags determine the unique bc containing c.

Lemma 9.29 — Exact value typing

If Γv:A, then Γv:vt(v), vt(v)A, and vt(v)D0. More precisely:

  1. if v=(v1,v2), there are A1,A2 with Γvi:Ai and A1×A2A;

  2. if v=λ(AiBi)ix.e, every premise Γ,x:Aie:Bi holds and i(AiBi)A.

Proof of Lemma 9.29 — Exact value typing

Proof. Induct on the typing derivation. Rules T-Const, T-Pair, and T-Abs give the three exact types and the displayed inversion data. For T-Sub, compose the induction-hypothesis inclusion with its subtype premise. For T-Inter, the two induction hypotheses have the same value syntax and hence the same exact type; combine their inclusions into the intersection. No other typing rule concludes with value syntax.

Nonemptiness is by value shape. The actual constant c inhabits its tag; the pair of witnesses inhabits the product; and the empty finite graph inhabits every arrow in a nonempty interface, hence their intersection. ◻

Lemma 9.30 — Value refinement and canonical forms

If Γv:S, then for every test type U, vUvt(v)U and Γv:SU,vUvt(v)¬U and Γv:S¬U. No value has type 0. A value at a type below 1×1 is a pair, and a value at a type below 01 is an annotated abstraction.

Proof of Lemma 9.30 — Value refinement and canonical forms

Proof. Induct simultaneously on the value and test type to prove vt(v)U when vU, and vt(v)¬U otherwise. Basic tags use disjointness; product tests use the two component hypotheses; and the Fun test uses the annotated-abstraction shape. Boolean cases are the corresponding set identities. Combine either inclusion with lemma 9.29 and subsume to the required intersection.

If Γv:0, exact value typing would put the nonempty vt(v) below 0, a contradiction. Finally, the three principal value shapes occupy disjoint summands of D; exact value typing therefore proves the pair and abstraction canonical forms. ◻

Union is a control-flow join

Subtyping introduces a union without changing the value. The following two rules are derived instances of T-Sub, using AAB and BAB:

Γe:A
Γe:AB
_1
Γe:B
Γe:AB
_2

Unlike A+B, the type AB adds no injection tag. The runtime must test a property already possessed by the value.

For the binder typecase of definition 9.18, if e:S, the then branch receives x:SU and the else branch receives x:S¬U. In particular, if S=AB and the test is A, the else type is (AB)¬A=DB¬A and is not generally B. If BA, the else refinement is 0, so rule T-Case has no typing premise for that branch. A value selecting the else branch would have type 0 by lemma 9.30, which is impossible. If A and B overlap, the refinement contains only the part of B outside A.

The binder matters. Refining a freely repeated expression would require a proof that every occurrence denotes the same runtime result. The binder names the already evaluated value once and makes that equality syntactic.

Remark 20.30 — Why there is no sum elimination without a tag

From e:AB one cannot choose an A branch or a B branch merely by inspecting the syntax by which e was typed. Subsumption can assign AB to the same value using either inclusion, and an intersection value may inhabit both arms. The typing derivation is erased at runtime. A sum value, by contrast, contains either inl or inr. Typecase therefore uses the decidable structural test of definition 9.19; it is not the eliminator for a tagged sum.

Exercise 9.4

★☆☆ State the extra runtime datum carried by A+B and absent from AB. Explain why ordinary case analysis cannot be a reduction rule for the latter.

Example 9.2 — The first overloaded application

By (9.4), (NatNat)(BoolBool) (NatBool)(NatBool). This inclusion is precisely the last premise of T-App. With I for the left side and S=NatBool, the complete last step is z:Ssame:Iz:Sz:Sz:Sz:STVarISSz:Ssame z:STApp. A binder typecase gives a second derivation: it refines z to Nat or Bool, obtains the corresponding result in each branch, and joins them. By lemma 9.23, the least output is IS=S.

Example 20.32 — A typed self-application

Intersection also types a genuine self occurrence. Put A=01,X=((A1)A). The type X is nonempty: the empty finite graph inhabits both arrow atoms. Under x:X, both occurrences synthesize X. We have X01 and XX1: the latter follows from XA1 and XA. Thus T-App gives x:Xx:Xx:Xx:XXX1x:Xxx:1TApp. Consequently λ(X1)x.xx:X1 is admitted without a recursive type equation. This is self-application inside the body, not the divergent term obtained by applying the abstraction to itself.

Exercise 9.1

★☆☆ Starting from the T-Abs derivation of same:(NatNat)(BoolBool), use subsumption to derive each arrow type separately. Then apply T-Inter to reconstruct its intersection type without using T-Abs a second time.

Exercise 9.3

★☆☆ Let S=AB. Compute both refinements for a test against A. Give one choice of A,B for which the else branch is empty and one for which it is a proper subtype of B.

Exercise 9.11

★☆☆ Return to the self-application derivation of example 20.32. Verify every subtype premise using the Boolean intersection eliminations and arrow variance of proposition 9.7.

Lemma 9.31 — Interface application

Let w=λIx.e have exact interface I=iKc(AiBi) under Γ, with the T-Abs premises Γ,x:Aie:Bi. If ISR and Γv:S, then Γe[v/x]:R.

Proof of Lemma 9.31 — Interface application

Proof. If the interface has one arrow A1B1, the value derivation Γv:S and the no-0-value clause of lemma 9.30 imply SD0. If some d lay in [[SA1]], the graph {(d,Ω)} would inhabit A1B1 but not SR; hence SA1. Choose d[[S]]. If some r[[B1R]], the ordinary-output graph {(d,r)} would again inhabit A1B1 but not SR; hence B1R. Substitution therefore types the body at B1, followed by subsumption.

Otherwise every Ai is a test type. Arrow decomposition gives SiAi. Put J={ivAi}. This set is nonempty: otherwise exact value refinement would put the nonempty vt(v) below the complement of every Ai, contradicting vt(v)S. In the ρ(I) obligation of definition 9.22, take K=KcJ. The exact value type is disjoint from iKAi, so SiKAi; the other half of that obligation is therefore iJBiR. For each iJ, (9.16) and subsumption type Γv:Ai; the corresponding T-Abs premise and substitution type the body at Bi. Rule T-Inter combines the derivations, and subsumption gives R. ◻

The value-shape step in this lemma is the local restriction inherited from the finite calculus: annotated values admit the finite Boolean split needed by an interface. It is not a claim of occurrence completeness for arbitrary open expressions.

Theorem 9.32 — Preservation

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

Proof of Theorem 9.32 — Preservation

Proof. Induct on the final typing rule. The induction hypothesis for an immediate premise Γe0:C says that every step e0e0 preserves exactly C.

First consider contextual steps. From Γ(e1,e2):A1×A2, the last-rule premises type both components. If e1e1, the induction hypothesis and T-Pair type e1,e2; if e1 is a value and e2e2, they type e1,e2. Rules T-Proj and T-Case use the induction hypothesis for their scrutinee. Rule T-App uses it first for the function and then, when the function is a value, for the argument. In every case the semantic side conditions are unchanged. A step below T-Sub is followed by the same subsumption. A step below T-Inter is preserved by both induction hypotheses, after which T-Inter is reapplied. Constants, variables, and abstractions have no contextual step under the weak reduction of definition 9.20.

There remain four root families. For π1(v1,v2)v1, lemma 9.29 gives Γvi:Ai and A1×A2P, with both Ai nonempty. Equation (9.15) gives Pproj1(P)×1. For every a1[[A1]], choose a2[[A2]]; the two product inclusions put (a1,a2) in [[proj1(P)×1]]. Hence A1proj1(P), and subsumption types the reduct. The second projection is symmetric.

For (λIx.e)ve[v/x], inversion by lemma 9.29 recovers every premise Γ,x:Aie:Bi and the inclusion IF. Inversion of T-App gives FSB; composing with IF gives ISB. The result is exactly lemma 9.31 with R=B.

For the then typecase root, (9.16) derives Γv:SU. Exact value typing shows that this refinement is nonempty, so the conditional then premise of T-Case is derivable. Substitution gives Γe+[v/x]:B+, followed by subsumption to B+B. If the test fails, (9.16) gives Γv:S¬U; substitution gives Γe[v/x]:B, followed by subsumption to the same union. ◻

Theorem 9.33 — Progress and safety

If e:A, then e is a value or some e satisfies ee. Consequently a closed well-typed term never reduces to a stuck nonvalue.

Proof of Theorem 9.33 — Progress and safety

Proof. Induct on the final typing rule, with induction hypothesis “the premise term is a value or it takes a step.” Constants and abstractions are values; a closed variable judgment is impossible. Subsumption does not change the term, so it uses its sole induction hypothesis. Intersection uses either premise, whose term is the same.

For a pair, step the left component if possible; if it is a value, step the right component; if both are values, the pair is a value. For a projection, first use the scrutinee induction hypothesis. If the scrutinee is a value, canonical forms from lemma 9.30 show that it is a pair, so one of the two projection roots applies.

For an application, first step its function, then its argument. If both are values, exact value typing gives a nonempty V=vt(v) with VF01. Canonical forms therefore show that the function value is an annotated abstraction. The beta root therefore applies. For typecase, first step the scrutinee. Once it is a value, the exhaustive clauses of definition 9.19 decide exactly one of vU and vU, so exactly one typecase root applies.

For safety, induct on the length of a reduction sequence. Preservation types the first reduct at A; progress applies again to it. Thus no finite prefix can end in a closed stuck nonvalue. ◻

The theorem applies exactly to the weak call-by-value relation of definition 9.20. To see why, consider a hypothetical extension rnd(AB) that nondeterministically returns either an A-value or a B-value. If beta reduction duplicated this expression before evaluating it, the two copies in (λx.(x,x))rnd(AB) could choose differently, so the result would no longer have the promised correlation type (A×A)(B×B). Likewise, if a pair (vA,e0):A×0 could be formed while e0 diverged and projection reduced before the second component became a value, π1(vA,e0) would produce an A-value from a product type with no values. These counterexamples require nondeterminism or divergence, neither of which belongs to the local calculus.

Exercise 9.12

★★☆ Prove the variable and abstraction cases of substitution, then use them in the beta case of theorem 9.32.

Exercise 9.13

★★☆ Write the full preservation derivation for both typecase reductions. Identify where the proof uses that the selected refinement is nonempty.

Least synthesis for annotated terms

Definition 9.34 — Synthesis

Define the partial function synΓ(e) by structural recursion. Constants return their basic tag, variables return their context type, and pairs return the product of component results. Projection of a synthesized A× succeeds when A×1×1 and returns proji(A×).

For an abstraction with interface I=i(AiBi), recursively reject first if the written interface is empty or is not well shaped according to definition 9.18. Otherwise recursively check its body under x:Ai against Bi for every i, then return I. For application, synthesize F and S; succeed exactly when F01 and FS1, then return FS.

For typecase, first decide the two finite-variable scope premises of T-Case and reject if either fails, then synthesize S for the scrutinee. An empty refinement contributes 0 without typechecking its branch; a nonempty refinement recursively synthesizes its branch under the refined binder. Return the union of the two branch results. Finally, checking e:A succeeds when synthesis returns some SA.

All recursion is on a strict term subexpression and all side conditions call the terminating subtype decider, so synthesis terminates.

Lemma 20.37 — Synthesis soundness

If synΓ(e)=S, then Γe:S.

Proof of Lemma 20.37 — Synthesis soundness

Proof. Suppose synΓ(e)=S and induct on e. Constants and variables use T-Const and T-Var; a pair uses the two induction hypotheses and T-Pair. For a projection, the recursive call gives Γe0:P, and the successful side condition gives P1×1, so T-Proj returns the stated output. For an abstraction, success entails nonemptiness and well-shapedness of the interface. For every arrow AiBi, the body induction returns CiBi; subsumption checks that branch at Bi. Thus T-Abs returns exactly the written interface I.

For application, the recursive calls give Γe1:F and Γe2:S0. The two successful side conditions meet the hypotheses of lemma 9.23, whose right-to-left direction gives FS0(FS0). Rule T-App therefore derives the returned type. For typecase, a nonempty refinement has a recursively synthesized branch, which the induction hypothesis types at its returned type. An empty refinement contributes 0 and activates no branch-typing premise. The scope checks and these two alternatives are exactly the premises of T-Case, so that rule derives the returned union. This proves synΓ(e)=SΓe:S. ◻

Lemma 20.38 — Synthesis leastness

If Γe:A, then synΓ(e)=S for some SA.

Proof of Lemma 20.38 — Synthesis leastness

Proof. Induct on a derivation of Γe:A. The constant, variable, and pair cases follow directly from the induction hypotheses. Under T-Sub, a synthesized SA0 is below the new conclusion by transitivity. The two T-Inter premises concern the same syntax; the deterministic recursive function therefore returns the same S for both, and SA and SB imply SAB.

For T-Proj, let A×,0 be the synthesized scrutinee type. The induction hypothesis gives A×,0A×, hence A×,01×1. From A×proji(A×)×1 (with the factors exchanged for i=2) and A×,0A×, the projection characterization yields proji(A×,0)proji(A×). Thus the synthesized projection type is below the declarative conclusion. In T-Abs, the declarative rule guarantees that the written interface is well shaped. Each body induction returns a subtype of its declared Bi, so synthesis returns exactly that interface I, with II.

For T-App, let the recursive calls return F0F and S0S. The premise FSB, arrow variance, and transitivity give F0IHFtypingpremiseSBS0SandvarianceS0BB1S010S0andvariance01. Thus both algorithmic callability checks succeed, and lemma 9.23 gives F0S0B.

For T-Case, if the synthesized scrutinee type is S0S, context narrowing changes a branch premise under x:SU to one under x:S0U. Replacing U by ¬U gives the corresponding else-branch narrowing. If the new refinement is nonempty, the old one is also nonempty; the branch induction hypothesis therefore returns a subtype of B+ or B. If the new refinement is empty, synthesis contributes 0, already below the corresponding branch type. The explicit scope premises ensure that its preliminary scope checks succeed. Hence the returned union is below B+B. Therefore Γe:AsynΓ(e)=S for some SA. ◻

Theorem 9.35 — Checker characterization

For finite annotated terms, including terms whose interfaces or free variables may be rejected, Γe:AsynΓ(e)=S for some SA. Thus declarative typechecking is decidable. When synthesis succeeds, S is the least type, up to =D, among the declarative types of this term with its fixed annotations and fixed context.

Proof of Theorem 9.35 — Checker characterization

Proof. Apply lemma 20.38 for the forward implication. Conversely, lemma 20.37 types e at S. Rule T-Sub then uses SA. The final claim is the quantified leastness conclusion. ◻

The qualification “with fixed annotations” is essential. The procedure checks a written interface; it neither infers one nor proves a principal-type theorem for an unannotated intersection language.

Exercise 9.14

★★☆ Trace synthesis for same and for its direct application to Nat, Bool, and NatBool. Compare the last result with (9.2).

Exercise 9.15

★★☆ Trace synthesis for xx under x:X and then for the annotated abstraction in example 20.32.

Exercise 20.16

★★★ Prove the application case of the checker characterization in both directions. For completeness, start from a declarative T-App derivation and recursive results F0F and S0S; derive both algorithmic callability tests and F0S0B. For soundness, start from a successful algorithmic application call and reconstruct a declarative T-App conclusion at its returned type. Name every use of arrow variance and lemma 9.23.

Occurrence typing and its boundary

Let z:NatBool. The term caseType z as x in Natxx has type NatBool. In the then branch, x:(NatBool)Nat=DNat; in the else branch, x:(NatBool)¬Nat=DBool. Here is the complete derivation. Put S=NatBool. The two subtype equalities above give x:SNatx:SNatx:SNatx:SNatTVarSNatNatx:SNatx:NatTSub. x:S¬Natx:S¬Natx:S¬Natx:S¬NatTVarS¬NatBoolx:S¬Natx:BoolTSub. Let D+ be the T-Sub derivation of x:SNatx:Nat, and let D be the T-Sub derivation of x:S¬Natx:Bool. Both refinements are nonempty, so the empty-branch implications are vacuous and the remaining instance is z:Sz:Sz:Sz:STVarxzfv(x){z,x}D+Dz:ScaseType z as x in Natxx:NatBoolTCase.

This is occurrence typing for one evaluated value named by a binder. General occurrence systems also refine repeated expressions, projections, and paths, and must prove that evaluation does not invalidate those refinements. No such claim is made here.

Example 9.36 — Overlap changes the else type

Put W=NatBool and give z the deliberately overlapping presentation NatW=DW. Testing W makes the else refinement empty, not the other written arm Nat. Conversely, testing Nat gives the else type W¬Nat=DBool, a proper subtype of the other written arm W. Replacing an else refinement by “the other union arm” is therefore unsound in the first order and imprecise in the second.

For array access, both (a,i)=([10,20],1)and(a,i)=([10,20],7) have the same unary types a,a:ArrayNat and i,i:Nat. Only the first array access satisfies 0i<len(a). Unary Boolean combinations cannot express a constraint relating an array value a, an index i, and len(a). Such a constraint requires dependent refinements, not another semantic-subtyping connective.

Results and signature boundaries

For λFG as defined in definition 9.4, definition 9.18, definition 9.19, definition 9.20 the development establishes Boolean semantic subtyping, a terminating and complete subtype decision procedure including arrows and negation, decidable checking of annotated terms, preservation, progress, and safety. The characteristic result is theorem 9.35: synthesis returns a least type for a term with fixed annotations and context.

The signatures separate the following constructions:

  • AB and AB classify one value by Boolean operations; A×B classifies a pair and A+B a tagged value.

  • The arrow laws (9.4) and (9.5) are inclusions; their reverse directions would require graph-membership conditions absent from the hypotheses.

  • The checker decides a term with a written interface. Principal inference would also have to construct that interface.

  • The safety theorem uses the weak call-by-value contexts of definition 9.20; call by name, strong reduction, nondeterminism, recursion, and effects define different step relations.

  • The typecase rule refines its bound variable by SU or S¬U. It introduces no path predicate for an arbitrary subexpression.

  • The finite-graph interpretation maps types to subsets of D. Term typing and reduction remain syntactic, so no denotational adequacy claim for program phrases enters the safety proof.

  • Dependent and non-idempotent intersections have different formation and elimination rules from the idempotent semantic intersection used here.

Sources.

The finite-graph model, Boolean normalization, and decomposition method follow Frisch, Castagna, and Benzaken [FCB08]; the chapter specializes their regular setting to finite type trees. For the binder/typecase boundary, see Castagna et al. [CLNL22]. The optional non-idempotent comparison follows Bernadet and Graham-Lengrand [BGL13].

Suggested first pass.

None of these problems is a prerequisite for later chapters. Begin with exercise 9.16; it reconstructs the chapter’s principal binder-refinement mechanism. Then use exercise 9.17 to check the exact handoff to refinements.

Exercise 9.16

★★☆ Repeat the complete occurrence derivation with the test Bool. State both semantic subtype equalities and the order of the two branch types in the concluding union.

Exercise 9.17

★☆☆ Give two further same-typed array/index pairs, one satisfying (9.17) and one violating it. Explain why adding more unions and intersections of ArrayNat and Nat cannot distinguish them.

Exercise 20.19

★★★ Practical project.semantic-subtyping-counterexample Build and run a finite-graph inclusion checker. Maintain the invariant that every negative inclusion result carries a graph admitted by the left normal form and excluded by the right. The eight-case run must end with All 8 semantic-subtyping corpus cases passed., and the audit must be empty. Test three deliberately unsound variants: remove the Ω guard, change universal arrow decomposition to existential choice, and bypass a typecase scope check. The named eight cases must reject each variant. Passing these finite witnesses is not a proof of the simulation or safety theorems.


  1. The semantic-subtyping literature writes AB for equality of denotations. This book reserves for equivalence of types in the homotopy-theoretic sense, where the coherence data is part of the definition, and writes =D here. The relation is unchanged; only the glyph differs.↩︎

Search the book

Type to search the local edition.