Safe Haskell | None |
---|
This module contains the implementation of the circuits for determining which player has won a completed game of Hex. Please see Quipper.Algorithms.BF.Main for an overview of the boolean formula algorithm, or Quipper.Algorithms.BF.BooleanFormula to see where these circuits are used in the overall implementation of the boolean formula algorithm. The functions defined in this module make heavy use of Quipper's "build_circuit" keyword, to automatically generate quantum circuits.
Synopsis
- qtrace :: [Bool] -> [Bool]
- template_qtrace :: Circ ([Qubit] -> Circ [Qubit])
- template_show :: Show a => Circ (a -> Circ String)
- template_head :: Circ ([a] -> Circ a)
- template_tail :: Circ ([a] -> Circ [a])
- template_length :: Circ ([a] -> Circ Int)
- template_take :: Circ (Int -> Circ ([Qubit] -> Circ [Qubit]))
- template_drop :: Circ (Int -> Circ ([Qubit] -> Circ [Qubit]))
- template_replicate :: Circ (Int -> Circ (BoolParam -> Circ [BoolParam]))
- template_map :: Circ ((a -> Circ a) -> Circ ([a] -> Circ [a]))
- template_integer :: Int -> Circ Int
- template_symb_minus_ :: Circ (Int -> Circ (Int -> Circ Int))
- template_symb_plus_ :: Circ (Int -> Circ (Int -> Circ Int))
- template_symb_oangle_ :: Circ (Int -> Circ (Int -> Circ Bool))
- template_symb_oangle_symb_equal_ :: Circ (Int -> Circ (Int -> Circ Bool))
- template_div :: Circ (Int -> Circ (Int -> Circ Int))
- cand :: Bool -> Bool -> Bool
- template_cand :: Circ (Bool -> Circ (Bool -> Circ Bool))
- template_symb_cangle_ :: Circ (Int -> Circ (Int -> Circ Bool))
- template_symb_exclamation_symb_exclamation_ :: Circ ([a] -> Circ (Int -> Circ a))
- template_mod :: Circ (Int -> Circ (Int -> Circ Int))
- template_zip :: Circ ([Qubit] -> Circ ([Qubit] -> Circ [(Qubit, Qubit)]))
- template_unzip :: Circ ([(Qubit, Qubit)] -> Circ ([Qubit], [Qubit]))
- template_or :: Circ ([Qubit] -> Circ Qubit)
- type HexBoardParam = ([BoolParam], [BoolParam])
- newBools :: [BoolParam] -> [Bool]
- template_newBools :: Circ ([BoolParam] -> Circ [Qubit])
- bools2int :: [Bool] -> Int
- bools2int' :: [Bool] -> Int
- int2bools :: Int -> Int -> [Bool]
- int2bools' :: Int -> Int -> [Bool]
- int2bools'' :: Int -> [Bool]
- lookup :: [Bool] -> [Bool] -> Bool
- template_lookup :: Circ ([Qubit] -> Circ ([Qubit] -> Circ Qubit))
- update :: [Bool] -> [Bool] -> [Bool]
- template_update :: Circ ([Qubit] -> Circ ([Qubit] -> Circ [Qubit]))
- test_update :: [Qubit] -> [Qubit] -> Circ [Qubit]
- addressed_perform :: QData qa => [qa] -> [Qubit] -> (qa -> Circ b) -> Circ b
- update_pos :: Int -> [Bool] -> Bool -> [Bool]
- template_update_pos :: Circ (Int -> Circ ([Qubit] -> Circ (Qubit -> Circ [Qubit])))
- testpos :: Int -> [Bool] -> [Bool] -> [Bool] -> Int -> [Bool]
- template_testpos :: Circ (Int -> Circ ([Qubit] -> Circ ([Qubit] -> Circ ([Qubit] -> Circ (Int -> Circ [Qubit])))))
- test_positions :: Int -> Int -> Int -> [Bool] -> [Bool] -> [Bool] -> ([Bool], [Bool])
- template_test_positions :: Circ (Int -> Circ (Int -> Circ (Int -> Circ ([Qubit] -> Circ ([Qubit] -> Circ ([Qubit] -> Circ ([Qubit], [Qubit])))))))
- while_for :: Int -> Int -> Int -> [Bool] -> [Bool] -> [Bool] -> ([Bool], [Bool])
- template_while_for :: Circ (Int -> Circ (Int -> Circ (Int -> Circ ([Qubit] -> Circ ([Qubit] -> Circ ([Qubit] -> Circ ([Qubit], [Qubit])))))))
- while :: Int -> Int -> [Bool] -> [Bool] -> [Bool] -> [Bool]
- template_while :: Circ (Int -> Circ (Int -> Circ ([Qubit] -> Circ ([Qubit] -> Circ ([Qubit] -> Circ [Qubit])))))
- swapBool :: (Bool, Bool) -> (Bool, Bool)
- template_swapBool :: Circ ((Qubit, Qubit) -> Circ (Qubit, Qubit))
- flood_fill :: Int -> [Bool] -> [Bool] -> [Bool]
- template_flood_fill :: Circ (Int -> Circ ([Qubit] -> Circ ([Qubit] -> Circ [Qubit])))
- checkwin_red' :: [Bool] -> Bool
- template_checkwin_redsymb_quote_ :: Circ ([Qubit] -> Circ Qubit)
- checkwin_red :: Int -> [Bool] -> Bool
- template_checkwin_red :: Circ (Int -> Circ ([Qubit] -> Circ Qubit))
- checkwin_red_c :: Int -> [Qubit] -> Circ Qubit
- movesT :: Int -> [[Bool]] -> [Bool] -> [Bool] -> BoolParam -> Bool
- template_movesT :: Circ (Int -> Circ ([[Qubit]] -> Circ ([Qubit] -> Circ ([Qubit] -> Circ (BoolParam -> Circ Qubit)))))
- hexT :: HexBoardParam -> BoolParam -> Int -> [[Bool]] -> Bool
- template_hexT :: Circ (([BoolParam], [BoolParam]) -> Circ (BoolParam -> Circ (Int -> Circ ([[Qubit]] -> Circ Qubit))))
- newBoolParam :: Bool -> BoolParam
- newBoolParams :: [Bool] -> [BoolParam]
- hex_oracle_c :: ([Bool], [Bool]) -> Int -> Int -> [[Qubit]] -> Circ Qubit
- hex_oracle :: ([Bool], [Bool]) -> Int -> Int -> ([[Qubit]], Qubit) -> Circ ([[Qubit]], Qubit)
- hex_oracle_dummy :: ([[Qubit]], Qubit) -> Circ ([[Qubit]], Qubit)
- checkwin_red_circuit :: Int -> ([Qubit], Qubit) -> Circ ([Qubit], Qubit)
Documentation
qtrace :: [Bool] -> [Bool] Source #
A dummy gate, that when lifted will add a quantum trace to the circuit.
template_qtrace :: Circ ([Qubit] -> Circ [Qubit]) Source #
A hand-lifted version of qtrace, adds a named "trace" gate to the circuit.
template_show :: Show a => Circ (a -> Circ String) Source #
A hand-lifted version of the Prelude show
function.
template_length :: Circ ([a] -> Circ Int) Source #
A hand-lifted function to get the length
of a list.
template_take :: Circ (Int -> Circ ([Qubit] -> Circ [Qubit])) Source #
A hand-lifted version of the take
function, specialized to lists of qubits.
template_drop :: Circ (Int -> Circ ([Qubit] -> Circ [Qubit])) Source #
A hand-lifted version of the drop
function, specialized to lists of qubits.
template_map :: Circ ((a -> Circ a) -> Circ ([a] -> Circ [a])) Source #
A hand-lifted version of the map
function.
template_cand :: Circ (Bool -> Circ (Bool -> Circ Bool)) Source #
A hand-lifted version of the cand
function.
template_symb_exclamation_symb_exclamation_ :: Circ ([a] -> Circ (Int -> Circ a)) Source #
A hand-lifted version of the !!
function.
template_zip :: Circ ([Qubit] -> Circ ([Qubit] -> Circ [(Qubit, Qubit)])) Source #
A hand-lifted version of the zip
function, specialized to lists of qubits.
template_unzip :: Circ ([(Qubit, Qubit)] -> Circ ([Qubit], [Qubit])) Source #
A hand-lifted version of the unzip
function, specialized to a list of pairs of qubits.
template_or :: Circ ([Qubit] -> Circ Qubit) Source #
A hand-lifted version of the or
function, specialized to a list of qubits.
type HexBoardParam = ([BoolParam], [BoolParam]) Source #
The Hex board consists of boolean parameters.
newBools :: [BoolParam] -> [Bool] Source #
Convert a list of boolean parameters into a list of boolean inputs.
template_newBools :: Circ ([BoolParam] -> Circ [Qubit]) Source #
A hand-lifted function to convert a list of boolean parameters into a list of qubits initialized as ancillas is the given states.
bools2int :: [Bool] -> Int Source #
Convert a little-endian list of booleans into an integer by
reversing the list and calling the big-endian conversion function
bools2int'
.
bools2int' :: [Bool] -> Int Source #
Convert a big-endian list of booleans into an integer. This is mainly used for displaying a "position" register.
int2bools :: Int -> Int -> [Bool] Source #
Convert an integer into a little-endian list of booleans of length n
by reversing the big-endian list created by the int2bools'
function.
int2bools' :: Int -> Int -> [Bool] Source #
Convert an integer into a big-endian list of booleans of length n. | Note that the behavior when x is greater than 2n - 1 is erroneous.
int2bools'' :: Int -> [Bool] Source #
Convert an integer into a big-endian list of booleans of minimal length.
lookup :: [Bool] -> [Bool] -> Bool Source #
This function is a stub, because a hand lifted version is given for creating the circuits.
template_lookup :: Circ ([Qubit] -> Circ ([Qubit] -> Circ Qubit)) Source #
Hand-lifted version of lookup that uses addressed_perform
to look up a qubit at the given address.
update :: [Bool] -> [Bool] -> [Bool] Source #
Update the board, by negating the boolean in board, at the given address.
template_update :: Circ ([Qubit] -> Circ ([Qubit] -> Circ [Qubit])) Source #
Hand-lifted version of update that uses addressed_perform
to negate a qubit at the given address.
test_update :: [Qubit] -> [Qubit] -> Circ [Qubit] Source #
An unencapsulated version of template_update
, for testing purposes.
:: QData qa | |
=> [qa] | Array of quantum data. |
-> [Qubit] | Index into the array. |
-> (qa -> Circ b) | An operation to be performed. |
-> Circ b |
Perform a given operation on a quantum-addressed element of an array of quantum data.
update_pos :: Int -> [Bool] -> Bool -> [Bool] Source #
Update the boolean value at the given position, to the given value.
Oracle implementation
The functions in this implementation follow a separation of the boolean formula algorithm into two parts. The first part consists of the algorithms defined in Quipper.Algorithms.BF.BooleanFormula. The second part consists of the algorithms defined in this module. This separation relates to the first part defining the quantum parts of the algorithm, including the phase estimation, and the quantum walk, whereas the remaining four define the classical implementation of the circuit for determining which player has won a completed game of Hex, which is converted to a quantum circuit using Quipper's "build_circuit" keyword.
testpos :: Int -> [Bool] -> [Bool] -> [Bool] -> Int -> [Bool] Source #
A helper function, used by the flood_fill
function, that
checks whether a given board position is currently vacant.
template_testpos :: Circ (Int -> Circ ([Qubit] -> Circ ([Qubit] -> Circ ([Qubit] -> Circ (Int -> Circ [Qubit]))))) Source #
test_positions :: Int -> Int -> Int -> [Bool] -> [Bool] -> [Bool] -> ([Bool], [Bool]) Source #
Given a board position, this function will call
testpos
for each of its neighboring board positions.
template_test_positions :: Circ (Int -> Circ (Int -> Circ (Int -> Circ ([Qubit] -> Circ ([Qubit] -> Circ ([Qubit] -> Circ ([Qubit], [Qubit]))))))) Source #
while_for :: Int -> Int -> Int -> [Bool] -> [Bool] -> [Bool] -> ([Bool], [Bool]) Source #
This function calls test_positions
for every board position in strictly
increasing order.
template_while_for :: Circ (Int -> Circ (Int -> Circ (Int -> Circ ([Qubit] -> Circ ([Qubit] -> Circ ([Qubit] -> Circ ([Qubit], [Qubit]))))))) Source #
while :: Int -> Int -> [Bool] -> [Bool] -> [Bool] -> [Bool] Source #
This function is used by flood_fill
to perform an approximation of a while loop.
This starts with newmap containing only the blue pieces from the top row of the
Hex board, and fills in all contiguous regions, i.e., areas bounded by red pieces.
The resulting bitmap will only have blue pieces in the bottom row of the Hex board,
if blue has won. The number of times the loop will repeat is bounded by the size of
the Hex board.
template_while :: Circ (Int -> Circ (Int -> Circ ([Qubit] -> Circ ([Qubit] -> Circ ([Qubit] -> Circ [Qubit]))))) Source #
swapBool :: (Bool, Bool) -> (Bool, Bool) Source #
Swap the position of two boolean values within a pair.
flood_fill :: Int -> [Bool] -> [Bool] -> [Bool] Source #
Implements a flood_fill
algorithm on a representation of a Hex
board. Returning the "flooded" version of the board.
checkwin_red' :: [Bool] -> Bool Source #
A sub-algorithm of the checkwin_red
algorithm, which is given the bottom row of
booleans after the flood_fill
algorithm has been run, and checks to see if any of
them are True
.
checkwin_red :: Int -> [Bool] -> Bool Source #
Given a description of a valid Hex board, i.e., a board that represents a finished game, with a single piece on each square, will return a boolean value stating whether the red player has won.
checkwin_red_c :: Int -> [Qubit] -> Circ Qubit Source #
An unencapsulated version of the checkwin_red
circuit.
movesT :: Int -> [[Bool]] -> [Bool] -> [Bool] -> BoolParam -> Bool Source #
A recursive sub-algorithm of hexT
that goes through each
direction in the position register and recursively updates the
ancilla register representing the blueboard and redboard
depending on which player's turn it is. If a position is already
set in one of the ancilla registers, then the current player has
played an invalid move, and therefore loses. If we pass through the
entire position register, then we have a valid description of a Hex
board split between the redboard and blueboard registers, which
can then be passed to checkwin_red
to see who has won (we
actually only pass the redboard to checkwin_red
as every square
is now either a red piece or a blue piece, so no extra information
is held in the blueboard register).
template_movesT :: Circ (Int -> Circ ([[Qubit]] -> Circ ([Qubit] -> Circ ([Qubit] -> Circ (BoolParam -> Circ Qubit))))) Source #
hexT :: HexBoardParam -> BoolParam -> Int -> [[Bool]] -> Bool Source #
The overall hex function. This initializes two ancilla registers
to represent the redboard and the blueboard, and passes these
to the recursive movesT
function to determine which color has won
the game of Hex.
template_hexT :: Circ (([BoolParam], [BoolParam]) -> Circ (BoolParam -> Circ (Int -> Circ ([[Qubit]] -> Circ Qubit)))) Source #
newBoolParam :: Bool -> BoolParam Source #
A function to convert a boolean to a boolean parameters
newBoolParams :: [Bool] -> [BoolParam] Source #
A function to convert a list of booleans to a list of boolean parameters.
hex_oracle_c :: ([Bool], [Bool]) -> Int -> Int -> [[Qubit]] -> Circ Qubit Source #
An interface to the lifted version of hexT
(i.e.,
template_hexT
), which unbinds the inputs from the Circ
monad.
hex_oracle :: ([Bool], [Bool]) -> Int -> Int -> ([[Qubit]], Qubit) -> Circ ([[Qubit]], Qubit) Source #
An embedding of hex_oracle_c
into a reversible circuit, where all
ancillas are uncomputed automatically.
hex_oracle_dummy :: ([[Qubit]], Qubit) -> Circ ([[Qubit]], Qubit) Source #
A dummy oracle is just a gate named "HEX" applied to the input qubits.
checkwin_red_circuit :: Int -> ([Qubit], Qubit) -> Circ ([Qubit], Qubit) Source #
An embedding of checkwin_red_c
into a reversible circuit, where all
ancillas are uncomputed automatically.