``` qbits n cbits n qregs n cregs n mem n ``` The order of the headers is important and should not be changed. The `qbits` header specifies the number of qubits in each quantum register. The `cbits` header specifies the number of classical bits in each classical register. The `qregs` header specifies the number of quantum registers. The `cregs` header specifies the number of classical registers. The `n` after each header is any integer number. Operands/arguments for all instructions are delimited by spaces and not commas. Code execution should always end at a `hlt` instruction. If the emulator reaches the end of code but does not encounter a `hlt` instruction, it will end with a "PC out of bounds" error. ## Quantum Instructions The general format for quantum instructions are: ``` op qn ``` Where `op` is the name/opcode, `qn` specifies a specific qubit `n` of the currently selected quantum register. `` can include more qubits as arguments, or in the case of some instructions, a rotation expressed as a rational multiple of pi, in the format `[n]pi[/n]`, where `n` can be any integer number, and items in `[]` are optional. Quantum registers can be selected via the `qsel` instruction, which has the general format `qsel qrn` where `n` is any non-negative number. List of currently implemented quantum instructions: | Quantum Gate | Instruction name | Syntax example | Explanation | | ------------------- | ---------------- | ------------------- | ----------- | | Hadamard | h | `h q0` | Applies a Hadamard to qubit 0 | | CNOT | cnot | `cnot q0 q1` | Applies a CNOT to qubit 1 with qubit 0 being the control | | CCNOT/Toffoli | ccnot | `ccnot q0 q1 q2` | Applies a Toffoli to qubit 2 with qubit 0 and qubit 1 being the controls | | Pauli X | x | `x q0` | Applies a Pauli X to qubit 0 | | Pauli Y | y | `y q0` | Applies a Pauli Y to qubit 0 | | Pauli Z | z | `z q0` | Applies a Pauli Z to qubit 0 | | Rx | rx | `rx q0 pi/3` | Rotates the statevector of qubit 0 by pi/3 radians along X axis on bloch sphere | | Ry | ry | `ry q0 pi` | Rotates the statevector of qubit 0 by pi radians along Y axis on bloch sphere | | Rz | rz | `rz q0 pi/4` | Rotates the statevector of qubit 0 by pi/4 radians along Z axis on bloch sphere | | U gate | u | `u q0 pi pi/3 pi/6` | Rotates the statevector of qubit 0 by the 3 Euler angles pi, pi/3, pi/6 | | S gate | s | `s q0` | Applies an S gate to qubit 0 | | T gate | t | `t q0` | Applies a T gate to qubit 0 | | S-dagger | sdg | `sdg q0` | Applies a S-dagger or the inverse of S gate to qubit 0 | | T-dagger | tdg | `tdg q0` | Applies a T-dagger or the inverse of T gate to qubit 0 | | Phase gate | p | `p q0 pi/3` | Applies a relative phase of pi/3 radians to qubit 0 | | Controlled Hadamard | ch | `ch q0 q1` | Applies a controlled Hadamard to qubit 1 with qubit 0 being the control | | Controlled Pauli Y | cy | `cy q0 q1` | Applies a controlled Pauli Y to qubit 1 with qubit 0 being the control | | Controlled Pauli Z | cz | `cz q0 q1` | Applies a controlled Pauli Z to qubit 1 with qubit 0 being the control | | Controlled Phase | cp | `cp q0 q1 pi/2` | Applies a controlled Phase gate to qubit 1 of pi/2 radians with qubit 0 being the control | | Swap | swap | `swap q0 q1` | Swaps the state of qubits 0 and 1 | | Square Root NOT | sqrtx | `sqrtx q0 ` | Applies a sqrt(NOT)/sqrt(X) to qubit 0 | | Square Root Swap | sqrtswp | `sqrtswp q0 q1` | Applies a sqrt(Swap) to qubits 0 and 1, halfway swapping their state | | Controlled Swap | cswap | `cswap q0 q1 q2` | Swaps the state of qubits 1 and 2 with qubit 0 being the control | | Measure | m | `m q0 cr1 c3` | Measures the state of qubit 0 into 3rd bit of classical register 1 | *Note: Remove any measurement operations before running the emulator with `--print-state` (or `-p`) as the emulator does not ignore them currently when run with that flag set* ## Classical Instructions General format for classical instructions are: ``` op ``` Where `op` is the name/opcode, operands may include `crn`, which specifies a specific classical register `n`, or an immediate literal value (for now non-negative due to not implemented in parser yet) Other than these differences, they behave basically the same as any other assembly language instructions. List of currently implemented classical instructions: *Note: The value of a register refers to the value stored in the register. The value of an immediate is the immediate number itself.* *Note 2: An operand can either be a register or immediate unless a restriction is specified.* | Instruction name | Description | | ---------------- | ----------- | | add | op1 = op2 + op3. op1 is always a register. | | sub | op1 = op2 - op3. op1 is always a register. | | mult | op1 = op2 * op3. op1 is always a register. All values are treated unsigned. | | umult | op1 = (op2 * op3) >> (cbits/2). op1 is always a register. All values are treated unsigned. | | div | op1 = op2 / op3. op1 is always a register. Performs integer division. All values are treated unsigned. | | smult | op1 = op2 * op3. op1 is always a register. All values are treated signed. | | sumult | op1 = (op2 * op3) >> (cbits/2). op1 is always a register. All values are treated signed. | | sdiv | op1 = op2 / op3. op1 is always a register. Performs integer division. All values are treated signed. | | not | op1 = ~op2. op1 is always a register. | | and | op1 = op2 & op3. op1 is always a register. | | or | op1 = op2 \| op3. op1 is always a register. | | xor | op1 = op2 ^ op3. op1 is always a register. | | nand | op1 = ~(op2 & op3). op1 is always a register. | | nor | op1 = ~(op2 \| op3). op1 is always a register. | | xnor | op1 = ~(op2 ^ op3). op1 is always a register. | ## Misc. Instructions These instructions are here because. | Instruction name | Description | | ---------------- | ----------- | | qsel | Selects a quantum register so that proceeding quantum instructions act on that qreg. | | cmp | Updates flags based on comparing values in op1 and op2. op1 is always a register. | | jmp | Unconditionally jump to a label. | | jeq | Jump to label if comparison resulted in EQ flag set. | | jne | Jump to label if comparsion did not result in EQ flag set. | | jg | Jump to label if comparison resulted in GREATER flag set. | | jge | Jump to label if comparison resulted in GREATER or EQ flag set. | | jl | Jump to label if comparison resulted in LESSER flag set. | | jle | Jump to label if comparison resulted in LESSER or EQ flag set. | | hlt | Halt the program. | # Examples This program simulates the $\ket{\Phi^+}$ bell state: ``` qbits 2 cbits 2 qregs 1 cregs 1 qsel qr0 h q0 cnot q0 q1 m q0 cr0 c0 m q1 cr0 c1 hlt ```