{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeFamilies #-}
{-# LINE 1 "Quipper/Libraries/Qram.hs" #-}
module Quipper.Libraries.Qram (
indexed_access,
indexed_fetch_at,
indexed_store_at,
indexed_swap_at,
) where
import Quipper
import Quipper.Libraries.Arith
indexed_access :: (QData qa) => [qa] -> QDInt -> Circ qa
indexed_access as i = indexed_access_qulist as (qulist_of_qdint_bh i)
indexed_access_qulist :: (QData qa) => [qa] -> [Qubit] -> Circ qa
indexed_access_qulist [] i = error "indexed_access: cannot address length-0 register"
indexed_access_qulist (a:as) [] = return a
indexed_access_qulist as (i:is) = do
let n = 2 ^ length is
r = max 0 $ min n (length as - n)
for (r-1) 0 (-1) $ \j -> do
swap_at (as !! j) (as !! (j+n)) `controlled` i
a <- indexed_access_qulist as is
return a
indexed_fetch_at :: (QData qa) => [qa] -> QDInt -> qa -> Circ ()
indexed_fetch_at as i q = do
with_computed (indexed_access as i) $ \x -> do
controlled_not_at q x
indexed_store_at :: (QData qa) => [qa] -> QDInt -> qa -> Circ ()
indexed_store_at as i q = do
with_computed (indexed_access as i) $ \x -> do
controlled_not_at x q
indexed_swap_at :: (QData qa) => [qa] -> QDInt -> qa -> Circ ()
indexed_swap_at as i q = do
with_computed (indexed_access as i) $ \x -> do
swap_at x q