QReg arguments, and b01t wraps it in a typed object — either an ExactDSLFunction or a DSLFunction — that you call .build_exact() or .build() on to produce a compiled program. Your choice of decorator determines which gates are allowed, what certification the program receives, and whether classical branching is permitted.
@coherent
@coherent wraps the decorated function in an ExactDSLFunction with Certification.SAFE. Use it for programs that must be fully ancilla-certified — every ancilla qubit is guaranteed to return to |0⟩ by construction. The compiler enforces the complete ancilla discipline (compute / phase / uncompute) and rejects any gate not in the exact gate set ({X, H, Z, S, S†, T, T†, CX, CZ, SWAP, CCX, CCZ, MCX, MCZ}).
When to use: whenever you need a structurally certified unitary channel. The hero theorem applies: if .build_exact() succeeds, the program is provably safe.
Key rules:
- Only exact gates are allowed.
rx,ry,rz,cry,crzraiseDSLValidationError. measureis forbidden.if_thenis forbidden.- Ancilla blocks must complete at least one full
compute/phase(orapply) /uncomputecycle. - A
@coherentfunction may not call a@primitivefunction outside of an ancillacomputeorphaseblock.
@primitive
@primitive wraps the decorated function in an ExactDSLFunction with Certification.PRIMITIVE. The gate set and syntax rules are identical to @coherent, but scratch registers are caller-managed rather than certified by the compiler. Use @primitive for low-level building blocks where you manage ancilla cleanliness yourself, or where the ancilla is shared with the calling function.
When to use: for subroutines that intentionally leave ancilla in a non-zero state for a caller to clean up, or for inner routines that are called from within a compute or phase block of a @coherent function.
Key rules:
- Same exact gate set as
@coherent. - A
@coherentfunction can call a@primitivefunction only from inside acompute(...)orphase(...)block. - Calling a
@primitivefunction at the top level of a@coherentbody raisesDSLValidationError.
@parametric
@parametric wraps the decorated function in a DSLFunction with Effect.COHERENT. It unlocks the parametric rotation gates (rx, ry, rz, cry, crz) while keeping unitary semantics — no measurement, no classical branching. The resulting IRProgram has effect = Effect.COHERENT.
When to use: variational algorithms (VQE, QAOA) and any circuit that needs continuous-angle rotations. Programs that pass the safety checker (is_safe_program) are marked is_safe = True in the returned IRProgram.
Key rules:
- All exact gates plus
rx,ry,rz,cry,crzare allowed. measureandif_thenare forbidden.- A
@parametricfunction cannot call an@adaptivefunction.
@adaptive
@adaptive wraps the decorated function in a DSLFunction with Effect.ADAPTIVE. Adaptive programs can measure qubits and branch on classical results via if_then. The returned IRProgram has effect = Effect.ADAPTIVE and is_safe = False (adaptive programs are never safe by the safety model).
When to use: measurement-based protocols, quantum error correction, and teleportation circuits that require mid-circuit measurement and feed-forward.
Key rules:
- All gates from both the exact and parametric sets are allowed.
measure,measure_all, andif_thenare allowed.- An
@adaptivefunction can call@parametricfunctions, but not vice versa.
ExactDSLFunction.build_exact()
Compiles a@coherent or @primitive function into an ExactProgram.
One argument per register in the decorated function. Each argument is either a
("name", size) tuple or an existing QReg object. Register names must be unique.ExactProgram with fields name, regs, ops, and certification.
Raises: DSLValidationError if any gate, ancilla, or structural rule is violated during the build.
DSLFunction.build()
Compiles a@parametric or @adaptive function into an IRProgram.
One argument per register in the decorated function. Each argument is either a
("name", size) tuple or an existing QReg object. Register names must be unique.IRProgram with fields name, effect, regs, ops, and is_safe.
Raises: DSLValidationError if any rule is violated during the build.