Tower: Data Structures in Quantum Superposition CHARLES YUAN,MIT CSAIL, USA MICHAEL CARBIN,MIT CSAIL, USA Emerging quantum algorithms for problems such as element distinctness, subset sum, and closest pair demonstrate computational advantages by relying on abstract data structures. Practically realizing such an algorithm as a program for a quantum computer requires an efficient implementation of the data structure whose operations correspond to unitary operators that manipulate quantum superpositions of data. To correctly operate in superposition, an implementation must satisfy three properties Ð reversibility, history independence, and bounded-time execution. Standard implementations, such as the representation of an abstract set as a hash table, fail these properties, calling for tools to develop specialized implementations. In this work, we present Core Tower, the first language for quantum programming with random-access memory. Core Tower enables the developer to implement data structures as pointer-based, linked data. It features a reversible semantics enabling every valid program to be translated to a unitary quantum circuit. We present Boson, the first memory allocator that supports reversible, history-independent, and constant- time dynamic memory allocation in quantum superposition. We also present Tower, a language for quantum programming with recursively defined data structures. Tower features a type system that bounds all recursion using classical parameters as is necessary for a program to execute on a quantum computer. Using Tower, we implement Ground, the first quantum library of data structures, including lists, stacks, queues, strings, and sets. We provide the first executable implementation of sets that satisfies all three mandated properties of reversibility, history independence, and bounded-time execution. CCS Concepts: • Theory of computation→ Data structures design and analysis; • Computer systems organization→ Quantum computing; • Software and its engineering→ Language features; Formal language definitions; Memory management. Additional Key Words and Phrases: quantum programming, data structures, quantum random-access memory, reversible programming, history independence ACM Reference Format: Charles Yuan and Michael Carbin. 2022. Tower: Data Structures in Quantum Superposition. Proc. ACM Program. Lang. 6, OOPSLA2, Article 134 (October 2022), 30 pages. https://doi.org/10.1145/3563297 1 INTRODUCTION Algorithms for quantum computers promise computational advantages in areas ranging from integer factorization [Shor 1997] and search [Grover 1996] to cryptography [Bennett and Brassard 2014], linear algebra [Harrow et al. 2009], physical simulation [Childs et al. 2018; Kassal et al. 2011], and combinatorial optimization [Farhi et al. 2014]. Enabling practical realization of these algorithms 134 on quantum hardware is a major aim of quantum programming languages, in which a developer may write programs that execute on a quantum computer. The principles of quantum mechanics specify how a quantum computer manipulates quantum states consisting of qubits, the quantum analogs of classical bits. A quantum state exists in a Authors’ addresses: Charles Yuan, MIT CSAIL, 32 Vassar St, Cambridge, MA, 02139, USA, chenhuiy@csail.mit.edu; Michael Carbin, MIT CSAIL, 32 Vassar St, Cambridge, MA, 02139, USA, mcarbin@csail.mit.edu. This work is licensed under a Creative Commons Attribution 4.0 International License. © 2022 Copyright held by the owner/author(s). 2475-1421/2022/10-ART134 https://doi.org/10.1145/3563297 Proc. ACM Program. Lang., Vol. 6, No. OOPSLA2, Article 134. Publication date: October 2022. 134:2 Charles Yuan and Michael Carbin superposition, a weighted sum over classical states. The computer may evolve the state using unitary operators, or it may measure the state, which causes a superposition to assume a classical state with probability derived mathematically from the weight ascribed to that state in the sum. 1.1 Data Structures and Quantum Algorithms Existing quantum programming languages [Altenkirch and Grattage 2005; Bichsel et al. 2020; Green et al. 2013; Paykin et al. 2017; Selinger and Valiron 2005; Svore et al. 2018; Wecker et al. 2014] build abstractions for individual qubits and primitive data types such as integers. By contrast, emerging quantum algorithms incorporate abstract data structures for sake of implementation and efficiency. The concrete representation of such a data structure classically is a linked structure in random-access memory, defined recursively and constructed by dynamic allocation. For example, the set data structure can maintain a duplicate-free collection of items, check an element for membership in the collection, and add and remove elements from the collection. Examples of quantum algorithms that depend critically on sets include Ambainis [2003], who presents an 𝑂 (𝑛2/3) quantum algorithm for element distinctness that improves over the Ω(𝑛) classical bound; Bernstein et al. [2013], who present a quantum algorithm for subset sum that beats the classical complexity of 𝑂 (2𝑛/4); and Aaronson et al. [2019], who present an ?̃? (𝑛2/3) quantum algorithm for closest pair, improving over 𝑂 (𝑛 log𝑛) classically. Each of these algorithms relies on an implementation of sets whose operations execute in 𝑂 (log𝑐 𝑛) time. Classically, random-access memory is used to attain this efficient time complex- ity, and these algorithms similarly invoke its quantum analogue. However, to date, no quantum programming language provides abstractions for constructing and manipulating sets and other abstract data types in random-access memory, a hurdle to the realization of these algorithms. 1.2 Three Requirements for Data Structures Importantly, not all classical data structure implementations are compatible with quantum pro- gramming. Ambainis [2003] identifies a data structure appropriate for use in a quantum algorithm as one that satisfies three properties: reversibility, history independence and bounded-time execution. Reversible Operation. The operations of the data structure must each be reversible, meaning it can be executed forwards or backwards to produce or undo its effect on the program state. In order to execute on a quantum computer, a program must first be translated into a sequence of primitive quantum gates. Each gate corresponds to either a measurement or a unitary operator over the program state. Conventional operations over a data structure in superposition cannot safely invoke measurement, because measurement does not preserve the superposition of program data. Instead, it irreversibly collapses the data into a classical state, which would cause algorithms such as Aaronson et al. [2019]; Ambainis [2003]; Bernstein et al. [2013] to return incorrect results. Thus, when a program executes an operation on data in superposition, the operation must correspond to a unitary operator, which has an inverse by definition. As a consequence, the operations of a data structure in superposition must be reversible. History-Independent Representation. The representation of the data structure must be history- independent, meaning that each instance of the data structure is assigned a single unique physical representation in memory that is insensitive to the history of operations performed on it. History independence is essential for the correctness or performance of algorithms such as Aaron- son et al. [2019]; Ambainis [2003]; Bernstein et al. [2013]. The reason is that they rely on quantum interference, the phenomenon in which weights of identical states in a superposition combine or cancel, altering the outcomes of measurements and the output of the algorithm. Proc. ACM Program. Lang., Vol. 6, No. OOPSLA2, Article 134. Publication date: October 2022. Tower: Data Structures inQuantum Superposition 134:3 For example, the algorithm of Ambainis [2003] generates a superposition over sets of integers. Suppose that among these are two instances of the set {1, 2} whose weights in the superposition have equal complex magnitude but opposite sign. Then, the correctness of the algorithm relies on quantum interference to guarantee that the probability of observing the set {1, 2} cancels to zero. However, suppose that sets are concretely represented using linked lists, such that the first instance is represented as [1, 2] and the second as [2, 1]. Because the memory representations of these two instances are physically distinct, their weights do not cancel, leading the algorithm to produce incorrect outputs. Thus, for the algorithm to execute correctly, each semantic instance of an abstract data structure must be assigned a unique underlying physical representation. Bounded-Time Execution. A data structure operation must execute in bounded time, meaning its execution time is bounded by classical parameters not dependent on quantum data. A recursive definition of a data structure typically corresponds to recursive implementations of its operations. Recursion enables an operation to use variable time complexity to traverse and manipulate a variable-sized data structure. However, a quantum computer does not natively support recursive control flow and must first classically convert the program to a loop-free form. Hence, all recursion in the program must be bounded by classically determined parameters. 1.3 Tower: Data Structures in Quantum Superposition Core Tower. We present Core Tower, the first language that enables quantum programming with data in random-access memory. It enables the construction and manipulation of pointer-based, linked data, by means of operations for integers, pointers, and control flow. Reversibility. In Core Tower, every program that can execute forwards can also execute backwards. A developer may compute an expression by assigning it to a variable, or uncompute an expression, which reverses the computation, by un-assigning it from a variable. Other features enable the developer to swap two variables, or to swap a variable with the content of memory at an address. We present a fully reversible operational semantics of Core Tower. Each operator has a reverse within the syntax, meaning a developer may write a program and derive another program with reversed semantics using the syntactic transformation of program inversion. We provide a translation from a valid Core Tower program to a unitary operator that can execute on a quantum computer. Specifically, the operator corresponding to a Core Tower program acts uni- formly across each classical program state in a superposition. The operator may then be embedded within a larger quantum algorithm that creates and manipulates weights of superpositions. Boson. We present Boson, the first memory allocator that enables reversible, history-independent, and constant-time dynamic memory allocation in superposition. A developer may invoke Boson to write a history-independent implementation of a data structure. History Independence. To leverage Boson, the developer constructs dynamically allocated, linked data whose linking structure is in one-to-one correspondence with semantic data structure instances. At runtime, Boson stores data into superpositions of allocation sites that are chosen to guarantee that the instance’s physical memory representation, including the values of pointers, is unique. Classically, a memory allocator may establish history independence by randomizing alloca- tion addresses. The implementation of Boson lifts randomization to quantum superposition via symmetrization, an approach from quantum simulation [Abrams and Lloyd 1997; Berry et al. 2017]. Tower. We combine Core Tower and Boson to build Tower, a programming language for quantum programming with data structures. Tower features co-recursive types and recursive functions that enable the developer to recursively define data structures and operations. Proc. ACM Program. Lang., Vol. 6, No. OOPSLA2, Article 134. Publication date: October 2022. 134:4 Charles Yuan and Michael Carbin Bounded-Time Execution. The type system of Tower ensures that all recursive functions are bounded in size by classical parameters. A Tower program lowers to Core Tower by unrolling recursive calls, meaning that it corresponds to a bounded-size quantum circuit. 1.4 Ground: Data Structure Library We use Tower to implement Ground, the first quantum library of data structures, consisting of lists, stacks, queues, strings, and sets. Of note, we demonstrate the first executable implementation of sets that is reversible, history-independent, and bounded-time, using radix trees [Morrison 1968] as proposed by Bernstein et al. [2013]. Prior to this work, we are not aware of any existing quantum implementation of the set data structure that satisfies all three properties.1 As a case study, we describe three challenges we encountered during the development process that do not arise in classical programming, as well as techniques to overcome them: • Recursive uncomputation means that functions that uncompute the results of recursive calls may incur exponential slowdown in time complexity. We instead structure a program to avoid having recursive calls be temporary values. • Mutated uncomputation means that directly uncomputing temporary variables after the program state has been mutated may result in incorrect outcomes. We instead correctly uncompute values using context from the updated program state. • Branch sequentializationmeans that the time complexity of a conditionally branching quantum program is equal to the sum and not the maximum of its branches. To prevent inefficiency, we structure a program to avoid recursion under branches. 1.5 Contributions In this work, we present the following contributions: • Core Tower (Section 4). We present Core Tower, the first language for quantum programming with random-access memory. We formalize its type system, reversible operational semantics, program inversion transformation, and translation into a unitary quantum circuit. • Boson (Section 5). We present Boson, the first allocator that enables reversible, history- independent, and constant-time dynamic memory allocation in superposition. We present the implementation of Boson using techniques from quantum simulation. • Tower (Section 6). We present Tower, a language that enables bounded-time quantum pro- gramming with recursively defined data structures. We formalize its type system, which verifies that recursion is classically bounded, and its lowering into Core Tower. • Ground (Section 7.2). We present Ground, the first quantum library of abstract data struc- tures, including lists, stacks, queues, strings, and sets. We present the first executable set implementation satisfying reversibility, history independence, and bounded-time execution. • Case Study (Sections 7.3 to 7.5). We characterize three challenges we faced in the library implementation that do not arise in classical programming ś recursive uncomputation, mutated uncomputation, and branch sequentialization ś and techniques to overcome them. Summary. Our work establishes programming abstractions for data structures in quantum superposition in the form of language design and provides the first quantum library of fundamental data structures. Together, Tower, Boson, and Ground enable developers to implement algorithms and construct quantum software utilizing familiar and useful data structures. 1Concurrent to this work, Gidney [2022] provides an implementation of a quantum dictionary data structure. Their implementation does not use random-access memory and achieves linear time complexity, whereas our implementation achieves poly-logarithmic time complexity. Their work was made public while this work was under conference review. Proc. ACM Program. Lang., Vol. 6, No. OOPSLA2, Article 134. Publication date: October 2022. Tower: Data Structures inQuantum Superposition 134:5 2 BACKGROUND ON QUANTUM COMPUTATION The following is an overview of key concepts in quantum computation relevant to this work. A comprehensive reference may be found in Nielsen and Chuang [2010]. Qubit. The basic unit of quantum information is the qubit, a linear combination 𝛾0 |0⟩ + 𝛾1 |1⟩ known as a superposition, where |0⟩ and |1⟩ are basis states and 𝛾0, 𝛾1 ∈ C are amplitudes satisfying |𝛾0 |2 + |𝛾1 |2 = 1 describing relative weights of basis states. Examples of qubits include the classical zero bit |0⟩, classical one bit |1⟩, and the superposition states √1 ( |0⟩ + |1⟩) and √1 (𝑖 |0⟩ − |1⟩). 2 2 Quantum State. A 2𝑛-dimensional quantum state |𝜓 ⟩ is a superposition over 𝑛-bit strings. For example, √1 ( |00⟩ + |11⟩) is a quantum state over two qubits. Multiple qubits form a quantum state 2 system by means of the tensor product ⊗, e.g. the state |01⟩ is equal to the product |0⟩ ⊗ |1⟩. As is standard in quantum computing, we also use the notation |𝑥,𝑦⟩ to represent |𝑥⟩ ⊗ |𝑦⟩. Unitary Operators. A unitary operator 𝑈 is a linear operator on quantum states that preserves inner products and whose inverse is its Hermitian adjoint. Examples of unitary operators include single-qubit quantum gates such as: • X Ð bit-flip (NOT) gate, which maps |0⟩ ↦→ |1⟩ and vice versa; • Z Ð phase-flip gate, which leaves |0⟩ unchanged and maps |1⟩ →↦ − |1⟩; • H Ð Hadamard gate, which maps |0⟩ ↦→ √1 ( |0⟩ + |1⟩) and |1⟩ ↦→ √1 ( |0⟩ − |1⟩). 2 2 Other examples include two-qubit gates, such as controlled-NOT, controlled-Z, and SWAP. The controlled gates perform NOT or Z on their target qubit if their control qubit is in state |1⟩, and the SWAP gate swaps two qubits in a quantum state. Measurement. A quantum measurement is a probabilistic operation over quantum states. When a qubit 𝛾0 |0⟩ + 𝛾1 |1⟩ is measured,2 the outcome is |0⟩ with probability |𝛾 20 | and |1⟩ with probability |𝛾 |21 . Measuring a qubit within a quantum state causes the entire state to probabilistically assume one of two outcome states. To define the outcomes of measuring the first qubit of |𝜓 ⟩, we first rewrite the state into the form |𝜓 ⟩ = 𝛾0 |0⟩ ⊗ |𝜓0⟩ + 𝛾1 |1⟩ ⊗ |𝜓1⟩. Then, with probability |𝛾0 |2 the measurement outcome is |0⟩ ⊗ |𝜓0⟩, and with probability |𝛾 21 | the outcome is |1⟩ ⊗ |𝜓1⟩. Outcomes of measuring multiple qubits or qubits other than the first are defined analogously. Random Access. Quantum random-access memory (qRAM)3 [Giovannetti et al. 2008] enables manipulating data at addresses in superposition. Let 𝑘 be the system word size. The single-qubit quantum random-access gate is defined to be the unitary operation that maps [Ambainis 2003]: |𝑖, 𝑏, 𝑧1, . . . , 𝑧𝑚⟩ ↦→ |𝑖, 𝑧𝑖 , 𝑧1, . . . , 𝑧𝑖−1, 𝑏, 𝑧𝑖+1, . . . , 𝑧𝑚⟩ where 𝑖 is a 𝑘-bit integer, 𝑏 is a bit, and |𝑧𝑖 , . . . , 𝑧𝑚⟩ is the qRAM Ð an array of𝑚 qubits. The effect of this gate is to swap the data at position 𝑖 in the array 𝑧 with the data in the register 𝑏. In this work, we utilize a multi-qubit random-access gate, in which 𝑏 and each 𝑧𝑖 is a 𝑘-bit string rather than a single bit. Such a gate may be implemented as a straightforward extension of leading proposals for hardware qRAM [Arunachalam et al. 2015; Matteo et al. 2020; Paler et al. 2020]. We account for the cost of data structure operations using a model in which quantum random access takes 𝑂 (1) time. This accounting facilitates a direct comparison to the classical RAM cost model, in which dereferencing a pointer is modeled as constant-time regardless of the underlying hardware design. It is possible to use an alternative cost model in which quantum random access 2In this work, we refer only to projective computational (i.e. 0/1) basis measurements. 3The abbreviation qRAM is not to be confused with the QRAM model of computation by Knill [1996], which does not incorporate quantum random access. Proc. ACM Program. Lang., Vol. 6, No. OOPSLA2, Article 134. Publication date: October 2022. 134:6 Charles Yuan and Michael Carbin takes 𝑂 (log𝑚) time, which is used by Aaronson et al. [2019]; Ambainis [2003]; Bernstein et al. [2013]; Buhrman et al. [2021]. To account under this model, the reported complexity of each data structure operation should be multiplied by a poly-logarithmic time factor. 3 QUANTUM DATA STRUCTURES IN TOWER In this section, we present data structures in quantum superposition and justify the properties of reversibility, history independence, and bounded-time execution. We illustrate how a developer uses Tower to implement fundamental data structures satisfying these properties. 3.1 Linked Data in Superposition In classical computing, linked data forms the basis of numerous abstract data structures. For example, linked lists may be used to concretely implement abstract stacks, queues, and sets. We use the notation l ↩→ [1, 2] to represent a classical program state4 in which the variable l denotes a linked list storing the integers 1 and 2. Superposition. In a Tower program, the state of all program variables and memory exists in quantum superposition. For example, the quantum state of the program may be in a uniform superposition of three classical states in which l denotes different linked lists: 1 ( ) 〉 〉 〉 √ l ↩→ [] + l → [1, 2] + ↩ l ↩→ [1, . . . , 100] 3 Data Structure Operations. We may lift a classical operation on a list to a unitary operation on a list in superposition. For example, the operation push_front prepends an element onto every list in the superposition. Executing push_front(l, 6) would produce a new quantum state: 1 ( ) 〉 〉 〉 √ l ↩→ [6] + l ↩→ [6, 1, 2] + l ↩→ [6, 1, . . . , 100] 3 Memory Representation. The memory representation of a singly-linked list is a collection of nodes, each consisting of content data and a pointer to the next node, or null if there is none. Within a classical program state, null denotes the empty list, and a pointer to a memory location at which a pair of 1 and null are stored denotes the singleton list containing the element 1. The program state l ↩→ [1, 2] is depicted by the following diagram, in which denotes null: l 1 2 3.2 Implementing Linked Data Structures in Tower Tower makes it possible to implement linked data structures in quantum superposition. A key aspect of the design of Tower is a set of programming primitives that are each reversible, meaning a program can be executed forwards or backwards to produce or reverse its computational effect. Reversibility. Reversible primitives correspond to unitary operators that can be realized as gates in a quantum computer (Section 2). Though a quantum computer is also capable of performing irreversible measurement, measurement collapses the program state from superposition. Algorithms such as Aaronson et al. [2019]; Ambainis [2003]; Bernstein et al. [2013] are therefore designed to avoid performing measurement on the data structure in superposition, which if performed would cause the algorithm to produce an incorrect output or lose its efficiency advantage. Correspondingly, we designed Tower with reversible primitives that make it possible to manipu- late data structures without collapsing their superposition. 4A classical program state is a bit string, meaning that the set of all program states is finite. Proc. ACM Program. Lang., Vol. 6, No. OOPSLA2, Article 134. Publication date: October 2022. Tower: Data Structures inQuantum Superposition 134:7 1 type list = (uint, ptr); 1 fun pop_front(l: ptr) -> uint { 2 fun push_front(l: ptr, x: uint) { 2 let node <- default; 3 let head <- alloc; 3 *l <-> node; 4 l <-> head; /* Swap */ 4 let head <- node.2; 5 let node <- (x, head); 5 let x <- node.1; /* Get output */ 6 let head -> node.2; /* Uncompute */ 6 let node -> (x, head); 7 *l <-> node; /* Swap */ 7 l <-> head; 8 let node -> default; /* Uncompute */ 8 let head -> alloc; 9 return (); 9 return x; 10 } 10 } Fig. 1. Implementation of push_front. Fig. 2. Implementation of pop_front. node 6 head 0 head 0 head 1 2 l 1 2 l 1 2 l 1 2 l 0 x 6 x 6 x 6 x 6 let head <- alloc(list); l <-> head; let node <- (x, head); (a) Initial state (b) After line 3 (c) After line 4 (d) After line 5 node 6 node 0 1 2 node 0 1 2 head 1 2 l 0 l 6 l 6 x 6 x 6 x 6 let head -> node.2; *l <-> node; let node -> default; (e) After line 6 (f) After line 7 (g) After line 8 Fig. 3. Program states after executing each line of push_front(l, 6), where l denotes [1, 2]. In each step, newly introduced features are shown in red, removed features are shown in gray, and swapped features are shown in green. Features used for computing or uncomputing other features are shown in blue. Implementing push_front. In Figure 1, we present the Tower implementation of the operation push_front on linked lists. When executed forwards, push_front(l, 6) prepends 6 to the list l, and when executed backwards, it removes 6 from the front of l. At a high level, the function initializes a new list node that stores x and points to the input list, and then points l to this node. In Figure 3, we depict the effect of each line of the procedure diagrammatically. In Figure 3a, we show the initial program state of push_front(l, 6), assuming l denotes [1, 2]. In Figure 3b, we depict the effect of line 3, which uses the assignment operator <- to assign the variable head to a new list node in memory, allocated using the alloc operator and initialized to an empty default value. Line 4 (Figure 3c) uses the swap operator <-> to reversibly swap the values of head and l. Line 5 (Figure 3d) assigns node to be a pair of the input x and head. Uncomputation. At this point, the variable head is no longer useful. Line 6 (Figure 3e) uses the un-assignment operator -> to un-assign head from the second field of node, meaning that it uncomputes the value of the variable head and then discards the variable from the program. Uncomputation [Bennett 1973] is the action of reversing the computation that produces the value of a variable, restoring that variable’s value to zero. The reason uncomputation is necessary here is that by the design of Tower, every program is reversible, meaning that 1) a program may only discard a variable after restoring its value to zero, and 2) no language primitive enables the program to generally erase any unspecified value to zero. If the forward execution of the program Proc. ACM Program. Lang., Vol. 6, No. OOPSLA2, Article 134. Publication date: October 2022. 134:8 Charles Yuan and Michael Carbin were permitted to discard or erase an unspecified value, then the reverse execution would be forced to correctly re-materialize that discarded or erased value, which is impossible. On line 6, the program uses the un-assignment operator to restore the value of head to zero.5 Specifically, the effect of line 6 is defined as the reverse of that of the statement: let head <- node.2; An assignment such as this one may be interpreted as a reversible sequence of steps. First, head is initialized to zero. Then, each bit of head is flipped if and only if the corresponding bit of node.2 is set. The result is that the values of head and node.2 are equal. The un-assignment on line 6 may be interpreted as the above sequence of steps in reverse. It starts with head and node.2 having equal values, and performs the same bit flips on head conditioned on node.2. The result is that head has a value of zero, which the program safely discards. Continuing on, line 7 (Figure 3f) swaps node with the contents of memory at address l. Recalling that after line 4, l stores an empty default node, it is then the case that after line 7, l points to the new list head and node stores an empty node, which is then uncomputed by line 8 (Figure 3g). Reversing Operation. The reversibility of Tower programs makes it simple to implement the closely related operation of pop_front, which removes the first element from a list and returns the element. Indeed, the implementation of pop_front is nearly the syntactic reverse of push_front. In Figure 2, we present pop_front. It first reverses line 8 of push_front, replacing un-assignment with assignment, and then line 7, which remains identical Ð the reverse of a swap operation is itself. It reverses line 6 of push_front, assigning the second field of node to head. Line 5 of pop_front is new to this function Ð it obtains x from the first field of node so that x may be returned. The following lines reverse the first three lines of push_front, and the function returns x. 3.3 Dynamic Memory Allocation with Boson Sets are foundational to programming and critical to algorithms. Surprisingly, many implementa- tions of sets such as lists, hash tables, and binary trees are unsuitable for quantum programming. Interference. Algorithms such as Aaronson et al. [2019]; Ambainis [2003]; Bernstein et al. [2013]; Buhrman et al. [2021] rely on interference, the constructive or destructive interaction of amplitudes in a quantum state. For example, Ambainis [2003] generates a superposition over program states s ↩→ 𝑠𝑖 , meaning that variable s stores a set of integers 𝑠𝑖 . The correctness of the algorithm relies on the fact that if 𝑠1 and 𝑠2 denote sets containing the same integers, then their amplitudes interfere. In particular, suppose that 𝑠1 and 𝑠2 both denote the set {1, 2}. Then, the algorithm requires that: 〉 〉 𝛾 s ↩→ 𝑠 1 − 𝛾 s ↩→ 𝑠2 = 0 History Independence. However, suppose that sets are implemented using linked lists, where 𝑠1 is represented as [1, 2] and 𝑠2 as [2, 1]. Because s ↩→ [1, 2] and s ↩→ [2, 1] are physically distinct states, these terms do not cancel, causing the algorithm to produce incorrect outputs. For the algorithm to produce correct outputs, the implementation of the data structure must satisfy the property of history independence. We adapt its definition from Naor and Teague [2001]:6 Definition 3.1 (History Independence). An implementation of an abstract data structure is history- independent if and only if, when any two sequences of abstract operations yield semantically equivalent data structure instances, then the physical representations of the instances are identical. 5Tower also supports other operators that abstract the management of temporary values, which we discuss in Section 6. We focus here on the un-assignment operator for explanatory purposes. 6This definition is termed the łstrongž variant of history independence in the original work. Conceptually similar definitions are found in cryptographic models of computing, such as Wang et al. [2014]. Proc. ACM Program. Lang., Vol. 6, No. OOPSLA2, Article 134. Publication date: October 2022. Tower: Data Structures inQuantum Superposition 134:9 s s 1 fun find_pos[n](l: ptr, x: uint, 1 2 2 1 2 acc: uint) -> uint { 3 with { (a) One possible memory rep- (b) A distinct represen- 4 let node <- default; resentation of s ↩→ [1, 2] . tation of the same state. 5 *l <-> node; 6 let (this_x, next) <- node; 1 √ 7 let r <- acc + 1;s 1 2 6 8 let eq <- this_x == x; 9 } do if eq { + · · · + 10 let out <- acc; 11 } else { 1 √ s 2 1 12 let out <- find_pos[n-1](next, x, r); 6 13 } 14 return out; (c) Boson’s unique superposition representation. 15 } Fig. 4. Distinct physical memory representations of Fig. 5. Implementation of find_pos. the same program state in a qRAM of size 6. The implementation of a set as an unsorted linked list is not history-independent, as the lists [1, 2] and [2, 1] both represent the same set {1, 2}. Similarly, implementations of sets such as balanced binary trees or hash tables7 are not history-independent and are thus unsuitable for use in quantum algorithms that leverage interference on data structures. Unique Linking Structure. A history-independent implementation must assign each semantic instance of the data structure a unique linking structure in the underlying representation. For example, suppose a set is instead implemented as a sorted list without duplicates. The set {1, 2} is then uniquely represented as the list [1, 2], ostensibly satisfying history independence. Memory Addresses. However, a unique linking structure does not by itself guarantee history independence. In the example, the issue is that s ↩→ [1, 2] may still refer to physically distinct program states in which the pointers to the linked list nodes take on different values. For example, Figure 4a depicts a program state in which s points to memory location 1, which stores value 1 and a pointer to memory location 3, which stores value 2 and null. Figure 4b depicts a state in which s points to memory location 5, which stores 1 and a pointer to memory location 1, which stores 2 and null. These two program states are physically distinct but semantically equivalent, causing quantum interference to fail. Boson Allocator. We resolve this issue by developing Boson, a memory allocator that ensures that addresses of all dynamic allocations in the program are history-independent. Under Boson, the single unique program state in which s denotes [1, 2] is Figure 4c, in which the linked list nodes are stored in a uniform superposition of all possible allocation sites. Radix Trees. The sorted list implementation of sets has 𝑂 (𝑛) operation complexity, which is asymptotically inefficient. By contrast, Bernstein et al. [2013] propose using a radix tree [Morrison 1968], whose linking structure is in one-to-one correspondence with sets and which supports operations in 𝑂 (log𝑛) time. In this work, we construct an efficient and history-independent implementation of sets by combining the radix tree with the Boson dynamic memory allocator. 7Other reasons why hash tables are unsuitable are 1) removal from a hash table is not directly reversible, and 2) all operations assume their worst case𝑂 (𝑛) rather than average case𝑂 (1) complexity when all recursion is classically unfolded. Proc. ACM Program. Lang., Vol. 6, No. OOPSLA2, Article 134. Publication date: October 2022. 134:10 Charles Yuan and Michael Carbin 3.4 Recursive Data Structure Operations in Tower The last tool needed to implement operations on linked data structures is recursion. We demonstrate recursion in Tower by implementing the function find_pos, which returns the position of an integer x in a list l, assuming it is present in the list. This operation traverses to the end of the list, and a natural implementation performs this traversal recursively. Recursion Bounds. Classically, a recursive call pushes a return address onto the program stack and sets the program counter to the entry point of the function. By contrast, a quantum processor does not possess a program counter or the ability to loop potentially infinitely. All recursive procedures must instead be unrolled to a fixed, classically known depth, and inlined. Tower guarantees that fully unrolling a recursive function is always possible using a classical recursion bound specifying the number of recursion levels. The Tower type system verifies that in a program, all recursive function calls satisfy their respective recursion bound. Implementing find_pos. In Figure 5, we implement find_pos in Tower by recursively traversing l and comparing each element with x. The implementation takes an accumulator argument acc, such that calling the function with zero for acc returns the position of x. On line 1, the bound [n] denotes that find_pos may recursively call itself at most n times. Lines 3ś13 feature a with-do statement, syntactic sugar that facilitates uncomputation. Tower executes this statement by executing the body of with, then the do, then the reverse of the with. In this program, reversing the with-block uncomputes node, this_x, next, r, and eq. Line 5 swaps the contents of memory at address l with an empty node node, and line 6 extracts from node the content this_x and pointer next to the tail. Line 8 computes eq, a flag for whether this_x is equal to x. If it is, line 10 returns the current position, and if it is not, line 12 recursively calls find_pos on the tail of the list, with a recursion bound that has decreased by one. 4 CORE TOWER: REVERSIBLE AND CIRCUIT-BASED SEMANTICS This section presents Core Tower, an imperative programming language that enables quantum programming with random-access memory. The operational semantics of the language is fully reversible, enabling a program to execute forwards or backwards. A Core Tower program admits inversion, which syntactically transforms it into another program with reversed semantics. A program also admits a syntactic translation into a unitary quantum circuit. In Section 6, we extend Core Tower with co-recursive data types and recursion to produce Tower. 4.1 Syntax The syntax of Core Tower consists of types, values, expressions, and statements. Type 𝜏 F () | uint | bool | (𝜏1, 𝜏2) | ptr(𝜏) Value 𝑣 F 𝑥 | () | (𝑥1, 𝑥2) | 𝑛 | true | false | null𝜏 | ptr𝜏 [𝑝] (𝑛 ∈ UInt, 𝑝 ∈ Addr) Expression 𝑒 F 𝑣 | 𝜋1 (𝑥) | 𝜋2 (𝑥) | 𝑢𝑜𝑝 𝑥 | 𝑥1 𝑏𝑜𝑝 𝑥2 Operator 𝑢𝑜𝑝 F not | test 𝑏𝑜𝑝 F && | || | + | - | * Statement 𝑠 F skip | 𝑠1; 𝑠2 | 𝑥 ← 𝑒 | 𝑥 → 𝑒 | 𝑥1 ⇔ 𝑥2 | ∗𝑥1 ⇔ 𝑥2 | if 𝑥 then 𝑠 end Types. The types 𝜏 are unit, unsigned integers, Booleans, products, and pointers. Values. The language distinguishes syntactic values 𝑣 , which are variables, unit, pairs of variables, numeric, Boolean, and pointer literals. Numeric literals 𝑛 are elements of a set UInt of unsigned integers in the range [0, 2𝑘 − 1] and pointer literals 𝑝 are elements of a set Addr of addresses in the range [1, 2𝑘 − 1], where the parameter 𝑘 is the word size of the system. Proc. ACM Program. Lang., Vol. 6, No. OOPSLA2, Article 134. Publication date: October 2022. Tower: Data Structures inQuantum Superposition 134:11 TV-Var TV-Pair TV-Num TV-Bool Γ ⊢ 𝑥1 : 𝜏1 Γ ⊢ 𝑥2 : 𝜏2 𝑏 ∈ {true, false} Γ, 𝑥 : 𝜏 ⊢ 𝑥 : 𝜏 Γ ⊢ (𝑥1, 𝑥2) : (𝜏1, 𝜏2) Γ ⊢ 𝑛 : uint Γ ⊢ 𝑏 : bool TV-Null TV-Ptr TE-Proj TE-Not Γ ⊢ 𝑥 : (𝜏1, 𝜏2) Γ ⊢ 𝑥 : bool Γ ⊢ null𝜏 : ptr(𝜏) Γ ⊢ ptr𝜏 [𝑝] : ptr(𝜏) Γ ⊢ 𝜋𝑖 (𝑥) : 𝜏𝑖 Γ ⊢ not 𝑥 : bool TE-Test TE-Lop TE-Aop Γ ⊢ 𝑥 : 𝜏 Γ ⊢ 𝑥1 : bool Γ ⊢ 𝑥2 : bool Γ ⊢ 𝑥1 : uint Γ ⊢ 𝑥2 : uint 𝜏 ∈ {uint, ptr(𝜏 ′)} 𝑏𝑜𝑝 ∈ {&&, ||} 𝑏𝑜𝑝 ∈ {+, -, *} Γ ⊢ test 𝑥 : bool Γ ⊢ 𝑥1 𝑏𝑜𝑝 𝑥2 : bool Γ ⊢ 𝑥1 𝑏𝑜𝑝 𝑥2 : uint Fig. 6. Selected typing rules in Core Tower. The full definition is presented in Appendix A. S-Skip S-Seq S-Assign S-UnAssign Γ ⊢ 𝑠 ′ ′ ′′1 ⊣ Γ Γ ⊢ 𝑠2 ⊣ Γ Γ ⊢ 𝑒 : 𝜏 𝑥 ∉ Γ Γ ⊢ 𝑒 : 𝜏 𝑥 ∉ Γ Γ ⊢ skip ⊣ ′′Γ Γ ⊢ 𝑠1; 𝑠2 ⊣ Γ Γ ⊢ 𝑥 ← 𝑒 ⊣ Γ, 𝑥 : 𝜏 Γ, 𝑥 : 𝜏 ⊢ 𝑥 → 𝑒 ⊣ Γ S-Swap S-MemSwap S-If Γ ⊢ 𝑥1 : 𝜏 Γ ⊢ 𝑥2 : 𝜏 Γ ⊢ 𝑥1 : ptr(𝜏) Γ ⊢ 𝑥2 : 𝜏 Γ ⊢ 𝑠 ⊣ Γ Γ ⊢ 𝑥 : bool 𝑥 ∉ mod(𝑠) Γ ⊢ 𝑥1 ⇔ 𝑥2 ⊣ Γ Γ ⊢ ∗𝑥1 ⇔ 𝑥2 ⊣ Γ Γ ⊢ if 𝑥 then 𝑠 end ⊣ Γ Fig. 7. Well-formation rules for statements in Core Tower. Expressions. Expressions 𝑒 are values, projections, and unary and binary operators. These opera- tors are standard logical and arithmetic operators on Booleans and integers. The operation test tests whether an integer is equal to zero or a pointer is equal to null. Statements. Statements 𝑠 include skip, which has no effect, and composition 𝑠1; 𝑠2 of statements. The assignment statement 𝑥 ← 𝑒 initializes a variable 𝑥 and evaluates 𝑒 , storing the result in 𝑥 . The un-assignment statement 𝑥 → 𝑒 is unique to reversible programming Ð it evaluates 𝑒 in reverse to restore 𝑥 back to its default state, and discards 𝑥 . The swap statement 𝑥1 ⇔ 𝑥2 exchanges the contents of variables 𝑥1 and 𝑥2. The swap-with-memory statement ∗𝑥1 ⇔ 𝑥2 exchanges the contents of memory at address 𝑥1 with the contents of 𝑥2. Finally, the statement if 𝑥 then 𝑠 end has the effect of 𝑠 whenever the condition 𝑥 is true. 4.2 Type System The type system of Core Tower assigns a type to a value or expression and determines whether a statement is well-formed and corresponds to a valid quantum program. Typing. In Figure 6, we define the typing judgments for values and expressions. A context Γ is a mapping from variables 𝑥 to types 𝜏 . The judgment Γ ⊢ 𝑣 : 𝜏 states that under context Γ, the value 𝑣 has type 𝜏 . The judgment Γ ⊢ 𝑒 : 𝜏 states that under Γ, the expression 𝑒 has type 𝜏 . In Figure 7, we define the judgment Γ ⊢ 𝑠 ⊣ ′Γ , stating that under Γ, statement 𝑠 is well-formed and yields new context ′Γ . The statement skip has no effect, and sequencing of 𝑠1 and 𝑠2 composes their effect on the context. Assignment 𝑥 ← 𝑒 is well-defined when Γ does not contain 𝑥 , and produces a context giving 𝑥 the type of 𝑒 . Un-assignment is the reverse, removing 𝑥 from the context. A swap requires its arguments to have the same type, and a swap with memory requires the first argument to be a pointer to the type of the second. Proc. ACM Program. Lang., Vol. 6, No. OOPSLA2, Article 134. Publication date: October 2022. 134:12 Charles Yuan and Michael Carbin SE-Var SE-Pair 𝑅 [𝑥 ′] = 𝑣 · ⊢ 𝑣 : 𝜏 𝑅 [𝑥1] = 𝑣1 𝑅 [𝑥2] = 𝑣2 · ⊢ 𝑣1 : 𝜏1 · ⊢ 𝑣2 : 𝜏2 ⟨𝑥 ′, 𝑅 [𝑥 ← z(𝜏)]⟩ ⇓𝑥 ⟨𝑥 ′, 𝑅 [𝑥 ← 𝑣]⟩ ⟨(𝑥1, 𝑥2), 𝑅 [𝑥 ← (z(𝜏1), z(𝜏2))]⟩ ⇓𝑥 ⟨(𝑥1, 𝑥2), 𝑅 [𝑥 ← (𝑣1, 𝑣2)]⟩ SE-Val SE-Proj SE-Not 𝑣 𝑥 ′≠ 𝑣 ≠ (𝑥1, 𝑥2) · ⊢ 𝑣 : 𝜏 𝑅 [𝑥 ′] = (𝑣1, 𝑣2) · ⊢ 𝑣𝑖 : 𝜏 𝑅 [𝑥 ′] = 𝑏 𝑏 ∈ {true, false} ⟨𝑣, 𝑅 [𝑥 ← z(𝜏)]⟩ ⇓𝑥 ⟨𝑣, 𝑅 [𝑥 ← 𝑣]⟩ ⟨𝜋𝑖 (𝑥 ′), 𝑅 [𝑥 ← z(𝜏)]⟩ ⇓𝑥 ⟨not 𝑥 ′, 𝑅 [𝑥 ← false]⟩ ⇓𝑥 ⟨𝜋 ′𝑖 (𝑥 ), 𝑅 [𝑥 ← 𝑣𝑖 ]⟩ ⟨not 𝑥 ′, 𝑅 [𝑥 ← ¬𝑏]⟩ SE-Lop 𝑅 [𝑥1] = 𝑏1 𝑅 [𝑥2] = 𝑏2 SE-Aop 𝑏𝑜𝑝 ∈ {&&, ||} 𝑏1, 𝑏2 ∈ {true, false} 𝑅 [𝑥1] = 𝑛1 𝑅 [𝑥2] = 𝑛2 𝑏𝑜𝑝 ∈ {+, -, *} ⟨𝑥1 𝑏𝑜𝑝 𝑥2, 𝑅 [𝑥 ← false]⟩ ⇓𝑥 ⟨𝑥1 𝑏𝑜𝑝 𝑥2, 𝑅 [𝑥 ← 0]⟩ ⇓𝑥 ⟨𝑥1 𝑏𝑜𝑝 𝑥2, 𝑅 [𝑥 ← 𝑏1 𝑏𝑜𝑝 𝑏2]⟩ ⟨𝑥1 𝑏𝑜𝑝 𝑥2, 𝑅 [𝑥 ← 𝑛1 𝑏𝑜𝑝 𝑛2]⟩ Fig. 8. Selected forward step rules of expressions in Core Tower. The full definition is presented in Appendix A. An if-statement requires its branch 𝑠 to have no net effect on the context. For reversibility, it requires the condition to be a Boolean that is not modified by 𝑠 , as defined by the judgement: mod(skip) = ∅ mod(𝑥1 ⇔ 𝑥2) = {𝑥1, 𝑥2} mod(𝑠1; 𝑠2) = mod(𝑠1) ∪mod(𝑠2) mod(∗𝑥1 ⇔ 𝑥2) = {𝑥2} mod(𝑥 ← 𝑒) = mod(𝑥 → 𝑒) = {𝑥} mod(if 𝑥 then 𝑠 end) = mod(𝑠) 4.3 Reversible Operational Semantics The operational semantics of Core Tower describes reversible operations that may be lifted to act in superposition over a quantum state. The semantics specifies how the machine state evolves during program evaluation while preserving sufficient information to enable reversibility. Machine State. The semantics transitions over machine states ⟨𝑠, 𝑅,𝑀⟩. Machine states consist of a program 𝑠 , a register file 𝑅 mapping variables to values, and a memory 𝑀 mapping addresses to values. The register file 𝑅 corresponds to the main quantum registers over which we may perform arbitrary gates, while the memory𝑀 corresponds to the qRAM. We use Γ𝑅 to denote the typing context formed by mapping each variable in 𝑅 to the type of the value stored. Default Value. The default value of a type 𝜏 , denoted z(𝜏), is the initial value of a variable of type 𝜏 and corresponds to a convenient memory representation of constant zeroes of appropriate size: z(()) = () z(bool) = false z(ptr(𝜏)) = null𝜏 z(uint) = 0 z((𝜏1, 𝜏2)) = (z(𝜏1), z(𝜏2)) The number of bits required to represent a type is the same across a superposition of values of that type, and can be determined statically. When 𝜏1 and 𝜏2 are represented using the same number of bits, their default values z(𝜏1) and z(𝜏2) are physically identical. For example, 0 and null𝜏 are identical, assuming that integers and pointers are represented using the same number of bits. Forward Evaluation. In Figure 8, we define the forward expression evaluation judgment ⟨𝑒, 𝑅 [𝑥 ← 𝑧]⟩ ⇓𝑥 ⟨𝑒, 𝑅 [𝑥 ← 𝑣]⟩. This judgment states that expression 𝑒 evaluates to value 𝑣 , which is stored in register 𝑥 , whose initial state was 𝑧. This judgment maintains reversibility by ensuring that 1) 𝑒 is not destroyed by evaluation, 2) 𝑣 is stored into a particular location 𝑥 , and 3) the initial state 𝑧 of variable 𝑥 is a constant that remains known after this operation. Proc. ACM Program. Lang., Vol. 6, No. OOPSLA2, Article 134. Publication date: October 2022. Tower: Data Structures inQuantum Superposition 134:13 SS-SeqStep SS-Assign ⟨𝑠1, 𝑅, 𝑀⟩ ↦→ ⟨𝑠′ ′ ′1, 𝑅 , 𝑀 ⟩ Γ𝑅 ⊢ 𝑒 : 𝜏 ⟨𝑒, 𝑅 [𝑥 ← z(𝜏)]⟩ ⇓𝑥 ⟨𝑒, 𝑅 [𝑥 ← 𝑣]⟩ ⟨𝑠1; 𝑠2, 𝑅, 𝑀⟩ →↦ ⟨𝑠′1; 𝑠2, 𝑅′, 𝑀 ′⟩ ⟨𝑥 ← 𝑒, 𝑅,𝑀⟩ ↦→ ⟨skip, 𝑅 [𝑥 ← 𝑣], 𝑀⟩ SS-UnAssign SS-Swap Γ𝑅 ⊢ 𝑒 : 𝜏 ⟨𝑒, 𝑅 [𝑥 ← 𝑣]⟩ ⇑𝑥 ⟨𝑒, 𝑅 [𝑥 ← z(𝜏)]⟩ ⟨𝑥 → 𝑒, 𝑅 [𝑥 ← 𝑣], 𝑀⟩ →↦ ⟨skip, 𝑅, 𝑀⟩ ⟨𝑥1 ⇔ 𝑥2, 𝑅 [𝑥1, 𝑥2 ← 𝑣1, 𝑣2], 𝑀⟩ ↦→ ⟨skip, 𝑅 [𝑥1, 𝑥2 ← 𝑣2, 𝑣1], 𝑀⟩ SS-MemSwapNull SS-MemSwapPtr 𝑅 [𝑥1] = null𝜏 𝑅 [𝑥1] = ptr𝜏 [𝑝] ⟨∗𝑥1 ⇔ 𝑥2, 𝑅, 𝑀⟩ →↦ ⟨skip, 𝑅, 𝑀⟩ ⟨∗𝑥 ′1 ⇔ 𝑥2, 𝑅 [𝑥2 ← 𝑣], 𝑀 [𝑝 ← 𝑣 ]⟩ ↦→ ⟨skip, 𝑅 [𝑥2 ← 𝑣 ′], 𝑀 [𝑝 ← 𝑣]⟩ Fig. 9. Selected forward step rules of statements in Core Tower. The full definition is presented in Appendix A. RS-SeqStep RS-Assign ⟨𝑠 , 𝑅′, 𝑀 ′2 ⟩ ↦→𝑅 ⟨𝑠′2, 𝑅, 𝑀⟩ Γ𝑅 ⊢ 𝑒 : 𝜏 ⟨𝑒, 𝑅 [𝑥 ← 𝑣]⟩ ⇑𝑥 ⟨𝑒, 𝑅 [𝑥 ← z(𝜏)]⟩ ⟨𝑠 ′ ′1; 𝑠2, 𝑅 , 𝑀 ⟩ →↦ 𝑅 ⟨𝑠1; 𝑠′2, 𝑅, 𝑀⟩ ⟨𝑥 ← 𝑒, 𝑅 [𝑥 ← 𝑣], 𝑀⟩ ↦→𝑅 ⟨skip, 𝑅, 𝑀⟩ RS-UnAssign RS-Swap Γ𝑅 ⊢ 𝑒 : 𝜏 ⟨𝑒, 𝑅 [𝑥 ← z(𝜏)]⟩ ⇓𝑥 ⟨𝑒, 𝑅 [𝑥 ← 𝑣]⟩ ⟨𝑥 → 𝑒, 𝑅,𝑀⟩ →↦ 𝑅 ⟨skip, 𝑅 [𝑥 ← 𝑣], 𝑀⟩ ⟨𝑥1 ⇔ 𝑥2, 𝑅 [𝑥1, 𝑥2 ← 𝑣2, 𝑣1], 𝑀⟩ ↦→𝑅 ⟨skip, 𝑅 [𝑥1, 𝑥2 ← 𝑣1, 𝑣2], 𝑀⟩ Fig. 10. Selected reverse step rules of statements in Core Tower. The full definition is provided in Appendix A. The first evaluation rule specifies that evaluating a variable 𝑥 ′ copies its value into a destination variable 𝑥 that starts in default state. The following three rules similarly specify copying a known constant 𝑣 , or a pair of values, or one field of a pair, into 𝑥 . The rules for unary and binary operators update 𝑥 based on a criterion computed from the arguments, and the rule for arithmetic operators updates 𝑥 to an arithmetic result over the arguments. Reverse Evaluation. In Appendix A, we define the reverse expression evaluation judgment ⟨𝑒, 𝑅 [𝑥 ← 𝑣]⟩ ⇑𝑥 ⟨𝑒, 𝑅 [𝑥 ← 𝑧]⟩. This judgment states that given the result 𝑣 of evaluating 𝑒 , stored in variable 𝑥 , we may reverse the evaluation of 𝑒 and restore 𝑥 back to its initial state 𝑧. All rules defining this judgment are reverses of the rules defining the forward evaluation. Forward Step. In Figure 9, we define the forward statement step judgment ⟨𝑠, 𝑅,𝑀⟩ →↦ ⟨𝑠′, 𝑅′, 𝑀 ′⟩. This judgment states that given machine state ⟨𝑅,𝑀⟩, executing statement 𝑠 results in new machine state ⟨𝑅′, 𝑀 ′⟩ and new statement 𝑠′ to be executed next. The first two rules skip the skip statement and execute sequences left to right. The rule 𝑥 ← 𝑒 first allocates a variable 𝑥 in default state, and then forward evaluates 𝑒 , storing the result 𝑣 into 𝑥 . The rule for un-assignment 𝑥 → 𝑒 reverses the evaluation of 𝑒 to restore the state of 𝑥 from 𝑣 back to the default state, and then deallocates 𝑥 . The rule for 𝑥1 ⇔ 𝑥2 exchanges the values of 𝑥1 and 𝑥2 in 𝑅. The rule for swapping with memory at a null pointer has no effect. The rule to swap 𝑥2 with memory at a valid pointer 𝑝 swaps the value of 𝑥2 in 𝑅 with the contents of𝑀 at address 𝑝 . Finally, the two rules for if either transition to the body 𝑠 if the condition passes or to skip if it fails. Proc. ACM Program. Lang., Vol. 6, No. OOPSLA2, Article 134. Publication date: October 2022. 134:14 Charles Yuan and Michael Carbin Reverse Step. In Figure 10, we define the reverse statement step judgment ⟨𝑠, 𝑅′, 𝑀 ′⟩ ↦→ ′𝑅 ⟨𝑠 , 𝑅,𝑀⟩. This judgment states that given machine state ⟨𝑅′, 𝑀 ′⟩, executing statement 𝑠 in reverse results in new machine state ⟨𝑅,𝑀⟩ and new statement 𝑠′ to be executed next. Its rules are the reverse of the forward step. Sequential statements execute from right to left. The roles of 𝑥 ← 𝑒 and 𝑥 → 𝑒 are flipped, with the latter now evaluating 𝑒 forward and the former evaluating backward. Because the reverse of a swap operation is itself, the rules for swap statements are the same. Executing an if in reverse requires reversing its body. 4.4 Soundness We now show that Core Tower satisfies key soundness properties in both execution directions: Definition 4.1 (Valid Machine State). A machine state ⟨𝑠, 𝑅,𝑀⟩ is valid under initial context Γ and final context ′Γ , denoted Γ ⊢ ⟨𝑠, 𝑅,𝑀⟩ ⊣ ′Γ , if and only if ′Γ𝑅 = Γ and Γ ⊢ 𝑠 ⊣ Γ . Theorem 4.2 (Preservation). If ⊢ ⟨𝑠, 𝑅,𝑀⟩ ⊣ ′ and ⟨𝑠, 𝑅,𝑀⟩ ↦→ ⟨𝑠′Γ Γ , 𝑅′, 𝑀 ′⟩, then ′Γ ⊢ ⟨𝑠′, 𝑅′, 𝑀 ′⟩ ⊣ ′′ for some context ′′Γ Γ . Proof. By induction over the forward operational semantics of Core Tower. □ A valid machine state ⟨𝑠, 𝑅,𝑀⟩ fails to make forward progress only if it must execute statement 𝑥 → 𝑒 where 𝑒 does not compute the value of 𝑥 , i.e. 𝑅 = 𝑅′ [𝑥 ← 𝑣] and ⟨𝑒, 𝑅′ [𝑥 ← 𝑣]⟩ ⇑𝑥 ⟨𝑒, 𝑅′ [𝑥 ← z(𝜏)]⟩ fails to hold. We denote this condition ⟨𝑠, 𝑅,𝑀⟩ err and define it in Appendix A. Theorem 4.3 (Progress). Given a machine state ⟨𝑠, 𝑅,𝑀⟩ that is valid under some initial and final contexts, either 𝑠 is skip or ⟨𝑠, 𝑅,𝑀⟩ err or ⟨𝑠, 𝑅,𝑀⟩ ↦→ ⟨𝑠′, 𝑅′, 𝑀 ′⟩ for some 𝑠′, 𝑅′, 𝑀 ′. Proof. By induction over the definition of valid machine states. □ Theorem 4.4 (Reverse Preservation). If ′ ⊢ ⟨𝑠, 𝑅′, 𝑀 ′⟩ ⊣ ′′ and ⟨𝑠, 𝑅′Γ Γ , 𝑀 ′⟩ ↦→𝑅 ⟨𝑠′, 𝑅, 𝑀⟩, then ′ ′Γ ⊢ ⟨𝑠 , 𝑅,𝑀⟩ ⊣ Γ for some context Γ. Proof. By induction over the reverse operational semantics of Core Tower. □ A valid machine state ⟨𝑠, 𝑅′, 𝑀 ′⟩ fails to make reverse progress only if it must execute statement 𝑥 ← 𝑒 where 𝑒 does not compute the value of 𝑥 , defined analogously to the forward case. We denote this condition ⟨𝑠, 𝑅′, 𝑀 ′⟩ err𝑅 and define it in Appendix A. Theorem 4.5 (Reverse Progress). Given a state ⟨𝑠, 𝑅′, 𝑀 ′⟩ that is valid under some initial and final contexts, either 𝑠 is skip or ⟨𝑠, 𝑅′, 𝑀 ′⟩ err𝑅 or ⟨𝑠, 𝑅′, 𝑀 ′⟩ ↦→𝑅 ⟨𝑠′, 𝑅, 𝑀⟩ for some 𝑠′, 𝑅, 𝑀 . Proof. By induction over the definition of valid machine states. □ 4.5 Program Reversibility and Inversion Let the notation→↦ ∗ denote the reflexive transitive closure of ↦→, and similarly ↦→∗𝑅 for ↦→𝑅 . We say that a program 𝑠 terminates in the forward direction when, given a register file 𝑅 and memory 𝑀 , we have ⟨𝑠, 𝑅,𝑀⟩ ↦→∗ ⟨skip, 𝑅′, 𝑀 ′⟩ for some final 𝑅′ and𝑀 ′. We say that 𝑠 terminates in the reverse direction when, given 𝑅′ and𝑀 ′, we have ⟨𝑠, 𝑅′, 𝑀 ′⟩ ↦→∗𝑅 ⟨skip, 𝑅, 𝑀⟩ for some 𝑅 and𝑀 . The following theorem states that every Core Tower program is reversible, meaning that it terminates in the forward direction if and only if it does so in the reverse direction. Theorem 4.6 (Reversibility). ⟨𝑠, 𝑅,𝑀⟩ ↦→∗ ⟨skip, 𝑅′, 𝑀 ′⟩ iff ⟨𝑠, 𝑅′, 𝑀 ′⟩ ↦→∗𝑅 ⟨skip, 𝑅, 𝑀⟩. Proof. Follows from forward and reverse progress and preservation. □ The type system does not statically enforce that a program terminates in the forward direction, and it is the responsibility of the program to correctly uncompute temporary values. Proc. ACM Program. Lang., Vol. 6, No. OOPSLA2, Article 134. Publication date: October 2022. Tower: Data Structures inQuantum Superposition 134:15 Inversion. Given a program 𝑠 , its inversion I[𝑠] is a program whose semantics are reversed: I[skip] = skip I[𝑥 ← 𝑒] = 𝑥 → 𝑒 I[𝑥1 ⇔ 𝑥2] = 𝑥1 ⇔ 𝑥2 I[𝑠1; 𝑠2] = I[𝑠2]; I[𝑠1] I[𝑥 → 𝑒] = 𝑥 ← 𝑒 I[∗𝑥1 ⇔ 𝑥2] = ∗𝑥1 ⇔ 𝑥2 I[if 𝑥 then 𝑠 end] = if 𝑥 then I[𝑠] end The following theorem states that the forward semantics of a program is equivalent to the reverse semantics of its syntactic inversion. Theorem 4.7 (Invertibility). ⟨𝑠, 𝑅,𝑀⟩ →↦ ∗ ⟨skip, 𝑅′, 𝑀 ′⟩ iff ⟨I[𝑠], 𝑅′, 𝑀 ′⟩ ↦→∗𝑅 ⟨skip, 𝑅, 𝑀⟩. Proof. By induction over the definition of inversion. □ 4.6 Quantum Circuit Semantics We now develop a semantics of Core Tower that translates a program 𝑠 to a unitary quantum circuit in order to execute 𝑠 on a quantum computer. Expression Semantics. Given an expression 𝑒 whose forward operational semantics is defined as ⟨𝑒, 𝑅 [𝑥 ← z(𝜏)]⟩ ⇓𝑥 ⟨𝑒, 𝑅 [𝑥 ← 𝑣]⟩, we lift it to a unitary gate𝑈𝑒 that operates on register file 𝑅 and a new register 𝑥 and stores 𝑣 in this register, that is,𝑈𝑒 |𝑅, z(𝜏)⟩ = |𝑅, 𝑣⟩. Each possible expression ś production of constant value, variable reference, projection from a pair, integer arithmetic, and Boolean logic ś can be implemented as a unitary gate manipulating 𝑥 : • A constant value 𝑣 can be reversibly produced by applying the NOT gate on each bit of 𝑥 whose corresponding bit is set in the bit representation of 𝑣 . • A variable 𝑥 ′ may be reversibly copied into 𝑥 by applying the controlled-NOT gate on each bit in 𝑥 conditioned on the corresponding bit of 𝑥 ′. • Projection is analogous to copying a variable, except only one field of the pair is copied. • Integer arithmetic may be reversibly performed through circuit designs such as Cheng and Tseng [2002]; Draper [2000]; Islam et al. [2009]. • Boolean logic may be embedded reversibly into NOT and Toffoli (controlled-controlled-NOT) gates, as established by Fredkin and Toffoli [1982]. Statement Semantics. In Figure 11, we translate a Core Tower statement 𝑠 to a circuit fragment C J𝑠K operating on the register file 𝑅 and memory𝑀 encoded as quantum states. In the circuits, a 𝑘 wire depicted as denotes a 𝑘-bit register representing an individual program value. A wire depicted as denotes a collection of such values, such as 𝑅 and𝑀 . A circuit fragment may be expanded to operate on the entire program state by tensor product with the identity gate. The skip statement translates to the identity circuit that maps a quantum state containing 𝑅 and 𝑀 to itself. Statements 𝑠1 and 𝑠2 are sequenced by concatenating their corresponding circuits C J𝑠1K and C J𝑠2K. An expression 𝑒 is assigned to 𝑥 by initializing a zero register, executing 𝑈𝑒 on |𝑅⟩ and this register, and naming the resulting register 𝑥 . An expression is un-assigned by executing 𝑈 †𝑒 , the inverse of 𝑈𝑒 , producing a register of zeroes that is discarded from the circuit. Variables 𝑥1 and 𝑥2 are swapped using swap gates across their entire bit register representations. A swap with memory is performed by invoking the quantum random access gate (Section 2) on the address 𝑥1, value 𝑥2, and memory𝑀 . For an if-statement, its body C J𝑠K is executed, conditioned on the bit 𝑥 . Soundness. The circuit semantics defines a unitary operator C J𝑠K : |𝑅,𝑀⟩ ↦→ |𝑅′, 𝑀 ′⟩ for each statement 𝑠 . It faithfully represents the operational semantics of the statement in Core Tower: Theorem 4.8 (Semantics Eqivalence). C J𝑠K |𝑅,𝑀⟩ |𝑅′= , 𝑀 ′⟩ iff ⟨𝑠, 𝑅,𝑀⟩ ↦→∗ ⟨skip, 𝑅′, 𝑀 ′⟩ Proof. By induction on the structure of 𝑠 . □ Proc. ACM Program. Lang., Vol. 6, No. OOPSLA2, Article 134. Publication date: October 2022. 134:16 Charles Yuan and Michael Carbin |𝑅,𝑀⟩ |𝑅,𝑀⟩ |𝑅,𝑀⟩ C J𝑠 K C J𝑠 K |𝑅′1 2 , 𝑀 ′⟩ C JskipK C J𝑠1; 𝑠2K (identity circuit) (concatenation) |𝑅⟩ |𝑅⟩ |𝑅⟩ |𝑅⟩ 𝑈 𝑈 †𝑒 𝑒 𝑘 𝑘 |0⟩⊗𝑘 |𝑥⟩ | 𝑘 𝑘𝑥⟩ |0⟩⊗𝑘 C J𝑥 ← 𝑒K C J𝑥 → 𝑒K (execute oracle) (un-execute oracle) 𝑘 | ⟩ 1 𝑘1 𝑥1 |𝑥𝑘 𝑘 1⟩|𝑥 ⟩ |𝑥 ⟩ |𝑥⟩ |𝑥⟩1 1 𝑘 𝑘 〉 | 2 2𝑥2⟩ qRAM ′ 𝑥2 | ⟩ 𝑘 𝑘 | ⟩ |𝑅,𝑀⟩ C J𝑠K |𝑅′𝑥 ,𝑀 ′⟩2 𝑥2 |𝑀⟩ |𝑀 ′⟩ C J𝑥1 ⇔ 𝑥2K C J∗𝑥1 ⇔ 𝑥2K C Jif 𝑥 then 𝑠 endK (swap) (random access) (conditional gate) Fig. 11. Definition of quantum circuit semantics of Core Tower. 5 BOSON: HISTORY-INDEPENDENT QUANTUMMEMORY ALLOCATION In this section, we present Boson, a memory allocator for quantum programs. The task of the allocator is to manage dynamic memory Ð when invoked by the program, it returns a pointer to an available allocation site and updates internal metadata to mark that site as being in use. Boson achieves the goals of reversibility, history independence, and bounded-time execution. Its allocation is reversible, with the reverse being deallocation. It guarantees that allocated data structures are history-independent Ð a data structure with a unique logical linking structure has a unique physical memory representation. Finally, it performs allocation in constant time. To develop Boson, we present in Section 5.1 a core algorithm for allocation based on a free list data structure that is reversible and constant-time. Though this algorithm without modification is not history-independent, as we demonstrate in Section 5.2, we then present symmetrization, Boson’s modification to this algorithm that enables history-independent allocation, in Section 5.3. 5.1 Core Allocation Algorithm To illustrate the core allocation algorithm, we present an example that stores several values in dynamically allocated memory. We assume that the memory consists of a heap of𝑚 words of size 𝑘 , that integers and pointers are word-sized, and that null and zero have identical bit representations. Free List. Boson’s allocation algorithm relies on a free list data structure that tracks the free blocks of memory available to the program and is stored in the unallocated portion of the heap. A pointer to the head of the free list is maintained in a designated allocation register denoted alloc_reg. In Figure 12, we depict the initial state of the allocation register and heap. Before the program executes, Boson constructs this initial state by initializing alloc_reg to null and the blocks of the heap to a sequence [ptr [1], ptr [2], ptr [3], . . . , ptr [𝑚 − 1], null].8 Then, it swaps alloc_reg Proc. ACM Program. Lang., Vol. 6, No. OOPSLA2, Article 134. Publication date: October 2022. Tower: Data Structures inQuantum Superposition 134:17 Address 1 let p1 <- null; 6 let p2 <- null; 0 1 2 3 𝑚 − 1 2 p1 <-> alloc_reg; 7 p2 <-> alloc_reg; alloc _reg · · · 3 *p1 <-> alloc_reg; 8 *p2 <-> alloc_reg; 4 let n1 <- 1; 9 let n2 <- 2; Registers Heap Memory 5 *p1 <-> n1; 10 *p2 <-> n2; Fig. 12. Program state of allocation register and Fig. 13. Program storing two values in allocated mem- heap before program execution. Blocks in gray ory. Highlighted operations of the Boson allocator ob- indicate memory not allocated to the program. tain pointers to allocation sites from the free list. p2 p2 p1 p1 p1 alloc 0 · · · alloc 1 0 · · · alloc_reg _reg _reg 1 2 · · · (a) After line 3, p1 ↩→ 0 . (b) After line 8, p1 ↩→ 1, p2 ↩→ 0 . (c) After line 10, p1 ↩→ 1, p2 ↩→ 2 . Fig. 14. Program states while executing the program in Figure 13 starting from Figure 12. Each allocation yields a block for the program to use and updates the allocation register to the new head of the free list. p2 p1 p1 alloc alloc alloc · · · _reg · · · 0 _reg · · · 2 1_reg (a) Reversed initial free list. (b) After line 3, p1 ↩→ 0 . (c) After line 10, p1 ↩→ 1, p2 ↩→ 2 . Fig. 15. Program states while executing the program in Figure 13 from an alternative initial free list. Compared to Figure 14, this execution begins with a free list that is the reverse of Figure 12. The final state in Figure 15c is semantically equivalent to but physically distinct from Figure 14c, violating history independence. l l l alloc alloc alloc _reg 1 2 · · · _reg 2 · · · _reg · · · l l − − l alloc 2 1 · · · alloc − ≠ 02 · · · alloc_reg _reg _reg · · · (a) Initial state of l. (b) After remove(l, 1), l ↩→ [2] . (c) After remove(l, 2), l ↩→ [] . Fig. 16. Disruption of interference by distinct representations of the empty heap. The program begins from a superposition over [1, 2] and [2, 1] (normalizing amplitudes not shown). It invokes remove to remove 1 and 2 in sequence. In both terms of the superposition, the heap is then empty. However, the free lists have distinct structures. Consequently, interference fails to occur and the program outputs may be corrupted. with the first block of the heap. The effect is that at the start of program execution, the whole heap constitutes the free list, and a pointer to the first free block is stored in alloc_reg. 8The value of the last block is defined to be null so that further allocations return null once memory has been exhausted. Proc. ACM Program. Lang., Vol. 6, No. OOPSLA2, Article 134. Publication date: October 2022. 134:18 Charles Yuan and Michael Carbin alloc _reg · · · l 1 2 · · · + alloc _reg · · · + l 2 1 · · · + · · · + alloc _reg · · · + . . . + l · · · 2 1 Fig. 17. Result of symmetrization on the initial pro- Fig. 18. Unique physical representation of state gram state from Figure 12 (normalizing amplitudes not l ↩→ [1, 2] (normalizing amplitudes not shown), shown). The symmetrized free list exists in a superpo- which stores data in a superposition of all possible sition of all possible permutations. allocation sites and is history-independent. Allocation. In Figure 13, we present a program that stores the values 1 and 2 in memory. Lines 1 to 3 invoke the Boson allocator to obtain a pointer p1 to space allocated for the first value: (1) let p1 <- null initializes p1 to null, and then (2) p1 <-> alloc_reg stores in p1 the address of the first available free block and stores zero in alloc_reg, and then (3) *p1 <-> alloc_reg stores into alloc_reg the value at memory address p1, which is the address of the next available block, and stores zero into memory at address p1. In Figure 14a, we depict the program state after executing line 3. The allocation register now points to the new head of the free list, and p1 points to the newly allocated, zero-initialized word. On lines 6 to 8, the program invokes the allocator again to obtain space to store the second value. In Figure 14b, we depict the state after executing line 8, in which the block to which p1 points has been updated to store 1, and p2 points to another newly allocated and zero-initialized word. Finally, in Figure 14c, we depict the state after line 10, in which p2 now points to the value 2. By virtue of using the free list, allocation takes constant time. Boson deallocates memory by reversing the allocation operation, which has the effect of putting the newly freed block at the head of the free list. To support variable-sized allocation, Boson partitions the heap into sections of blocks whose sizes are different powers of two, and allocates from the appropriate free list. 5.2 Core Algorithm Is Not History-Independent Without modification, the core algorithm does not ensure that data structure representations are history-independent, because the addresses of individual allocations are dependent on the contents of the free list, which vary as the program executes. In Figure 15, we depict how a free list structured differently from Figure 12, which may possibly be found in the middle of executing a program, would cause the execution of Figure 13 to produce a final state distinct from Figure 14c. Quantum interference (Section 3.3) would fail between Figure 14c and Figure 15c even though these program states are semantically equivalent. Interference after Deallocation. As a more extreme and unintuitive example, even after all dynamic memory is deallocated, the representation of the empty heap may cause quantum interference to fail over the remaining register file, leading program outputs to be corrupted.9 9An alternative and equivalent mathematical description of the failure is that quantum entanglement [Nielsen and Chuang 2010] exists between the memory and the register file, meaning that discarding and measuring the memory would cause the quantum state of the register file to catastrophically collapse from superposition. Proc. ACM Program. Lang., Vol. 6, No. OOPSLA2, Article 134. Publication date: October 2022. Tower: Data Structures inQuantum Superposition 134:19 In Figure 16, we present this example. The initial program state is a superposition: 1 ( ) 〉 〉 √ l ↩→ [1, 2] − l ↩→ [2, 1] 2 The program invokes the operation remove, which removes and deallocates an element from l, on the values 1 and 2 in sequence. The result is that all memory is returned to the free list. Because l now always points to an empty list, we would expect quantum interference to occur: 1 ( ) 〉 〉 √ l → [] − ↩ l ↩→ [] = 0 2 However, the physical representations of l ↩→ [] , which necessarily incorporate alloc_reg and the free list stored in memory, differ across the two terms. Thus, quantum interference fails. As demonstrated by these examples, the core allocation algorithm must be modified to prevent the program from producing an incorrect output after memory allocations and deallocations. 5.3 Symmetrization Achieves History Independence We now develop symmetrization, the operation that Boson performs to modify the core allocation algorithm to guarantee history independence. A key idea is that classically, a statistical form of history independence is achieved by making probabilistic choices in the data structure: Definition 5.1 (Statistical History Independence). An implementation of an abstract data structure is statistically history-independent if and only if, when any two sequences of abstract operations yield equivalent data structures, then the distributions of their physical representations are identical. Randomization. Conceivably, the core allocation algorithm of Section 5.1may bemade statistically history-independent by choosing new allocations uniformly at random. Doing so would require ini- tializing the free list to a uniformly randompermutation of the sequence [ptr [1], . . . , ptr [𝑚 − 1]].10 Superposition. Statistical history independence guarantees a unique probability distribution for the physical representation of the heap. However, this property is insufficient for the support of quantum algorithms, since probability distributions do not exist on equal basis with superpositions in quantummechanics Ð interference only occurs between equal superpositions, not probability dis- tributions, of program states [Bell 1964]. Thus, instead of randomization, Boson uses superposition to achieve full, rather than statistical, history independence for the heap. Symmetrization. A single time before the program executes, Boson initializes the free list to a uniform superposition of permutations by invoking a unitary operator that we call symmetrization: ∑︁ | 11, . . . , 𝑛⟩ ↦→ √ |𝜋 (1), . . . , 𝜋 (𝑛)⟩ 𝑛! 𝜋∈Sym(𝑛) The notation |1, . . . , 𝑛⟩ denotes a bit string of length 𝑘𝑛 constituting the concatenation of the 𝑘-bit binary representations of the integers 1 through 𝑛. Theorem 5.2. If the heap is symmetrized before program execution, then after any sequence of allocation and deallocation operations, the representation of the heap is history-independent. Proof. Follows from Theorem 9 in Naor and Teague [2001], replacing equality of probability distributions with equality of superpositions. □ 10Invoking randomness only at initialization means that an allocation immediately following a deallocation will yield the just-deallocated address. This correlation does not violate statistical history independence because the heap always remains in a uniformly random distribution over all possible choices of allocation sites. Proc. ACM Program. Lang., Vol. 6, No. OOPSLA2, Article 134. Publication date: October 2022. 134:20 Charles Yuan and Michael Carbin In Figure 17, we illustrate the result of symmetrization on an empty heap state. Before symmetriza- tion, the free list follows the particular sequence depicted in Figure 12. Afterward, the free list exists in the unique superposition of all possible permutations, preventing the issue from Section 5.2. In Figure 18, we present the unique physical representation of the program state l ↩→ [1, 2] under symmetrization, which stores data in a superposition of all possible allocation sites. This uniqueness satisfies history independence and means that quantum interference occurs correctly. Implementation. Symmetrization is a central component of quantum simulation, in which it imposes bosonic11 exchange symmetry [Liboff 1980] on the list. A multitude of implementations of this operator exist in the simulation literature, including Abrams and Lloyd [1997] and Barenco et al. [1997], who achieve implementations in𝑂 (𝑛2 log2 𝑛) gates; Chiew et al. [2019], in𝑂 (𝑛2 log𝑛) gates; and Berry et al. [2017], in 𝑂 (𝑛 log𝑛 log log𝑛) gates and parallel time 𝑂 (log𝑛 log log𝑛).12 6 TOWER: RECURSIVE DATA STRUCTURE OPERATIONS This section presents Tower, a language with co-recursive types and bounded recursive functions. 6.1 Syntax The syntax of Tower augments Core Tower with new types, expressions and statements, as well as function declarations 𝑑 , recursion bounds 𝛽 , and programs 𝑝 . Recursion bounds enable Tower to guarantee that all programs are bounded by classically known parameters. 𝜏 F · · · | 𝑡 | 𝜈𝑡 .𝜏 Declaration 𝑑 fun 𝑓 𝑏?F (𝑥1 : 𝜏1, . . . , 𝑥𝑘 : 𝜏𝑘 ) → 𝜏 is 𝑠 𝑒 F · · · | alloc(𝜏) | 𝑓 𝛽? (𝑥1, . . . , 𝑥 ′ ′𝑘 ) Bound 𝛽 F 𝑏 | 𝑛 | 𝑏 − 𝑛 (𝑛 ∈ N, 𝑛 ∈ N \ {0}) 𝑠 F · · · | return 𝑥 Program 𝑝 F 𝑑 ;𝑝 | fun main (𝑥 : 𝜏) → 𝜏 ′ is 𝑠 Types. The syntax of Tower introduces type variables denoted 𝑡 as well as co-recursive types 𝜈𝑡 .𝜏 in which the variable 𝑡 may appear in 𝜏 . Expressions. The expression alloc(𝜏) allocates zero-initialized space for a value of type 𝜏 and returns a pointer to that type. The expression 𝑓 𝛽? (𝑥1, . . . , 𝑥𝑘 ) invokes function 𝑓 on arguments 𝑥1, . . . 𝑥𝑘 with recursion bound 𝛽 , or no bound if 𝛽 is absent. Statements. The statement return 𝑥 returns the value of 𝑥 to the caller. Declarations. The declaration fun 𝑓 𝑏? (𝑥1 : 𝜏1, . . . , 𝑥𝑘 : 𝜏𝑘 ) → 𝜏 is 𝑠 declares a function named 𝑓 with recursion bound variable 𝑏 (or no bound if absent), arguments 𝑥1, . . . , 𝑥𝑘 with types 𝜏1, . . . , 𝜏𝑘 respectively, return type 𝜏 , and body 𝑠 . A function body must contain exactly one return statement, as the final statement. Tower permits recursive, but not mutually recursive, functions.13 Bounds. A recursion bound may be a variable 𝑏, a classical integer 𝑛, or their difference. Programs. A program is a series of function declarations followed by the entry point main. 6.2 Type System The type system defines well-formed types and enforces that all recursion is classically bounded. 11Fermionic antisymmetry, which is closely related, additionally flips the sign according to the parity of the permutation 𝜋 . 12Comparable to the complexity of the quantum Fourier transform [Coppersmith 1994]. 13The presented type system of Tower could be modified straightforwardly to support mutual recursion. Proc. ACM Program. Lang., Vol. 6, No. OOPSLA2, Article 134. Publication date: October 2022. Tower: Data Structures inQuantum Superposition 134:21 TE-CallBounded TE-CallNonRecursive 𝛽 = 𝑛 or 𝛽 = 𝑏 or 𝑏 − 𝑛 where fst(Φ[𝑓1]) = 𝑏 𝑓1 ≠ 𝑓2 Φ[𝑓2] = (None, ((𝜏1, . . . , 𝜏𝑘 ), 𝜏)) 𝑓1 ≠ 𝑓2 Φ[𝑓2] = (Some 𝑏2, ((𝜏1, . . . , 𝜏𝑘 ), 𝜏)) Γ ⊢ 𝑥1 : 𝜏1 · · · Γ ⊢ 𝑥𝑘 : 𝜏𝑘 Γ ⊢ 𝑥1 : 𝜏1 · · · Γ ⊢ 𝑥𝑘 : 𝜏𝑘 Φ; Γ ⊢𝑓 𝑓2 (𝑥1, . . . , 𝑥𝑘 ) : 𝜏 𝛽1 Φ; Γ ⊢𝑓 𝑓2 (𝑥1, . . . , 𝑥1 𝑘 ) : 𝜏 TE-CallSelf Φ[𝑓 ] = (Some 𝑏, ((𝜏1, . . . , 𝜏𝑘 ), 𝜏)) Γ ⊢ 𝑥1 : 𝜏1 · · · Γ ⊢ 𝑥𝑘 : 𝜏𝑘 ; ⊢ 𝑓 𝑏−𝑛Φ Γ 𝑓 (𝑥1, . . . , 𝑥𝑘 ) : 𝜏 Fig. 19. Selected typing rules for expressions in Tower. The full definition is presented in Appendix A. Type Formation. In Appendix A, we define the well-formation of types. A context Δ is a set of type variables currently in scope. The judgment Δ ⊢ 𝜏 ok states that under context Δ, the type 𝜏 is well-formed. All rules are standard except the case for co-recursive types, which additionally requires that a type variable 𝑡 may only appear under a pointer indirection. For example, the type of lists of integers is list ≜ 𝜈𝑡 .(uint, ptr(𝑡)), in which we require that the self-reference 𝑡 must occur under a pointer, similarly to structure definitions in C. We interpret co- recursive types equi-recursively. For example, we equate the list type list ≜ 𝜈𝑡 .(uint, ptr(𝑡)) with its unfolding (uint, ptr(list)). In Appendix A, we define the judgment 𝜏1 = 𝜏2, an equivalence relation that is compatible with unfolding co-recursive types. The default value of a co-recursive type, z(𝜈𝑡 .𝜏), is defined to be the default value of its unfolding, z(𝜏 [𝑡 ← 𝜈𝑡 .𝜏]). Recursive Functions. The type system of Tower introduces a function context Φ that maps func- tions to their recursion bound variable (if present), argument list, and return type, and augments the typing judgments with the function context Φ and the function 𝑓 being type-checked. In Figure 19, we define the new typing judgment for expressions. The judgment Φ; Γ ⊢𝑓 𝑒 : 𝜏 states that under function context Φ and context Γ, inside function 𝑓 , expression 𝑒 has type 𝜏 . The type system assigns alloc(𝜏) the type ptr(𝜏). Most of the remaining rules simply add Φ and 𝑓 , and we show only the new rules for function calls. If the function being called, 𝑓2, is not recursive, it must be called with no bound and the correct arguments. If it is recursive, it must be called with a bound, which in turn may refer only to the bound variable of the caller function 𝑓1. In the last rule, the function 𝑓 is making a recursive call to itself, which requires the bound to be smaller than the bound variable 𝑏. In Appendix A, we define the new judgment for well-formation of statements. The judgment Φ; ′Γ ⊢𝑓 𝑠 ⊣ Γ states that under Φ and Γ, inside function 𝑓 , statement 𝑠 is well-formed and yields new context ′Γ . Most of the rules simply add Φ and 𝑓 . The new rule for return requires that the context contains only the returned variable, and yields an empty context. 6.3 Translation into Core Tower Tower’s dynamic semantics is defined by translation into Core Tower. Each statement invoking alloc is replaced with the three Core Tower statements defined in Section 5.1. Each function call, starting from main, is translated by recursively inlining the function body as follows: In the general case, a function call has a specified recursion bound. Given a function call 𝑥 ← 𝑓 𝑛 (𝑥1, . . . , 𝑥𝑘 ), the translator looks up the definition of 𝑓 and renames its arguments and return value to be fun 𝑓 𝑏 (𝑥1 : 𝜏1, . . . , 𝑥𝑘 : 𝜏𝑘 ) → 𝜏 is 𝑠; return 𝑥 . It also renames the local variables of 𝑓 to avoid conflicts with the caller. It then inlines 𝑠 into the caller, replacing instances of 𝑏 with 𝑛. It recursively expands introduced function calls until the recursion bound reaches zero, and it Proc. ACM Program. Lang., Vol. 6, No. OOPSLA2, Article 134. Publication date: October 2022. 134:22 Charles Yuan and Michael Carbin replaces expressions 𝑓 0 (𝑥1, . . . , 𝑥𝑘 ) with z(𝜏). A reverse function call 𝑥 → 𝑓 𝑛 (𝑥1, . . . , 𝑥𝑘 ) is similar, except that the body of 𝑓 is inverted (Section 4.5) before it is inlined. Additional features of Tower, such as with-do blocks, nested expressions, and patterns, also lower into Core Tower and are described in Appendix B. In Appendix C, we provide a detailed example for the translation of a recursive Tower program into Core Tower by the procedure above. Theorem 6.1. In a well-typed program, the process of inlining recursive calls always terminates. Proof. Every recursive call has a bound strictly smaller than the bound of the function definition. A call with bound zero terminates immediately. By induction, all other recursive calls terminate. □ As a result, a well-typed Tower program can be converted into a bounded-size quantum circuit. 6.4 Translation Soundness The soundness and reversibility properties of Tower follow from those of Core Tower. A well- typed Tower program translates to a Core Tower program that is well-typed if coercion between compatible pointer types is additionally permitted. Coercion is used by the implementation of alloc(𝜏) in Section 5.1 to assign a pointer to a free block into a variable of type ptr(𝜏). Since a free block is bitwise compatible with a value of type 𝜏 , such coercion is always safe with respect to the operational and circuit semantics of Core Tower. Theorem 6.2. The inlining of recursive calls and alloc operators in a well-typed Tower program produces a Core Tower program that is well-typed if the coercion of compatible pointers is permitted. Proof. The inlining of alloc(𝜏) is type-correct if coercions are permitted, as discussed above. The type-correctness of the inlining of recursive functions holds by induction on the bound. □ 7 GROUND: DATA STRUCTURE LIBRARY AND CASE STUDY This section presents Ground, a library of abstract data structures we implemented in Tower, as well as a case study of development challenges during its implementation. 7.1 Language Implementation To develop the library, we implemented a Tower interpreter in OCaml that classically executes the operational semantics. The type checker ensures that all recursion is bounded, and the interpreter verifies at runtime that 1) values are uncomputed correctly and 2) all heap memory is freed. We also implemented a compiler for Tower into quantum circuits. Given a Tower program, the compiler generates for each function a reversible logic circuit that when executed on a bit- representation of its input stores its output into an auxiliary register. The compiler outputs assembly code that invokes primitive logical, arithmetic, and memory operations. The compiler can further instantiate these primitive operations into multi-controlled-NOT gates. The current implementations of these operations prioritize simplicity; more optimized designs are possible but not yet implemented. The output is in a simple textual netlist format that is amenable to conversion for use in other quantum computation frameworks. The source code of the Tower interpreter and compiler and the Ground library and tests is available in the artifact of this paper [Yuan and Carbin 2022] and on GitHub.14 7.2 Summary of Data Structure Library Table 1 summarizes the Ground data structure library. We implemented the abstract data structures of lists, stacks, queues, strings, and sets.15 In the table, the name of an abstract data structure 14https://github.com/psg-mit/tower-oopsla22 Proc. ACM Program. Lang., Vol. 6, No. OOPSLA2, Article 134. Publication date: October 2022. Tower: Data Structures inQuantum Superposition 134:23 1 fun length[n](l: ptr) -> uint { 1 fun length[n](l: ptr, acc: uint) -> uint { 2 with { 2 with { 3 let l_empty <- l == null; 3 let l_empty <- l == null; 4 } do if l_empty { 4 } do if l_empty { 5 let out <- 0; 5 let out <- acc; 6 } else with { 6 } else with { 7 let temp <- default; 7 let temp <- default; 8 *l <-> temp; 8 *l <-> temp; 9 let next <- temp.2; 9 let next <- temp.2; 10 let r <- length[n-1](next); 10 let r <- acc + 1; 11 } do { 11 } do { 12 let out <- r + 1; 12 let out <- length[n-1](next, r); 13 } 13 } 14 return out; 14 return out; 15 } 15 } Fig. 20. 𝑂 (2𝑛)-time list length. Fig. 21. 𝑂 (𝑛)-time, avoiding recursive uncomputation. is followed by its underlying implementation in parentheses. All implementations are history- independent except for hash table-based sets. The time complexity for certain pointer-based data structures is a function of 𝑛, the number of elements in the data structure. For word-based data structures, the complexity of operations instead scales with the system word size 𝑘 ,16 and becomes polynomial in 𝑘 if the operation performs recursion bounded by 𝑘 and performs operations over words of size 𝑘 at each level. We report the counts of qubits and gates used by the compiled circuit for each operation, including temporary qubits, after minimal optimization. To focus on the fundamental complexity of each operation, these counts exclude 1) the qubits constituting the qRAM, 2) qubits and gates internal to the implementation of primitive logical, arithmetic, and memory operations, and 3) gates to copy and swap qubits, all of which are highly dependent on parameter and optimization choices. For operations with variable complexity, these counts are functions of 𝑛 or 𝑘 . Word sizes 4 ≤ 𝑘 ≤ 12 are assumed for operations whose complexity depends on 𝑘 , and 𝑘 = 8 is assumed otherwise. In Appendix D, we detail the characteristics of each data structure. During the development process, we encountered several challenges that do not arise in classical programming, and share them with future quantum developers. In the following sections, we describe three challenges: recursive uncomputation, mutated uncomputation, and branch sequentialization. 7.3 Challenge 1: Recursive Uncomputation Recursive uncomputation arises when the result of a recursive call is uncomputed, and causes certain programs to incur exponential slowdown in asymptotic time complexity. We must be careful to appropriately craft the implementation to avoid naive implementations that cause this slowdown. In Figure 20, we present a correct but inefficient way to compute the length of a linked list. Line 3 determines if the list l is empty. If so, line 5 sets the output to zero, and if not, lines 7ś9 obtain a pointer next to the tail of the list. Line 10 recursively computes the length of the tail. Line 12 adds one to the result of the recursion. After the do-block completes, Tower reverses the effects of both prior with-blocks to uncompute all temporary variables and restore the original state of the list. Recursive Uncomputation. Though the program in Figure 20 is correct, its time complexity is𝑂 (2𝑛). The reason is that the recursive call on line 10 produces a temporary value r that is uncomputed at 15Maps may be implemented as a straightforward augmentation of sets with values stored alongside each key. 16The word size 𝑘 is in turn logarithmic in the maximum number of elements 𝑛 of the data structure. Proc. ACM Program. Lang., Vol. 6, No. OOPSLA2, Article 134. Publication date: October 2022. 134:24 Charles Yuan and Michael Carbin Table 1. Overview of Ground library. All operations are reversible. łRecursionž denotes whether the operation uses bounded recursion. łMutationž indicates whether it leaves input in a mutated state. łComplexityž indicates its time complexity in terms of the number of elements 𝑛 or the word size 𝑘 . łLoCž counts the lines of code implementing the operation and its dedicated helpers, excluding calls to other operations listed here. łQubitsž counts qubits used, excluding those internal to the qRAM and primitive logic/arithmetic/memory operations. łGatesž counts primitive logic/arithmetic/memory gates invoked, excluding copy/swap gates. Data Structure Reversible Recursion Mutation Complexity LoC Qubits Gates List − length Yes Yes No 𝑂 (𝑛) 20 34𝑛 + 32 23𝑛 + 3 − sum Yes Yes No 𝑂 (𝑛) 20 34𝑛 + 40 21𝑛 + 3 − find_pos Yes Yes No 𝑂 (𝑛) 20 42𝑛 + 31 19𝑛 + 3 − remove Yes Yes Yes 𝑂 (𝑛) 48 26𝑛 + 56 42𝑛 + 3 Stack (list) − push_front Yes No Yes 𝑂 (1) 8 40 4 − pop_front Yes No Yes 𝑂 (1) 8 48 4 Queue (list) − push_back Yes Yes Yes 𝑂 (𝑛) 21 34𝑛 + 32 24𝑛 − pop_front Yes No Yes 𝑂 (1) 8 48 4 String (word) − is_empty Yes No No 𝑂 (1) 2 25 3 − length Yes No No 𝑂 (1) 2 24 1 − get_prefix Yes No No 𝑂 (𝑘) 8 11𝑘 52 − get_substring Yes No No 𝑂 (𝑘) 8 12𝑘 54 − get Yes No No 𝑂 (𝑘) 7 6𝑘 + 1 19 − is_prefix Yes Yes No 𝑂 (poly(𝑘)) 26 𝑘2 + 11𝑘 98𝑘 + 3 − num_matching Yes Yes No 𝑂 (poly(𝑘)) 42 𝑘2 + 13𝑘 + 4 110𝑘 + 127 − equal Yes No No 𝑂 (𝑘) 8 6𝑘 + 3 5 − concat Yes No No 𝑂 (𝑘) 9 11𝑘 8 − compare Yes Yes No 𝑂 (poly(𝑘)) 27 5𝑘2 + 12𝑘 108𝑘 + 3 Set (radix tree) − insert Yes Yes Yes 𝑂 (poly(𝑘)) 136 13𝑘2 + 21𝑘 + 9 1440𝑘2 + 5056𝑘 − contains Yes Yes No 𝑂 (poly(𝑘)) 334 17𝑘2 + 18𝑘 + 2 784𝑘2 + 1612𝑘 + 1 Set (hash table)∗ − insert Yes Yes Yes 𝑂 (𝑛) 63 52𝑛 + 72 68𝑛 + 15 − contains Yes Yes No 𝑂 (𝑛) 7 52𝑛 + 81 136𝑛 + 39 ∗ Hash table-based sets are not history-independent. the end of the do-block. As a result, length makes both a forward and a reverse recursive call at each level, resulting in exponential complexity. Avoiding recursive uncomputation requires not uncomputing the result of recursive calls. One possible approach is inspired by tail recursion from classical programming, where the result of a recursive call is returned without any intervening operations. In Figure 21, we avoid recursive uncomputation using an extra accumulator argument. Line 5 returns the accumulator in the base case. Line 10 adds one to the accumulator, and line 12 recursively calls the function with the new accumulator and directly assigns the result to the output. Calling this function with an initial accumulator of zero returns the length. In the new implemen- tation, no second recursive call is necessary, and the implementation achieves 𝑂 (𝑛) complexity. We encountered this challenge in the implementations of find_pos, length, remove, and sum for lists as well as is_prefix, num_matching, and compare for strings. Proc. ACM Program. Lang., Vol. 6, No. OOPSLA2, Article 134. Publication date: October 2022. Tower: Data Structures inQuantum Superposition 134:25 1 fun contains(t: tree, k: uint) -> bool { 1 fun contains(t: tree, k: uint) -> bool { 2 if t == null { let out <- false; } 2 if t == null { let out <- false; } 3 else if t.1 == k { let out <- true; } 3 else if t.1 == k { let out <- true; } 4 else if t.1 < k { 4 else { 5 let out <- contains(t.2, k); 5 if t.1 < k { let child <- t.2; } 6 } else { 6 else { let child <- t.3; } 7 let out <- contains(t.3, k); 7 let out <- contains(child, k); 8 } 8 } 9 return out; 9 return out; 10 } 10 } Fig. 23. 𝑂 (𝑛)-time binary tree traversal. Fig. 24. 𝑂 (log𝑛)-time, avoiding branch sequentialization. 7.4 Challenge 2: Mutated Uncomputation Mutated uncomputation refers to when uncomputing a temporary value is not straightforward because the program mutates data under conditional branches. The typical strategy of uncomputing a temporary using the expression that originally computed it fails when variables in that expression have been mutated by intervening statements. In Figure 22, we implement the push_back operation, which adds x to the end of l. Line 2 computes the flag l_empty. If it is true, lines 4ś7 allocate a new node storing x and set l to point to it. Otherwise, line 12 extracts the tail of the list, and line 15 recursively calls push_back on it. Mutated Uncomputation. Line 18 uncomputes 1 fun push_back[n](l: ptr, x: uint) { l_empty differently from its computation on line 2. 2 let l_empty <- l == null; The reason is that l may have been modified by 3 if l_empty { line 5, which would break the relationship between 4 let head <- alloc; l and l_empty. Instead, the program uncomputes 5 l <-> head; l_empty based on whether the tail of the new list 6 let head -> null; stored in node is null on line 18, which is true if 7 let node <- (x, null); and only if l_empty was true after line 2. 8 } else { As shown, correctly uncomputing certain values 9 let node <- default; requires reasoning about the invariants that hold 10 *l <-> node; on the program state after mutation. We encoun- 11 with { 12 let (h, tail) <- node; tered this challenge in remove for lists, push_back 13 let node -> (h, tail); for queues, and insert for sets implemented us- 14 } do { ing both hash tables and radix trees. By contrast, 15 let () <- push_back[n-1](tail, x); operations that do not mutate data may typically 16 } uncompute temporaries straightforwardly. 17 } 18 let l_empty -> node.2 == null; 7.5 Challenge 3: Branch Sequentialization 19 *l <-> node; Branch sequentialization denotes the fact that 20 let node -> default; the time complexity of a conditionally branching 21 return (); 22 } quantum program may be larger than its classical equivalent and the developer may need to structure Fig. 22. Implementation of push_back. the program differently to avoid this slowdown. In Figure 23, we present a pseudo-Tower program that traverses a binary search tree. Classically, if t is balanced, then the time complexity of the program is 𝑂 (log𝑛). Branch Sequentialization. However, if Figure 23 is compiled to a quantum circuit (Section 4.6), each if-statement becomes a gate that conditions over the gate translation of the if-body. Each Proc. ACM Program. Lang., Vol. 6, No. OOPSLA2, Article 134. Publication date: October 2022. 134:26 Charles Yuan and Michael Carbin recursive level of the resulting circuit contains a gate that traverses the left child and a gate that traverses the right child, resulting in 𝑂 (𝑛) total complexity. Put simply, the time complexity of a quantum program is the sum and not the maximum of the complexities of its possible branches. Efficiently traversing a branching data structure requires making only one recursive call in the function. In Figure 24, we present a program that performs such a traversal in 𝑂 (log𝑛). We encountered this challenge in radix tree insert and contains, which use a similar approach to attain poly-logarithmic complexity in the number of elements. 8 LIMITATIONS Error Checking. Programming with memory causes numerous errors such as null pointer deref- erence, use after free, and out of memory. Detecting such errors is difficult in quantum programs, which cannot use exceptional control flow. Consequently, Tower defines a dereference of a null pointer to be a no-op and does not dynamically enforce memory safety. Developments in quantum runtime error checking such as Li et al. [2020] may enable detection of memory errors. Memory Management. In Tower, the developer must manually reset and deallocate memory, which raises the possibility of automatic memory reclamation. Unfortunately, classical garbage collection traverses the heap, which has a high time cost. Also, erasing information cannot be performed reversibly without uncomputation, which is difficult after memory has become garbage. Boson incurs internal and external heap fragmentation when allocating variable-sized blocks of memory. Practical dynamic memory management in quantum programs must reconcile space inefficiency of simple allocation schemes with the expense of traversing the heap. 9 RELATED WORK Quantum Programming with Data Structures. The three requirements for data structures in superposition were introduced by Ambainis [2003] and elaborated by Bernstein et al. [2013] and Aaronson et al. [2019], who propose using radix trees [Morrison 1968] to implement sets. These authors also define quantum operations such as creating a superposition of all sets. Other examples of data structures in superposition have been proposed by Booth et al. [2021]; Chen and Movassagh [2021]; Jeffery et al. [2013]; Shi [2021]. They may be distinguished from data structures not in superposition that are accessed by quantum algorithms for tasks such as simulation [Chakraborty et al. 2019] and machine learning [Kerenidis and Prakash 2016]. Péchoux et al. [2020] develop a quantum programming language with inductive data types and recursion. However, in this language it is not possible to construct a superposition over differently linked structures. For example, it is not possible to construct a superposition over linked lists with different lengths, nor over trees with different shapes. Such a restriction is not present in Tower. In fact, this restriction prevents the implementation of a set that satisfies history independence. To illustrate, suppose we implement sets concretely as sorted, duplicate-free linked lists, as in Section 3. Then, if x denotes a set whose state is a superposition of [1, 2] and [1, 3], invoking insert(x, 2) should yield a superposition of [1, 2] and [1, 2, 3]. However, this superposition is over two lists with different lengths, which is not permitted by Péchoux et al. [2020]. Reversible Programming. Janus [Lutz 1986; Yokoyama and Glück 2007] introduced reversible pro- gramming and conditions that are checked after an if-block completes. Consequent developments include Bowman et al. [2011]; Haulund [2017]; Thomsen and Axelsen [2015]. Other applications include bidirectional lenses [Bohannon et al. 2008] and reversible hardware [Vieri 1995]. Reversible Memory Management. Uncomputation [Bennett 1989] has become a central feature of quantum programming languages such as Abraham et al. [2019]; Bichsel et al. [2020]; Svore Proc. ACM Program. Lang., Vol. 6, No. OOPSLA2, Article 134. Publication date: October 2022. Tower: Data Structures inQuantum Superposition 134:27 et al. [2018]. The fact that recursive uncomputation may lead to asymptotic slowdown was noted by Aaronson [2002]. Proposed solutions include whole-program uncomputation [Paradis et al. 2021] and heuristics trading off between space and time [Ding et al. 2020]. Axelsen and Glück [2013] present a reversible free list memory allocator, which inspired parts of Boson but is not history-independent. Buhrman et al. [2022] propose a quantum allocator that traverses a prefix tree stored in qRAM for every allocation. By contrast, Boson symmetrizes the heap once and then performs allocation in constant time. History Independence. Naor and Teague [2001] introduced history independence in the context of privacy and cryptography, in which it guarantees that an adversary with access to the physical memory of a system cannot recover sensitive information about the sequence of events that produced the current state. They present history-independent versions of hash tables and a general scheme for memory allocation that inspired parts of Boson. Later work [Bajaj et al. 2016; Hartline et al. 2002] elaborates the deterministic and statistical forms of history independence and provides additional schemes for history-independent data structure construction. By contrast, oblivious data structures [Wang et al. 2014] guarantee that the memory access patterns, e.g. the sequence of dereferenced pointers, of semantically equivalent data structure operations are identical. Unlike history independence, obliviousness is not necessary for a data structure to operate in superposition. Nevertheless, oblivious techniques such as static and garbled circuits [Yao 1982; Zahur and Evans 2013] and oblivious RAM [Goldreich and Ostrovsky 1996] enable construction of fixed-control-flow data structures and may be useful in the quantum domain. 10 CONCLUSION Data structures establish abstractions over mathematical objects, such as lists and sets, that are taken for granted in the design of algorithms and ubiquitous in classical programming. However, data structure implementations suitable under quantum superposition must satisfy additional properties, and existing quantum programming frameworks do not support their construction. In this work, we introduce Tower, a language for quantum programming with data structures, and Boson, a memory allocator that operates in quantum superposition, along with Ground, a library of abstract data structures, including the first implementation of the set data structure satisfying the requirements laid out by quantum algorithms. We hope that the library will be useful for quantum developers and that Tower and Boson will lead to even more useful abstractions. Unlocking the potential of quantum computation rests on our ability to leverage the accumulated wisdom of algorithm and software design while grappling with physical and practical constraints that are unfamiliar to classical developers. As we have shown, understanding classically-motivated principles of computing, such as history independence, allows us to build bridges to abstractions such as data structures that will enable scalable and accessible quantum software. ACKNOWLEDGMENTS Wewould like to thank JesseMichel, LoganWeber, Tian Jin, and anonymous reviewers who provided feedback on drafts of this paper.We thank Scott Aaronson for directing us to the quantum algorithms that were critical to the motivation of this work. We also give special thanks to Chris McNally for invaluable discussions on the nature of quantum random-access memory, and introducing to the authors the physical concept of exchange symmetry. This work was supported in part by the MIT-IBM Watson AI Lab and the Sloan Foundation. Any opinions, findings, and conclusions or recommendations expressed in this material are those of the authors and do not necessarily reflect the views of the funding agencies. Proc. ACM Program. Lang., Vol. 6, No. OOPSLA2, Article 134. Publication date: October 2022. 134:28 Charles Yuan and Michael Carbin REFERENCES Scott Aaronson. 2002. Quantum Lower Bound for Recursive Fourier Sampling. https://doi.org/10.48550/ARXIV.QUANT- PH/0209060 arXiv:0209060 [quant-ph] Scott Aaronson, Nai-Hui Chia, Han-Hsuan Lin, Chunhao Wang, and Ruizhe Zhang. 2019. On the Quantum Complexity of Closest Pair and Related Problems. arXiv:1911.01973 [quant-ph] Héctor Abraham et al. 2019. Qiskit: An Open-source Framework for Quantum Computing. Daniel S. Abrams and Seth Lloyd. 1997. Simulation of Many-Body Fermi Systems on a Universal Quantum Computer. Phys. Rev. Lett. 79 (Sep 1997). Issue 13. https://doi.org/10.1103/PhysRevLett.79.2586 T. Altenkirch and J. Grattage. 2005. A Functional Quantum Programming Language. In IEEE Symposium on Logic in Computer Science. https://doi.org/10.1109/LICS.2005.1 Andris Ambainis. 2003. Quantum walk algorithm for element distinctness. arXiv:0311001 [quant-ph] Srinivasan Arunachalam, Vlad Gheorghiu, Tomas Jochym-O’Connor, Michele Mosca, and Priyaa Varshinee Srinivasan. 2015. On the robustness of bucket brigade quantum RAM. New Journal of Physics 17, 12 (Dec 2015). https://doi.org/10.1088/1367- 2630/17/12/123010 Holger Bock Axelsen and Robert Glück. 2013. Reversible Representation and Manipulation of Constructor Terms in the Heap. In Reversible Computation, Gerhard W. Dueck and D. Michael Miller (Eds.). Sumeet Bajaj, Anrin Chakraborti, and Radu Sion. 2016. Practical Foundations of History Independence. IEEE Transactions on Information Forensics and Security 11, 2 (2016). https://doi.org/10.1109/TIFS.2015.2491309 Adriano Barenco, André Berthiaume, David Deutsch, Artur Ekert, Richard Jozsa, and Chiara Macchiavello. 1997. Stabilization of Quantum Computations by Symmetrization. SIAM J. Comput. 26, 5 (1997). https://doi.org/10.1137/S0097539796302452 J. S. Bell. 1964. On the Einstein Podolsky Rosen paradox. Physics 1 (Nov 1964). Issue 3. https://doi.org/10.1103/ PhysicsPhysiqueFizika.1.195 C. H. Bennett. 1973. Logical Reversibility of Computation. IBM Journal of Research and Development 17, 6 (1973). https: //doi.org/10.1147/rd.176.0525 Charles H. Bennett. 1989. Time/Space Trade-Offs for Reversible Computation. SIAM J. Comput. 18, 4 (Aug 1989). https: //doi.org/10.1137/0218053 Charles H. Bennett and Gilles Brassard. 2014. Quantum cryptography: Public key distribution and coin tossing. Theoretical Computer Science 560 (2014). https://doi.org/10.1016/j.tcs.2014.05.025 Daniel J. Bernstein, Stacey Jeffery, Tanja Lange, and Alexander Meurer. 2013. Quantum Algorithms for the Subset-Sum Problem. In Post-Quantum Cryptography. Dominic W. Berry, Mária Kieferová, Artur Scherer, Yuval R. Sanders, Guang Hao Low, Nathan Wiebe, Craig Gidney, and Ryan Babbush. 2017. Improved techniques for preparing eigenstates of fermionic Hamiltonians. npj Quantum Information 4 (2017). https://doi.org/10.1038/s41534-018-0071-5 Benjamin Bichsel, Maximilian Baader, Timon Gehr, and Martin Vechev. 2020. Silq: A High-Level Quantum Language with Safe Uncomputation and Intuitive Semantics. In ACM SIGPLAN Conference on Programming Language Design and Implementation. https://doi.org/10.1145/3385412.3386007 Aaron Bohannon, J. Nathan Foster, Benjamin C. Pierce, Alexandre Pilkiewicz, and Alan Schmitt. 2008. Boomerang: Resourceful Lenses for String Data. In ACM SIGPLAN Symposium on Principles of Programming Languages. https: //doi.org/10.1145/1328438.1328487 Kyle E. C. Booth, Bryan O'Gorman, Jeffrey Marshall, Stuart Hadfield, and Eleanor Rieffel. 2021. Quantum-accelerated constraint programming. Quantum (2021). https://doi.org/10.22331/q-2021-09-28-550 William Bowman, Roshan James, and Amr Sabry. 2011. Dagger Traced Symmetric Monoidal Categories and Reversible Programming. In Workshop on Reversible Computation. Harry Buhrman, Bruno Loff, Subhasree Patro, and Florian Speelman. 2021. Limits of quantum speed-ups for computational geometry and other problems: Fine-grained complexity via quantum walks. arXiv:2106.02005 [quant-ph] Harry Buhrman, Bruno Loff, Subhasree Patro, and Florian Speelman. 2022. Memory Compression with Quantum Random- Access Gates. https://doi.org/10.48550/ARXIV.2203.05599 arXiv:2203.05599 [quant-ph] Shantanav Chakraborty, András Gilyén, and Stacey Jeffery. 2019. The Power of Block-Encoded Matrix Powers: Im- proved Regression Techniques via Faster Hamiltonian Simulation. https://doi.org/10.4230/LIPICS.ICALP.2019.33 arXiv:1804.01973 [quant-ph] Lijie Chen and Ramis Movassagh. 2021. Quantum Merkle Trees. https://doi.org/10.48550/ARXIV.2112.14317 arXiv:2112.14317 [quant-ph] K-W Cheng and C-C Tseng. 2002. Quantum full adder and subtractor. Electron. Lett. 38 (2002). https://doi.org/10.1049/el: 20020949 Mitchell Chiew, Kooper de Lacy, Chao-Hua Yu, Sam Marsh, and Jingbo Wang. 2019. Graph comparison via nonlinear quantum search. Quantum Information Processing 18 (08 2019). https://doi.org/10.1007/s11128-019-2407-2 Proc. ACM Program. Lang., Vol. 6, No. OOPSLA2, Article 134. Publication date: October 2022. Tower: Data Structures inQuantum Superposition 134:29 AndrewM. Childs, Dmitri Maslov, Yunseong Nam, Neil J. Ross, and Yuan Su. 2018. Toward the first quantum simulation with quantum speedup. Proceedings of the National Academy of Sciences 115, 38 (2018). https://doi.org/10.1073/pnas.1801723115 D. Coppersmith. 1994. An approximate Fourier transform useful in quantum factoring. Yongshan Ding, Xin-Chuan Wu, Adam Holmes, Ash Wiseth, Diana Franklin, Margaret Martonosi, and Frederic T. Chong. 2020. SQUARE: Strategic Quantum Ancilla Reuse for Modular Quantum Programs via Cost-Effective Uncomputation. In International Symposium on Computer Architecture. https://doi.org/10.1109/ISCA45697.2020.00054 Thomas G. Draper. 2000. Addition on a Quantum Computer. arXiv:quant-ph/0008033 [quant-ph] Edward Farhi, Jeffrey Goldstone, and Sam Gutmann. 2014. A Quantum Approximate Optimization Algorithm. https: //doi.org/10.48550/ARXIV.1411.4028 arXiv:1411.4028 [quant-ph] Edward Fredkin and Tommaso Toffoli. 1982. Conservative logic. International Journal of Theoretical Physics 21 (1982). https://doi.org/10.1007/BF01857727 Craig Gidney. 2022. Quantum Dictionaries without QRAM. https://doi.org/10.48550/ARXIV.2204.13835 arXiv:2204.13835 [quant-ph] Vittorio Giovannetti, Seth Lloyd, and Lorenzo Maccone. 2008. Quantum Random Access Memory. Physical Review Letters 100, 16 (Apr 2008). https://doi.org/10.1103/physrevlett.100.160501 Oded Goldreich and Rafail Ostrovsky. 1996. Software Protection and Simulation on Oblivious RAMs. J. ACM 43, 3 (May 1996). https://doi.org/10.1145/233551.233553 Alexander S. Green, Peter LeFanu Lumsdaine, Neil J. Ross, Peter Selinger, and Benoît Valiron. 2013. Quipper: A Scalable Quantum Programming Language. In ACM SIGPLAN Conference on Programming Language Design and Implementation. https://doi.org/10.1145/2491956.2462177 Lov K. Grover. 1996. A Fast Quantum Mechanical Algorithm for Database Search. In ACM Symposium on Theory of Computing. https://doi.org/10.1145/237814.237866 Aram W. Harrow, Avinatan Hassidim, and Seth Lloyd. 2009. Quantum Algorithm for Linear Systems of Equations. Physical Review Letters 103, 15 (Oct 2009). https://doi.org/10.1103/physrevlett.103.150502 Jason D. Hartline, Edwin S. Hong, Alexander E. Mohr, William R. Pentney, and Emily C. Rocke. 2002. Characterizing History Independent Data Structures. In Algorithms and Computation, Prosenjit Bose and Pat Morin (Eds.). Tue Haulund. 2017. Design and Implementation of a Reversible Object-Oriented Programming Language. https://doi.org/ 10.48550/ARXIV.1707.07845 arXiv:1707.07845 [cs] Md Saiful Islam, Muhammad Mahbubur Rahman, Zerina Begum, and Mohd Z Hafiz. 2009. Low cost quantum realization of reversible multiplier circuit. Information technology journal 8, 2 (2009). https://doi.org/10.3923/itj.2009.208.213 Stacey Jeffery, Robin Kothari, and Frederic Magniez. 2013. Nested Quantum Walks with Quantum Data Structures. In ACM-SIAM Symposium on Discrete Algorithms. https://doi.org/10.1137/1.9781611973105.106 Ivan Kassal, James D. Whitfield, Alejandro Perdomo-Ortiz, Man-Hong Yung, and Alán Aspuru-Guzik. 2011. Simulating Chemistry Using Quantum Computers. Annual Review of Physical Chemistry 62, 1 (2011). https://doi.org/10.1146/annurev- physchem-032210-103512 Iordanis Kerenidis and Anupam Prakash. 2016. Quantum Recommendation Systems. https://doi.org/10.48550/ARXIV.1603. 08675 arXiv:1603.08675 [quant-ph] E Knill. 1996. Conventions for quantum pseudocode. Gushu Li, Li Zhou, Nengkun Yu, Yufei Ding, Mingsheng Ying, and Yuan Xie. 2020. Projection-Based Runtime Assertions for Testing and Debugging Quantum Programs. In ACM Conference on Object-Oriented Programming, Systems, Languages, and Applications. https://doi.org/10.1145/3428218 Richard L. Liboff. 1980. Introductory quantum mechanics. Addison-Wesley. Christopher Lutz. 1986. Janus: a time-reversible language. (1986). Letter to R. Landauer.. Olivia Di Matteo, Vlad Gheorghiu, andMichele Mosca. 2020. Fault-Tolerant Resource Estimation of Quantum Random-Access Memories. IEEE Transactions on Quantum Engineering 1 (2020). https://doi.org/10.1109/tqe.2020.2965803 Donald R. Morrison. 1968. PATRICIAśPractical Algorithm To Retrieve Information Coded in Alphanumeric. J. ACM 15, 4 (Oct 1968). https://doi.org/10.1145/321479.321481 Moni Naor and Vanessa Teague. 2001. Anti-persistence: History independent data structures. In ACM Symposium on Theory of Computing. https://doi.org/10.1145/380752.380844 Michael A. Nielsen and Isaac L. Chuang. 2010. Quantum Computation and Quantum Information: 10th Anniversary Edition. Cambridge University Press. Alexandru Paler, Oumarou Oumarou, and Robert Basmadjian. 2020. Parallelizing the queries in a bucket-brigade quantum random access memory. Physical Review A 102, 3 (Sep 2020). https://doi.org/10.1103/physreva.102.032608 Anouk Paradis, Benjamin Bichsel, Samuel Steffen, and Martin Vechev. 2021. Unqomp: Synthesizing Uncomputation in Quantum Circuits. In ACM SIGPLAN Conference on Programming Language Design and Implementation. https: //doi.org/10.1145/3453483.3454040 Proc. ACM Program. Lang., Vol. 6, No. OOPSLA2, Article 134. Publication date: October 2022. 134:30 Charles Yuan and Michael Carbin Jennifer Paykin, Robert Rand, and Steve Zdancewic. 2017. QWIRE: A Core Language for Quantum Circuits. In ACM SIGPLAN Symposium on Principles of Programming Languages. https://doi.org/10.1145/3009837.3009894 Romain Péchoux, Simon Perdrix, Mathys Rennela, and Vladimir Zamdzhiev. 2020. Quantum Programming with Inductive Datatypes: Causality and Affine Type Theory. In Lecture Notes in Computer Science. Springer International Publishing. https://doi.org/10.1007/978-3-030-45231-5_29 Peter Selinger and Benoît Valiron. 2005. A Lambda Calculus for Quantum Computation with Classical Control. Typed Lambda Calculi and Applications (2005). https://doi.org/10.1017/S0960129506005238 Run-Hua Shi. 2021. Quantum Bloom Filter and Its Applications. IEEE Transactions on Quantum Engineering (2021). https://doi.org/10.1109/TQE.2021.3054623 Peter W. Shor. 1997. Polynomial-Time Algorithms for Prime Factorization and Discrete Logarithms on a Quantum Computer. SIAM J. Comput. 26, 5 (Oct 1997). https://doi.org/10.1137/S0097539795293172 Krysta Svore, Martin Roetteler, Alan Geller, Matthias Troyer, John Azariah, Christopher Granade, Bettina Heim, Vadym Kliuchnikov, Mariia Mykhailova, and Andres Paz. 2018. Q#: Enabling Scalable Quantum Computing and Development with a High-level DSL. In Real World Domain Specific Languages Workshop. https://doi.org/10.1145/3183895.3183901 Michael Kirkedal Thomsen and Holger Bock Axelsen. 2015. Interpretation and Programming of the Reversible Functional Language RFUN. In Symposium on the Implementation and Application of Functional Programming Languages. https: //doi.org/10.1145/2897336.2897345 Carlin Vieri. 1995. Pendulumśa reversible computer architecture. Xiao Shaun Wang, Kartik Nayak, Chang Liu, T-H. Hubert Chan, Elaine Shi, Emil Stefanov, and Yan Huang. 2014. Oblivious Data Structures. In ACM SIGSAC Conference on Computer and Communications Security. https://doi.org/10.1145/2660267. 2660314 Dave Wecker, Krysta M. Svore, and Krysta M. Svore. 2014. LIQUi|>: A Software Design Architecture and Domain-Specific Language for Quantum Computing. (February 2014). Andrew C. Yao. 1982. Protocols for Secure Computations. In Symposium on Foundations of Computer Science. https: //doi.org/10.5555/1382436.1382751 Tetsuo Yokoyama and Robert Glück. 2007. A Reversible Programming Language and Its Invertible Self-Interpreter. In ACM SIGPLAN Symposium on Partial Evaluation and Semantics-Based Program Manipulation. https://doi.org/10.1145/1244381. 1244404 Charles Yuan and Michael Carbin. 2022. Tower: Data Structures in Quantum Superposition. https://doi.org/10.5281/zenodo. 6819031 Samee Zahur and David Evans. 2013. Circuit Structures for Improving Efficiency of Security and Privacy Tools. In IEEE Symposium on Security and Privacy. https://doi.org/10.1109/SP.2013.40 Proc. ACM Program. Lang., Vol. 6, No. OOPSLA2, Article 134. Publication date: October 2022.