Motivation

Why Qwerty? #

Qwerty is a new quantum programming language whose novel constructs such as literals for qubit states and the basis type allow programmers to create and trace quantum programs without needing to understand bra–ket notation or gate-based semantics. Qwerty is embedded in Python, allowing both intuitive circuit synthesis from classical logic and easy interoperability between classical and quantum code, making Qwerty a robust framework for mixed quantum–classical computation.

Qwerty differs from many other quantum languages in three aspects:

  1. Programs are expressed through basis translations instead of low-level circuitry;
  2. Quantum program behavior can be traced intuitively through language constructs without physics notation; and
  3. Hybrid quantum/classical programs are written in a popular programming language, both on qubits and on classical bits, either inside or outside qubit lifetime.

The figure below illustrates these differences by comparing the diffusion step of Grover’s search algorithm in circuitry versus in Qwerty. The Qwerty code directly expresses, “replace \( \ket{+}\!\ket{+}\!\ket{+}\!\ket{+} \) with \( -\!\ket{+}\!\ket{+}\!\ket{+}\!\ket{+} \) ,’’ whereas the circuit implementation requires significantly more explanation and expertise to understand.

  • Qwerty #

    'pppp' >> -'pppp'
  • Quantum Circuit #

    A four-qubit Grover diffuser circuit

Hello World: Grover’s in Qwerty #

To introduce Qwerty, we begin with implementing Grover’s well-known quantum search algorithm. Whereas a classical brute-force search through \( 2^N \) possibilities requires \( O(2^N) \) queries to an N-bit black box oracle, Grover’s algorithm needs only \( O(\sqrt{2^N}) \) queries. The Qwerty code for Grover’s algorithm begins on lines 3-5 (below) by defining an example oracle. For simplicity, the example oracle marks the bits \( 1010 \) as the answer. As the C-style syntax on line 5 demonstrates, Qwerty programmers express classical oracles with classical code instead of quantum gates.

 1from qwerty import *
 2
 3@classical
 4def oracle(x: bit[4]) -> bit:
 5    return x[0] & ~x[1] & x[2] & ~x[3]
 6
 7@qpu
 8def grover_iter(q):
 9    return (q | oracle.sign
10              | 'pppp' >> -'pppp')
11
12@qpu
13def grover():
14    return ('pppp' | grover_iter
15                   | grover_iter
16                   | grover_iter
17                   | measure**4)
18
19print(grover())

Grover’s algorithm consists of many iterations, each of which rotates the state away from the space of wrong answers toward the space of correct answers. Line 8 defines a single Grover iteration as a Qwerty function named grover_iter. (Applying the @qpu decorator to a function as seen on line 7 indicates that the function is written in Qwerty, not Python.) Because the syntax x | f | g represents g(f(x)) in Qwerty, lines 9-10 pass q first through an embedding of the oracle (oracle.sign) and then the Grover diffuser ('pppp' >> -'pppp'). The syntax oracle.sign produces the quantum form of the classical function oracle needed by Grover’s algorithm, which avoids the need to understand or prepare a \( \ket{-} \) ancilla.

The Grover diffuser on line 10 is written as a basis translation, the fundamental state evolution primitive in Qwerty. The basis translation 'pppp' >> -'pppp' allows the programmer to write the Grover diffuser by describing how the state should change, i.e., that \( \ket{+}^{\otimes 4} \) should be replaced with \( {-}\ket{+}^{\otimes 4} \) , instead of by picking specific gates that accomplish this transformation.

The procedure for Grover’s algorithm begins by preparing a superposition of all possibilities. In this example, we have decided to perform the search across all four-bit values; thus, line 14 prepares a superposition of all four-bit values using the qubit literal 'pppp'. Because 'p' is an equal superposition of both bits '0' and '1', a four-fold 'p' state represents all combinations of four single-bit values. In traditional quantum programming, this preparation of a \( \ket{+}^{\otimes 4} \) state would be performed by writing a for loop with Hadamard gates, but qubit literals are more succinct and express programmer intention more explicitly.

On lines 14-17, the pipeline in grover() pipes this initial 'pppp' state through three Grover iterations and into a four-qubit measurement in the computational basis. (Note the number of iterations must be chosen carefully because otherwise one may rotate either too far past the space of correct answers or not far enough from the space of wrong answers.) The final line is ordinary Python code and calls the Qwerty function grover() with typical Python function call syntax, demonstrating the seamless integration of Qwerty with Python.