Prerequisites. Direct starred prerequisites: none. No later core chapter depends on this route.
A dependent type may inspect its argument more than once. A linear term, however, must use a linear argument exactly once. Combining these two clauses naively makes the type checker consume a run-time resource: if 𝑞:𝖰𝗎𝖻𝗂𝗍 and a type contains 𝐵(𝑞,𝑞), then ordinary dependent substitution duplicates 𝑞. Declaring the two occurrences “static” does not repair the rule, because evaluating a general term in order to form a type may itself change the state.
The repair separates a resource-bearing value from the parameter that records its reusable shape. Types depend only on parameters; terms may still use state exactly once. The distinction is enforced by the judgments, not by an informal promise that the type checker will avoid dangerous evaluations.
The selected calculus has types 𝐴,𝐵::=𝐶∣𝟏∣!𝐴∣(𝑥:𝐴)⊸𝐵[𝑥]∣(𝑥:𝐴)⊗𝐵[𝑥]∣(𝑥:𝑃1)→𝑃2[𝑥], where 𝐶 ranges over state types. Parameter types are generated by 𝑃::=𝟏∣!𝐴∣(𝑥:𝑃1)⊗𝑃2[𝑥]∣(𝑥:𝑃1)→𝑃2[𝑥]. Terms include variables, unit, linear abstraction and application, pairs and pair elimination, 𝗅𝗂𝖿𝗍𝑀, and 𝖿𝗈𝗋𝖼𝖾𝑀. Parameter abstraction 𝜆′𝑥.𝑅, parameter application 𝑅1@𝑅2, and 𝖿𝗈𝗋𝖼𝖾′𝑅 form the parameter sublanguage.
A usage index is 𝑘∈{0,1,𝜔}. A context entry is 𝑥:𝑘𝐴; index 𝜔 is permitted only when 𝐴 is a parameter type. A parameter contextΦ is a context in which every variable whose type is not a parameter type has index 0. Thus Φ may contain a parameter at index 0, 1, or 𝜔, but it cannot provide a state-bearing closure to a term.
The indices form the three-element usage algebra used in the source calculus. Zero is the additive identity, one is the multiplicative identity, 𝑘+ℓ=𝜔 when 𝑘,ℓ≠0, and 0𝑘=0, 𝜔𝜔=𝜔. Addition and scalar multiplication act pointwise on contexts with the same declaration spine. Consequently Γ1+Γ2 is defined only when corresponding variables have the same types and its result is a well-formed context.
The shape operationSh erases state while retaining parameter information. Its decisive clauses are Sh(𝐶)=𝟏,Sh(!𝐴)=!𝐴,Sh((𝑥:𝐴)⊸𝐵[𝑥])=(𝑥:Sh(𝐴))→Sh(𝐵[𝑥]),Sh((𝑥:𝐴)⊗𝐵[𝑥])=(𝑥:Sh(𝐴))⊗Sh(𝐵[𝑥]),Sh(𝑃)=𝑃,Sh(𝑥)=𝑥,Sh(𝜆𝑥.𝑀)=𝜆′𝑥.Sh(𝑀),Sh(𝑀𝑁)=Sh(𝑀)@Sh(𝑁),Sh(𝗅𝗂𝖿𝗍𝑀)=𝗅𝗂𝖿𝗍𝑀,Sh(𝖿𝗈𝗋𝖼𝖾𝑀)=𝖿𝗈𝗋𝖼𝖾′Sh(𝑀). It acts componentwise on pairs, pair eliminations, and contexts. Shape is a meta-operation, like capture-avoiding substitution; it is not a run-time term constructor. It is idempotent on well-formed parameter syntax.
For example, a qubit has shape 𝟏. A pair consisting of a natural parameter 𝑛 and an 𝑛-wire register retains 𝑛 but forgets the register state. Hence the shape may index a result type without giving the type checker permission to measure, copy, or discard the register.
The tempting replacement Sh(𝑀)=𝑀 fails for state terms. If 𝑀 allocates or measures a qubit, putting 𝑀 into a type makes type formation stateful. The clause Sh(𝐶)=𝟏 is therefore load-bearing: it records that the state object exists while discarding the state itself.
The premise of LD-⊸-F exposes the separation. The term-level argument has type 𝐴, but the codomain receives only an argument of type Sh(𝐴). No linear resource occurs in the kinding context.
★☆☆ Prove by structural induction on the syntax in definition 98.2 that Sh(Sh(𝐴))=Sh(𝐴) and likewise for parameter terms. State why the claim is not an equation asserting that a state term equals its shape.
In LD-App, 𝑁 occurs once in the program and Sh(𝑁) may occur repeatedly in the classifier. The two uses are not two resource uses. The same distinction appears in LD-Pair: 𝑀 contributes one state-bearing component, while its shape selects the second component’s type.
Take a base state type 𝖢𝖾𝗅𝗅, a parameter type 𝖭𝖺𝗍, and a family 𝖱𝖾𝖺𝖽𝗒:𝖭𝖺𝗍→∗. Suppose Γ𝑓⊢𝑓:(𝑧:𝖢𝖾𝗅𝗅)⊸𝖱𝖾𝖺𝖽𝗒(𝑠@𝑧)andΓ𝑐⊢𝑐:𝖢𝖾𝗅𝗅, where the codomain variable has type Sh(𝖢𝖾𝗅𝗅)=𝟏 and 𝑠:𝟏→𝖭𝖺𝗍 is a parameter-level summary. Then LD-App derives Γ𝑓+Γ𝑐⊢𝑓𝑐:𝖱𝖾𝖺𝖽𝗒(𝑠@Sh(𝑐)). The cell is consumed in 𝑓𝑐; the reusable index is its unit-shaped summary. Since Sh(𝑥)=𝑥 on variable syntax, the printed expressions 𝑠@Sh(𝑐) and 𝑠@𝑐 coincide after applying the meta-operation. Their typing role is nevertheless fixed: the occurrence of 𝑐 in the classifier has type Sh(𝖢𝖾𝗅𝗅)=𝟏, not 𝖢𝖾𝗅𝗅.
Proof. Induct on the typing derivation. In the variable case, applying shape to its declaration replaces the declared type by its parameter shape. For LD-App, the induction hypotheses give Sh(𝑀):(𝑥:Sh(𝐴))→Sh(𝐵[𝑥])andSh(𝑁):Sh(𝐴). Parameter application therefore has the type on the left in Sh(𝐵)[Sh(𝑁)/𝑥]=Sh(𝐵[Sh(𝑁)/𝑥]), where the equality follows by structural induction on 𝐵. The pair case uses the same commutation equation for the second component. Linear abstraction becomes parameter abstraction. Lift is fixed by shape, force becomes 𝖿𝗈𝗋𝖼𝖾′, and pair elimination commutes componentwise with shape. These cases cover every constructor in definition 98.1. ◻
★★☆ Assume 𝑢:1𝐴,𝑣:0𝐷⊢𝑀:𝐴, and 𝑢:0𝐴,𝑣:1𝐷⊢𝑁:𝐵[Sh(𝑀)] uses only 𝑣. Write the two premise contexts and their pointwise sum in an application of LD-Pair. Explain why replacing the index 0 on the second occurrence of 𝑢 by 1 makes the sum ill formed when 𝐴 is a state type.
Ordinary substitution conflates three operations. A parameter may be put in a type, a parameter may be put in a term, and a state-bearing value may be put in a term while only its shape is put in dependent types. The theorem must state all three because the third induction invokes the first two.
Proof. Prove the three clauses simultaneously by induction on the kinding and typing derivations. Parameter variables give clauses (1) and (2) by the usual variable split. Formation of either dependent linear former uses clause (1) under its parameter binder.
For clause (3), the variable case exposes the quantitative invariant. If the last rule selects 𝑥, then 𝑘=1 and the conclusion is precisely the given derivation Γ2⊢𝑉:𝐴, weakened by the zero-use declarations on either side. If it selects another variable, the declaration for 𝑥 has index zero in that branch; the induction conclusion adds 0Γ2, so no resource in 𝑉 is consumed.
In the application case, split the premise occurrence of 𝑥:𝑘𝐴 as 𝑥:𝑘1𝐴+𝑥:𝑘2𝐴, where 𝑘=𝑘1+𝑘2. The two induction hypotheses produce contexts Δ1+𝑘1Γ2 and Δ2+𝑘2Γ2. Rebuilding LD-App is licensed by (Δ1+𝑘1Γ2)+(Δ2+𝑘2Γ2)=Δ1+Δ2+(𝑘1+𝑘2)Γ2. Its result type is correct because shape commutes with value substitution: Sh(𝑁[𝑉/𝑥])=Sh(𝑁)[Sh(𝑉)/𝑥]. The pair case has the same context equation, and the displayed shape equation aligns the second component’s type.
For linear abstraction, alpha-rename its binder away from 𝑉, apply the induction hypothesis under the binder, and rebuild LD-Lam. If the binder has index zero or 𝜔, its parameter-type side condition is unchanged by substitution. Pair elimination splits 𝑘 among the scrutinee and body and uses associativity and distributivity of context addition exactly as the application case. Lift has a parameter context, so a state-bearing substituted value can occur there only with scalar zero; force preserves the induction context. Parameter abstraction, parameter application, and 𝖿𝗈𝗋𝖼𝖾′ use clauses (1) and (2). Thus every formation and typing rule is rebuilt with the stated context. ◻
The value premise in clause (3) cannot be dropped for this call-by-value calculus. Substituting an arbitrary effectful computation duplicates or reorders its state transition when the variable occurs in a value body. The shape in the dependent suffix is equally necessary: replacing it by 𝑉 would insert a state term into a kinding judgment.
★★☆ Write the complete LD-Pair case of theorem 98.6(3). Name the two usage indices assigned to the substituted variable, derive the two component judgments, and show both the context-sum equation and the equation aligning the second component’s type.
The evaluation judgment 𝑀⇓𝑉 is defined on open terms. Its application and pair-elimination rules are
𝑀⇓𝜆𝑥.𝑀′𝑁⇓𝑉𝑀′[𝑉/𝑥]⇓𝑉′
𝑀𝑁⇓𝑉′
LD-Eval-App
𝐿⇓(𝑉1,𝑉2)𝑀[𝑉1/𝑥][𝑉2/𝑦]⇓𝑉
𝗅𝖾𝗍(𝑥,𝑦)=𝐿𝗂𝗇𝑀⇓𝑉
LD-Eval-Let
Force evaluates a lifted body, and parameter application uses the corresponding parameter abstraction. Variables count as values so that type-level evaluation is defined on open parameter terms. Write 𝑅≡ev𝑅′ when both parameter terms evaluate to a common parameter value. Type conversion is driven by this symmetric computational equality:
Proof of Lemma 98.8 — Evaluation commutes with shape
Proof. Induct on the evaluation derivation. Application becomes parameter application, and the three induction hypotheses rebuild its evaluation rule. Pair elimination commutes with shape and with both substitutions. Force becomes 𝖿𝗈𝗋𝖼𝖾′, whose evaluation rule returns the shaped lifted body. Values are fixed by their corresponding parameter-value rules. These are all rules in definition 98.7. ◻
Let LD1 be the fragment in which every abstraction evaluated by LD-Eval-App is derived by LD-Lam with binder index 1. If Γ⊢𝑀:𝐴 is an LD1 derivation and 𝑀⇓𝑉, then Γ⊢𝑉:𝐴.
Proof of Proposition 98.9 — Preservation for evaluation
Proof. Induct on the evaluation derivation. In the application case, inversion of LD-App gives Γ1⊢𝑀:(𝑥:𝐵)⊸𝐴[𝑥],Γ2⊢𝑁:𝐵,Γ=Γ1+Γ2. The first two induction hypotheses type 𝜆𝑥.𝑀′ and 𝑉 at those same types. Inversion of LD-Lam and the fragment boundary give Γ1,𝑥:1𝐵⊢𝑀′:𝐴[𝑥]. Apply theorem 98.6(3) to obtain Γ⊢𝑀′[𝑉/𝑥]:𝐴[Sh(𝑉)/𝑥]. By lemma 98.8, Sh(𝑁)⇓Sh(𝑉); rule LD-ConvEval aligns this with 𝐴[Sh(𝑁)/𝑥], since the shaped value evaluates to itself. The final induction hypothesis types the result. Pair elimination uses the two successive instances of the same substitution clause. The force and parameter-application cases use their corresponding substitution clauses. Values close the induction. ◻
The restriction is load-bearing. The unrestricted source syntax permits LD-Lam with 𝑘=0 or 𝑘=𝜔 when the domain is a parameter type, whereas LD-App always contributes one copy of the argument context. The published application proof explicitly supposes 𝑘=1[FKS22]. Consequently the present chapter does not claim operational preservation for the other two cases without an additional parameter-weakening or parameter-substitution rule that aligns the required contexts.
A state–parameter model is the fibration specified by Fu–Kishida–Selinger’s Definition 2.8 [FKS22]. Its signature is the following data and laws.
The functor ♯:E→B is a pullback fibration. The base B is locally cartesian closed, the total category E is symmetric monoidal closed, and ♯ preserves the terminal object. In the equivalent adjunction presentation, ♯ has a full faithful right adjoint 𝑞, identity counit, unit 𝜂:idE⇒𝑞♯, and the specified pullbacks along arrows 𝑞𝑓.
The functor ♯ preserves the monoidal closed structure, and the tensor of cartesian arrows is cartesian.
For 𝐴,𝐵∈E/𝑞𝑋, the fibered objects 𝐴⊗𝑞𝑋𝐵 and 𝐴⊸𝑞𝑋𝐵 are the cartesian liftings of product and exponential in B/𝑋, and −⊗𝑞𝑋𝐴⊣𝐴⊸𝑞𝑋−.
The parameterized-unit functor 𝑝:B→E, obtained by cartesian lifting from the monoidal unit, has a right adjoint ♭. Thus !=𝑝♭ has counit 𝖿𝗈𝗋𝖼𝖾:!⇒idE.
These clauses are the source conditions (1)–(9), not a placeholder for unspecified “appropriate” structure. For 𝑋∈B, 𝐴∈E/𝑞𝑋, and 𝐵∈E/♯𝐴, the source’s Theorem 2.14 constructs the dependent adjunction −⊗𝑞𝑋𝐴⊣Π𝑞𝑋,𝐴 and its counit 𝜖:(Π𝑞𝑋,𝐴𝐵)⊗𝑞𝑋𝐴→𝐵; this is a consequence of the signature, not an unnamed extra axiom.
Proof of Theorem 98.11 — Imported interpretation package
Proof. This is the exact import of clauses (1)–(7) of source Theorem 3.11. The hypotheses of definition 98.10 match Definition 2.8 clause for clause; the source’s simultaneous induction supplies the five groups above and the displayed context equation. No normalization, canonicity, or completeness conclusion is imported. ◻
Under theorem 98.11, suppose Γ1,𝑥:1𝐴⊢𝑀:𝐵[𝑥] and Γ2⊢𝑉:𝐴. Then [[𝑀[𝑉/𝑥]]] is the unique arrow into the pullback for 𝐵[Sh(𝑉)/𝑥]. Its upper path is [[𝑀]]∘(id[[Γ1]]⊗[[𝑉]]).
Proof of Lemma 98.12 — Imported semantic value substitution
Proof. The imported result is the source’s value-substitution proposition [FKS22]. Its source diagram defines the arrow by the pullback universal property and defines the displayed arrow with precisely the domain printed above. This is the 𝑘=1, empty-suffix specialization; no undefined 𝜔-fold tensoring operation is used. ◻
Proof. Induct on the evaluation derivation. The application case contains the decisive step; its premises are 𝐹⇓𝜆𝑥.𝑀0, 𝑁⇓𝑉, and 𝑀0[𝑉/𝑥]⇓𝑊. Typing inversion and proposition 98.9 give Γ1,𝑥:1𝐵⊢𝑀0:𝐴[𝑥],Γ2⊢𝑉:𝐵,Γ=Γ1+Γ2. The three evaluation induction hypotheses give [[𝐹]]=[[𝜆𝑥.𝑀0]],[[𝑁]]=[[𝑉]],[[𝑀0[𝑉/𝑥]]]=[[𝑊]]. Application is interpreted by the counit 𝜖. Semantic substitution and the counit equation therefore yield the annotated chain [[𝐹𝑁]]𝐼𝐻=[[(𝜆𝑥.𝑀0)𝑉]]𝑐𝑜𝑢𝑛𝑖𝑡=[[𝑀0[𝑉/𝑥]]]𝐼𝐻=[[𝑊]]. The middle equality is exactly lemma 98.12; its source object is [[Γ1]]⊗[[Γ2]], so no implicit contraction duplicates 𝑉.
For pair elimination, interpret pair formation by dependent tensor and use semantic substitution twice; the tensor beta equation gives the required composite. Force uses the counit of the linear exponential, parameter application uses ordinary dependent-function beta in B, and the remaining evaluation rules use functoriality followed by their induction hypotheses. Thus every LD1 evaluation derivation preserves its denotation. ◻
Dropping the state–parameter structure leaves the conclusion without a meaning: the application proof uses both the context-tensor equation and the dependent counit. Dropping the evaluation premise also fails; two terms of the same type need not denote the same morphism. Conversely, the theorem does not prove that evaluation terminates or that every closed value is canonical. The source states an unrestricted soundness result as Theorem 3.12, but its displayed application argument explicitly assumes 𝑘=1. The theorem above records the fragment established by that argument rather than silently generalizing it.
★★☆ Redraw the application case of theorem 98.13 as a commuting square. Label its four objects, the tensor-environment map, the counit, and the map induced by 𝑉. Then write the equality of the two paths; the diagram alone is not the answer.
Let 𝖵𝖾𝖼𝖢𝖾𝗅𝗅(𝑛) be the state type of a register containing exactly 𝑛 cells and let 𝖥𝗂𝗇(𝑛) be the parameter type of valid positions. Consider 𝗋𝖾𝖺𝖽:(𝑛:𝖭𝖺𝗍)→(𝑟:𝖵𝖾𝖼𝖢𝖾𝗅𝗅(𝑛))⊸(𝑖:𝖥𝗂𝗇(𝑛))→𝖡𝗂𝗍⊗𝖵𝖾𝖼𝖢𝖾𝗅𝗅(𝑛). The parameter 𝑛 may be reused to check 𝑖, while the register 𝑟 occurs once. For 𝑛=2, 𝑖=1, and 𝑟:𝖵𝖾𝖼𝖢𝖾𝗅𝗅(2), the typing calculation is 𝗋𝖾𝖺𝖽2:(𝑟:𝖵𝖾𝖼𝖢𝖾𝗅𝗅(2))⊸(𝑖:𝖥𝗂𝗇(2))→𝖡𝗂𝗍⊗𝖵𝖾𝖼𝖢𝖾𝗅𝗅(2),𝗋𝖾𝖺𝖽2𝑟:(𝑖:𝖥𝗂𝗇(2))→𝖡𝗂𝗍⊗𝖵𝖾𝖼𝖢𝖾𝗅𝗅(2),𝗋𝖾𝖺𝖽2𝑟@1:𝖡𝗂𝗍⊗𝖵𝖾𝖼𝖢𝖾𝗅𝗅(2). The first application consumes 𝑟; parameter application reuses 2. An attempted second call with the same 𝑟 has context usage 1+1=𝜔, which is forbidden for the state type 𝖵𝖾𝖼𝖢𝖾𝗅𝗅(2). The returned register, rather than the consumed name, must be threaded into the next call.
This protocol resembles an ownership API and its parameter index resembles a session-state index. Those resemblances do not identify the calculi: the present soundness proof depends on a state–parameter fibration and does not establish progress for a session operational semantics or borrowing laws for an ownership language.
The pinned Proto-Quipper-D tutorial exercises the same boundary in three stages [FKRS20]. Its first circuit boxes a reusable generator at type 𝖢𝗂𝗋𝖼(𝟏,𝖰𝗎𝖻𝗂𝗍⊗𝖰𝗎𝖻𝗂𝗍), separating the parameter-level circuit description from the state-bearing qubit wires. Its dependent Fourier-transform family then has the inspectable interface 𝗊𝖿𝗍𝖡𝗈𝗑:(𝑛:𝖭𝖺𝗍)→𝖢𝗂𝗋𝖼(𝖵𝖾𝖼𝖰𝗎𝖻𝗂𝗍𝑛,𝖵𝖾𝖼𝖰𝗎𝖻𝗂𝗍𝑛). The retained results bell00Box.pdf, teleBox.pdf, and qft5.pdf display the generated circuits; the vector length remains a parameter while each circuit consumes and returns its wire bundle.
The dynamic-lifting test measures a freshly initialized qubit, lifts the resulting bit into a host Boolean, and branches in a recursive binary-number calculation. A neighboring negative test attempts to use that dynamically lifted number as the length of a returned vector and is rejected: a run-time measurement cannot retroactively determine the static family in the result type. This implementation trace illustrates the state/parameter boundary; it is not a premise of theorem 98.13.
★★☆ Type two successive reads by eliminating the tensor returned by the first call and passing its register component to the second. Give the usage of the original register and of the bound returned register. Show the exact context sum that rejects two reads of the original register.
★★☆ Reconstruct all three clauses of theorem 98.6 for the term (𝑀,𝑁). Identify the clause used for the second component’s type and the clause used for each component term. Test the boundary obtained by replacing Sh(𝑉) with 𝑉.
★★★ For the application fragment, instantiate a state–parameter model whose parameter category is finite sets and whose state morphisms carry a finite state transition. Define the dependent counit and verify the semantic substitution square on a two-state example. State which additional structure would be required for pairs and !𝐴.
★★★Practical project.ldtt-shape-usage-checker Implement in Agda or Kappa the finite syntax consisting of state and parameter variables, linear application, dependent pairs, and shape. Maintain the invariant that a state variable has total usage at most one and that every classifier contains only parameter syntax. On the named threaded-read, duplicate-read, and raw-state-index inputs, require these exact stdout fragments:
threaded-read term accepted
duplicate-read term rejected for state usage
raw state index rejected during kinding
Also print the shape-substituted result type of threaded-read. The checker is a finite executable instance of the substitution invariant; it does not prove theorem 98.13.
Sources. The syntax, shape operation, three-clause substitution theorem, and semantic soundness theorem are reconstructed from Fu, Kishida, and Selinger’s linear dependent type theory for quantum programming: Theorem 3.7 appears on p. 16 and Theorem 3.12 on p. 19 of the pinned version [FKS22]. Their Proto-Quipper-D tutorial supplies the circuit-programming route, but surface acceptance is not used as evidence for the semantic theorem. Benton’s linear/nonlinear separation is background for the parameter/state split [Ben94].