The Quipper System

QuipperLib.DynamicLiftings

Description

This library provides various transformers and functions for performing dynamic liftings based on different mechanisms. Some use simulations to do the dynamic liftings; others just do them randomly. There are also functions for printing the simulated circuit.

This code is experimental.

Synopsis

# Random Dynamic Liftings and Liftings from a List

type RandomCirc a = StateT StdGen Circ a Source #

A State monad that holds a random generator.

type ListCirc a = StateT [Bool] Circ a Source #

A State monad that holds a list of booleans.

To evaluate a RandomCirc we require a seed for the random generator.

evalListCirc :: [Bool] -> ListCirc a -> Circ a Source #

To evaluate a ListCirc we require a list of booleans.

evalRandomCirc_unary :: Int -> (a -> RandomCirc b) -> a -> Circ b Source #

Lift evalRandomCirc to unary random circuit generating functions.

evalListCirc_unary :: [Bool] -> (a -> ListCirc b) -> a -> Circ b Source #

Left evalListCirc to unary list circuit generating functions.

randomRRandomCirc :: Random a => (a, a) -> RandomCirc a Source #

Lift the underlying randomR function into the RandomCirc monad.

print_unary_random :: QCData qa => Format -> (qa -> RandomCirc b) -> qa -> IO () Source #

Print a RandomCirc by evaluating it with a seed in the IO monad.

print_unary_list :: QCData qa => Format -> Int -> (qa -> ListCirc b) -> qa -> IO () Source #

Print a LiftCirc by evaluating it in the IO Monad, so as to read in a given number of booleans.

lifted_identity_transformer :: MonadTrans t => Transformer (t Circ) Qubit Bit Source #

Lift the identity_transformer using any monad transformer.

Dynamic lifting can make use of a random result (without caring which wire is being lifted).

Dynamic lifting can pop the head off of a list of booleans, and use that to lift the given wire.

A dynamic transformer which is the identity transformer (lifted to RandomCirc), except for the dynamic lifting operation.

A dynamic transformer which is the identity transformer (lifted to ListCirc), except for the dynamic lifting operation.

print_unary_with_random_liftings :: (QCData a, QCData b) => Format -> (a -> Circ b) -> a -> IO () Source #

Print a circuit, using random dynamic liftings.

print_unary_with_list_liftings :: (QCData a, QCData b) => Format -> Int -> (a -> Circ b) -> a -> IO () Source #

Print a circuit, using a list of dynamic liftings.

# Simulating the Dynamic Liftings

Add state to the Circ Monad so that we can simulate the circuit and use that data for dynamic liftings.

Constructors

 SS Fields

When we start a simulation, we need an empty starting state, with a seed for the generator.

type SimulatedCirc a = StateT SimulationState Circ a Source #

A State monad that holds our SimulationState.

Evaluate a SimulatedCirc. This requires a seed for the random generator.

evalSimulatedCirc_unary :: Int -> (a -> SimulatedCirc b) -> a -> Circ b Source #

Lift evalSimulatedCirc to unary functions.

randomRSimulatedCirc :: Random a => (a, a) -> SimulatedCirc a Source #

Lift the underlying randomR function into the SimulatedCirc monad.

A specialized put function for the quantum state that uses the current state instead of a previously retrieved state.

A specialized put function for the classical state that uses the current state instead of a previously retrieved state.

It doesn't make sense having a quantum control on a classical gate, so we can throw an error if that is the case, and just lookup the boolean result otherwise.

Map the s_classical_control function to all the controls, and take the and of the result.

When we want a quantum control, we will be working with one "basis state" at a time, and can look up the qubit's value in that basis state to see whether the control fires.

Map the s_qc_control function to all the controls (under the given basis state), and take the and of the result.

Apply the given function only if the controls fire.

The simulated_lift_transformer is the actual transformer that does the simulation, while recreating the circuit.

Dynamic lifting can make use of a simulated result.

A dynamic transformer which simulates the circuit, whilst reconstructing it with simulated lifting results. Note: do not handle classical controlling.

Print a RandomCirc by evaluating it with a seed in the IO monad.

print_unary_with_simulated_liftings :: (QCData a, QCData b) => Format -> (a -> Circ b) -> BType a -> IO () Source #

Print a circuit, using simulated liftings.

simulate_liftings_unary :: (QCData a, QCData b) => Int -> (a -> Circ b) -> BType a -> Circ b Source #

Pass a (possibly) dynamic circuit through the simulated_dynamic_lift_transformer and evaluate the liftings so as to leave us with a static circuit that represents a single run of the original circuit, with the given inputs. We also need to pass in a seed for the RNG.