    {-# LANGUAGE TypeFamilies #-}

    -- | A sequential representation.
    module Futhark.IR.Seq
      ( Seq,

        -- * Simplification
        simplifyProg,

        -- * Module re-exports
        module Futhark.IR.Prop,
        module Futhark.IR.Traversals,
        module Futhark.IR.Pretty,
        module Futhark.IR.Syntax,
      )
    where

    import Futhark.Builder
    import Futhark.Construct
    import Futhark.IR.Pretty
    import Futhark.IR.Prop
    import Futhark.IR.Syntax
    import Futhark.IR.Traversals
    import Futhark.IR.TypeCheck qualified as TC
    import Futhark.Optimise.Simplify qualified as Simplify
    import Futhark.Optimise.Simplify.Engine qualified as Engine
    import Futhark.Optimise.Simplify.Rules
    import Futhark.Pass

    -- | The phantom type for the Seq representation.
    data Seq

    instance RepTypes Seq

    instance ASTRep Seq where
      expTypesFromPat :: forall (m :: * -> *).
    (HasScope Seq m, Monad m) =>
    Pat (LetDec Seq) -> m [BranchType Seq]
    expTypesFromPat = [ExtType] -> m [ExtType]
    forall a. a -> m a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure ([ExtType] -> m [ExtType])
    -> (Pat Type -> [ExtType]) -> Pat Type -> m [ExtType]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Pat Type -> [ExtType]
    forall dec. Typed dec => Pat dec -> [ExtType]
    expExtTypesFromPat

    instance TC.Checkable Seq where
      checkOp :: Op (Aliases Seq) -> TypeM Seq ()
    checkOp Op (Aliases Seq)
    NoOp (Aliases Seq)
    NoOp = () -> TypeM Seq ()
    forall a. a -> TypeM Seq a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure ()

    instance Buildable Seq where
      mkBody :: Stms Seq -> Result -> Body Seq
    mkBody = BodyDec Seq -> Stms Seq -> Result -> Body Seq
    forall rep. BodyDec rep -> Stms rep -> Result -> Body rep
    Body ()
      mkExpPat :: [Ident] -> Exp Seq -> Pat (LetDec Seq)
    mkExpPat [Ident]
    idents Exp Seq
    _ = [Ident] -> Pat Type
    basicPat [Ident]
    idents
      mkExpDec :: Pat (LetDec Seq) -> Exp Seq -> ExpDec Seq
    mkExpDec Pat (LetDec Seq)
    _ Exp Seq
    _ = ()
      mkLetNames :: forall (m :: * -> *).
    (MonadFreshNames m, HasScope Seq m) =>
    [VName] -> Exp Seq -> m (Stm Seq)
    mkLetNames = [VName] -> Exp Seq -> m (Stm Seq)
    forall rep (m :: * -> *).
    (ExpDec rep ~ (), LetDec rep ~ Type, MonadFreshNames m,
     TypedOp (OpC rep), HasScope rep m) =>
    [VName] -> Exp rep -> m (Stm rep)
    simpleMkLetNames

    instance BuilderOps Seq

    instance TraverseOpStms Seq where
      traverseOpStms :: forall (m :: * -> *). Monad m => OpStmsTraverser m (Op Seq) Seq
    traverseOpStms Scope Seq -> Stms Seq -> m (Stms Seq)
    _ = Op Seq -> m (Op Seq)
    NoOp Seq -> m (NoOp Seq)
    forall a. a -> m a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure

    instance PrettyRep Seq

    instance BuilderOps (Engine.Wise Seq)

    instance TraverseOpStms (Engine.Wise Seq) where
      traverseOpStms :: forall (m :: * -> *).
    Monad m =>
    OpStmsTraverser m (Op (Wise Seq)) (Wise Seq)
    traverseOpStms Scope (Wise Seq) -> Stms (Wise Seq) -> m (Stms (Wise Seq))
    _ = Op (Wise Seq) -> m (Op (Wise Seq))
    NoOp (Wise Seq) -> m (NoOp (Wise Seq))
    forall a. a -> m a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure

    simpleSeq :: Simplify.SimpleOps Seq
    simpleSeq :: SimpleOps Seq
    simpleSeq = SimplifyOp Seq (Op (Wise Seq)) -> SimpleOps Seq
    forall rep.
    (SimplifiableRep rep, Buildable rep) =>
    SimplifyOp rep (Op (Wise rep)) -> SimpleOps rep
    Simplify.bindableSimpleOps (SimpleM Seq (Op (Wise Seq), Stms (Wise Seq))
    -> SimplifyOp Seq (Op (Wise Seq))
    forall a b. a -> b -> a
    const (SimpleM Seq (Op (Wise Seq), Stms (Wise Seq))
     -> SimplifyOp Seq (Op (Wise Seq)))
    -> SimpleM Seq (Op (Wise Seq), Stms (Wise Seq))
    -> SimplifyOp Seq (Op (Wise Seq))
    forall a b. (a -> b) -> a -> b
    $ (NoOp (Wise Seq), Stms (Wise Seq))
    -> SimpleM Seq (NoOp (Wise Seq), Stms (Wise Seq))
    forall a. a -> SimpleM Seq a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (NoOp (Wise Seq)
    forall {k} (rep :: k). NoOp rep
    NoOp, Stms (Wise Seq)
    forall a. Monoid a => a
    mempty))

    -- | Simplify a sequential program.
    simplifyProg :: Prog Seq -> PassM (Prog Seq)
    simplifyProg :: Prog Seq -> PassM (Prog Seq)
    simplifyProg = SimpleOps Seq
    -> RuleBook (Wise Seq)
    -> HoistBlockers Seq
    -> Prog Seq
    -> PassM (Prog Seq)
    forall rep.
    SimplifiableRep rep =>
    SimpleOps rep
    -> RuleBook (Wise rep)
    -> HoistBlockers rep
    -> Prog rep
    -> PassM (Prog rep)
    Simplify.simplifyProg SimpleOps Seq
    simpleSeq RuleBook (Wise Seq)
    forall rep. (BuilderOps rep, TraverseOpStms rep) => RuleBook rep
    standardRules HoistBlockers Seq
    forall {k} {rep :: k}. HoistBlockers rep
    blockers
      where
        blockers :: HoistBlockers rep
    blockers = HoistBlockers rep
    forall {k} {rep :: k}. HoistBlockers rep
    Engine.noExtraHoistBlockers