{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeFamilies #-}
{-# LINE 1 "Quipper/Libraries/Unboxing.hs" #-}
{-# LANGUAGE Rank2Types #-}
module Quipper.Libraries.Unboxing where
import Quipper
import Quipper.Internal
import Quipper.Internal.Circuit (BoxId (..), RepeatFlag (..))
import Quipper.Internal.Monad (endpoints_of_wires_in_arity)
import Quipper.Internal.Generic (inline_subroutine, transform_unary)
unbox_transformer :: Transformer Circ Qubit Bit
unbox_transformer (T_Subroutine name inv ncf _ _ _ ws2 a2 (RepeatFlag reps) f) = f $
\namespace ws c -> do
outputs <- loopM reps ws
((without_controls_if ncf) .
(with_controls c) .
((if inv then flip reverse_generic (endpoints_of_wires_in_arity a2 ws2) else id)
(inline_subroutine name namespace)))
return (outputs, c)
unbox_transformer x = identity_transformer x
unbox_unary :: (QCData x, QCData y) => (x -> Circ y) -> (x -> Circ y)
unbox_unary circ = transform_unary unbox_transformer circ
unbox :: (QCData x, QCData y, QCurry qfun x y) => qfun -> qfun
unbox = qcurry . unbox_unary . quncurry
unbox_recursive_filtered_transformer :: (BoxId -> Bool) -> Transformer Circ Qubit Bit
unbox_recursive_filtered_transformer p b@(T_Subroutine boxid inv ncf _ _ _ ws2 a2 (RepeatFlag reps) f) =
if not (p boxid)
then identity_transformer b
else f $
\namespace ws c -> do
outputs <- loopM reps ws
((without_controls_if ncf) .
(with_controls c) .
((if inv then flip reverse_generic (endpoints_of_wires_in_arity a2 ws2) else id) $
(unbox_recursive_filtered p) $
(inline_subroutine boxid namespace)))
return (outputs, c)
unbox_recursive_filtered_transformer _ x = identity_transformer x
unbox_recursive_filtered_unary :: (QCData x, QCData y) => (BoxId -> Bool) -> (x -> Circ y) -> (x -> Circ y)
unbox_recursive_filtered_unary p = transform_unary (unbox_recursive_filtered_transformer p)
unbox_recursive_filtered :: (QCData x, QCData y, QCurry qfun x y) => (BoxId -> Bool) -> qfun -> qfun
unbox_recursive_filtered p = qcurry . (unbox_recursive_filtered_unary p) . quncurry
unbox_recursive :: (QCData x, QCData y, QCurry qfun x y) => qfun -> qfun
unbox_recursive = unbox_recursive_filtered (const True)