module Transform.Simplify.Spec where

import PlutusCore qualified as PLC
import PlutusCore.MkPlc (mkIterApp, mkIterAppNoAnn)
import Test.Tasty (TestTree, testGroup)
import Transform.Lib
  ( T
  , app
  , builtin
  , case_
  , con
  , constr
  , delay
  , err
  , force
  , ite
  , lam
  , name
  , sopFalse
  , sopTrue
  , text
  , var
  )
import Transform.Simplify.Lib (goldenVsCse, goldenVsOptimized)
import UntypedPlutusCore
  ( CseWhichSubterms (..)
  , DefaultFun
  , DefaultUni
  , Name
  , Term (..)
  , UVarDecl (..)
  )
import UntypedPlutusCore.MkUPlc (mkIterLamAbs)

basic :: Term Name PLC.DefaultUni PLC.DefaultFun ()
basic :: Term Name DefaultUni DefaultFun ()
basic = Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
force (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$ Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
delay (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$ Integer -> Term Name DefaultUni DefaultFun ()
con Integer
1

nested :: Term Name PLC.DefaultUni PLC.DefaultFun ()
nested :: Term Name DefaultUni DefaultFun ()
nested = Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
force (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$ Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
force (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$ Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
delay (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$ Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
delay (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$ Integer -> Term Name DefaultUni DefaultFun ()
con Integer
1

extraDelays :: Term Name PLC.DefaultUni PLC.DefaultFun ()
extraDelays :: Term Name DefaultUni DefaultFun ()
extraDelays = Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
force (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$ Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
delay (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$ Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
delay (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$ Integer -> Term Name DefaultUni DefaultFun ()
con Integer
1

interveningLambda :: Term Name PLC.DefaultUni PLC.DefaultFun ()
interveningLambda :: Term Name DefaultUni DefaultFun ()
interveningLambda = Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
force (String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"a" (Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
delay (String -> Term Name DefaultUni DefaultFun ()
var String
"a" Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
`app` String -> Term Name DefaultUni DefaultFun ()
var String
"a")) Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
`app` Integer -> Term Name DefaultUni DefaultFun ()
con Integer
1)

caseOfCase1 :: Term Name PLC.DefaultUni PLC.DefaultFun ()
caseOfCase1 :: Term Name DefaultUni DefaultFun ()
caseOfCase1 = Term Name DefaultUni DefaultFun ()
-> [Term Name DefaultUni DefaultFun ()]
-> Term Name DefaultUni DefaultFun ()
case_ (Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
ite (String -> Term Name DefaultUni DefaultFun ()
var String
"b") Term Name DefaultUni DefaultFun ()
sopTrue Term Name DefaultUni DefaultFun ()
sopFalse) [Integer -> Term Name DefaultUni DefaultFun ()
con Integer
1, Integer -> Term Name DefaultUni DefaultFun ()
con Integer
2]

{-| This should not simplify, because one of the branches of `ifThenElse` is not a `Constr`.
Unless both branches are known constructors, the case-of-case transformation
may increase the program size. -}
caseOfCase2 :: Term Name PLC.DefaultUni PLC.DefaultFun ()
caseOfCase2 :: Term Name DefaultUni DefaultFun ()
caseOfCase2 = Term Name DefaultUni DefaultFun ()
-> [Term Name DefaultUni DefaultFun ()]
-> Term Name DefaultUni DefaultFun ()
case_ (Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
ite (String -> Term Name DefaultUni DefaultFun ()
var String
"b") (String -> Term Name DefaultUni DefaultFun ()
var String
"t") Term Name DefaultUni DefaultFun ()
sopFalse) [Integer -> Term Name DefaultUni DefaultFun ()
con Integer
1, Integer -> Term Name DefaultUni DefaultFun ()
con Integer
2]

{-| Similar to `caseOfCase1`, but the type of the @true@ and @false@ branches is
@[Integer]@ rather than Bool (note that @Constr 0@ has two parameters, @x@ and @xs@). -}
caseOfCase3 :: Term Name PLC.DefaultUni PLC.DefaultFun ()
caseOfCase3 :: Term Name DefaultUni DefaultFun ()
caseOfCase3 = Term Name DefaultUni DefaultFun ()
-> [Term Name DefaultUni DefaultFun ()]
-> Term Name DefaultUni DefaultFun ()
case_ (Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
ite (String -> Term Name DefaultUni DefaultFun ()
var String
"b") Term Name DefaultUni DefaultFun ()
trueBranch Term Name DefaultUni DefaultFun ()
sopFalse) [String -> Term Name DefaultUni DefaultFun ()
var String
"f", Integer -> Term Name DefaultUni DefaultFun ()
con Integer
2]
  where
    trueBranch :: Term Name DefaultUni DefaultFun ()
trueBranch = Word64
-> [Term Name DefaultUni DefaultFun ()]
-> Term Name DefaultUni DefaultFun ()
constr Word64
0 [String -> Term Name DefaultUni DefaultFun ()
var String
"x", String -> Term Name DefaultUni DefaultFun ()
var String
"xs"]

-- | The `Delay` should be floated into the lambda.
floatDelay1 :: Term Name PLC.DefaultUni PLC.DefaultFun ()
floatDelay1 :: Term Name DefaultUni DefaultFun ()
floatDelay1 = String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"a" (Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
force (String -> Term Name DefaultUni DefaultFun ()
var String
"a") Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
`plus` Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
force (String -> Term Name DefaultUni DefaultFun ()
var String
"a")) Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
`app` Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
delay (Integer -> Term Name DefaultUni DefaultFun ()
con Integer
1)

{-| The `Delay` should not be floated into the lambda, because the argument (1 + 2)
is not work-free. -}
floatDelay2 :: Term Name PLC.DefaultUni PLC.DefaultFun ()
floatDelay2 :: Term Name DefaultUni DefaultFun ()
floatDelay2 =
  String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"a" (Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
force (String -> Term Name DefaultUni DefaultFun ()
var String
"a") Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
`plus` Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
force (String -> Term Name DefaultUni DefaultFun ()
var String
"a"))
    Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
`app` Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
delay (Integer -> Term Name DefaultUni DefaultFun ()
con Integer
1 Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
`plus` Integer -> Term Name DefaultUni DefaultFun ()
con Integer
2)

{-| The `Delay` should not be floated into the lambda in the first simplifier iteration,
because one of the occurrences of `a` is not under `Force`. It should be floated into
the lambda in the second simplifier iteration, after `b` is inlined. -}
floatDelay3 :: Term Name PLC.DefaultUni PLC.DefaultFun ()
floatDelay3 :: Term Name DefaultUni DefaultFun ()
floatDelay3 =
  String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"a" (Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
force (String -> Term Name DefaultUni DefaultFun ()
var String
"a") Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
`plus` Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
force (String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"b" (String -> Term Name DefaultUni DefaultFun ()
var String
"b") Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
`app` String -> Term Name DefaultUni DefaultFun ()
var String
"a"))
    Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
`app` Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
delay (Integer -> Term Name DefaultUni DefaultFun ()
con Integer
1)

{-| The 'Delay' should not be floated into the lambda because the argument to the 'Delay' is
not pure. -}
floatDelay4 :: Term Name PLC.DefaultUni PLC.DefaultFun ()
floatDelay4 :: Term Name DefaultUni DefaultFun ()
floatDelay4 = String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"a" Term Name DefaultUni DefaultFun ()
body Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
`app` Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
delay (Word64
-> [Term Name DefaultUni DefaultFun ()]
-> Term Name DefaultUni DefaultFun ()
constr Word64
0 [Term Name DefaultUni DefaultFun ()
err])
  where
    body :: Term Name DefaultUni DefaultFun ()
body = Term Name DefaultUni DefaultFun ()
-> [Term Name DefaultUni DefaultFun ()]
-> Term Name DefaultUni DefaultFun ()
case_ (Word64
-> [Term Name DefaultUni DefaultFun ()]
-> Term Name DefaultUni DefaultFun ()
constr Word64
0 []) [Integer -> Term Name DefaultUni DefaultFun ()
con Integer
1, Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
force (String -> Term Name DefaultUni DefaultFun ()
var String
"a")]

basicInline :: Term Name PLC.DefaultUni PLC.DefaultFun ()
basicInline :: Term Name DefaultUni DefaultFun ()
basicInline = String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"a" (String -> Term Name DefaultUni DefaultFun ()
var String
"a") Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
`app` Integer -> Term Name DefaultUni DefaultFun ()
con Integer
1

{-| A helper function to create a term which tests whether the inliner
behaves as expected for a given pure or impure term. It receives a term
together with a list of its free variables. The free variables are bound
at the top level of the final term in order to ensure that the produced
final term is well-scoped. -}
mkInlinePurityTest
  :: ([Name], Term Name PLC.DefaultUni PLC.DefaultFun ())
  -> Term Name PLC.DefaultUni PLC.DefaultFun ()
mkInlinePurityTest :: ([Name], Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
mkInlinePurityTest ([Name]
freeVars, Term Name DefaultUni DefaultFun ()
term) =
  -- In `[(\a . \b . a) term]`, `term` will be inlined if and only if it is pure.
  [UVarDecl Name ()]
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall name ann (uni :: * -> *) fun.
[UVarDecl name ann]
-> Term name uni fun ann -> Term name uni fun ann
mkIterLamAbs (() -> Name -> UVarDecl Name ()
forall name ann. ann -> name -> UVarDecl name ann
UVarDecl () (Name -> UVarDecl Name ()) -> [Name] -> [UVarDecl Name ()]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Name]
freeVars) (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$
    String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"a" (String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"b" (String -> Term Name DefaultUni DefaultFun ()
var String
"a")) Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
`app` Term Name DefaultUni DefaultFun ()
term

-- | A single @Var@ is pure.
inlinePure1 :: Term Name PLC.DefaultUni PLC.DefaultFun ()
inlinePure1 :: Term Name DefaultUni DefaultFun ()
inlinePure1 = ([Name], Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
mkInlinePurityTest ([String -> Name
name String
"a"], String -> Term Name DefaultUni DefaultFun ()
var String
"a")

{-| @force (delay a)@ is pure.

Note that this relies on @forceDelayCancel@ to cancel the @force@ and the @delay@,
otherwise the inliner would treat the term as impure. -}
inlinePure2 :: Term Name PLC.DefaultUni PLC.DefaultFun ()
inlinePure2 :: Term Name DefaultUni DefaultFun ()
inlinePure2 = ([Name], Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
mkInlinePurityTest ([String -> Name
name String
"a"], Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
force (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$ Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
delay (String -> Term Name DefaultUni DefaultFun ()
var String
"a"))

{-| @[(\x -> \y -> [x x]) (con integer 1)]@ is pure.

Note that the @(con integer 1)@ won't get inlined: it isn't pre-inlined because
@x@ occurs twice, and it isn't post-inlined because @costIsAcceptable Constant{} = False@.
However, the entire term will be inlined since it is pure. -}
inlinePure3 :: Term Name PLC.DefaultUni PLC.DefaultFun ()
inlinePure3 :: Term Name DefaultUni DefaultFun ()
inlinePure3 =
  ([Name], Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
mkInlinePurityTest
    ([], Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
app (String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"x" (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$ String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"y" (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$ String -> Term Name DefaultUni DefaultFun ()
var String
"x" Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
`app` String -> Term Name DefaultUni DefaultFun ()
var String
"x") (Integer -> Term Name DefaultUni DefaultFun ()
con Integer
1))

{-| @force ([(\x -> delay (\y -> [x x])) (delay ([error (con integer 1)]))])@ is pure,
but it is very tricky to see so. It requires us to match up a force and a
delay through several steps of intervening computation. -}
inlinePure4 :: Term Name PLC.DefaultUni PLC.DefaultFun ()
inlinePure4 :: Term Name DefaultUni DefaultFun ()
inlinePure4 =
  ([Name], Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
mkInlinePurityTest
    ( []
    , Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
force (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$
        String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"x" (Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
delay (String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"y" (String -> Term Name DefaultUni DefaultFun ()
var String
"x" Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
`app` String -> Term Name DefaultUni DefaultFun ()
var String
"x")))
          Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
`app` Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
delay (Term Name DefaultUni DefaultFun ()
err Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
`app` Integer -> Term Name DefaultUni DefaultFun ()
con Integer
1)
    )

-- | @error@ is impure.
inlineImpure1 :: Term Name PLC.DefaultUni PLC.DefaultFun ()
inlineImpure1 :: Term Name DefaultUni DefaultFun ()
inlineImpure1 = ([Name], Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
mkInlinePurityTest ([], Term Name DefaultUni DefaultFun ()
err)

-- | @force (delay error)@ is impure.
inlineImpure2 :: Term Name PLC.DefaultUni PLC.DefaultFun ()
inlineImpure2 :: Term Name DefaultUni DefaultFun ()
inlineImpure2 = ([Name], Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
mkInlinePurityTest ([], Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
force (Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
delay Term Name DefaultUni DefaultFun ()
err))

{-| @force (force (force (delay (delay (delay (error))))))@ is impure, since it
is the same as @error@. -}
inlineImpure3 :: Term Name PLC.DefaultUni PLC.DefaultFun ()
inlineImpure3 :: Term Name DefaultUni DefaultFun ()
inlineImpure3 =
  ([Name], Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
mkInlinePurityTest ([], Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
force (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> (Term Name DefaultUni DefaultFun ()
    -> 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 ()
-> Term Name DefaultUni DefaultFun ()
force (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> (Term Name DefaultUni DefaultFun ()
    -> 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 ()
-> Term Name DefaultUni DefaultFun ()
force (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> (Term Name DefaultUni DefaultFun ()
    -> 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 ()
-> Term Name DefaultUni DefaultFun ()
delay (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> (Term Name DefaultUni DefaultFun ()
    -> 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 ()
-> Term Name DefaultUni DefaultFun ()
delay (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$ Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
delay Term Name DefaultUni DefaultFun ()
err)

{-| @force (force (force (delay (delay a))))@ is impure, since @a@ may expand
to an impure term such as @error@. -}
inlineImpure4 :: Term Name PLC.DefaultUni PLC.DefaultFun ()
inlineImpure4 :: Term Name DefaultUni DefaultFun ()
inlineImpure4 =
  ([Name], Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
mkInlinePurityTest
    ( [String -> Name
name String
"a"]
    , Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
force (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> (Term Name DefaultUni DefaultFun ()
    -> 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 ()
-> Term Name DefaultUni DefaultFun ()
force (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> (Term Name DefaultUni DefaultFun ()
    -> 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 ()
-> Term Name DefaultUni DefaultFun ()
force (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> (Term Name DefaultUni DefaultFun ()
    -> 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 ()
-> Term Name DefaultUni DefaultFun ()
delay (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> (Term Name DefaultUni DefaultFun ()
    -> 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 ()
-> Term Name DefaultUni DefaultFun ()
delay (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$ String -> Term Name DefaultUni DefaultFun ()
var String
"a"
    )

{-| @(\a -> f (a 0 1) (a 2)) (\x y -> g x y)@

The first occurrence of `a` should be inlined because doing so does not increase
the size or the cost.

The second occurrence of `a` should be unconditionally inlined in the second simplifier
iteration, but in this test we are only running one iteration. -}
callsiteInline :: Term Name PLC.DefaultUni PLC.DefaultFun ()
callsiteInline :: Term Name DefaultUni DefaultFun ()
callsiteInline = String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"f" (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$ String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"g" (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$ Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
app Term Name DefaultUni DefaultFun ()
fun Term Name DefaultUni DefaultFun ()
arg
  where
    fun :: Term Name DefaultUni DefaultFun ()
fun =
      String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"a" (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$
        Term Name DefaultUni DefaultFun ()
-> [Term Name DefaultUni DefaultFun ()]
-> Term Name DefaultUni DefaultFun ()
forall (term :: * -> *) tyname name (uni :: * -> *) fun.
TermLike term tyname name uni fun =>
term () -> [term ()] -> term ()
mkIterAppNoAnn
          (String -> Term Name DefaultUni DefaultFun ()
var String
"f")
          [ Term Name DefaultUni DefaultFun ()
-> [Term Name DefaultUni DefaultFun ()]
-> Term Name DefaultUni DefaultFun ()
forall (term :: * -> *) tyname name (uni :: * -> *) fun.
TermLike term tyname name uni fun =>
term () -> [term ()] -> term ()
mkIterAppNoAnn (String -> Term Name DefaultUni DefaultFun ()
var String
"a") [Integer -> Term Name DefaultUni DefaultFun ()
con Integer
0, Integer -> Term Name DefaultUni DefaultFun ()
con Integer
1]
          , Term Name DefaultUni DefaultFun ()
-> [Term Name DefaultUni DefaultFun ()]
-> Term Name DefaultUni DefaultFun ()
forall (term :: * -> *) tyname name (uni :: * -> *) fun.
TermLike term tyname name uni fun =>
term () -> [term ()] -> term ()
mkIterAppNoAnn (String -> Term Name DefaultUni DefaultFun ()
var String
"a") [Integer -> Term Name DefaultUni DefaultFun ()
con Integer
2]
          ]
    arg :: Term Name DefaultUni DefaultFun ()
arg =
      String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"x" (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> (Term Name DefaultUni DefaultFun ()
    -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"y" (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$
        Term Name DefaultUni DefaultFun ()
-> [Term Name DefaultUni DefaultFun ()]
-> Term Name DefaultUni DefaultFun ()
forall (term :: * -> *) tyname name (uni :: * -> *) fun.
TermLike term tyname name uni fun =>
term () -> [term ()] -> term ()
mkIterAppNoAnn (String -> Term Name DefaultUni DefaultFun ()
var String
"g") [String -> Term Name DefaultUni DefaultFun ()
var String
"y", String -> Term Name DefaultUni DefaultFun ()
var String
"x"]

multiApp :: Term Name PLC.DefaultUni PLC.DefaultFun ()
multiApp :: Term Name DefaultUni DefaultFun ()
multiApp = Term Name DefaultUni DefaultFun ()
-> [Term Name DefaultUni DefaultFun ()]
-> Term Name DefaultUni DefaultFun ()
forall (term :: * -> *) tyname name (uni :: * -> *) fun.
TermLike term tyname name uni fun =>
term () -> [term ()] -> term ()
mkIterAppNoAnn Term Name DefaultUni DefaultFun ()
applyLam [Integer -> Term Name DefaultUni DefaultFun ()
con Integer
1, Integer -> Term Name DefaultUni DefaultFun ()
con Integer
2, Integer -> Term Name DefaultUni DefaultFun ()
con Integer
3]
  where
    applyLam :: Term Name DefaultUni DefaultFun ()
applyLam =
      String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"a" (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$
        String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"b" (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$
          String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"c" (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$
            Term Name DefaultUni DefaultFun ()
-> [Term Name DefaultUni DefaultFun ()]
-> Term Name DefaultUni DefaultFun ()
forall (term :: * -> *) tyname name (uni :: * -> *) fun.
TermLike term tyname name uni fun =>
term () -> [term ()] -> term ()
mkIterAppNoAnn (String -> Term Name DefaultUni DefaultFun ()
var String
"c") [String -> Term Name DefaultUni DefaultFun ()
var String
"a", String -> Term Name DefaultUni DefaultFun ()
var String
"b"]

forceDelayNoApps :: Term Name PLC.DefaultUni PLC.DefaultFun ()
forceDelayNoApps :: Term Name DefaultUni DefaultFun ()
forceDelayNoApps = Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
force (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$ Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
delay (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$ Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
force (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$ Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
delay (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$ Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
force (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$ Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
delay (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$ Integer -> Term Name DefaultUni DefaultFun ()
con Integer
1

forceDelayNoAppsLayered :: Term Name PLC.DefaultUni PLC.DefaultFun ()
forceDelayNoAppsLayered :: Term Name DefaultUni DefaultFun ()
forceDelayNoAppsLayered = Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
force (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$ Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
force (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$ Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
force (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$ Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
delay (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$ Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
delay (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$ Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
delay (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$ Integer -> Term Name DefaultUni DefaultFun ()
con Integer
1

{-| The UPLC term in this test should come from the following TPLC term after erasing its types:

> (/\(p :: *) -> \(x : p) -> /\(q :: *) -> \(y : q) -> /\(r :: *) -> \(z : r) -> z)
>   Int 1 Int 2 Int 3

This case is simple in the sense that each type abstraction
is followed by a single term abstraction. -}
forceDelaySimple :: Term Name PLC.DefaultUni PLC.DefaultFun ()
forceDelaySimple :: Term Name DefaultUni DefaultFun ()
forceDelaySimple = Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
force (Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
force (Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
force Term Name DefaultUni DefaultFun ()
t Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
`app` Integer -> Term Name DefaultUni DefaultFun ()
con Integer
1) Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
`app` Integer -> Term Name DefaultUni DefaultFun ()
con Integer
2) Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
`app` Integer -> Term Name DefaultUni DefaultFun ()
con Integer
3
  where
    t :: Term Name DefaultUni DefaultFun ()
t = Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
delay (String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"x" (Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
delay (String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"y" (Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
delay (String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"z" (String -> Term Name DefaultUni DefaultFun ()
var String
"z"))))))

{-| A test for the case when there are multiple applications between the 'Force' at the top
and the 'Delay' at the top of the term inside the abstractions/applications. -}
forceDelayMultiApply :: Term Name PLC.DefaultUni PLC.DefaultFun ()
forceDelayMultiApply :: Term Name DefaultUni DefaultFun ()
forceDelayMultiApply =
  String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"funcVar" (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$
    Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
force (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$
      Term Name DefaultUni DefaultFun ()
-> [Term Name DefaultUni DefaultFun ()]
-> Term Name DefaultUni DefaultFun ()
forall (term :: * -> *) tyname name (uni :: * -> *) fun.
TermLike term tyname name uni fun =>
term () -> [term ()] -> term ()
mkIterAppNoAnn
        ( String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"x1" (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$
            String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"x2" (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$
              String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"x3" (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$
                String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"f" (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$
                  Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
delay (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$
                    Term Name DefaultUni DefaultFun ()
-> [Term Name DefaultUni DefaultFun ()]
-> Term Name DefaultUni DefaultFun ()
forall (term :: * -> *) tyname name (uni :: * -> *) fun.
TermLike term tyname name uni fun =>
term () -> [term ()] -> term ()
mkIterAppNoAnn (String -> Term Name DefaultUni DefaultFun ()
var String
"f") [String -> Term Name DefaultUni DefaultFun ()
var String
"x1", String -> Term Name DefaultUni DefaultFun ()
var String
"x2", String -> Term Name DefaultUni DefaultFun ()
var String
"x3"]
        )
        [Integer -> Term Name DefaultUni DefaultFun ()
con Integer
1, Integer -> Term Name DefaultUni DefaultFun ()
con Integer
2, Integer -> Term Name DefaultUni DefaultFun ()
con Integer
3, String -> Term Name DefaultUni DefaultFun ()
var String
"funcVar"]

{-| A test for the case when there are multiple type abstractions over a single term
abstraction/application. -}
forceDelayMultiForce :: Term Name PLC.DefaultUni PLC.DefaultFun ()
forceDelayMultiForce :: Term Name DefaultUni DefaultFun ()
forceDelayMultiForce =
  Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
force (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$ Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
force (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$ Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
force (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$ Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
app (String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"x" (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$ Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
delay (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$ Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
delay (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$ Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
delay (String -> Term Name DefaultUni DefaultFun ()
var String
"x")) (Integer -> Term Name DefaultUni DefaultFun ()
con Integer
1)

{-| The UPLC term in this test should come from the following TPLC term after erasing its types:

> (/\(p1 :: *) (p2 :: *) -> \(x : p2) ->
>   /\(q1 :: *) (q2 :: *) (q3 :: *) -> \(y1 : q1) (y2 : q2) (y3 : String) ->
>     /\(r :: *) -> \(z1 : r) -> \(z2 : r) ->
>       /\(t :: *) -> \(f : p1 -> q1 -> q2 -> String -> r -> r -> String) ->
>         f x y1 y2 y3 z1 z2
> ) Int Int 1 Int String Int 2 "foo" "bar" Int 3 3 ByteString
> (funcVar : Int -> Int -> String -> String -> Int -> String)

Note this term has multiple interleaved type and term instantiations/applications. -}
forceDelayComplex :: Term Name PLC.DefaultUni PLC.DefaultFun ()
forceDelayComplex :: Term Name DefaultUni DefaultFun ()
forceDelayComplex = Term Name DefaultUni DefaultFun ()
whole
  where
    term :: Term Name DefaultUni DefaultFun ()
term =
      Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
delay
        (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> (Term Name DefaultUni DefaultFun ()
    -> 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 ()
-> Term Name DefaultUni DefaultFun ()
delay
        (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> (Term Name DefaultUni DefaultFun ()
    -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"x"
        (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> (Term Name DefaultUni DefaultFun ()
    -> 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 ()
-> Term Name DefaultUni DefaultFun ()
delay
        (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> (Term Name DefaultUni DefaultFun ()
    -> 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 ()
-> Term Name DefaultUni DefaultFun ()
delay
        (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> (Term Name DefaultUni DefaultFun ()
    -> 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 ()
-> Term Name DefaultUni DefaultFun ()
delay
        (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> (Term Name DefaultUni DefaultFun ()
    -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"y1"
        (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> (Term Name DefaultUni DefaultFun ()
    -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"y2"
        (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> (Term Name DefaultUni DefaultFun ()
    -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"y3"
        (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> (Term Name DefaultUni DefaultFun ()
    -> 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 ()
-> Term Name DefaultUni DefaultFun ()
delay
        (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> (Term Name DefaultUni DefaultFun ()
    -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"z1"
        (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> (Term Name DefaultUni DefaultFun ()
    -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"z2"
        (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> (Term Name DefaultUni DefaultFun ()
    -> 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 ()
-> Term Name DefaultUni DefaultFun ()
delay
        (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> (Term Name DefaultUni DefaultFun ()
    -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"f"
        (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$ Term Name DefaultUni DefaultFun ()
-> [Term Name DefaultUni DefaultFun ()]
-> Term Name DefaultUni DefaultFun ()
forall (term :: * -> *) tyname name (uni :: * -> *) fun.
TermLike term tyname name uni fun =>
term () -> [term ()] -> term ()
mkIterAppNoAnn
          (String -> Term Name DefaultUni DefaultFun ()
var String
"f")
          [ String -> Term Name DefaultUni DefaultFun ()
var String
"x"
          , String -> Term Name DefaultUni DefaultFun ()
var String
"y1"
          , String -> Term Name DefaultUni DefaultFun ()
var String
"y2"
          , String -> Term Name DefaultUni DefaultFun ()
var String
"y3"
          , String -> Term Name DefaultUni DefaultFun ()
var String
"z1"
          , String -> Term Name DefaultUni DefaultFun ()
var String
"z2"
          ]
    whole :: Term Name DefaultUni DefaultFun ()
whole =
      String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"funcVar" (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$
        Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
app
          ( Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
force (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$
              Term Name DefaultUni DefaultFun ()
-> [Term Name DefaultUni DefaultFun ()]
-> Term Name DefaultUni DefaultFun ()
forall (term :: * -> *) tyname name (uni :: * -> *) fun.
TermLike term tyname name uni fun =>
term () -> [term ()] -> term ()
mkIterAppNoAnn
                ( Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
force (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$
                    Term Name DefaultUni DefaultFun ()
-> [Term Name DefaultUni DefaultFun ()]
-> Term Name DefaultUni DefaultFun ()
forall (term :: * -> *) tyname name (uni :: * -> *) fun.
TermLike term tyname name uni fun =>
term () -> [term ()] -> term ()
mkIterAppNoAnn
                      (Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
force (Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
force (Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
force (Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
force (Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
force Term Name DefaultUni DefaultFun ()
term) Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
`app` Integer -> Term Name DefaultUni DefaultFun ()
con Integer
1))))
                      [ Integer -> Term Name DefaultUni DefaultFun ()
con Integer
2
                      , String -> Term Name DefaultUni DefaultFun ()
text String
"foo"
                      , String -> Term Name DefaultUni DefaultFun ()
text String
"bar"
                      ]
                )
                [ Integer -> Term Name DefaultUni DefaultFun ()
con Integer
3
                , Integer -> Term Name DefaultUni DefaultFun ()
con Integer
3
                ]
          )
          (String -> Term Name DefaultUni DefaultFun ()
var String
"funcVar")

forceCaseDelayNoApps1 :: Term Name PLC.DefaultUni PLC.DefaultFun ()
forceCaseDelayNoApps1 :: Term Name DefaultUni DefaultFun ()
forceCaseDelayNoApps1 =
  String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"scrut" (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$ Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
force (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$ Term Name DefaultUni DefaultFun ()
-> [Term Name DefaultUni DefaultFun ()]
-> Term Name DefaultUni DefaultFun ()
case_ (String -> Term Name DefaultUni DefaultFun ()
var String
"scrut") [Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
delay (Integer -> Term Name DefaultUni DefaultFun ()
con Integer
1)]

forceCaseDelayWithApps1 :: Term Name PLC.DefaultUni PLC.DefaultFun ()
forceCaseDelayWithApps1 :: Term Name DefaultUni DefaultFun ()
forceCaseDelayWithApps1 =
  String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"scrut" (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$ Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
force (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$ Term Name DefaultUni DefaultFun ()
-> [Term Name DefaultUni DefaultFun ()]
-> Term Name DefaultUni DefaultFun ()
case_ (String -> Term Name DefaultUni DefaultFun ()
var String
"scrut") [String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"x" (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$ Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
delay (Integer -> Term Name DefaultUni DefaultFun ()
con Integer
1)]

forceCaseDelayNoApps2 :: Term Name PLC.DefaultUni PLC.DefaultFun ()
forceCaseDelayNoApps2 :: Term Name DefaultUni DefaultFun ()
forceCaseDelayNoApps2 =
  String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"scrut" (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$ Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
force (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$ Term Name DefaultUni DefaultFun ()
-> [Term Name DefaultUni DefaultFun ()]
-> Term Name DefaultUni DefaultFun ()
case_ (String -> Term Name DefaultUni DefaultFun ()
var String
"scrut") [Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
delay (Integer -> Term Name DefaultUni DefaultFun ()
con Integer
1), Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
delay (Integer -> Term Name DefaultUni DefaultFun ()
con Integer
2)]

forceCaseDelayWithApps2 :: Term Name PLC.DefaultUni PLC.DefaultFun ()
forceCaseDelayWithApps2 :: Term Name DefaultUni DefaultFun ()
forceCaseDelayWithApps2 =
  String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"scrut" (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$
    Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
force (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$
      Term Name DefaultUni DefaultFun ()
-> [Term Name DefaultUni DefaultFun ()]
-> Term Name DefaultUni DefaultFun ()
case_ (String -> Term Name DefaultUni DefaultFun ()
var String
"scrut") [String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"x" (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$ Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
delay (Integer -> Term Name DefaultUni DefaultFun ()
con Integer
1), Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
delay (Integer -> Term Name DefaultUni DefaultFun ()
con Integer
2)]

forceCaseDelayNoApps2Fail :: Term Name PLC.DefaultUni PLC.DefaultFun ()
forceCaseDelayNoApps2Fail :: Term Name DefaultUni DefaultFun ()
forceCaseDelayNoApps2Fail =
  String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"scrut" (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$ Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
force (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$ Term Name DefaultUni DefaultFun ()
-> [Term Name DefaultUni DefaultFun ()]
-> Term Name DefaultUni DefaultFun ()
case_ (String -> Term Name DefaultUni DefaultFun ()
var String
"scrut") [Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
delay (Integer -> Term Name DefaultUni DefaultFun ()
con Integer
1), Integer -> Term Name DefaultUni DefaultFun ()
con Integer
2]

forceCaseDelayWithApps2Fail :: Term Name PLC.DefaultUni PLC.DefaultFun ()
forceCaseDelayWithApps2Fail :: Term Name DefaultUni DefaultFun ()
forceCaseDelayWithApps2Fail =
  String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"scrut" (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$
    Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
force (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$
      Term Name DefaultUni DefaultFun ()
-> [Term Name DefaultUni DefaultFun ()]
-> Term Name DefaultUni DefaultFun ()
case_
        (String -> Term Name DefaultUni DefaultFun ()
var String
"scrut")
        [ String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"x" (String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"y" (Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
delay (Integer -> Term Name DefaultUni DefaultFun ()
con Integer
1)))
        , String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"x" (Integer -> Term Name DefaultUni DefaultFun ()
con Integer
2)
        ]

-- case ((\x -> constr 0 []) 1) [42]
letFloatOutCase1 :: Term Name PLC.DefaultUni PLC.DefaultFun ()
letFloatOutCase1 :: Term Name DefaultUni DefaultFun ()
letFloatOutCase1 = Term Name DefaultUni DefaultFun ()
-> [Term Name DefaultUni DefaultFun ()]
-> Term Name DefaultUni DefaultFun ()
case_ (String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"x" Term Name DefaultUni DefaultFun ()
sopTrue Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
`app` Integer -> Term Name DefaultUni DefaultFun ()
con Integer
1) [Integer -> Term Name DefaultUni DefaultFun ()
con Integer
42]

-- \a -> case ((\x -> constr 0 [x, x]) a) addInteger
letFloatOutCase2 :: Term Name PLC.DefaultUni PLC.DefaultFun ()
letFloatOutCase2 :: Term Name DefaultUni DefaultFun ()
letFloatOutCase2 = String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"a" (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$ Term Name DefaultUni DefaultFun ()
-> [Term Name DefaultUni DefaultFun ()]
-> Term Name DefaultUni DefaultFun ()
case_ Term Name DefaultUni DefaultFun ()
binding [DefaultFun -> Term Name DefaultUni DefaultFun ()
builtin DefaultFun
PLC.AddInteger]
  where
    body :: Term Name DefaultUni DefaultFun ()
body = Word64
-> [Term Name DefaultUni DefaultFun ()]
-> Term Name DefaultUni DefaultFun ()
constr Word64
0 [String -> Term Name DefaultUni DefaultFun ()
var String
"x", String -> Term Name DefaultUni DefaultFun ()
var String
"x"]
    binding :: Term Name DefaultUni DefaultFun ()
binding = String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"x" Term Name DefaultUni DefaultFun ()
body Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
`app` String -> Term Name DefaultUni DefaultFun ()
var String
"a"

-- \a -> force ((\x -> delay x) a)
letFloatOutForce :: Term Name PLC.DefaultUni PLC.DefaultFun ()
letFloatOutForce :: Term Name DefaultUni DefaultFun ()
letFloatOutForce = String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"a" (Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
force Term Name DefaultUni DefaultFun ()
binding)
  where
    delayLam :: Term Name DefaultUni DefaultFun ()
delayLam = String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"x" (Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
delay (String -> Term Name DefaultUni DefaultFun ()
var String
"x"))
    binding :: Term Name DefaultUni DefaultFun ()
binding = Term Name DefaultUni DefaultFun ()
delayLam Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
`app` String -> Term Name DefaultUni DefaultFun ()
var String
"a"

-- | This is the first example in Note [CSE].
cse1 :: Term Name PLC.DefaultUni PLC.DefaultFun ()
cse1 :: Term Name DefaultUni DefaultFun ()
cse1 = String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"x" (String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"y" (Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
plus Term Name DefaultUni DefaultFun ()
onePlusTwoPlusX Term Name DefaultUni DefaultFun ()
caseExpr))
  where
    twoPlusX :: Term Name DefaultUni DefaultFun ()
twoPlusX = Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
plus (Integer -> Term Name DefaultUni DefaultFun ()
con Integer
2) (String -> Term Name DefaultUni DefaultFun ()
var String
"x")
    onePlusTwoPlusX :: Term Name DefaultUni DefaultFun ()
onePlusTwoPlusX = Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
plus (Integer -> Term Name DefaultUni DefaultFun ()
con Integer
1) Term Name DefaultUni DefaultFun ()
twoPlusX
    threePlusX :: Term Name DefaultUni DefaultFun ()
threePlusX = Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
plus (Integer -> Term Name DefaultUni DefaultFun ()
con Integer
3) (String -> Term Name DefaultUni DefaultFun ()
var String
"x")
    fourPlusX :: Term Name DefaultUni DefaultFun ()
fourPlusX = Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
plus (Integer -> Term Name DefaultUni DefaultFun ()
con Integer
4) (String -> Term Name DefaultUni DefaultFun ()
var String
"x")
    branch1 :: Term Name DefaultUni DefaultFun ()
branch1 = Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
plus Term Name DefaultUni DefaultFun ()
onePlusTwoPlusX Term Name DefaultUni DefaultFun ()
threePlusX
    branch2 :: Term Name DefaultUni DefaultFun ()
branch2 = Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
plus Term Name DefaultUni DefaultFun ()
twoPlusX Term Name DefaultUni DefaultFun ()
threePlusX
    branch3 :: Term Name DefaultUni DefaultFun ()
branch3 = Term Name DefaultUni DefaultFun ()
fourPlusX
    caseExpr :: Term Name DefaultUni DefaultFun ()
caseExpr = Term Name DefaultUni DefaultFun ()
-> [Term Name DefaultUni DefaultFun ()]
-> Term Name DefaultUni DefaultFun ()
case_ (String -> Term Name DefaultUni DefaultFun ()
var String
"y") [Term Name DefaultUni DefaultFun ()
branch1, Term Name DefaultUni DefaultFun ()
branch2, Term Name DefaultUni DefaultFun ()
branch3]

-- | This is the second example in Note [CSE].
cse2 :: Term Name DefaultUni DefaultFun ()
cse2 :: Term Name DefaultUni DefaultFun ()
cse2 = Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
force (Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
force Term Name DefaultUni DefaultFun ()
body)
  where
    body :: Term Name DefaultUni DefaultFun ()
body = Term Name DefaultUni DefaultFun ()
-> [((), Term Name DefaultUni DefaultFun ())]
-> Term Name DefaultUni DefaultFun ()
forall (term :: * -> *) tyname name (uni :: * -> *) fun ann.
TermLike term tyname name uni fun =>
term ann -> [(ann, term ann)] -> term ann
mkIterApp (DefaultFun -> Term Name DefaultUni DefaultFun ()
builtin DefaultFun
PLC.IfThenElse) [((), Term Name DefaultUni DefaultFun ()
cond), ((), Term Name DefaultUni DefaultFun ()
trueBranch), ((), Term Name DefaultUni DefaultFun ()
falseBranch)]
    cond :: Term Name DefaultUni DefaultFun ()
cond = DefaultFun -> Term Name DefaultUni DefaultFun ()
builtin DefaultFun
PLC.LessThanInteger Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
`app` Integer -> Term Name DefaultUni DefaultFun ()
con Integer
0 Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
`app` Integer -> Term Name DefaultUni DefaultFun ()
con Integer
0
    trueBranch :: Term Name DefaultUni DefaultFun ()
trueBranch = Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
delay (Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
plus (Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
plus (Integer -> Term Name DefaultUni DefaultFun ()
con Integer
1) (Integer -> Term Name DefaultUni DefaultFun ()
con Integer
2)) (Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
plus (Integer -> Term Name DefaultUni DefaultFun ()
con Integer
1) (Integer -> Term Name DefaultUni DefaultFun ()
con Integer
2)))
    falseBranch :: Term Name DefaultUni DefaultFun ()
falseBranch = Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
delay (Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
plus (Integer -> Term Name DefaultUni DefaultFun ()
con Integer
1) (Integer -> Term Name DefaultUni DefaultFun ()
con Integer
2))

-- | This is the third example in Note [CSE].
cse3 :: Term Name PLC.DefaultUni PLC.DefaultFun ()
cse3 :: Term Name DefaultUni DefaultFun ()
cse3 = String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"f" (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$ String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"x" (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$ String -> Term Name DefaultUni DefaultFun ()
var String
"f" Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
`app` Term Name DefaultUni DefaultFun ()
arg1 Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
`app` Term Name DefaultUni DefaultFun ()
arg2
  where
    arg1 :: Term Name DefaultUni DefaultFun ()
arg1 =
      String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"y" (Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
plus (Integer -> Term Name DefaultUni DefaultFun ()
con Integer
1) (Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
plus (String -> Term Name DefaultUni DefaultFun ()
var String
"y") (String -> Term Name DefaultUni DefaultFun ()
var String
"y")))
        Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
`app` Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
plus (Integer -> Term Name DefaultUni DefaultFun ()
con Integer
0) (String -> Term Name DefaultUni DefaultFun ()
var String
"x")
    arg2 :: Term Name DefaultUni DefaultFun ()
arg2 =
      String
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
lam String
"z" (Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
plus (Integer -> Term Name DefaultUni DefaultFun ()
con Integer
2) (Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
plus (String -> Term Name DefaultUni DefaultFun ()
var String
"z") (String -> Term Name DefaultUni DefaultFun ()
var String
"z")))
        Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
`app` Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
plus (Integer -> Term Name DefaultUni DefaultFun ()
con Integer
0) (String -> Term Name DefaultUni DefaultFun ()
var String
"x")

--  ((1+2) + (3+4) + ...)
--  +
--  ((1+2) + (3+4) + ...)
cseExpensive :: Term Name DefaultUni DefaultFun ()
cseExpensive :: Term Name DefaultUni DefaultFun ()
cseExpensive = [Integer] -> Term Name DefaultUni DefaultFun ()
mkArg [Integer
0 .. Integer
200] Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
`plus` [Integer] -> Term Name DefaultUni DefaultFun ()
mkArg [Integer
0 .. Integer
200]
  where
    mkArg :: [Integer] -> Term Name DefaultUni DefaultFun ()
mkArg = (Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ()
 -> Term Name DefaultUni DefaultFun ())
-> [Term Name DefaultUni DefaultFun ()]
-> Term Name DefaultUni DefaultFun ()
forall a. (a -> a -> a) -> [a] -> a
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldl1 Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
plus ([Term Name DefaultUni DefaultFun ()]
 -> Term Name DefaultUni DefaultFun ())
-> ([Integer] -> [Term Name DefaultUni DefaultFun ()])
-> [Integer]
-> Term Name DefaultUni DefaultFun ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Integer -> Term Name DefaultUni DefaultFun ())
-> [Integer] -> [Term Name DefaultUni DefaultFun ()]
forall a b. (a -> b) -> [a] -> [b]
map (\Integer
i -> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
plus (Integer -> Term Name DefaultUni DefaultFun ()
con (Integer
2 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
i)) (Integer -> Term Name DefaultUni DefaultFun ()
con (Integer
2 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
i Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
1)))

-- tree where nodes are + and leaves are constants
csePlusTree :: Term Name DefaultUni DefaultFun ()
csePlusTree :: Term Name DefaultUni DefaultFun ()
csePlusTree = Int -> Term Name DefaultUni DefaultFun ()
go Int
5
  where
    go :: Int -> T
    go :: Int -> Term Name DefaultUni DefaultFun ()
go Int
0 = Integer -> Term Name DefaultUni DefaultFun ()
con Integer
1
    go Int
n = Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
plus (Int -> Term Name DefaultUni DefaultFun ()
go (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)) (Int -> Term Name DefaultUni DefaultFun ()
go (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1))

-- (1 + (1 + ... + 0))
-- optimised to
-- let f = (1 +) in f (f (... 0))
cseRepeatPlus :: Term Name DefaultUni DefaultFun ()
cseRepeatPlus :: Term Name DefaultUni DefaultFun ()
cseRepeatPlus = Int -> Term Name DefaultUni DefaultFun ()
go Int
5
  where
    go :: Int -> T
    go :: Int -> Term Name DefaultUni DefaultFun ()
go Int
0 = Integer -> Term Name DefaultUni DefaultFun ()
con Integer
0
    go Int
n = Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
plus (Integer -> Term Name DefaultUni DefaultFun ()
con Integer
1) (Int -> Term Name DefaultUni DefaultFun ()
go (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1))

testSimplifyInputs :: [(String, Term Name PLC.DefaultUni PLC.DefaultFun ())]
testSimplifyInputs :: [(String, Term Name DefaultUni DefaultFun ())]
testSimplifyInputs =
  [ (String
"basic", Term Name DefaultUni DefaultFun ()
basic)
  , (String
"nested", Term Name DefaultUni DefaultFun ()
nested)
  , (String
"extraDelays", Term Name DefaultUni DefaultFun ()
extraDelays)
  , (String
"floatDelay1", Term Name DefaultUni DefaultFun ()
floatDelay1)
  , (String
"floatDelay2", Term Name DefaultUni DefaultFun ()
floatDelay2)
  , (String
"floatDelay3", Term Name DefaultUni DefaultFun ()
floatDelay3)
  , (String
"floatDelay4", Term Name DefaultUni DefaultFun ()
floatDelay4)
  , (String
"interveningLambda", Term Name DefaultUni DefaultFun ()
interveningLambda)
  , (String
"basicInline", Term Name DefaultUni DefaultFun ()
basicInline)
  , (String
"callsiteInline", Term Name DefaultUni DefaultFun ()
callsiteInline)
  , (String
"inlinePure1", Term Name DefaultUni DefaultFun ()
inlinePure1)
  , (String
"inlinePure2", Term Name DefaultUni DefaultFun ()
inlinePure2)
  , (String
"inlinePure3", Term Name DefaultUni DefaultFun ()
inlinePure3)
  , (String
"inlinePure4", Term Name DefaultUni DefaultFun ()
inlinePure4)
  , (String
"inlineImpure1", Term Name DefaultUni DefaultFun ()
inlineImpure1)
  , (String
"inlineImpure2", Term Name DefaultUni DefaultFun ()
inlineImpure2)
  , (String
"inlineImpure3", Term Name DefaultUni DefaultFun ()
inlineImpure3)
  , (String
"inlineImpure4", Term Name DefaultUni DefaultFun ()
inlineImpure4)
  , (String
"multiApp", Term Name DefaultUni DefaultFun ()
multiApp)
  , (String
"forceDelayNoApps", Term Name DefaultUni DefaultFun ()
forceDelayNoApps)
  , (String
"forceDelayNoAppsLayered", Term Name DefaultUni DefaultFun ()
forceDelayNoAppsLayered)
  , (String
"forceDelaySimple", Term Name DefaultUni DefaultFun ()
forceDelaySimple)
  , (String
"forceDelayMultiApply", Term Name DefaultUni DefaultFun ()
forceDelayMultiApply)
  , (String
"forceDelayMultiForce", Term Name DefaultUni DefaultFun ()
forceDelayMultiForce)
  , (String
"forceDelayComplex", Term Name DefaultUni DefaultFun ()
forceDelayComplex)
  , (String
"forceCaseDelayNoApps1", Term Name DefaultUni DefaultFun ()
forceCaseDelayNoApps1)
  , (String
"forceCaseDelayWithApps1", Term Name DefaultUni DefaultFun ()
forceCaseDelayWithApps1)
  , (String
"forceCaseDelayNoApps2", Term Name DefaultUni DefaultFun ()
forceCaseDelayNoApps2)
  , (String
"forceCaseDelayWithApps2", Term Name DefaultUni DefaultFun ()
forceCaseDelayWithApps2)
  , (String
"forceCaseDelayNoApps2Fail", Term Name DefaultUni DefaultFun ()
forceCaseDelayNoApps2Fail)
  , (String
"forceCaseDelayWithApps2Fail", Term Name DefaultUni DefaultFun ()
forceCaseDelayWithApps2Fail)
  , (String
"letFloatOutCase1", Term Name DefaultUni DefaultFun ()
letFloatOutCase1)
  , (String
"letFloatOutCase2", Term Name DefaultUni DefaultFun ()
letFloatOutCase2)
  , (String
"letFloatOutForce", Term Name DefaultUni DefaultFun ()
letFloatOutForce)
  ]

testCseInputs :: [(String, Term Name PLC.DefaultUni PLC.DefaultFun ())]
testCseInputs :: [(String, Term Name DefaultUni DefaultFun ())]
testCseInputs =
  [ (String
"cse1", Term Name DefaultUni DefaultFun ()
cse1)
  , (String
"cse2", Term Name DefaultUni DefaultFun ()
cse2)
  , (String
"cse3", Term Name DefaultUni DefaultFun ()
cse3)
  , (String
"cseExpensive", Term Name DefaultUni DefaultFun ()
cseExpensive)
  ]

testCseInputsWorkFree :: [(String, Term Name PLC.DefaultUni PLC.DefaultFun ())]
testCseInputsWorkFree :: [(String, Term Name DefaultUni DefaultFun ())]
testCseInputsWorkFree =
  [ (String
"cse1WorkFree", Term Name DefaultUni DefaultFun ()
cse1)
  , (String
"csePlusTree", Term Name DefaultUni DefaultFun ()
csePlusTree)
  , (String
"cseRepeatPlus", Term Name DefaultUni DefaultFun ()
cseRepeatPlus)
  ]

test_simplify :: TestTree
test_simplify :: TestTree
test_simplify =
  String -> [TestTree] -> TestTree
testGroup
    String
"simplify"
    ([TestTree] -> TestTree) -> [TestTree] -> TestTree
forall a b. (a -> b) -> a -> b
$ ((String, Term Name DefaultUni DefaultFun ()) -> TestTree)
-> [(String, Term Name DefaultUni DefaultFun ())] -> [TestTree]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((String -> Term Name DefaultUni DefaultFun () -> TestTree)
-> (String, Term Name DefaultUni DefaultFun ()) -> TestTree
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry String -> Term Name DefaultUni DefaultFun () -> TestTree
goldenVsOptimized) [(String, Term Name DefaultUni DefaultFun ())]
testSimplifyInputs
      [TestTree] -> [TestTree] -> [TestTree]
forall a. Semigroup a => a -> a -> a
<> ((String, Term Name DefaultUni DefaultFun ()) -> TestTree)
-> [(String, Term Name DefaultUni DefaultFun ())] -> [TestTree]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((String -> Term Name DefaultUni DefaultFun () -> TestTree)
-> (String, Term Name DefaultUni DefaultFun ()) -> TestTree
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (CseWhichSubterms
-> String -> Term Name DefaultUni DefaultFun () -> TestTree
goldenVsCse CseWhichSubterms
ExcludeWorkFree)) [(String, Term Name DefaultUni DefaultFun ())]
testCseInputs
      [TestTree] -> [TestTree] -> [TestTree]
forall a. Semigroup a => a -> a -> a
<> ((String, Term Name DefaultUni DefaultFun ()) -> TestTree)
-> [(String, Term Name DefaultUni DefaultFun ())] -> [TestTree]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((String -> Term Name DefaultUni DefaultFun () -> TestTree)
-> (String, Term Name DefaultUni DefaultFun ()) -> TestTree
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (CseWhichSubterms
-> String -> Term Name DefaultUni DefaultFun () -> TestTree
goldenVsCse CseWhichSubterms
AllSubterms)) [(String, Term Name DefaultUni DefaultFun ())]
testCseInputsWorkFree

--------------------------------------------------------------------------------
-- Local helpers ---------------------------------------------------------------

plus :: T -> T -> T
plus :: Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
plus Term Name DefaultUni DefaultFun ()
i Term Name DefaultUni DefaultFun ()
j = DefaultFun -> Term Name DefaultUni DefaultFun ()
builtin DefaultFun
PLC.AddInteger Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
`app` Term Name DefaultUni DefaultFun ()
i Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
`app` Term Name DefaultUni DefaultFun ()
j