Circuit DSL
MIMIQ provides a convenient Domain Specific Language (DSL) for defining circuits, blocks, and custom gate declarations. This DSL allows for a more concise and readable syntax compared to the standard push! or insert! methods.
Creating Circuits
The @circuit macro creates a new Circuit and populates it with instructions defined in the block.
Syntax
@circuit begin
@on GateType(args...) q=qubits c=bits z=zvars
# ...
endor
@circuit do
@on GateType(args...) q=qubits c=bits z=zvars
# ...
endThe instructions are added using the special macro @on.
Examples
julia> c = @circuit begin
@on GateH() q=1
@on GateCX() q=(1, 2)
end
2-qubit circuit with 2 instructions:
├── H @ q[1]
└── CX @ q[1], q[2]Creating Blocks
The @block macro works similarly to @circuit but returns a Block object, which can be useful for defining reusable sub-circuits.
Example
julia> b = @block begin
@on GateX() q=1
@on GateZ() q=1
end
BlockGate Declarations
The @gatedecl macro allows you to define new gate types with custom arguments and instructions. This is a powerful feature for creating parametric gates or higher-level abstractions.
Syntax
@gatedecl Name(args...) begin
# ... instructions ...
endExamples
defining a custom ansatz:
julia> @gatedecl MyAnsatz(θ) begin
@on GateX() q=1
@on GateRX(θ) q=2
@on GateCX() q=(1, 2)
end
MyAnsatz
julia> @variables λ
(λ,)
julia> g = MyAnsatz(λ)
MyAnsatz(λ)You can then use this custom gate in a circuit:
julia> c = Circuit()
julia> push!(c, g, 1, 2)
2-qubit circuit with 1 instructions:
└── MyAnsatz(λ) @ q[1], q[2]The @on Syntax
The @on macro is used within the DSL blocks to define instructions. It supports specifying targets for quantum registers (q), classical registers (c), and Z-registers (z).
- usage:
@on Operation(args...) [q=...] [c=...] [z=...]
The targets can be single integers, tuples, vectors, or ranges.
@on GateH() q=1 # Single qubit
@on GateCX() q=(1, 2) # Tuple of qubits
@on GateX() q=1:5 # Range (broadcast)
@on Measure() q=1 c=1 # Qubit and classical bit