Prerequisites. Direct starred prerequisites: Chapter 40, Chapter 185. No later core chapter depends on this route.
Example 185.6 generated a circuit whose size is selected by a classical number, and the type of the result was Circ(𝛼,𝛼) for every value of that number. That is correct and useless for the next step. Consider instead a circuit acting on 𝑛 wires — an adder on an 𝑛-qubit register, or a Fourier transform of width 𝑛. Its input interface has 𝑛 wires, so its type must mention 𝑛: qft : (𝑛:𝖭𝖺𝗍)→Circ(𝖰𝗎𝖻𝗂𝗍𝑛,𝖰𝗎𝖻𝗂𝗍𝑛). No type of definition 185.1 has this shape. The grammar of simple types is 𝑇,𝑈 ::=𝛼 ∣𝐼 ∣𝑇 ⊗𝑈, generated without reference to terms; a type 𝖰𝗎𝖻𝗂𝗍𝑛 with 𝑛 a program variable is not in it, and adding it is not a matter of notation. Writing the family as a function 𝖭𝖺𝗍 →Circ(𝑇,𝑈) for fixed 𝑇,𝑈 fixes the width before 𝑛 is known; writing it as a list of circuits abandons the interface entirely, since 𝗅𝗂𝗌𝗍 Circ(𝑇,𝑈) still has one 𝑇.
What is needed is a type former whose result depends on a term, together with a guarantee that evaluating a type never disturbs a quantum state. Both are supplied by making the dependency parametric: only terms with no effect on the quantum register may appear in types, and every term has a shape — its effect-free skeleton — which is what the type system actually substitutes. This chapter fixes that system, states its substitution and preservation theorems at their exact hypotheses, and builds the size-indexed family that chapter 185 could not type.
Signature delta
|
Proto-Quipper-M |
This chapter |
| Types |
no dependency on terms; simple types generated from wire constants |
dependent linear Π and Σ, with a separate parameter Π |
| Contexts |
parameter context Φ and label context 𝑄, kept apart |
one context with usage indices 0,1,𝜔; a parameter context is one in which every linear type has index 0 |
| Duplication |
!𝐴 with 𝐴 a type; labels never duplicable |
!𝐴, and additionally the index 𝜔 permitted only at parameter types |
| Types and terms |
disjoint |
terms may occur in types, but only parameter terms, and a value is substituted into a type through its shape Sh(𝑉) |
| Theorems used |
theorem 185.9 (safety, soundness, adequacy) |
none of them: the theorems of this chapter are proved for its own system (theorem 186.5, theorem 186.6) |
The last row is the important one. Proto-Quipper-M’s adequacy does not transfer: its statement quantifies over its own configurations and its own category of labelled circuits, and the system below changes both the judgment form and the class of types. Chapter 40 supplies the general linear-dependent judgment and the separation of parameters from state; this chapter uses that vocabulary and proves its own metatheory.
The system
Let 𝐶 range over base types of states, among them 𝖰𝗎𝖻𝗂𝗍. The grammars are Types𝐴,𝐵 ::= 𝐶∣𝖴𝗇𝗂𝗍∣ !𝐴∣(𝑥:𝐴)⊸𝐵[𝑥]∣ (𝑥:𝐴)⊗𝐵[𝑥]∣(𝑥:𝑃1)→𝑃2[𝑥],Parameter types𝑃 ::= 𝖴𝗇𝗂𝗍∣ !𝐴∣(𝑥:𝑃1)⊗𝑃2[𝑥]∣ (𝑥:𝑃1)→𝑃2[𝑥],Terms𝑀,𝑁 ::= 𝗎𝗇𝗂𝗍∣𝑥∣𝜆𝑥.𝑀∣𝑀𝑁∣ 𝖿𝗈𝗋𝖼𝖾 𝑀∣𝖿𝗈𝗋𝖼𝖾0𝑅∣𝗅𝗂𝖿𝗍 𝑀∣ (𝑀,𝑁)∣𝗅𝖾𝗍 (𝑥,𝑦)=𝑁 𝗂𝗇 𝑀∣𝜆0𝑥.𝑅∣𝑅1@𝑅2,Values𝑉 ::= 𝗎𝗇𝗂𝗍∣𝑥∣𝜆𝑥.𝑀∣𝜆0𝑥.𝑅∣𝗅𝗂𝖿𝗍 𝑀, where the parameter terms 𝑅 are the terms built without 𝜆𝑥.𝑀, 𝑀𝑁, 𝖿𝗈𝗋𝖼𝖾, and the state constants. Usage indices are 𝑘 ::=0 ∣1 ∣𝜔, and a context is a list 𝑥 :𝑘𝐴 in which 𝑘 =𝜔 occurs only at a parameter type. A parameter context Φ is a context in which every linear type has index 0. Addition and multiplication of indices are commutative with units 0 and 1, with 𝑘 +ℓ =𝜔 for 𝑘,ℓ ≠0, with 0 ⋅𝑘 =0 and 𝜔 ⋅𝜔 =𝜔, extended to contexts pointwise: Γ1 +Γ2 adds indices and 𝑘Γ multiplies them.
Referenced from 6 locations
Only parameter terms appear in types. The reason is operational and is worth stating before the rules: type checking evaluates the terms occurring in types, and if those terms could act on the quantum register, then type checking would change the state being described.
The shape operation maps types to parameter types and terms to parameter terms: Sh(𝐶)=𝖴𝗇𝗂𝗍,Sh(!𝐴)= !𝐴,Sh(𝑃)=𝑃,Sh((𝑥:𝐴)⊸𝐵[𝑥])=(𝑥:Sh(𝐴))→Sh(𝐵[𝑥]),Sh((𝑥:𝐴)⊗𝐵[𝑥])=(𝑥:Sh(𝐴))⊗Sh(𝐵[𝑥]), and on terms by Sh(𝑥) =𝑥, Sh(𝗎𝗇𝗂𝗍) =𝗎𝗇𝗂𝗍, Sh(𝜆𝑥.𝑁) =𝜆0𝑥.Sh(𝑁), Sh(𝑀𝑁) =Sh(𝑀)@ Sh(𝑁), Sh(𝖿𝗈𝗋𝖼𝖾 𝑀) =𝖿𝗈𝗋𝖼𝖾0 Sh(𝑀), Sh(𝗅𝗂𝖿𝗍 𝑀) =𝗅𝗂𝖿𝗍 𝑀, componentwise on pairs and 𝗅𝖾𝗍, and the identity on parameter terms. It is extended to contexts by applying it to every type.
Referenced from 7 locations
The clause Sh(𝐶) =𝖴𝗇𝗂𝗍 is the whole idea: a state type has exactly one shape, so a wire contributes nothing to the type-level data, while its presence and count do, through the structure of the type. The operation is idempotent, and it is a meta-operation like substitution, not a term former.
Judgments are Γ ⊢𝑀 :𝐴, with kinding Φ ⊢𝐴 : ∗ and well-formed contexts Γ ⊢. The rules that carry the dependency are Γ⊢Sh(Γ)⊢𝐴:∗𝑘=𝜔 only if 𝐴 is a parameter typeΓ,𝑥:𝑘𝐴⊢, Φ,𝑥:𝑘Sh(𝐴)⊢𝐵[𝑥]:∗Φ⊢(𝑥:𝐴)⊸𝐵[𝑥]:∗,Γ,𝑥:1𝐴⊢𝑀:𝐵[𝑥]Γ⊢𝜆𝑥.𝑀:(𝑥:𝐴)⊸𝐵[𝑥], Γ1⊢𝑀:(𝑥:𝐴)⊸𝐵[𝑥]Γ2⊢𝑉:𝐴Γ1+Γ2⊢𝑀𝑉:𝐵[Sh(𝑉)],Φ⊢𝑀:𝐴Φ⊢𝗅𝗂𝖿𝗍 𝑀: !𝐴, together with the rules for ⊗, for the parameter arrow → with its 𝜆0 and @, and for 𝖿𝗈𝗋𝖼𝖾 and 𝖿𝗈𝗋𝖼𝖾0. Every context appearing in a rule is required to be well formed, which is where the side condition on 𝜔 is enforced.
Referenced from 5 locations
The application rule shows the mechanism. The result type is 𝐵 with the shape of the argument substituted, not the argument: a value of a linear type may not appear in a type, but its shape may, and the shape carries exactly the information that survives erasing the state.
If Γ ⊢𝑀 :𝐴 then Sh(Γ) ⊢𝐴 : ∗ and Γ ⊢; moreover Sh(Γ) ⊢Sh(𝑀) :Sh(𝐴).
Referenced from 5 locations
Proof of Theorem 186.4 — Shape preserves typing
Proof. Induction on the derivation of Γ ⊢𝑀 :𝐴. At a variable, the context rule already contains the kinding premise, and Sh(𝑥) =𝑥 with the type replaced by its shape. At an abstraction, the induction hypothesis gives Sh(Γ),𝑥 :𝑘Sh(𝐴) ⊢Sh(𝑀) :Sh(𝐵), and the parameter abstraction rule concludes Sh(Γ) ⊢𝜆0𝑥.Sh(𝑀) :(𝑥 :Sh(𝐴)) →Sh(𝐵), which is Sh((𝑥 :𝐴) ⊸𝐵) by definition 186.2. At an application, the induction hypotheses give parameter terms of the corresponding parameter types and the rule for @ applies; the two shapes agree because Sh is idempotent, so Sh(𝐵[Sh(𝑉)]) =Sh(𝐵)[Sh(𝑉)]. The remaining constructors are formal copies of these three, with Sh pushed through the constructor by the corresponding clause of definition 186.2. ◻
If Φ,𝑥 :𝑃,Φ′ ⊢𝐵[𝑥] : ∗ and Φ ⊢𝑅 :𝑃, then Φ,Φ′[𝑅/𝑥] ⊢𝐵[𝑅] : ∗.
If Φ,𝑥 :𝑃,Γ ⊢𝑀 :𝐵[𝑥] and Φ ⊢𝑅 :𝑃, then Φ,Γ[𝑅/𝑥] ⊢𝑀[𝑅/𝑥] :𝐵[𝑅].
Let Γ1,𝑥 :𝑘𝐴,Γ′ ⊢𝑀 :𝐵[𝑥] and Γ2 ⊢𝑉 :𝐴. Then Γ1+𝑘Γ2, Γ′[Sh(𝑉)/𝑥] ⊢ 𝑀[𝑉/𝑥]:𝐵[Sh(𝑉)].
Referenced from 10 locations
Proof of Theorem 186.5 — Substitution
Proof. Clauses (i) and (ii) are proved by simultaneous induction on the kinding and typing derivations. The substituted term 𝑅 is a parameter term, so it may be duplicated and may enter a type; the only case that is not a direct application of the induction hypothesis is the context rule, where the premise Sh(Γ) ⊢𝐴 : ∗ becomes Sh(Γ[𝑅/𝑥]) ⊢𝐴[𝑅/𝑥] : ∗ by (i) applied at a smaller derivation, using that Sh commutes with substitution of a parameter term because Sh(𝑅) =𝑅.
Clause (iii) is the one whose statement is not the expected one, so its mechanism is written out. The term 𝑉 is a value, possibly of a linear type; it may therefore not be substituted into a type, and the statement substitutes Sh(𝑉) there instead. Consider the application case: 𝑀 =𝑀1𝑉1 with Γ′1,𝑥 :𝑘1𝐴 ⊢𝑀1 :(𝑦 :𝐴1) ⊸𝐵1[𝑦] and Γ″1,𝑥 :𝑘2𝐴 ⊢𝑉1 :𝐴1, where 𝑘 =𝑘1 +𝑘2 and Γ1 =Γ′1 +Γ″1. The induction hypothesis applies to each premise with its own index, giving Γ′1 +𝑘1Γ2 ⊢𝑀1[𝑉/𝑥] and Γ″1 +𝑘2Γ2 ⊢𝑉1[𝑉/𝑥], and the application rule concludes at the type 𝐵1[Sh(𝑉1[𝑉/𝑥])]. It remains to check that this is (𝐵1[Sh(𝑉1)])[𝑉/𝑥] with Sh(𝑉) substituted for 𝑥; that is the equation Sh(𝑉1[𝑉/𝑥]) =Sh(𝑉1)[Sh(𝑉)/𝑥], which holds by induction on 𝑉1 from definition 186.2, every clause of which commutes with substitution. Finally (𝑘1 +𝑘2)Γ2 =𝑘1Γ2 +𝑘2Γ2 by the arithmetic of indices, so the two contexts add to Γ1 +𝑘Γ2. The abstraction and pair cases are the same argument with one and with two premises respectively; the variable case is the axiom together with 𝑘 =1. ◻
If Γ ⊢𝑀 :𝐴 and 𝑀 ⇓𝑀′ in the big-step call-by-value semantics, then Γ ⊢𝑀′ :𝐴.
Referenced from 6 locations
Proof of Theorem 186.6 — Type preservation
Proof. Rule induction on 𝑀 ⇓𝑀′. The value rules are immediate. For application, 𝑀 =𝑀1𝑀2 with 𝑀1 ⇓𝜆𝑥.𝑁, 𝑀2 ⇓𝑉, and 𝑁[𝑉/𝑥] ⇓𝑀′; the induction hypothesis gives Γ1 ⊢𝜆𝑥.𝑁 :(𝑥 :𝐴1) ⊸𝐵[𝑥] and Γ2 ⊢𝑉 :𝐴1, inversion of the abstraction rule gives Γ1,𝑥 :1𝐴1 ⊢𝑁 :𝐵[𝑥], and theorem 186.5(iii) with 𝑘 =1 gives Γ1 +Γ2 ⊢𝑁[𝑉/𝑥] :𝐵[Sh(𝑉)], which is the type assigned to 𝑀 by the application rule. A second use of the induction hypothesis transports this to 𝑀′. The cases for pairs, 𝗅𝖾𝗍, 𝖿𝗈𝗋𝖼𝖾, and the parameter constructs are formal copies, each using the clause of theorem 186.5 matching the sort of the substituted term. ◻
Theorem 186.4, Theorem 186.5, Theorem 186.6 are Theorem 3.6, Theorem 3.7, and Proposition 3.10 of Fu, Kishida, and Selinger, Linear Dependent Type Theory for Quantum Programming Languages [FKS22]; the proofs above follow their inductions and are written out here for the cases in which the shape operation does visible work. That paper additionally constructs a denotational interpretation in a state-parameter fibration and proves its soundness, its Theorems 3.11 and 3.12; those are not reproduced here, and no statement of this chapter depends on them.
A size-indexed circuit family
Let 𝖭𝖺𝗍 be a parameter type with constructors 0 and 𝗌𝗎𝖼𝖼, and define the family of state types 𝖵𝖾𝖼 𝖰𝗎𝖻𝗂𝗍 0:=𝖴𝗇𝗂𝗍,𝖵𝖾𝖼 𝖰𝗎𝖻𝗂𝗍 (𝗌𝗎𝖼𝖼 𝑛):=𝖰𝗎𝖻𝗂𝗍⊗𝖵𝖾𝖼 𝖰𝗎𝖻𝗂𝗍 𝑛. Its shape is Sh(𝖵𝖾𝖼 𝖰𝗎𝖻𝗂𝗍 𝑛) =𝖴𝗇𝗂𝗍 for every 𝑛 by definition 186.2, while the type itself depends on 𝑛; the index is a parameter and the wires are states.
Referenced from 2 locations
Let CNOT have type !(𝖰𝗎𝖻𝗂𝗍 ⊗𝖰𝗎𝖻𝗂𝗍 ⊸𝖰𝗎𝖻𝗂𝗍 ⊗𝖰𝗎𝖻𝗂𝗍). Define by recursion on the parameter 𝑛 chain:(𝑛:𝖭𝖺𝗍)→ !(𝖰𝗎𝖻𝗂𝗍⊗𝖵𝖾𝖼 𝖰𝗎𝖻𝗂𝗍 𝑛⊸𝖰𝗎𝖻𝗂𝗍⊗𝖵𝖾𝖼 𝖰𝗎𝖻𝗂𝗍 𝑛) by chain 0:=𝗅𝗂𝖿𝗍(𝜆𝑝. 𝑝) and chain (𝗌𝗎𝖼𝖼 𝑚):=𝗅𝗂𝖿𝗍(𝜆𝑝. 𝗅𝖾𝗍 (𝑐,𝑣)=𝑝 𝗂𝗇𝗅𝖾𝗍 (𝑤,𝑣′)=𝑣 𝗂𝗇𝗅𝖾𝗍 (𝑐′,𝑤′)=(𝖿𝗈𝗋𝖼𝖾CNOT)(𝑐,𝑤) 𝗂𝗇 …), where the omitted part applies 𝖿𝗈𝗋𝖼𝖾(chain 𝑚) to (𝑐′,𝑣′) and reassembles the result with 𝑤′. The recursion is on 𝑛, which is a parameter and may therefore be inspected and used twice; the wires 𝑐,𝑤,𝑣′ each occur exactly once, as the linear rules require.
Boxing gives chainbox :(𝑛 :𝖭𝖺𝗍) →Circ(𝖰𝗎𝖻𝗂𝗍 ⊗𝖵𝖾𝖼 𝖰𝗎𝖻𝗂𝗍 𝑛, 𝖰𝗎𝖻𝗂𝗍 ⊗𝖵𝖾𝖼 𝖰𝗎𝖻𝗂𝗍 𝑛). For 𝑛 =3 the generated circuit has three CNOT gates and the interface (ℓ0:𝖰𝗎𝖻𝗂𝗍, ℓ1,ℓ2,ℓ3:𝖰𝗎𝖻𝗂𝗍) ⟶ (ℓ′0, ℓ′1,ℓ′2,ℓ′3), four wires in and four out, which is what the type says once 𝑛 is instantiated. Compare example 185.6: there the type was Circ(𝛼,𝛼) for every 𝑛, and the generated circuit’s interface was not visible in it.
Referenced from 4 locations
A circuit that computes a value while producing garbage has type 𝑎 ⊸𝖶𝗂𝗍𝗁𝖦𝖺𝗋𝖻𝖺𝗀𝖾 𝑏, where the monad 𝖶𝗂𝗍𝗁𝖦𝖺𝗋𝖻𝖺𝗀𝖾 records a vector of garbage wires together with its length; the operation 𝖽𝗂𝗌𝗉𝗈𝗌𝖾 adds one wire to that vector. Because the length is an index and not a constant, the number of garbage wires produced by a computation need not be known when the combinator below is typed.
The combinator takes a garbage-producing 𝑓 :!(𝑎 ⊸𝖶𝗂𝗍𝗁𝖦𝖺𝗋𝖻𝖺𝗀𝖾 𝑏) and a consumer 𝑔 :!(𝑐 ⊗𝑏 ⊸𝑑 ⊗𝑏) and returns a garbage-free 𝑐 ⊗𝑎 ⊸𝑑 ⊗𝑎. It is built from an existential boxing operation whose type is 𝖾𝗑𝗂𝗌𝗍𝗌𝖡𝗈𝗑:(𝑝:𝑏→𝖳𝗒𝗉𝖾)→!(𝑎⊸(𝑛:𝑏)⊗𝑝𝑛)→(𝑛:𝑏)⊗Circ(𝑎, 𝑝𝑛), which boxes a circuit-generating function whose output interface is not known in advance, returning the width 𝑛 together with a circuit at that width. The combinator then unboxes the circuit, runs it, applies 𝑔 to the useful output, and applies the reverse of the same circuit to the garbage, which restores the input wires. Every step is typed: the two uses of the boxed circuit are at the same 𝑛 because 𝑛 is bound once by the Σ-type, and the reverse has the interface exchanged.
The boundary is exactly stated by the authors of the system: the type guarantees that no garbage wire is left uncollected, and it does not guarantee that the uncomputed wires are returned in the state |0⟩. Semantic correctness of the generated circuit is not decided by the type system; a failure of it is a programming error and not a type error. This distinction is the same one drawn in remark 185.11, now applied to a construction whose types have become expressive enough to make the confusion tempting.
Referenced from 5 locations
★☆☆ Compute Sh(𝐴) for 𝐴 =𝖰𝗎𝖻𝗂𝗍 ⊗𝖵𝖾𝖼 𝖰𝗎𝖻𝗂𝗍 𝑛, for 𝐴 =!(𝖰𝗎𝖻𝗂𝗍 ⊸𝖰𝗎𝖻𝗂𝗍), and for 𝐴 =(𝑥 :𝖭𝖺𝗍) →Circ(𝖰𝗎𝖻𝗂𝗍,𝖰𝗎𝖻𝗂𝗍), and say in each case which information about 𝐴 survives.
Referenced from 2 locations
★★☆ Let Γ2 ⊢𝑉 :𝖰𝗎𝖻𝗂𝗍. Using the index arithmetic of definition 186.1, compute Γ1 +𝑘Γ2 for 𝑘 =0,1,𝜔 and say which of the three is excluded by well-formedness, and why.
Referenced from 2 locations
★★☆ Explain why (𝑥 :𝖰𝗎𝖻𝗂𝗍) →𝑃[𝑥] is not a type of definition 186.1, and why (𝑥 :𝖰𝗎𝖻𝗂𝗍) ⊸𝐵[𝑥] is. Then show that the second is only useful when 𝐵 depends on 𝑥 through Sh(𝑥), and compute what that dependency can be.
Referenced from 3 locations
Comparisons and boundary
A mechanized circuit language. QWIRE embeds a circuit language in Coq, where circuits are typed by an inductive family and their well-typedness is a Coq proposition; a development in it is checked by the host proof assistant. The comparison is instructive precisely at the trust boundary: in QWIRE the guarantee is “Coq accepted this proof about this embedded circuit”, with the embedding itself part of what must be trusted, whereas in the system above the guarantee is “this term has this type in the calculus of definition 186.3”, with the type checker part of what must be trusted. Neither statement implies the other, and neither implies semantic correctness of the circuit, by example 186.9.
Reversing and control. A modern Proto-Quipper variant adds a modality for reversible computations, a control operation, and a 𝗐𝗂𝗍𝗁-𝖼𝗈𝗆𝗉𝗎𝗍𝖾𝖽 construct as a primitive rather than a derived combinator. As a rule delta against definition 186.3: types gain a modal former marking reversibility, the boxing rule gains a premise that the boxed function is reversible, and the reverse operation becomes a term former rather than a library function. Its own authors leave the combination of that modal system with the dependent types of this chapter open, so no theorem and no implementation is transferred here; what is transferred is the observation that 𝗐𝗂𝗍𝗁-𝖼𝗈𝗆𝗉𝗎𝗍𝖾𝖽 can be primitive.
Dependent indices verify the stated interfaces. They do not verify amplitudes, they do not verify that a gate is implemented correctly by hardware, and they do not establish an algorithmic speedup. Example 186.8 guarantees that a circuit of width 𝑛 +1 is produced for input 𝑛; whether that circuit computes anything useful is a separate question with a separate proof.
Suggested first pass.
None of these problems is a prerequisite for a later chapter. Begin with exercise 186.4, then exercise 186.5; the implementation project exercise 186.7 may be attempted at any time.
★★☆ Construct two size-indexed circuit families: one applying 𝐻 to every wire of 𝖵𝖾𝖼 𝖰𝗎𝖻𝗂𝗍 𝑛, and one applying CNOT to every adjacent pair. Give the type of each, compute the generated interface for 𝑛 =3, and count the gates as a function of 𝑛.
Referenced from 3 locations
★★☆ Write out the pair case of theorem 186.5(iii) in full, including the index arithmetic and the shape equation Sh(𝑉1[𝑉/𝑥])=Sh(𝑉1)[Sh(𝑉)/𝑥]. Then exhibit a term for which substituting 𝑉 rather than Sh(𝑉) into the type produces a type that is not well kinded.
Referenced from 3 locations
★★☆ Repair the following unsafe uncomputation attempt: a program applies 𝑓 to produce a result and garbage, applies 𝑔, and then discards the garbage wires with 𝖽𝗂𝗌𝗉𝗈𝗌𝖾 instead of running the reverse circuit. State which type in example 186.9 rejects the attempt, and what physical difference the rejection corresponds to.
Referenced from 2 locations
Bibliographic notes
The syntax, shape operation, typing discipline with indices, substitution theorem, and type preservation of section 186.2, section 186.3 are those of Fu, Kishida, and Selinger, Linear Dependent Type Theory for Quantum Programming Languages [FKS22]: definition 186.1 is its Definition 3.1, definition 186.2 its Definition 3.2, theorem 186.4 its Theorem 3.6, theorem 186.5 its Theorem 3.7, and theorem 186.6 its Proposition 3.10. Its denotational interpretation in a state-parameter fibration and the corresponding soundness theorem are its Theorems 3.11 and 3.12 and are not used here. The general linear dependent judgment and the separation of parameters from state are developed in chapter 40.
The size-indexed families and the uncomputation combinator of section 186.4 follow the tutorial of Fu, Kishida, Ross, and Selinger [FKRS20], which contains the 𝖶𝗂𝗍𝗁𝖦𝖺𝗋𝖻𝖺𝗀𝖾 monad, the 𝖾𝗑𝗂𝗌𝗍𝗌𝖡𝗈𝗑 operation, and the 𝗐𝗂𝗍𝗁-𝖼𝗈𝗆𝗉𝗎𝗍𝖾𝖽 combinator, together with the explicit statement that the system guarantees syntactic and not semantic correctness of the generated circuit; a pinned experimental implementation accompanies it. QWIRE is retained as an independent mechanized comparison, and the modal Proto-Quipper with reversing and control [FKRS26] as the bounded rule-and-example delta of section 186.5.