Verified Compilation of Quantum Oracles: Liyi Li, Finn Voichick, Kesha Hietala, Yuxiang Peng, Xiaodi Wu, Michael Hicks
Verified Compilation of Quantum Oracles: Liyi Li, Finn Voichick, Kesha Hietala, Yuxiang Peng, Xiaodi Wu, Michael Hicks
1 INTRODUCTION
Quantum computers offer unique capabilities that can be used to program substantially faster algo-
rithms compared to those written for classical computers. For example, Grover’s search algorithm
[Grover 1996, 1997] can query unstructured data in sub-linear time (compared to linear time on a
classical computer), and Shor’s algorithm [Shor 1994] can factorize a number in polynomial time
(compared to the sub-exponential time for the best known classical algorithm). An important source
of speedups in these algorithms are the quantum computer’s ability to apply an oracle function
coherently, i.e., to a superposition of classical queries, thus carrying out in one step a function that
would potentially take many steps on a classical computer. For Grover’s, the oracle is a predicate
function that determines when the searched-for data is found. For Shor’s, it is a classical modular
exponentiation function; the algorithm finds the period of this function where the modulus is the
number being factored.
While the classical oracle function is perhaps the least interesting part of a quantum algorithm,
it contributes a significant fraction of the final program’s compiled quantum circuit. For example,
Gidney and Ekerå [2021] estimated that Shor’s modular exponentiation function constitutes 90% of
the final code. In our own experiments with Grover’s, our oracle makes up over 99% of the total
gate count (the oracle has 3.3 million gates). Because quantum computers will be resource-limited
for the foreseeable future [Somma 2020; Wilkins 2021], programmers and programming tools will
be expected to heavily optimize their quantum circuits, especially the oracles. Such optimizations,
including ones that involve approximation, risk bugs that can be hard to detect. This is because
Authors’ addresses: Liyi Li, University of Maryland, USA, [email protected]; Finn Voichick, University of Maryland, USA,
[email protected]; Kesha Hietala, University of Maryland, USA, [email protected]; Yuxiang Peng, University of Maryland, USA,
[email protected]; Xiaodi Wu, University of Maryland, USA, [email protected]; Michael Hicks, University of Maryland,
USA, [email protected].
1:2 Liyi Li, Finn Voichick, Kesha Hietala, Yuxiang Peng, Xiaodi Wu, and Michael Hicks
Fig. 1. The qvm high-assurance compiler stack. Checkbox means verified; gear means property-tested.
quantum programs are inherently difficult to simulate, test, and debug—qubits on real quantum
computers are noisy and unreliable; observing a quantum program state mid-execution may change
that state; and simulating a general quantum program on a classical computer is intractable because
quantum states can require resources exponential in the number of qubits.
In this paper, we report on a framework we have been developing called vqo, the Verified
Quantum Oracle framework, whose goal is to help programmers write quantum oracles that are
correct and efficient. vqo is part of qvm, for Quantum Verified Machine, which has several elements,
as shown in Figure 1.
• Using vqo, an oracle can be specified in a simple, high-level programming language we call
Oqimp, which has standard imperative features and can express arbitrary classical programs.
It distinguishes quantum variables from classical parameters, allowing the latter to be partially
evaluated [Jones et al. 1993], thereby saving qubits during compilation.
• The resulting Oqimp program is compiled to Oqasm (pronounced “O-chasm”), the oracle
quantum assembly language. Oqasm was designed to be efficiently simulatable while never-
theless admitting important optimizations; it is our core technical contribution and we say
more about it below. The generated Oqasm code links against implementations of standard
operators (addition, multiplication, sine, cosine, etc.) also written in Oqasm.
• The Oqasm oracle is then translated to sqir, the Simple Quantum Intermediate Representation,
which is a circuit language embedded in the Coq proof assistant. sqir has been used to
prove correct both quantum algorithms [Hietala et al. 2021a] and optimizations [Hietala
et al. 2021b], the latter as part of voqc, the Verified Optimizer for Quantum Circuits. After
linking the oracle with the quantum program that uses it, the complete sqir program can
be optimized and extracted to OpenQASM 2.0 [Cross et al. 2017] to run on a real quantum
machine. Both vqo’s compilation from Oqimp to Oqasm and translation from Oqasm to sqir
have been proved correct in Coq.
vqo helps programmers ensure their oracles are correct by supporting both testing and verifica-
tion, and ensures they are efficient by supporting several kinds of optimization. Both aspects are
captured in the design of Oqasm, a quantum assembly language specifically designed for oracles.
Because oracles are classical functions, a reasonable approach would have been to design Oqasm
to be a circuit language comprised of “classical” gates; e.g., prior work has targeted gates X (“not”),
CNOT (“controlled not”), and CCNOT (“controlled controlled not,” aka Toffoli). Doing so would simplify
proofs of correctness and support efficient testing by simulation because an oracle’s behavior could
be completely characterized by its behavior on computational basis states (essentially, classical
bitstrings). ReverC [Amy et al. 2017] and ReQWIRE [Rand et al. 2018] take this approach. However,
doing so cannot support optimized oracle implementations that use fundamentally quantum
Verified Compilation of Quantum Oracles 1:3
functionality, e.g., as in quantum Fourier transform (QFT)-based arithmetic circuits [Beauregard 2003;
Draper 2000]. These circuits employ quantum-native operations (e.g., controlled-phase operations)
in the QFT basis. Our key insight is that expressing such optimizations does not require expressing
all quantum programs, as is possible in a language like sqir. Instead, Oqasm’s type system restricts
programs to those that admit important optimizations while keeping simulation tractable. Oqasm
also supports virtual qubits; its type system ensures that position shifting operations, commonly
used when compiling arithmetic functions, require no extra SWAP gates when compiled to sqir, so
there is no added run-time cost.
Leveraging Oqasm’s efficient simulatability, we implemented a property-based random testing
(PBT) framework for Oqasm programs in QuickChick [Paraskevopoulou et al. 2015], a variant of
Haskell’s QuickCheck [Claessen and Hughes 2000] for Coq programs. This framework affords two
benefits. First, we can test that an Oqasm operator or Oqimp program is correct according to its
specification. Formal proof in Coq can be labor-intensive, so PBT provides an easy-to-use confidence
boost, especially prior to attempting formal proof. Second, we can use testing to assess the effect
of approximations when developing oracles. For example, we might like to use approximate QFT,
rather than full-precision QFT, in an arithmetic oracle in order to save gates. PBT can be used to
test the effect of this approximation within the overall oracle by measuring the distance between
the fully-precise result and the approximate one.
To assess vqo’s effectiveness we have used it to build several efficient oracles and oracle compo-
nents, and have either tested or proved their correctness.
• Using Oqimp we implemented sine, cosine, and other geometric functions used in Hamiltonian
simulation [Feynman 1982], leveraging the arithmetic circuits described below. Compared
to a sine function implemented in Quipper [Green et al. 2013], a state-of-the-art quantum
programming framework, vqo’s uses far fewer qubits thanks to Oqimp’s partial evaluation.
• We have implemented a variety of arithmetic operators in Oqasm, including QFT-, approxi-
mate QFT- and Toffoli-based multiplication, addition, modular multiplication, and modular
division. Overall, circuit sizes are competitive with, and oftentimes better than, those pro-
duced by Quipper. Qubit counts for the final QFT-based circuits are always lower, sometimes
significantly so (up to 53%), compared to the Toffoli-based circuits.
• We have proved correct both QFT and Toffoli-based adders, and QFT and Toffoli-based
modular multipliers (which are used in Shor’s algorithm). These constitute the first proved-
correct implementations of these functions, as far as we are aware.
• We used PBT to test the correctness of various Oqasm operators. Running 10,000 generated
tests on 8- or 16-bit versions of the operators takes just a few seconds. Testing 60-bit versions
of the adders and multipliers takes just a few minutes, whereas running a general quantum
simulator on the final circuits fails. We found several interesting bugs in the process of doing
PBT and proof, including in the original algorithmic description of the QFT-based modular
multiplier [Beauregard 2003].
• We used PBT to analyze the precision difference between QFT and approximate QFT (AQFT)
circuits, and the suitability of AQFT in different algorithms. We found that the AQFT adder
(which uses AQFT in place of QFT) is not an accurate implementation of addition, but that it
can be used as a subcomponent of division/modulo with no loss of precision, reducing gate
count by 4.5–79.3%.
• Finally, to put all of the pieces together, we implemented the ChaCha20 stream cipher
[Bernstein 2008] in Oqimp and used it as an oracle for Grover’s search, previously implemented
and proved correct in sqir [Hietala et al. 2021a]. We used PBT to test the oracle’s correctness.
1:4 Liyi Li, Finn Voichick, Kesha Hietala, Yuxiang Peng, Xiaodi Wu, and Michael Hicks
𝐻 𝑅2 𝑅3 𝑅4 𝐻 𝑅2 𝑅3
• 𝐻 𝑅2 𝑅3 • 𝐻 𝑅2
• • 𝐻 𝑅2 • • 𝐻
• • • 𝐻 𝐻
Fig. 2. Example quantum circuits: QFT over 4 qubits (left) and approximate QFT with 3 qubit precision (right).
𝑅𝑚 is a 𝑧-axis rotation by 2𝜋/2𝑚 .
Combining its tested property with Grover’s correctness property, we demonstrate that
Grover’s is able to invert the ChaCha20 function and find collisions.
The rest of the paper is organized as follows. We begin with some background on quantum
computing (Section 2) and then present Oqasm’s syntax, typing, and semantics (Section 3). Then we
discuss vqo’s implementation: Oqasm’s translator and property-based tester, and Oqimp (Section 4).
Finally, we present our results (Sections 5 to 7), compare against related work (Section 8), and
conclude. All code presented in this paper is freely available at https://github.com/inQWIRE/VQO.
2 BACKGROUND
We begin with some background on quantum computing and quantum algorithms.
Quantum States. A quantum state consists of one or more quantum bits (qubits). A qubit can be
expressed as a two dimensional vector 𝛽 where 𝛼, 𝛽 are complex numbers such that |𝛼 | 2 + |𝛽 | 2 = 1.
𝛼
The 𝛼 and 𝛽 are called amplitudes. We frequently write the qubit vector as 𝛼 |0⟩ + 𝛽 |1⟩ where
|0⟩ = 10 and |1⟩ = 01 are computational basis states. When both 𝛼 and 𝛽 are non-zero, we can
think of the qubit as being “both 0 and 1 at once,” a.k.a. a superposition. For example, √1 (|0⟩ + |1⟩)
2
is an equal superposition of |0⟩ and |1⟩.
We can join multiple qubits together to form a larger quantum state with the tensor product (⊗)
from linear algebra. For example, the two-qubit state |0⟩ ⊗ |1⟩ (also written as |01⟩) corresponds to
vector [ 0 1 0 0 ]𝑇 . Sometimes a multi-qubit state cannot be expressed as the tensor of individual
states; such states are called entangled. One example is the state √1 (|00⟩ + |11⟩), known as a Bell
2
pair. Entangled states lead to exponential blowup: A general 𝑛-qubit state must be described with a
2𝑛 -length vector, rather than 𝑛 vectors of length two. The latter is possible for unentangled states
like |0⟩ ⊗ |1⟩; Oqasm’s type system guarantees that qubits remain unentangled.
Quantum Circuits. Quantum programs are commonly expressed as circuits, like those shown
in Figure 2. In these circuits, each horizontal wire represents a qubit, and boxes on these wires
indicate quantum operations, or gates. Gates may be controlled by a particular qubit, as indicated
by a filled circle and connecting vertical line. The circuits in Figure 2 use four qubits and apply 10
(left) or 7 (right) gates: four Hadamard (𝐻 ) gates and several controlled 𝑧-axis rotation (“phase”)
gates. When programming, circuits are often built by meta-programs embedded in a host language,
e.g., Python (for Qiskit [Cross 2018], Cirq [Google Quantum AI 2019], PyQuil [Rigetti Computing
2021], and others), Haskell (for Quipper [Green et al. 2013]), or Coq (for sqir and our work).
Quantum Fourier Transform. The quantum Fourier transform (QFT) is the quantum analogue
of the discrete Fourier transform. It is used in many quantum algorithms, including the phase
estimation portion of Shor’s factoring algorithm [Shor 1994]. The standard implementation of a
QFT circuit (for 4 qubits) is shown on the left of Figure 2; an approximate QFT (AQFT) circuit can be
constructed by removing select controlled phase gates [Barenco et al. 1996; Hales and Hallgren 2000;
Nam et al. 2020]. This produces a cheaper circuit that implements an operation mathematically
Verified Compilation of Quantum Oracles 1:5
similar to the QFT. The AQFT circuit we use in vqo (for 4 qubits) is shown on the right of Figure 2.
When it is appropriate to use AQFT in place of QFT is an open research problem, and one that is
partially addressed by our work on Oqasm, which allows efficient testing of the effect of AQFT
inside of oracles.
Computational and QFT Bases. The computational basis is just one possible basis for the
underlying vector space. Another basis is the Hadamard basis, written as a tensor product of
{|+⟩ , |−⟩}, obtained by applying a Hadamard transform to elements of the computational basis,
where |+⟩ = √1 (|0⟩ + |1⟩) and |−⟩ = √1 (|0⟩ − |1⟩). A third useful basis is the Fourier (or QFT) basis,
2 2
obtained by applying a quantum Fourier transform (QFT) to elements of the computational basis.
Quantum Algorithms and Oracles. Quantum algorithms manipulate input information en-
coded in “oracles,” which are callable black box circuits. For example, Grover’s algorithm for
unstructured quantum search [Grover 1996, 1997] is a general approach for searching a quantum
“database,” which is encoded in an oracle for a function 𝑓 : {0, 1}𝑛 → {0, 1}. Grover’s finds an
element 𝑥 ∈ {0, 1}𝑛 such that 𝑓 (𝑥) = 1 using 𝑂 (2𝑛/2 ) queries, a quadratic speedup over the best
possible classical algorithm, which requires Ω(2𝑛 ) queries. An oracle can be constructed for an
arbitrary function 𝑓 simply by constructing a reversible classical logic circuit implementing 𝑓 and
then replacing classical logic gates with corresponding quantum gates, e.g., X for “not,” CNOT for
“xor,” and CCNOT (aka Toffoli) for “and.” However, this approach does not always produce the most
efficient circuits; for example, quantum circuits for arithmetic can be made more space-efficient
using the quantum Fourier transform [Draper 2000].
Transforming an irreversible computation into a quantum circuit often requires introducing
ancillary qubits, or ancillae, to store intermediate information [Nielsen and Chuang 2011, Chapter
3.2]. Oracle algorithms typically assume that the oracle circuit is reversible, so any data in ancillae
must be uncomputed by inverting the circuit that produced it. Failing to uncompute this information
leaves it entangled with the rest of the state, potentially leading to incorrect program behavior. To
make this uncomputation more efficient and less error-prone, recent programming languages such
as Silq [Bichsel et al. 2020] have developed notions of implicit uncomputation. We have similar
motivations in developing vqo: we aim to make it easier for programmers to write efficient quantum
oracles, and to assure, through verification and randomized testing, that they are correct.
This section presents Oqasm states and the language’s syntax, semantics, typing, and soundness
results. As a running example, we use the QFT adder [Beauregard 2003] shown in Figure 3. The
Coq function rz_adder generates an Oqasm program that adds two natural numbers a and b, each
of length n qubits.
Fig. 5. Oqasm syntax. For an operator OP, OP [−1] indi- Fig. 6. SR unfolds to a series of RZ instructions
cates that the operator has a built-in inverse available.
Typing. In Oqasm, typing is with respect to a type environment Ω and a size environment Σ,
which map Oqasm variables to their basis and size (number of qubits), respectively. The typing
judgment is written Σ; Ω ⊢ 𝜄 ⊲ Ω ′ which states that 𝜄 is well-typed under Ω and Σ, and transforms
the variables’ bases to be as in Ω ′ (Σ is unchanged). Select type rules are given in Figure 7; the rules
not shown (for ID, Rshift, Rev, and SR−1 ) are similar.
The type system enforces three invariants. First, it enforces that instructions are well-formed,
meaning that gates are applied to valid qubit positions (the second premise in X) and that any
control qubit is distinct from the target(s) (the fresh premise in CU). This latter property enforces
the quantum no-cloning rule. For example, we can apply the CU in rz_adder’ (Figure 3) because
position a,m is distinct from variable b.
Second, the type system enforces that instructions leave affected qubits in a proper basis (thereby
avoiding entanglement). The rules implement the state machine shown in Figure 8. For example,
QFT 𝑛 transforms a variable from Nor to Phi 𝑛 (rule QFT), while QFT−1 𝑛 transforms it from Phi 𝑛
back to Nor (rule RQFT). Position shifting operations are disallowed on variables 𝑥 in the Phi
1:8 Liyi Li, Finn Voichick, Kesha Hietala, Yuxiang Peng, Xiaodi Wu, and Michael Hicks
SEQ
Σ; Ω ⊢ 𝜄 1 ⊲ Ω′ Σ; Ω′ ⊢ 𝜄 2 ⊲ Ω′′
Σ; Ω ⊢ 𝜄 1 ; 𝜄 2 ⊲ Ω′′
⟦ID 𝑝⟧𝜑 =𝜑
⟦X (𝑥, 𝑖)⟧𝜑 = 𝜑[(𝑥, 𝑖) ↦→ ↑ xg(↓ 𝜑 (𝑥, 𝑖))] where xg( |0⟩) = |1⟩ xg( |1⟩) = |0⟩
⟦CU (𝑥, 𝑖) 𝜄⟧𝜑 = cu(↓ 𝜑 (𝑥, 𝑖), 𝜄, 𝜑) where cu( |0⟩, 𝜄, 𝜑) = 𝜑 cu( |1⟩, 𝜄, 𝜑) = ⟦𝜄⟧𝜑
⟦SR 𝑚 𝑥⟧𝜑 = 𝜑[∀𝑖 ≤ 𝑚. (𝑥, 𝑖) ↦→ ↑ |Φ(𝑟𝑖 + 1
2𝑚−𝑖+1
) ⟩] when ↓ 𝜑 (𝑥, 𝑖) = |Φ(𝑟𝑖 ) ⟩
⟦SR−1 𝑚 𝑥⟧𝜑 = 𝜑[∀𝑖 ≤ 𝑚. (𝑥, 𝑖) ↦→ ↑ |Φ(𝑟𝑖 − 1
2𝑚−𝑖+1
) ⟩] when ↓ 𝜑 (𝑥, 𝑖) = |Φ(𝑟𝑖 ) ⟩
= 𝜑[𝑥 ↦→ ↑ qt(Σ(𝑥), ↓ 𝜑 (𝑥), 𝑛)] where qt(𝑖, |𝑦 ⟩ , 𝑛) =
Ë𝑖−1 𝑦
⟦QFT 𝑛 𝑥⟧𝜑 𝑘=0 ( |Φ( 𝑛−𝑘 ) ⟩)
2
⟦QFT−1 𝑛 𝑥⟧𝜑 = 𝜑[𝑥 ↦→ ↑ qt−1 (Σ(𝑥), ↓ 𝜑 (𝑥), 𝑛)]
⟦Lshift 𝑥⟧𝜑 = 𝜑[𝑥 ↦→ pm𝑙 (𝜑 (𝑥))] where pm𝑙 (𝑞 0 ⊗ 𝑞 1 ⊗ · · · ⊗ 𝑞𝑛−1 ) = 𝑞𝑛−1 ⊗ 𝑞 0 ⊗ 𝑞 1 ⊗ · · ·
⟦Rshift 𝑥⟧𝜑 = 𝜑[𝑥 ↦→ pm𝑟 (𝜑 (𝑥))] where pm𝑟 (𝑞 0 ⊗ 𝑞 1 ⊗ · · · ⊗ 𝑞𝑛−1 ) = 𝑞 1 ⊗ · · · ⊗ 𝑞𝑛−1 ⊗ 𝑞 0
⟦Rev 𝑥⟧𝜑 = 𝜑[𝑥 ↦→ pm𝑎 (𝜑 (𝑥))] where pm𝑎 (𝑞 0 ⊗ · · · ⊗ 𝑞𝑛−1 ) = 𝑞𝑛−1 ⊗ · · · ⊗ 𝑞 0
⟦𝜄 1 ; 𝜄 2 ⟧𝜑 = ⟦𝜄 2 ⟧(⟦𝜄 1 ⟧𝜑)
↓ 𝛼 (𝑏)𝑞 = 𝑞 ↓ (𝑞 1 ⊗ · · · ⊗ 𝑞𝑛 ) =↓ 𝑞 1 ⊗ · · · ⊗ ↓ 𝑞𝑛
𝜑[(𝑥, 𝑖) ↦→ ↑ 𝑞] = 𝜑[(𝑥, 𝑖) ↦→ 𝛼 (𝑏)𝑞] where 𝜑 (𝑥, 𝑖) = 𝛼 (𝑏)𝑞𝑖
𝜑[(𝑥, 𝑖) ↦→ ↑ 𝛼 (𝑏 1 )𝑞] = 𝜑[(𝑥, 𝑖) ↦→ 𝛼 (𝑏 1 + 𝑏 2 )𝑞] where 𝜑 (𝑥, 𝑖) = 𝛼 (𝑏 2 )𝑞𝑖
𝜑[𝑥 ↦→ 𝑞𝑥 ] = 𝜑[∀𝑖 < Σ(𝑥). (𝑥, 𝑖) ↦→ 𝑞 (𝑥,𝑖 ) ]
𝜑[𝑥 ↦→ ↑ 𝑞𝑥 ] = 𝜑[∀𝑖 < Σ(𝑥). (𝑥, 𝑖) ↦→ ↑ 𝑞 (𝑥,𝑖 ) ]
basis because the qubits that make up 𝑥 are internally related (see Definition 3.1) and cannot be
rearranged. Indeed, applying a Lshift and then a QFT−1 on 𝑥 in Phi would entangle 𝑥’s qubits.
Third, the type system enforces that the effect of position shifting operations can be statically
tracked. The neutral condition of CU requires that any shifting within 𝜄 is restored by the time it
completes. For example, CU 𝑝 (Lshift 𝑥) ; X (𝑥, 0) is not well-typed, because knowing the final
physical position of qubit (𝑥, 0) would require statically knowing 𝑝. On the other hand, the program
CU 𝑐 (Lshift 𝑥 ; X (𝑥, 0) ; Rshift 𝑥) ; X (𝑥, 0) is well-typed because the effect of the Lshift is
“undone” by an Rshift inside the body of the CU.
Verified Compilation of Quantum Oracles 1:9
1 Notethat Φ(𝑥) = Φ(𝑥 + 𝑛), where the integer 𝑛 refers to phase 2𝜋𝑛; so multiple choices of 𝜐 are possible.
2A Hilbert space is a vector space with an inner product that is complete with respect to the norm defined by the inner
product. S𝑑 is a subset, not a subspace of H𝑑 because S𝑑 is not closed under addition: Adding two well-formed states can
produce a state that is not well-formed.
1:10 Liyi Li, Finn Voichick, Kesha Hietala, Yuxiang Peng, Xiaodi Wu, and Michael Hicks
SR 0 SR−1 0
.. SR 1 . . . ..
. . . SR−1 1
. (𝑥 + 𝑎)𝑛 = SR (𝑛 − 1) . (𝑥 − 𝑎)𝑛 = SR−1 (𝑛 − 1)
We can extend the groupoid to ({𝜄}, Σ, H𝑑 ) by defining a general 2𝑑 dimensional Hilbert space
H𝑑 ,such that S𝑑 ⊆ H𝑑 , and removing the typing requirements on {𝜄}. Clearly, ({𝜄}, Σ, H𝑑 ) is still
a groupoid because every Oqasm operation is valid in a traditional quantum language like sqir.
We then have the following two two theorems to connect Oqasm operations with operations in the
general Hilbert space:
Theorem 3.3. ({𝜄}, Σ, Ω, S𝑑 ) ⊆ ({𝜄}, Σ, H𝑑 ) is a subgroupoid.
Ë𝑑−1
Theorem 3.4. Let |𝑦⟩ be an abbreviation of 𝛼 (𝑟𝑚 ) |𝑏𝑚 ⟩ for 𝑏𝑚 ∈ {0, 1}. If for every
′ Í2𝑑 −1 Í2𝑑𝑚=0
−1 ′
𝑖 ∈ [0, 2 ), ⟦𝜄⟧ |𝑦𝑖 ⟩ = |𝑦𝑖 ⟩, then ⟦𝜄⟧( 𝑖=0 |𝑦𝑖 ⟩) = 𝑖=0 |𝑦𝑖 ⟩.
𝑑
We prove these theorems as corollaries of the compilation correctness theorem from Oqasm
to sqir (Theorem 4.1). Theorem 3.3 suggests that the space S𝑑 is closed under the application of
any well-typed Oqasm operation. Theorem 3.4 says that Oqasm oracles can be safely applied to
superpositions over classical states.3
Oqasm programs are easily invertible, as shown by the rules in Figure 10. This inversion operation
is useful for constructing quantum oracles; for example, the core logic in the QFT-based subtraction
circuit is just the inverse of the core logic in the addition circuit (Figure 10). This allows us to reuse
the proof of addition in the proof of subtraction. The inversion function satisfies the following
properties:
Theorem 3.5. [Type reversibility] For any well-typed program 𝜄, such that Σ; Ω ⊢ 𝜄 ⊲ Ω ′, its
inv
inverse 𝜄 ′, where 𝜄 −−→ 𝜄 ′, is also well-typed and we have Σ; Ω ′ ⊢ 𝜄 ′ ⊲ Ω. Moreover, ⟦𝜄; 𝜄 ′⟧𝜑 = 𝜑.
Fig. 12. Select Oqasm to sqir translation rules (sqir circuits are marked blue)
The proof of translation correctness is by induction on the Oqasm program 𝜄. Most of the proof
simply shows the correspondence of operations in 𝜄 to their translated-to gates 𝜖 in sqir, except for
shifting operations, which update the virtual-to-physical map.
Note that to link a complete, translated oracle 𝜄 into a larger sqir program may require that
𝛾 = 𝛾 ′, i.e., neutral(𝜄), so that logical inputs match logical outputs. This requirement is naturally
met for programs written to be reversible, as is the case for all arithmetic circuits in this paper, e.g.,
rz_adder from Figure 3.
4 Translation in fact threads through the typing judgment, but we elide that for simplicity.
1:12 Liyi Li, Finn Voichick, Kesha Hietala, Yuxiang Peng, Xiaodi Wu, and Michael Hicks
Implementation. PBT randomly generates inputs using a hand-crafted generator, and confirms
that a property holds for the given inputs. Since arithmetic/oracle operations are defined over
Nor-basis inputs, we wrote a generator for these inputs. A single test of an Oqasm program involves
five steps: (1) generate (or specify) 𝑛, which is the number of qubits in the input; (2) for each input
variable 𝑥, generate uniformly random bitstrings 𝑏 0𝑏 1 ...𝑏𝑛−1 of length 𝑛, representing 𝑥’s initial
Ë𝑛−1
qubit value 𝑖=0 𝛼 (0) |𝑏𝑖 ⟩; (3) prepare an Oqasm state 𝜑 containing all input variables’ encoded
bitstrings; (4) execute the Oqasm program with the prepared state; and (5) check that the resulting
state satisfies the desired property.
We took several steps to improve testing performance. First, we streamlined the representation
of states: Per the semantics in Figure 9, in a state with 𝑛 qubits, the phase associated with each qubit
can be written as 𝛼 ( 2𝜐𝑛 ) for some natural number 𝜐. Qubit values in both bases are thus pairs of
𝑦
natural numbers: the global phase 𝜐 (in range [0, 2𝑛 )) and 𝑏 (for |𝑏⟩) or 𝑦 (for |Φ( 2𝑛 )⟩). An Oqasm
state 𝜑 is a map from qubit positions 𝑝 to qubit values 𝑞; in our proofs, this map is implemented as
a partial function, but for testing, we use an AVL tree implementation (proved equivalent to the
functional map). To avoid excessive stack use, we implemented the Oqasm semantics function tail-
recursively. To run the tests, QuickChick runs OCaml code that it extracts from the Coq definitions;
during extraction, we replace natural numbers and operations thereon with machine integers and
operations. We present performance results in Section 5.
Testing Correctness. A full formal proof is the gold standard for correctness, but it is also
laborious. It is especially deflating to be well through a proof only to discover that the intended
property does not hold and, worse, that nontrivial changes to the program are necessary. Our PBT
framework gives assurance that an Oqasm program property is correct by attempting to falsify
it using thousands of randomly generated instances, with good coverage of the program’s input
space. We have used PBT to test the correctness of a variety of operators useful in oracle programs,
as presented in Section 5. When implementing a QFT-adder circuit, using PBT revealed that we had
encoded the wrong endianness. We have also used PBT with Oqimp programs by first compiling
them to Oqasm and then testing their correctness at that level.
82 84 86 2𝑛−2
8
sin 𝑥 ≈ 8 ∗ ( 𝑥8 − 3! ( 𝑥8 ) 3 + 5! ( 𝑥8 ) 5 − 7! ( 𝑥8 ) 7 + ... + (−1) 𝑛−1 (2𝑛−1) 𝑥 2𝑛−1
!(8) )
if(𝑥 < 𝑦)
𝑧+=𝑥;
𝑎=𝑥 * 𝑦; 𝑧=𝑥 * 𝑦; 𝑧=𝑥 * 𝑦;
𝑎=𝑥 * 𝑦; 𝑧=𝑥 * 𝑦;
(1) (2) else (3) 𝑥=𝑥 + 1; ✗ (4) inv(𝑧); (5) ✓
inv(𝑧); ✗ inv(𝑧);
𝑧=𝑥 * 𝑦; inv(𝑧); inv(𝑧); ✗
inv(𝑧);
inv(𝑧); ✗
function returns, only the return value is copied and stored to a target variable. For other values,
like 𝑥 /8 , the compiler will insert an inverse circuit to revert all side effects.
When variables are reused within a function, they must be uncomputed using Oqimp’s inv 𝑥
operation. For example, in Figure 13, the second inv operation returns 𝑥𝑧 to its state prior to
the execution of 𝑥𝑧 =pow(𝑥 /8, 𝑛 4 ) so that 𝑥𝑧 can be reassigned in the next iteration. We plan to
incorporate automatic uncomputation techniques to insert inv 𝑥 calls automatically, but doing so
requires care to avoid blowup in the generated circuit [Paradis et al. 2021].
The vqo compiler imposes three restrictions on the use of inv 𝑥, which aim to ensure that each
use uncomputes just one assignment to 𝑥. First, since the semantics of an inv operation reverses the
most recent assignment, we require that every inv operation have a definite predecessor. Example
(1) in Figure 14 shows an inv operation on a variable that does not have a predecessor; (2) shows
a variable 𝑧 whose predecessor is not always executed. Both are invalid in Oqimp. Second, the
statements between an inv operation and its predecessor cannot write to any variables used in the
body of the predecessor. Example (3) presents an invalid case where 𝑥 is used in the predecessor
of 𝑧, and is assigned between the inv and the predecessor. The third restriction is that, while
sequenced inv operations are allowed, the number of inv operations must match the number of
predecessors. Example (4) is invalid, while (5) is valid, because the first inv in (5) matches the
multiplication assignment and the second inv matches the addition assignment.
To implement these well-formedness checks, vqo’s Oqimp compiler maintains a stack of assign-
ment statements. Once the compiler hits an inv operation, it pops statements from the stack to
find a match for the variable being uncomputed. It also checks that none of the popped statements
contain an assignment of variables used in the predecessor statement.
Compilation from Oqimp to Oqasm. The Oqimp compiler performs partial evaluation [Jones
et al. 1993] on the input program given classical parameters; the residual program is compiled to a
quantum circuit. In particular, we compile an Oqimp program by evaluating its 𝐶-mode components,
storing the results in a store 𝜎, and then using these results while translating its 𝑄-mode components
into Oqasm code. For example, when compiling the for loop in Figure 13, the compiler will look up
the value of loop-bound variable 𝑛 in the store and update 𝑖’s value in the store for each iteration.
When compiling the loop-body statement 𝑛 1 =𝑖 + 1, variable 𝑛 1 will simply be updated in the store,
and no code generated. When compiling statement 𝑥𝑧 =pow(𝑥 /8, 𝑛 4 ), the fact that 𝑥𝑧 has mode 𝑄
means that Oqasm code must be generated. Thus, each iteration will compile the non 𝐶-mode
components of the body, essentially inlining the loop. As an illustration, if we were to initialize 𝑛
to 3, the partially evaluated program would be equivalent to the following (in Oqasm rather than
Oqimp).
82
𝑥𝑟 = 𝑥 /8 ; 𝑥𝑧 = pow(𝑥 /8 , 3); 𝑥 1 = 3! ∗ 𝑥𝑧 ; 𝑥𝑟 -= 𝑥 1 ; inv 𝑥 1 ; inv 𝑥𝑧 ;
84
𝑥𝑧 = pow(𝑥 /8 , 5); 𝑥 1 = 5! ∗ 𝑥𝑧 ; 𝑥𝑟 += 𝑥 1 ; inv 𝑥 1 ; inv 𝑥𝑧 ;
86
𝑥𝑧 = pow(𝑥 /8 , 7); 𝑥 1 = 7! ∗ 𝑥𝑧 ; 𝑥𝑟 -= 𝑥 1 ; inv 𝑥 1 ; inv 𝑥𝑧 ;
We have verified that compilation from Oqimp to Oqasm is correct, in Coq, with a caveat:
Proofs for assignment statements are parameterized by correctness statements about the involved
Verified Compilation of Quantum Oracles 1:15
|𝑥𝑖 ⟩ • • • |𝑥𝑖 ⟩
•
|𝑏 ⟩ | (𝑐 + 𝑏)%𝑛⟩
.. ADD(c) SUB(n) ADD(n) SUB(c) ADD(c)
.. =
. ADD(c)%n
.
• •
|0⟩ |0⟩
•
|𝑥 ⟩ • |𝑥 ⟩
.. ...
.
•
|0⟩ |𝑐𝑥%𝑛⟩
.. ADD(20 c)%n ADD(21 c)%n . . . ADD(2𝑛−1 c)%n
.
operators. Each Coq operator function has a correctness statement associated with it; e.g., we state
that the Oqasm code produced by invoking rz_adder for addition corresponds to an addition at
the Oqimp level. In the case of rz_adder and a few others, we have a proof of this in Coq; for the
rest, we use PBT to provide some assurance that the statement is true. Further details about Oqimp
compilation and its correctness claims can be found in Appendix B.
QC time
# qubits # gates (16 / 60
# qubits # gates Verified bits)
Oqasm TOFF 33 423 ✓ Oqasm TOFF 49 11265 6 / 74
Oqasm QFT 32 1206 ✓ Oqasm TOFF (const) 33 1739 ± 367 3 / 31
Oqasm QFT (const) 16 756 ± 42 ✓ Oqasm QFT 48 4339 4 / 138
Quipper TOFF 47 768 Oqasm QFT (const) 32 1372 ± 26 4 / 158
Quipper QFT 33 6868 Quipper TOFF 63 8060
Quipper TOFF (const) 31 365 ± 11 Quipper TOFF (const) 41 2870 ± 594
(a) Addition circuits (16 bits) (b) Multiplication circuits (16 bits)
QC time
# qubits # gates (16 / 60
bits)
Oqasm TOFF (const) 49 28768 16 / 397
Oqasm QFT (const) 34 15288 5 / 412 # qubits # gates Verified
Oqasm AQFT (const) 34 5948 4 / 323 Oqasm TOFF (const) 41 56160 ✓
Quipper TOFF 98 37737 Oqasm QFT (const) 19 18503 ✓
(c) Division/modulo circuits (16 bits) (d) Modular multiplication circuits (8 bits)
Fig. 16. Comparison of Oqasm and Quipper arithmetic operators. In the “const” case, one argument is a
classically-known constant parameter. For (a)-(b) we present the average (± standard deviation) over 20
randomly selected constants 𝑐 with 0 < 𝑐 < 216 . For division/modulo, 𝑥 mod 𝑛, we only consider the case
when 𝑛 = 1, which results in the maximum number of circuit iterations; the Quipper version assumes 𝑛 is a
variable, but uses the same number of iterations as the constant case when 𝑛 = 1. In (d), we use the constant
255 (= 28 − 1) for the modulus and set the other constant to 173 (which is invertible mod 255). Quipper
supports no QFT-based circuits aside from an adder. “QC time” is the time (in seconds) for QuickChick to run
10,000 tests.
𝑥 ,𝑦 = variables, 𝑁 = constant,
[] 𝑎,𝑞,𝑡 = AQFT-based (𝑎 ), QFT-based (𝑞 ), or Toffoli-based (𝑡 )
All testing is done with 16-bit/60-bit circuits.
for the QFT adder (Figure 3) and confirmed that testing found the endianness bug. The tables in
Figure 16 give the running times for the QuickChick tests—the times include the cost of extracting
the Coq code to OCaml, compiling it, and running it with 10,000 randomly generated inputs. We
tested these operations both on 16-bit inputs (the number that’s relevant to the reported qubit and
gate sizes) and 60-bit inputs. For the smaller sizes, tests complete in a few seconds; for the larger
sizes, in a few minutes. For comparison, we translated the operators’ Oqasm programs to sqir,
converted the sqir programs to OpenQASM 2.0 [Cross et al. 2017], and then attempted to simulate
the resulting circuits on test inputs using the DDSim [Burgholzer et al. 2021], a state-of-the-art
quantum simulator. Unsurprisingly, the simulation of the 60-bit versions did not complete when
running overnight.
We also verified and property-tested several other operations, as shown in Figure 17.
During development, we found two bugs in the original presentation of the QFT-based modular
multiplier [Beauregard 2003]. The first issue was discovered via random testing and relates to
assumptions about the endianness of stored integers. The binary number in Figure 6 of the paper uses
a little-endian format whereas the rest of the circuit assumes big-endian. Quipper’s implementation
of this algorithm solves the problem by creating a function in their Haskell compiler to reverse the
order of qubits. In Oqasm, we can use the Rev operation (which does not insert SWAPs) to correct
the format of the input binary number.
The second issue was discovered during verification. Beauregard [2003] indicates that the input
𝑥 should be less than 2𝑛 where 𝑛 is the number of bits. However, to avoid failure the input must
actually be less than 𝑁 , where 𝑁 is the modulus defined in Shor’s algorithm. To complete the proof
of correctness, we needed to insert a preprocessing step to change the input to 𝑥%𝑁 . The original
on-paper implementation of the ripple-carry-based modular multiplier [Markov and Saeedi 2012]
has the same issue.
convert many-qubit gates to the one- and two-qubit gates supported by voqc.6 We found during
evaluation that gate counts are highly sensitive to the decompositions used: Using a more naïve
decomposition of the controlled-Toffoli gate (which simply computes the controlled version of
every gate in the standard Toffoli decomposition) increased the size of our Toffoli-based modular
multiplication circuit by 1.9x, and a similarly naïve decomposition of the controlled-controlled-𝑅𝑧
gate increased the size of our QFT-based modular multiplication circuit by 4.4x. We also found that
gate counts (especially for the Toffoli-based circuits) are sensitive to choice of constant parameter:
The QFT-based constant multiplication circuits had between 1320 and 1412 gates, while the Toffoli-
based circuits had between 988 and 2264. Unlike gate counts, qubit counts are more difficult to
optimize because they require fundamentally changing the structure of the circuit; this makes
QFT’s qubit savings for modular multiplication even more impressive.
Overall, our results suggest that QFT-based arithmetic provides better and more consistent
performance, so when compiling Oqimp programs (like the sine function in Figure 13) to Oqasm,
we should bias towards using the QFT-based operators.
Comparing to Quipper. Overall, Figure 16(a)-(c) shows that operator implementations in Oqasm
consume resources comparable to those available in Quipper, often using fewer qubits and gates,
both for Toffoli- and QFT-based operations. In the case of the QFT adder, the difference in results
is because the Quipper-to-OpenQASM converter we use has a more expensive decomposition
of controlled-𝑅𝑧 gates.7 In the other cases (all Toffoli-based circuits), we made choices when
implementing the oracles that improved their resource usage. Nothing fundamental stopped the
Quipper developers from having made the same choices, but we note they did not have the benefit
of the Oqasm type system and PBT framework. Quipper has recently begun to develop a random
testing framework based on QuickCheck [Claessen and Hughes 2000], but it only applies to Toffoli-
based (i.e., classical) gates.
voqc, each Toffoli gate is decomposed into 9 single-qubit gates and 6 two-qubit gates. In contrast, vqo’s decomposition for
controlled-𝑅𝑧 uses 3 single-qubit gates, 2 two-qubit gates, and no ancilla qubits.
Verified Compilation of Quantum Oracles 1:19
|Φ(𝑥𝑛−1 ) ⟩ •
|Φ(𝑥𝑛−2 ) ⟩ QFT−1 𝑁 QFT 𝑁
.. 𝑥 − 2𝐼 −𝑖 𝑛 𝑥 + 2𝐼 −𝑖 𝑛 ..
. .
|Φ(𝑥 0 ) ⟩
|𝑏𝑛−1 ⟩. ...
..
|𝑏 1 ⟩. • ..
.
|𝑏 0 ⟩. .
(a) QFT-based
|Φ(𝑥𝑛−1 ) ⟩ ×
|Φ(𝑥𝑛−2 ) ⟩ QFT−1 RSH QFT (𝑁 − 𝑖 − 1) 𝑥 + (2𝐼 −𝑖 𝑛 mod 2𝐼 −𝑖−1 )
.. 𝑥 − 2𝐼 −𝑖 𝑛 (𝑁 − 𝑖) ..
. .
|Φ(𝑥 0 ) ⟩
|𝑏𝑛−1 ⟩. ...
..
|𝑏 1 ⟩. × • ..
.
|𝑏 0 ⟩. .
(b) AQFT-based (addition and subtraction are approximate)
QFT adder always induces an error of at most ±2𝑏 − 1. This exponential error suggests that the
“approximate adder” is not particularly useful on its own, as it is effectively ignoring the least
significant bits in the computation. However, it computes the most significant bits correctly: if the
inputs are both multiples of 2𝑏 then an approximate adder that drops 𝑏 bits of precision will always
produce the correct result.
Exact Division/Modulo using an Approximate Adder. Even though the approximate adder
is not particularly useful for addition, there are still cases where it can be useful as a subcomponent.
For example, the modulo/division circuit relies on an addition subcomponent, but does not need
every bit to be correctly added.
Figure 19(a) shows one step of an 𝑁 -bit QFT-based modulo circuit that computes 𝑥 mod 𝑛 for
constant 𝑛. The algorithm runs for 𝐼 + 1 iterations, where 2𝑁 −1 ≤ 2𝐼 𝑛 < 2𝑁 , with the iteration
counter 𝑖 increasing from 0 to 𝐼 (inclusive). In each iteration, the circuit in Figure 19(a) computes
𝑥 − 2𝐼 −𝑖 𝑛 and uses the result’s most significant bit (MSB) to check whether 𝑥 < 2𝑁 −1−𝑖 . If the MSB
is 0, then 𝑥 ≥ 2𝑁 −1−𝑖 and the circuit continues to next iteration; otherwise, it adds 2𝐼 −𝑖 𝑛 to the
result and continues.
We can improve the resource usage of the circuit in Figure 19(a) by replacing the addition,
subtraction, and QFT components with approximate versions, as shown in Figure 19(b). At the
1:20 Liyi Li, Finn Voichick, Kesha Hietala, Yuxiang Peng, Xiaodi Wu, and Michael Hicks
start of each iteration, 𝑥 < 2𝑁 −𝑖 , so it is safe to replace components with versions that will perform
the intended operation on the lowest (𝑁 − 𝑖) bits. The circuit in Figure 19(b) begins by subtracting
the top (𝑁 − 𝑖) bits, and then converts 𝑥 back to the Nor basis using an (𝑁 − 𝑖)-bit precision QFT.
It then swaps the MSB with an ancilla, guaranteeing that the MSB is 0. Next, it uses a Rshift to
move the cleaned MSB to become the lowest significant bit (effectively, multiplying 𝑥 by 2) and
uses a (𝑁 − 𝑖 − 1)-bit precision QFT to convert back to the Phi basis. Finally, it conditionally adds
back the top (𝑁 − 𝑖 − 1) bit of the value (2𝐼 −𝑖 𝑛 mod 2𝐼 −𝑖−1 ), ignoring the original MSB.
The result is a division/modulo circuit that uses approximate components, but, as our testing
assures, is exactly correct. Figure 18(b) shows the required resources for varying numbers of
iterations. Compared to the QFT-based circuit, for a single iteration, the approximation provides a
4.5% savings. And the saving increases with more iterations. In the case of the maximum number
of iterations (16 for 𝑛 = 1), the AQFT-based division/modulo circuit uses 61.1% fewer gates than the
QFT-based implementation and 79.3% fewer gates than the Toffoli-based implementation.
outputs depending on whether 𝑥 and 𝑦 are constants. If they both are constant, Oqimp simply
𝑥∗𝑦
assigns the result of computing 𝑀 to a quantum variable. If 𝑥 is a constant, but 𝑦 is not, Oqimp
𝑥
evaluates 𝑀 classically, assigns the value to 𝑟 1 , and evaluates 𝑟 2 using a constant multiplication
circuit. If they are both quantum variables, Oqimp generates a circuit to evaluate the division first
and then the multiplication.
𝑥∗𝑦
In Figure 20 (a) we show the size of the circuit generated for 𝑀 where zero, one, or both
variables are classically known. It is clear that more classical variables in a program lead to a more
efficient output circuit. If 𝑥 and 𝑦 are both constants, then only a constant assignment circuit is
needed, which is a series of X gates. Even if only one variable is constant, it may lead to substantial
savings: In this example, if 𝑥 is constant, the compiler can avoid the division circuit and use a
constant multiplier instead of a general multiplier. These savings quickly add up: Figure 20 (b)
shows the qubit size difference between our implementation of sine and Quippers’. Both the TOFF
and QFT-based circuits use fewer than 7% of the qubits used by Quipper’s sine implementation. 8
8 Oqimp also benefits from its representation of fixed-precision numbers (Section 4.3), which is more restrictive than
Quipper’s. Our representation of fixed-precision numbers reduces the qubit usage of the sine function by half, so about half
of the qubit savings can be attributed to this.
Verified Compilation of Quantum Oracles 1:21
# qubits # gates
OQIMP (𝑥, 𝑦 const) 16 16
OQIMP TOFF (𝑥 const) 33 1739 ± 376 # qubits
OQIMP QFT (𝑥 const) 16 1372 ± 26 OQIMP TOFF 418
OQIMP TOFF 33 61470 OQIMP QFT 384
OQIMP QFT 32 25609 Quipper 6142
𝑥∗𝑦
(a) Fixed-precision circuits for 𝑀 with 𝑀 = 5 (16 bits) (b) Sine circuits (64 bits)
8 RELATED WORK
Oracles in Quantum Languages. Quantum programming languages have proliferated in re-
cent years. Many of these languages (e.g. Quil [Rigetti Computing 2019], OpenQASM 2.0 [Cross et al.
2017], sqir [Hietala et al. 2021b]) describe low-level circuit programs and provide no abstractions for
describing quantum oracles. Higher-level languages may provide library functions for performing
common oracle operations (e.g. Q# [Microsoft 2017], Scaffold [Abhari et al. 2012; Litteken et al.
2020]) or support compiling from classical programs to quantum circuits (e.g. Quipper [Green
1:22 Liyi Li, Finn Voichick, Kesha Hietala, Yuxiang Peng, Xiaodi Wu, and Michael Hicks
et al. 2013]), but still leave some important details (like uncomputation of ancilla qubits) to the
programmer.
There has been some work on type systems to enforce that uncomputation happens correctly (e.g.
Silq [Bichsel et al. 2020]), and on automated insertion of uncomputation circuits (e.g. Quipper [Green
et al. 2013], Unqomp [Paradis et al. 2021]), but while these approaches provide useful automation,
they also lead to inefficiencies in compiled circuits. For example, all of these tools force compilation
into the classical gate set X, CNOT, and CCNOT (or “Toffoli”), which precludes the use of QFT-based
arithmetic, which uses fewer qubits than Toffoli-based approaches. Of course, programmers are not
obligated to use automation for constructing oracles—they can do it by hand for greater efficiency—
but this risks mistakes. vqo allows programmers to produce oracles automatically from Oqimp using
inv to uncompute, or to manually implement oracle functions in Oqasm, in both cases supporting
formal verification and testing.
Verified Compilation of Quantum Programs. Recent work has looked at verified optimiza-
tion of quantum circuits (e.g., voqc [Hietala et al. 2021b], CertiQ [Shi et al. 2019]), but the problem
of verified compilation from high-level languages to quantum circuits has received less attention.
The only examples of verified compilers for quantum circuits are ReVerC [Amy et al. 2017] and
ReQWIRE [Rand et al. 2018]. Both of these tools support verified translation from a low-level
Boolean expression language to circuits consisting of X, CNOT, and CCNOT gates. Compared to these
Verified Compilation of Quantum Oracles 1:23
tools, vqo supports both a higher-level classical source language (Oqimp) and a more interesting
quantum target language (Oqasm).
9 CONCLUSION
We present vqo, a framework for expressing, testing, and verifying quantum oracles. The key
component of vqo is Oqasm, the oracle quantum assembly language, which can express a restricted
class of quantum programs that are efficiently simulatable (and hence testable) and are useful
for implementing quantum oracles. We have verified the translator from Oqasm to sqir and
have verified (or randomly tested) many arithmetic circuits written in Oqasm. We also present
Oqimp, a high-level imperative language, and compiler from Oqimp to Oqasm (framework verified
and arithmetic operations randomly tested). We have used vqo to implement oracles and oracle
components useful in quantum programming, like modular multiplication and sine, and showed
that our performance is comparable to the state-of-the-art (unverified) framework Quipper. We also
demonstrated the benefit of partial evaluation in Oqimp, showing that partial evaluation results in
our implementation of sine using just 7% of the qubits used in Quipper’s implementation.
ACKNOWLEDGMENTS
We thank Leonidas Lampropoulos for helping us with effective use of QuickChick, and Aaron
Green and Robert Rand for helpful comments and contributions during the development of this
work. This material is based upon work supported by the U.S. Department of Energy, Office of
Science, Office of Advanced Scientific Computing Research, Quantum Testbed Pathfinder Program
under Award Number DE-SC0019040, and the Air Force Office of Scientific Research under Grant
No. FA95502110051.
REFERENCES
Ali Abhari, Arvin Faruque, Mohammad Javad Dousti, Lukas Svec, Oana Catu, Amlan Chakrabati, Chen-Fu Chiang, Seth
Vanderwilt, John Black, Frederic Chong, Margaret Martonosi, Martin Suchara, Ken Brown, Massoud Pedram, and Todd
Brun. 2012. Scaffold: Quantum Programming Language. Technical Report. Princeton University.
Matthew Amy, Martin Roetteler, and Krysta M. Svore. 2017. Verified Compilation of Space-Efficient Reversible Circuits. In
Computer Aided Verification, Rupak Majumdar and Viktor Kunčak (Eds.). Springer International Publishing, Cham, 3–21.
Adriano Barenco, Artur Ekert, Kalle-Antti Suominen, and Päivi Törmä. 1996. Approximate quantum Fourier transform and
decoherence. Physical Review A 54, 1 (Jul 1996), 139–146. https://doi.org/10.1103/physreva.54.139
Stephane Beauregard. 2003. Circuit for Shor’s Algorithm Using 2n+3 Qubits. Quantum Info. Comput. 3, 2 (March 2003),
175–185.
Daniel J. Bernstein. 2008. ChaCha, a variant of Salsa20 (The State of the Art of Stream Ciphers). ECRYPT Network of
Excellence in Cryptology, 273–278. https://cr.yp.to/papers.html#chacha
Daniel J. Bernstein. 2010. Grover vs. McEliece. In Post-Quantum Cryptography, Nicolas Sendrier (Ed.). Springer Berlin
Heidelberg, Berlin, Heidelberg, 73–80. https://doi.org/10.1007/978-3-642-12929-2_6
Xiaoning Bian. 2020. Compile Quipper quantum circuit to OpenQasm 2.0 program. https://www.mathstat.dal.ca/~xbian/
QasmTrans/ [Online; accessed 8-July-2021].
Benjamin Bichsel, Maximilian Baader, Timon Gehr, and Martin Vechev. 2020. Silq: A High-Level Quantum Language with
Safe Uncomputation and Intuitive Semantics. In Proceedings of the 41st ACM SIGPLAN Conference on Programming
Language Design and Implementation (London, UK) (PLDI 2020). Association for Computing Machinery, New York, NY,
USA, 286–300. https://doi.org/10.1145/3385412.3386007
Lukas Burgholzer, Hartwig Bauer, and Robert Wille. 2021. Hybrid Schrödinger-Feynman Simulation of Quantum Circuits
With Decision Diagrams. arXiv:2105.07045 [quant-ph]
Christophe Chareton, Sébastien Bardin, François Bobot, Valentin Perrelle, and Benoit Valiron. 2020. Toward Certified
Quantum Programming. arXiv e-prints (2020). arXiv:2003.05841 [cs.PL]
Andrew M. Childs. 2009. On the Relationship Between Continuous- and Discrete-Time Quantum Walk. Communications in
Mathematical Physics 294, 2 (Oct 2009), 581–603.
Koen Claessen and John Hughes. 2000. QuickCheck: A Lightweight Tool for Random Testing of Haskell Programs. In
Proceedings of the Fifth ACM SIGPLAN International Conference on Functional Programming (ICFP ’00). Association for
1:24 Liyi Li, Finn Voichick, Kesha Hietala, Yuxiang Peng, Xiaodi Wu, and Michael Hicks
P.W. Shor. 1994. Algorithms for quantum computation: discrete logarithms and factoring. In Proceedings 35th Annual
Symposium on Foundations of Computer Science. 124–134. https://doi.org/10.1109/SFCS.1994.365700
Rolando Somma. 2020. Are We Ready for Quantum Computers? Scientific American (2020). https://blogs.scientificamerican.
com/observations/are-we-ready-for-quantum-computers
Angela Wilkins. 2021. The Way I See It: The State of Quantum Computing. Rice University (2021). https://news.rice.edu/
news/2021/way-i-see-it-state-quantum-computing
1:26 Liyi Li, Finn Voichick, Kesha Hietala, Yuxiang Peng, Xiaodi Wu, and Michael Hicks
H 𝑅𝑖
H
H 𝑅𝑗 H
.. .. = .. C .. . C . .. C QFT−1 .
..
. . . . .. .. .
H
H 𝑅𝑘
Fig. 22. Example quantum pattern as part of a graph representation in the quantum walk algorithm [Loke
2017]. 𝑅𝑖 is a 𝑧-axis rotation by 2𝜋/2𝑖 (written RZ i in Oqasm+).
{QFT 𝑛} {H}1
Phi 𝑛 Nor Had 𝑛 {H}+=𝑛
{QFT−1 𝑛}
Fig. 23. Typing state machine. Red indicates new additions to Oqasm+.
Fig. 24. Oqasm+ syntax. For an operator OP, OP [−1] indicates that the operator has a built-in inverse available.
Typing:
RZ RRZ RZ-HAD
Ω (𝑥) = Nor 𝑛 < Σ(𝑥) Ω (𝑥) = Nor 𝑛 < Σ(𝑥) Ω (𝑥) = Had 𝑛 𝑚<𝑛
Σ; Ω ⊢ RZ 𝑞 (𝑥, 𝑛) ⊲ Ω Σ; Ω ⊢ RZ−1 𝑞 (𝑥, 𝑛) ⊲ Ω Σ; Ω ⊢ RZ 𝑞 (𝑥, 𝑚) ⊲ Ω
NOR-HAD
Σ; Ω [var(𝜄) ↦→ Nor] ⊢ 𝜄 ⊲ Ω′ Ω′ (var(𝜄)) = Nor
Ω (var(𝜄)) = Had 𝑛 𝑛 ≤ pos(𝜄) < Σ(𝑥)
Σ; Ω ⊢ 𝜄 ⊲ Ω′ [↦→ Had 𝑛]
Semantics:
⟦RZ 𝑚 (𝑥, 𝑖)⟧𝜑 = 𝜑[(𝑥, 𝑖) ↦→ ↑ rz(𝑚, ↓ 𝜑 (𝑥, 𝑖))]
where rz(𝑚, |0⟩) = |0⟩ rz(𝑚, |1⟩) = 𝛼 ( 2𝑚
1
) |1⟩ rz(𝑚, |Φ(𝑟 ) ⟩) = |Φ(𝑟 + 1
2𝑚 )⟩
⟦RZ−1 𝑚 (𝑥, 𝑖)⟧𝜑 = 𝜑[(𝑥, 𝑖) ↦→ ↑ rrz(𝑚, ↓ 𝜑 (𝑥, 𝑖))]
where rrz(𝑚, |0⟩) = |0⟩ rrz(𝑚, |1⟩) = 𝛼 (− 2𝑚
1
) |1⟩ rrz(𝑚, |Φ(𝑟 ) ⟩) = |Φ(𝑟 − 1
2𝑚 )⟩
⟦H (𝑥, 𝑖)⟧𝜑 = 𝜑[(𝑥, 𝑖) ↦→ |Φ( 𝑏2 ) ⟩] where ↓ 𝜑 (𝑥, 𝑖) = |𝑏 ⟩
thus, all allowed Nor gates are permitted. The Oqasm+ semantics extends the Oqasm semantics
(Figure 9) with rules for H and RZ gates, as shown in the bottom of Figure 25.
To support the new Had basis, we extend Definition 3.1 as follows:
Definition A.1 (Well-formed Oqasm state). A state 𝜑 is well-formed, written Σ; Ω ⊢ 𝜑, iff:
• For every 𝑥 ∈ Ω such that Ω(𝑥) = Nor, for every 𝑘 < Σ(𝑥), 𝜑 (𝑥, 𝑘) has the form 𝛼 (𝑟 ) |𝑏⟩.
• For every 𝑥 ∈ Ω such that Ω(𝑥) = Had 𝑛, for every 𝑘 < 𝑛, 𝜑 (𝑥, 𝑘) has the form 𝛼 (𝑏) |Φ(𝑏 ′)⟩;
and for every 𝑛 ≤ 𝑘 < Σ(𝑥), 𝜑 (𝑥, 𝑘) has the form 𝛼 (𝑏) |𝑐⟩.
• For every 𝑥 ∈ Ω such that Ω(𝑥) = Phi 𝑛 and 𝑛 ≤ Σ(𝑥), there exists a value 𝜐 such that for
every 𝑘 < Σ(𝑥), 𝜑 (𝑥, 𝑘) has the form 𝛼 (𝑟 ) |Φ( 2𝑛−𝑘
𝜐
)⟩.
We have re-proved type soundness (Theorem 3.2) for Oqasm+, but the subgroupoid (Theorem 3.3)
and type reversibility (Theorem 3.5) theorems do not hold. We can re-state the quantum summation
formula (Theorem 3.4) as follows, allowing input in the Nor basis and output in the Had basis.
Ë𝑑−1
Theorem A.2. Let |𝑦⟩ be an abbreviation of 𝑚=0 𝛼 (𝑟𝑚 ) |𝑏𝑚 ⟩ for 𝑏𝑚 ∈ {0, 1}. If for every
Í2𝑑 −1 Í2𝑑 −1
𝑖 ∈ [0, 2𝑑 ), ⟦𝜄⟧ |𝑦𝑖 ⟩ = |Φ(𝑟𝑖 )⟩, then ⟦𝜄⟧( 𝑖=0 |𝑦𝑖 ⟩) = 𝑖=0 |Φ(𝑟𝑖 )⟩.
Bitstring 𝑏
Nat. Num 𝑚, 𝑛
Variable 𝑥, 𝑦
Mode 𝑞 ::= 𝐶 |𝑄
Base type 𝜔 ::= bool | fixedp | nat
Type 𝜏 ::= 𝜔 𝑞 | array 𝑛 𝜔 𝑞
Value 𝑣 ::= 𝑙 | (𝜔)𝑏
LValue 𝑙 ::= 𝑥 | 𝑥[𝑣]
Bool Expr 𝑒 ::= 𝑣 < 𝑣 | 𝑣 = 𝑣 | even 𝑣 | ...
Operator 𝑜𝑝 ::= + | − | × | ⊗ | ...
𝑜𝑝
Statement 𝑠 ::= 𝑙 ← 𝑣 𝑜𝑝 𝑣 | 𝑙 ←−− 𝑣 | 𝑙 ←− 𝑣 | 𝑙 ← 𝑓 𝑣¯
| inv 𝑙 | for 𝑥 𝑣 𝑠 | if 𝑒 𝑠 𝑠 | 𝑠 ; 𝑠
FunDef 𝑑 ::= def 𝑓 (𝜔 𝑞 𝑥) { 𝜏 𝑦; 𝑠; return 𝑣 }
Program 𝑃 ::= 𝜏 𝑥; 𝑑
𝜎; 𝑣 −→ 𝑛 Ξ ⊢ 𝜎 [𝑥 ↦→ 0]; 𝑠; 𝑛 −→ 𝜎 ′
Ξ ⊢ 𝜎; 𝑙 ← 𝑣 1 𝑜𝑝 𝑣 2 −→ 𝜎 [𝑙 ↦→ app𝑜𝑝 (𝑣 1, 𝑣 2 )] (bin) (for_t)
Ξ ⊢ 𝜎; for 𝑥 𝑣 𝑠 −→ 𝜎 ′
Ξ ⊢ 𝜎; 𝑠 −→ 𝜎 Ξ ⊢ 𝜎 ; 𝑠; 𝑛 −→ 𝜎
′ ′ ′′
Ξ ⊢ 𝜎; 𝑠; 0 −→ 𝜎 (for_0) Ξ ⊢ 𝜎; 𝑠; S 𝑛 −→ 𝜎 ′′
(for_n)
acts as the “main” function. A function definition 𝑑 declares parameters and local variables; its body
consists of a statement 𝑠; and it concludes by returning a value 𝑣. All variables are initialized as 0.
Variables 𝑥 have types 𝜏, which are either primitive types 𝜔 𝑞 or arrays thereof, of size 𝑛. A
primitive type pairs a base type 𝜔 with a quantum mode 𝑞. There are three base types: type nat
indicates non-negative (natural) numbers; type fixedp indicates fixed-precision real numbers in
the range (−1, 1); and type bool represents booleans. The programmer specifies the number of
qubits to use to represent nat and fixedp numbers when invoking the vqo compiler. We discuss
modes 𝑞 and our rationale for the choice of primitive types, below.
Oqimp statements 𝑠 consist of assignments, loops, conditionals, and sequences of statements, as
is typical. Assignments are always made to lvalues 𝑙, which are either variables or array locations,
and come in four forms. 𝑙 ← 𝑣 𝑜𝑝 𝑣 assigns to 𝑙 the result of applying binary operator 𝑜𝑝 on two
value parameters 𝑣. Values can be either lvalues or literals (𝜔)𝑏, where 𝑏 is a bitstring and 𝜔 is
𝑜𝑝
the base type that indicates its interpretation. 𝑙 ←−− 𝑣 is a unary assignment; it is equivalent to
− 𝑣 initializes 𝑙 to a value. 𝑙 ← 𝑓 𝑣¯ assigns to 𝑙 the result of calling function 𝑓 with
𝑙 ← 𝑙 𝑜𝑝 𝑣. 𝑙 ←
arguments 𝑣¯.
B.2 Semantics
We define a big-step operational semantics for Oqimp; select rules are shown in Figure 27. The
judgment Ξ ⊢ 𝜎; 𝑠 −→ 𝑟 states that under function environment Ξ and input store 𝜎, statement 𝑠
evaluates to result 𝑟 . Here, Ξ is a partial map from function variables 𝑓 to their definitions, and 𝜎 is
a partial map from variables 𝑥 and array locations 𝑥[𝑛] to a history of literal values (𝜔)𝑏. A result
𝑟 is either an output store 𝜎 ′ or a run-time failure Error, which arises due to an out-of-bounds
Verified Compilation of Quantum Oracles 1:29
index or a division by zero. The semantics also defines the standard subsidiary judgments, e.g.,
Ξ; 𝜎 ⊢ 𝑒 −→ (𝜔)𝑏 evaluates 𝑒 under Ξ and 𝜎 to a literal result.
The Oqimp semantics is largely standard except for the treatment of 𝜎: An assignment of 𝑣 to a
𝑄-mode variable 𝑥 pushes 𝑣 to the history 𝜎 (𝑥), and likewise for assignments to 𝑥[𝑛]. Assignment
to a 𝐶-mode variable 𝑥 replaces 𝑥’s history with the singleton [𝑣]. Lookup of 𝑥 returns the topmost
literal of 𝜎 (𝑥), while inv 𝑥 pops off the top element of 𝜎 (𝑥). For example, in Figure 13, executing
the statement 𝑥𝑧 =pow(𝑥 /8, 𝑛 4 ) updates the topmost element of 𝜎 (𝑥𝑧 ) to pow(𝑥 /8, 𝑛 4 ). After the
computation of inv 𝑥𝑧 , this new value for 𝑥𝑧 is erased and the store entry for 𝑥𝑧 reverts to what it
was before. Evaluating 𝑙 ← 𝑓 𝑣¯ performs uncomputation automatically. It amounts to evaluating
𝑓 ’s body 𝑠 (stored in Ξ) under 𝜎 extended with mappings for the function’s parameters to 𝑣¯ and
local variables to 0. When execution of 𝑠 concludes, the returned result will be copied to 𝑙, and the
added mappings will be dropped from the output 𝜎 (effectively uncomputing them). Moreover any
updates to global variables will be reverted, just as if inv had been applied for each modification
thereto. To evaluate a program 𝑃, we populate Ξ with 𝑃’s function definitions, set the initial 𝜎 to
map 𝑃’s global variables to (𝜔)0 (where 𝜔 is extracted from the variable’s declared type), and then
evaluate main’s body 𝑠 (which has no arguments); main’s return 𝑣 is evaluated using the 𝜎 ′ that
results.
B.3 Typing
The semantics of Oqimp defines what a program 𝑃 would do if we ran it directly, but our intention
is not to do this, but to compile 𝑃 to a quantum oracle. We can think of 𝑃 as a computation whose
inputs are the 𝑄-mode global variables; all of the 𝐶-mode globals—and function calls, loops, etc.—
will be inlined away by the compiler, so that what remains can be compiled directly to a quantum
circuit. When that quantum circuit is executed, it will produce the result indicated by the Oqimp
semantics.
To ensure that this is possible, the Oqimp type system restricts how various constructs are used,
based on when their variables are available, as is standard for partial evaluation [Jones et al. 1993].
The Oqimp type system in Figure 28 defines three judgments. The first is Γ ⊢ 𝑣 : 𝜔 𝑞 , which states
1:30 Liyi Li, Finn Voichick, Kesha Hietala, Yuxiang Peng, Xiaodi Wu, and Michael Hicks
that under assumptions Γ, value 𝑣 has primitive type 𝜔 𝑞 ; a similar judgment (not shown) handles
boolean expressions 𝑒. As usual Γ maps variables 𝑥 to types 𝜏. Arrays are not first class, and always
classical, so the array index rule requires the index to have mode 𝐶. Modes 𝑞 are organized as a
lattice with 𝐶 ⊏ 𝑄 for the purposes of subtyping: a value known at compile-time (𝐶) can have its
use deferred to run-time (𝑄) if need be.
The second judgment has form Ξ; Γ; 𝑞 ⊢ 𝑠, which states that in context 𝑞 and under assumptions
Ξ and Γ, statement 𝑠 is well formed. The context 𝑞 indicates the mode of the data that determines
whether the current statement was reached, either classical 𝐶 (compile time) or quantum 𝑄 (run
time). At the outset, the context 𝑞 is 𝐶—the program’s execution depends on no prior result—but
the context can change at a conditional. If the guard 𝑒’s type is bool𝑄 , then which branch executes
depends on a quantum result, so the branches should be checked in mode 𝑄. If the guard 𝑒’s type is
bool𝐶 , then the branches should be checked in the current mode 𝑞. Both notions are captured in a
single rule, with the branches checked in mode 𝑞 ′ ⊔ 𝑞, where 𝑞 ′ is the current mode and 𝑞 is from
the guard’s.
Rule (binop_c) types the assignment to a 𝐶-mode (compile-time) lvalue. Here, both operands
must be 𝐶 mode too, i.e., known at compile time. Such a statement can only be typed in context
𝐶: It will have no run-time effect, so its execution must not be conditional on quantum data. Rule
(binop_q) considers assignments to 𝑄-mode variables, which can occur in any context 𝑞. Both
operands are also in 𝑄 mode (possibly made so through subtyping), and moreover must be different
from the output-variable (𝑙), though the operands can be the same. This restriction is leveraged to
𝑜𝑝
simplify compilation (the 𝑙 ←−− 𝑣 form can be used to update the left-hand side). If both operands
are the same, one is copied out to a temporary register, to avoid violating the no cloning rule.
Rule call checks that the input arguments and the parameters for the function have the same
size, the types are matched, and the return value (𝑣) of the function is a subtype of the to-be-assigned
variable (𝑙).
A for loop may be evaluated in whatever context 𝑞 its body 𝑠 may be evaluated in. During
compilation it will be unrolled, so we require the iterator 𝑥 and the bound value 𝑣 to be type 𝐶.
The rule (fun), which type checks a function, has form Ξ; Γ ⊢ 𝑑 ⊲ Ξ′ where Ξ and Ξ′ are partial
maps from function names to a tuple of (i) a list of function arguments, (ii) a list of declarations
(𝜏 𝑦) in the function, (iii) a function body statement, (iv) the return value for the function, and (v)
a map (Γ) recording the types for variables in the function and global variables declared in the
program. The judgment outputs Ξ′ containing the function information and acting as the new
function environment. gen_Γ(Γ, 𝜏 𝑥@𝜏 𝑦) adds variable-type information to Γ for the two lists 𝜏 𝑥
and 𝜏 𝑦. The list 𝜏 𝑥 should contain only 𝐶-mode variables since we require all function arguments
to be 𝐶 (users can always use global 𝑄-mode variables), while the local declaration list 𝜏 𝑦 contains
𝐶 or 𝑄 mode variables. The type judgment for functions resembles the (fun) rule except that the
input is a list of functions, and the type judgment for the whole program resembles the (call)
rule except that we also need to generate a type environment for global variables.
Well-formedness of inv 𝑥 statements is checked in conjunction with typing, as described in
Section 4.3.
B.4 Soundness
Definition B.1. (Store Consistency) Let 𝑠 be an Oqimp statement and Γ be a type environment
such that Γ ⊢ 𝑠. We say that store 𝑆 is consistent with Γ if and only if for every variable 𝑥 and index
𝑖, if Γ(𝑥) is defined and 𝑖 < sizeof(𝑥), then there exists a value 𝑣, such that 𝑆 (𝑥, 𝑖) = 𝑣.
Type soundness is divided into two parts: progress and preservation. The progress theorem (for
statements) says that every well typed Oqimp program can take a step:
Verified Compilation of Quantum Oracles 1:31
Theorem B.2. (Progress) Let 𝑠 be a well-formed Oqimp statement, and Γ and Γ ′ be type environ-
ments such that Γ ⊢ 𝑠 ⊲ Γ ′. Let 𝑆 be a store that is consistent with Γ ′. Then there exists a 𝑣 such that
Ξ ⊢𝑠 𝑆; 𝑠 −→ 𝑣.
The value 𝑣 above can be an Error state or a final store evaluated from the big-step semantics
for statements (⊢𝑠 ). Because Oqimp uses a big-step operational semantics, it is trivial to prove that
the final type environment after evaluating statement 𝑠 is the same as the input type environment.
We thus choose to prove a different form of preservation related to store consistency:
Theorem B.3. (Preservation) Let 𝑠 be a well-formed Oqimp statement, and Γ and Γ ′ be type
environments such that Γ ⊢ 𝑠 ⊲Γ ′. Let 𝑆 and 𝑆 ′ be stores. If 𝑆 is consistent with Γ and Ξ ⊢𝑠 𝑆; 𝑠 −→ 𝑆 ′,
then 𝑆 ′ is consistent with Γ ′.
The preservation theorem says that if a statement evaluates to a non-Error state with resulting
store 𝑆 ′, then 𝑆 ′ is consistent with the resulting type environment. The proofs of the two theorems
are done by induction on the statement 𝑠; both are mechanized in Coq.
𝑜𝑝 Γ ⊢ 𝑒 : bool𝐶 Ξ ⊢ 𝜎; 𝑒 −→ (bool)true
Γ ⊢ 𝑙 : 𝜔𝐶 Γ ⊢ 𝑣 : 𝜔𝐶 Ξ ⊢𝑠 𝜎; 𝑙 ←−− 𝑣 −→ 𝜎 ′
(bin_c) Ξ; Γ; Θ ⊢ (𝑛, 𝜎, 𝑠 1 ) ⇝ (𝑛 ′, 𝜎 ′, 𝑢) (if_c)
𝑜𝑝
Ξ; Γ; Θ ⊢ (𝑛, 𝜎, 𝑙 ←−− 𝑣) ⇝ (𝑛, 𝜎 ′, ID (Θ(𝑙), 0)) Ξ; Γ; Θ; ⊢ (𝑛, 𝜎, if 𝑒 𝑠 1 𝑠 2 ) ⇝ (𝑛 ′, 𝜎 ′, 𝑢)
Γ ⊢ 𝑒 : bool𝑄 Ξ; Γ; Θ ⊢ (𝑛, 𝜎, 𝑒) ⇝ (𝑛𝑒 , 𝜎𝑒 , 𝑢𝑒 ) Ξ; Γ; Θ ⊢ (𝑛𝑒 , 𝜎𝑒 , 𝑠 1 ) ⇝ (𝑛 1, 𝜎1, 𝑢 1 )
Ξ; Γ; Θ ⊢ (𝑛 1, 𝜎𝑒 , 𝑠 2 ) ⇝ (𝑛 2, 𝜎2, 𝑢 2 ) 𝑢 ′ = 𝑢𝑒 ; CU (𝜒, 𝑛) 𝑢 1 ; X (𝜒, 𝑛) ; CU (𝜒, 𝑛) 𝑢 2 (if_q)
Ξ; Γ; Θ ⊢ (𝑛, 𝜎, if 𝑒 𝑠 1 𝑠 2 ) ⇝ (𝑛 2, 𝜎𝑒 , 𝑢 ′ )
Rule (call) compiles a function call. add_Θ𝑄 extends the Oqimp-to-Oqasm variable map with
the new 𝑄-mode variables in the local declaration list 𝜏 𝑦. The Oqimp type system requires that all
function arguments (𝜏 𝑥) have mode 𝐶. init_𝜎 𝐶 initializes the values of all variables in 𝜏 𝑥 to their
corresponding values in 𝑣 and all 𝐶-mode variables in 𝜏 𝑦 to 0. copy(𝑥, 𝑦) is an Oqasm program
that copies the states of all qubits in 𝑥 to 𝑦 using a series of CU 𝑝𝑥 X 𝑝 𝑦 operations. In the case
where 𝑙 ′ (the return value of 𝑓 ) has mode 𝐶, we do not need to generate a circuit for the function 𝑓 ;
instead, we just generate a circuit to set 𝑙 to the value of 𝑙 ′. If 𝑙 also has mode 𝐶, we just update 𝑙’s
in 𝜎 without generating any circuit.
We prove that compilation is correct: Given an Oqimp program 𝑃 that compiles to an Oqasm
circuit 𝐶, evaluating 𝑃 according to the Oqimp semantics will produce a value consistent with
evaluating 𝐶 according to the Oqasm semantics. The proof is mechanized in Coq and proceeds
by induction on the compilation judgment, relying on proofs of correctness for Oqasm arithmetic
operators, as discussed in Section 4.1.