stim-parser-0.1.0.0: src/StimParser/Trans.hs
{-# LANGUAGE TypeFamilies #-}
module StimParser.Trans where
import Control.Monad.State.Lazy
import Control.Monad
import StimParser.Expr
import Data.Maybe
type Env = State (Int, Coords)
-- questions raised:
-- is that `Measure` the only case where we increase the count?
-- no, each Gpp also increases the count
-- if `Measure` contains multiple qubits, do we increase the count by one for each qubit?
-- yes
-- how could we deal with the rec inside the Repeat block?
-- just, expand it into List
-- TODO: SHIFT_COORDS will affect the coordinate in stim annotation
-- transform all (QRec Rec) into (Q Int)
class FlattenQ a where
type Out a
flattenQ :: a -> Env (Out a)
instance FlattenQ Q where
type Out Q = Q
flattenQ (Q i) = return (Q i)
flattenQ (QRec (Rec r)) = do
(count, _) <- get
return $ Q (count + r + 1)
flattenQ _ = error "currently flattenQ does not support this qtype"
instance FlattenQ Gate where
type Out Gate = Gate
flattenQ (Gate gt tag qs) = do
nqs <- mapM flattenQ qs
return $ Gate gt tag nqs
-- for each measure, we increase the count by 1
-- currently, we assume measure does not contains (QRec Rec)
instance FlattenQ Measure where
type Out Measure = Measure
flattenQ m@(Measure mty tag mph qs) = do
(count, cs) <- get
let ncount = count + length qs
put (ncount, cs)
return m
instance FlattenQ Gpp where
type Out Gpp = Gpp
flattenQ g = do
(count, cs) <- get
let ncount = count + 1
put (ncount, cs)
return g
instance FlattenQ Noise where
type Out Noise = Noise
flattenQ (NoiseNormal nty tag errTag phs qs) = do
nqs <- mapM flattenQ qs
return $ NoiseNormal nty tag errTag phs nqs
flattenQ n@(NoiseE {}) = return n
instance FlattenQ Ann where
type Out Ann = Maybe Ann
flattenQ (Ann SHIFT_COORDS tag fs qs) = do
-- nqs <- mapM flattenQ qs
(count, Coords cs) <- get
let ncs = zipWith (+) fs cs
put (count, Coords ncs)
return Nothing
-- TODO: type-level constraint that fs and cs should be of the same length
-- TODO: type-level constraint that count should not be used in this case
flattenQ (Ann DETECTOR tag fs qs) = do
(count, Coords cs) <- get
let nfs = zipWith (+) fs cs
nqs <- mapM flattenQ qs
return $ Just $ Ann DETECTOR tag nfs nqs
flattenQ (Ann aty tag fs qs) = do
nqs <- mapM flattenQ qs
return $ Just $ Ann aty tag fs nqs
instance FlattenQ Stim where
type Out Stim = Maybe Stim
flattenQ (StimG g) = (Just . StimG) <$> flattenQ g
flattenQ (StimM g) = (Just . StimM) <$> flattenQ g
flattenQ (StimGpp g) = (Just . StimGpp) <$> flattenQ g
flattenQ (StimNoise g) = (Just . StimNoise) <$> flattenQ g
flattenQ (StimAnn g) = do
ng <- flattenQ g
case ng of
Nothing -> return Nothing
Just nng -> return $ Just $ StimAnn nng
flattenQ (StimList gs) = do
ngs <- mapM flattenQ gs
let nngs = map fromJust $ filter isJust ngs
return $ Just $ StimList nngs
-- StimList <$> mapM flattenQ gs
flattenQ (StimRepeat n s) = do
ns <- replicateM n (flattenQ s)
let nns = map fromJust $ filter isJust ns
return $ Just $ StimList nns
-- StimList <$> replicateM n (flattenQ s)