Lectures onType Theory
Chapter 186
Chapter 186Optional

Linear-Dependent Quantum Programming and Proto-Quipper-D

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 n wires — an adder on an n-qubit register, or a Fourier transform of width n. Its input interface has n wires, so its type must mention n: qft : (n:Nat)Circ(Qubitn,Qubitn). No type of definition 185.1 has this shape. The grammar of simple types is T,U::=αITU, generated without reference to terms; a type Qubitn with n a program variable is not in it, and adding it is not a matter of notation. Writing the family as a function NatCirc(T,U) for fixed T,U fixes the width before n is known; writing it as a list of circuits abandons the interface entirely, since listCirc(T,U) still has one T.

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 Q, kept apart one context with usage indices 0,1,ω; a parameter context is one in which every linear type has index 0
Duplication !A with A a type; labels never duplicable !A, 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(V)
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

Definition 186.1 — Syntax

Let C range over base types of states, among them Qubit. The grammars are TypesA,B ::= CUnit !A(x:A)B[x] (x:A)B[x](x:P1)P2[x],Parameter typesP ::= Unit !A(x:P1)P2[x] (x:P1)P2[x],TermsM,N ::= unitxλx.MMN force Mforce0Rlift M (M,N)let (x,y)=N in Mλ0x.RR1@R2,ValuesV ::= unitxλx.Mλ0x.Rlift M, where the parameter terms R are the terms built without λx.M, MN, force, and the state constants. Usage indices are k::=01ω, and a context is a list x:kA in which k=ω 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 k+=ω for k,0, with 0k=0 and ωω=ω, extended to contexts pointwise: Γ1+Γ2 adds indices and kΓ multiplies them.

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.

Definition 186.2 — Shape

The shape operation maps types to parameter types and terms to parameter terms: Sh(C)=Unit,Sh(!A)= !A,Sh(P)=P,Sh((x:A)B[x])=(x:Sh(A))Sh(B[x]),Sh((x:A)B[x])=(x:Sh(A))Sh(B[x]), and on terms by Sh(x)=x, Sh(unit)=unit, Sh(λx.N)=λ0x.Sh(N), Sh(MN)=Sh(M)@Sh(N), Sh(force M)=force0Sh(M), Sh(lift M)=lift M, componentwise on pairs and let, and the identity on parameter terms. It is extended to contexts by applying it to every type.

The clause Sh(C)=Unit 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.

Definition 186.3 — Selected typing rules

Judgments are ΓM:A, with kinding ΦA: and well-formed contexts Γ. The rules that carry the dependency are ΓSh(Γ)A:k=ω only if A is a parameter typeΓ,x:kA, Φ,x:kSh(A)B[x]:Φ(x:A)B[x]:,Γ,x:1AM:B[x]Γλx.M:(x:A)B[x], Γ1M:(x:A)B[x]Γ2V:AΓ1+Γ2MV:B[Sh(V)],ΦM:AΦlift M: !A, together with the rules for , for the parameter arrow with its λ0 and @, and for force and force0. Every context appearing in a rule is required to be well formed, which is where the side condition on ω is enforced.

The application rule shows the mechanism. The result type is B 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.

Substitution and preservation

Theorem 186.4 — Shape preserves typing

If ΓM:A then Sh(Γ)A: and Γ; moreover Sh(Γ)Sh(M):Sh(A).

Proof of Theorem 186.4 — Shape preserves typing

Proof. Induction on the derivation of ΓM:A. At a variable, the context rule already contains the kinding premise, and Sh(x)=x with the type replaced by its shape. At an abstraction, the induction hypothesis gives Sh(Γ),x:kSh(A)Sh(M):Sh(B), and the parameter abstraction rule concludes Sh(Γ)λ0x.Sh(M):(x:Sh(A))Sh(B), which is Sh((x:A)B) 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(B[Sh(V)])=Sh(B)[Sh(V)]. The remaining constructors are formal copies of these three, with Sh pushed through the constructor by the corresponding clause of definition 186.2. ◻

Theorem 186.5 — Substitution

  1. If Φ,x:P,ΦB[x]: and ΦR:P, then Φ,Φ[R/x]B[R]:.

  2. If Φ,x:P,ΓM:B[x] and ΦR:P, then Φ,Γ[R/x]M[R/x]:B[R].

  3. Let Γ1,x:kA,ΓM:B[x] and Γ2V:A. Then Γ1+kΓ2, Γ[Sh(V)/x]  M[V/x]:B[Sh(V)].

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 R 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(Γ)A: becomes Sh(Γ[R/x])A[R/x]: by (i) applied at a smaller derivation, using that Sh commutes with substitution of a parameter term because Sh(R)=R.

Clause (iii) is the one whose statement is not the expected one, so its mechanism is written out. The term V is a value, possibly of a linear type; it may therefore not be substituted into a type, and the statement substitutes Sh(V) there instead. Consider the application case: M=M1V1 with Γ1,x:k1AM1:(y:A1)B1[y] and Γ1,x:k2AV1:A1, where k=k1+k2 and Γ1=Γ1+Γ1. The induction hypothesis applies to each premise with its own index, giving Γ1+k1Γ2M1[V/x] and Γ1+k2Γ2V1[V/x], and the application rule concludes at the type B1[Sh(V1[V/x])]. It remains to check that this is (B1[Sh(V1)])[V/x] with Sh(V) substituted for x; that is the equation Sh(V1[V/x])=Sh(V1)[Sh(V)/x], which holds by induction on V1 from definition 186.2, every clause of which commutes with substitution. Finally (k1+k2)Γ2=k1Γ2+k2Γ2 by the arithmetic of indices, so the two contexts add to Γ1+kΓ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 k=1. ◻

Theorem 186.6 — Type preservation

