An unrestricted variable may be copied or ignored. That is wrong for an open file. Consider first the unrestricted interface 𝗋𝖾𝖺𝖽:𝖥𝗂𝗅𝖾→𝖥𝗂𝗅𝖾×𝖡𝗒𝗍𝖾𝗌,𝖼𝗅𝗈𝗌𝖾:𝖥𝗂𝗅𝖾→𝖴𝗇𝗂𝗍. Unrestricted typing then admits both 𝜆𝑓.(𝗋𝖾𝖺𝖽𝑓,𝗋𝖾𝖺𝖽𝑓)and𝜆𝑓.∗. We write 1 for 𝖴𝗇𝗂𝗍 and ∗ for its sole value below. The first program asks one handle to occupy two future states. The second forgets the obligation to close it. The arrows and products in this opening display are the unrestricted → and ×: they exhibit the bug. Giving 𝖥𝗂𝗅𝖾 a new atomic name changes neither derivation: contraction still copies the assumption and weakening still discards it.
The repair changes the judgment rather than the atom. Its right-hand context contains assumptions used exactly once: application and pairing split it, while both case branches receive the same residual resources because only one branch runs. A handle is owned and consumed; the calculus has no aliases, borrows, lifetimes, or provenance.
The split forced by one handle
Write Γ;Δ⊢𝑒:𝐴, read “under reusable assumptions Γ and exactly-once assumptions Δ, term 𝑒 has type 𝐴.” The semicolon is a firewall, not concatenation. Assumptions in Γ are unrestricted. The finite map Δ is a linear context: each assumption in it must be used exactly once. Both contexts are finite maps, their domains are disjoint, and exchange is built into map equality.
The complete linear and affine term rules are collected in subappendix A.33; the derivations below make every context split explicit.
Write Δ1#Δ2 when their domains are disjoint, and Δ1⊎Δ2 for their union under that condition: Δ1⊎Δ2isdefinediffdom(Δ1)∩dom(Δ2)=∅. The same symbol ⋅ denotes the empty finite map in either context position; “linear” describes the second slot’s role, not a different empty object.
The connective 𝐴⊸𝐵 is linear implication, commonly read “𝐴 lollipop 𝐵.” The connective 𝐴⊗𝐵, read “𝐴 tensor 𝐵,” will pair two independently owned resources below.
The ordinary unsplit rule would be Γ;Δ⊢𝑒1:𝐴⊸𝐵Γ;Δ⊢𝑒2:𝐴Γ;Δ⊢𝑒1𝑒2:𝐵T−App−Bad. With Δ=𝑓:𝖥𝗂𝗅𝖾, it types a function which closes 𝑓 in one premise and reads 𝑓 in the other; both premises claim the same unique assumption. The rule that partitions the inputs is instead Γ;Δ1⊢𝑒1:𝐴⊸𝐵Γ;Δ2⊢𝑒2:𝐴Δ1#Δ2Γ;Δ1⊎Δ2⊢𝑒1𝑒2:𝐵. The same obstruction forces tensor introduction: two components cannot both receive the whole linear context.
The split is a partition of ownership, not a copy: 𝑒1 receives Δ1, 𝑒2 receives Δ2, and their domains are disjoint.
Whenever either side is defined, Δ⊎⋅=Δ,Δ1⊎Δ2=Δ2⊎Δ1,(Δ1⊎Δ2)⊎Δ3=Δ1⊎(Δ2⊎Δ3). If 𝑥:𝐴∈Δ1⊎Δ2, it belongs to exactly one summand. More precisely, if Δ1⊎Δ2=Θ1⊎Θ2, there are unique pairwise-disjoint contexts Ξ𝑖𝑗, for 𝑖,𝑗∈{1,2}, such that Δ𝑖=Ξ𝑖1⊎Ξ𝑖2,Θ𝑗=Ξ1𝑗⊎Ξ2𝑗.
Proof. These are finite-map calculations. Disjointness makes membership exclusive. The two bracketings have the same domain and assign the same type to each member. For the refinement clause, let Ξ𝑖𝑗 be the restriction of Δ𝑖 to dom(Δ𝑖)∩dom(Θ𝑗). The two given partitions make the four domains pairwise disjoint and their row and column unions give the displayed equations. Any other four contexts with those equations have the same domains and types, so the refinement is unique. ◻
★☆☆ Suppose Δ1,Δ2,Θ1,Θ2 have pairwise-disjoint domains. Derive ((Δ1⊎Δ2)⊎Θ1)⊎Θ2=Δ1⊎(Θ1⊎(Δ2⊎Θ2)) and (Δ1⊎Θ1)⊎(Δ2⊎Θ2)=(Θ2⊎Δ2)⊎(Θ1⊎Δ1). List the disjointness fact that makes each displayed union defined.
★☆☆ Consider the rejected unsplit rule Γ;Δ⊢𝑒1:𝐴⊸𝐵Γ;Δ⊢𝑒2:𝐴Γ;Δ⊢𝑒1𝑒2:𝐵. For this diagnostic, use the linear primitive types of the file-token extension below: 𝗋𝖾𝖺𝖽:𝖥𝗂𝗅𝖾⊸(𝖥𝗂𝗅𝖾⊗𝖡𝗒𝗍𝖾𝗌) and 𝖼𝗅𝗈𝗌𝖾:𝖥𝗂𝗅𝖾⊸1. Set Δ=𝑓:𝖥𝗂𝗅𝖾, 𝑒1:=𝜆𝑢.𝗅𝖾𝗍∗=𝑢𝗂𝗇𝗋𝖾𝖺𝖽𝑓,𝑒2:=𝖼𝗅𝗈𝗌𝖾𝑓. Check the two premises separately and observe that the candidate conclusion types 𝑒1𝑒2, which closes 𝑓 and then tries to read it. Identify the duplicated assumption and explain why deleting a separate contraction rule does not repair this rule.
Tensor and linear implication are multiplicative connectives: their rules divide resources between simultaneous premises. Sums are additive connectives: their alternatives share one residual context because only one branch executes. The exponential !𝐴, read “bang 𝐴,” marks a value built without capturing a linear resource; eliminating it may therefore expose its payload in the reusable context. These distinctions motivate the grammar rather than merely naming its symbols.
The formal core 𝜆lin is the monomorphic, pure, call-by-value calculus defined by this grammar and the rules of definition 18.5. It has atomic types, multiplicative unit and tensor, linear implication, additive sums, and one exponential.
Let 𝑏 range over atomic types. The syntax is 𝐴,𝐵::=𝑏∣1∣𝐴⊗𝐵∣𝐴⊸𝐵∣𝐴⊕𝐵∣!𝐴,𝑒::=𝑥∣∗∣𝜆𝑥.𝑒∣𝑒1𝑒2∣𝑒1⊗𝑒2∣𝗅𝖾𝗍𝑥⊗𝑦=𝑒1𝗂𝗇𝑒2∣𝗅𝖾𝗍∗=𝑒1𝗂𝗇𝑒2∣𝗂𝗇𝗅𝑒∣𝗂𝗇𝗋𝑒∣𝖼𝖺𝗌𝖾𝑒𝗈𝖿𝗂𝗇𝗅𝑥⇒𝑒1∣𝗂𝗇𝗋𝑦⇒𝑒2∣!𝑣∣𝗅𝖾𝗍!𝑥=𝑒1𝗂𝗇𝑒2,𝑣,𝑤::=𝑥∣∗∣𝜆𝑥.𝑒∣𝑣⊗𝑤∣𝗂𝗇𝗅𝑣∣𝗂𝗇𝗋𝑣∣!𝑣. Open variables count as values; a closed evaluation contains none. We use 𝗅𝖾𝗍𝑥=𝑒1𝗂𝗇𝑒2 as the abbreviation (𝜆𝑥.𝑒2)𝑒1.
The rules range over well-formed Γ;Δ with disjoint domains.
𝑥:𝐴∈Γ
Γ;⋅⊢𝑥:𝐴
T-UVar
Γ;𝑥:𝐴⊢𝑥:𝐴
T-LVar
Γ;⋅⊢∗:1
T-OneI
Γ;Δ1⊢𝑒1:1Γ;Δ2⊢𝑒2:𝐶
Γ;Δ1⊎Δ2⊢𝗅𝖾𝗍∗=𝑒1𝗂𝗇𝑒2:𝐶
T-OneE
Γ;Δ,𝑥:𝐴⊢𝑒:𝐵
Γ;Δ⊢𝜆𝑥.𝑒:𝐴⊸𝐵
T-LolliI
Γ;Δ1⊢𝑒1:𝐴⊸𝐵Γ;Δ2⊢𝑒2:𝐴
Γ;Δ1⊎Δ2⊢𝑒1𝑒2:𝐵
T-LolliE
Γ;Δ1⊢𝑒1:𝐴Γ;Δ2⊢𝑒2:𝐵
Γ;Δ1⊎Δ2⊢𝑒1⊗𝑒2:𝐴⊗𝐵
T-TensorI
Γ;Δ1⊢𝑒1:𝐴⊗𝐵Γ;Δ2,𝑥:𝐴,𝑦:𝐵⊢𝑒2:𝐶
Γ;Δ1⊎Δ2⊢𝗅𝖾𝗍𝑥⊗𝑦=𝑒1𝗂𝗇𝑒2:𝐶
T-TensorE
Γ;Δ⊢𝑒:𝐴
Γ;Δ⊢𝗂𝗇𝗅𝑒:𝐴⊕𝐵
T-PlusI1
Γ;Δ⊢𝑒:𝐵
Γ;Δ⊢𝗂𝗇𝗋𝑒:𝐴⊕𝐵
T-PlusI2
Γ;Δ0⊢𝑒0:𝐴⊕𝐵Γ;Δ𝑟,𝑥:𝐴⊢𝑒1:𝐶Γ;Δ𝑟,𝑦:𝐵⊢𝑒2:𝐶
Γ;Δ0⊎Δ𝑟⊢𝖼𝖺𝗌𝖾𝑒0𝗈𝖿𝗂𝗇𝗅𝑥⇒𝑒1∣𝗂𝗇𝗋𝑦⇒𝑒2:𝐶
T-Case
The same Δ𝑟 appears in both alternatives because the two premises describe mutually exclusive futures of one run. The derivation contains both proof branches, but reduction selects exactly one of them; no execution ever owns two copies of Δ𝑟.
Γ;⋅⊢𝑣:𝐴
Γ;⋅⊢!𝑣:!𝐴
T-BangI
Γ;Δ1⊢𝑒1:!𝐴Γ,𝑥:𝐴;Δ2⊢𝑒2:𝐵
Γ;Δ1⊎Δ2⊢𝗅𝖾𝗍!𝑥=𝑒1𝗂𝗇𝑒2:𝐵
T-BangE
Bang introduction is the firewall: no linear assumption can be sealed inside a duplicable value. Its premise is a value, not a computation. This call-by-value restriction also prevents an effect from happening while a bang is being constructed. Bang elimination reveals 𝑥 in Γ.
Evaluation is left to right. Its contexts are 𝐸::=[]∣𝐸𝑒∣𝑣𝐸∣𝐸⊗𝑒∣𝑣⊗𝐸∣𝗅𝖾𝗍𝑥⊗𝑦=𝐸𝗂𝗇𝑒∣𝗅𝖾𝗍∗=𝐸𝗂𝗇𝑒∣𝗂𝗇𝗅𝐸∣𝗂𝗇𝗋𝐸∣𝖼𝖺𝗌𝖾𝐸𝗈𝖿𝗂𝗇𝗅𝑥⇒𝑒1∣𝗂𝗇𝗋𝑦⇒𝑒2∣𝗅𝖾𝗍!𝑥=𝐸𝗂𝗇𝑒. There is no reduction beneath a lambda or inside an unselected branch. The root rules are
(𝜆𝑥.𝑒)𝑣⇝0𝑒[𝑣/𝑥]
E-LinBeta
𝗅𝖾𝗍𝑥⊗𝑦=𝑣⊗𝑤𝗂𝗇𝑒⇝0𝑒[𝑣/𝑥,𝑤/𝑦]
E-Tensor
𝗅𝖾𝗍∗=∗𝗂𝗇𝑒⇝0𝑒
E-One
𝖼𝖺𝗌𝖾(𝗂𝗇𝗅𝑣)𝗈𝖿𝗂𝗇𝗅𝑥⇒𝑒1∣𝗂𝗇𝗋𝑦⇒𝑒2⇝0𝑒1[𝑣/𝑥]
E-InL
𝖼𝖺𝗌𝖾(𝗂𝗇𝗋𝑣)𝗈𝖿𝗂𝗇𝗅𝑥⇒𝑒1∣𝗂𝗇𝗋𝑦⇒𝑒2⇝0𝑒2[𝑣/𝑦]
E-InR
𝗅𝖾𝗍!𝑥=!𝑣𝗂𝗇𝑒⇝0𝑒[𝑣/𝑥]
E-Bang
The one-step relation is the compatible closure 𝐸[𝑒]⟶𝐸[𝑒′] of 𝑒⇝0𝑒′.
For example, 𝗌𝗐𝖺𝗉=𝜆𝑝.𝗅𝖾𝗍𝑥⊗𝑦=𝑝𝗂𝗇𝑦⊗𝑥:(𝐴⊗𝐵)⊸(𝐵⊗𝐴). Tensor elimination extends the body context by 𝑥:𝐴,𝑦:𝐵; tensor introduction assigns them to opposite singleton premises.
The exponential makes precisely marked data structural: 𝖼𝗈𝗉𝗒𝐴=𝜆𝑢.𝗅𝖾𝗍!𝑥=𝑢𝗂𝗇!𝑥⊗!𝑥:!𝐴⊸(!𝐴⊗!𝐴),𝖽𝗂𝗌𝖼𝖺𝗋𝖽𝐴=𝜆𝑢.𝗅𝖾𝗍!𝑥=𝑢𝗂𝗇∗:!𝐴⊸1. After T-BangE, 𝑥:𝐴 belongs to Γ. Each occurrence uses T-UVar with empty linear context. The value 𝑢:!𝐴 itself is still eliminated exactly once.
Let 𝗋𝗈𝗎𝗍𝖾:=𝜆𝑧.𝜆𝑟.𝖼𝖺𝗌𝖾𝑧𝗈𝖿𝗂𝗇𝗅𝑥⇒𝑥⊗𝑟∣𝗂𝗇𝗋𝑦⇒𝑦⊗𝑟. In either branch, tensor introduction splits the residual context into the singletons containing the payload and 𝑟:𝑅. Write 𝑞 for the case expression in the definition of 𝗋𝗈𝗎𝗍𝖾. Then: ⋅;𝑧:𝐴⊕𝐴⊢𝑧:𝐴⊕𝐴⋅;𝑥:𝐴,𝑟:𝑅⊢𝑥⊗𝑟:𝐴⊗𝑅⋅;𝑦:𝐴,𝑟:𝑅⊢𝑦⊗𝑟:𝐴⊗𝑅⋅;𝑧:𝐴⊕𝐴,𝑟:𝑅⊢𝑞:𝐴⊗𝑅T−Case. Two uses of T-LolliI therefore give ⋅;⋅⊢𝗋𝗈𝗎𝗍𝖾:(𝐴⊕𝐴)⊸(𝑅⊸𝐴⊗𝑅). The common residual is copied between proof alternatives, but a reduction selects only one alternative.
★☆☆ Modify 𝗋𝗈𝗎𝗍𝖾 so the left branch returns 𝗂𝗇𝗋(𝑥⊗𝑟) and the right branch returns 𝗂𝗇𝗅(𝑦⊗𝑟). Derive its result type and explain why 𝑟 still belongs to the common residual context.
Fix an infinite set 𝖳𝗈𝗄 of runtime tokens. Extend the core by atomic 𝖥𝗂𝗅𝖾 and 𝖡𝗒𝗍𝖾𝗌, primitive values 𝗈𝗉𝖾𝗇:1⊸𝖥𝗂𝗅𝖾,𝗋𝖾𝖺𝖽:𝖥𝗂𝗅𝖾⊸(𝖥𝗂𝗅𝖾⊗𝖡𝗒𝗍𝖾𝗌),𝖼𝗅𝗈𝗌𝖾:𝖥𝗂𝗅𝖾⊸1, and runtime values 𝖿𝗂𝗅𝖾ℎ and 𝖻𝗒𝗍𝖾𝗌ℎ, where ℎ∈𝖳𝗈𝗄. A token is live exactly while it belongs to a finite set 𝐻⊆𝖳𝗈𝗄. The closed primitive typing axioms are
Γ;⋅⊢𝗈𝗉𝖾𝗇:1⊸𝖥𝗂𝗅𝖾
T-Open
Γ;⋅⊢𝗋𝖾𝖺𝖽:𝖥𝗂𝗅𝖾⊸(𝖥𝗂𝗅𝖾⊗𝖡𝗒𝗍𝖾𝗌)
T-Read
Γ;⋅⊢𝖼𝗅𝗈𝗌𝖾:𝖥𝗂𝗅𝖾⊸1
T-Close
Γ;⋅⊢𝖻𝗒𝗍𝖾𝗌ℎ:𝖡𝗒𝗍𝖾𝗌
T-Bytes
The runtime file value has no closed source typing axiom. Its ownership is recorded by the configuration judgment below.
Reduction acts on (𝐻,𝑒). Core steps leave 𝐻 unchanged. The new roots, closed under the existing evaluation contexts, are
ℎ∈𝖳𝗈𝗄∖𝐻
(𝐻,𝗈𝗉𝖾𝗇∗)⟶(𝐻∪{ℎ},𝖿𝗂𝗅𝖾ℎ)
E-Open
ℎ∈𝐻
(𝐻,𝗋𝖾𝖺𝖽𝖿𝗂𝗅𝖾ℎ)⟶(𝐻,𝖿𝗂𝗅𝖾ℎ⊗𝖻𝗒𝗍𝖾𝗌ℎ)
E-Read
ℎ∈𝐻
(𝐻,𝖼𝗅𝗈𝗌𝖾𝖿𝗂𝗅𝖾ℎ)⟶(𝐻∖{ℎ},∗)
E-Close
Fresh allocation creates a token; close is its only destructor; read returns the same token with ordinary bytes. Since 𝖳𝗈𝗄 is infinite and 𝐻 is finite, 𝖳𝗈𝗄∖𝐻 is nonempty, so E-Open always has a fresh choice.
The missing file-value axiom is load bearing. If one added 𝑋Γ;⋅⊢𝖿𝗂𝗅𝖾ℎ:𝖥𝗂𝗅𝖾T−File−Bad, then T-TensorI could use that closed derivation twice and conclude Γ;⋅⊢𝖿𝗂𝗅𝖾ℎ⊗𝖿𝗂𝗅𝖾ℎ:𝖥𝗂𝗅𝖾⊗𝖥𝗂𝗅𝖾. One runtime token would already have two owners. The configuration judgment below replaces this axiom by one linear placeholder for each live token.
The value premise of T-BangI is essential for the same extension. If promotion accepted a computation and evaluation included a context !𝐸, then (∅,!(𝗈𝗉𝖾𝗇∗))𝐸−𝑂𝑝𝑒𝑛⟶({ℎ},!𝖿𝗂𝗅𝖾ℎ). The result cannot be represented by a linear placeholder beneath the bang. The value restriction excludes this term, while !𝗈𝗉𝖾𝗇 remains legal and allocates a fresh token at each later call.
Proof of Proposition 18.8 — The read-close derivation
Proof. The three load-bearing splits are visible in these judgments: ⋅;⋅⊢𝗈𝗉𝖾𝗇:1⊸𝖥𝗂𝗅𝖾⋅;𝑢:1⊢𝑢:1⋅;⋅⊎(𝑢:1)⊢𝗈𝗉𝖾𝗇𝑢:𝖥𝗂𝗅𝖾⋅;⋅⊢𝗋𝖾𝖺𝖽:𝖥𝗂𝗅𝖾⊸(𝖥𝗂𝗅𝖾⊗𝖡𝗒𝗍𝖾𝗌)⋅;𝑓:𝖥𝗂𝗅𝖾⊢𝑓:𝖥𝗂𝗅𝖾⋅;⋅⊎(𝑓:𝖥𝗂𝗅𝖾)⊢𝗋𝖾𝖺𝖽𝑓:𝖥𝗂𝗅𝖾⊗𝖡𝗒𝗍𝖾𝗌⋅;𝑓′:𝖥𝗂𝗅𝖾⊢𝖼𝗅𝗈𝗌𝖾𝑓′:1⋅;𝑏:𝖡𝗒𝗍𝖾𝗌⊢𝑏:𝖡𝗒𝗍𝖾𝗌⋅;(𝑓′:𝖥𝗂𝗅𝖾)⊎(𝑏:𝖡𝗒𝗍𝖾𝗌)⊢𝗅𝖾𝗍∗=𝖼𝗅𝗈𝗌𝖾𝑓′𝗂𝗇𝑏:𝖡𝗒𝗍𝖾𝗌. The first two conclusions use T-LolliE; the third uses T-LolliE for close and then T-OneE. Now T-TensorE combines the second conclusion with the third: its scrutinee owns exactly 𝑓:𝖥𝗂𝗅𝖾, and its body owns exactly 𝑓′:𝖥𝗂𝗅𝖾,𝑏:𝖡𝗒𝗍𝖾𝗌. Thus the body of the outer let has type 𝖡𝗒𝗍𝖾𝗌 under 𝑓:𝖥𝗂𝗅𝖾. The let abbreviation is an application; its function premise abstracts 𝑓, and its argument premise is the first displayed conclusion. Their split is ⋅⊎(𝑢:1), so one final T-LolliI over 𝑢 gives the claimed type.
For any ℎ∈𝖳𝗈𝗄, the informative part of the trace is (∅,𝗋𝖾𝖺𝖽𝖢𝗅𝗈𝗌𝖾∗)𝐸−𝐿𝑖𝑛𝐵𝑒𝑡𝑎⟶∗(∅,𝗅𝖾𝗍𝑓=𝗈𝗉𝖾𝗇∗𝗂𝗇⋯)𝐸−𝑂𝑝𝑒𝑛⟶({ℎ},𝗅𝖾𝗍𝑓=𝖿𝗂𝗅𝖾ℎ𝗂𝗇⋯)𝐸−𝐿𝑖𝑛𝐵𝑒𝑡𝑎⟶∗({ℎ},𝗅𝖾𝗍𝑓′⊗𝑏=𝗋𝖾𝖺𝖽𝖿𝗂𝗅𝖾ℎ𝗂𝗇⋯)𝐸−𝑅𝑒𝑎𝑑⟶({ℎ},𝗅𝖾𝗍𝑓′⊗𝑏=𝖿𝗂𝗅𝖾ℎ⊗𝖻𝗒𝗍𝖾𝗌ℎ𝗂𝗇⋯)𝐸−𝑇𝑒𝑛𝑠𝑜𝑟⟶∗({ℎ},𝗅𝖾𝗍∗=𝖼𝗅𝗈𝗌𝖾𝖿𝗂𝗅𝖾ℎ𝗂𝗇𝖻𝗒𝗍𝖾𝗌ℎ)𝐸−𝐶𝑙𝑜𝑠𝑒⟶(∅,𝗅𝖾𝗍∗=∗𝗂𝗇𝖻𝗒𝗍𝖾𝗌ℎ)𝐸−𝑂𝑛𝑒⟶(∅,𝖻𝗒𝗍𝖾𝗌ℎ). The rule names on the arrows identify every core segment and every file step. ◻
The terms 𝜆𝑓.(𝗋𝖾𝖺𝖽𝑓)⊗(𝗋𝖾𝖺𝖽𝑓), 𝜆𝑓.∗, and 𝜆𝑓.𝗅𝖾𝗍𝑓′⊗𝑏=𝗋𝖾𝖺𝖽𝑓𝗂𝗇𝑏 fail respectively by duplicating 𝑓, dropping 𝑓, and dropping the returned 𝑓′.
The comparison with a move-only API is limited: this calculus demands an explicit exactly-once path, whereas an affine language may drop an unused value and insert destructors. The theorem therefore concerns the displayed token machine.
Proof of Lemma 18.9 — Exchange and unrestricted weakening
Proof. Permutation is finite-map equality. For weakening, induct on typing and add 𝑥:𝐵 to each unrestricted premise, renaming binders when necessary. A linear weakening would derive Γ;𝑦:𝐶,𝑧:𝐵⊢𝑦:𝐶, but no rule consumes 𝑧. Direct inspection of the last rule proves the impossibility; the exact-use induction below extends this last-rule contradiction by proving that every derivable term consumes each linear assumption exactly once. ◻
Proof. Induct on typing. At T-UVar, the selected variable is 𝑥, when the second premise concludes, or another variable, when the rule reapplies. For a split rule apply the hypotheses to all premises: the substituted value contributes no linear context. Both alternatives of T-Case receive the substitution and retain the same residual context. Bang introduction remains legal because the value has empty linear context. In the T-LolliI case, alpha-rename its binder 𝑦 away from 𝑥 and the free variables of 𝑣, apply the induction hypothesis to Γ,𝑥:𝐴;Δ,𝑦:𝐶⊢𝑒:𝐷, and reapply T-LolliI to the resulting premise Γ;Δ,𝑦:𝐶⊢𝑒[𝑣/𝑥]:𝐷. The other binders use the same freshness convention, after which the final rule reapplies. ◻
Proof. Induct on the first derivation. At T-LVar, the distinguished variable is 𝑥, Δ1=⋅, and the second premise concludes. In a binary multiplicative rule, exclusive membership puts 𝑥 in one premise. For example, if the last rule is T-LolliE, write its conclusion split as Σ1⊎Σ2=Δ1,𝑥:𝐴. Exclusive membership gives exactly one of Σ1=Σ′1,𝑥:𝐴orΣ2=Σ′2,𝑥:𝐴. In the first case, the induction hypothesis changes the function premise to Γ;Σ′1⊎Δ2⊢𝑒1[𝑣/𝑥]:𝐶⊸𝐵, while the argument premise retains context Σ2. Reapplying T-LolliE gives context (Σ′1⊎Δ2)⊎Σ2=(Σ′1⊎Σ2)⊎Δ2=Δ1⊎Δ2. In the second case, the function premise retains Σ1, and the induction hypothesis changes the argument premise to Γ;Σ′2⊎Δ2⊢𝑒2[𝑣/𝑥]:𝐶. The rebuilt context is Σ1⊎(Σ′2⊎Δ2)=(Σ1⊎Σ′2)⊎Δ2=Δ1⊎Δ2. Tensor introduction uses this exclusive-membership calculation. So does each elimination rule whose displayed premises split the context.
For T-Case, if 𝑥∈Δ0, substitute only in the scrutinee. If 𝑥∈Δ𝑟, substitute in both branch premises. This duplicates syntax between alternatives, not along an execution; both branches retain the same enlarged residual context. Bang introduction cannot be final because its linear context is empty. Bang elimination is another split. Injections use their sole premise, and binders are renamed fresh. These cases exhaust the rules. ◻
Proof of Corollary 18.12 — Two-variable linear substitution
Proof. Alpha-rename 𝑥,𝑦 away from each other’s substituent. Regard the first premise as Γ;(Δ,𝑦:𝐵),𝑥:𝐴⊢𝑒:𝐶. Because Δ1 is disjoint from both Δ and 𝑦, linear substitution gives Γ;Δ⊎Δ1,𝑦:𝐵⊢𝑒[𝑣/𝑥]:𝐶. The second substitution, using Δ2, gives Γ;Δ⊎Δ1⊎Δ2⊢𝑒[𝑣/𝑥][𝑤/𝑦]:𝐶. The freshness choices and 𝑦∉𝖥𝖵(𝑣) give 𝑒[𝑣/𝑥][𝑤/𝑦]=𝑒[𝑣/𝑥,𝑤/𝑦]. Associativity from lemma 18.2 gives (Δ⊎Δ1)⊎Δ2=Δ⊎(Δ1⊎Δ2) for the displayed context. ◻
For a variable 𝑧, define a partial natural 𝗎𝗌𝖾𝑧(𝑒). “Partial” means that the function is deliberately undefined when the two alternatives of a case use 𝑧 a different number of times; the case clause below states that condition. Put 𝗎𝗌𝖾𝑧(𝑧)=1, 𝗎𝗌𝖾𝑧(𝑥)=0 for 𝑥≠𝑧, and give every constant use zero. Write 𝗎𝗌𝖾𝑥𝑧(𝑒)={0𝑧=𝑥,𝗎𝗌𝖾𝑧(𝑒)𝑧≠𝑥, and define 𝗎𝗌𝖾𝑥,𝑦𝑧 by masking both binders. The remaining clauses are 𝗎𝗌𝖾𝑧(𝜆𝑥.𝑒)=𝗎𝗌𝖾𝑥𝑧(𝑒),𝗎𝗌𝖾𝑧(𝑒1𝑒2)=𝗎𝗌𝖾𝑧(𝑒1)+𝗎𝗌𝖾𝑧(𝑒2),𝗎𝗌𝖾𝑧(𝑒1⊗𝑒2)=𝗎𝗌𝖾𝑧(𝑒1)+𝗎𝗌𝖾𝑧(𝑒2),𝗎𝗌𝖾𝑧(𝗅𝖾𝗍∗=𝑒1𝗂𝗇𝑒2)=𝗎𝗌𝖾𝑧(𝑒1)+𝗎𝗌𝖾𝑧(𝑒2),𝗎𝗌𝖾𝑧(𝗅𝖾𝗍𝑥⊗𝑦=𝑒1𝗂𝗇𝑒2)=𝗎𝗌𝖾𝑧(𝑒1)+𝗎𝗌𝖾𝑥,𝑦𝑧(𝑒2),𝗎𝗌𝖾𝑧(𝗂𝗇𝗅𝑒)=𝗎𝗌𝖾𝑧(𝑒),𝗎𝗌𝖾𝑧(𝗂𝗇𝗋𝑒)=𝗎𝗌𝖾𝑧(𝑒),𝗎𝗌𝖾𝑧(!𝑣)=𝗎𝗌𝖾𝑧(𝑣),𝗎𝗌𝖾𝑧(𝗅𝖾𝗍!𝑥=𝑒1𝗂𝗇𝑒2)=𝗎𝗌𝖾𝑧(𝑒1)+𝗎𝗌𝖾𝑥𝑧(𝑒2). For 𝖼𝖺𝗌𝖾𝑒0𝗈𝖿𝗂𝗇𝗅𝑥⇒𝑒1∣𝗂𝗇𝗋𝑦⇒𝑒2, first calculate 𝑘1=𝗎𝗌𝖾𝑥𝑧(𝑒1) and 𝑘2=𝗎𝗌𝖾𝑦𝑧(𝑒2). The use is defined exactly when both branch uses and the scrutinee use are defined and 𝑘1=𝑘2; its value is 𝗎𝗌𝖾𝑧(𝑒0)+𝑘1. Every displayed sum is defined only when its summands are.
Proof. Prove both clauses simultaneously by induction on typing, alpha-renaming each new binder away from the queried 𝑧. The two variable rules give one for the selected linear variable and zero for an absent variable. In every multiplicative split, exclusive membership puts a linear 𝑧 in exactly one premise. Its induction hypothesis gives use count one there; because 𝑧 is absent from every other premise context, their induction hypotheses give use count zero.
In T-Case, a variable from Δ0 contributes one in the scrutinee and zero in both branches. A variable from Δ𝑟 contributes zero in the scrutinee and one in each branch. Thus the partial case clause is defined and has value one in either placement. If 𝑧 is absent, all three uses are zero. Bang introduction has empty linear context; bang elimination is another split, with its bound variable masked in the body. The one-premise rules and introductions follow from their displayed structural clauses. This also proves that every use invoked in the theorem is defined. ◻
Write 𝐻⊩𝑒:𝐴, read “the live-token set 𝐻 owns 𝑒 at type 𝐴,” when pairwise distinct variables (𝑥ℎ)ℎ∈𝐻 and a template 𝑒0 satisfy ⋅;(𝑥ℎ:𝖥𝗂𝗅𝖾)ℎ∈𝐻⊢𝑒0:𝐴,𝑒=𝑒0[𝖿𝗂𝗅𝖾ℎ/𝑥ℎ]ℎ∈𝐻. The same placeholder may occur in corresponding case alternatives; exact pathwise use still gives one demand on each execution path.
For a closed value typed in the pure core: a value at 1 is ∗; at 𝐴⊸𝐵 it is a lambda; at 𝐴⊗𝐵 it is a tensor; at 𝐴⊕𝐵 it is the corresponding injection; and at !𝐴 it is a bang.
For the file extension, if 𝐻⊩𝑣:𝐴, the same clauses hold except that a function value may also be the uniquely typed primitive 𝗈𝗉𝖾𝗇, 𝗋𝖾𝖺𝖽, or 𝖼𝗅𝗈𝗌𝖾. A value at 𝖥𝗂𝗅𝖾 is 𝖿𝗂𝗅𝖾ℎ for a unique live ℎ∈𝐻.
Proof. For the first claim, inspect the core value grammar and invert the final typing rule. There is no subsumption to obscure the outer constructor, and a closed variable is impossible. For the second, invert a witnessing template from definition 18.19. A value template at function type is a lambda or one of the three primitive constants. The only template value at 𝖥𝗂𝗅𝖾 is a linear placeholder 𝑥ℎ, and the closing substitution turns it into 𝖿𝗂𝗅𝖾ℎ; distinct placeholders and tokens give uniqueness. ◻
Every derivation of Γ;Δ⊢𝐸[𝑒]:𝐴 contains a uniquely designated hole subderivation Γ;Θ⊢𝑒:𝐵; within that derivation, Θ and 𝐵 are determined by the path through 𝐸. Replacing that subderivation by Γ;Θ⊢𝑒′:𝐵 yields Γ;Δ⊢𝐸[𝑒′]:𝐴.
Proof of Lemma 18.16 — Evaluation-context replacement
Proof. Proceed simultaneously by structural induction on 𝐸 and inversion of the outer typing derivation. At the hole, the whole derivation is the designated subderivation. Each application and tensor frame selects one of the two premises of its unique syntax-directed outer rule; each tensor, unit, case, or bang-elimination frame selects its scrutinee premise; and an injection frame selects its sole premise. The induction hypothesis decomposes that premise and fixes Θ,𝐵; the untouched premises and their original context split then reconstruct the outer derivation. A case context changes only its scrutinee, so the common branch context is unchanged. These constructors exhaust the evaluation-context grammar, and there is no context beneath a bang because T-BangI accepts only a value. Replacing the designated premise and reversing this induction proves recomposition. ◻
Proof. Contextual steps use lemma 18.16. For beta, invert implication elimination and introduction, then apply linear substitution and split associativity. For tensor, invert tensor elimination and introduction, then apply two-variable substitution. For unit, inversion says that ∗ contributes the empty context.
For a left sum root, injection inversion gives Γ;Δ0⊢𝑣:𝐴, and the selected branch has Γ;Δ𝑟,𝑥:𝐴⊢𝑒1:𝐶; linear substitution restores Δ0⊎Δ𝑟. For the right root, replace 𝗂𝗇𝗅,𝑣,𝑥,𝑒1,𝐴 by 𝗂𝗇𝗋,𝑣,𝑦,𝑒2,𝐵; the same substitution argument restores the same split. For bang, introduction inversion gives an empty linear context; elimination puts 𝑥:𝐴 in Γ, so unrestricted substitution concludes. ◻
Proof of Theorem 18.18 — Progress and ordinary safety
Proof. Induct on typing. A closed derivation cannot end in a variable rule. For application, step the function and argument in order; when both are values, the function is a lambda by canonical forms, so beta applies. For 𝑒1⊗𝑒2, step 𝑒1, then 𝑒2; two values form a tensor value. An injection steps its payload; an injected value is a value. Each elimination first steps its scrutinee. At a value scrutinee, canonical forms gives the matching tensor, injection, unit, or bang introduction, so the corresponding root rule applies. A bang introduction is already a value.
If a closed typed term reaches 𝑒′, repeated preservation gives ⋅;⋅⊢𝑒′:𝐴. Progress therefore excludes a stuck nonvalue 𝑒′. ◻
Proof. Choose the witnessing template for the premise. Substitution of file tokens for variables changes no constructor in the evaluation-context spine, and the active term 𝗈𝗉𝖾𝗇∗ contains no token. The template therefore factors as 𝐸0[𝗈𝗉𝖾𝗇∗], with 𝐸0 closing to 𝐸.
The hole has type 𝖥𝗂𝗅𝖾 under the empty linear context: both 𝗈𝗉𝖾𝗇 and ∗ have empty linear context and application unions those two empty maps. Replace that subderivation by ⋅;𝑥ℎ:𝖥𝗂𝗅𝖾⊢𝑥ℎ:𝖥𝗂𝗅𝖾. Induction outward through 𝐸0 adds the fresh singleton to the unique multiplicative premise containing the hole. For a case scrutinee it is added to Δ0, leaving the common branch context unchanged. An application or tensor frame places the hole in its left or right premise; tensor, unit, and bang elimination place it in the scrutinee premise; an injection places it in its payload premise; and a case frame places it in its scrutinee premise. Each frame therefore adds the singleton only to the premise containing the hole. No evaluation context descends under bang, so the induction has no T-BangI case. The rebuilt template has the old placeholders together with 𝑥ℎ, and its closing substitution is 𝐸[𝖿𝗂𝗅𝖾ℎ]. ◻
Suppose 𝐻⊩𝐸[𝑟ℎ]:𝐴, where 𝑟ℎ is 𝗋𝖾𝖺𝖽𝖿𝗂𝗅𝖾ℎ or 𝖼𝗅𝗈𝗌𝖾𝖿𝗂𝗅𝖾ℎ. A witnessing template can be chosen with the same evaluation-context spine and active redex 𝗋𝖾𝖺𝖽𝑥ℎ or 𝖼𝗅𝗈𝗌𝖾𝑥ℎ, respectively. Replacing the former by 𝑥ℎ⊗𝖻𝗒𝗍𝖾𝗌ℎ preserves the template typing. Replacing the latter by ∗ removes 𝑥ℎ:𝖥𝗂𝗅𝖾 and preserves the remaining template typing.
Proof. Induct on the evaluation context. At the hole, use the unique placeholder whose closing image is 𝖿𝗂𝗅𝖾ℎ. Each context constructor corresponds to one typing premise and retains its original split. If the hole is the scrutinee of a case, exact use puts 𝑥ℎ in the scrutinee context and the absent-variable clause of theorem 18.14 gives zero uses in both branches. Reduction never enters an unselected branch. The other split constructors are simpler: exclusive membership places 𝑥ℎ only in the premise containing the hole.
For read, T-LolliE, T-Read, and T-LVar type the active redex. The replacement is typed by T-TensorI from the same linear placeholder and the closed T-Bytes value. For close, the active T-LolliE consumes the sole placeholder; replacing its unit result by T-OneI therefore removes that singleton from the witnessing context. Context replacement rebuilds the outer derivation. ◻
If 𝐻⊩𝑒:𝐴, then 𝑒 is a value or the configuration takes a step. If moreover (𝐻,𝑒)⟶(𝐻′,𝑒′), then 𝐻′⊩𝑒′:𝐴. Core reduction and read preserve the one owner of each live token, open adds one fresh owner, and close removes its selected owner. If a well-owned configuration of type 1 reaches (𝐻,𝑣), then 𝐻=∅ and 𝑣=∗.
Proof of Theorem 18.20 — File-token preservation and cleanup
Proof. For progress, induct on the typing derivation of the template while following the corresponding closed term. The core cases repeat theorem 18.18. At a value-headed application, the extended canonical-forms clause gives either a lambda, when beta applies, or one of the three primitives. Its unique declared domain and the argument canonical-form clause force ∗ for open and a live 𝖿𝗂𝗅𝖾ℎ for read or close, so the corresponding configuration root applies.
At a core root, template substitution preserves every context split. For read and close, lemma 36.22 replaces the active placeholder while preserving the surrounding template. For open, lemma 36.21 gives directly 𝐻∪{ℎ}⊩𝐸[𝖿𝗂𝗅𝖾ℎ]:𝐴 from 𝐻⊩𝐸[𝗈𝗉𝖾𝗇∗]:𝐴 and ℎ∉𝐻. Thus the reconstructed template has exactly one path to each live token. For every ℎ∈𝐻, the placeholder 𝑥ℎ:𝖥𝗂𝗅𝖾 belongs to the template’s linear context, so theorem 18.14 gives 𝗎𝗌𝖾𝑥ℎ(𝑒0)=1. Pairwise distinct placeholders and the closing substitution map only that 𝑥ℎ to 𝖿𝗂𝗅𝖾ℎ. Read preserves the same occurrence, open adds the fresh occurrence proved above, and close removes precisely its selected occurrence.
At result type 1, canonical forms gives 𝑣=∗. If 𝐻 were nonempty, exact use would force a file-placeholder occurrence in that unit value, a contradiction. ◻
The theorem does not assert termination or success of a host close operation. It states only that the abstract token cannot be duplicated, silently lost, or present after a returned unit.
Under Curry–Howard, 𝐴⊸𝐵 is implication using its assumption once, 𝐴⊗𝐵 is simultaneous possession, 𝐴⊕𝐵 is a choice, 1 is the empty multiplicative resource, and !𝐴 admits a proof to the unrestricted context. Their context rules are their meanings.
The cut Γ;Δ1⊢𝑣:𝐴Γ;Δ2,𝑥:𝐴⊢𝑒:𝐵Γ;Δ1⊎Δ2⊢𝑒[𝑣/𝑥]:𝐵 is linear substitution; unrestricted cut is unrestricted substitution. It is the resource-sensitive counterpart of the cut-as-substitution calculation in section 3.5: a proof of 𝐴 is inserted at one marked use of 𝐴, while the split records exactly which resources travel with it.
When every introduced payload required by call by value is already a value, the principal implication, tensor, unit, sum, and exponential cuts are the six root reductions of definition 18.4. Each preserves its conclusion and removes an introduction immediately followed by elimination of its principal formula. With a nonvalue payload, evaluation contexts first perform administrative steps until this value-principal configuration is reached; no claim of unrestricted proof cut elimination is being made.
Proof of Proposition 18.21 — Principal cut computations
Proof. Implication substitutes an argument into a lambda body. Tensor substitutes both components; unit removes the empty proof; either sum introduction selects one branch; and bang uses unrestricted substitution because its introduction had empty linear context. These are precisely the root cases of theorem 18.17.
For example, tensor introduction immediately followed by tensor elimination has the typed principal contraction Γ;Δ𝑣⊢𝑣:𝐴Γ;Δ𝑤⊢𝑤:𝐵Γ;Δ𝑣⊎Δ𝑤⊢𝑣⊗𝑤:𝐴⊗𝐵T−TensorIΓ;Δ𝑛,𝑥:𝐴,𝑦:𝐵⊢𝑛:𝐶Γ;(Δ𝑣⊎Δ𝑤)⊎Δ𝑛⊢𝗅𝖾𝗍𝑥⊗𝑦=𝑣⊗𝑤𝗂𝗇𝑛:𝐶T−TensorE. The term contracts to 𝑛[𝑣/𝑥,𝑤/𝑦]. The two-variable instance of linear substitution derives Γ;Δ𝑣⊎Δ𝑤⊎Δ𝑛⊢𝑛[𝑣/𝑥,𝑤/𝑦]:𝐶; the split displays which resources travel with each value. ◻
A commuting conversion moves an elimination past an independent case analysis; it changes proof schedule without changing which introduction that elimination is paired with. A representative conversion is 𝗅𝖾𝗍𝑝⊗𝑞=(𝖼𝖺𝗌𝖾𝑠𝗈𝖿𝗂𝗇𝗅𝑥⇒𝑒1∣𝗂𝗇𝗋𝑦⇒𝑒2)𝗂𝗇𝑛commutesto𝖼𝖺𝗌𝖾𝑠𝗈𝖿𝗂𝗇𝗅𝑥⇒𝗅𝖾𝗍𝑝⊗𝑞=𝑒1𝗂𝗇𝑛∣𝗂𝗇𝗋𝑦⇒𝗅𝖾𝗍𝑝⊗𝑞=𝑒2𝗂𝗇𝑛, after alpha-renaming 𝑝,𝑞,𝑥,𝑦 pairwise distinct and requiring 𝑥,𝑦∉FV(𝑛). If 𝑠 uses Δ0, both branch bodies use the same Δ𝑟, and 𝑛 uses Δ𝑛,𝑝:𝑃,𝑞:𝑄, both sides use Δ0⊎Δ𝑟⊎Δ𝑛.
Proof. Invert tensor elimination and then T-Case. Its two branches have one common residual context. Combine that context with the context of 𝑛, apply tensor elimination separately in both alternatives, and rebuild the outer case. Split associativity identifies the conclusion contexts. ◻
This proves the computational reading of the displayed principal and commuting cuts, not proof-net normalization for full linear logic.
For 𝜌∈{ℓ,𝑎,𝑟,𝑢}, write Γ;Δ⊢𝜌𝑒:𝐴. The subscript names the linear, affine, relevant, or unrestricted judgment, respectively. Each contains every rule of definition 18.5, with the judgment subscript changed uniformly. Their only differences are these structural rules:
In C-Rel, read the rule from premise to conclusion: the premise checks two distinct assumptions 𝑥:𝐴,𝑦:𝐴; the conclusion identifies both with one assumption 𝑧:𝐴 and simultaneously replaces their occurrences by 𝑧. It is contraction, not a rule that expands one resource while the term evaluates.
Thus linear means exactly once, affine at most once, relevant at least once, and unrestricted any number. The identity belongs to all four; 𝜆𝑥.∗ needs weakening; 𝜆𝑥.𝑥⊗𝑥 needs contraction. The affine derivation is 𝑋Γ;⋅⊢𝑎∗:1T−OneIΓ;𝑥:𝐴⊢𝑎∗:1W−AffΓ;⋅⊢𝑎𝜆𝑥.∗:𝐴⊸1T−LolliI For relevant typing, contraction gives Γ;𝑥1:𝐴⊢𝑟𝑥1:𝐴Γ;𝑥2:𝐴⊢𝑟𝑥2:𝐴Γ;𝑥1:𝐴,𝑥2:𝐴⊢𝑟𝑥1⊗𝑥2:𝐴⊗𝐴T−TensorIΓ;𝑥:𝐴⊢𝑟𝑥⊗𝑥:𝐴⊗𝐴C−RelΓ;⋅⊢𝑟𝜆𝑥.𝑥⊗𝑥:𝐴⊸(𝐴⊗𝐴)T−LolliI. The unrestricted judgment admits both trees. The linear judgment admits neither conclusion.
Fix 𝜌∈{ℓ,𝑎,𝑟,𝑢} and 𝑛≥0. Suppose Γ;Δ,𝑥1:𝐴1,…,𝑥𝑛:𝐴𝑛⊢𝜌𝑒:𝐵 and, for every 1≤𝑖≤𝑛, Γ;Θ𝑖⊢𝜌𝑣𝑖:𝐴𝑖. Assume that Δ,Θ1,…,Θ𝑛 have pairwise-disjoint domains; that the 𝑥𝑖 are distinct and absent from those contexts and from Γ; and that 𝑥𝑖∉FV(𝑣𝑗) for all 𝑖,𝑗. Then capture-avoiding simultaneous substitution gives Γ;Δ⊎Θ1⊎⋯⊎Θ𝑛⊢𝜌𝑒[𝑣1/𝑥1,…,𝑣𝑛/𝑥𝑛]:𝐵.
Proof. Induct on the first derivation, with the statement strengthened over every finite 𝑛. Alpha-rename each rule binder away from the 𝑥𝑖 and the free variables of the 𝑣𝑖. At T-LVar, either the selected variable belongs to Δ, when the rule reapplies, or it is the sole 𝑥𝑖, when the corresponding substituent derivation is the conclusion. The unrestricted variable and constant cases are one line each: T-UVar reapplies under the substituted unrestricted context, while a constant has no variable premise to transform.
For a multiplicative rule, exclusive membership partitions the 𝑥𝑖 between its premises. Apply the induction hypothesis to each part and use the pairwise disjointness of the Θ𝑖 to rebuild the conclusion. The common-refinement clause of lemma 18.2 gives a partition of the reassociated split with each 𝑥𝑖 in the same premise. For T-Case, send variables from the scrutinee context only to the scrutinee; send variables from the residual context, with the same substituents, to both alternatives. Only one alternative contributes to the conclusion context, so each Θ𝑖 still occurs once. The one-premise rules follow directly. T-BangI can be final only when 𝑛=0, because its linear context is empty.
It remains to treat the added structural rules. Suppose W-Aff adds 𝑧:𝐶. If 𝑧 belongs to Δ, apply the induction hypothesis to the premise and restore the weakening. If 𝑧=𝑥𝑘, omit 𝑥𝑘 and 𝑣𝑘 from the induction hypothesis; the term does not contain 𝑥𝑘. Then apply W-Aff once for every declaration of Θ𝑘. This adds exactly the missing context and proves the affine case. The same calculation handles weakening in ⊢𝑢.
Now suppose C-Rel contracts 𝑧1:𝐶,𝑧2:𝐶 to 𝑧:𝐶. If 𝑧∈dom(Δ), apply the induction hypothesis to the premise and contract 𝑧1,𝑧2 again. If 𝑧=𝑥𝑘, take two fresh renamings Θ1𝑘,Θ2𝑘 of Θ𝑘, and let 𝑣1𝑘,𝑣2𝑘 be the corresponding renamings of 𝑣𝑘. Apply the induction hypothesis to the strict premise with the substitution list 𝑥1↦𝑣1,…,𝑥𝑘−1↦𝑣𝑘−1,𝑧1↦𝑣1𝑘,𝑧2↦𝑣2𝑘,𝑥𝑘+1↦𝑣𝑘+1,…,𝑥𝑛↦𝑣𝑛. Its contexts are pairwise disjoint by the fresh renamings. For every declaration 𝑞:𝐶𝑞 in Θ𝑘, apply C-Rel to the corresponding pair 𝑞1:𝐶𝑞,𝑞2:𝐶𝑞. After all these contractions and renaming back to 𝑞, the duplicated context Θ1𝑘⊎Θ2𝑘 has become Θ𝑘, and the term is 𝑒[𝑣1𝑘/𝑧1,𝑣2𝑘/𝑧2][𝑞/𝑞1,𝑞/𝑞2]𝑞∈dom(Θ𝑘)=𝑒[𝑣𝑘/𝑧1,𝑣𝑘/𝑧2]. This is precisely the substitution instance of the contraction conclusion. No weakening is used. The unrestricted case admits the same contraction calculation, and these cases exhaust the derivation. ◻
Proof of Lemma 36.28 — Substitution in every structural regime
Proof. Clause (b) is the 𝑛=1 instance of lemma 36.27. For (a), induct on the first derivation. At T-UVar, use the substituent when the selected variable is 𝑥, and reapply the rule otherwise. In every split, apply the induction hypothesis to all premises: the substituent contributes no linear context. Both alternatives of T-Case receive it and retain the same residual context. Substitution of a value for a variable in a value yields a value, so T-BangI’s value premise is preserved. If the last rule is weakening or contraction, its affected variable is linear and therefore different from the unrestricted 𝑥; apply the induction hypothesis to its premise and restore that rule. In the contraction case the two substitutions commute: the substituent has empty linear context, so it contains neither contracted variable. Variable, abstraction, application, tensor, sum, bang, weakening, and contraction rules exhaust the derivation. ◻
Proof of Lemma 36.29 — Reduction reflects variable identification
Proof. A variable-to-variable map preserves the outer constructor. By the constructor-directed value grammar, it maps a variable to a variable, a lambda to a lambda, unit to unit, a tensor of values to a tensor of values, an injection of a value to the same injection, and a bang value to a bang value. Conversely, the outer constructor of an application or elimination is unchanged, and a tensor or injection whose payload was a nonvalue retains that nonvalue recursively. Structural induction therefore gives that 𝑒 is a value exactly when 𝑒𝜎 is a value. Now induct on the evaluation context of the given step. At the root, inspect the six reductions. For example, ((𝜆𝑥.𝑛)𝑣)𝜎 contracts to (𝑛[𝑣/𝑥])𝜎=(𝑛𝜎)[𝑣𝜎/𝑥], after alpha-renaming 𝑥 away from 𝜎. Tensor and bang use the same substitution equation; unit and sums merely select a displayed subterm. The context case follows by the induction hypothesis and reconstruction of the unchanged context constructor. ◻
Proof of Theorem 36.30 — Safety after each structural delta
Proof. For preservation, induct on typing. A syntax-directed last rule is handled exactly as in theorem 18.17, using lemma 36.28 at beta, tensor, sum, and bang roots. If the last rule is affine weakening, apply the induction hypothesis to its premise and restore the same weakening. If it is relevant contraction, write its conclusion as 𝑑[𝑧/𝑥,𝑧/𝑦]. By lemma 36.29, the observed step is 𝑑[𝑧/𝑥,𝑧/𝑦]⟶𝑑′[𝑧/𝑥,𝑧/𝑦] for a step 𝑑⟶𝑑′. Apply the induction hypothesis to the contraction premise and reapply C-Rel. The unrestricted judgment has both cases.
For progress, neither weakening nor contraction can be the final rule of a derivation whose linear conclusion is empty: each adds a declaration to that conclusion. The final rule is therefore syntax directed. Its premises also have empty linear contexts wherever the existing progress induction needs a closed term. The canonical-form argument from theorem 18.18 applies unchanged because the structural deltas add no term or value. Iterate preservation to obtain the final safety claim. ◻
For comparison with the strict configuration judgment, write 𝐻⊩𝜌𝑒:𝐴⟺∃(𝑥ℎ)ℎ∈𝐻,𝑒0.⋅;(𝑥ℎ:𝖥𝗂𝗅𝖾)ℎ∈𝐻⊢𝜌𝑒0:𝐴∧𝑒=𝑒0[𝖿𝗂𝗅𝖾ℎ/𝑥ℎ]ℎ∈𝐻. where the 𝑥ℎ are pairwise distinct. Thus an affine placeholder may be unused, a relevant placeholder may be contracted to several occurrences, and an unrestricted placeholder may do either. This notation changes the static template discipline; it does not change the file machine, in which a single handle name still denotes a single live token.
The pure progress theorem theorem 36.30 holds in all four regimes. For the separate file machine, however, its consequences divide as follows.
Linear typing has configuration progress, preservation, exactly one dynamic owner of every live token, and cleanup, as in theorem 18.20.
Affine typing has configuration progress and preservation and maintains at most one displayed owner of a live token, but cleanup fails: a live token may have no owner.
Relevant typing forbids static abandonment—in particular, 𝐻⊩𝑟𝑣:1 implies 𝐻=∅—but contraction can give one token several displayed owners. Configuration preservation, and hence the iterated progress guarantee, can fail after the first consuming operation.
Unrestricted typing admits both the affine cleanup failure and the relevant preservation/progress failure.
Proof of Proposition 36.31 — The file boundary in the four regimes
Proof. The linear clause is the previous theorem. In the affine case the progress and preservation proofs repeat its template induction with weakening carried unchanged. Since affine typing has no contraction, no live token acquires more than one displayed placeholder occurrence. But affine typing derives 𝜆𝑓.∗:𝖥𝗂𝗅𝖾⊸1. For fresh ℎ, its closed use has the trace (∅,(𝜆𝑓.∗)(𝗈𝗉𝖾𝗇∗))𝐸−𝑂𝑝𝑒𝑛⟶({ℎ},(𝜆𝑓.∗)𝖿𝗂𝗅𝖾ℎ)𝐸−𝐿𝑖𝑛𝐵𝑒𝑡𝑎⟶({ℎ},∗), so evaluation returns unit while ℎ is live.
For the relevant boundary, contract two premises of type 𝖥𝗂𝗅𝖾 in 𝖻𝖺𝖽𝖢𝗅𝗈𝗌𝖾:=(𝜆𝑓.𝗅𝖾𝗍∗=𝖼𝗅𝗈𝗌𝖾𝑓𝗂𝗇𝖼𝗅𝗈𝗌𝖾𝑓)(𝗈𝗉𝖾𝗇∗). After allocation and beta, its two occurrences display the same token. Write 𝑐ℎ:=𝖼𝗅𝗈𝗌𝖾𝖿𝗂𝗅𝖾ℎ; then ({ℎ},𝗅𝖾𝗍∗=𝑐ℎ𝗂𝗇𝑐ℎ)𝐸−𝐶𝑙𝑜𝑠𝑒⟶(∅,𝗅𝖾𝗍∗=∗𝗂𝗇𝑐ℎ)𝐸−𝑂𝑛𝑒⟶(∅,𝑐ℎ). The last term is a nonvalue with no applicable file rule, because ℎ∉∅. Equivalently, the first close destroys the premise of the relevant template judgment for the remaining occurrence. This is a preservation failure, not a cleanup trace: the computation never returns unit. Conversely, a well-owned relevant value at unit is ∗ by the value grammar and inversion of its closing substitution. A derivation of ⋅;Δ⊢𝑟∗:1 has Δ=⋅: the T-OneI case is immediate, and a final C-Rel reduces the claim to its strictly smaller premise derivation, while no other rule concludes a typing for ∗. Hence the placeholder context indexed by 𝐻 is empty, so 𝐻=∅, without appealing to an unstated relevant-use theorem. Unrestricted typing derives both counterexamples. None is a counterexample to theorem 18.20, whose premise is strictly linear. ◻
The exponential is a local permission, not a global regime change: !𝐴 enters Γ only after introduction with empty linear context.
The number three
Zero, one, and arbitrary use do not express a fixed larger demand. Consider 𝗍𝗁𝗋𝗂𝖼𝖾=𝜆𝑓.𝜆𝑥.𝑓(𝑓(𝑓𝑥)). For 𝑓:𝐴⊸𝐴, the term is rejected because its three occurrences cannot occupy disjoint singleton contexts. Unpacking an !(𝐴⊸𝐴) yields the typable named wrapper: 𝗍𝗁𝗋𝗂𝖼𝖾!:=𝜆𝑔.𝗅𝖾𝗍!𝑓=𝑔𝗂𝗇𝜆𝑥.𝑓(𝑓(𝑓𝑥)),𝗍𝗁𝗋𝗂𝖼𝖾!:!(𝐴⊸𝐴)⊸(𝐴⊸𝐴). But that type says only “unrestricted”; it also types one, two, or a thousand calls. Affine and relevant typing say at most one and at least one. An exact three needs grades with addition for sibling uses and multiplication for nested uses. A quantitative judgment must therefore record a number, not only permission or prohibition.
Zero use is still information
Prerequisites.
This card uses only the dependent function displayed below and capture-avoiding substitution in its result family; both operations are specified locally. It is not a prerequisite for the chapter’s core calculus. The structural judgment established earlier is Γ;Δ⊢𝜌𝑒:𝐴. To avoid a collision with it, we alpha-rename McBride’s source symbols 𝑅,Γ,Δ,𝜌,𝜋 to Q,Θ,Ξ,𝑞,𝑝.
The number zero has a finer role once types may depend on terms. Removing a variable from a context makes it unavailable even to a type. Giving it zero run-time quantity can instead retain it for forming a type while forbidding its computational consumption.
Fix a rig Q, with zero, addition, and multiplication but no additive negation. A resource context Ξ marks every variable of one precontext Θ by a quantity in Q; context addition is pointwise and therefore retains zero-marked variables. The checking and synthesis judgments are Ξ⊢𝑞𝑇∋𝑡,Ξ⊢𝑞𝑒∈𝑆. The quantity 𝑞 asks for 𝑞 copies of the subject. Types are formed at quantity zero. A dependent function (𝑝𝑥:𝑆)→𝑇 has unit price 𝑝, and its application rule is
Ξ0⊢𝑞𝑓∈(𝑝𝑥:𝑆)→𝑇Ξ1⊢𝑞𝑝𝑆∋𝑠
Ξ0+Ξ1⊢𝑞𝑓𝑠∈𝑇[𝑠:𝑆/𝑥]
R-App
This is the bidirectional dependent calculus of [McB16], not a rule extension of 𝜆lin.
Because Ξ0 and Ξ1 mark the same precontext, substitution in the result type remains meaningful even where an argument has quantity zero in one premise. In the none–one–tons rig {0,1,𝜔}, the three prices read (0𝑥:𝑆)→𝑇staticcontemplation,(1𝑥:𝑆)→𝑇linearconsumption,(𝜔𝑥:𝑆)→𝑇unboundeduse. The comparison needs no indexed family: if the result family 𝑇(𝑥) mentions 𝑥, then (0𝑥:𝑆)→𝑇(𝑥) may contemplate 𝑥 without consuming it, whereas (1𝑥:𝑆)→𝑇(𝑥) permits one run-time use. Type-level dependency does not itself request a second run-time copy.
Proof of Proposition 36.33 — Four different notions at zero
Proof. The first two clauses follow from the shapes of precontexts and marked contexts. A zero-marked entry survives pointwise splitting, but the variable rule cannot consume it at a nonzero result quantity. The rigid calculus has no weakening rule. McBride’s later ordered variant adds Ξ⊢𝑞𝑇∋𝑡Ξ≤Ξ′Ξ′⊢𝑞𝑇∋𝑡R−Weak, with extra factorization, splitting, and zero-reflection conditions; that is the separate source of discardability. Finally, the judgments contain no rule equating all inhabitants of a proposition. Erasing a zero-priced argument from a run-time program is computational irrelevance, not definitional proof irrelevance. ◻
At the exact source signature, preservation is Corollary 36, unique erasure existence is Lemma 40 for 𝑞≠0, and erased program steps are simulated by source computation in Theorem 44 of [McB16]. The erasure development assumes the zero-sum property 𝑞+𝑝=0⟹𝑞=0=𝑝, rendering McBride’s stated “absence of negation” hypothesis in the book’s notation, so zero cannot arise by cancellation. The ordered-rig variant is the separate development in §12 of the same source. These results motivate quantities in later calculi; without a translation, they are not theorems about graded coeffects or dependent quantitative type theory.
★★☆ In the none–one–tons rig, classify each change to a context containing 𝑥:𝑆: remove 𝑥; mark it by zero; add an ordered weakening that permits an unused unit-priced input; postulate that all inhabitants of a proof type are equal. For each change, name which clause of proposition 36.33 it realizes and whether zero-erasure alone justifies it.
Wadler gives the connective order, term presentation, proof reductions, and the embedding of intuitionistic implication as !𝐴⊸𝐵[Wad93]. The dual-context reconstruction and operational theorems above are local. In particular, the file-token extension strengthens general promotion to value promotion; that premise blocks allocation beneath a duplicable constructor.
Girard develops the proof-theoretic discipline [Gir87], while Benton gives the historical mixed linear/nonlinear comparison [Ben94]. No categorical structure is used in the local proofs. McBride supplies the source-bounded zero-use comparison and its preservation and erasure theorems [McB16]; no result is transferred from that dependent calculus to the chapter’s token machine.
None of these problems is a prerequisite for a later chapter.
Each problem below combines two mechanisms already proved. No new rule is needed; the point is to locate the exact boundary at which a tempting stronger claim fails.
★★☆ Assume pairwise-disjoint Δ𝑣,Δ𝑤,Δ𝑒 and derivations Γ;Δ𝑣⊢𝑣:𝑃,Γ;Δ𝑤⊢𝑤:𝑄,Γ;Δ𝑒,𝑥:𝑃,𝑦:𝑄⊢𝑒:𝐶. Type both 𝗅𝖾𝗍𝑥⊗𝑦=𝑣⊗𝑤𝗂𝗇𝑒 and its reduct 𝑒[𝑣/𝑥,𝑤/𝑦] under Γ;Δ𝑣⊎Δ𝑤⊎Δ𝑒. Display the two one-variable substitutions and the associativity equation that identifies their conclusion context with the redex context.
★★★ Assume that Δ𝑡,Δ𝑠,Δ𝑟 are pairwise disjoint and that Γ;Δ𝑡⊢𝑡:𝑃⊗𝑄,Γ;Δ𝑠⊢𝑠:𝐴⊕𝐵,Γ;Δ𝑟,𝑝:𝑃,𝑞:𝑄,𝑥:𝐴⊢𝑒1:𝐶,Γ;Δ𝑟,𝑝:𝑃,𝑞:𝑄,𝑦:𝐵⊢𝑒2:𝐶. Take 𝑝,𝑞,𝑥,𝑦 pairwise distinct, with 𝑝,𝑞∉FV(𝑠) and 𝑥,𝑦∉FV(𝑡). Prove that both sides of 𝗅𝖾𝗍𝑝⊗𝑞=𝑡𝗂𝗇(𝖼𝖺𝗌𝖾𝑠𝗈𝖿𝗂𝗇𝗅𝑥⇒𝑒1∣𝗂𝗇𝗋𝑦⇒𝑒2)commutesto𝖼𝖺𝗌𝖾𝑠𝗈𝖿𝗂𝗇𝗅𝑥⇒𝗅𝖾𝗍𝑝⊗𝑞=𝑡𝗂𝗇𝑒1∣𝗂𝗇𝗋𝑦⇒𝗅𝖾𝗍𝑝⊗𝑞=𝑡𝗂𝗇𝑒2 have type 𝐶 under Γ;Δ𝑡⊎Δ𝑠⊎Δ𝑟. Display the common residual context at T-Case on each side.
★★★ Let Δ0,Δ𝑟,Θ be pairwise disjoint and assume Γ;Θ⊢𝑣:𝐴. First take Γ;Δ0,𝑥:𝐴⊢𝑠:𝑃⊕𝑄,Γ;Δ𝑟,𝑝:𝑃⊢𝑒1:𝐶,Γ;Δ𝑟,𝑞:𝑄⊢𝑒2:𝐶. Derive the substituted case under Γ;(Δ0⊎Θ)⊎Δ𝑟. Then instead take Γ;Δ0⊢𝑠:𝑃⊕𝑄,Γ;Δ𝑟,𝑥:𝐴,𝑝:𝑃⊢𝑒1:𝐶,Γ;Δ𝑟,𝑥:𝐴,𝑞:𝑄⊢𝑒2:𝐶. Substitute in both alternatives and derive the case under Γ;Δ0⊎(Δ𝑟⊎Θ). Explain why unequal residual contexts for the two alternatives would make T-Case inapplicable.
★★☆ Give inversion proofs that none of 𝜆𝑓.(𝗋𝖾𝖺𝖽𝑓)⊗(𝗋𝖾𝖺𝖽𝑓):𝖥𝗂𝗅𝖾⊸((𝖥𝗂𝗅𝖾⊗𝖡𝗒𝗍𝖾𝗌)⊗(𝖥𝗂𝗅𝖾⊗𝖡𝗒𝗍𝖾𝗌)),𝜆𝑓.∗:𝖥𝗂𝗅𝖾⊸1,𝜆𝑓.𝗅𝖾𝗍𝑓′⊗𝑏=𝗋𝖾𝖺𝖽𝑓𝗂𝗇𝑏:𝖥𝗂𝗅𝖾⊸𝖡𝗒𝗍𝖾𝗌 has its displayed type. Name the impossible split or missing use in the first two terms. In the third, show that tensor elimination leaves 𝑓′:𝖥𝗂𝗅𝖾 in the branch context after 𝑏 is returned.
★★☆ Define 𝑞(𝑧,𝑓):=𝖼𝖺𝗌𝖾𝑧𝗈𝖿𝗂𝗇𝗅𝑢⇒𝗅𝖾𝗍∗=𝑢𝗂𝗇𝗅𝖾𝗍∗=𝖼𝗅𝗈𝗌𝖾𝑓𝗂𝗇∗∣𝗂𝗇𝗋𝑣⇒𝗅𝖾𝗍∗=𝑣𝗂𝗇𝗅𝖾𝗍∗=𝖼𝗅𝗈𝗌𝖾𝑓𝗂𝗇∗. Derive ⋅;𝑧:1⊕1,𝑓:𝖥𝗂𝗅𝖾⊢𝑞(𝑧,𝑓):1. Although 𝑓 is printed in both alternatives, calculate 𝗎𝗌𝖾𝑓(𝑞(𝑧,𝑓))=1. For ℎ∈𝖳𝗈𝗄, trace both 𝑞(𝗂𝗇𝗅∗,𝖿𝗂𝗅𝖾ℎ) and 𝑞(𝗂𝗇𝗋∗,𝖿𝗂𝗅𝖾ℎ) from live set {ℎ} to (∅,∗).
★★☆ Let 𝖽𝗋𝗈𝗉:=(𝜆𝑓.∗)(𝗈𝗉𝖾𝗇∗). Using exactly one W-Aff, derive ⋅;⋅⊢𝑎𝖽𝗋𝗈𝗉:1. Then, for fresh ℎ∈𝖳𝗈𝗄, calculate (∅,𝖽𝗋𝗈𝗉)⟶∗({ℎ},(𝜆𝑓.∗)𝖿𝗂𝗅𝖾ℎ)⟶({ℎ},∗). Identify the cleanup conclusion of theorem 18.20 that fails to transfer to the affine regime. Explain why this is not a counterexample to the theorem, whose premise uses ⊩ from the strictly linear system.
★★☆ Derive the relevant typing of 𝖻𝖺𝖽𝖢𝗅𝗈𝗌𝖾 from proposition 36.31, displaying the two distinct file assumptions immediately above C-Rel. Give its complete file-machine trace through the stuck final configuration. Then state, separately, which of configuration preservation, one-owner, and cleanup fail in the affine, relevant, and unrestricted regimes. Do not call the relevant trace a cleanup counterexample.
★★☆ For an atomic 𝐴, classify 𝜆𝑥.𝑥:𝐴⊸𝐴,𝜆𝑥.∗:𝐴⊸1,𝜆𝑥.𝑥⊗𝑥:𝐴⊸(𝐴⊗𝐴), and 𝜆𝑥.(𝑥⊗𝑥)⊗𝑥:𝐴⊸((𝐴⊗𝐴)⊗𝐴) by the inclusion-minimal rule set among ⊢ℓ,⊢𝑎,⊢𝑟,⊢𝑢 that derives each judgment. Give the required number of weakenings and contractions. Prove by inversion that the discarded function is not relevant or linear and that each copying function is not affine or linear.
★★☆ Derive the displayed exponential type of the named term 𝗍𝗁𝗋𝗂𝖼𝖾!. Identify its three T-UVar uses of the variable released by T-BangE, and explain why the derivation records no numeral three. Finally explain why the unwrapped 𝗍𝗁𝗋𝗂𝖼𝖾 has no linear typing at (𝐴⊸𝐴)⊸(𝐴⊸𝐴).
★★★Practical project.linear-token-checker Implement the finite linear checker and token evaluator in Kappa. The oracle must accept tensor swap, equal-residual case analysis, copying after bang elimination, and 𝗋𝖾𝖺𝖽𝖢𝗅𝗈𝗌𝖾 with an empty final live set; it must reject duplicated and discarded linear variables, unequal branch residuals, a dropped post-read file, and effectful promotion. Mutate tensor so its second component receives the original context instead of the first component’s residual; the mutant must type-check and audit cleanly but fail at least the duplication case. Maintain two invariants explicitly: each linear variable is consumed exactly once on every accepted control-flow path, and each live runtime token has exactly one syntactic owner. Require the observable acceptance checks to report an empty final residual context for every accepted closed program and an empty final live-token set for the successful read-close run. The pathwise owner theorem remains the mathematical invariant proved in the chapter; the corpus does not emit a per-step ownership trace. Appendix E records the four acceptance commands and appendix F gives the implementation stages.