The core quantum bug
In quantum computing, an ancilla is a temporary helper qubit that you borrow to carry out some intermediate computation. The contract is simple: you return it to |0⟩ when you’re done. If you don’t, the ancilla stays entangled with your system register. Any subsequent operation on the system now has an invisible dependency on a qubit you thought was gone. The program silently degrades from a unitary channel — a reversible, information-preserving transformation — into a mixed channel that loses quantum information. This bug is called a dirty ancilla. It is remarkably easy to write and virtually impossible to catch by inspection.Why existing frameworks miss it
Qiskit, Cirq, and Q# all operate on a flat list of gate operations. They have no structural notion of “this qubit is a temporary helper that must be returned clean.” As long as the circuit is syntactically valid, they accept it. Consider the classic mistake:H · Z · H should work. But H is not a permutation gate. It creates superposition, so between the compute and uncompute steps the ancilla is entangled with the system. The “uncomputation” does not undo that entanglement. The ancilla is dirty. The program is a mixed channel.
b01t rejects this at build time. The compute block accepts only permutation gates. Permutation gates are classical-reversible: they map computational basis states to computational basis states without creating superposition. If you only use permutation gates to copy information into an ancilla, you can always reverse that copy exactly, and the ancilla returns to |0⟩.
The Hero Theorem
b01t’s correctness guarantee is machine-checked in Lean 4:
Hero Theorem: every well-typed @coherent program is a proven unitary channel.
“Well-typed” here means the program passed b01t’s build-time checks — specifically, that all ancilla blocks follow the compute/phase/uncompute discipline with the correct gate restrictions. You don’t need to simulate the density matrix. You don’t need to inspect the circuit. If build_exact() returns without raising, the program is structurally certified.
The Lean proof is machine-checked, not just a manual argument. The certification is as strong as the proof assistant, not as strong as the programmer’s intuition.
Certification levels
EveryExactProgram carries a certification field that records which level of guarantee the program was built to:
Certification.SAFE
Produced by
@coherent. All scratch registers are managed through the ancilla discipline. Ancilla cleanliness is structurally certified. The Hero Theorem applies.Certification.PRIMITIVE
Produced by
@primitive. Uses the exact gate set and is coherent (unitary), but scratch registers are caller-managed. The DSL does not certify ancilla cleanliness — that responsibility is yours.The two safety guarantees
ACertification.SAFE program gives you two independent guarantees:
1. Ancilla cleanliness. Every ancilla qubit that enters a with ancilla(...) block exits that block in |0⟩. This is enforced by the gate restrictions on compute and phase blocks, plus the automatic inversion performed by uncompute(). It is a structural property of the program’s AST — it cannot be violated without raising a DSLValidationError.
2. Unitary channel. Because all ancillae are clean and the gate set is exactly {H, S, T, CNOT} and their derivatives, the total transformation is a unitary operator on the system register. No quantum information is lost. The program is safe to compose with other certified programs without worrying about hidden entanglement.
What build_exact() checks
When you call oracle.build_exact(("sys", 1)), b01t:
Validates the gate set
Rejects any gate not in the exact set (H, X, Z, S, T, SDG, TDG, CX, CZ, SWAP, CCX, CCZ, MCX, MCZ). Parameterized rotations like
rx, ry, and rz are forbidden.Validates ancilla block structure
Confirms that every
with ancilla(...) block contains at least one complete compute/phase/uncompute cycle, in that order.Validates gate restrictions
Confirms that
compute blocks use only permutation gates (X, CX, CCX, SWAP, MCX) and phase blocks use only diagonal gates (Z, CZ, CCZ, S, SDG, T, TDG, MCZ).Auto-generates uncomputation
Computes the gate-by-gate inverse of the
compute block and inserts it as uncompute_ops in the AST.DSLValidationError with a clear message pointing to the exact violation — before any circuit is submitted to a backend.