If ΓM:A and MM in the big-step call-by-value semantics, then ΓM:A.

Proof of Theorem 186.6 — Type preservation

Proof. Rule induction on MM. The value rules are immediate. For application, M=M1M2 with M1λx.N, M2V, and N[V/x]M; the induction hypothesis gives Γ1λx.N:(x:A1)B[x] and Γ2V:A1, inversion of the abstraction rule gives Γ1,x:1A1N:B[x], and theorem 186.5(iii) with k=1 gives Γ1+Γ2N[V/x]:B[Sh(V)], which is the type assigned to M by the application rule. A second use of the induction hypothesis transports this to M. The cases for pairs, let, force, 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

Definition 186.7 — Wire vectors

Let Nat be a parameter type with constructors 0 and succ, and define the family of state types Vec Qubit 0:=Unit,Vec Qubit (succ n):=QubitVec Qubit n. Its shape is Sh(Vec Qubit n)=Unit for every n by definition 186.2, while the type itself depends on n; the index is a parameter and the wires are states.

Example 186.8 — A chain of controlled gates

Let CNOT have type !(QubitQubitQubitQubit). Define by recursion on the parameter n chain:(n:Nat) !(QubitVec Qubit nQubitVec Qubit n) by chain 0:=lift(λp.p) and chain (succ m):=lift(λp. let (c,v)=p inlet (w,v)=v inlet (c,w)=(forceCNOT)(c,w) in ), where the omitted part applies force(chain m) to (c,v) and reassembles the result with w. The recursion is on n, which is a parameter and may therefore be inspected and used twice; the wires c,w,v each occur exactly once, as the linear rules require.

Boxing gives chainbox:(n:Nat)Circ(QubitVec Qubit n, QubitVec Qubit n). For n=3 the generated circuit has three CNOT gates and the interface (0:Qubit, 1,2,3:Qubit)  (0, 1,2,3), four wires in and four out, which is what the type says once n is instantiated. Compare example 185.6: there the type was Circ(α,α) for every n, and the generated circuit’s interface was not visible in it.

Example 186.9 — Type-safe uncomputation

A circuit that computes a value while producing garbage has type aWithGarbage b, where the monad WithGarbage records a vector of garbage wires together with its length; the operation dispose 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 f:!(aWithGarbage b) and a consumer g:!(cbdb) and returns a garbage-free cada. It is built from an existential boxing operation whose type is existsBox:(p:bType)!(a(n:b)pn)(n:b)Circ(a, pn), which boxes a circuit-generating function whose output interface is not known in advance, returning the width n together with a circuit at that width. The combinator then unboxes the circuit, runs it, applies g 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 n because n 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.

Exercise 186.1

★☆☆ Compute Sh(A) for A=QubitVec Qubit n, for A=!(QubitQubit), and for A=(x:Nat)Circ(Qubit,Qubit), and say in each case which information about A survives.

Exercise 186.2

★★☆ Let Γ2V:Qubit. Using the index arithmetic of definition 186.1, compute Γ1+kΓ2 for k=0,1,ω and say which of the three is excluded by well-formedness, and why.

Exercise 186.3

★★☆ Explain why (x:Qubit)P[x] is not a type of definition 186.1, and why (x:Qubit)B[x] is. Then show that the second is only useful when B depends on x through Sh(x), and compute what that dependency can be.

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 with-computed 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 with-computed 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 n+1 is produced for input n; 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.

Exercise 186.4

★★☆ Construct two size-indexed circuit families: one applying H to every wire of Vec Qubit n, and one applying CNOT to every adjacent pair. Give the type of each, compute the generated interface for n=3, and count the gates as a function of n.

Exercise 186.5

★★☆ Write out the pair case of theorem 186.5(iii) in full, including the index arithmetic and the shape equation Sh(V1[V/x])=Sh(V1)[Sh(V)/x]. Then exhibit a term for which substituting V rather than Sh(V) into the type produces a type that is not well kinded.

Exercise 186.6

★★☆ Repair the following unsafe uncomputation attempt: a program applies f to produce a result and garbage, applies g, and then discards the garbage wires with dispose instead of running the reverse circuit. State which type in example 186.9 rejects the attempt, and what physical difference the rejection corresponds to.

Exercise 186.7

★★★ Practical project.indexed-circuit-checker Implement in Agda or Kappa a type checker and circuit generator for the fragment of definition 186.1, definition 186.3 containing Unit, Qubit, !A, linear and , the parameter arrow, Nat with recursion, and the family Vec Qubit n. Implement the shape operation, index arithmetic on contexts, kinding, typing, and generation of the circuit for a closed boxed term.

The invariant to maintain is the pair proved in theorem 186.4, theorem 186.5: every type is kinded in the shape of its context, and substituting a value into a type goes through Sh. The concrete result is a function taking a closed term of type (n:Nat)Circ() and a numeral, and returning the generated circuit with its input and output interfaces.

Acceptance test. For chainbox of example 186.8 at n{0,1,3} the tool reports circuits with 0, 1, and 3 gates and interfaces of width 1, 2, and 4; the term of exercise 186.3 using (x:Qubit)P[x] is rejected at kinding, with the checker naming the parameter-type premise; a term that uses a wire variable twice is rejected by index arithmetic, with the checker printing the offending index ω at a non-parameter type; and substituting a value into a type without applying Sh — the prescribed mutation — must make the tool accept a term whose reported result type mentions a qubit variable, which the kinding check must then reject.

The program checks and generates finite circuits for closed terms at fixed numerals. It illustrates theorem 186.5, theorem 186.6 and proves neither, and it establishes nothing about the semantics of the generated circuit, in accordance with example 186.9.

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 WithGarbage monad, the existsBox operation, and the with-computed 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.

Search the book

Type to search the local edition.