Safe Haskell | None |
---|---|

Language | Haskell98 |

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

- type RandomCirc a = StateT StdGen Circ a
- type ListCirc a = StateT [Bool] Circ a
- evalRandomCirc :: Int -> RandomCirc a -> Circ a
- evalListCirc :: [Bool] -> ListCirc a -> Circ a
- evalRandomCirc_unary :: Int -> (a -> RandomCirc b) -> a -> Circ b
- evalListCirc_unary :: [Bool] -> (a -> ListCirc b) -> a -> Circ b
- randomRRandomCirc :: Random a => (a, a) -> RandomCirc a
- print_unary_random :: QCData qa => Format -> (qa -> RandomCirc b) -> qa -> IO ()
- print_unary_list :: QCData qa => Format -> Int -> (qa -> ListCirc b) -> qa -> IO ()
- lifted_identity_transformer :: MonadTrans t => Transformer (t Circ) Qubit Bit
- random_dynamic_lift :: Bit -> RandomCirc Bool
- list_dynamic_lift :: Bit -> ListCirc Bool
- random_dynamic_lift_transformer :: DynamicTransformer (StateT StdGen Circ) Qubit Bit
- list_dynamic_lift_transformer :: DynamicTransformer (StateT [Bool] Circ) Qubit Bit
- print_unary_with_random_liftings :: (QCData a, QCData b) => Format -> (a -> Circ b) -> a -> IO ()
- print_unary_with_list_liftings :: (QCData a, QCData b) => Format -> Int -> (a -> Circ b) -> a -> IO ()
- data SimulationState = SS {}
- empty_simulation_state :: Int -> SimulationState
- type SimulatedCirc a = StateT SimulationState Circ a
- evalSimulatedCirc :: Int -> SimulatedCirc a -> Circ a
- evalSimulatedCirc_unary :: Int -> (a -> SimulatedCirc b) -> a -> Circ b
- randomRSimulatedCirc :: Random a => (a, a) -> SimulatedCirc a
- putQS :: Amplitudes Double -> SimulatedCirc ()
- putCS :: Map Bit Bool -> SimulatedCirc ()
- s_classical_control :: Map Bit Bool -> Signed (B_Endpoint Qubit Bit) -> Bool
- s_classical_controls :: Map Bit Bool -> Ctrls Qubit Bit -> Bool
- s_qc_control :: Map Bit Bool -> Map Qubit Bool -> Signed (B_Endpoint Qubit Bit) -> Bool
- s_qc_controls :: Map Bit Bool -> Map Qubit Bool -> Ctrls Qubit Bit -> Bool
- s_if_controls :: Map Bit Bool -> Ctrls Qubit Bit -> (Map Qubit Bool -> Amplitudes Double) -> Map Qubit Bool -> Amplitudes Double
- simulated_lift_transformer :: Transformer (StateT SimulationState Circ) Qubit Bit
- simulated_dynamic_lift :: Bit -> SimulatedCirc Bool
- simulated_dynamic_lift_transformer :: DynamicTransformer (StateT SimulationState Circ) Qubit Bit
- print_simulated :: Format -> SimulatedCirc b -> IO ()
- print_unary_with_simulated_liftings :: (QCData a, QCData b) => Format -> (a -> Circ b) -> BType a -> IO ()
- simulate_liftings_unary :: (QCData a, QCData b) => Int -> (a -> Circ b) -> BType a -> Circ b

# Random Dynamic Liftings and Liftings from a List

evalRandomCirc :: Int -> RandomCirc a -> Circ a Source #

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.

random_dynamic_lift :: Bit -> RandomCirc Bool Source #

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

list_dynamic_lift :: Bit -> ListCirc Bool Source #

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

random_dynamic_lift_transformer :: DynamicTransformer (StateT StdGen Circ) Qubit Bit Source #

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

list_dynamic_lift_transformer :: DynamicTransformer (StateT [Bool] Circ) Qubit Bit Source #

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

data SimulationState Source #

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

empty_simulation_state :: Int -> SimulationState Source #

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.

evalSimulatedCirc :: Int -> SimulatedCirc a -> Circ a Source #

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.

putQS :: Amplitudes Double -> SimulatedCirc () Source #

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

putCS :: Map Bit Bool -> SimulatedCirc () Source #

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

s_classical_control :: Map Bit Bool -> Signed (B_Endpoint Qubit Bit) -> Bool Source #

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.

s_classical_controls :: Map Bit Bool -> Ctrls Qubit Bit -> Bool Source #

Map the `s_classical_control`

function to all the controls, and take the
`and`

of the result.

s_qc_control :: Map Bit Bool -> Map Qubit Bool -> Signed (B_Endpoint Qubit Bit) -> Bool Source #

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.

s_qc_controls :: Map Bit Bool -> Map Qubit Bool -> Ctrls Qubit Bit -> Bool Source #

Map the `s_qc_control`

function to all the controls (under the given basis
state), and take the `and`

of the result.

s_if_controls :: Map Bit Bool -> Ctrls Qubit Bit -> (Map Qubit Bool -> Amplitudes Double) -> Map Qubit Bool -> Amplitudes Double Source #

Apply the given function only if the controls fire.

simulated_lift_transformer :: Transformer (StateT SimulationState Circ) Qubit Bit Source #

The `simulated_lift_transformer`

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

simulated_dynamic_lift :: Bit -> SimulatedCirc Bool Source #

Dynamic lifting can make use of a simulated result.

simulated_dynamic_lift_transformer :: DynamicTransformer (StateT SimulationState Circ) Qubit Bit Source #

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

print_simulated :: Format -> SimulatedCirc b -> IO () Source #

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.