diff --git a/docs/explanation/analog_interface.md b/docs/explanation/analog_interface.md
deleted file mode 100644
index dfac8e30..00000000
--- a/docs/explanation/analog_interface.md
+++ /dev/null
@@ -1,150 +0,0 @@
-The analog interface represents a quantum experiment in terms of time evolving Hamiltonians.
-
-## Quantum Degrees of Freedom
-
-In this analog interface, we allow for 2 different quantum degrees of freedom:
-
-/// tab | Qubits
-Qubits consist of a pair of states (spin $\uparrow$ and spin $\downarrow$).
-///
-/// tab | Bosonic
-Bosonic degrees of freedom form a fock space.
-///
-
-## Operators
-
-/// tab | Pauli
-
-The basis of operators for the qubits are the Pauli operators:
-
-- $\sigma^I$
[][oqd_core.interface.analog.operator.PauliI]
-- $\sigma^x$ [][oqd_core.interface.analog.operator.PauliX]
-- $\sigma^y$ [][oqd_core.interface.analog.operator.PauliY]
-- $\sigma^z$ [][oqd_core.interface.analog.operator.PauliZ]
-
-///
-
-/// tab | Ladder
-
-The basis of operators for the bosonic degree of freedom are the ladder operators:
-
-- $a$ [][oqd_core.interface.analog.operator.Annihilation]
-- $a^{\dagger}$ [][oqd_core.interface.analog.operator.Creation]
-- $I$ [][oqd_core.interface.analog.operator.Identity]
-
-///
-
-### Operator Operations
-
-The basis operators can be combined with the operations:
-
-- Addition [][oqd_core.interface.analog.operator.OperatorAdd]
-
-- Multiplication [][oqd_core.interface.analog.operator.OperatorMul]
-
-- Tensor Product [][oqd_core.interface.analog.operator.OperatorKron]
-
-- Scalar Multiplication [][oqd_core.interface.analog.operator.OperatorScalarMul]
-
-## Hamiltonian
-
-The Hamiltonian is an operator that governs interactions between quantum degrees of freedom.
-
-The state of the system evolves under the unitary:
-
-$$
-U = e^{i H t}
-$$
-
-
-/// admonition | Example
- type: example
-Spin-dependent force Hamiltonian:
-
-$$
-H = \sigma^+ \otimes a + \sigma^- \otimes a^{\dagger}
-$$
-
-```py
-H = PauliPlus() @ Annihilation() + PauliMinus() @ Creation()
-```
-
-///
-
-## Analog Gate [][oqd_core.interface.analog.operation.AnalogGate]
-
-The [AnalogGate][oqd_core.interface.analog.operation.AnalogGate] wraps the Hamiltonian.
-
-```py
-gate = AnalogGate(hamiltonian=H)
-```
-
-
-/// admonition | Note
- type: note
-The purpose of the [AnalogGate][oqd_core.interface.analog.operation.AnalogGate] is to accomodate dissipation during the time evolution in the future.
-///
-
-## Analog Circuit [][oqd_core.interface.analog.operation.AnalogCircuit]
-
-The [AnalogCircuit][oqd_core.interface.analog.operation.AnalogCircuit] is the top level structure that describes a quantum experiment at the analog layer.
-
-An [AnalogCircuit][oqd_core.interface.analog.operation.AnalogCircuit] consist of different kinds of statements:
-
-/// tab | Initialize
-
-//// html | div[style='float: right']
-[][oqd_core.interface.analog.operation.Initialize]
-////
-
-Initializes all quantum degrees of freedom in the experiment:
-
-- Qubits $\rightarrow$ $| \downarrow \rangle$
-- Bosons $\rightarrow$ $| 0 \rangle$
-
-
-//// admonition | Not Implemented
- type: warning
-Initialize describes a global initialization. There is no support for individual initialization currently.
-////
-///
-
-/// tab | Evolve
-
-//// html | div[style='float: right']
-[][oqd_core.interface.analog.operation.Evolve]
-////
-
-Evolve desribes the evolution of the system with an AnalogGate for a set duration.
-///
-
-/// tab | Measure
-
-//// html | div[style='float: right']
-[][oqd_core.interface.analog.operation.Measure]
-////
-
-Performs a projective measurement of all quantum degrees of freedom.
-
-
-//// admonition | Not Implemented
- type: warning
-Measure describes a global measurement. There is no support for individual measurement currently.
-////
-///
-
-## Usage
-
-
-/// admonition | Example
- type: example
-
-```py
-circuit = AnalogCircuit()
-
-circuit.initialize()
-circuit.evolve(gate, duration=1)
-circuit.measure()
-```
-
-///
diff --git a/docs/explanation/atomic_interface.md b/docs/explanation/atomic_interface.md
deleted file mode 100644
index ca6e7d61..00000000
--- a/docs/explanation/atomic_interface.md
+++ /dev/null
@@ -1,328 +0,0 @@
-The atomic interface expresses quantum information experiments in terms of light-matter interactions.
-
-## System [][oqd_core.interface.atomic.system.System]
-
-The system describes the properties of the trapped-ion quantum device.
-
-### Ion [][oqd_core.interface.atomic.system.Ion]
-
-An ion is described by its set of electronic energy levels. Each energy level has its associated quantum numbers:
-
-- Principal quantum number
-- Spin angular momentum, $S$
-- Orbital angular momentum, $L$
-- Spin-orbital angular momentum, $J = S + L$
-- Nuclear angular momentum, $I$
-- Spin-orbital-nuclear angular momentum, $F = J + I$
-- Magnetization, $m_F$
-- Energy, $E$
-
-with the set of electronic energy levels, we assign two states to be the qubit states.
-
-Manipulating the qubit states involves driving transitions between the qubit states of the ions, either directly or indirectly.
-
-
-/// admonition | Example
- type: example
-
-Definiition of an [`Ion`][oqd_core.interface.atomic.system.Ion] for $^{171}\mathrm{Yb}^+$:
-
-```python
-
-downstate = Level(
- label="q0",
- principal=6,
- spin=1/2,
- orbital=0,
- nuclear=1/2,
- spin_orbital=1/2,
- spin_orbital_nuclear=0,
- spin_orbital_nuclear_magnetization=0,
- energy=0,
-)
-upstate = Level(
- label="q1",
- principal=6,
- spin=1/2,
- orbital=0,
- nuclear=1/2,
- spin_orbital=1/2,
- spin_orbital_nuclear=1,
- spin_orbital_nuclear_magnetization=0,
- energy=2*pi*12.643e9,
-)
-estate = Level(
- label="e0",
- principal=5,
- spin=1/2,
- orbital=1,
- nuclear=1/2,
- spin_orbital=1/2,
- spin_orbital_nuclear=0,
- spin_orbital_nuclear_magnetization=0,
- energy=2*pi*811.52e12,
-)
-
-Yb171 = Ion(
- mass=171,
- charge=1,
- position=[0,0,0],
- levels=[
- downstate,
- upstate,
- estate,
- ],
- transitions=[
- Transition(
- label="q0->q1",
- level1=downstate,
- level2=upstate,
- einsteinA=...,
- ),
- Transition(
- label="q0->e0",
- level1=downstate,
- level2=estate,
- einsteinA=...,
- ),
- Transition(
- label="q1->e0",
- level1=upstate,
- level2=estate,
- einsteinA=...,
- ),
- ],
-)
-```
-
-///
-
-### Phonon [][oqd_core.interface.atomic.system.Phonon]
-
-In the trapped-ion system the system exhibits collective phonon modes, which are bosonic degrees of freedom.
-
-These phonon modes are characterized by:
-
-- Energy (eigenfrequency)
-- Profile of the collective phonon mode in terms of the ions' motion (eigenvector)
-
-
-/// admonition | Example
- type: example
-
-Definition of the set of phonon modes for a trapped-ion system with a single ion:
-
-```python
-COM_x = Phonon(
- energy=2*pi*5e6,
- eigenvector=[1,0,0]
-)
-COM_y = Phonon(
- energy=2*pi*5e6,
- eigenvector=[0,1,0]
-)
-COM_z = Phonon(
- energy=2*pi*1e6,
- eigenvector=[0,0,1]
-)
-```
-
-///
-
-### Other
-
-
-/// admonition | Not Implemented
- type: warning
-The system is further described by a list of experimental parameters that require calibration to determine, e.g.:
-
-- Maximum laser power
-- Laser lock frequency
-- etc.
-
-These parameters will in the future be included in the [`System`][oqd_core.interface.atomic.system.System].
-
-The [`System`][oqd_core.interface.atomic.system.System] will be retrieved from a calibration database to determine the current state of the system and the status of all calibrations required to run quantum experiments.
-
-///
-
-## Pulse Program [][oqd_core.interface.atomic.protocol.Protocol]
-
-The pulse program for a quantum experiment is described by a [`Protocol`][oqd_core.interface.atomic.protocol.Protocol]. The protocol defines the list of optical channels in the experiment and the real-time scheduling of pulses of the optical channels in order to perform the quantum experiment.
-
-### Optical Channel [][oqd_core.interface.atomic.protocol.Beam]
-
-An optical channel is described by a [`Beam`][oqd_core.interface.atomic.protocol.Beam] with the following parameters:
-
-- Transition of the ion for which to reference the Beam to.
-- Rabi frequency to drive the referenced transition with.
-- Detuning from the resonance of the referenced transition.
-- Phase of the beam relative to the clock of the ion.
-- Polarization of the beam.
-- Wavevector of the beam.
-- Target ion addressed by the beam.
-
-
-/// admonition | Example
- type: example
-
-Beam used to drive a microwave Rabi oscillation in the X-axis:
-
-```python
-microwave_beam = Beam(
- transition=Transition(level1=downstate,level2=upstate,...),
- rabi= 2*pi*1e6,
- detuning=0,
- phase=0,
- polarization=...
- wavevector=...
- target=0
-)
-```
-
-///
-
-
-/// admonition | Note
- type: note
-
-The following parameters may be specified with the [math interface](#explanation/math_interface):
-
-- Rabi frequency
-- Detuning
-- Phase
- ///
-
-### Pulse [][oqd_core.interface.atomic.protocol.Pulse]
-
-A pulse turns on an optical channel for a duration of time.
-
-
-/// admonition | Example
- type: example
-
-Pulse that drives a microwave Rabi oscillation in the X-axis for a duration $T$:
-
-```python
-microwave_pulse = Pulse(
- beam=microwave_beam,
- duration=T,
-)
-```
-
-///
-
-#### Measurement
-
-To perform a measurement, we not only have to turn on an optical channel, we also have to turn on a detector, this is handled by the [`MeasurePulse`][oqd_core.interface.atomic.protocol.MeasurePulse].
-
-
-/// admonition | Example
- type: example
-
-Pulse that drives a fluorescent transition and turns on the detector for a duration $T$:
-
-```python
-detection_pulse = MeasurePulse(
- beam=detection_beam,
- duration=T,
-)
-```
-
-///
-
-### Composition of Protocols
-
-The pulse program for a quantum experiment is usually more complex than a pulse of a single beam. This is handled with [`SequentialProtocol`][oqd_core.interface.atomic.protocol.SequentialProtocol] and [`ParallelProtocol`][oqd_core.interface.atomic.protocol.ParallelProtocol].
-
-/// tab | `SequentialProtocol`
-
-//// html | div[style='float: right']
-[][oqd_core.interface.atomic.protocol.SequentialProtocol]
-////
-
-Sequential protocol applies a set of pulses or subprotocols sequentially in time.
-
-
-//// admonition | Example
- type: example
-
-The following protocol is for a Rabi flop and a measurement:
-
-```python
-microwave_beam = Beam(
- transition=Transition(level1=downstate,level2=upstate,...),
- rabi= 2*pi*1e6,
- detuning=0,
- phase=0,
- polarization=...
- wavevector=...
- target=0
-)
-
-detection_beam = Beam(
- transition=Transition(level1=upstate,level2=estate,...),
- rabi= 2*pi*1e6,
- detuning=0,
- phase=0,
- polarization=...
- wavevector=...
- target=0
-)
-
-protocol = SequentialProtocol(
- sequence=[
- Pulse(beam=raman1_beam,duration=T),
- Pulse(beam=raman2_beam,duration=100e-6)
- ]
- )
-```
-
-////
-///
-
-/// tab | `ParallelProtocol`
-
-//// html | div[style='float: right']
-[][oqd_core.interface.atomic.protocol.ParallelProtocol]
-////
-
-Sequential protocol applies a set of pulses or subprotocols parallel in time.
-
-
-//// admonition | Example
- type: example
-
-The following protocol is for a two-photon Raman transition:
-
-```python
-raman1_beam = Beam(
- transition=Transition(level1=downstate,level2=estate,...),
- rabi= 2*pi*1e6,
- detuning=2*pi*1e9,
- phase=0,
- polarization=...
- wavevector=...
- target=0
-)
-raman2_beam = Beam(
- transition=Transition(level1=upstate,level2=estate,...),
- rabi= 2*pi*1e6,
- detuning=2*pi*1e9,
- phase=0,
- polarization=...
- wavevector=...
- target=0
-)
-
-protocol = ParallelProtocol(
- sequence=[
- Pulse(beam=raman1_beam,duration=T),
- Pulse(beam=raman2_beam,duration=T)
- ]
- )
-```
-
-////
-
-///
diff --git a/docs/explanation/canonicalization.md b/docs/explanation/canonicalization.md
deleted file mode 100644
index 6d29c498..00000000
--- a/docs/explanation/canonicalization.md
+++ /dev/null
@@ -1,504 +0,0 @@
-Canonicalization is used to remove redundancy in the representation.
-
-Consider the following two Hamiltonians:
-
-$$
-H_{1} = X \otimes I + I \otimes X
-$$
-
-$$
-H_{2} = I \otimes X + X \otimes I
-$$
-
-$H_{1}$ is equivalent to $H_{2}$. Hence we convert the operators to a canonical form and the canonical form of the above operator is:
-
-$$
-H_{c} = 1\cdot(I \otimes X) + 1\cdot(X \otimes I)
-$$
-
-These canonicalization steps (e.g. distribution) are done by implementing a `RewriteRule` with the corresponding logic.
-
-## Canonicalization Rules
-
-### Distribution [][oqd_core.compiler.analog.rewrite.OperatorDistribute]
-
-[`Distribution`][oqd_core.compiler.analog.rewrite.canonicalize.OperatorDistribute] distributes the multiplication, scalar multiplication and tensor product of operators over the addition of operators.
-
-
-/// admonition | Example
- type: example
-
-$$X \otimes (Y + Z) \longrightarrow X \otimes Y + X \otimes Z$$
-
-//// tab | Original Graph
-
-```mermaid
- graph TD
- element0("PauliX"):::Pauli
- element1("PauliY"):::Pauli
- element2("PauliZ"):::Pauli
- element3("OperatorAdd"):::OperatorAdd
- element3 --> element1 & element2
- element4("OperatorKron"):::OperatorKron
- element4 --> element0 & element3
- classDef Pauli stroke:#800000,stroke-width:3px
- classDef Ladder stroke:#800000,stroke-width:3px
- classDef OperatorAdd stroke:#800000,stroke-width:3px
- classDef OperatorScalarMul stroke:#800000,stroke-width:3px
- classDef OperatorKron stroke:#800000,stroke-width:3px
- classDef OperatorMul stroke:#800000,stroke-width:3px
- classDef MathExpr stroke:#800000,stroke-width:3px
-```
-
-////
-
-//// tab | Transformed Graph
-
-```mermaid
- graph TD
- element0("PauliX"):::Pauli
- element1("PauliY"):::Pauli
- element2("OperatorKron"):::OperatorKron
- element2 --> element0 & element1
- element3("PauliX"):::Pauli
- element4("PauliZ"):::Pauli
- element5("OperatorKron"):::OperatorKron
- element5 --> element3 & element4
- element6("OperatorAdd"):::OperatorAdd
- element6 --> element2 & element5
- classDef Pauli stroke:#800000,stroke-width:3px
- classDef Ladder stroke:#800000,stroke-width:3px
- classDef OperatorAdd stroke:#800000,stroke-width:3px
- classDef OperatorScalarMul stroke:#800000,stroke-width:3px
- classDef OperatorKron stroke:#800000,stroke-width:3px
- classDef OperatorMul stroke:#800000,stroke-width:3px
- classDef MathExpr stroke:#800000,stroke-width:3px
-```
-
-////
-///
-
-### Gather Math Expression [][oqd_core.compiler.analog.rewrite.GatherMathExpr]
-
-[`GatherMath`][oqd_core.compiler.analog.rewrite.canonicalize.GatherMathExpr] centralizes the coefficients of the operators by gathering them.
-
-
-/// admonition | Example
- type: example
-
-$$ X \times 3 \times I \longrightarrow 3 \times (X \times I)$$
-//// tab | Original Graph
-
-```mermaid
- graph TD
- element0("MathExpr
--------
expr = #quot;3#quot;"):::MathExpr
- element1("PauliX"):::Pauli
- element2("OperatorScalarMul"):::OperatorScalarMul
- element2 --> element0 & element1
- element3("PauliI"):::Pauli
- element4("OperatorMul"):::OperatorMul
- element4 --> element2 & element3
- classDef Pauli stroke:#800000,stroke-width:3px
- classDef Ladder stroke:#800000,stroke-width:3px
- classDef OperatorAdd stroke:#800000,stroke-width:3px
- classDef OperatorScalarMul stroke:#800000,stroke-width:3px
- classDef OperatorKron stroke:#800000,stroke-width:3px
- classDef OperatorMul stroke:#800000,stroke-width:3px
- classDef MathExpr stroke:#800000,stroke-width:3px
-```
-
-////
-
-//// tab | Transformed Graph
-
-```mermaid
- graph TD
- element0("MathExpr
--------
expr = #quot;3#quot;"):::MathExpr
- element1("PauliX"):::Pauli
- element2("PauliI"):::Pauli
- element3("OperatorMul"):::OperatorMul
- element3 --> element1 & element2
- element4("OperatorScalarMul"):::OperatorScalarMul
- element4 --> element0 & element3
- classDef Pauli stroke:#800000,stroke-width:3px
- classDef Ladder stroke:#800000,stroke-width:3px
- classDef OperatorAdd stroke:#800000,stroke-width:3px
- classDef OperatorScalarMul stroke:#800000,stroke-width:3px
- classDef OperatorKron stroke:#800000,stroke-width:3px
- classDef OperatorMul stroke:#800000,stroke-width:3px
- classDef MathExpr stroke:#800000,stroke-width:3px
-```
-
-////
-///
-
-### Proper Order [][oqd_core.compiler.analog.rewrite.ProperOrder]
-
-[`ProperOrder`][oqd_core.compiler.analog.rewrite.canonicalize.ProperOrder] uses the associative property to convert a chain of [`OperatorAdd`][oqd_core.interface.analog.operator.OperatorAdd] or a chain of [`OperatorMul`][oqd_core.interface.analog.operator.OperatorMul] and reorder the operation order from left to right.
-
-
-/// admonition | Example
- type: example
-
-$$ X \otimes (Y + Z) \longrightarrow (X + Y) + Z $$
-
-//// tab | Original Graph
-
-```mermaid
- graph TD
- element0("PauliX"):::Pauli
- element1("PauliY"):::Pauli
- element2("PauliZ"):::Pauli
- element3("OperatorAdd"):::OperatorAdd
- element3 --> element1 & element2
- element4("OperatorAdd"):::OperatorAdd
- element4 --> element0 & element3
- classDef Pauli stroke:#800000,stroke-width:3px
- classDef Ladder stroke:#800000,stroke-width:3px
- classDef OperatorAdd stroke:#800000,stroke-width:3px
- classDef OperatorScalarMul stroke:#800000,stroke-width:3px
- classDef OperatorKron stroke:#800000,stroke-width:3px
- classDef OperatorMul stroke:#800000,stroke-width:3px
- classDef MathExpr stroke:#800000,stroke-width:3px
-```
-
-////
-
-//// tab | Transformed Graph
-
-```mermaid
- graph TD
- element0("PauliX"):::Pauli
- element1("PauliY"):::Pauli
- element2("OperatorAdd"):::OperatorAdd
- element2 --> element0 & element1
- element3("PauliZ"):::Pauli
- element4("OperatorAdd"):::OperatorAdd
- element4 --> element2 & element3
- classDef Pauli stroke:#800000,stroke-width:3px
- classDef Ladder stroke:#800000,stroke-width:3px
- classDef OperatorAdd stroke:#800000,stroke-width:3px
- classDef OperatorScalarMul stroke:#800000,stroke-width:3px
- classDef OperatorKron stroke:#800000,stroke-width:3px
- classDef OperatorMul stroke:#800000,stroke-width:3px
- classDef MathExpr stroke:#800000,stroke-width:3px
-```
-
-////
-///
-
-### Pauli Algebra [][oqd_core.compiler.analog.rewrite.PauliAlgebra]
-
-[`PauliAlgebra`][oqd_core.compiler.analog.rewrite.canonicalize.PauliAlgebra] applies the Pauli algebra to simplify the operator.
-
-
-/// admonition | Example
- type: example
-
-$$ X \times Y + I \times I \longrightarrow iZ + I $$
-//// tab | Original Graph
-
-```mermaid
- graph TD
- element0("PauliX"):::Pauli
- element1("PauliY"):::Pauli
- element2("OperatorMul"):::OperatorMul
- element2 --> element0 & element1
- element3("PauliI"):::Pauli
- element4("PauliI"):::Pauli
- element5("OperatorMul"):::OperatorMul
- element5 --> element3 & element4
- element6("OperatorAdd"):::OperatorAdd
- element6 --> element2 & element5
- classDef Pauli stroke:#800000,stroke-width:3px
- classDef Ladder stroke:#800000,stroke-width:3px
- classDef OperatorAdd stroke:#800000,stroke-width:3px
- classDef OperatorScalarMul stroke:#800000,stroke-width:3px
- classDef OperatorKron stroke:#800000,stroke-width:3px
- classDef OperatorMul stroke:#800000,stroke-width:3px
- classDef MathExpr stroke:#800000,stroke-width:3px
-```
-
-////
-
-//// tab | Transformed Graph
-
-```mermaid
- graph TD
- element0("MathExpr
--------
expr = #quot;1j#quot;"):::MathExpr
- element1("PauliZ"):::Pauli
- element2("OperatorScalarMul"):::OperatorScalarMul
- element2 --> element0 & element1
- element3("PauliI"):::Pauli
- element4("OperatorAdd"):::OperatorAdd
- element4 --> element2 & element3
- classDef Pauli stroke:#800000,stroke-width:3px
- classDef Ladder stroke:#800000,stroke-width:3px
- classDef OperatorAdd stroke:#800000,stroke-width:3px
- classDef OperatorScalarMul stroke:#800000,stroke-width:3px
- classDef OperatorKron stroke:#800000,stroke-width:3px
- classDef OperatorMul stroke:#800000,stroke-width:3px
- classDef MathExpr stroke:#800000,stroke-width:3px
-```
-
-////
-///
-
-### Normal Order [][oqd_core.compiler.analog.rewrite.NormalOrder]
-
-[`NormalOrder`][oqd_core.compiler.analog.rewrite.canonicalize.NormalOrder] puts the ladder operators into normal order.
-
-
-/// admonition | Example
- type: example
-
-$$ C \times A + A \times C \longrightarrow C \times A + C \times A + J$$
-//// tab | Original Graph
-
-```mermaid
- graph TD
- element0("Creation"):::Ladder
- element1("Annihilation"):::Ladder
- element2("OperatorMul"):::OperatorMul
- element2 --> element0 & element1
- element3("Annihilation"):::Ladder
- element4("Creation"):::Ladder
- element5("OperatorMul"):::OperatorMul
- element5 --> element3 & element4
- element6("OperatorAdd"):::OperatorAdd
- element6 --> element2 & element5
- classDef Pauli stroke:#800000,stroke-width:3px
- classDef Ladder stroke:#800000,stroke-width:3px
- classDef OperatorAdd stroke:#800000,stroke-width:3px
- classDef OperatorScalarMul stroke:#800000,stroke-width:3px
- classDef OperatorKron stroke:#800000,stroke-width:3px
- classDef OperatorMul stroke:#800000,stroke-width:3px
- classDef MathExpr stroke:#800000,stroke-width:3px
-```
-
-////
-
-//// tab | Transformed Graph
-
-```mermaid
- graph TD
- element0("Creation"):::Ladder
- element1("Annihilation"):::Ladder
- element2("OperatorMul"):::OperatorMul
- element2 --> element0 & element1
- element3("Creation"):::Ladder
- element4("Annihilation"):::Ladder
- element5("OperatorMul"):::OperatorMul
- element5 --> element3 & element4
- element6("Identity"):::Ladder
- element7("OperatorAdd"):::OperatorAdd
- element7 --> element5 & element6
- element8("OperatorAdd"):::OperatorAdd
- element8 --> element2 & element7
- classDef Pauli stroke:#800000,stroke-width:3px
- classDef Ladder stroke:#800000,stroke-width:3px
- classDef OperatorAdd stroke:#800000,stroke-width:3px
- classDef OperatorScalarMul stroke:#800000,stroke-width:3px
- classDef OperatorKron stroke:#800000,stroke-width:3px
- classDef OperatorMul stroke:#800000,stroke-width:3px
- classDef MathExpr stroke:#800000,stroke-width:3px
-```
-
-////
-///
-
-### Prune Identity [][oqd_core.compiler.analog.rewrite.PruneIdentity]
-
-[`PruneIdentity`][oqd_core.compiler.analog.rewrite.canonicalize.PruneIdentity] prunes the unnecessary ladder identities from the graph.
-
-
-/// admonition | Example
- type: example
-
-$$ C\times A \times J\longrightarrow C \times A$$
-//// tab | Original Graph
-
-```mermaid
- graph TD
- element0("Creation"):::Ladder
- element1("Annihilation"):::Ladder
- element2("OperatorMul"):::OperatorMul
- element2 --> element0 & element1
- element3("Identity"):::Ladder
- element4("OperatorMul"):::OperatorMul
- element4 --> element2 & element3
- classDef Pauli stroke:#800000,stroke-width:3px
- classDef Ladder stroke:#800000,stroke-width:3px
- classDef OperatorAdd stroke:#800000,stroke-width:3px
- classDef OperatorScalarMul stroke:#800000,stroke-width:3px
- classDef OperatorKron stroke:#800000,stroke-width:3px
- classDef OperatorMul stroke:#800000,stroke-width:3px
- classDef MathExpr stroke:#800000,stroke-width:3px
-```
-
-////
-
-//// tab | Transformed Graph
-
-```mermaid
- graph TD
- element0("Creation"):::Ladder
- element1("Annihilation"):::Ladder
- element2("OperatorMul"):::OperatorMul
- element2 --> element0 & element1
- classDef Pauli stroke:#800000,stroke-width:3px
- classDef Ladder stroke:#800000,stroke-width:3px
- classDef OperatorAdd stroke:#800000,stroke-width:3px
- classDef OperatorScalarMul stroke:#800000,stroke-width:3px
- classDef OperatorKron stroke:#800000,stroke-width:3px
- classDef OperatorMul stroke:#800000,stroke-width:3px
- classDef MathExpr stroke:#800000,stroke-width:3px
-```
-
-////
-///
-
-### Sorted Order [][oqd_core.compiler.analog.rewrite.SortedOrder]
-
-[`SortedOrder`][oqd_core.compiler.analog.rewrite.canonicalize.SortedOrder] sorts the addition terms in operators into a predefined order.
-
-
-/// admonition | Example
- type: example
-
-$$ X \otimes I + I \otimes X \longrightarrow I \otimes X + X \otimes I$$
-//// tab | Original Graph
-
-```mermaid
- graph TD
- element0("PauliX"):::Pauli
- element1("PauliI"):::Pauli
- element2("OperatorKron"):::OperatorKron
- element2 --> element0 & element1
- element3("PauliI"):::Pauli
- element4("PauliX"):::Pauli
- element5("OperatorKron"):::OperatorKron
- element5 --> element3 & element4
- element6("OperatorAdd"):::OperatorAdd
- element6 --> element2 & element5
- classDef Pauli stroke:#800000,stroke-width:3px
- classDef Ladder stroke:#800000,stroke-width:3px
- classDef OperatorAdd stroke:#800000,stroke-width:3px
- classDef OperatorScalarMul stroke:#800000,stroke-width:3px
- classDef OperatorKron stroke:#800000,stroke-width:3px
- classDef OperatorMul stroke:#800000,stroke-width:3px
- classDef MathExpr stroke:#800000,stroke-width:3px
-```
-
-////
-
-//// tab | Transformed Graph
-
-```mermaid
- graph TD
- element0("PauliI"):::Pauli
- element1("PauliX"):::Pauli
- element2("OperatorKron"):::OperatorKron
- element2 --> element0 & element1
- element3("PauliX"):::Pauli
- element4("PauliI"):::Pauli
- element5("OperatorKron"):::OperatorKron
- element5 --> element3 & element4
- element6("OperatorAdd"):::OperatorAdd
- element6 --> element2 & element5
- classDef Pauli stroke:#800000,stroke-width:3px
- classDef Ladder stroke:#800000,stroke-width:3px
- classDef OperatorAdd stroke:#800000,stroke-width:3px
- classDef OperatorScalarMul stroke:#800000,stroke-width:3px
- classDef OperatorKron stroke:#800000,stroke-width:3px
- classDef OperatorMul stroke:#800000,stroke-width:3px
- classDef MathExpr stroke:#800000,stroke-width:3px
-```
-
-////
-///
-
-### Scale Terms [][oqd_core.compiler.analog.rewrite.ScaleTerms]
-
-[`ScaleTerms`][oqd_core.compiler.analog.rewrite.canonicalize.ScaleTerms] introduces scalar multiplication to terms without a coefficient for a more consistent reprensentation.
-
-
-/// admonition | Example
- type: example
-
-$$ I \otimes X + X \otimes I \longrightarrow 1*(I \otimes X) + 1*(X \otimes I)$$
-//// tab | Original Graph
-
-```mermaid
- graph TD
- element0("PauliI"):::Pauli
- element1("PauliX"):::Pauli
- element2("OperatorKron"):::OperatorKron
- element2 --> element0 & element1
- element3("PauliX"):::Pauli
- element4("PauliI"):::Pauli
- element5("OperatorKron"):::OperatorKron
- element5 --> element3 & element4
- element6("OperatorAdd"):::OperatorAdd
- element6 --> element2 & element5
- classDef Pauli stroke:#800000,stroke-width:3px
- classDef Ladder stroke:#800000,stroke-width:3px
- classDef OperatorAdd stroke:#800000,stroke-width:3px
- classDef OperatorScalarMul stroke:#800000,stroke-width:3px
- classDef OperatorKron stroke:#800000,stroke-width:3px
- classDef OperatorMul stroke:#800000,stroke-width:3px
- classDef MathExpr stroke:#800000,stroke-width:3px
-```
-
-////
-
-//// tab | Transformed Graph
-
-```mermaid
-graph TD
-element0("MathExpr
--------
expr = #quot;1#quot;"):::MathExpr
-element1("PauliI"):::Pauli
-element2("PauliX"):::Pauli
-element3("OperatorKron"):::OperatorKron
-element3 --> element1 & element2
-element4("OperatorScalarMul"):::OperatorScalarMul
-element4 --> element0 & element3
-element5("MathExpr
--------
expr = #quot;1#quot;"):::MathExpr
-element6("PauliX"):::Pauli
-element7("PauliI"):::Pauli
-element8("OperatorKron"):::OperatorKron
-element8 --> element6 & element7
-element9("OperatorScalarMul"):::OperatorScalarMul
-element9 --> element5 & element8
-element10("OperatorAdd"):::OperatorAdd
-element10 --> element4 & element9
-classDef Pauli stroke:#800000,stroke-width:3px
-classDef Ladder stroke:#800000,stroke-width:3px
-classDef OperatorAdd stroke:#800000,stroke-width:3px
-classDef OperatorScalarMul stroke:#800000,stroke-width:3px
-classDef OperatorKron stroke:#800000,stroke-width:3px
-classDef OperatorMul stroke:#800000,stroke-width:3px
-classDef MathExpr stroke:#800000,stroke-width:3px
-```
-
-////
-
-///
-
-## Canonicalization Pass [][oqd_core.compiler.analog.passes.canonicalize.analog_operator_canonicalization]
-
-```mermaid
-stateDiagram-v2
-
-[*] --> distribution_pass: done
-distribution_pass --> ProperOrder: done
-ProperOrder --> pauli_algebra_pass: done
-pauli_algebra_pass --> GatherPauli: done
-GatherPauli --> VerifyHilbertSpaceDim: done
-VerifyHilbertSpaceDim --> normal_order_pass: done
-normal_order_pass --> PruneIdentity: pass
-PruneIdentity --> scale_terms_pass: done
-scale_terms_pass --> SortedOrder: done
-SortedOrder --> math_canonicalization_pass: done
-math_canonicalization_pass --> end: done
-```
diff --git a/docs/explanation/math_interface.md b/docs/explanation/math_interface.md
deleted file mode 100644
index fd304efa..00000000
--- a/docs/explanation/math_interface.md
+++ /dev/null
@@ -1,134 +0,0 @@
-The math interface is utilized to specify arbitrary profiles for operands in other interfaces.
-
-## Math Expression [][oqd_core.interface.math.MathExpr]
-
-[MathExpr][oqd_core.interface.math.MathExpr] represents a mathematical expression.
-
-## Primitives
-
-The primitives of the math interface consist of:
-
-/// tab | `MathNum`
-
-//// html | div[style='float: right']
-[][oqd_core.interface.math.MathNum]
-////
-
-[`MathNum`][oqd_core.interface.math.MathNum] represents a number.
-
-
-/// admonition | Note
- type: note
-Numbers are considered to belong to the real numbers, i.e. they can be positive or negative floats.
-///
-///
-
-/// tab | `MathImag`
-
-//// html | div[style='float: right']
-[][oqd_core.interface.math.MathImag]
-////
-
-[`MathImag`][oqd_core.interface.math.MathImag] represents the imaginary unit.
-///
-
-/// tab | `MathVar`
-
-//// html | div[style='float: right']
-[][oqd_core.interface.math.MathVar]
-////
-
-[`MathVar`][oqd_core.interface.math.MathVar] represents a protected named variable to be substituted during compile time or runtime.
-///
-
-## Operators
-
-The compatible operators for the math interface consist of:
-
-/// tab | `MathAdd`
-
-//// html | div[style='float: right']
-[][oqd_core.interface.math.MathAdd]
-////
-
-[`MathAdd`][oqd_core.interface.math.MathAdd] represents an addition of two expressions.
-///
-
-/// tab | `MathMul`
-
-//// html | div[style='float: right']
-[][oqd_core.interface.math.MathMul]
-////
-
-[`MathMul`][oqd_core.interface.math.MathMul] represents an multiplication of two expressions.
-///
-
-/// tab | `MathPow`
-
-//// html | div[style='float: right']
-[][oqd_core.interface.math.MathPow]
-////
-
-[`MathPow`][oqd_core.interface.math.MathPow] represents an exponentiation of an expression with the other expression.
-///
-
-/// tab | `MathSub`
-
-//// html | div[style='float: right']
-[][oqd_core.interface.math.MathSub]
-////
-
-[`MathSub`][oqd_core.interface.math.MathSub] represents an subtraction of two expressions.
-///
-
-/// tab | `MathDiv`
-
-//// html | div[style='float: right']
-[][oqd_core.interface.math.MathDiv]
-////
-
-[`MathDiv`][oqd_core.interface.math.MathDiv] represents an division of two expressions.
-///
-
-/// tab | `MathFunc`
-
-//// html | div[style='float: right']
-[][oqd_core.interface.math.MathFunc]
-////
-
-[`MathFunc`][oqd_core.interface.math.MathFunc] represents the application of a named function on an expression.
-
-The compatible named functions include:
-
-- trigonometric (`sin`, `cos`, `tan`)
-- inverse trigonometric functions (`asin`, `acos`, `atan`, `atan2`)
-- hyperbolic trigonometric (`sinh`, `cosh`, `tanh`)
-- inverse hyperbolic trigonometric functions (`asinh`, `acosh`, `atanh`)
-- exponential (`exp`)
-- logarithm (`log`)
-- complex number functions (`real`, `imag`, `conj`, `abs`)
-- step function (`heaviside`)
-
-///
-
-## Usage
-
-
-/// admonition | Example
- type: example
-
-$$
-10 \sin^2(\omega t + \phi)
-$$
-
-```py
-expr = (
- 10
- * MathFunc(
- func="sin", expr=MathVar(name="omega") * MathVar(name="t") + MathVar(name="phi")
- )
- ** 2
-)
-```
-
-///
diff --git a/docs/frontend/analog_frontend.md b/docs/frontend/analog_frontend.md
new file mode 100644
index 00000000..885aef13
--- /dev/null
+++ b/docs/frontend/analog_frontend.md
@@ -0,0 +1,67 @@
+The analog frontend provides tools to convert analog source text into a parsed tree and to convert a parsed tree back into source text.
+
+## Frontend Components
+
+The analog frontend is implemented in `src/oqd_core/frontend/analog`.
+
+### ANTLR4 Generated Files
+
+These files are generated from the grammar `src/grammar/analog` using ANTLR4:
+
+- [`AnalogLexer.py`](../../src/oqd_core/frontend/analog/AnalogLexer.py)
+- [`AnalogParser.py`](../../src/oqd_core/frontend/analog/AnalogParser.py)
+- [`AnalogLexer.tokens`](../../src/oqd_core/frontend/analog/AnalogLexer.tokens)
+- [`AnalogParser.tokens`](../../src/oqd_core/frontend/analog/AnalogParser.tokens)
+- [`AnalogLexer.interp`](../../src/oqd_core/frontend/analog/AnalogLexer.interp)
+- [`AnalogParser.interp`](../../src/oqd_core/frontend/analog/AnalogParser.interp)
+- [`AnalogParserListener.py`](../../src/oqd_core/frontend/analog/AnalogParserListener.py)
+- [`AnalogParserVisitor.py`](../../src/oqd_core/frontend/analog/AnalogParserVisitor.py)
+
+For more details on the analog grammar, see [`analog_grammar.md`](../grammar/analog_grammar.md).
+
+### AST Builder
+
+[`AnalogCircuitAST.py`](../../src/oqd_core/frontend/analog/AnalogCircuitAST.py) contains the implementation of the AST Builder. The `parse_analog` function uses the `AnalogASTBuilder` class to convert the analog source text into an [`AnalogCircuit`][oqd_core.interface.analog.circuit.AnalogCircuit].
+
+### Serializer
+
+[`serialize.py`](../../src/oqd_core/frontend/analog/serialize.py) contains the implementation of the serializer. The `serialize_analog` function uses the `SerializeAnalog` class to convert an [`AnalogCircuit`][oqd_core.interface.analog.circuit.AnalogCircuit] into analog source text.
+
+## Usage of the AST Builder and Serializer
+
+### Parse Analog Source
+
+
+/// admonition | Example
+ type: example
+
+```py
+from oqd_core.frontend.analog import parse_analog
+
+source = """
+q = qreg(2)
+h = %X %@ %I
+evolve(h, 1.0, q)
+measure(q)
+"""
+
+circuit = parse_analog(source)
+```
+
+///
+
+### Serialize an Analog Circuit
+
+
+/// admonition | Example
+ type: example
+
+```py
+from oqd_core.frontend.analog import parse_analog, serialize_analog
+
+source = "q = qreg(1)\ninitialize(q)\nmeasure(q)\n"
+circuit = parse_analog(source)
+serialized = serialize_analog(circuit)
+```
+
+///
diff --git a/docs/frontend/atomic_frontend.md b/docs/frontend/atomic_frontend.md
new file mode 100644
index 00000000..f19d5d50
--- /dev/null
+++ b/docs/frontend/atomic_frontend.md
@@ -0,0 +1,75 @@
+The atomic frontend provides tools to convert atomic source text into a parsed tree and to convert a parsed tree back into source text.
+
+## Frontend Components
+
+The atomic frontend is implemented in `src/oqd_core/frontend/atomic`.
+
+### ANTLR4 Generated Files
+
+These files are generated from the grammar `src/grammar/atomic` using ANTLR4:
+
+- [`AtomicLexer.py`](../../src/oqd_core/frontend/atomic/AtomicLexer.py)
+- [`AtomicParser.py`](../../src/oqd_core/frontend/atomic/AtomicParser.py)
+- [`AtomicLexer.tokens`](../../src/oqd_core/frontend/atomic/AtomicLexer.tokens)
+- [`AtomicParser.tokens`](../../src/oqd_core/frontend/atomic/AtomicParser.tokens)
+- [`AtomicLexer.interp`](../../src/oqd_core/frontend/atomic/AtomicLexer.interp)
+- [`AtomicParser.interp`](../../src/oqd_core/frontend/atomic/AtomicParser.interp)
+- [`AtomicParserListener.py`](../../src/oqd_core/frontend/atomic/AtomicParserListener.py)
+- [`AtomicParserVisitor.py`](../../src/oqd_core/frontend/atomic/AtomicParserVisitor.py)
+
+For more details on the atomic grammar, see [`atomic_grammar.md`](../grammar/atomic_grammar.md).
+
+### AST Builder
+
+[`AtomicCircuitAST.py`](../../src/oqd_core/frontend/atomic/AtomicCircuitAST.py) contains the implementation of the AST Builder. The `parse_atomic` function uses the `AtomicASTBuilder` class to convert the atomic source text into an [`AtomicCircuit`][oqd_core.interface.atomic.circuit.AtomicCircuit].
+
+### Serializer
+
+[`serialize.py`](../../src/oqd_core/frontend/atomic/serialize.py) contains the implementation of the serializer. The `serialize_atomic` function uses the `SerializeAtomic` class to convert an [`AtomicCircuit`][oqd_core.interface.atomic.circuit.AtomicCircuit] into atomic source text.
+
+## Usage of the AST Builder and Serializer
+
+### Parse Atomic Source
+
+
+/// admonition | Example
+ type: example
+
+```py
+from oqd_core.frontend.atomic import parse_atomic
+
+source = """
+ions = ionreg(2)
+mw = beam(2.0, 1.0, 0.0, [1.0, 0.0, 0.0], [0.0, 0.0, 1.0])
+pulse1 = pulse(mw, 1e-5, ions[0])
+parallel {
+pulse(mw, 5e-6, ions[0], false)
+pulse(mw, 5e-6, ions[1], true)
+}
+"""
+
+circuit = parse_atomic(source)
+```
+
+///
+
+### Serialize an Atomic Circuit
+
+
+/// admonition | Example
+ type: example
+
+```py
+from oqd_core.frontend.atomic import parse_atomic, serialize_atomic
+
+source = """
+ions = ionreg(1)
+mw = beam(2.0, 1.0, 0.0, [1.0, 0.0, 0.0], [0.0, 0.0, 1.0])
+pulse(mw, 1e-5, ions[0], true)
+"""
+
+circuit = parse_atomic(source)
+serialized = serialize_atomic(circuit)
+```
+
+///
diff --git a/docs/grammar/analog_grammar.md b/docs/grammar/analog_grammar.md
new file mode 100644
index 00000000..af8cdeb4
--- /dev/null
+++ b/docs/grammar/analog_grammar.md
@@ -0,0 +1,85 @@
+The analog grammar defines the text syntax for the analog frontend.
+
+It is implemented with ANTLR4 using:
+
+- [`AnalogLexer.g4`](../../src/grammar/analog/AnalogLexer.g4) for tokens
+- [`AnalogParser.g4`](../../src/grammar/analog/AnalogParser.g4) for grammar rules
+
+## ANTLR4 Basics
+
+ANTLR4 splits the language definition into two parts:
+
+- A lexer grammar that converts characters into tokens
+- A parser grammar that converts tokens into a parse tree
+
+## Grammar Features
+
+### Program and Blocks
+
+- `program` is the container for the code
+- `block` supports newline-separated statements and empty lines
+- `statement` supports declarations, control flow, and expressions
+
+### Statements and Control Flow
+
+The grammar supports:
+
+- Variable declarations with `declaration`
+- Conditionals with `ifelse_stmt`
+- Loops with `while_stmt`
+- Loop control with `break_stmt` and `continue_stmt`
+
+### Registers, Lists, and Indexing
+
+The grammar includes register constructors and list extraction:
+
+- `quantum_register`
+- `mode_register`
+- `analog_list`
+- `analog_list_extract`
+
+### Expressions and Operators
+
+The grammar supports:
+
+- Arithmetic precedence through `aexpr`, `mexpr`, `uexpr`, and `eexpr`
+- Boolean logic with both word and symbolic forms (`and`/`&&`, `or`/`||`, `not`/`!`)
+- Comparators (`==`, `!=`, `<`, `<=`, `>`, `>=`)
+- Arithmetic operator tokens (`+`, `-`, `*`, `/`, `^`)
+- Analog operator tokens (`%@`, `%+`, `%-`, `%*`)
+
+### Literals, Functions, and Operators
+
+The lexer defines:
+
+- Integer and float literals (`INT`, `FLOAT`)
+- Math variables (`MATH_VAR`) and imaginary literal (`IMAG`)
+- Function names (`abs`, `sin`, `cos`, `tan`, `exp`, `log`, `sinh`, `cosh`, `tanh`, `atan`, `acos`, `asin`, `atanh`, `asinh`, `acosh`, `heaviside`, `conj`, `real`, `imag`, `atan2`)
+- Quantum operator tokens (`%I`, `%X`, `%Y`, `%Z`, `%C`, `%A`, `%J`)
+
+### Built-in Functions
+
+The grammar supports the core analog statements through `initialize`, `evolve`, and `measure`:
+
+- `initialize(targets)`
+ - `targets`: target expression (`expr`)
+- `measure(targets)`
+ - `targets`: target expression (`expr`)
+- `evolve(hamiltonian, duration, targets)`
+ - `hamiltonian`: operator expression (`expr`)
+ - `duration`: math expression (`aexpr`)
+ - `targets`: target expression (`expr`)
+
+## Generate Parser Files for Frontend
+
+Run generation from the grammar directory and output generated files into `src/oqd_core/frontend/analog`. Run `antlr4` on the Lexer first, and then the Parser, as the Parser depends on the Lexer.
+
+```bash
+uv sync
+source .venv/bin/activate
+cd src/grammar/analog
+antlr4 -Dlanguage=Python3 -visitor -listener -o ../../oqd_core/frontend/analog AnalogLexer.g4
+antlr4 -Dlanguage=Python3 -visitor -listener -o ../../oqd_core/frontend/analog AnalogParser.g4
+```
+
+This generates lexer, parser, listener, and visitor artifacts used by the frontend parser pipeline.
diff --git a/docs/grammar/atomic_grammar.md b/docs/grammar/atomic_grammar.md
new file mode 100644
index 00000000..01118314
--- /dev/null
+++ b/docs/grammar/atomic_grammar.md
@@ -0,0 +1,87 @@
+The atomic grammar defines the text syntax for the atomic frontend.
+
+It is implemented with ANTLR4 using:
+
+- [`AtomicLexer.g4`](../../src/grammar/atomic/AtomicLexer.g4) for tokens
+- [`AtomicParser.g4`](../../src/grammar/atomic/AtomicParser.g4) for grammar rules
+
+## ANTLR4 Basics
+
+ANTLR4 splits the language definition into two parts:
+
+- A lexer grammar that converts characters into tokens
+- A parser grammar that converts tokens into a parse tree
+
+## Grammar Features
+
+### Program and Blocks
+
+- `program` is the container for the code
+- `block` supports newline-separated statements and empty lines
+- `statement` supports declarations, control flow, and expressions
+
+### Statements and Control Flow
+
+The grammar supports:
+
+- Variable declarations with `declaration`
+- Conditionals with `ifelse_stmt`
+- Loops with `while_stmt`
+- Loop control with `break_stmt` and `continue_stmt`
+
+### Registers, Lists, and Indexing
+
+The grammar includes register constructors and list extraction:
+
+- `ion_register`
+- `atomic_list`
+- `atomic_list_extract`
+
+### Expressions and Operators
+
+The grammar supports:
+
+- Arithmetic precedence through `aexpr`, `mexpr`, `uexpr`, and `eexpr`
+- Boolean logic with both word and symbolic forms (`and`/`&&`, `or`/`||`, `not`/`!`)
+- Comparators (`==`, `!=`, `<`, `<=`, `>`, `>=`)
+- Arithmetic operator tokens (`+`, `-`, `*`, `/`, `^`)
+
+### Literals, Functions, and Operators
+
+The lexer defines:
+
+- Integer and float literals (`INT`, `FLOAT`)
+- Math variables (`MATH_VAR`) and imaginary literal (`IMAG`)
+- Function names (`abs`, `sin`, `cos`, `tan`, `exp`, `log`, `sinh`, `cosh`, `tanh`, `atan`, `acos`, `asin`, `atanh`, `asinh`, `acosh`, `heaviside`, `conj`, `real`, `imag`, `atan2`)
+
+### Built-in Functions
+
+The grammar supports the core atomic statements through `beam`, `pulse`, and `parallel`.
+
+- `beam(frequency, rabi, phase, polarization, wavevector)`
+ - `frequency`: math expression (`aexpr`)
+ - `rabi`: math expression (`aexpr`)
+ - `phase`: math expression (`aexpr`)
+ - `polarization`: vector expression (`aexpr`),
+ - `wavevector`: vector expression (`aexpr`),
+- `pulse(beam, duration, target[, measured])`
+ - `beam`: beam expression (`aexpr`),
+ - `duration`: math expression (`aexpr`)
+ - `target`: target expression (`aexpr`)
+ - `measured`: boolean expression (`aexpr`), optional, defaults to `false`
+- `parallel { ... }`
+ - `...`: block (`block`) containing pulse statements to run in parallel
+
+## Generate Parser Files for Frontend
+
+Run generation from the grammar directory and output generated files into `src/oqd_core/frontend/atomic`. Run `antlr4` on the Lexer first, and then the Parser, as the Parser depends on the Lexer.
+
+```bash
+uv sync
+source .venv/bin/activate
+cd src/grammar/atomic
+antlr4 -Dlanguage=Python3 -visitor -listener -o ../../oqd_core/frontend/atomic AtomicLexer.g4
+antlr4 -Dlanguage=Python3 -visitor -listener -o ../../oqd_core/frontend/atomic AtomicParser.g4
+```
+
+This generates lexer, parser, listener, and visitor artifacts used by the frontend parser pipeline.
diff --git a/docs/interfaces/analog_interface.md b/docs/interfaces/analog_interface.md
new file mode 100644
index 00000000..764b2874
--- /dev/null
+++ b/docs/interfaces/analog_interface.md
@@ -0,0 +1,134 @@
+The analog interface represents a quantum experiment in terms of time evolving Hamiltonians.
+
+## Quantum Degrees of Freedom
+
+In this analog interface, we allow for 2 different quantum degrees of freedom:
+
+- Qubits consist of a pair of states (spin $\uparrow$ and spin $\downarrow$).
+- Bosonic degrees of freedom form a fock space.
+
+They are implemented using registers and index-based extraction:
+
+- [`QuantumRegister`][oqd_core.interface.analog.expr.QuantumRegister] creates a qubit register
+- [`ModeRegister`][oqd_core.interface.analog.expr.ModeRegister] creates a bosonic mode register
+- [`Extract`][oqd_core.interface.analog.expr.Extract] accesses a target by index
+- [`AnalogList`][oqd_core.interface.analog.expr.AnalogList] collects analog expressions in a list
+
+## Analog Operators
+
+/// tab | Pauli
+
+The basis of operators for the qubits are the Pauli operators:
+
+- $\sigma^I$ [][oqd_core.interface.analog.expr.PauliI]
+- $\sigma^x$ [][oqd_core.interface.analog.expr.PauliX]
+- $\sigma^y$ [][oqd_core.interface.analog.expr.PauliY]
+- $\sigma^z$ [][oqd_core.interface.analog.expr.PauliZ]
+
+///
+
+/// tab | Ladder
+
+The basis of operators for the bosonic degree of freedom are the ladder operators:
+
+- $a$ [][oqd_core.interface.analog.expr.Annihilation]
+- $a^{\dagger}$ [][oqd_core.interface.analog.expr.Creation]
+- $I$ [][oqd_core.interface.analog.expr.Identity]
+
+///
+
+### Operator Operations
+
+The basis operators can be combined with the operations:
+
+- Addition [][oqd_core.interface.analog.expr.OperatorAdd]
+
+- Subtraction [][oqd_core.interface.analog.expr.OperatorSub]
+
+- Multiplication [][oqd_core.interface.analog.expr.OperatorMul]
+
+- Tensor Product [][oqd_core.interface.analog.expr.OperatorKron]
+
+## Math Expressions
+
+Analog parameters support math expressions.
+
+### Math Primitives
+
+- [`MathNum`][oqd_core.interface.analog.expr.MathNum] represents numeric literals in analog math expressions.
+- [`MathImag`][oqd_core.interface.analog.expr.MathImag] represents the imaginary unit.
+- [`MathVar`][oqd_core.interface.analog.expr.MathVar] represents compile-time variables in expressions.
+
+### Math Operations
+
+- Addition [][oqd_core.interface.analog.expr.MathAdd]
+- Subtraction [][oqd_core.interface.analog.expr.MathSub]
+- Multiplication [][oqd_core.interface.analog.expr.MathMul]
+- Division [][oqd_core.interface.analog.expr.MathDiv]
+- Exponentiation [][oqd_core.interface.analog.expr.MathPow]
+- Named functions [][oqd_core.interface.analog.expr.MathFunc]
+
+Compatible named functions include:
+`sin`, `cos`, `tan`, `asin`, `acos`, `atan`, `atan2`, `sinh`, `cosh`, `tanh`, `asinh`, `acosh`, `atanh`, `exp`, `log`, `real`, `imag`, `conj`, `abs`, `heaviside`.
+
+## Boolean Expressions
+
+Boolean expressions are used for conditional and loop control flow. [][oqd_core.interface.analog.expr.Bool]
+
+### Boolean Operations
+
+- NOT [][oqd_core.interface.analog.expr.BoolNot]
+- AND [][oqd_core.interface.analog.expr.BoolAnd]
+- OR [][oqd_core.interface.analog.expr.BoolOr]
+- Equal [][oqd_core.interface.analog.expr.BoolEq]
+- Not equal [][oqd_core.interface.analog.expr.BoolNotEq]
+- Less than [][oqd_core.interface.analog.expr.BoolLessThan]
+- Less than or equal [][oqd_core.interface.analog.expr.BoolLessThanEq]
+- Greater than [][oqd_core.interface.analog.expr.BoolGreaterThan]
+- Greater than or equal [][oqd_core.interface.analog.expr.BoolGreaterThanEq]
+
+
+# Analog Circuit
+
+The [AnalogCircuit][oqd_core.interface.analog.circuit.AnalogCircuit] is the top level structure that contains analog statements and control flow.
+
+## Statements
+
+### Analog Operations
+
+- [`Initialize`][oqd_core.interface.analog.expr.Initialize] initializes the specified targets before evolution.
+
+- [`Evolve`][oqd_core.interface.analog.expr.Evolve] applies a Hamiltonian for a duration on the specified targets.
+
+- [`Measure`][oqd_core.interface.analog.expr.Measure] performs measurement on the specified targets.
+
+### Declarations
+
+- [`Declaration`][oqd_core.interface.analog.statement.Declaration] binds an expression result to a named identifier for later use.
+
+### Control Flow
+
+- [`IfElse`][oqd_core.interface.analog.statement.IfElse] conditionally executes `then_branch` or `else_branch`.
+
+- [`While`][oqd_core.interface.analog.statement.While] implements the While loop when the condition is true.
+
+- [`Break`][oqd_core.interface.analog.statement.Break] exits the innermost loop.
+
+- [`Continue`][oqd_core.interface.analog.statement.Continue] skips to the next loop iteration.
+
+## Usage
+
+
+/// admonition | Example
+ type: example
+
+```py
+from oqd_core.interface.analog import AnalogCircuit, Initialize, Measure, Evolve
+
+circuit = AnalogCircuit()
+circuit.Initialize(targets=q)
+circuit.Evolve(hamiltonian=H, duration=1, targets=q)
+circuit.Measure(targets=q)
+```
+
+///
diff --git a/docs/interfaces/atomic_interface.md b/docs/interfaces/atomic_interface.md
new file mode 100644
index 00000000..10044510
--- /dev/null
+++ b/docs/interfaces/atomic_interface.md
@@ -0,0 +1,100 @@
+The atomic interface expresses quantum information experiments in terms of light-matter interactions.
+
+## Ions
+
+Ions are implemented through ion registers and index-based extraction.
+
+- [`IonRegister`][oqd_core.interface.atomic.expr.IonRegister] creates an ion register
+- [`Extract`][oqd_core.interface.atomic.expr.Extract] accesses a target ion by index
+- [`AtomicList`][oqd_core.interface.atomic.expr.AtomicList] collects Atomic Expressions in a list
+
+## Math Expressions
+
+Atomic parameters support math expressions.
+
+### Math Primitives
+
+- [`MathNum`][oqd_core.interface.atomic.expr.MathNum] represents numeric literals in atomic math expressions.
+- [`MathImag`][oqd_core.interface.atomic.expr.MathImag] represents the imaginary unit.
+- [`MathVar`][oqd_core.interface.atomic.expr.MathVar] represents compile-time variables in expressions.
+
+### Math Operations
+
+- Addition [][oqd_core.interface.atomic.expr.MathAdd]
+- Subtraction [][oqd_core.interface.atomic.expr.MathSub]
+- Multiplication [][oqd_core.interface.atomic.expr.MathMul]
+- Division [][oqd_core.interface.atomic.expr.MathDiv]
+- Exponentiation [][oqd_core.interface.atomic.expr.MathPow]
+- Named functions [][oqd_core.interface.atomic.expr.MathFunc]
+
+Compatible named functions include:
+`sin`, `cos`, `tan`, `asin`, `acos`, `atan`, `atan2`, `sinh`, `cosh`, `tanh`, `asinh`, `acosh`, `atanh`, `exp`, `log`, `real`, `imag`, `conj`, `abs`, `heaviside`.
+
+## Boolean Expressions
+
+Boolean expressions are used for conditional and loop control flow. [][oqd_core.interface.atomic.expr.Bool]
+
+### Boolean Operations
+
+- NOT [][oqd_core.interface.atomic.expr.BoolNot]
+- AND [][oqd_core.interface.atomic.expr.BoolAnd]
+- OR [][oqd_core.interface.atomic.expr.BoolOr]
+- Equal [][oqd_core.interface.atomic.expr.BoolEq]
+- Not equal [][oqd_core.interface.atomic.expr.BoolNotEq]
+- Less than [][oqd_core.interface.atomic.expr.BoolLessThan]
+- Less than or equal [][oqd_core.interface.atomic.expr.BoolLessThanEq]
+- Greater than [][oqd_core.interface.atomic.expr.BoolGreaterThan]
+- Greater than or equal [][oqd_core.interface.atomic.expr.BoolGreaterThanEq]
+
+
+# Atomic Circuit
+
+The [`AtomicCircuit`][oqd_core.interface.atomic.circuit.AtomicCircuit] is the top-level structure that contains atomic statements and control flow.
+
+## Statements
+
+### Atomic Operations
+
+- [`Beam`][oqd_core.interface.atomic.expr.Beam] represents the optical channel.
+
+- [`Pulse`][oqd_core.interface.atomic.expr.Pulse] applies a beam for a duration on a target ion.
+
+- [`ParallelProtocol`][oqd_core.interface.atomic.statement.ParallelProtocol] composes pulses in a parallel fashion.
+
+### Declarations
+
+- [`Declaration`][oqd_core.interface.atomic.statement.Declaration] binds an expression result to a named identifier for later use.
+
+### Control Flow
+
+- [`IfElse`][oqd_core.interface.atomic.statement.IfElse] conditionally executes `then_branch` or `else_branch`.
+
+- [`While`][oqd_core.interface.atomic.statement.While] implements the While loop when the condition is true.
+
+- [`Break`][oqd_core.interface.atomic.statement.Break] exits the innermost loop.
+
+- [`Continue`][oqd_core.interface.atomic.statement.Continue] skips to the next loop iteration.
+
+## Usage
+
+
+/// admonition | Example
+ type: example
+
+```py
+from oqd_core.interface.atomic import AtomicCircuit, Beam
+
+circuit = AtomicCircuit()
+
+mw = Beam(
+ frequency=2.0,
+ rabi=1.0,
+ phase=0.0,
+ polarization=[1.0, 0.0, 0.0],
+ wavevector=[0.0, 0.0, 1.0],
+)
+
+circuit.pulse(duration=10e-6, target=0, beam=mw, measured=False)
+```
+
+///
diff --git a/docs/reference/analog_interface.md b/docs/reference/analog_interface.md
index 1a0fe394..a73818da 100644
--- a/docs/reference/analog_interface.md
+++ b/docs/reference/analog_interface.md
@@ -1,43 +1,77 @@
-## Operations
+::: oqd_core.interface.analog
+## Circuit
-::: oqd_core.interface.analog.operation
+::: oqd_core.interface.analog.circuit
options:
heading_level: 3
members: [
"AnalogCircuit",
- "AnalogGate",
- "AnalogOperation",
- "Evolve",
- "Measure",
- "Initialize",
]
-## Operators
+## Expressions
-::: oqd_core.interface.analog.operator
+::: oqd_core.interface.analog.expr
options:
heading_level: 3
members: [
- "Operator",
- "OperatorTerminal",
- "Pauli",
+ "AnalogExpr",
+ "AnalogExprSubtypes",
+ "CastAnalogExpr",
+ "Terminal",
+ "Access",
+ "QuantumRegister",
+ "ModeRegister",
+ "MathExpr",
+ "MathVar",
+ "MathNum",
+ "MathImag",
+ "MathFunc",
+ "MathAdd",
+ "MathSub",
+ "MathMul",
+ "MathDiv",
+ "MathPow",
+ "BoolExpr",
+ "Bool",
+ "BoolNot",
+ "BoolAnd",
+ "BoolOr",
+ "BoolEq",
+ "BoolNotEq",
+ "BoolLessThan",
+ "BoolLessThanEq",
+ "BoolGreaterThan",
+ "BoolGreaterThanEq",
"PauliI",
"PauliX",
"PauliY",
"PauliZ",
- "PauliPlus",
- "PauliMinus",
- "Ladder",
"Creation",
"Annihilation",
"Identity",
- "OperatorBinaryOp",
"OperatorAdd",
"OperatorSub",
"OperatorMul",
- "OperatorScalarMul",
"OperatorKron",
- "OperatorSubtypes",
+ "AnalogList",
+ "Extract",
+ "Initialize",
+ "Evolve",
+ "Measure",
+ ]
+
+
+## Statements
+
+::: oqd_core.interface.analog.statement
+ options:
+ heading_level: 3
+ members: [
+ "Declaration",
+ "IfElse",
+ "While",
+ "Break",
+ "Continue",
]
diff --git a/docs/reference/atomic_interface.md b/docs/reference/atomic_interface.md
index 3d9c2536..5dfebc7e 100644
--- a/docs/reference/atomic_interface.md
+++ b/docs/reference/atomic_interface.md
@@ -1 +1,81 @@
::: oqd_core.interface.atomic
+
+## Circuit
+
+::: oqd_core.interface.atomic.circuit
+ options:
+ heading_level: 3
+ members: [
+ "AtomicCircuit",
+ ]
+
+
+## Expressions
+
+::: oqd_core.interface.atomic.expr
+ options:
+ heading_level: 3
+ members: [
+ "AtomicExpr",
+ "AtomicExprSubtypes",
+ "CastAtomicExpr",
+ "Terminal",
+ "Access",
+ "IonRegister",
+ "MathExpr",
+ "MathVar",
+ "MathNum",
+ "MathImag",
+ "MathFunc",
+ "MathAdd",
+ "MathSub",
+ "MathMul",
+ "MathDiv",
+ "MathPow",
+ "BoolExpr",
+ "Bool",
+ "BoolNot",
+ "BoolAnd",
+ "BoolOr",
+ "BoolEq",
+ "BoolNotEq",
+ "BoolLessThan",
+ "BoolLessThanEq",
+ "BoolGreaterThan",
+ "BoolGreaterThanEq",
+ "AtomicList",
+ "Extract",
+ "Beam",
+ "Pulse",
+ ]
+
+
+## Statements
+
+::: oqd_core.interface.atomic.statement
+ options:
+ heading_level: 3
+ members: [
+ "Declaration",
+ "ParallelProtocol",
+ "IfElse",
+ "While",
+ "Break",
+ "Continue",
+ ]
+
+
+## Species
+
+::: oqd_core.interface.atomic.species
+ options:
+ heading_level: 3
+ members: [
+ "Level",
+ "Transition",
+ "Ion",
+ "IonBuilder",
+ "Yb171IIBuilder",
+ "Ba133IIBuilder",
+ "ZeemanShift",
+ ]
diff --git a/docs/reference/math_interface.md b/docs/reference/math_interface.md
index a625ddc7..e69de29b 100644
--- a/docs/reference/math_interface.md
+++ b/docs/reference/math_interface.md
@@ -1 +0,0 @@
-::: oqd_core.interface.math
diff --git a/mkdocs.yaml b/mkdocs.yaml
index 96c27862..22ee5322 100644
--- a/mkdocs.yaml
+++ b/mkdocs.yaml
@@ -22,20 +22,23 @@ nav:
- Installation: get-started/installation.md
- Acknowledgement: get-started/acknowledgement.md
- - Explanation:
- - Interfaces:
- - Analog: explanation/analog_interface.md
- - Atomic: explanation/atomic_interface.md
- - Math: explanation/math_interface.md
-
- - Compilers:
- - Canonicalization: explanation/canonicalization.md
+ - Interfaces:
+ - Analog: interfaces/analog_interface.md
+ - Atomic: interfaces/atomic_interface.md
+ - Canonicalization: interfaces/canonicalization.md
+
+ - Grammar:
+ - Analog: grammar/analog_grammar.md
+ - Atomic: grammar/atomic_grammar.md
+
+ - Frontend:
+ - Analog: frontend/analog_frontend.md
+ - Atomic: frontend/atomic_frontend.md
- API Reference:
- Interface:
- Analog: reference/analog_interface.md
- Atomic: reference/atomic_interface.md
- - Math: reference/math_interface.md
- Compiler:
- Math: reference/math_compiler.md
@@ -65,7 +68,6 @@ theme:
icon: material/weather-night
name: Switch to light mode
-
features:
- search.suggest
- search.highlight
@@ -140,7 +142,7 @@ markdown_extensions:
- mdx_truly_sane_lists:
nested_indent: 2
- truly_sane: True
+ truly_sane: true
extra_javascript:
- javascripts/mathjax.js
@@ -151,4 +153,4 @@ extra_css:
- stylesheets/headers.css
- stylesheets/admonitions.css
- stylesheets/brand.css
- - stylesheets/logo.css
+ - stylesheets/logo.css
\ No newline at end of file