{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeFamilies #-}
{-# LINE 1 "Quipper/Algorithms/BF/Testing.hs" #-}
module Quipper.Algorithms.BF.Testing where
import Quipper.Algorithms.BF.BooleanFormula
import Quipper.Algorithms.BF.Hex
import Quipper.Algorithms.BF.HexBoard
import Quipper
import Quipper.Libraries.Simulation
import Quipper.Libraries.Unboxing
moves_to_hex :: BooleanFormulaOracle -> [Int] -> HexBoard
moves_to_hex o moves = fromPos o pos
where pos = moves_to_pos o moves
moves_to_pos :: BooleanFormulaOracle -> [Int] -> [[Bool]]
moves_to_pos o moves = map (int2bools (oracle_m o)) moves
set_bool :: [Bool] -> [Bool] -> Bool -> [Bool]
set_bool board address value = (take n board) ++ value:(drop (n+1) board)
where n = bools2int address
fromPos :: BooleanFormulaOracle -> [[Bool]] -> HexBoard
fromPos o pos = fromPos' pos (start_board o) (odd (oracle_s o))
where
fromPos' :: [[Bool]] -> HexBoard -> Bool -> HexBoard
fromPos' [] rb _ = rb
fromPos' (p:ps) (red,blue) is_red = fromPos' ps (if is_red then (set_bool red p True,set_bool blue p False) else (set_bool red p False,set_bool blue p True)) (not is_red)
double :: Double
double = undefined
oracle_with_input :: BooleanFormulaOracle -> BoolRegister -> Circ BooleanFormulaRegister
oracle_with_input o input = do
reg <- qinit input
oracle o reg
return reg
run_oracle_with_input :: BooleanFormulaOracle -> BoolRegister -> IO BoolRegister
run_oracle_with_input oracle input = do
run_generic_io double (unbox (oracle_with_input oracle input))
diffuse_with_input :: BoolRegister -> Circ BooleanFormulaRegister
diffuse_with_input input = do
reg <- qinit input
diffuse reg
return reg
run_diffuse_with_input :: BoolRegister -> IO BoolRegister
run_diffuse_with_input input = do
run_generic_io double (diffuse_with_input input)
walk_with_input :: BoolRegister -> Circ BooleanFormulaRegister
walk_with_input input = do
reg <- qinit input
walk reg
return reg
run_walk_with_input :: BoolRegister -> IO BoolRegister
run_walk_with_input input = do
run_generic_io double (walk_with_input input)
undo_oracle_with_input :: BooleanFormulaOracle -> BoolRegister -> Circ BooleanFormulaRegister
undo_oracle_with_input o input = do
reg <- qinit input
undo_oracle o reg
return reg
run_undo_oracle_with_input :: BooleanFormulaOracle -> BoolRegister -> IO BoolRegister
run_undo_oracle_with_input oracle input = do
run_generic_io double (unbox (undo_oracle_with_input oracle input))
run_odwu_with_input :: BooleanFormulaOracle -> BoolRegister -> IO BoolRegister
run_odwu_with_input o input = do
oracle_output <- run_oracle_with_input o input
diffuse_output <- run_diffuse_with_input oracle_output
walk_output <- run_walk_with_input diffuse_output
run_undo_oracle_with_input o walk_output
repeat_odwu_n :: Int -> BooleanFormulaOracle -> BoolRegister -> IO [HexBoard]
repeat_odwu_n n oracle input = repeat_odwu_n' n oracle input []
where
repeat_odwu_n' 0 _ _ accum = return (reverse accum)
repeat_odwu_n' n oracle input accum = do
output <- run_odwu_with_input oracle input
let flags = position_flags output
let pos = position output
let hexboard = start_board (update_start_board oracle (fromPos oracle (tidy flags pos)))
repeat_odwu_n' (n-1) oracle output (hexboard:accum)
repeat_odwu_infinite :: BooleanFormulaOracle -> BoolRegister -> IO ()
repeat_odwu_infinite oracle input = do
output <- run_odwu_with_input oracle input
let flags = position_flags output
let pos = position output
putStrLn "Position Register: "
putStr (show ((\(l,p) -> [if l then 'L' else ' ',if p then 'P' else ' ']) flags))
putStr " : "
putStrLn (show (map bools2int pos))
output_start_board ASCII (update_start_board oracle (fromPos oracle (tidy flags pos)))
repeat_odwu_infinite oracle output
tidy :: (Bool,Bool) -> [[Bool]] -> [[Bool]]
tidy flags pos = if pos == (zeroes ++ [three]) then [] else tidy' flags pos
where
zeroes = replicate (length pos - 1) (replicate (length (head pos)) False)
three = (replicate (length (head pos) - 2) False) ++ [True,True]
tidy' _ [] = []
tidy' (l,p) (a:as) = case (a == replicate (length a) False) of
True -> tidy' (l,p) as
False -> case (a == (replicate (length a - 1) False) ++ [True]) of
False -> a:as
True -> if p then (a:as) else as
hex_with_input :: BooleanFormulaOracle -> BoolRegister -> Circ Qubit
hex_with_input oracle input = do
let init = start_board oracle
let s = oracle_s oracle
let x_max = oracle_x_max oracle
reg <- qinit input
let pos = position reg
let binary = work_binary reg
(_,binary') <- hex_oracle init s x_max (pos,binary)
return binary'
run_hex_with_input :: BooleanFormulaOracle -> BoolRegister -> IO Bool
run_hex_with_input oracle input = run_generic_io double (hex_with_input oracle input)
checkwin_trace :: BooleanFormulaOracle -> IO [[Bool]]
checkwin_trace o = do
let circuit = hex_with_input o (createRegister o)
trace <- run_generic_trace_io double circuit
let boards = map (\(Vector [(bs,_)]) -> bs) trace
return boards