-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | The Quantum IO Monad is a library for defining quantum computations in Haskell -- -- The Quantum IO Monad is a library for defining quantum computations in -- Haskell. It can be thought of as an embedded language within Haskell, -- and comes with functions for simulating the running of these quantum -- computations. The distribution contains many example computations -- written in QIO, including an implementation of Shor's algorithm. @package QIO @version 1.2 -- | This module defines a Vector as a list of pairs. In the context of -- QIO, a Vector is the type used to represent a probability -- distribution. module QIO.Vec -- | A Vector over types x and a is a wrapper around list -- of pairs of a and x. newtype Vec x a Vec :: [(a, x)] -> Vec x a unVec :: Vec x a -> [(a, x)] -- | An empty Vector is defined as the empty list empty :: Vec x a -- | The "probability" of an object in a Vector, is the sum of all the -- probabilities associated with that object. (<@@>) :: (Num x, Eq a) => Vec x a -> a -> x -- | A Vector can be multiplied by a scalar, by mapping the multiplcation -- over each probability in the vector. (<**>) :: Num x => x -> (Vec x a) -> Vec x a -- | Two Vectors can be added, using list concatenation. (<++>) :: (Vec x a) -> (Vec x a) -> Vec x a instance (Show x, Show a) => Show (Vec x a) instance Num n => Monad (Vec n) -- | This module defines the Syntax of the Quantum IO Monad, which is an -- embedded language for writing quantum computations. module QIO.QioSyn -- | For Real numbers, we simply use the built in Double type type RR = Double -- | For Complex numbers, we use the built in Complex numbers, over our -- Real number type (i.e. Double) type CC = Complex RR -- | The amplitude of a complex number is the magnitude squared. amp :: CC -> RR -- | The type of Qubits in QIO are simply integer references. newtype Qbit Qbit :: Int -> Qbit -- | A rotation is in essence a two-by-two complex valued matrix type Rotation = (Bool, Bool) -> CC -- | The underlying data type of a U unitary operation data U UReturn :: U Rot :: Qbit -> Rotation -> U -> U Swap :: Qbit -> Qbit -> U -> U Cond :: Qbit -> (Bool -> U) -> U -> U Ulet :: Bool -> (Qbit -> U) -> U -> U -- | The underlying data type of a QIO Computation data QIO a QReturn :: a -> QIO a MkQbit :: Bool -> (Qbit -> QIO a) -> QIO a ApplyU :: U -> (QIO a) -> QIO a Meas :: Qbit -> (Bool -> QIO a) -> QIO a -- | Apply the given rotation to the given qubit rot :: Qbit -> Rotation -> U -- | Swap the state of the two given qubits swap :: Qbit -> Qbit -> U -- | Apply the conditional unitary, depending on the value of the given -- qubit cond :: Qbit -> (Bool -> U) -> U -- | Introduce an Ancilla qubit in the given state, for use in the -- sub-unitary ulet :: Bool -> (Qbit -> U) -> U -- | Returns the inverse (or reverse) of the given unitary operation urev :: U -> U -- | Apply a not rotation to the given qubit unot :: Qbit -> U -- | Apply a hadamard rotation to the given qubit uhad :: Qbit -> U -- | Apply a phase rotation (of the given angle) to the given qubit uphase :: Qbit -> RR -> U -- | Initialise a qubit in the given state (adding it to the overall -- quantum state) mkQbit :: Bool -> QIO Qbit -- | Apply the given unitary operation to the current quantum state applyU :: U -> QIO () -- | Measure the given qubit, and return the measurement outcome (note that -- this operation may affect the overall quantum state, as a measurement -- is destructive) measQbit :: Qbit -> QIO Bool -- | The identity rotation rid :: Rotation -- | The not rotation rnot :: Rotation -- | The hadamard rotation rhad :: Rotation -- | The phase rotation rphase :: RR -> Rotation -- | Returns the inverse (or reverse) of the given rotation rrev :: Rotation -> Rotation -- | A helper function for the show instance of U show' :: U -> Int -> Int -> String -- | A helper function that returns a string of 4x spaces. spaces :: Int -> String instance Num Qbit instance Enum Qbit instance Eq Qbit instance Ord Qbit instance Show U instance Show Rotation instance Show Qbit instance Eq Rotation instance Monad QIO instance Monoid U -- | This module defines a type class for quantum data types, as well as -- some instances of this class for pairs, lists, and quantum integers module QIO.Qdata -- | The Qdata type class defines the operation a quantum datatype -- must implement. class Qdata a qa | a -> qa, qa -> a mkQ :: Qdata a qa => a -> QIO qa measQ :: Qdata a qa => qa -> QIO a letU :: Qdata a qa => a -> (qa -> U) -> U condQ :: Qdata a qa => qa -> (a -> U) -> U -- | A recursive conditional on a list of quantum data condQRec :: Qdata a qa => [qa] -> [(a -> U)] -> U -- | Quantum integers are of a fixed length, which is defined by this -- constant. Currently, this is set to 4. qIntSize :: Int -- | A Quantum integer is a wrapper around a fixed-length list of qubits newtype QInt QInt :: [Qbit] -> QInt -- | Convert an integer to a list of Booleans int2bits :: Int -> [Bool] -- | Convert a list of Booleans to an integer bits2int :: [Bool] -> Int instance Show QInt instance Qdata Int QInt instance Qdata a qa => Qdata [a] [qa] instance (Qdata a qa, Qdata b qb) => Qdata (a, b) (qa, qb) instance Qdata Bool Qbit -- | This module contains the definition of a Type Class that represents a -- Heap. In the context of QIO, a Heap is the type used to represent a -- classical basis state. An instance of a Heap is also defined, that -- makes use of a Map. module QIO.Heap -- | The Heap Type Class class Eq h => Heap h where hswap h x y = update (update h y (fromJust (h ? x))) x (fromJust (h ? y)) initial :: Heap h => h update :: Heap h => h -> Qbit -> Bool -> h (?) :: Heap h => h -> Qbit -> Maybe Bool forget :: Heap h => h -> Qbit -> h hswap :: Heap h => h -> Qbit -> Qbit -> h -- | HeapMap is simply a type synonym for a Map from Qubits to Boolean -- values type HeapMap = Map Qbit Bool instance Heap HeapMap -- | This module defines the functions that can be used run the classical -- subset of QIO. That is, QIO computations that only use classical -- unitary operations. module QIO.QioClass -- | A classical unitary operation is defined as a function that will -- update the current classical state. newtype UnitaryC U :: (Int -> HeapMap -> HeapMap) -> UnitaryC unU :: UnitaryC -> Int -> HeapMap -> HeapMap -- | A single qubit rotation can be converted into the classical unitary -- type, if it is indeed classical (otherwise an error is thrown). uRotC :: Qbit -> Rotation -> UnitaryC -- | A swap operation can be defined in the classical unitary type. uSwapC :: Qbit -> Qbit -> UnitaryC -- | A conditional operation can be defined in the classical unitary type. uCondC :: Qbit -> (Bool -> UnitaryC) -> UnitaryC -- | A let operation can be defined in the classical unitary type. uLetC :: Bool -> (Qbit -> UnitaryC) -> UnitaryC -- | A unitary can be run by converting it into the classical unitary type. runUC :: U -> UnitaryC -- | A classical state consists of the next free qubit reference, along -- with a Heap that represents the overall state of the current qubits in -- scope. data StateC StateC :: Int -> HeapMap -> StateC fv :: StateC -> Int heap :: StateC -> HeapMap -- | An initial state is defined as an empty heap, with 0 set as the next -- free qubit referece initialStateC :: StateC -- | A QIO computation can be converted into a stateful computation, over a -- state of type StateC. runQStateC :: QIO a -> State StateC a -- | We can run a classical QIO computation by converting it into a -- stateful computation, and evaluating that using the initial state. runC :: QIO a -> a instance Monoid UnitaryC -- | This module defines a class of Vectors over types with Equality, along -- with an instance of this class using lists of pairs. In the context of -- QIO, these Vectors are used to hold the amplitudes of various -- basis-states within a superposition. module QIO.VecEq -- | Any type that fulfills this type class is a Vector over types with -- equality class VecEq v vzero :: VecEq v => v x a (<+>) :: (VecEq v, Eq a, Num x) => v x a -> v x a -> v x a (<*>) :: (VecEq v, Num x, Eq x) => x -> v x a -> v x a (<@>) :: (VecEq v, Eq a, Num x) => a -> v x a -> x fromList :: VecEq v => [(a, x)] -> v x a toList :: VecEq v => v x a -> [(a, x)] -- | This type is a wrapper around a list of pairs. newtype VecEqL x a VecEqL :: [(a, x)] -> VecEqL x a unVecEqL :: VecEqL x a -> [(a, x)] -- | An empty VecEqL is a wrapper around the empty list vEqZero :: VecEqL x a -- | A basis state with the given amplitude can be added to a VecEqL by -- adding the amplitudes if the state is already in the vector, or by -- inserting the base state if it isn't already in the vector. add :: (Eq a, Num x) => (a, x) -> VecEqL x a -> VecEqL x a -- | Combining two vectors is achieved by folding the add operation over -- the second vector vEqPlus :: (Eq a, Num x) => VecEqL x a -> VecEqL x a -> VecEqL x a -- | Scalar multiplcation is achieved by mapping the multiplication over -- each pair in the vector. Multiplication by 0 is a special case, and -- will remove all the basis states from the vector. vEqTimes :: (Num x, Eq x) => x -> VecEqL x a -> VecEqL x a -- | The amplitude of an element can be found by looking through each -- element until the matchinf one is found. vEqAt :: (Eq a, Num x) => a -> VecEqL x a -> x -- | An EqMonad is a monad that has Return and Bind operations that depend -- on the type in the monad being a member of the Eq class class EqMonad m eqReturn :: (EqMonad m, Eq a) => a -> m a eqBind :: (EqMonad m, Eq a, Eq b) => m a -> (a -> m b) -> m b -- | We can define a datatype that holds EqMonad operations, so that it can -- be defined as a Monad. data AsMonad m a Embed :: m a -> AsMonad m a Return :: a -> AsMonad m a Bind :: AsMonad m a -> (a -> AsMonad m b) -> AsMonad m b -- | Given Equality, we can unembed the EqMonad operations from an AsMonad unEmbed :: Eq a => AsMonad m a -> m a instance (Show x, Show a) => Show (VecEqL x a) instance EqMonad m => Monad (AsMonad m) instance (VecEq v, Num x, Eq x) => EqMonad (v x) instance VecEq VecEqL -- | This module defines the functions that can be used to simulate the -- running of QIO computations. module QIO.Qio -- | A Pure state can be thought of as a vector of classical basis -- states, stored as Heaps, along with complex amplitudes. type Pure = VecEqL CC HeapMap -- | The state of a qubit can be updated in a Pure state, by mapping the -- update operation over each Heap. updateP :: Pure -> Qbit -> Bool -> Pure -- | A Unitary can be thought of as an operation on a HeapMap that -- may produce a Pure state. newtype Unitary U :: (Int -> HeapMap -> Pure) -> Unitary unU :: Unitary -> Int -> HeapMap -> Pure -- | A function that checks if a given Rotation is in face unitary. -- Note that this is currently a dummy stub function, and states that any -- rotation is unitary. (This is only o.k. at the moment as all the -- rotations defined in the QIO library are unitary, but won't catch -- un-unitary user-defined Rotations) unitaryRot :: Rotation -> Bool -- | Given the four complex numbers that make up a 2-by-2 matrix, we can -- create a Unitary that applies the rotation to the given qubit. uMatrix :: Qbit -> (CC, CC, CC, CC) -> Unitary -- | A rotation can be converted into a Unitary, using the -- uMatrix function uRot :: Qbit -> Rotation -> Unitary -- | A swap operation can be defined as a Unitary uSwap :: Qbit -> Qbit -> Unitary -- | A conditional operation can be defined as a Unitary uCond :: Qbit -> (Bool -> Unitary) -> Unitary -- | A let operation can be defined as a Unitary uLet :: Bool -> (Qbit -> Unitary) -> Unitary -- | Any member of the U type can be "run" by converting it into a -- Unitary. runU :: U -> Unitary -- | A quantum state is a defined as the next free qubit reference, along -- with the Pure state that represents the overall quantum state data StateQ StateQ :: Int -> Pure -> StateQ free :: StateQ -> Int pure :: StateQ -> Pure -- | The initial StateQ initialStateQ :: StateQ -- | Given a Pure state, return a sum of all the amplitudes. pa :: Pure -> RR -- | A Split, is defined as a probability, along with the two Pure states. data Split Split :: RR -> Pure -> Pure -> Split p :: Split -> RR ifTrue :: Split -> Pure ifFalse :: Split -> Pure -- | Given a Pure state, we can create a Split, by essentially splitting -- the state into the part where the qubit is True, and the part where -- the qubit is False. This is how measurements are implemented in QIO. split :: Pure -> Qbit -> Split -- | We can extend a Monad into a PMonad if it defines a way of -- probabilistically merging two computations, based on a given -- probability. class Monad m => PMonad m merge :: PMonad m => RR -> m a -> m a -> m a -- | The type Prob is defined as a wrapper around Vectors with Real -- probabilities. data Prob a Prob :: Vec RR a -> Prob a unProb :: Prob a -> Vec RR a -- | Given a PMonad, a QIO Computation can be converted into a Stateful -- computation over a quantum state (of type StateQ). evalWith :: PMonad m => QIO a -> State StateQ (m a) -- | A QIO computation is evaluated by converting it into a stateful -- computation and then evaluating that over the initial state. eval :: PMonad m => QIO a -> m a -- | Running a QIO computation evaluates it in the IO PMonad run :: QIO a -> IO a -- | Simulating a QIO computation evaluates it in the Prob PMonad sim :: QIO a -> Prob a instance PMonad Prob instance Monad Prob instance Show a => Show (Prob a) instance PMonad IO instance Monoid Unitary -- | This module contains some simple examples of quantum computations -- written using the Quantum IO Monad. module QIO.QExamples -- | Initialise a qubit in the |0> state q0 :: QIO Qbit -- | Initialise a qubit in the |1> state q1 :: QIO Qbit -- | Initialise a qubit in the |+> state. This is done by applying a -- Hadamard gate to the |0> state. qPlus :: QIO Qbit -- | Initialise a qubit in the |-> state. This is done by applying a -- Hadamard gate to the |1> state. qMinus :: QIO Qbit -- | Create a random Boolean value, by measuring the state |+> randBit :: QIO Bool -- | This function can be used to share the state of one qubit, with -- another newly initialised qubit. This is not the same as -- cloning, as the two qubits will be in an entangled state. -- sharing is achieved by simply initialising a new qubit in state -- |0>, and then applying a controlled-not to that qubit, depending on -- the state of the given qubit. share :: Qbit -> QIO Qbit -- | A Bell state can be created by sharing the |+> state bell :: QIO (Qbit, Qbit) -- | This function creates a Bell state, and then measures it. The -- resulting pair of Booleans will always be in the same state as one -- another. test_bell :: QIO (Bool, Bool) -- | This function initiaslised a qubit in the state corresponding to the -- given Boolean value. The Hadamard transform (which is self-inverse) is -- applied to the qubit twice, and then the qubit is measured. This -- should correspond to the identity function on the given Boolean value. hadTwice :: Bool -> QIO Bool -- | A different implementation of hadTwice where QIO is used to -- apply two unitaries, each of which is a single Hadamard gate, as -- opposed to a single unitary, which is two Hadamard gates. hadTwice' :: Bool -> QIO Bool -- | The operations that Alice must perform in the classic quantum -- teleportation example. alice :: Qbit -> Qbit -> QIO (Bool, Bool) -- | A definition of the Pauli-Z gate. uZZ :: Qbit -> U -- | The unitary operations that Bob must perform in the classic quantum -- teleportation example. bobsU :: (Bool, Bool) -> Qbit -> U -- | The overall operations that Bob must perform in the classic quantum -- teleportation example bob :: Qbit -> (Bool, Bool) -> QIO Qbit -- | The overall QIO computation that teleports the state of single qubit teleportation :: Qbit -> QIO Qbit -- | A small test function of quantum teleportation, which teleports a bell -- state, and then measures it. test_teleport :: QIO (Bool, Bool) -- | teleports a qubit in the state |1> teleport_true' :: QIO Qbit -- | teleports a qubit in the state |1>, and then measures it teleport_true :: QIO Bool -- | teleports a qubit in the state |+> teleport_random' :: QIO Qbit -- | teleports a qubit in the state |+>, and then measures it. teleport_random :: QIO Bool -- | The implementation of Deutsch's algorithm requires a unitary to -- represent the oracle function. u :: (Bool -> Bool) -> Qbit -> Qbit -> U -- | Deutsch's algorithm takes an oracle function, and returns a -- Boolean that states whether the given function is balanced, or -- consant. deutsch :: (Bool -> Bool) -> QIO Bool -- | A test QIO computation that is infinite in one measurement path. This -- is a problem if we try to calculate the probability distribution of -- possible results, as the infinite path will be followed. problem :: QIO Bool -- | This module contains QIO unitaries that represent various Arithmetic -- functions. These are exactly the Arithmetic functions required to -- implement Shor's algorithm. module QIO.QArith -- | A swap operation can be applied to two QInts, by mapping qubit swap -- operations over the underlying qubits that make up a QInt. swapQInt :: QInt -> QInt -> U -- | ifElseQ defines a quantum If statement, whereby depending on the state -- of the given (control) qubit, one of two unitaries are applied. ifElseQ :: Qbit -> U -> U -> U -- | ifQ defines a special case of ifElseQ, where the Else part of the -- computation is simply the identity. ifQ :: Qbit -> U -> U -- | A controlled-not operations, that applies a Not to the second qubit, -- depending on the state of the first qubit. cnot :: Qbit -> Qbit -> U -- | A three-qubit adder. addBit :: Qbit -> Qbit -> Qbit -> U -- | Calculates the carry (qu)bit. carry :: Qbit -> Qbit -> Qbit -> Qbit -> U -- | uses the addBit and carry unitaries to add the contents -- of two quantum registers, setting an overflow bit if necessary. This -- unitary makes use of a letU construct to introduce ancilla bits as -- necessary. addBits :: [Qbit] -> [Qbit] -> Qbit -> U -- | An alternate implementation of addBits that is explicitly given -- a register of ancilla qubits for all the intermediate carry -- results. addBits' :: [Qbit] -> [Qbit] -> [Qbit] -> Qbit -> U -- | Defines the QIO unitary that adds two QInts, with an overflow qubit adder :: QInt -> QInt -> Qbit -> U -- | A small function to test the adder unitary tadder :: (Int, (Int, Bool)) -> QIO (Int, (Int, Bool)) -- | A small function to test applying the adder unitary in reverse, ie. -- this defines subtraction. tRadder :: (Int, (Int, Bool)) -> QIO (Int, (Int, Bool)) -- | A small function to test applying the adder unitary, and then applying -- the reverse of the adder unitary, which should give the identity -- function. tBiAdder :: (Int, (Int, Bool)) -> QIO (Int, (Int, Bool)) -- | This unitary is for modular addition, and is done modulo some fixed -- classical modulus, given as the first Int argument. adderMod :: Int -> QInt -> QInt -> U -- | A small function to test the modular addition unitary. tadderMod :: Int -> (Int, Int) -> QIO (Int, Int) -- | This unitary defines modular multiplication, whereby the integer -- n is the the modulus, and the integer a is the -- scalar by which to multiply the quantum integer x. The result -- is added to the quantum integer y, ie. if y is in -- state 0 before the operation, then it is left in the sate a*x mod n. multMod :: Int -> Int -> QInt -> QInt -> U -- | A small function for testing the modular multiplication unitary. This -- function initialises y as zero, so the output is as expected. tmultMod :: Int -> Int -> Int -> QIO (Int, Int) -- | A unitary that adds a single qubit control to modular multiplication condMultMod :: Qbit -> Int -> Int -> QInt -> QInt -> U -- | A classical Haskell function that returns the smalles positive inverse -- of a `mod n (if one exists). That is, the smallest positive integer x, -- such that x*a mod n equals 1. inverseMod :: Int -> Int -> Int -- | The unitary that represents modular exponentiation is constructed in -- terms of multiple "steps". This function defines those steps. modExpStep :: Qbit -> Int -> Int -> QInt -> Int -> U -- | A QIO computation that forms a test of the modExpStep unitary modExpStept :: Int -> Int -> Int -> Int -> QIO Int -- | This function defines a unitary that implements modular -- exponentiation, as required in Shor's algorithm. Given classical -- arguments n and a, a quantum register containg x, and a quantum -- register o in state 1, this unitary will leave the quantum register o -- in the state a^x mod n. modExp :: Int -> Int -> QInt -> QInt -> U -- | A QIO computation that forms a test of the modular exponentiation -- unitary. modExpt :: Int -> (Int, Int) -> QIO Int -- | This module implements various functions that return a probabilistic -- result, defined as unitary operators, and quantum computations. module QIO.QIORandom -- | The exponentiated Pauli-X rotation rX :: RR -> Rotation -- | The exponentiated Pauli-Y rotation rY :: RR -> Rotation -- | Applies a Hadamard rotation to each qubit in the given list of qubits hadamards :: [Qbit] -> U -- | returns the highest integer power of 2 that is less than or equal to -- x\ pow2 :: Int -> Int -- | A rotation that, given a qubit in state 0, leaves it in a -- super-position of 0 and 1, such that the probability of measuring as -- state 0 is ps. weightedU :: RR -> Qbit -> U -- | A QIO computation that uses the weightedU unitary, to return a -- Bool that has a probablity of pf of being False. weightedBool :: RR -> QIO Bool -- | removes any leading Falses from a list of booleans rlf :: [Bool] -> [Bool] -- | removes any leading Falses from the (big-endian) bit-wise -- representation of the given Int. rlf_l :: Int -> [Bool] -- | returns the number of bits left after calling the flf_l -- function rlf_n :: Int -> Int -- | Given an Int max that is the largest number required to be represented -- in a quantum register, this function trims the front off the given -- register, to leave the number of qubits required to represent max. trim :: Int -> [Qbit] -> [Qbit] -- | Given an Int max, and a quantum register in the state max, this -- function defines a unitary operation that will leave the quantum -- register in state that has equal probability of being measured in any -- of the states 0 to max. randomU :: Int -> [Qbit] -> U -- | A quantum computation that will return a quantum integer in a state -- that has equal probabilities of being measured in any of the state 0 -- to max. randomQInt :: Int -> QIO QInt -- | A quantum computation that will return a quantum integer in a state -- that has equal probabilities of being measured in any of the state min -- to max. randomQIO :: (Int, Int) -> QIO Int -- | A quantum computation that measures the outcome of randomQInt randomInt :: Int -> QIO Int -- | A quantum computation that returns an integer that is equally likely -- to be any number in the range 0 to x-1 random :: Int -> QIO Int -- | This function uses a Quantum computation to simulate the roll of a -- dice dice :: IO Int -- | This function simulates the given number of repitions of dice rolls dice_rolls :: Int -> IO [Int] -- | Returns the number of occurences of 1 through 6 in the given list of -- Ints occs :: [Int] -> (Int, Int, Int, Int, Int, Int) -- | Returns the number of occurences of 1 through 6 in the given number of -- rolls of the dice. probs' :: Int -> IO (Int, Int, Int, Int, Int, Int) -- | Returns the percentage of occurences of 1 through 6, after the given -- number of rolls of the dice. probs :: Int -> IO (RR, RR, RR, RR, RR, RR) -- | This module provides an implementation of the Quantum Fourier -- Transform in QIO. module QIO.Qft -- | Defines the unitary the represents appliying a Quantum Fourier -- Transform to the given quantum register. qft :: [Qbit] -> U -- | The definition of the QFT unitary makes use of an accumulator, to -- repeatedly apply smaller QFTs to the tail of the given quantum -- register. qftAcu :: [Qbit] -> [Bool] -> [Bool] -> U -- | The "base" step involved in a QFT is a series of controlled rotations. qftBase :: [Bool] -> Qbit -> U -- | The rotation used in the QFT is a phase rotation, parameterised by the -- angle 1/(2^k) rotK :: Int -> Qbit -> U -- | A test of the QFT unitary, over a quantum integer initialised to n. tryQft :: Int -> QIO Int -- | This module defines the QIO computation that represents Shor's -- factorisation algorithm. It makes use of the Arithmetic library, and -- the Quantum Fourier Transform. module QIO.Shor -- | The inverse Quantum Fourier Transform is defined by reversing the QFT qftI :: QInt -> U -- | The Hadamard transform can be mapped over the qubits in a Quantum -- Integer. hadamardsI :: QInt -> U -- | The overall "phase-estimation" structure of Shor's algorithm. shorU :: QInt -> QInt -> Int -> Int -> U -- | A quantum computation the implementes shor's algorithm, returning the -- period of the function. shor :: Int -> Int -> QIO Int -- | A classical (inefficient) implementation of the period finding -- subroutine period :: Int -> Int -> Int -- | A wrapper for Shor's algorithm, that returns prime factors of n. factor :: Int -> QIO (Int, Int) -- | This function simulates the running of a QIO computation, whilst using -- System.Time functions to time how long the simulation took. runTime :: QIO a -> IO a -- | Times the running of various subroutines within the factorisation -- algorithm. factorV' :: Int -> IO (Int, Int) -- | Calls the factorV', and times the overall factorisation. factorV :: Int -> IO () -- | This function defines a quantum computation that returns a random -- index, that is used to pick from a list of integers that are co-prime -- to n. rand_coprime :: Int -> QIO Int -- | A different implementation of rand_coprime, that defines a -- quantum computation that returns a random number between 2 and n, that -- is then returned if it is co-prime to n. rand_co' :: Int -> QIO Int -- | Integer division by 2. half :: Int -> Int -- | Reduces a pair of integers, by dividing them by thier gcd, until their -- gcd is 1. reduce :: (Int, Int) -> (Int, Int)