Quanta: A high-level language that compiles to OpenQASM 3
Project description
Quanta Language
Quanta is a high-level, Python-like language that compiles to OpenQASM 3. It provides a clean, readable syntax for quantum circuit development while maintaining full compatibility with OpenQASM 3 and Qiskit.
Features
- 🐍 Python-like syntax - Familiar and readable
- ⚛️ Function-style gates - Gates as function calls:
H(q[0]),CNot(q[0], q[1]) - 🔒 Static analysis - Compile-time safety checks
- 🎯 OpenQASM 3 output - Direct compilation to standard QASM
- 🚀 Qiskit integration - Seamless execution with Qiskit backends
- 🖥️ Frontend debug -
get_prints(source)runs a statevector sim and returns allPrint()output (simulator only)
Installation
pip install quanta-lang
Requires Python 3.10+ and Qiskit.
Quick Start
As a Library
from quanta import compile, run, get_prints
# Compile Quanta source to OpenQASM 3
source = """
qubit[2] q
bit[2] c
gate Bellgate(a, b) {
H(a)
CNot(a, b)
}
Bellgate(q[0], q[1])
MeasureAll(q, c)
"""
qasm = compile(source)
print(qasm)
# Run and get measurement results
result = run(source, shots=1024)
print(result)
# Frontend debug: capture Print() output (statevector simulator only)
debug_source = "qubit q\nH(q)\nprint(q)"
terminal = get_prints(debug_source)
print(terminal) # e.g. "1/sqrt(2) * |0> + 1/sqrt(2) * |1>"
CLI Usage
# Compile to QASM
quanta compile example.qta -o output.qasm
# Run circuit
quanta run example.qta --shots 1024
# Check syntax
quanta check example.qta
Example
Quanta Source (bell.qta)
// Bell state example
qubit[2] q
bit[2] c
gate Bellgate(a, b) {
H(a)
CNot(a, b)
}
Bellgate(q[0], q[1])
MeasureAll(q, c)
Print(c)
Generated OpenQASM 3
OPENQASM 3;
include "stdgates.inc";
qubit[2] q;
bit[2] c;
h q[0];
cx q[0], q[1];
measure q[0] -> c[0];
measure q[1] -> c[1];
Language Features
- Types:
int,float,bool,str,list,dict,qubit,bit,qint[n],bint[n] - Gate Macros:
gatekeyword for compile-time circuit composition - Modifiers:
ctrlandinv(dagger) modifiers for gates, andresetfor qubits - Functions: Compile-time inlined for quantum operations
- Control Flow:
forloops (unrolled),if/else(classical only) - Gate Set:
H,X,CNot,CZ,Swap,RZ,Measure, and more - High-Level Gates:
Bell,GHZ,WState,SwapGate,QFT,InverseQFT - Quantum Arithmetic:
QAdd,QMult,Compare,Grover; operator overloading+and*onqint - Standard Library:
Print(),Len(),MeasureAll(),Assert(),Range() - Constants: Built-in
pi,e, and user-definedconstdeclarations - API:
compile(source),run(source, shots=...),get_prints(source)(frontend debug, simulator only)
Quanta Language Specification
Quanta is a Python-like, static quantum programming language that compiles deterministically to OpenQASM 3.
Design Principles
- Readable & familiar (Python / C# inspired)
- No abstraction leaks: everything maps cleanly to OpenQASM 3
- Explicit quantum semantics
- Static-circuit first (no runtime quantum control in v1)
- Frontend power, backend honesty
- Semicolons optional, never required except for same-line statements
Comments
// single-line comment
No multiline comments in v1 (simplifies parsing & tooling).
Type System
Primitive Types (Classical)
int, float, bool, str, list, dict
varis the default inferred type- Static typing is optional but encouraged
Quantum Types (QASM-Mapped)
qubit
bit
qubit[n]
bit[n]
qint[n] // Quantum integer (N qubits)
bint[n] // Classical bit integer (N classical bits)
📌 Rules
- These map 1:1 to OpenQASM 3 registers
- No dynamic allocation
qint[n]represents N qubits interpreted as an integer (0 to 2^n-1)bint[n]represents N classical bits (0 to 2^n-1)
Variables
Declaration
var x = 10
int y = 3
float z = 1.23
var→ inferred, immutable type after assignment- Quantum variables must be explicitly declared
Constants & Immutability
const N = 4
let theta = pi / 4
| Keyword | Meaning |
|---|---|
const |
Compile-time literal |
let |
Immutable value, resolved once |
Arrays (Lists)
Literals
list a = [1, 2, 3]
list b = [1:6] // [1,2,3,4,5]
list c = [1:2:6] // [1,3,5]
Indexing
a[0]
q[qidx[1]]
📌 Quantum rule
Any array used in quantum operations must be compile-time resolvable.
Dictionaries (Maps)
dict gates = {
"control": 0,
"target": 1
}
gates["control"]
📌 Restriction
- Dictionaries are frontend-only
- Must fully resolve before quantum lowering
Functions (Classical)
Void Function
func apply_h(q) {
H(q)
}
Typed Return
func int add(a, b) {
return a + b
}
Inferred Return
func var mul(a, b) {
return a * b
}
📌 Rule
func name(...)→ no returnfunc <type> name(...)→ must return
Quantum Integer Types (qint and bint)
qint[N] - Quantum Integer
A qint[N] represents N qubits interpreted as an integer in the computational basis:
qint[3] x = 2 // Initialize to |010⟩
qint[4] y // Uninitialized (|0000⟩)
Properties:
- Storage: N qubits
- Domain: 0 to 2^N - 1
- Nature: Quantum (superposition allowed)
- Copying: ❌ Forbidden
- Measurement: Explicit only
- Arithmetic: Reversible, unitary
bint[N] - Classical Bit Integer
A bint[N] represents N classical bits, equivalent to an unsigned integer:
bint[3] c = 2 // Classical integer
Properties:
- Storage: N classical bits
- Domain: 0 to 2^N - 1
- Nature: Classical
- Copying: ✔ Allowed
- Arithmetic: Classical
- Source: Measurement only
Initialization
qint[3] x = 2 // Initialize qubits to encode value 2
bint[3] c = 2 // Classical assignment
For qint, initialization:
- Sets all qubits to |0⟩
- Applies NOT (X) gates to encode the binary value
Example:
qint[3] q = 2 // Binary: 010, so |010⟩
Generates:
qubit[3] q;
x q[1]; // Set bit 1 (second bit) to |1⟩
The value 2 in binary is 010 (bits from LSB to MSB: 0, 1, 0), so only q[1] is set to |1⟩.
Quantum Arithmetic Operations
QAdd - Quantum Addition
Variadic quantum addition operation:
qint[3] a = 1
qint[3] b = 3
qint[3] c
QAdd(a, b, c) // c = a + b (mod 2^3)
QAdd(a, b, d, result) // result = a + b + d (mod 2^N)
Semantics:
- First N-1 arguments are inputs
- Last argument is the destination (output)
- Result =
(q1 + q2 + q3 + ...) mod 2^n - All operands must have matching bit widths
Implementation:
- Uses a ripple-carry adder circuit design
- Computes addition bit-by-bit from LSB to MSB
- Propagates carry bits using Toffoli (CCX) gates
- Reversible: carry bits are computed forward, then uncomputed backward
- Requires
n-1ancilla qubits for carry storage (where n is bit width)
Circuit Structure:
- Forward pass: Compute carry[1..n-1] using Toffoli gates
- Sum computation: Compute sum[i] = a[i] XOR b[i] XOR carry[i] for all bits
- Backward pass: Uncompute carry[n-1..1] to restore ancilla qubits
QMult - Quantum Multiplication
Variadic quantum multiplication operation:
qint[3] a = 2
qint[3] b = 3
qint[5] out // Output must be wider
QMult(a, b, out) // out = a * b
QMult(a, b, c, out) // out = a * b * c
Semantics:
- First N-1 arguments are inputs
- Last argument is the destination (output)
- Result =
(q1 * q2 * q3 * ...) mod 2^n - Output width must be ≥ sum of input widths (ideally 2n for full precision)
Implementation:
- Uses shift-and-add multiplication algorithm
- For each bit
iof the multiplier (B):- If
B[i] == 1, add(A << i)to result using controlled ripple-carry adder - The shift is implicit in which qubits of result receive the addition
- If
- Each controlled addition is reversible (uses uncomputation)
- Result accumulates:
result = Σ(B[i] * (A << i))for all bitsi
Circuit Structure:
- Initialize result register to |0⟩
- For each bit
i = 0ton-1of multiplier B:- If
B[i] == 1(controlled operation): - Add
(A shifted by i bits)to result using controlled ripple-carry adder
- If
- Each controlled addition uses reversible operations with carry uncomputation
Example:
For A = 3 (011) and B = 5 (101):
- Bit 0 of B = 1 → add
A × 2^0 = 3to result - Bit 1 of B = 0 → skip
- Bit 2 of B = 1 → add
A × 2^2 = 12to result - Final result = 3 + 12 = 15
Requires: Controlled ripple-carry adders, ancilla qubits for carry storage
QFTAdd - QFT-Based Quantum Addition (Fast Adder)
Variadic quantum addition using Quantum Fourier Transform (QFT):
qint[3] a = 1
qint[3] b = 3
qint[3] c
QFTAdd(a, b, c) // c = a + b (mod 2^3) using QFT
QFTAdd(a, b, d, result) // result = a + b + d (mod 2^N)
Semantics:
- First N-1 arguments are inputs
- Last argument is the destination (output)
- Result =
(q1 + q2 + q3 + ...) mod 2^n - All operands must have matching bit widths
Implementation:
- Uses QFT-based adder (Draper adder) circuit design
- Applies QFT to target register to encode value in phase domain
- Uses controlled phase rotations to add operands
- Applies inverse QFT to transform back to computational basis
Circuit Structure:
- QFT: Apply Quantum Fourier Transform to target register
- Phase rotations: Controlled phase rotations to add each operand
- Inverse QFT: Transform back to computational basis
Advantages:
- Lower circuit depth than ripple-carry adder
- Logarithmic depth in optimized implementations (O(log n))
- Often used within algorithms requiring modular arithmetic (e.g., Shor's algorithm)
- Reduces carry propagation overhead
QTreeAdd - Tree-Based Quantum Addition (Parallel Adder)
Variadic quantum addition using tree-based carry-save structure:
qint[3] a = 1
qint[3] b = 3
qint[3] c
QTreeAdd(a, b, c) // c = a + b (mod 2^3) using tree adder
QTreeAdd(a, b, d, result) // result = a + b + d (mod 2^N)
Semantics:
- First N-1 arguments are inputs
- Last argument is the destination (output)
- Result =
(q1 + q2 + q3 + ...) mod 2^n - All operands must have matching bit widths
Implementation:
- Uses tree-based carry-save/parallel adder circuit design
- Parallelizes carry computation using balanced tree structure
- Reduces multiple partial operands in a tree (Wallace-tree inspired)
- Uses parallel controlled gates to handle carry propagation efficiently
Circuit Structure:
- Parallel computation: Compute partial sums and carries in parallel
- Tree reduction: Reduce carries using balanced tree structure
- Final combination: Combine all partial sums with carries
Advantages:
- Significantly reduced circuit depth compared to ripple chain
- Better suited for multi-operand addition
- Space-depth tradeoffs via ancilla reuse
- Highly parallel addition operations
QExpEncMult - Exponent-Encoded Quantum Multiplication
Variadic quantum multiplication using exponent encoding:
qint[3] a = 2
qint[3] b = 3
qint[5] out
QExpEncMult(a, b, out) // out = a * b using exponent encoding
QExpEncMult(a, b, c, out) // out = a * b * c
Semantics:
- First N-1 arguments are inputs
- Last argument is the destination (output)
- Result =
(q1 * q2 * q3 * ...) mod 2^n - Output width must be ≥ sum of input widths (ideally 2n for full precision)
Implementation:
- Uses exponent-encoded multiplication algorithm
- Encodes operands as superposition states in compact form (logarithmic qubits)
- Uses fast quantum adder (QFT-based) to sum encodings
- Extracts product from sum via measurement and classical post-processing
Circuit Structure:
- Encode operands: Transform n-bit operands to ~log(n) qubits (exponent encoding)
- Fast addition: Use QFT-based adder on encoded operands
- Decode result: Transform encoded sum back to computational basis (requires measurement + classical post-processing)
Advantages:
- Uses only O(log n) qubits (plus ancilla) to represent n-bit operands
- Circuit depth can be O(log² n) with appropriate adders
- Gate complexity scales linearly in n while using sub-linear register widths
- Radically different resource scaling from shift-and-add
Note: Requires measurement and classical post-processing for decoding
QTreeMult - Tree-Based Quantum Multiplication
Variadic quantum multiplication using tree-based partial product reduction:
qint[3] a = 2
qint[3] b = 3
qint[5] out
QTreeMult(a, b, out) // out = a * b using tree multiplier
QTreeMult(a, b, c, out) // out = a * b * c
Semantics:
- First N-1 arguments are inputs
- Last argument is the destination (output)
- Result =
(q1 * q2 * q3 * ...) mod 2^n - Output width must be ≥ sum of input widths (ideally 2n for full precision)
Implementation:
- Uses tree-based multiplication (Wallace/Dadda-style) circuit design
- Inspired by classical multipliers like Wallace tree
- Reduces partial products more efficiently using quantum reversible gates
- Uses tree of controlled adders to combine partial products efficiently
Circuit Structure:
- Generate partial products: Create all partial products A * B[i] * 2^i in parallel
- Tree reduction: Wallace/Dadda-style tree to reduce partial products
- Final addition: Combine remaining partial products with fast adder (QFT or tree-based)
Advantages:
- Significantly less costly in T gates and overall depth
- Useful for devices where T-count and depth dominate performance
- Better space-depth tradeoffs than shift-and-add
- Parallelizes reductions to reduce depth vs naive shift/add
Requires: Ancilla qubits for partial products and intermediate results
QSub - Quantum Subtraction
Variadic quantum subtraction using ripple-borrow subtractor:
qint[3] a = 5
qint[3] b = 3
qint[3] c
QSub(a, b, c) // c = a - b (mod 2^3)
QSub(a, b, d, result) // result = a - b - d (mod 2^N)
Semantics:
- First N-1 arguments are inputs
- Last argument is the destination (output)
- Result =
(q1 - q2 - q3 - ...) mod 2^n(modular subtraction) - All operands must have matching bit widths
- Supports modular two's complement arithmetic
Implementation:
- Uses ripple-borrow subtractor circuit design
- Similar to
QAddbut with borrow propagation instead of carry - Uses CNOT gates for XOR operations
- Uses Toffoli (CCX) gates for borrow computation
- Reversible: borrow bits are computed then uncomputed
Circuit Structure:
- Compute bitwise differences with borrow propagation
- Uses CNOT for XOR and CCX for borrow computation
- Similar to
Comparebut preserves difference result - Reversible: borrow bits are computed then uncomputed
Advantages:
- Standard subtraction algorithm
- Reversible implementation
- Works well for small to medium bit widths
QDiv - Quantum Division
Quantum integer division with remainder:
qint[4] dividend = 7
qint[4] divisor = 3
qint[4] quotient
qint[4] remainder
QDiv(dividend, divisor, quotient, remainder) // 7 ÷ 3 = 2 R 1
Semantics:
QDiv(dividend, divisor, quotient, remainder)computes both quotient and remainder- Integer division:
quotient = floor(dividend / divisor) - Modulus:
remainder = dividend mod divisor - Both quotient and remainder registers must be same width as dividend
- Division by zero should trigger compile-time error
Implementation:
- Uses repeated subtraction algorithm
- Subtracts divisor from dividend until dividend < divisor
- Counts iterations to compute quotient
- Final dividend value is the remainder
- Requires controlled subtraction and comparison operations
Circuit Structure:
- Copy dividend to remainder register
- Initialize quotient to zero
- Loop: while remainder >= divisor:
- Subtract divisor from remainder (controlled)
- Increment quotient (controlled)
- Check if remainder >= divisor (using Compare)
- Final remainder is the result
Advantages:
- Computes both quotient and remainder in one operation
- Reversible implementation
- Works for any divisor
Note: Full implementation requires controlled subtraction and comparison, which adds complexity.
QMod - Quantum Modulus
Variadic quantum modulus operation:
qint[4] a = 7
qint[4] b = 3
qint[4] r
QMod(a, b, r) // r = a mod b = 1
// With multiple divisors:
qint[4] a, b, c, result
QMod(a, b, c, result) // result = a mod b mod c
Semantics:
- First N-1 arguments are inputs
- Last argument is the destination (output)
- Result =
(q1 mod q2 mod q3 mod ...) mod 2^n - All operands must have matching bit widths
Implementation:
- Uses repeated subtraction algorithm (same as division)
- Subtracts divisor from dividend until dividend < divisor
- Final value is the remainder
- For variadic case, applies modulus operations sequentially
Circuit Structure:
- Copy first operand to result register
- For each subsequent operand:
- Repeatedly subtract operand from result
- Continue until result < operand
- Final result is the modulus
Advantages:
- Computes modular reduction efficiently
- Supports chained modulus operations
- Reversible implementation
Quantum Arithmetic Functions Summary
| Function | Description | Best For | Depth | Qubits | Notes |
|---|---|---|---|---|---|
QAdd |
Ripple-carry adder | Small to medium bit widths, simple circuits | O(n) | n + ancilla | Standard, well-understood |
QFTAdd |
QFT-based adder (Draper) | Large bit widths, modular arithmetic | O(log n) | n + ancilla | Lower depth, used in Shor's algorithm |
QTreeAdd |
Tree-based parallel adder | Multi-operand addition, parallel execution | O(log n) | n + ancilla | Highly parallel, reduced depth |
QSub |
Ripple-borrow subtractor | Small to medium bit widths, subtraction | O(n) | n + ancilla | Standard subtraction, reversible |
QMult |
Shift-and-add multiplier | Small to medium bit widths | O(n²) | 2n + ancilla | Standard, straightforward |
QExpEncMult |
Exponent-encoded multiplier | Very large operands, space-constrained | O(log² n) | O(log n) | Logarithmic qubits, requires measurement |
QTreeMult |
Tree-based multiplier (Wallace/Dadda) | T-count optimization, depth-critical | O(n log n) | 2n + ancilla | Reduced T-count, better depth |
QDiv |
Repeated subtraction division | Small divisors, integer division | O(2ⁿ)* | 2n + ancilla | Computes quotient and remainder |
QMod |
Repeated subtraction modulus | Modular reduction operations | O(2ⁿ)* | n + ancilla | Computes remainder efficiently |
*Note: QDiv and QMod depth depends on the divisor value. Worst case is O(2ⁿ) for repeated subtraction.
Choosing the Right Function:
- Small circuits (< 8 bits): Use
QAdd,QSub, andQMultfor simplicity - Large circuits (> 16 bits): Consider
QFTAddorQTreeAddfor addition - Space-constrained: Use
QExpEncMultfor logarithmic qubit usage - T-count critical: Use
QTreeMultfor optimized multiplication - Modular arithmetic: Use
QFTAdd(used in Shor's algorithm) - Subtraction: Use
QSubfor standard subtraction operations - Division/Modulus: Use
QDiv/QModfor integer division and modular reduction
Operator Overloading
Quanta supports operator overloading for +, -, *, /, and % on qint types. By default, these operators use QAdd, QSub, QMult, QDiv, and QMod respectively:
qint[3] a = 1
qint[3] b = 3
qint[3] c = a + b // Sugar for: qint[3] c; QAdd(a, b, c)
qint[3] d = a - b // Sugar for: qint[3] d; QSub(a, b, d)
qint[4] x = 2
qint[4] y = 3
qint[4] z = 4
qint[4] total = x + y + z // Sugar for: QAdd(x, y, z, total)
qint[4] diff = x - y - z // Sugar for: QSub(x, y, z, diff)
qint[3] r = (a + b) * c // Compound expression with precedence
qint[4] q = a / b // Sugar for: QDiv(a, b, q, _remainder)
qint[4] m = a % b // Sugar for: QMod(a, b, m)
Default Desugaring:
qint z = x + y→qint z; QAdd(x, y, z)(uses ripple-carry adder)qint d = x - y→qint d; QSub(x, y, d)(uses ripple-borrow subtractor)qint w = x * y→qint w; QMult(x, y, w)(uses shift-and-add multiplier)qint q = x / y→qint q, _remainder; QDiv(x, y, q, _remainder)(division with remainder)qint m = x % y→qint m; QMod(x, y, m)(modulus operation)- Operator precedence:
*,/,%bind tighter than+,- - Automatic destination initialization
Division Operator Notes:
- The
/operator computes the quotient and creates a temporary remainder variable - To get both quotient and remainder, use explicit
QDiv():qint[4] dividend = 7 qint[4] divisor = 3 qint[4] quotient, remainder QDiv(dividend, divisor, quotient, remainder) // Get both values
When to Use Explicit Function Calls:
For optimal performance, use explicit function calls when you need specific implementations:
// For large bit widths or modular arithmetic, use QFTAdd explicitly
qint[64] a, b, c
QFTAdd(a, b, c) // Better than: c = a + b (which uses QAdd)
// For multi-operand addition with parallelism, use QTreeAdd
qint[16] x, y, z, w, sum
QTreeAdd(x, y, z, w, sum) // Better than: sum = x + y + z + w
// For T-count optimization, use QTreeMult explicitly
qint[8] m1, m2, product
QTreeMult(m1, m2, product) // Better than: product = m1 * m2
// For space-constrained scenarios, use QExpEncMult
qint[32] a, b, result
QExpEncMult(a, b, result) // Uses logarithmic qubits
// For division with remainder, use QDiv explicitly
qint[8] dividend, divisor, quotient, remainder
QDiv(dividend, divisor, quotient, remainder) // Get both quotient and remainder
Recommendation:
- Small circuits (< 8 bits): Use operators
+,-,*,/,%(defaults to QAdd/QSub/QMult/QDiv/QMod) - Large circuits (> 16 bits): Use explicit
QFTAddorQTreeAddfor addition - T-count critical: Use explicit
QTreeMultfor multiplication - Space-constrained: Use explicit
QExpEncMult - Division with remainder: Use explicit
QDiv()to get both quotient and remainder
Compare - Quantum Comparison
qint[3] a
qint[3] b
qint[1] flag // or qubit flag
Compare(a, b, flag) // flag = (a >= b)
Semantics:
flagmust beqint[1]orqubit- Result usable only as quantum control
|a⟩|b⟩|0⟩ → |a⟩|b⟩|a ≥ b⟩
Grover - Grover Operator
qint[3] x
H(x) // Create uniform superposition
Grover(x, 5) // Amplify probability of x == 5
Semantics:
- Applies Grover iteration over register
x - Oracle: phase-flip states where
x == target - Diffusion operator
targetmust be classical (intorbint)xshould be in uniform superposition beforehand
Gate Calls (Core Feature)
Function-Like Gate Syntax
H(q[0])
X(q[1])
CNot(q[0], q[1])
RZ(pi/2, q[0])
Built-in Gate Mapping
| Quanta | OpenQASM 3 |
|---|---|
H(q) |
h q; |
X(q) |
x q; |
CNot(a,b) |
cx a, b; |
CZ(a,b) |
cz a, b; |
Swap(a,b) |
swap a, b; |
Measure(q,c) |
measure q -> c; |
📌 Gates look like functions but are not functions semantically.
Gate Macros (gate)
Compile-time circuit composition.
gate Bellgate(a, b) {
H(a)
CNot(a, b)
}
Usage:
Bellgate(q[0], q[1])
📌 gate:
- Cannot return
- Expands inline
- Accepts modifiers (
ctrl,inv)
High-Level Quantum Gates
Quanta provides built-in high-level quantum gates that compile to standard OpenQASM 3 circuits. These gates make the language more expressive and user-friendly.
Bell(q0, q1) - Bell State Preparation
Prepares a Bell pair (maximally entangled 2-qubit state):
|00⟩ → (|00⟩ + |11⟩) / √2
Usage:
qubit[2] q
Bell(q[0], q[1])
OpenQASM 3 Equivalent:
h q[0];
cx q[0], q[1];
Explanation:
- Hadamard on first qubit → puts it into superposition
- CNOT entangles the second qubit with the first
GHZ(q0, q1, q2, ...) - GHZ State Preparation
Prepares a GHZ state on ≥2 qubits:
|000…⟩ → (|000…⟩ + |111…⟩) / √2
Usage:
qubit[4] q
GHZ(q[0], q[1], q[2], q[3])
OpenQASM 3 Equivalent:
h q[0];
cx q[0], q[1];
cx q[1], q[2];
cx q[2], q[3];
// ... continues chain for more qubits
General rule:
Prepare superposition on the first qubit, then cascade CNOTs down the list.
WState(q0, q1, q2) - W State Preparation
Creates a 3-qubit W state:
(|100⟩ + |010⟩ + |001⟩) / √3
Usage:
qubit[3] q
WState(q[0], q[1], q[2])
OpenQASM 3 Equivalent:
ry(2*acos(1/sqrt(3))) q[0];
cx q[0], q[1];
cx q[0], q[2];
This produces the equal-superposition of one excitation across three qubits.
SwapGate(a, b) - Swap Gate
Swaps two qubits using the standard 3-CNOT decomposition.
Usage:
qubit[4] q
SwapGate(q[0], q[3])
OpenQASM 3 Equivalent:
cx q[0], q[3];
cx q[3], q[0];
cx q[0], q[3];
Classic CX ladder swap.
QFT(q0, q1, ...) - Quantum Fourier Transform
Applies the Quantum Fourier Transform on a register of qubits.
Usage:
qubit[4] q
QFT(q[0], q[1], q[2], q[3])
OpenQASM 3 Equivalent:
h q[0];
crz(pi/2) q[1], q[0];
crz(pi/4) q[2], q[0];
crz(pi/8) q[3], q[0];
h q[1];
crz(pi/2) q[2], q[1];
crz(pi/4) q[3], q[1];
h q[2];
crz(pi/2) q[3], q[2];
h q[3];
// Bit-reversal (swap)
swap q[0], q[3];
swap q[1], q[2];
This is the canonical QFT decomposition.
InverseQFT(q0, q1, ...) - Inverse Quantum Fourier Transform
Applies the Inverse Quantum Fourier Transform (reverse of QFT).
Usage:
qubit[4] q
InverseQFT(q[0], q[1], q[2], q[3])
OpenQASM 3 Equivalent:
Same gates as QFT in reverse order with crz(-θ) instead of crz(θ).
Controlled (ctrl) & Dagger (inv) Modifiers
Controlled (ctrl)
ctrl X(q[0], q[1])
ctrl[2] Z(q[0], q[1], q[2])
Dagger (inv)
inv RZ(theta, q[0])
RZ(theta, q[0])†
Combined
ctrl inv U(q[0], q[1])
📌 Maps directly to:
ctrl @ inv @ U q[0], q[1];
🚫 Not allowed on Measure
Control Flow (Compile-Time)
For Loop
for (i in [0:3]) {
H(q[i])
}
Unrolled at compile time.
If / Else (Classical Only)
if (x > 0) {
x = x - 1
} else {
x = x + 1
}
📌 Restriction
- No runtime classical-quantum branching in v1
- Conditions must be statically resolvable
Classes (Frontend Only)
class Pair {
var a
var b
func init(x, y) {
a = x
b = y
}
}
📌 Classes:
- Do not exist in QASM
- Fully expanded before lowering
Standard Library (v1)
Print() – Debug / Frontend Runtime
Print(c) // [1,0,0]
Print(c[0]) // 1
Print(q) // |ψ⟩ (symbolic)
| Type | Output |
|---|---|
| Primitive | Normal |
bit[n] |
Measurement results |
qubit[n] |
Symbolic bra-ket |
📌 No amplitudes unless simulator supports it.
get_prints(quanta_code) – Frontend debug execution (Python API)
Frontend Debug Execution Only. Not compatible with hardware backend.
Parses Quanta source, runs it in a statevector simulator, and returns the string that would be printed by all Print() / print() calls.
- Classical:
print(c)appends the value ofc(e.g.[0, 1]for a bit register). - Quantum:
print(q)appends a symbolic state summary (e.g.1/sqrt(2) * |0> + 1/sqrt(2) * |1>). No state collapse. - Entangled subsystems: If you print a register that is entangled with others, the full state is shown with a note:
Subsystem entangled. 1/sqrt(2) * |00> + 1/sqrt(2) * |11>.
from quanta import get_prints
terminal = get_prints("""
qubit q
H(q)
print(q)
""")
# terminal == "1/sqrt(2) * |0> + 1/sqrt(2) * |1>"
Limits: Raises RuntimeError if total qubits > 20 (statevector uses 2^n memory).
Other Core Helpers
Len(q)
Range(0, 3)
MeasureAll(q, c)
reset q
Assert(len(q) == len(c))
Error("Invalid circuit")
Warn("Simulator-only feature")
Function Descriptions:
-
Len(q)- Returns the size of a quantum register, classical register, or array. Evaluated at compile-time. Useful for bounds checking and loop generation.qubit[5] q var size = Len(q) // size = 5
-
Range(start, steps, end)- Generates a compile-time range for use inforloops. Creates a list of integers fromstart(inclusive) (default = 0) toend(exclusive) insteps(default = 1).for (i in range(3)) { H(q[i]) // Applies H to q[0], q[1], q[2] } for (i in range(0, 3)) { H(q[i]) // Applies H to q[0], q[1], q[2] } for (i in range(0, 1, 3)) { H(q[i]) // Applies H to q[0], q[1], q[2] } -
MeasureAll(q, c)- Convenience function that measures all qubits in registerqto corresponding classical bits in registerc. Generates individualmeasurestatements for each qubit. Both registers must have the same size.qubit[3] q bit[3] c MeasureAll(q, c) // Equivalent to: measure(q[0], c[0]); measure(q[1], c[1]); measure(q[2], c[2]);
-
reset q- Resets one or more qubits to the |0⟩ state. Maps to OpenQASM 3resetstatement. Useful for reinitializing qubits during circuit execution.reset q[0] // Reset single qubit reset q // Reset entire register
-
Assert(condition)- Compile-time assertion that validates a condition during compilation. If the condition evaluates to false, compilation fails with an error. Useful for validating circuit constraints.Assert(len(q) == len(c)) // Ensures registers have matching sizes Assert(len(q) > 0) // Ensures non-empty register
-
Error("message")- Emits a compile-time error with the specified message and stops compilation. Useful for validating circuit parameters or detecting unsupported configurations.if (len(q) > 10) { Error("Register size exceeds maximum of 10 qubits") } -
Warn("message")- Emits a compile-time warning with the specified message but allows compilation to continue. Useful for alerting about potential issues or simulator-only features.Warn("This circuit uses features only available in simulators")
Complete Examples
Example 1: Bell State
qubit[2] q
bit[2] c
gate Bellgate(a, b) {
H(a)
CNot(a, b)
}
Bellgate(q[0], q[1])
MeasureAll(q, c)
Print(c)
Example 2: Quantum Arithmetic
// Quantum integer arithmetic
qint[3] a = 1
qint[3] b = 3
qint[3] c = a + b // Operator overloading
// Multiple operands
qint[4] x = 2
qint[4] y = 3
qint[4] d = 4
qint[4] total = x + y + d // QAdd(x, y, d, total)
// Multiplication
qint[3] m1 = 2
qint[3] m2 = 3
qint[5] product
QMult(m1, m2, product) // product = m1 * m2
// Comparison
qint[3] val1
qint[3] val2
qint[1] flag
Compare(val1, val2, flag) // flag = (val1 >= val2)
Example 2b: Advanced Quantum Arithmetic
// QFT-based addition (lower depth)
qint[8] a = 5
qint[8] b = 7
qint[8] c
QFTAdd(a, b, c) // Fast QFT adder
// Tree-based addition (parallel)
qint[8] x = 2
qint[8] y = 3
qint[8] z = 4
qint[8] sum
QTreeAdd(x, y, z, sum) // Parallel tree adder
// Exponent-encoded multiplication (logarithmic qubits)
qint[4] m1 = 3
qint[4] m2 = 5
qint[8] exp_product
QExpEncMult(m1, m2, exp_product) // Uses ~log(n) qubits
// Tree-based multiplication (reduced T-count)
qint[4] n1 = 2
qint[4] n2 = 3
qint[8] tree_product
QTreeMult(n1, n2, tree_product) // Wallace/Dadda-style
Example 2c: Subtraction, Division, and Modulus
// Quantum subtraction
qint[4] a = 7
qint[4] b = 3
qint[4] diff = a - b // diff = 4 (using QSub)
// Variadic subtraction
qint[4] x = 15
qint[4] y = 5
qint[4] z = 2
qint[4] result = x - y - z // result = 8 (using QSub)
// Quantum division with remainder
qint[4] dividend = 7
qint[4] divisor = 3
qint[4] quotient, remainder
QDiv(dividend, divisor, quotient, remainder) // quotient = 2, remainder = 1
// Division using operator
qint[4] q = dividend / divisor // q = 2 (quotient only, remainder discarded)
// Quantum modulus
qint[4] value = 7
qint[4] mod = 3
qint[4] r = value % mod // r = 1 (using QMod)
// Chained modulus operations
qint[4] a = 25
qint[4] b = 7
qint[4] c = 3
qint[4] result = a % b % c // result = (25 mod 7) mod 3 = 4 mod 3 = 1
Example 3: Grover's Algorithm
qint[3] x
H(x) // Create uniform superposition
Grover(x, 5) // Search for value 5
Measure(x, c)
Generated OpenQASM 3 (Bell State Example)
OPENQASM 3;
include "stdgates.inc";
qubit[2] q;
bit[2] c;
h q[0];
cx q[0], q[1];
measure q[0] -> c[0];
measure q[1] -> c[1];
Semicolons
Optional by default:
var x = 1
var y = 2;
Required on same line:
var x = 1; var y = 2
Identity Statement
Quanta is to OpenQASM 3 what Python/C# is to assembly — a static, readable, honest frontend that never pretends quantum hardware can do what it can't.
Documentation
Development
# Install in development mode (from project root)
pip install -e .[dev]
# Run the test suite
python ignore/test.py
# Or use pytest if configured
pytest
# Format and lint
black src
ruff check src
License
MIT License - see LICENSE for details.
Contributing
Contributions are welcome! Please open an issue or submit a pull request.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file quanta_lang-0.1.10.tar.gz.
File metadata
- Download URL: quanta_lang-0.1.10.tar.gz
- Upload date:
- Size: 70.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7bae3aaaf6ba8e981811d5460ecf912f42fff21afa634be65749fc411e050f70
|
|
| MD5 |
52224554c3fd36cc485ec437227b7e21
|
|
| BLAKE2b-256 |
2d104a94f53432b93136bd23d367de16c747eba6b8d6beee02c91a8e05b4cf1f
|
File details
Details for the file quanta_lang-0.1.10-py3-none-any.whl.
File metadata
- Download URL: quanta_lang-0.1.10-py3-none-any.whl
- Upload date:
- Size: 54.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
46b82c40cbeb2caea3959a8f7104acd08ff8a7f3a72a195c7d18a565d6309dcd
|
|
| MD5 |
4b68ebd836ee88ca0c2e7315d23e1d69
|
|
| BLAKE2b-256 |
9aa058055ce1dce6f7b54ee3363c3bf2881a30c2bd1fc27f94897bab93d9b1ab
|