Dependent Session Types and Protocol-Indexed Programming
Prerequisites. Direct starred prerequisites: Chapter 21, Chapter 40. No later core chapter depends on this route.
The protocol 𝖭𝖺𝗍⊗𝖵𝖾𝖼⊗𝖾𝗇𝖽 of chapter 21 lets a provider send a natural number, then a vector, then stop. It does not require the vector length to equal the transmitted number. Replacing the second payload by a family 𝖵𝖾𝖼(𝑛) creates a binding problem: communication must substitute the received numeral into every later protocol, while the channel itself must still be used exactly once.
Fix a total dependent functional language with judgments Ψ⊢𝑀:𝜏 and capture-avoiding substitution. Session types extend the binary connectives of chapter 21 by two dependent quantifiers and one value-transport type: 𝐴,𝐵::=𝟏∣𝐴⊗𝐵∣𝐴⊸𝐵∣𝐴⊕𝐵∣𝐴&𝐵∣!𝐴∣∀𝑥:𝜏.𝐴∣∃𝑥:𝜏.𝐴∣$𝜏. Processes are generated by the following productions. The alternation bar of the grammar begins a line; a bar inside a production, as on the second line, is parallel composition of two processes. 𝑃,𝑄::=𝟎inaction∣𝑃∣𝑄parallelcomposition∣(𝜈𝑥)𝑃channelrestriction∣𝑥⟨𝑦⟩.𝑃sendafreshchannel𝑦∣𝑥(𝑦).𝑃receiveachanneloranindex∣!𝑥(𝑦).𝑃replicatedchannelinput∣𝑥⟨𝑀⟩.𝑃sendthefunctionalterm𝑀∣𝑥.𝗂𝗇𝗅;𝑃selecttheleftbranch∣𝑥.𝗂𝗇𝗋;𝑃selecttherightbranch∣𝑥.𝖼𝖺𝗌𝖾(𝑃,𝑄)offertwobranches∣[𝑥↔𝑦]forwarder∣[𝑥←𝑀]valuetransport The process judgment Ψ;Γ;Δ⟹𝑃::𝑧:𝐴 means that 𝑃 offers session 𝐴 along 𝑧, using functional variables Ψ, persistent channels Γ, and linear channels Δ. The domains of Γ and Δ are disjoint. Every declaration in Δ occurs in exactly one premise of a multiplicative rule.
Write 𝑃=𝗌𝖼𝑄 when 𝑃 and 𝑄 are structurally congruent. This is the least congruence containing alpha-equivalence and 𝑃∣𝟎=𝗌𝖼𝑃,𝑃∣𝑄=𝗌𝖼𝑄∣𝑃,𝑃∣(𝑄∣𝑅)=𝗌𝖼(𝑃∣𝑄)∣𝑅,𝑥∉fn(𝑃)⟹𝑃∣(𝜈𝑥)𝑄=𝗌𝖼(𝜈𝑥)(𝑃∣𝑄),(𝜈𝑥)𝟎=𝗌𝖼𝟎,(𝜈𝑥)(𝜈𝑦)𝑃=𝗌𝖼(𝜈𝑦)(𝜈𝑥)𝑃,[𝑥↔𝑦]=𝗌𝖼[𝑦↔𝑥]. Root reduction consists of the seven communication rules 𝑥⟨𝑦⟩.𝑄∣𝑥(𝑧).𝑃⟶𝑄∣𝑃[𝑦/𝑧],𝑥⟨𝑦⟩.𝑄∣!𝑥(𝑧).𝑃⟶𝑄∣𝑃[𝑦/𝑧]∣!𝑥(𝑧).𝑃,𝑥⟨𝑀⟩.𝑄∣𝑥(𝑧).𝑃⟶𝑄∣𝑃[𝑀/𝑧],(𝜈𝑥)([𝑥↔𝑦]∣𝑃)⟶𝑃[𝑦/𝑥],(𝜈𝑥)([𝑥←𝑀]∣𝑃)⟶𝑃[𝑀/𝑥],𝑥.𝗂𝗇𝗅;𝑃∣𝑥.𝖼𝖺𝗌𝖾(𝑄,𝑅)⟶𝑃∣𝑄,𝑥.𝗂𝗇𝗋;𝑃∣𝑥.𝖼𝖺𝗌𝖾(𝑄,𝑅)⟶𝑃∣𝑅. It is closed by parallel composition and restriction: 𝑄⟶𝑄′𝑃∣𝑄⟶𝑃∣𝑄′,𝑃⟶𝑄(𝜈𝑦)𝑃⟶(𝜈𝑦)𝑄, and by structural congruence: if 𝑃=𝗌𝖼𝑃′, 𝑃′⟶𝑄′, and 𝑄′=𝗌𝖼𝑄, then 𝑃⟶𝑄. These clauses define every use of ⟶ through theorem 102.8, theorem 102.9.
Eighteen rules are inherited unchanged from the propositions-as-sessions reading of chapter 21. They are collected here because the preservation proof below rebuilds each of them.
Ψ;Γ;𝑥:𝐴⟹[𝑥↔𝑧]::𝑧:𝐴
Id
Ψ;Γ;⋅⟹𝟎::𝑧:𝟏
Ψ;Γ;Δ⟹𝑃::𝑧:𝐶
Ψ;Γ;Δ,𝑥:𝟏⟹𝑃::𝑧:𝐶
Ψ;Γ;Δ1⟹𝑃::𝑦:𝐴Ψ;Γ;Δ2⟹𝑄::𝑧:𝐵
Ψ;Γ;Δ1,Δ2⟹(𝜈𝑦)𝑧⟨𝑦⟩.(𝑃∣𝑄)::𝑧:𝐴⊗𝐵
Ψ;Γ;Δ,𝑦:𝐴,𝑥:𝐵⟹𝑃::𝑧:𝐶
Ψ;Γ;Δ,𝑥:𝐴⊗𝐵⟹𝑥(𝑦).𝑃::𝑧:𝐶
Ψ;Γ;Δ,𝑥:𝐴⟹𝑃::𝑧:𝐵
Ψ;Γ;Δ⟹𝑧(𝑥).𝑃::𝑧:𝐴⊸𝐵
Ψ;Γ;Δ1⟹𝑃::𝑦:𝐴Ψ;Γ;Δ2,𝑥:𝐵⟹𝑄::𝑧:𝐶
Ψ;Γ;Δ1,Δ2,𝑥:𝐴⊸𝐵⟹(𝜈𝑦)𝑥⟨𝑦⟩.(𝑃∣𝑄)::𝑧:𝐶
Ψ;Γ;Δ⟹𝑃::𝑧:𝐴Ψ;Γ;Δ⟹𝑄::𝑧:𝐵
Ψ;Γ;Δ⟹𝑧.𝖼𝖺𝗌𝖾(𝑃,𝑄)::𝑧:𝐴&𝐵
Ψ;Γ;Δ,𝑥:𝐴⟹𝑃::𝑧:𝐶Ψ;Γ;Δ,𝑥:𝐵⟹𝑄::𝑧:𝐶
Ψ;Γ;Δ,𝑥:𝐴⊕𝐵⟹𝑥.𝖼𝖺𝗌𝖾(𝑃,𝑄)::𝑧:𝐶
⊕L
Ψ;Γ;Δ,𝑥:𝐴⟹𝑃::𝑧:𝐶
Ψ;Γ;Δ,𝑥:𝐴&𝐵⟹𝑥.𝗂𝗇𝗅;𝑃::𝑧:𝐶
_1
Ψ;Γ;Δ⟹𝑃::𝑧:𝐴
Ψ;Γ;Δ⟹𝑧.𝗂𝗇𝗅;𝑃::𝑧:𝐴⊕𝐵
⊕R_1
The companion rules &L2 and ⊕R2 replace 𝗂𝗇𝗅 by 𝗂𝗇𝗋, 𝐴 by 𝐵 in the premise, and nothing else. Replication is
Ψ;Γ;⋅⟹𝑃::𝑦:𝐴
Ψ;Γ;⋅⟹!𝑧(𝑦).𝑃::𝑧:!𝐴
!R
Ψ;Γ,𝑢:𝐴;Δ⟹𝑃::𝑧:𝐶
Ψ;Γ;Δ,𝑥:!𝐴⟹𝑃[𝑥/𝑢]::𝑧:𝐶
!L
Ψ;Γ,𝑢:𝐴;Δ,𝑦:𝐴⟹𝑃::𝑧:𝐶
Ψ;Γ,𝑢:𝐴;Δ⟹(𝜈𝑦)𝑢⟨𝑦⟩.𝑃::𝑧:𝐶
Copy
and the two cuts are
Ψ;Γ;Δ1⟹𝑃::𝑥:𝐴Ψ;Γ;Δ2,𝑥:𝐴⟹𝑄::𝑧:𝐶
Ψ;Γ;Δ1,Δ2⟹(𝜈𝑥)(𝑃∣𝑄)::𝑧:𝐶
Cut
Ψ;Γ;⋅⟹𝑃::𝑥:𝐴Ψ;Γ,𝑢:𝐴;Δ⟹𝑄::𝑧:𝐶
Ψ;Γ;Δ⟹(𝜈𝑢)((!𝑢(𝑥).𝑃)∣𝑄)::𝑧:𝐶
Cut^!
Six rules are new, and the smallest pair comes first. The transport type $𝜏, written with a dollar sign because it imports a functional value into the session language, internalizes a checked term as a session. Its right rule offers such a value; its left rule changes one linear channel assumption into a functional assumption:
Ψ⊢𝑀:𝜏
Ψ;Γ;⋅⟹[𝑧←𝑀]::𝑧:$𝜏
Ψ,𝑥:𝜏;Γ;Δ⟹𝑃::𝑧:𝐶
Ψ;Γ;Δ,𝑥:$𝜏⟹𝑃::𝑧:𝐶
The process term in the conclusion is the same syntax 𝑃; the rule changes the sort of the name 𝑥. A cut against $R performs the delayed functional substitution: (𝜈𝑥)([𝑥←𝑀]∣𝑃)⟶𝑃[𝑀/𝑥]. A bank that receives an identifier and a deposit and then stops offers 𝖳𝖡𝖺𝗇𝗄:=$𝗌𝗍𝗋𝗂𝗇𝗀⊸($𝗇𝖺𝗍⊸𝟏), and the process 𝑥(𝑠).𝑥(𝑛).𝟎 offers it along 𝑥. Nothing in that type relates 𝑠 to 𝑛. Making the second payload depend on the first is what the quantifiers below add.
The source writes dependent quantifiers as behavioral input and output:
The beta communication is (𝜈𝑦)(𝑦(𝑥).𝑃∣𝑦⟨𝑀⟩.𝑄)⟶(𝜈𝑦)(𝑃[𝑀/𝑥]∣𝑄). The substitution in the reduct acts on functional terms, process terms, session types, and channel classifiers.
In the intuitionistic presentation, a right rule describes the provider and a left rule describes the client; typing requires no endpoint duality operator. A two-ended interface needs one, and chapter 21 already fixes it on the binary connectives. Only the two quantifiers and the transport type are new.
On the fragment without the shared service type !𝐴, extend the duality of chapter 21 by ―――――∀𝑥:𝜏.𝐴=∃𝑥:𝜏.――𝐴,―――――∃𝑥:𝜏.𝐴=∀𝑥:𝜏.――𝐴,―――$𝜏=$𝜏. The inherited clauses are unchanged, and in particular ――――𝐴⊗𝐵=𝐴⊸――𝐵,――――𝐴⊸𝐵=𝐴⊗――𝐵.
Read the two inherited clauses carefully, because the tempting variant is wrong. In ⊗R the provider creates a fresh channel 𝑦 and itself offers 𝐴 on it; in ⊗L the client receives 𝑦 as an assumption 𝑦:𝐴. Both endpoints therefore name the transmitted channel by the same type 𝐴, and duality must leave the payload alone. Writing ――𝐴⊸――𝐵 instead would dualize a channel that no endpoint ever reads from the other side; chapter 21 rejects it for the same reason and restricts syntactic duality to closed message types. The quantifier clauses are safe because 𝜏 is a functional type, not a session type, so there is nothing in 𝜏 to dualize.
Both new clauses are involutive, and $𝜏 is self-dual because value transport moves a functional term in one direction only. None of them adds a rule to the source calculus.
Suppose the provider and client derivations end in matching ∀R/∀L rules, or matching ∃R/∃L rules. Their cut reduces to a cut whose two channel classifiers are both 𝐴[𝑀/𝑥].
Proof of Lemma 102.5 — Quantifier communication fidelity
Proof. For ∀, the provider continuation is derived under 𝑥:𝜏 with offered type 𝐴. The client premise contains 𝑦:𝐴[𝑀/𝑥]. Functional substitution in the provider derivation gives offered type 𝐴[𝑀/𝑥], so the reduct (𝜈𝑦)(𝑃[𝑀/𝑥]∣𝑄) is a cut on that same type. For ∃, the provider premise already offers 𝐴[𝑀/𝑥], and substitution in the client premise changes its assumption from 𝐴 to 𝐴[𝑀/𝑥]. Thus both quantifier pairs produce the displayed classifier. ◻
★☆☆ For 𝐴 in the shared-free fragment, prove by induction on 𝐴 that ―――――𝐴[𝑀/𝑥]=――𝐴[𝑀/𝑥]. Write the two quantifier cases and state why capture-avoiding renaming is needed when the outer binder has the same name as 𝑥.
Let 𝖵𝖾𝖼(𝐸,𝑛) be the functional type of vectors of elements of 𝐸 and length 𝑛. A provider that first receives a length and then a matching vector offers 𝖱𝖾𝖼𝗏𝖵𝖾𝖼(𝐸):=∀𝑛:𝖭𝖺𝗍.∀𝑣:𝖵𝖾𝖼(𝐸,𝑛).𝟏. A dual sender offers the existential interface 𝖲𝖾𝗇𝖽𝖵𝖾𝖼(𝐸):=∃𝑛:𝖭𝖺𝗍.∃𝑣:𝖵𝖾𝖼(𝐸,𝑛).𝟏. Let 𝑎,𝑏:𝐸 and put 𝑤2:=𝖼𝗈𝗇𝗌𝑎(𝖼𝗈𝗇𝗌𝑏𝗇𝗂𝗅):𝖵𝖾𝖼(𝐸,2),𝑤1:=𝖼𝗈𝗇𝗌𝑎𝗇𝗂𝗅:𝖵𝖾𝖼(𝐸,1). If the sender chooses the witness 2 and then the witness 𝑤2, the two communications calculate the residual protocol as (∃𝑛:𝖭𝖺𝗍.∃𝑣:𝖵𝖾𝖼(𝐸,𝑛).𝟏)[2/𝑛]=∃𝑣:𝖵𝖾𝖼(𝐸,2).𝟏,(∃𝑣:𝖵𝖾𝖼(𝐸,2).𝟏)[𝑤2/𝑣]=𝟏. Sending 𝑤1 instead fails at the second step. Rule ∃R requires Ψ⊢𝑤1:𝖵𝖾𝖼(𝐸,2), and 𝑤1 has type 𝖵𝖾𝖼(𝐸,1); the first witness fixes the index at 2. The rejection occurs in the functional premise of the typing rule, before any communication happens.
A proof-relevant branch can transmit ∃𝑛:𝖭𝖺𝗍.∃𝑝:𝖤𝗏𝖾𝗇(𝑛).(𝖧𝖺𝗅𝖿𝖯𝖺𝗒𝗅𝗈𝖺𝖽(𝑛,𝑝)⊕𝖱𝖾𝗃𝖾𝖼𝗍). The continuation may depend on the proof 𝑝, not merely on the Boolean fact that 𝑛 is even. Erasing 𝑝 requires the separate proof-irrelevant extension and its erasure theorem; dependent sessions alone do not erase it.
★★☆ Derive the provider and client rules for a transfer of a length-three vector. Perform the two communication steps and write the residual type after each substitution. Replace the vector by length two and identify the first premise that has no derivation.
Functional substitution changes indices everywhere. Channel substitution composes processes and splits only the linear channel context. Conflating them loses the invariant needed by preservation.
Proof of Lemma 102.6 — Functional weakening and substitution
Proof. Weakening is induction on the functional or process derivation. The quantifier binder case alpha-renames its bound name to a name outside FV(𝑀)∪dom(Ψ,Ψ′).
For substitution, induct on the process derivation while using the functional substitution theorem in every term premise. In ∀R, choose 𝑦∉FV(𝑀)∪dom(Ψ,Ψ′); the induction hypothesis yields the substituted body under 𝑦:𝜎, and the rule rebuilds the quantified conclusion. In ∀L, functional substitution gives the witness type and the process induction hypothesis gives the continuation with classifier 𝐵[𝑁/𝑦][𝑀/𝑥]. The fresh choice gives 𝐵[𝑀/𝑥][𝑁[𝑀/𝑥]/𝑦], the classifier required by the rebuilt rule. The two existential cases use the same commutation equation, with right and left rules exchanged.
It remains to check twenty concrete rules, or eighteen rule schemas when the two branch indices are grouped. Put 𝜃=[𝑀/𝑥],̂Ψ=Ψ,Ψ′[𝑀/𝑥]. Write a superscript (−)𝜃 for simultaneous capture-avoiding action on channel contexts, processes, and offered types. The cases fall into the following exhaustive forms.
The nullary cases are Id, 𝟏R, and $R. For Id, substitution changes only the classifier: ̂Ψ;Γ𝜃;𝑦:𝐴𝜃⟹[𝑦↔𝑧]::𝑧:𝐴𝜃. Rule 𝟏R is unchanged because its linear context and offered type contain no index. In $R, functional substitution first changes its sole premise Ψ,𝑥:𝜏,Ψ′⊢𝑁:𝜎 into Ψ,Ψ′𝜃⊢𝑁𝜃:𝜎𝜃; rebuilding $R gives [𝑧←𝑁𝜃]::𝑧:$𝜎𝜃.
Four rules split a linear context. The representative ⊗R case is ̂Ψ;Γ𝜃;Δ𝜃1⟹𝑃𝜃::𝑦:𝐴𝜃̂Ψ;Γ𝜃;Δ𝜃2⟹𝑄𝜃::𝑧:𝐵𝜃̂Ψ;Γ𝜃;Δ𝜃1,Δ𝜃2⟹(𝜈𝑦)𝑧⟨𝑦⟩.(𝑃𝜃∣𝑄𝜃)::𝑧:𝐴𝜃⊗𝐵𝜃. The induction hypotheses supply its two premises. Since 𝜃 changes classifiers but no channel name, dom(Δ𝜃1)∩dom(Δ𝜃2)=∅. Rule ⊸L is this schema with the first result channel sent to the second premise. Rule Cut replaces the displayed output constructor by (𝜈𝑦)(𝑃𝜃∣𝑄𝜃). Rule Cut! has an empty first linear context and puts its cut formula in the persistent context of the second premise. Functional substitution preserves both facts, so those three rules rebuild without an additional structural principle.
Two rules have two premises with the same linear context. For &R, the two induction hypotheses have exactly Δ𝜃 and rebuild 𝑧.𝖼𝖺𝗌𝖾(𝑃𝜃,𝑄𝜃). For ⊕L, they have Δ𝜃,𝑦:𝐴𝜃 and Δ𝜃,𝑦:𝐵𝜃, respectively, and rebuild 𝑦.𝖼𝖺𝗌𝖾(𝑃𝜃,𝑄𝜃). Thus neither case silently turns a shared context into a split one.
The remaining unary cases are exact instances of ̂Ψ;Γ𝜃;(Δ,𝑦:𝐴)𝜃⟹𝑃𝜃::𝑧:𝐶𝜃̂Ψ;Γ𝜃;(Δ,𝑦:𝐹(𝐴))𝜃⟹𝐹𝑦(𝑃𝜃)::𝑧:𝐺(𝐴,𝐶)𝜃,(𝑈) where 𝐹,𝐹𝑦,𝐺 are the constructors printed on the corresponding rule. The exact instances are as follows. Rule 𝟏L deletes the unused 𝑦:𝟏 from the premise. Rule ⊗L replaces premise entries 𝑤:𝐴,𝑦:𝐵 by the one conclusion entry 𝑦:𝐴⊗𝐵. Rule ⊸R abstracts the premise entry 𝑦:𝐴 and offers 𝐴⊸𝐵. Rules &L1 and &L2 select 𝐴 and 𝐵, respectively; rules ⊕R1 and ⊕R2 make the corresponding offered choice. Because substitution commutes with each type constructor, for example (𝐴⊗𝐵)𝜃=𝐴𝜃⊗𝐵𝜃, each conclusion is the required instance of (U).
For !R, the induction hypothesis retains the empty linear context. For !L, it changes the persistent premise entry 𝑢:𝐴 to 𝑢:𝐴𝜃 and the linear conclusion entry 𝑦:!𝐴 to 𝑦:!𝐴𝜃. The Copy case changes both its persistent 𝑢:𝐴 and fresh linear 𝑦:𝐴 entries to 𝐴𝜃; the side condition that 𝑦 is fresh is preserved because 𝜃 introduces no channel names. Finally, $L is alpha-renamed so that its channel name 𝑦 is different from the substituted functional variable 𝑥. Its induction hypothesis changes the premise functional entry from 𝑦:𝜎 to 𝑦:𝜎𝜃, and $L rebuilds the conclusion entry 𝑦:$𝜎𝜃. These nullary, split, same-context binary, unary, and four quantifier cases cover every rule in definition 102.1, definition 102.3. ◻
Composition of processes is Cut, and nothing has to be proved to compose them: the rule is the composition principle, and its disjointness side condition is what makes the composite linear. What does have to be proved is that composing a matching provider and client produces a step, and that the step leaves a well-typed process behind. Lemma 102.7 states that fact; it is the only channel-level result the preservation proof needs.
Let Ψ;Γ;Δ1⟹𝑃::𝑥:𝐴,Ψ;Γ;Δ2,𝑥:𝐴⟹𝑄::𝑧:𝐶, with dom(Δ1)∩dom(Δ2)=∅, so that Cut derives Ψ;Γ;Δ1,Δ2⟹(𝜈𝑥)(𝑃∣𝑄)::𝑧:𝐶. If in addition 𝑃 ends in the right rule for 𝐴 and 𝑄 in a left rule for 𝐴, then the following alternatives hold.
If 𝐴≠!𝐵, the cut reduces, and its reduct is derivable at the same conclusion Ψ;Γ;Δ1,Δ2⟹−::𝑧:𝐶 using only cuts on the immediate subformulas of 𝐴.
If 𝐴=!𝐵, proof conversion changes the ordinary cut to a persistent cut without a process step. Whenever its client exposes a Copy request, the request reduces to one cut on 𝐵, and the replicated provider remains available in Γ.
Proof. By cases on the cut formula 𝐴. Each nonpersistent case exhibits the step and then the rebuilt derivation; the conclusion is the same in every case, so only the cut structure changes. The persistent case exhibits first the proof conversion and then the step triggered by Copy.
For ∀𝑦:𝜏.𝐵, the provider receives a term by ∀R and the client sends one by ∀L. lemma 102.5 gives both residual classifiers as 𝐵[𝑀/𝑦], so the reduct is one cut on 𝐵[𝑀/𝑦]. For ∃ the polarities are exchanged and the same lemma applies.
For 𝐴1⊗𝐴2, the provider is (𝜈𝑦)𝑥⟨𝑦⟩.(𝑃1∣𝑃2) with 𝑃1::𝑦:𝐴1 and 𝑃2::𝑥:𝐴2, and the client is 𝑥(𝑦).𝑄 with 𝑦:𝐴1,𝑥:𝐴2 among its assumptions. The step is (𝜈𝑥)((𝜈𝑦)𝑥⟨𝑦⟩.(𝑃1∣𝑃2)∣𝑥(𝑦).𝑄)⟶(𝜈𝑥)(𝑃2∣(𝜈𝑦)(𝑃1∣𝑄)). Read the reduct carefully, because it is not what a substitution lemma would produce. The name 𝑥 survives: the inner cut composes 𝑃1 and 𝑄 on the fresh 𝑦 at type 𝐴1, and the outer cut still composes 𝑃2 and that composite on 𝑥, now at the residual type 𝐴2. One cut at 𝐴1⊗𝐴2 has become two, at 𝐴1 and at 𝐴2; the channel is consumed only when its type is finally 𝟏. 𝐴1⊸𝐴2 is the same step with provider and client exchanged.
For 𝐴1⊕𝐴2, the selection prefix 𝑥.𝗂𝗇𝗅 meets 𝑥.𝖼𝖺𝗌𝖾 and the reduct discards the unselected branch, leaving one cut on 𝐴1 along the same 𝑥; & exchanges the two sides. For 𝟏 the provider is 𝟎 and the client continues, so the cut disappears and 𝑥 is consumed — this is the one case in which it is. For $𝜏 the delayed functional substitution of definition 102.2 fires and 𝑥 changes sort from a linear channel to a functional assumption.
For !𝐵, the principal proof reduction first turns the ordinary cut against !L into the persistent cut (𝜈𝑢)(!𝑢(𝑦).𝑃0∣𝑄), where 𝑃0::𝑦:𝐵 has no linear assumptions and 𝑄 uses 𝑢:𝐵 only through Copy. A particular copy has process (𝜈𝑣)𝑢⟨𝑣⟩.𝑅. Scope extrusion exposes the root step 𝑢⟨𝑣⟩.𝑅∣!𝑢(𝑦).𝑃0⟶𝑅∣𝑃0[𝑣/𝑦]∣!𝑢(𝑦).𝑃0. The request channel 𝑣 is linear and the resulting cut formula is the immediate subformula 𝐵. The replicated input remains available, but its contraction is confined to the persistent declaration 𝑢:𝐵 in Γ; no declaration of Δ1,Δ2 is copied.
In every case the conclusion retains the union Δ1,Δ2, and disjointness is what lets the two premises be recombined without a name clash. ◻
Dropping disjointness from Cut permits both premises to use one linear channel, and the conclusion then duplicates it. Dropping totality of the functional language can make equality checking of protocol indices diverge. These hypotheses have different roles and neither follows from the other.
Proof. Induct on the typing derivation. A principal cut is lemma 102.7, whose statement already gives the rebuilt derivation at the same conclusion. The dependent quantifier cases of that lemma rest on lemma 102.5, and term passing additionally uses lemma 102.6 to move 𝑀 into the residual classifier. A reduction under parallel composition or restriction rebuilds the induction hypothesis with the same linear split. Structural congruence uses exchange, alpha-renaming, and the fact that restriction extrusion preserves the disjointness side condition. The persistent cut case invokes contraction only in Γ, never in Δ. These cases cover the operational rules of definition 102.2, so the induction proves preservation for the displayed calculus. ◻
If ⋅;⋅;⋅⟹𝑃::𝑥:𝟏and𝗅𝗂𝗏𝖾(𝑃), then there is a process 𝑄 such that 𝑃⟶𝑄. Here 𝗅𝗂𝗏𝖾(𝑃) means that, up to restrictions and structural congruence, 𝑃 contains a nonreplicated prefix, a forwarding process, or a term substitution.
Proof. We first prove the contextual claim used by the closed theorem. If Ψ;Γ;Δ⟹𝑅::𝑧:𝐶 and 𝗅𝗂𝗏𝖾(𝑅), then at least one of the following conclusions is derivable up to structural congruence:
𝑅⟶𝑅′ for some process 𝑅′;
𝑅 exposes a prefix whose subject is 𝑧, a channel in Δ, or, when 𝐶=!𝐴, a persistent channel in Γ;
𝑅 is a forwarding process [𝑥↔𝑧] with 𝑥∈Δ, or a functional substitution [𝑥←𝑀] whose free functional variables lie in Ψ.
Prove the claim by induction on the last typing rule. An introduction rule for ⊗,⊸,⊕,&,𝟏,∃, or ∀ exposes the constructor prescribed by that rule, so clause 2 holds. A forwarding or functional-substitution rule gives clause 3. Exchange and alpha-renaming preserve the selected clause because they change neither a prefix subject nor the free-channel set.
It remains to check the two cut families. Write the cut as (𝜈𝑥)(𝑅1∣𝑅2), with disjoint linear contexts in its two premises. Apply the induction hypothesis to every live premise. If one premise reduces, compatible closure reduces the cut. If the two premises expose dual actions on 𝑥, the corresponding root rule in definition 102.2 reduces the cut. This includes channel passing, label selection, termination, and the two dependent-quantifier cases. In a dependent communication, the residual classifiers are equal by lemma 102.5; functional payload communication also uses lemma 102.6. If no exposed action has subject 𝑥, restriction hides 𝑥 and the remaining exposed action has a free subject belonging to the conclusion context. A forwarding or functional-substitution form at 𝑥 contracts by the appropriate cut root; one on a different subject survives restriction and gives clause 3. A persistent cut uses the same analysis, except that contraction occurs only in Γ. These cases exhaust the typing rules and prove the contextual claim.
Apply the claim to the theorem’s derivation. The assumed-channel contexts Γ and Δ are empty, so clauses 2 and 3 cannot mention an assumed channel or a free functional payload. The offered channel has type 𝟏; its only introduction is the inactive termination process, which contradicts 𝗅𝗂𝗏𝖾(𝑃). Thus clause 2 is impossible on the offered channel as well. Clause 3 is impossible in the empty contexts. Clause 1 remains, and supplies 𝑄 with 𝑃⟶𝑄. ◻
The theorem does not apply to an open process waiting on an environment, to an ill-formed functional index, or to a multiparty network with incompatible global projections. It proves neither asynchronous queue safety nor a QTT resource bound.
★★☆ Construct a live, well-typed open process that waits for input on one linear environment channel. Show why each premise except closedness matches theorem 102.9, and why the process need not reduce alone.
The array transfer of section 102.2 sends one vector. A provider that sends 𝑛 separate elements, where 𝑛 is the numeral it has just transmitted, cannot be written at all in definition 102.1: the grammar of session types is finite and has no recursion, and ⊕ and & choose between two fixed continuations rather than between continuations selected by an index. Neither gap is an oversight in the presentation. Definition 102.1 is the complete set of connectives of the selected calculus, so both features require a different signature, and every theorem must be reproved there.
One such signature places the protocol itself in a static sort 𝗌𝗍𝗒𝗉𝖾 of the indexed functional language, so that a session type is a static term and index-level computation can build it.
Extend the base sorts of the indexed functional language by a sort 𝗌𝗍𝗒𝗉𝖾. The complete static lambda-calculus grammar used here is 𝑏0::=𝗂𝗇𝗍∣𝖻𝗈𝗈𝗅∣𝗍𝗒𝗉𝖾∣𝗏𝗍𝗒𝗉𝖾∣𝗌𝗍𝗒𝗉𝖾,𝜎::=𝑏0∣𝜎1→𝜎2,𝑠::=𝑎∣𝑐(𝑠1,…,𝑠𝑘)∣𝜆𝑎:𝜎.𝑠∣𝑠1(𝑠2). Static typing is the simply typed lambda calculus over a signature of sorted constants. Its constants of result sort 𝗌𝗍𝗒𝗉𝖾 generate protocols 𝜋::=𝖾𝗇𝖽(𝑖)∣𝗆𝗌𝗀(𝑖,̂𝜏)::𝜋∣𝖻𝗋𝖺𝗇𝖼𝗁(𝑖,𝜋1,𝜋2)∣𝗂𝗍𝖾(𝑏,𝜋1,𝜋2)∣𝗊𝗎𝖺𝗇(𝑖,𝜆𝑎:𝜎.𝜋)∣𝖿𝗂𝗑(𝜆𝑎:𝗌𝗍𝗒𝗉𝖾.𝜋), where 𝑖 names one of the two parties, ̂𝜏 is a linear type, 𝑏 is a static Boolean expression, and 𝜎 is a sort. A channel endpoint is classified by 𝖼𝗁𝖺𝗇(𝑟,𝜋), where 𝑟 is the role that reads 𝜋 locally. The three constructs absent from definition 102.1 are the last three: 𝗂𝗍𝖾 selects a continuation from a static Boolean, 𝗊𝗎𝖺𝗇 is the common form of the two quantifiers, and 𝖿𝗂𝗑 takes the fixed point of a static function on protocols. Thus 𝖿𝗂𝗑 in this grammar has argument sort (𝗌𝗍𝗒𝗉𝖾→𝗌𝗍𝗒𝗉𝖾); it does not accept a function of sort 𝗂𝗇𝗍→𝗌𝗍𝗒𝗉𝖾.
The array example uses an explicitly separate higher-order fixed-point extension. For a sort 𝜎, add 𝑓:𝜎→𝗌𝗍𝗒𝗉𝖾,𝑎:𝜎⊢𝜋:𝗌𝗍𝗒𝗉𝖾⊢𝑠:𝜎⊢𝖿𝗂𝗑𝜎(𝜆𝑓:𝜎→𝗌𝗍𝗒𝗉𝖾.𝜆𝑎:𝜎.𝜋;𝑠):𝗌𝗍𝗒𝗉𝖾. Its unfolding equation is well sorted and is named Fix: 𝖿𝗂𝗑𝜎(𝐹;𝑠)≡𝐹(𝜆𝑎:𝜎.𝖿𝗂𝗑𝜎(𝐹;𝑎))𝑠,𝐹:(𝜎→𝗌𝗍𝗒𝗉𝖾)→𝜎→𝗌𝗍𝗒𝗉𝖾.(𝐹𝑖𝑥)
Because 𝗂𝗍𝖾 branches on an index rather than on a transmitted label, it is genuinely index-dependent choice: the two endpoints agree on which branch is taken by computing 𝑏, and no selection message is sent. Ordinary label choice is the special case 𝖻𝗋𝖺𝗇𝖼𝗁(𝑖,𝜋1,𝜋2), which 𝗂𝗍𝖾 can encode.
The array protocol is now expressible. Write 𝗋𝖾𝗉𝖾𝖺𝗍(𝜏,𝑛):=𝗂𝗍𝖾(𝑛>0,𝗆𝗌𝗀(𝖲,𝜏)::𝗋𝖾𝗉𝖾𝖺𝗍(𝜏,𝑛−1),𝖾𝗇𝖽(𝖲)),𝖺𝗋𝗋𝖺𝗒(𝜏):=𝗊𝗎𝖺𝗇(𝖲,𝜆𝑛:𝗂𝗇𝗍.𝗆𝗌𝗀(𝖲,𝗂𝗇𝗍(𝑛))::𝗋𝖾𝗉𝖾𝖺𝗍(𝜏,𝑛)), where 𝗋𝖾𝗉𝖾𝖺𝗍 abbreviates the higher-order fixed point 𝖿𝗂𝗑𝗂𝗇𝗍(𝜆𝑝:𝗂𝗇𝗍→𝗌𝗍𝗒𝗉𝖾.𝜆𝑛:𝗂𝗇𝗍.𝗂𝗍𝖾(𝑛>0,𝗆𝗌𝗀(𝖲,𝜏)::𝑝(𝑛−1),𝖾𝗇𝖽(𝖲));𝑛). Here the body has sort 𝗌𝗍𝗒𝗉𝖾 under 𝑝:𝗂𝗇𝗍→𝗌𝗍𝗒𝗉𝖾 and 𝑛:𝗂𝗇𝗍, so the formation rule above applies. The parameter 𝑛 is supplied after the fixed point is tied; it is not passed to the unary 𝗌𝗍𝗒𝗉𝖾→𝗌𝗍𝗒𝗉𝖾 constructor of the core grammar. Read 𝖺𝗋𝗋𝖺𝗒(𝜏) as: the sender chooses 𝑛, sends an integer of the singleton type 𝗂𝗇𝗍(𝑛), and then sends exactly 𝑛 elements of type 𝜏. Unfold it at 𝑛=2: 𝗋𝖾𝗉𝖾𝖺𝗍(𝜏,2)𝐹𝑖𝑥=𝗆𝗌𝗀(𝖲,𝜏)::𝗋𝖾𝗉𝖾𝖺𝗍(𝜏,1)𝐹𝑖𝑥=𝗆𝗌𝗀(𝖲,𝜏)::𝗆𝗌𝗀(𝖲,𝜏)::𝗋𝖾𝗉𝖾𝖺𝗍(𝜏,0)𝐹𝑖𝑥=𝗆𝗌𝗀(𝖲,𝜏)::𝗆𝗌𝗀(𝖲,𝜏)::𝖾𝗇𝖽(𝖲). Each step evaluates the static Boolean 𝑛>0 and only then selects a branch; the recursion terminates because the index decreases and 𝗂𝗍𝖾 reaches its second branch at 0. This is the exact sense in which the recursion is data-indexed: the protocol’s length is the transmitted numeral.
★★☆ Unfold 𝖺𝗋𝗋𝖺𝗒(𝜏) at 𝑛=3 and write the resulting finite protocol. Then evaluate 𝗋𝖾𝗉𝖾𝖺𝗍(𝜏,𝑛) with the guard 𝑛>0 replaced by 𝑛≥0 over the integers, and identify the first index at which the unfolding stops terminating.
Three deltas separate the two systems, and none of them is cosmetic. The logical calculus types proof terms in Ψ and composes processes by Cut; ATS elaborates statics and linear views into a programming-language core and discharges index constraints with an external solver. The logical calculus has no 𝗂𝗍𝖾, no 𝖿𝗂𝗑, and no roles; the static language has no cut rule, so it has no cut-elimination argument to carry preservation. Consequently theorem 102.8, theorem 102.9 say nothing about definition 102.10. In particular, the logical theorems do not hold for recursive or index-chosen protocols without a separate ATS metatheory.
Suggested first pass.
None of these problems is a prerequisite for a later chapter. Begin with exercise 102.5, then complete exercise 102.8.
★★☆ Reconstruct preservation for an existential communication. Give the fresh functional variable, both substituted classifiers, and the channel-context split before and after reduction.
★★☆ For the negative input vector-length-mismatch, calculate the rejection verdict of the finite trace checker specified in the seminar tutorial. Then locate the single premise of ∃R that fails for that trace, and give the functional typing judgment that the premise demands and the one that actually holds. Finally, state what the run does not establish: name one hypothesis of theorem 102.8 that no finite trace check can verify.
★★★ Define a protocol whose sender transmits 𝑛:𝖭𝖺𝗍, a proof of 𝑛>0, and then an element of 𝖥𝗂𝗇(𝑛). Derive a valid trace and a trace rejected because the proof and index refer to different numerals. Explain why proof irrelevance is an additional system delta.
★★★Practical project.dependent-session-trace-checker Implement in Kappa a finite protocol checker for dependent send, dependent receive, termination, natural-number indices, vectors, and the index-driven unfolding of 𝗋𝖾𝗉𝖾𝖺𝗍 from section 102.5. Maintain the invariants that endpoint polarity is dual, that each endpoint advances once per communication, and that unfolding 𝗋𝖾𝗉𝖾𝖺𝗍(𝜏,𝑛) emits exactly 𝑛 messages. The named acceptance cases are 𝚟𝚎𝚌𝚝𝚘𝚛-𝟸↦𝚊𝚌𝚌𝚎𝚙𝚝𝚎𝚍:𝚎𝚗𝚍,𝚟𝚎𝚌𝚝𝚘𝚛-𝚕𝚎𝚗𝚐𝚝𝚑-𝚖𝚒𝚜𝚖𝚊𝚝𝚌𝚑↦𝚛𝚎𝚓𝚎𝚌𝚝𝚎𝚍:𝚎𝚡𝚙𝚎𝚌𝚝𝚎𝚍𝚅𝚎𝚌𝟸,𝚍𝚞𝚙𝚕𝚒𝚌𝚊𝚝𝚎-𝚎𝚗𝚍𝚙𝚘𝚒𝚗𝚝↦𝚛𝚎𝚓𝚎𝚌𝚝𝚎𝚍:𝚎𝚗𝚍𝚙𝚘𝚒𝚗𝚝𝚛𝚎𝚞𝚜𝚎𝚍,𝚊𝚛𝚛𝚊𝚢-𝟹↦𝚊𝚌𝚌𝚎𝚙𝚝𝚎𝚍:𝚎𝚗𝚍,𝚊𝚛𝚛𝚊𝚢-𝟹-𝚜𝚑𝚘𝚛𝚝↦𝚛𝚎𝚓𝚎𝚌𝚝𝚎𝚍:𝚎𝚡𝚙𝚎𝚌𝚝𝚎𝚍𝚅𝚎𝚌𝟷. A mutation that omits payload substitution must fail the mismatch oracle, and a mutation that unfolds 𝗋𝖾𝗉𝖾𝖺𝗍 one step too few must fail array-3. The checker is an executable fragment; it decides finite traces and proves neither preservation nor closed global progress.
Sources. The logical calculus, bank example, reduction rules, preservation, and global progress are reconstructed from Toninho, Caires, and Pfenning’s technical report; its Figure 1 on printed p. 18 collects the rules of definition 102.1, linear implication is its Section 2.2, type preservation is its Theorem 3.3 on printed p. 19, and contextual progress and global progress are its Lemma 3.4 and Theorem 3.5 on printed pp. 19–20 [TCP11]. The static protocol sort, index-dependent choice, the fixed-point constructor, and the array protocol of section 102.5 are Wu and Xi’s Figure 6 and Example 8, together with the surface examples reported by Wu and Xi [WX17]. The retrospective supplies historical context, not an additional theorem [TCP21].