Safe Haskell | None |
---|

This program reads an execution trace produced by QCL, and turns it into a Quipper circuit.

- type QCLState = IntMap Qubit
- type QCLCirc a = StateT QCLState Circ a
- provide :: Int -> QCLCirc Qubit
- qcl_reset :: QCLCirc ()
- qcl_cnot :: Int -> [Int] -> QCLCirc ()
- qcl_not :: Int -> QCLCirc ()
- qcl_fanout :: [Int] -> [Int] -> [Int] -> QCLCirc ()
- sqdist :: [Complex Double] -> [Complex Double] -> Double
- matrix_w :: [Complex Double] -> Bool
- matrix_exp :: [Complex Double] -> Maybe Double
- qcl_matrix :: Bool -> Int -> [Complex Double] -> [Int] -> QCLCirc ()
- qcl_cnot_inv :: Int -> [Int] -> QCLCirc ()
- qcl_not_inv :: Int -> QCLCirc ()
- qcl_fanout_inv :: [Int] -> [Int] -> [Int] -> QCLCirc ()
- testcircuit1 :: QCLCirc ()
- run :: QCLCirc a -> Circ a
- data QCLGate
- do_qcl_gate :: QCLGate -> QCLCirc ()
- identifier :: ReadP String
- int :: ReadP Int
- double :: ReadP Double
- commalist :: ReadP a -> ReadP [a]
- qureg :: ReadP (String, [Int])
- inversechar :: ReadP Bool
- complex :: ReadP (Complex Double)
- qcl_line :: ReadP QCLGate
- parse_qcl_line :: String -> QCLGate
- run_qcl_line :: String -> QCLCirc ()
- run_qcl_lines :: String -> QCLCirc ()
- testcircuit2 :: QCLCirc ()
- main :: IO ()

# A monad for a QCL state

type QCLState = IntMap Qubit Source #

In QCL, qubits are identified by integers. We have to map these
to Quipper's native qubits. A `QCLState`

holds such a map.
Implicitly, it also holds the set of qubits currently defined.

# Auxiliary state functions

provide :: Int -> QCLCirc Qubit Source #

Look up the qubit corresponding to a QCL register, or allocate a new qubit if it doesn't already exist.

# Implementation of the QCL primitives

qcl_cnot :: Int -> [Int] -> QCLCirc () Source #

Apply a controlled-not operation to the first argument.

qcl_fanout :: [Int] -> [Int] -> [Int] -> QCLCirc () Source #

: Copy the qubit register `qcl_fanout`

ins outs ctrls*ins* to
the qubit register *outs* by means of c-not operations, provided
that *outs* was previously 0. The whole operation is controlled by
*ctrls*.

sqdist :: [Complex Double] -> [Complex Double] -> Double Source #

Calculate the square distance between two vectors, which must be of the same length.

matrix_exp :: [Complex Double] -> Maybe Double Source #

If the matrix looks like a controlled *e*^*tiZ*-gate, return the
angle *t*.

qcl_matrix :: Bool -> Int -> [Complex Double] -> [Int] -> QCLCirc () Source #

: Apply the `qcl_matrix`

n amps regs*n*-by-*n* unitary gate
whose matrix is given in *amps*, to the qubit list *regs*. This
function must guess, based on the complex entries of the matrix,
what the name of the gate should be. This guessing is crude at the
moment, and must be extended to include additional gates as
required by each algorithm. If the first argument is `True`

, invert
the matrix.

qcl_fanout_inv :: [Int] -> [Int] -> [Int] -> QCLCirc () Source #

The inverse of `qcl_fanout`

.

testcircuit1 :: QCLCirc () Source #

A sample circuit to illustrate how to use the primitives.

# Unpacking QCLCirc

run :: QCLCirc a -> Circ a Source #

Run function for the `QCLCirc`

monad: execute the actions and
produce a circuit.

# An abstract syntax for QCL output

A data type to hold a QCL gate.

do_qcl_gate :: QCLGate -> QCLCirc () Source #

Take a gate from the abstract syntax and execute it in the
`QCLCirc`

monad.

# Parsing

The output of QCL consists of lines of the following forms. Lines not starting with "@" are comments or other non-circuit output.

@ RESET @ NOT(qureg q=<5>) @ CNOT(qureg q=<31>,quconst c=<4,30>) @ !CNOT(qureg q=<31>,quconst c=<4,30>) @ Fanout(quconst a=<47,48,49,50,51,52>,quvoid b=<40,41,42,43,44,45>;cond=<>) @ !Fanout(quconst a=<47,48,49,50,51,52>,quvoid b=<40,41,42,43,44,45>;cond=<>) @ Matrix4x4(complex u00=1,complex u01=0,complex u02=0,complex u03=0,complex u10=0,complex u11=1,complex u12=0,complex u13=0,complex u20=0,complex u21=0,complex u22=(0.995004,-0.0998334),complex u23=0,complex u30=0,complex u31=0,complex u32=0,complex u33=(0.995004,0.0998334),qureg q=<12,13>) @ !Matrix4x4(complex u00=1,complex u01=0,complex u02=0,complex u03=0,complex u10=0,complex u11=0.707107,complex u12=0.707107,complex u13=0,complex u20=0,complex u21=0.707107,complex u22=-0.707107,complex u23=0,complex u30=0,complex u31=0,complex u32=0,complex u33=1,qureg q=<0,6>)

We use Koen Claessen's parser combinators (see Text.ParserCombinators.ReadP) to implement the parser.

identifier :: ReadP String Source #

Parse a QCL identifier, which we take to be a non-empty string of alphanumeric characters, starting with a letter

Parse a signless integer. We avoid the usual trick (`readS_to_P`

`reads`

), because this introduces backtracking errors.

double :: ReadP Double Source #

Parse a floating point number. We avoid the usual trick
(`readS_to_P`

`reads`

), because this introduces backtracking
errors.

qureg :: ReadP (String, [Int]) Source #

Parse a QCL quantum register of the form

q=<31,32> c=<4,31> b=<40,41,42,43,44,45>.

inversechar :: ReadP Bool Source #

complex :: ReadP (Complex Double) Source #

Parse a complex number declaration of the format

complex u00=1

or

complex u22=(0.995004,-0.0998334).

parse_qcl_line :: String -> QCLGate Source #

run_qcl_line :: String -> QCLCirc () Source #

Monad version of `parse_qcl_line`

: parse a string and execute the
resulting gate directly in the `QCLCirc`

monad.

run_qcl_lines :: String -> QCLCirc () Source #

Parse a stream consisting of many lines of QCL output and execute
the parsed gates in the `QCLCirc`

monad.

testcircuit2 :: QCLCirc () Source #

A sample circuit to illustrate the parser.