{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeFamilies #-}
{-# LINE 1 "Quipper/Algorithms/BWT/Template.hs" #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE FlexibleInstances #-}
module Quipper.Algorithms.BWT.Template where
import Quipper
import Control.Monad (sequence)
import Quipper.Algorithms.BWT.Alternative (Oracle(..), Node, QNode)
import Quipper.Utils.Auxiliary hiding (boollist_xor)
import Quipper.Libraries.ClassicalOptim
boollist_xor :: [Bool] -> [Bool] -> [Bool]
boollist_xor x y = zipWith bool_xor x y
{-# LINE 38 "Quipper/Algorithms/BWT/Template.hs" #-}
$( decToCircMonad [d| boollist_xor :: [Bool] -> [Bool] -> [Bool]
boollist_xor x y = zipWith bool_xor x y
|] )
{-# LINE 39 "Quipper/Algorithms/BWT/Template.hs" #-}
bit_adder :: Bool -> (Bool,Bool,Bool) -> (Bool,Bool)
bit_adder sign (carry, x,y) =
let majority a b c =
if (a `bool_xor` b) then c else a in
let y' = y `bool_xor` sign in
let z = carry `bool_xor` x `bool_xor` y' in
let carry' = majority carry x y' in
(carry', z)
{-# LINE 51 "Quipper/Algorithms/BWT/Template.hs" #-}
$( decToCircMonad [d| bit_adder :: Bool -> (Bool,Bool,Bool) -> (Bool,Bool)
bit_adder sign (carry, x,y) =
let majority a b c =
if (a `bool_xor` b) then c else a in
let y' = y `bool_xor` sign in
let z = carry `bool_xor` x `bool_xor` y' in
let carry' = majority carry x y' in
(carry', z)
|] )
{-# LINE 52 "Quipper/Algorithms/BWT/Template.hs" #-}
parent :: Node -> Node
parent (x,y) = (x, False:(init y))
{-# LINE 60 "Quipper/Algorithms/BWT/Template.hs" #-}
$( decToCircMonad [d| parent :: Node -> Node
parent (x,y) = (x, False:(init y))
|] )
{-# LINE 61 "Quipper/Algorithms/BWT/Template.hs" #-}
childintree :: Node -> Bool -> Node
childintree (t,l) c =
case l of
[] -> error "childintree"
h:aa -> (t, aa ++ [c])
{-# LINE 71 "Quipper/Algorithms/BWT/Template.hs" #-}
$( decToCircMonad [d| childintree :: Node -> Bool -> Node
childintree (t,l) c =
case l of
[] -> error "childintree"
h:aa -> (t, aa ++ [c])
|] )
{-# LINE 72 "Quipper/Algorithms/BWT/Template.hs" #-}
doweld1 :: Boollist -> Bool -> [Bool] -> [Bool]
doweld1 f s l =
case l of
[] -> error "doweld1"
a:aa -> a : (snd (fold_right_zip (bit_adder s) (s, aa, f)))
{-# LINE 85 "Quipper/Algorithms/BWT/Template.hs" #-}
$( decToCircMonad [d| doweld1 :: Boollist -> Bool -> [Bool] -> [Bool]
doweld1 f s l =
case l of
[] -> error "doweld1"
a:aa -> a : (snd (fold_right_zip (bit_adder s) (s, aa, f)))
|] )
{-# LINE 86 "Quipper/Algorithms/BWT/Template.hs" #-}
doweld0 :: Boollist -> [Bool] -> [Bool]
doweld0 g l =
case l of
[] -> error "doweld0"
a:aa -> a : (g `boollist_xor` aa)
{-# LINE 96 "Quipper/Algorithms/BWT/Template.hs" #-}
$( decToCircMonad [d| doweld0 :: Boollist -> [Bool] -> [Bool]
doweld0 g l =
case l of
[] -> error "doweld0"
a:aa -> a : (g `boollist_xor` aa)
|] )
{-# LINE 97 "Quipper/Algorithms/BWT/Template.hs" #-}
weld :: Boollist -> Boollist -> Node -> Bool -> Node
weld f g (t,aa) weldBit =
if weldBit then (not t, doweld1 g t aa)
else (not t, doweld0 f aa)
{-# LINE 106 "Quipper/Algorithms/BWT/Template.hs" #-}
$( decToCircMonad [d| weld :: Boollist -> Boollist -> Node -> Bool -> Node
weld f g (t,aa) weldBit =
if weldBit then (not t, doweld1 g t aa)
else (not t, doweld0 f aa)
|] )
{-# LINE 107 "Quipper/Algorithms/BWT/Template.hs" #-}
child :: Boollist -> Boollist -> Node -> Bool -> Node
child f g (t,aa) childBit =
case aa of
[] -> error "child"
h:tt -> if h then weld f g (t, aa) childBit
else childintree (t, aa) childBit
{-# LINE 118 "Quipper/Algorithms/BWT/Template.hs" #-}
$( decToCircMonad [d| child :: Boollist -> Boollist -> Node -> Bool -> Node
child f g (t,aa) childBit =
case aa of
[] -> error "child"
h:tt -> if h then weld f g (t, aa) childBit
else childintree (t, aa) childBit
|] )
{-# LINE 119 "Quipper/Algorithms/BWT/Template.hs" #-}
level_parity :: [Bool] -> Bool
level_parity l = foldl (\a b -> not (a || b)) False (reverse l)
{-# LINE 128 "Quipper/Algorithms/BWT/Template.hs" #-}
$( decToCircMonad [d| level_parity :: [Bool] -> Bool
level_parity l = foldl (\a b -> not (a || b)) False (reverse l)
|] )
{-# LINE 129 "Quipper/Algorithms/BWT/Template.hs" #-}
is_zero :: [Bool] -> Bool
is_zero l = foldl (\a b -> a && (not b)) True l
{-# LINE 136 "Quipper/Algorithms/BWT/Template.hs" #-}
$( decToCircMonad [d| is_zero :: [Bool] -> Bool
is_zero l = foldl (\a b -> a && (not b)) True l
|] )
{-# LINE 137 "Quipper/Algorithms/BWT/Template.hs" #-}
is_root :: [Bool] -> Bool
is_root l = case (reverse l) of
[] -> True
(h:t) -> is_zero t
{-# LINE 147 "Quipper/Algorithms/BWT/Template.hs" #-}
$( decToCircMonad [d| is_root :: [Bool] -> Bool
is_root l = case (reverse l) of
[] -> True
(h:t) -> is_zero t
|] )
{-# LINE 148 "Quipper/Algorithms/BWT/Template.hs" #-}
v_function :: BoolParam
-> BoolParam
-> Boollist
-> Boollist
-> Node
-> (Bool,Node)
v_function c_hi c_lo f g a =
let aa = snd a in
let cbc_hi = newBool c_hi `bool_xor` level_parity aa in
let cbc_lo = newBool c_lo in
if (not (is_root aa) && cbc_hi && not (cbc_lo `bool_xor` (last aa))) then
(False, parent a)
else
let res = child f g a cbc_lo in
(is_zero aa || cbc_hi, res)
{-# LINE 169 "Quipper/Algorithms/BWT/Template.hs" #-}
$( decToCircMonad [d| v_function :: BoolParam
-> BoolParam
-> Boollist
-> Boollist
-> Node
-> (Bool,Node)
v_function c_hi c_lo f g a =
let aa = snd a in
let cbc_hi = newBool c_hi `bool_xor` level_parity aa in
let cbc_lo = newBool c_lo in
if (not (is_root aa) && cbc_hi && not (cbc_lo `bool_xor` (last aa))) then
(False, parent a)
else
let res = child f g a cbc_lo in
(is_zero aa || cbc_hi, res)
|] )
{-# LINE 170 "Quipper/Algorithms/BWT/Template.hs" #-}
type Color = Int
colorToBoolParam :: Color -> (BoolParam,BoolParam)
colorToBoolParam 0 = (PFalse,PFalse)
colorToBoolParam 1 = (PFalse,PTrue)
colorToBoolParam 2 = (PTrue,PFalse)
colorToBoolParam 3 = (PTrue,PTrue)
colorToBoolParam _ = error "color out of range"
classical_BWT_oracle :: Color
-> ([Qubit],[Qubit], QNode)
-> Circ (Qubit, QNode)
classical_BWT_oracle col (f,g,xs) =
unpack template_v_function b1 b2 f g xs
where
(b1,b2) = colorToBoolParam col
reversible_BWT_oracle ::
Color
-> (([Qubit], [Qubit], QNode), (Qubit, QNode))
-> Circ (([Qubit], [Qubit], QNode), (Qubit, QNode))
reversible_BWT_oracle color ((f, g, a), (r, b)) = do
comment_with_label "ENTER: reversible_BWT_oracle" ((f, g, a), (r, b)) (("f", "g", "a"), ("r", "b"))
((f, g, a), (r, b)) <- classical_to_reversible (classical_BWT_oracle color) ((f, g, a), (r, b))
comment_with_label "EXIT: reversible_BWT_oracle" ((f, g, a), (r, b)) (("f", "g", "a"), ("r", "b"))
return ((f, g, a), (r, b))
reversible_BWT_oracle_optim ::
Color
-> (([Qubit], [Qubit], QNode), (Qubit, QNode))
-> Circ (([Qubit], [Qubit], QNode), (Qubit, QNode))
reversible_BWT_oracle_optim color ((f, g, a), (r, b)) = do
comment_with_label "ENTER: reversible_BWT_oracle" ((f, g, a), (r, b)) (("f", "g", "a"), ("r", "b"))
((f, g, a), (r, b)) <- classical_to_reversible_optim (classical_BWT_oracle color) ((f, g, a), (r, b))
comment_with_label "EXIT: reversible_BWT_oracle" ((f, g, a), (r, b)) (("f", "g", "a"), ("r", "b"))
return ((f, g, a), (r, b))
oracle_template :: [Bool] -> [Bool] -> Oracle
oracle_template f g =
Oracle {
n = n,
m = m,
k = 4,
entrance = boollist_of_int_bh m 1,
oraclefun = \c (as,bs,r) -> do qf <- qinit f
qg <- qinit g
let (a:aa) = as
let (b:bb) = bs
reversible_BWT_oracle c ((qf, qg, (a,aa)), (r, (b,bb)))
qterm g qg
qterm f qf
}
where n = length f
m = n+2
oracle_template_optim :: [Bool] -> [Bool] -> Oracle
oracle_template_optim f g =
Oracle {
n = n,
m = m,
k = 4,
entrance = boollist_of_int_bh m 1,
oraclefun = \c (as,bs,r) -> do qf <- qinit f
qg <- qinit g
let (a:aa) = as
let (b:bb) = bs
reversible_BWT_oracle_optim c ((qf, qg, (a,aa)), (r, (b,bb)))
qterm g qg
qterm f qf
}
where n = length f
m = n+2