{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}

module Transform.Simplify.Lib where

import Control.Lens ((&), (.~))
import Data.ByteString.Lazy qualified as BSL
import Data.Text (Text)
import Data.Text qualified as T
import Data.Text.Encoding (encodeUtf8)
import Data.Tuple.Extra ((&&&))
import PlutusCore qualified as PLC
import PlutusCore.Builtin (BuiltinSemanticsVariant)
import PlutusCore.Pretty (PrettyPlc, Render (render), prettyPlcReadableSimple)
import PlutusPrelude (Default (def))
import Test.Tasty (TestTree, testGroup)
import Test.Tasty.Golden (goldenVsString)
import UntypedPlutusCore
  ( CseWhichSubterms
  , Name
  , SimplifierTrace
  , Term
  , defaultSimplifyOpts
  , runSimplifierT
  , soCseWhichSubterms
  , soInlineCallsiteGrowth
  , soMaxCseIterations
  , soMaxSimplifierIterations
  , soPreserveLogging
  , termSimplifier
  )
import UntypedPlutusCore.Transform.Certify.Hints qualified as Hints
import UntypedPlutusCore.Transform.Certify.Trace qualified as Trace

-- TODO Fix duplication with other golden tests, quite annoying
goldenVsPretty :: PrettyPlc a => String -> String -> a -> TestTree
goldenVsPretty :: forall a. PrettyPlc a => [Char] -> [Char] -> a -> TestTree
goldenVsPretty [Char]
extn [Char]
name a
value =
  [Char] -> [Char] -> IO ByteString -> TestTree
goldenVsString [Char]
name ([Char]
"untyped-plutus-core/test/Transform/" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
name [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
extn) (IO ByteString -> TestTree) -> IO ByteString -> TestTree
forall a b. (a -> b) -> a -> b
$
    ByteString -> IO ByteString
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ByteString -> IO ByteString)
-> (Doc Any -> ByteString) -> Doc Any -> IO ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ByteString
BSL.fromStrict (ByteString -> ByteString)
-> (Doc Any -> ByteString) -> Doc Any -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> ByteString
encodeUtf8 (Text -> ByteString) -> (Doc Any -> Text) -> Doc Any -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Doc Any -> Text
forall ann. Doc ann -> Text
forall str ann. Render str => Doc ann -> str
render (Doc Any -> IO ByteString) -> Doc Any -> IO ByteString
forall a b. (a -> b) -> a -> b
$
      a -> Doc Any
forall a ann. PrettyPlc a => a -> Doc ann
prettyPlcReadableSimple a
value

goldenVsSimplified :: String -> Term Name PLC.DefaultUni PLC.DefaultFun () -> TestTree
goldenVsSimplified :: [Char] -> Term Name DefaultUni DefaultFun () -> TestTree
goldenVsSimplified [Char]
name Term Name DefaultUni DefaultFun ()
t =
  [Char] -> [TestTree] -> TestTree
testGroup
    [Char]
