{-# LANGUAGE FlexibleContexts #-}

-- |
-- Module      : Jikka.Core.Convert
-- Description : is a module to combine other optimizers. / 他の最適化器を組み合わせて実行する module です。
-- Copyright   : (c) Kimiyuki Onaka, 2020
-- License     : Apache License 2.0
-- Maintainer  : kimiyuki95@gmail.com
-- Stability   : experimental
-- Portability : portable
--
-- `Jikka.Core.Convert` is a module to combine other all optimizers.
module Jikka.Core.Convert
  ( run,
  )
where

import Jikka.Common.Alpha
import Jikka.Common.Error
import qualified Jikka.Core.Convert.Alpha as Alpha
import qualified Jikka.Core.Convert.ArithmeticalExpr as ArithmeticalExpr
import qualified Jikka.Core.Convert.Beta as Beta
import qualified Jikka.Core.Convert.BubbleLet as BubbleLet
import qualified Jikka.Core.Convert.CloseAll as CloseAll
import qualified Jikka.Core.Convert.CloseMin as CloseMin
import qualified Jikka.Core.Convert.CloseSum as CloseSum
import qualified Jikka.Core.Convert.ConstantFolding as ConstantFolding
import qualified Jikka.Core.Convert.ConstantPropagation as ConstantPropagation
import qualified Jikka.Core.Convert.ConvexHullTrick as ConvexHullTrick
import qualified Jikka.Core.Convert.CumulativeSum as CumulativeSum
import qualified Jikka.Core.Convert.Eta as Eta
import qualified Jikka.Core.Convert.MakeScanl as MakeScanl
import qualified Jikka.Core.Convert.MatrixExponentiation as MatrixExponentiation
import qualified Jikka.Core.Convert.PropagateMod as PropagateMod
import qualified Jikka.Core.Convert.RemoveUnusedVars as RemoveUnusedVars
import qualified Jikka.Core.Convert.SegmentTree as SegmentTree
import qualified Jikka.Core.Convert.ShortCutFusion as ShortCutFusion
import qualified Jikka.Core.Convert.SpecializeFoldl as SpecializeFoldl
import qualified Jikka.Core.Convert.StrengthReduction as StrengthReduction
import qualified Jikka.Core.Convert.TrivialLetElimination as TrivialLetElimination
import qualified Jikka.Core.Convert.TypeInfer as TypeInfer
import qualified Jikka.Core.Convert.UnpackTuple as UnpackTuple
import Jikka.Core.Language.Expr (Program)

run'' :: (MonadAlpha m, MonadError Error m) => Program -> m Program
run'' :: Program -> m Program
run'' Program
prog = do
  Program
prog <- Program -> m Program
forall (m :: * -> *). MonadError Error m => Program -> m Program
RemoveUnusedVars.run Program
prog
  Program
prog <- Program -> m Program
forall (m :: * -> *).
(MonadAlpha m, MonadError Error m) =>
Program -> m Program
UnpackTuple.run Program
prog
  Program
prog <- Program -> m Program
forall (m :: * -> *).
(MonadAlpha m, MonadError Error m) =>
Program -> m Program
MatrixExponentiation.run Program
prog
  Program
prog <- Program -> m Program
forall (m :: * -> *).
(MonadAlpha m, MonadError Error m) =>
Program -> m Program
SpecializeFoldl.run Program
prog
  Program
prog <- Program -> m Program
forall (m :: * -> *).
(MonadAlpha m, MonadError Error m) =>
Program -> m Program
MakeScanl.run Program
prog
  Program
prog <- Program -> m Program
forall (m :: * -> *).
(MonadAlpha m, MonadError Error m) =>
Program -> m Program
PropagateMod.run Program
prog
  Program
prog <- Program -> m Program
forall (m :: * -> *). MonadError Error m => Program -> m Program
ConstantPropagation.run Program
prog
  Program
prog <- Program -> m Program
forall (m :: * -> *). MonadError Error m => Program -> m Program
ConstantFolding.run Program
prog
  Program
prog <- Program -> m Program
forall (m :: * -> *).
(MonadAlpha m, MonadError Error m) =>
Program -> m Program
ShortCutFusion.run Program
prog
  Program
prog <- Program -> m Program
forall (m :: * -> *).
(MonadAlpha m, MonadError Error m) =>
Program -> m Program
CloseSum.run Program
prog
  Program
prog <- Program -> m Program
forall (m :: * -> *).
(MonadAlpha m, MonadError Error m) =>
Program -> m Program
CloseAll.run Program
prog
  Program
prog <- Program -> m Program
forall (m :: * -> *).
(MonadAlpha m, MonadError Error m) =>
Program -> m Program
CloseMin.run Program
prog
  Program
prog <- Program -> m Program
forall (m :: * -> *).
(MonadAlpha m, MonadError Error m) =>
Program -> m Program
CumulativeSum.run Program
prog
  Program
prog <- Program -> m Program
forall (m :: * -> *).
(MonadAlpha m, MonadError Error m) =>
Program -> m Program
SegmentTree.run Program
prog
  Program
prog <- Program -> m Program
forall (m :: * -> *).
(MonadAlpha m, MonadError Error m) =>
Program -> m Program
BubbleLet.run Program
prog
  Program
prog <- Program -> m Program
forall (m :: * -> *). MonadError Error m => Program -> m Program
ArithmeticalExpr.run Program
prog
  Program
prog <- Program -> m Program
forall (m :: * -> *).
(MonadAlpha m, MonadError Error m) =>
Program -> m Program
ConvexHullTrick.run Program
prog
  Program
prog <- Program -> m Program
forall (m :: * -> *).
(MonadAlpha m, MonadError Error m) =>
Program -> m Program
StrengthReduction.run Program
prog
  Program -> m Program
forall (m :: * -> *).
(MonadAlpha m, MonadError Error m) =>
Program -> m Program
Eta.run Program
prog

run' :: (MonadAlpha m, MonadError Error m) => Program -> m Program
run' :: Program -> m Program
run' Program
prog = do
  Program
prog <- Program -> m Program
forall (m :: * -> *).
(MonadAlpha m, MonadError Error m) =>
Program -> m Program
Beta.run Program
prog
  Program
prog <- Program -> m Program
forall (m :: * -> *). MonadError Error m => Program -> m Program
TrivialLetElimination.run Program
prog
  Program
prog <- Program -> m Program
forall (m :: * -> *).
(MonadAlpha m, MonadError Error m) =>
Program -> m Program
run'' Program
prog
  Program
prog <- Program -> m Program
forall (m :: * -> *).
(MonadAlpha m, MonadError Error m) =>
Program -> m Program
run'' Program
prog
  Program
prog <- Program -> m Program
forall (m :: * -> *).
(MonadAlpha m, MonadError Error m) =>
Program -> m Program
run'' Program
prog
  Program
prog <- Program -> m Program
forall (m :: * -> *).
(MonadAlpha m, MonadError Error m) =>
Program -> m Program
run'' Program
prog
  Program -> m Program
forall (m :: * -> *).
(MonadAlpha m, MonadError Error m) =>
Program -> m Program
run'' Program
prog

run :: (MonadAlpha m, MonadError Error m) => Program -> m Program
run :: Program -> m Program
run Program
prog = do
  Program
prog <- Program -> m Program
forall (m :: * -> *).
(MonadAlpha m, MonadError Error m) =>
Program -> m Program
Alpha.run Program
prog
  Program
prog <- Program -> m Program
forall (m :: * -> *).
(MonadAlpha m, MonadError Error m) =>
Program -> m Program
TypeInfer.run Program
prog
  Program
prog <- Program -> m Program
forall (m :: * -> *).
(MonadAlpha m, MonadError Error m) =>
Program -> m Program
run' Program
prog
  Program
prog <- Program -> m Program
forall (m :: * -> *).
(MonadAlpha m, MonadError Error m) =>
Program -> m Program
run' Program
prog
  Program
prog <- Program -> m Program
forall (m :: * -> *).
(MonadAlpha m, MonadError Error m) =>
Program -> m Program
run' Program
prog
  Program
prog <- Program -> m Program
forall (m :: * -> *).
(MonadAlpha m, MonadError Error m) =>
Program -> m Program
run' Program
prog
  Program -> m Program
forall (m :: * -> *).
(MonadAlpha m, MonadError Error m) =>
Program -> m Program
run' Program
prog