name
    [ [Char] -> [Char] -> Term Name DefaultUni DefaultFun () -> TestTree
forall a. PrettyPlc a => [Char] -> [Char] -> a -> TestTree
goldenVsPretty [Char]
".golden.uplc" [Char]
name Term Name DefaultUni DefaultFun ()
t'
    , [Char] -> [Char] -> IO ByteString -> TestTree
goldenVsString ([Char]
name [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
".certifier-hints") [Char]
hintsPath
        (IO ByteString -> TestTree)
-> (Text -> IO ByteString) -> Text -> TestTree
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> IO ByteString
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
        (ByteString -> IO ByteString)
-> (Text -> ByteString) -> Text -> IO ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ByteString
BSL.fromStrict
        (ByteString -> ByteString)
-> (Text -> ByteString) -> Text -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> ByteString
encodeUtf8
        (Text -> TestTree) -> Text -> TestTree
forall a b. (a -> b) -> a -> b
$ SimplifierTrace Name DefaultUni DefaultFun () -> Text
renderCertifierHints SimplifierTrace Name DefaultUni DefaultFun ()
trace
    ]
  where
    (Term Name DefaultUni DefaultFun ()
t', SimplifierTrace Name DefaultUni DefaultFun ()
trace) = Quote
  (Term Name DefaultUni DefaultFun (),
   SimplifierTrace Name DefaultUni DefaultFun ())
-> (Term Name DefaultUni DefaultFun (),
    SimplifierTrace Name DefaultUni DefaultFun ())
forall a. Quote a -> a
PLC.runQuote (Term Name DefaultUni DefaultFun ()
-> Quote
     (Term Name DefaultUni DefaultFun (),
      SimplifierTrace Name DefaultUni DefaultFun ())
testSimplify Term Name DefaultUni DefaultFun ()
t)
    hintsPath :: [Char]
hintsPath = [Char]
"untyped-plutus-core/test/Transform/" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
name [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
".golden.certifier-hints"

renderCertifierHints :: Trace.SimplifierTrace Name PLC.DefaultUni PLC.DefaultFun () -> Text
renderCertifierHints :: SimplifierTrace Name DefaultUni DefaultFun () -> Text
renderCertifierHints (Trace.SimplifierTrace [Simplification Name DefaultUni DefaultFun ()]
ss)
  | [Simplification Name DefaultUni DefaultFun ()] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Simplification Name DefaultUni DefaultFun ()]
ss = Text
"<no certifier hints in trace>"
  | Bool
otherwise =
      [Text] -> Text
T.unlines ([Text] -> Text) -> [Text] -> Text
forall a b. (a -> b) -> a -> b
$
        (Int -> (SimplifierStage, Hints) -> Text)
-> [Int] -> [(SimplifierStage, Hints)] -> [Text]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith
          Int -> (SimplifierStage, Hints) -> Text
forall {a} {a}. (Show a, Show a) => a -> (a, Hints) -> Text
renderHintsWithIdx
          [(Int
1 :: Int) ..]
          ((Simplification Name DefaultUni DefaultFun () -> SimplifierStage
forall name (uni :: * -> *) fun a.
Simplification name uni fun a -> SimplifierStage
Trace.stage (Simplification Name DefaultUni DefaultFun () -> SimplifierStage)
-> (Simplification Name DefaultUni DefaultFun () -> Hints)
-> Simplification Name DefaultUni DefaultFun ()
-> (SimplifierStage, Hints)
forall a b c. (a -> b) -> (a -> c) -> a -> (b, c)
&&& Simplification Name DefaultUni DefaultFun () -> Hints
forall name (uni :: * -> *) fun a.
Simplification name uni fun a -> Hints
Trace.hints) (Simplification Name DefaultUni DefaultFun ()
 -> (SimplifierStage, Hints))
-> [Simplification Name DefaultUni DefaultFun ()]
-> [(SimplifierStage, Hints)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Simplification Name DefaultUni DefaultFun ()]
-> [Simplification Name DefaultUni DefaultFun ()]
forall a. [a] -> [a]
reverse [Simplification Name DefaultUni DefaultFun ()]
ss)
  where
    renderHintsWithIdx :: a -> (a, Hints) -> Text
renderHintsWithIdx a
i (a
st, Hints
h) =
      (Text
"-- Certifier hints #" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> [Char] -> Text
T.pack (a -> [Char]
forall a. Show a => a -> [Char]
show a
i) Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" (" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> [Char] -> Text
T.pack (a -> [Char]
forall a. Show a => a -> [Char]
show a
st) Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
") --\n")
        Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Hints -> Text
renderHints Hints
h
        Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"\n"

    renderHints :: Hints -> Text
renderHints = \case
      Hints
Hints.NoHints -> Text
"NoHints"
      Hints.Inline Inline
h -> Int -> Inline -> Text
renderInlineHints Int
0 Inline
h

    renderInlineHints :: Int -> Inline -> Text
renderInlineHints Int
i = \case
      Inline
Hints.InlVar -> Int -> Text -> Text
line Int
i Text
"InlVar"
      Hints.InlLam Inline
body -> Int -> Text -> Text
line Int
i Text
"InlLam" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Int -> Inline -> Text
renderInlineHints (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
2) Inline
body
      Hints.InlApply Inline
fun Inline
arg ->
        Int -> Text -> Text
line Int
i Text
"InlApply"
          Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Int -> Inline -> Text
renderInlineHints (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
2) Inline
fun
          Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Int -> Inline -> Text
renderInlineHints (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
2) Inline
arg
      Hints.InlDelay Inline
body -> Int -> Text -> Text
line Int
i Text
"InlDelay" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Int -> Inline -> Text
renderInlineHints (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
2) Inline
body
      Hints.InlForce Inline
body -> Int -> Text -> Text
line Int
i Text
"InlForce" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Int -> Inline -> Text
renderInlineHints (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
2) Inline
body
      Inline
Hints.InlCon -> Int -> Text -> Text
line Int
i Text
"InlCon"
      Inline
Hints.InlBuiltin -> Int -> Text -> Text
line Int
i Text
"InlBuiltin"
      Inline
Hints.InlError -> Int -> Text -> Text
line Int
i Text
"InlError"
      Hints.InlConstr [Inline]
args ->
        Int -> Text -> Text
line Int
i Text
"InlConstr" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> (Inline -> Text) -> [Inline] -> Text
forall m a. Monoid m => (a -> m) -> [a] -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (Int -> Inline -> Text
renderInlineHints (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
2)) [Inline]
args
      Hints.InlCase Inline
scrut [Inline]
alts ->
        Int -> Text -> Text
line Int
i Text
"InlCase"
          Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Int -> Inline -> Text
renderInlineHints (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
2) Inline
scrut
          Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> (Inline -> Text) -> [Inline] -> Text
forall m a. Monoid m => (a -> m) -> [a] -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (Int -> Inline -> Text
renderInlineHints (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
2)) [Inline]
alts
      Hints.InlExpand Inline
x -> Int -> Text -> Text
line Int
i Text
"InlExpand" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Int -> Inline -> Text
renderInlineHints (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
2) Inline
x
      Hints.InlDrop Inline
x -> Int -> Text -> Text
line Int
i Text
"InlDrop" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Int -> Inline -> Text
renderInlineHints (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
2) Inline
x

    line :: Int -> Text -> Text
line Int
i Text
payload = Int -> Text -> Text
T.replicate Int
i Text
" " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
payload Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"\n"

testSimplify
  :: Term Name PLC.DefaultUni PLC.DefaultFun ()
  -> PLC.Quote
       ( Term Name PLC.DefaultUni PLC.DefaultFun ()
       , SimplifierTrace Name PLC.DefaultUni PLC.DefaultFun ()
       )
testSimplify :: Term Name DefaultUni DefaultFun ()
-> Quote
     (Term Name DefaultUni DefaultFun (),
      SimplifierTrace Name DefaultUni DefaultFun ())
testSimplify =
  SimplifierT
  Name
  DefaultUni
  DefaultFun
  ()
  (QuoteT Identity)
  (Term Name DefaultUni DefaultFun ())
-> Quote
     (Term Name DefaultUni DefaultFun (),
      SimplifierTrace Name DefaultUni DefaultFun ())
forall name (uni :: * -> *) fun ann (m :: * -> *) a.
SimplifierT name uni fun ann m a
-> m (a, SimplifierTrace name uni fun ann)
runSimplifierT
    (SimplifierT
   Name
   DefaultUni
   DefaultFun
   ()
   (QuoteT Identity)
   (Term Name DefaultUni DefaultFun ())
 -> Quote
      (Term Name DefaultUni DefaultFun (),
       SimplifierTrace Name DefaultUni DefaultFun ()))
-> (Term Name DefaultUni DefaultFun ()
    -> SimplifierT
         Name
         DefaultUni
         DefaultFun
         ()
         (QuoteT Identity)
         (Term Name DefaultUni DefaultFun ()))
-> Term Name DefaultUni DefaultFun ()
-> Quote
     (Term Name DefaultUni DefaultFun (),
      SimplifierTrace Name DefaultUni DefaultFun ())
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SimplifyOpts Name ()
-> BuiltinSemanticsVariant DefaultFun
-> Term Name DefaultUni DefaultFun ()
-> SimplifierT
     Name
     DefaultUni
     DefaultFun
     ()
     (QuoteT Identity)
     (Term Name DefaultUni DefaultFun ())
forall name (uni :: * -> *) fun (m :: * -> *) a.
Compiling m uni fun name a =>
SimplifyOpts name a
-> BuiltinSemanticsVariant fun
-> Term name uni fun a
-> SimplifierT name uni fun a m (Term name uni fun a)
termSimplifier
      ( SimplifyOpts Name ()
forall name a. SimplifyOpts name a
defaultSimplifyOpts
          -- Just run one iteration, to see what that does
          SimplifyOpts Name ()
-> (SimplifyOpts Name () -> SimplifyOpts Name ())
-> SimplifyOpts Name ()
forall a b. a -> (a -> b) -> b
& (Int -> Identity Int)
-> SimplifyOpts Name () -> Identity (SimplifyOpts Name ())
forall name a (f :: * -> *).
Functor f =>
(Int -> f Int) -> SimplifyOpts name a -> f (SimplifyOpts name a)
soMaxSimplifierIterations ((Int -> Identity Int)
 -> SimplifyOpts Name () -> Identity (SimplifyOpts Name ()))
-> Int -> SimplifyOpts Name () -> SimplifyOpts Name ()
forall s t a b. ASetter s t a b -> b -> s -> t
.~ Int
1
          SimplifyOpts Name ()
-> (SimplifyOpts Name () -> SimplifyOpts Name ())
-> SimplifyOpts Name ()
forall a b. a -> (a -> b) -> b
& (Int -> Identity Int)
-> SimplifyOpts Name () -> Identity (SimplifyOpts Name ())
forall name a (f :: * -> *).
Functor f =>
(Int -> f Int) -> SimplifyOpts name a -> f (SimplifyOpts name a)
soMaxCseIterations ((Int -> Identity Int)
 -> SimplifyOpts Name () -> Identity (SimplifyOpts Name ()))
-> Int -> SimplifyOpts Name () -> SimplifyOpts Name ()
forall s t a b. ASetter s t a b -> b -> s -> t
.~ Int
0
          SimplifyOpts Name ()
-> (SimplifyOpts Name () -> SimplifyOpts Name ())
-> SimplifyOpts Name ()
forall a b. a -> (a -> b) -> b
& (AstSize -> Identity AstSize)
-> SimplifyOpts Name () -> Identity (SimplifyOpts Name ())
forall name a (f :: * -> *).
Functor f =>
(AstSize -> f AstSize)
-> SimplifyOpts name a -> f (SimplifyOpts name a)
soInlineCallsiteGrowth ((AstSize -> Identity AstSize)
 -> SimplifyOpts Name () -> Identity (SimplifyOpts Name ()))
-> AstSize -> SimplifyOpts Name () -> SimplifyOpts Name ()
forall s t a b. ASetter s t a b -> b -> s -> t
.~ AstSize
0
          SimplifyOpts Name ()
-> (SimplifyOpts Name () -> SimplifyOpts Name ())
-> SimplifyOpts Name ()
forall a b. a -> (a -> b) -> b
& (Bool -> Identity Bool)
-> SimplifyOpts Name () -> Identity (SimplifyOpts Name ())
forall name a (f :: * -> *).
Functor f =>
(Bool -> f Bool) -> SimplifyOpts name a -> f (SimplifyOpts name a)
soPreserveLogging ((Bool -> Identity Bool)
 -> SimplifyOpts Name () -> Identity (SimplifyOpts Name ()))
-> Bool -> SimplifyOpts Name () -> SimplifyOpts Name ()
forall s t a b. ASetter s t a b -> b -> s -> t
.~ Bool
False
      )
      (BuiltinSemanticsVariant DefaultFun
forall a. Default a => a
def :: BuiltinSemanticsVariant PLC.DefaultFun)

goldenVsCse
  :: CseWhichSubterms
  -> String
  -> Term Name PLC.DefaultUni PLC.DefaultFun ()
  -> TestTree
goldenVsCse :: CseWhichSubterms
-> [Char] -> Term Name DefaultUni DefaultFun () -> TestTree
goldenVsCse CseWhichSubterms
whichSubterms [Char]
name =
  [Char] -> [Char] -> Term Name DefaultUni DefaultFun () -> TestTree
forall a. PrettyPlc a => [Char] -> [Char] -> a -> TestTree
goldenVsPretty [Char]
".golden.uplc" [Char]
name
    (Term Name DefaultUni DefaultFun () -> TestTree)
-> (Term Name DefaultUni DefaultFun ()
    -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> TestTree
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Quote (Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
forall a. Quote a -> a
PLC.runQuote
    (Quote (Term Name DefaultUni DefaultFun ())
 -> Term Name DefaultUni DefaultFun ())
-> (Term Name DefaultUni DefaultFun ()
    -> Quote (Term Name DefaultUni DefaultFun ()))
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Term Name DefaultUni DefaultFun (),
  SimplifierTrace Name DefaultUni DefaultFun ())
 -> Term Name DefaultUni DefaultFun ())
-> Quote
     (Term Name DefaultUni DefaultFun (),
      SimplifierTrace Name DefaultUni DefaultFun ())
-> Quote (Term Name DefaultUni DefaultFun ())
forall a b. (a -> b) -> QuoteT Identity a -> QuoteT Identity b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Term Name DefaultUni DefaultFun (),
 SimplifierTrace Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
forall a b. (a, b) -> a
fst
    (Quote
   (Term Name DefaultUni DefaultFun (),
    SimplifierTrace Name DefaultUni DefaultFun ())
 -> Quote (Term Name DefaultUni DefaultFun ()))
-> (Term Name DefaultUni DefaultFun ()
    -> Quote
         (Term Name DefaultUni DefaultFun (),
          SimplifierTrace Name DefaultUni DefaultFun ()))
-> Term Name DefaultUni DefaultFun ()
-> Quote (Term Name DefaultUni DefaultFun ())
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CseWhichSubterms
-> Term Name DefaultUni DefaultFun ()
-> Quote
     (Term Name DefaultUni DefaultFun (),
      SimplifierTrace Name DefaultUni DefaultFun ())
testCse CseWhichSubterms
whichSubterms

testCse
  :: CseWhichSubterms
  -> Term Name PLC.DefaultUni PLC.DefaultFun ()
  -> PLC.Quote
       ( Term Name PLC.DefaultUni PLC.DefaultFun ()
       , SimplifierTrace Name PLC.DefaultUni PLC.DefaultFun ()
       )
testCse :: CseWhichSubterms
-> Term Name DefaultUni DefaultFun ()
-> Quote
     (Term Name DefaultUni DefaultFun (),
      SimplifierTrace Name DefaultUni DefaultFun ())
testCse CseWhichSubterms
whichSubterms =
  SimplifierT
  Name
  DefaultUni
  DefaultFun
  ()
  (QuoteT Identity)
  (Term Name DefaultUni DefaultFun ())
-> Quote
     (Term Name DefaultUni DefaultFun (),
      SimplifierTrace Name DefaultUni DefaultFun ())
forall name (uni :: * -> *) fun ann (m :: * -> *) a.
SimplifierT name uni fun ann m a
-> m (a, SimplifierTrace name uni fun ann)
runSimplifierT
    (SimplifierT
   Name
   DefaultUni
   DefaultFun
   ()
   (QuoteT Identity)
   (Term Name DefaultUni DefaultFun ())
 -> Quote
      (Term Name DefaultUni DefaultFun (),
       SimplifierTrace Name DefaultUni DefaultFun ()))
-> (Term Name DefaultUni DefaultFun ()
    -> SimplifierT
         Name
         DefaultUni
         DefaultFun
         ()
         (QuoteT Identity)
         (Term Name DefaultUni DefaultFun ()))
-> Term Name DefaultUni DefaultFun ()
-> Quote
     (Term Name DefaultUni DefaultFun (),
      SimplifierTrace Name DefaultUni DefaultFun ())
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SimplifyOpts Name ()
-> BuiltinSemanticsVariant DefaultFun
-> Term Name DefaultUni DefaultFun ()
-> SimplifierT
     Name
     DefaultUni
     DefaultFun
     ()
     (QuoteT Identity)
     (Term Name DefaultUni DefaultFun ())
forall name (uni :: * -> *) fun (m :: * -> *) a.
Compiling m uni fun name a =>
SimplifyOpts name a
-> BuiltinSemanticsVariant fun
-> Term name uni fun a
-> SimplifierT name uni fun a m (Term name uni fun a)
termSimplifier
      ( SimplifyOpts Name ()
forall name a. SimplifyOpts name a
defaultSimplifyOpts
          -- Just run one iteration, to see what that does
          SimplifyOpts Name ()
-> (SimplifyOpts Name () -> SimplifyOpts Name ())
-> SimplifyOpts Name ()
forall a b. a -> (a -> b) -> b
& (Int -> Identity Int)
-> SimplifyOpts Name () -> Identity (SimplifyOpts Name ())
forall name a (f :: * -> *).
Functor f =>
(Int -> f Int) -> SimplifyOpts name a -> f (SimplifyOpts name a)
soMaxSimplifierIterations ((Int -> Identity Int)
 -> SimplifyOpts Name () -> Identity (SimplifyOpts Name ()))
-> Int -> SimplifyOpts Name () -> SimplifyOpts Name ()
forall s t a b. ASetter s t a b -> b -> s -> t
.~ Int
0
          SimplifyOpts Name ()
-> (SimplifyOpts Name () -> SimplifyOpts Name ())
-> SimplifyOpts Name ()
forall a b. a -> (a -> b) -> b
& (Int -> Identity Int)
-> SimplifyOpts Name () -> Identity (SimplifyOpts Name ())
forall name a (f :: * -> *).
Functor f =>
(Int -> f Int) -> SimplifyOpts name a -> f (SimplifyOpts name a)
soMaxCseIterations ((Int -> Identity Int)
 -> SimplifyOpts Name () -> Identity (SimplifyOpts Name ()))
-> Int -> SimplifyOpts Name () -> SimplifyOpts Name ()
forall s t a b. ASetter s t a b -> b -> s -> t
.~ Int
1
          SimplifyOpts Name ()
-> (SimplifyOpts Name () -> SimplifyOpts Name ())
-> SimplifyOpts Name ()
forall a b. a -> (a -> b) -> b
& (CseWhichSubterms -> Identity CseWhichSubterms)
-> SimplifyOpts Name () -> Identity (SimplifyOpts Name ())
forall name a (f :: * -> *).
Functor f =>
(CseWhichSubterms -> f CseWhichSubterms)
-> SimplifyOpts name a -> f (SimplifyOpts name a)
soCseWhichSubterms ((CseWhichSubterms -> Identity CseWhichSubterms)
 -> SimplifyOpts Name () -> Identity (SimplifyOpts Name ()))
-> CseWhichSubterms -> SimplifyOpts Name () -> SimplifyOpts Name ()
forall s t a b. ASetter s t a b -> b -> s -> t
.~ CseWhichSubterms
whichSubterms
          SimplifyOpts Name ()
-> (SimplifyOpts Name () -> SimplifyOpts Name ())
-> SimplifyOpts Name ()
forall a b. a -> (a -> b) -> b
& (AstSize -> Identity AstSize)
-> SimplifyOpts Name () -> Identity (SimplifyOpts Name ())
forall name a (f :: * -> *).
Functor f =>
(AstSize -> f AstSize)
-> SimplifyOpts name a -> f (SimplifyOpts name a)
soInlineCallsiteGrowth ((AstSize -> Identity AstSize)
 -> SimplifyOpts Name () -> Identity (SimplifyOpts Name ()))
-> AstSize -> SimplifyOpts Name () -> SimplifyOpts Name ()
forall s t a b. ASetter s t a b -> b -> s -> t
.~ AstSize
0
          SimplifyOpts Name ()
-> (SimplifyOpts Name () -> SimplifyOpts Name ())
-> SimplifyOpts Name ()
forall a b. a -> (a -> b) -> b
& (Bool -> Identity Bool)
-> SimplifyOpts Name () -> Identity (SimplifyOpts Name ())
forall name a (f :: * -> *).
Functor f =>
(Bool -> f Bool) -> SimplifyOpts name a -> f (SimplifyOpts name a)
soPreserveLogging ((Bool -> Identity Bool)
 -> SimplifyOpts Name () -> Identity (SimplifyOpts Name ()))
-> Bool -> SimplifyOpts Name () -> SimplifyOpts Name ()
forall s t a b. ASetter s t a b -> b -> s -> t
.~ Bool
False
      )
      (BuiltinSemanticsVariant DefaultFun
forall a. Default a => a
def :: BuiltinSemanticsVariant PLC.DefaultFun)