{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeApplications #-}

module Transform.EvaluateBuiltins.Spec where

import Data.ByteString qualified as BS
import Data.ByteString.Base16 qualified as Base16
import Data.ByteString.Char8 qualified as BS8
import Data.Text (Text)
import PlutusCore qualified as PLC
import PlutusCore.MkPlc (mkConstant, mkIterApp)
import PlutusCore.Quote (freshName, runQuote)
import PlutusPrelude (Default (def))
import Test.Tasty (TestTree, testGroup)
import Transform.Simplify.Lib (goldenVsPretty)
import UntypedPlutusCore (DefaultFun, DefaultUni, Name, Term (..))
import UntypedPlutusCore.Transform.EvaluateBuiltins (evaluateBuiltinsPass)
import UntypedPlutusCore.Transform.Optimizer (evalOptimizer)

test_evaluateBuiltins :: TestTree
test_evaluateBuiltins :: TestTree
test_evaluateBuiltins =
  [Char] -> [TestTree] -> TestTree
testGroup [Char]
"EvaluateBuiltins" ([TestTree] -> TestTree) -> [TestTree] -> TestTree
forall a b. (a -> b) -> a -> b
$
    (([Char], Term Name DefaultUni DefaultFun ()) -> TestTree)
-> [([Char], Term Name DefaultUni DefaultFun ())] -> [TestTree]
forall a b. (a -> b) -> [a] -> [b]
map
      (([Char] -> Term Name DefaultUni DefaultFun () -> TestTree)
-> ([Char], Term Name DefaultUni DefaultFun ()) -> TestTree
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (([Char] -> Term Name DefaultUni DefaultFun () -> TestTree)
 -> ([Char], Term Name DefaultUni DefaultFun ()) -> TestTree)
-> ([Char] -> Term Name DefaultUni DefaultFun () -> TestTree)
-> ([Char], Term Name DefaultUni DefaultFun ())
-> TestTree
forall a b. (a -> b) -> a -> b
$ Bool -> [Char] -> Term Name DefaultUni DefaultFun () -> TestTree
goldenVsEvaluated Bool
True)
      [ ([Char]
"addInteger", Term Name DefaultUni DefaultFun ()
addIntegerTerm)
      , ([Char]
"ifThenElse", Term Name DefaultUni DefaultFun ()
ifThenElseTerm)
      , ([Char]
"traceConservative", Term Name DefaultUni DefaultFun ()
traceTerm)
      , ([Char]
"failingBuiltin", Term Name DefaultUni DefaultFun ()
failingBuiltinTerm)
      , ([Char]
"nonConstantArg", Term Name DefaultUni DefaultFun ()
nonConstantArgTerm)
      , ([Char]
"overApplication", Term Name DefaultUni DefaultFun ()
overApplicationTerm)
      , ([Char]
"underApplication", Term Name DefaultUni DefaultFun ()
underApplicationTerm)
      , ([Char]
"uncompressBlsConservative", Term Name DefaultUni DefaultFun ()
uncompressBlsG2Term)
      ]
      [TestTree] -> [TestTree] -> [TestTree]
forall a. [a] -> [a] -> [a]
++ (([Char], Term Name DefaultUni DefaultFun ()) -> TestTree)
-> [([Char], Term Name DefaultUni DefaultFun ())] -> [TestTree]
forall a b. (a -> b) -> [a] -> [b]
map
        (([Char] -> Term Name DefaultUni DefaultFun () -> TestTree)
-> ([Char], Term Name DefaultUni DefaultFun ()) -> TestTree
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (([Char] -> Term Name DefaultUni DefaultFun () -> TestTree)
 -> ([Char], Term Name DefaultUni DefaultFun ()) -> TestTree)
-> ([Char] -> Term Name DefaultUni DefaultFun () -> TestTree)
-> ([Char], Term Name DefaultUni DefaultFun ())
-> TestTree
forall a b. (a -> b) -> a -> b
$ Bool -> [Char] -> Term Name DefaultUni DefaultFun () -> TestTree
goldenVsEvaluated Bool
False)
        [ ([Char]
"traceNonConservative", Term Name DefaultUni DefaultFun ()
traceTerm)
        , ([Char]
"uncompressBlsNonConservative", Term Name DefaultUni DefaultFun ()
uncompressBlsG2Term)
        , ([Char]
"uncompressAndEqualBlsNonConservative", Term Name DefaultUni DefaultFun ()
uncompressAndEqualBlsTerm)
        ]

goldenVsEvaluated :: Bool -> String -> Term Name DefaultUni DefaultFun () -> TestTree
goldenVsEvaluated :: Bool -> [Char] -> Term Name DefaultUni DefaultFun () -> TestTree
goldenVsEvaluated Bool
conservative [Char]
name =
  [Char] -> [Char] -> Term Name DefaultUni DefaultFun () -> TestTree
forall a. PrettyPlc a => [Char] -> [Char] -> a -> TestTree
goldenVsPretty [Char]
".golden.uplc" ([Char]
"EvaluateBuiltins/" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [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
. Bool
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
runEvaluateBuiltins Bool
conservative

runEvaluateBuiltins
  :: Bool
  -> Term Name DefaultUni DefaultFun ()
  -> Term Name DefaultUni DefaultFun ()
runEvaluateBuiltins :: Bool
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
runEvaluateBuiltins Bool
conservative = Optimizer
  Name DefaultUni DefaultFun () (Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
forall name (uni :: * -> *) fun ann a.
Optimizer name uni fun ann a -> a
evalOptimizer (Optimizer
   Name DefaultUni DefaultFun () (Term Name DefaultUni DefaultFun ())
 -> Term Name DefaultUni DefaultFun ())
-> (Term Name DefaultUni DefaultFun ()
    -> Optimizer
         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
. Bool
-> BuiltinsInfo DefaultUni DefaultFun
-> CostingPart DefaultUni DefaultFun
-> Term Name DefaultUni DefaultFun ()
-> Optimizer
     Name DefaultUni DefaultFun () (Term Name DefaultUni DefaultFun ())
forall (m :: * -> *) (uni :: * -> *) fun name a.
(Monad m, ToBuiltinMeaning uni fun, Typeable name) =>
Bool
-> BuiltinsInfo uni fun
-> CostingPart uni fun
-> Term name uni fun a
-> OptimizerT name uni fun a m (Term name uni fun a)
evaluateBuiltinsPass Bool
conservative BuiltinsInfo DefaultUni DefaultFun
forall a. Default a => a
def BuiltinCostModel
CostingPart DefaultUni DefaultFun
forall a. Default a => a
def

addIntegerTerm :: Term Name DefaultUni DefaultFun ()
addIntegerTerm :: Term Name DefaultUni DefaultFun ()
addIntegerTerm =
  ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall name (uni :: * -> *) fun ann.
ann
-> Term name uni fun ann
-> Term name uni fun ann
-> Term name uni fun ann
Apply
    ()
    (()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall name (uni :: * -> *) fun ann.
ann
-> Term name uni fun ann
-> Term name uni fun ann
-> Term name uni fun ann
Apply () (() -> DefaultFun -> Term Name DefaultUni DefaultFun ()
forall name (uni :: * -> *) fun ann.
ann -> fun -> Term name uni fun ann
Builtin () DefaultFun
PLC.AddInteger) (forall a (uni :: * -> *) fun (term :: * -> *) tyname name ann.
(TermLike term tyname name uni fun, HasTermLevel uni a) =>
ann -> a -> term ann
mkConstant @Integer () Integer
1))
    (forall a (uni :: * -> *) fun (term :: * -> *) tyname name ann.
(TermLike term tyname name uni fun, HasTermLevel uni a) =>
ann -> a -> term ann
mkConstant @Integer () Integer
2)

ifThenElseTerm :: Term Name DefaultUni DefaultFun ()
ifThenElseTerm :: Term Name DefaultUni DefaultFun ()
ifThenElseTerm =
  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
    (()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall name (uni :: * -> *) fun ann.
ann -> Term name uni fun ann -> Term name uni fun ann
Force () (() -> DefaultFun -> Term Name DefaultUni DefaultFun ()
forall name (uni :: * -> *) fun ann.
ann -> fun -> Term name uni fun ann
Builtin () DefaultFun
PLC.IfThenElse))
    [ ((), forall a (uni :: * -> *) fun (term :: * -> *) tyname name ann.
(TermLike term tyname name uni fun, HasTermLevel uni a) =>
ann -> a -> term ann
mkConstant @Bool () Bool
True)
    , ((), forall a (uni :: * -> *) fun (term :: * -> *) tyname name ann.
(TermLike term tyname name uni fun, HasTermLevel uni a) =>
ann -> a -> term ann
mkConstant @Integer () Integer
1)
    , ((), forall a (uni :: * -> *) fun (term :: * -> *) tyname name ann.
(TermLike term tyname name uni fun, HasTermLevel uni a) =>
ann -> a -> term ann
mkConstant @Integer () Integer
2)
    ]

-- Used for both traceConservative (unchanged) and traceNonConservative (reduced to 1)
traceTerm :: Term Name DefaultUni DefaultFun ()
traceTerm :: Term Name DefaultUni DefaultFun ()
traceTerm =
  ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall name (uni :: * -> *) fun ann.
ann
-> Term name uni fun ann
-> Term name uni fun ann
-> Term name uni fun ann
Apply
    ()
    (()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall name (uni :: * -> *) fun ann.
ann
-> Term name uni fun ann
-> Term name uni fun ann
-> Term name uni fun ann
Apply () (()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall name (uni :: * -> *) fun ann.
ann -> Term name uni fun ann -> Term name uni fun ann
Force () (() -> DefaultFun -> Term Name DefaultUni DefaultFun ()
forall name (uni :: * -> *) fun ann.
ann -> fun -> Term name uni fun ann
Builtin () DefaultFun
PLC.Trace)) (forall a (uni :: * -> *) fun (term :: * -> *) tyname name ann.
(TermLike term tyname name uni fun, HasTermLevel uni a) =>
ann -> a -> term ann
mkConstant @Text () Text
"hello"))
    (forall a (uni :: * -> *) fun (term :: * -> *) tyname name ann.
(TermLike term tyname name uni fun, HasTermLevel uni a) =>
ann -> a -> term ann
mkConstant @Integer () Integer
1)

-- Division by zero; evaluates to error so should be left in place
failingBuiltinTerm :: Term Name DefaultUni DefaultFun ()
failingBuiltinTerm :: Term Name DefaultUni DefaultFun ()
failingBuiltinTerm =
  ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall name (uni :: * -> *) fun ann.
ann
-> Term name uni fun ann
-> Term name uni fun ann
-> Term name uni fun ann
Apply
    ()
    (()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall name (uni :: * -> *) fun ann.
ann
-> Term name uni fun ann
-> Term name uni fun ann
-> Term name uni fun ann
Apply () (() -> DefaultFun -> Term Name DefaultUni DefaultFun ()
forall name (uni :: * -> *) fun ann.
ann -> fun -> Term name uni fun ann
Builtin () DefaultFun
PLC.DivideInteger) (forall a (uni :: * -> *) fun (term :: * -> *) tyname name ann.
(TermLike term tyname name uni fun, HasTermLevel uni a) =>
ann -> a -> term ann
mkConstant @Integer () Integer
1))
    (forall a (uni :: * -> *) fun (term :: * -> *) tyname name ann.
(TermLike term tyname name uni fun, HasTermLevel uni a) =>
ann -> a -> term ann
mkConstant @Integer () Integer
0)

-- The variable argument prevents evaluation
nonConstantArgTerm :: Term Name DefaultUni DefaultFun ()
nonConstantArgTerm :: Term Name DefaultUni DefaultFun ()
nonConstantArgTerm = Quote (Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
forall a. Quote a -> a
runQuote (Quote (Term Name DefaultUni DefaultFun ())
 -> Term Name DefaultUni DefaultFun ())
-> Quote (Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$ do
  Name
x <- Text -> QuoteT Identity Name
forall (m :: * -> *). MonadQuote m => Text -> m Name
freshName Text
"x"
  Term Name DefaultUni DefaultFun ()
-> Quote (Term Name DefaultUni DefaultFun ())
forall a. a -> QuoteT Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Term Name DefaultUni DefaultFun ()
 -> Quote (Term Name DefaultUni DefaultFun ()))
-> Term Name DefaultUni DefaultFun ()
-> Quote (Term Name DefaultUni DefaultFun ())
forall a b. (a -> b) -> a -> b
$
    ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall name (uni :: * -> *) fun ann.
ann
-> Term name uni fun ann
-> Term name uni fun ann
-> Term name uni fun ann
Apply
      ()
      (()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall name (uni :: * -> *) fun ann.
ann
-> Term name uni fun ann
-> Term name uni fun ann
-> Term name uni fun ann
Apply () (() -> DefaultFun -> Term Name DefaultUni DefaultFun ()
forall name (uni :: * -> *) fun ann.
ann -> fun -> Term name uni fun ann
Builtin () DefaultFun
PLC.AddInteger) (() -> Name -> Term Name DefaultUni DefaultFun ()
forall name (uni :: * -> *) fun ann.
ann -> name -> Term name uni fun ann
Var () Name
x))
      (forall a (uni :: * -> *) fun (term :: * -> *) tyname name ann.
(TermLike term tyname name uni fun, HasTermLevel uni a) =>
ann -> a -> term ann
mkConstant @Integer () Integer
2)

-- ifThenElse returns a function (lambda), then applied to an extra argument
overApplicationTerm :: Term Name DefaultUni DefaultFun ()
overApplicationTerm :: Term Name DefaultUni DefaultFun ()
overApplicationTerm = Quote (Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
forall a. Quote a -> a
runQuote (Quote (Term Name DefaultUni DefaultFun ())
 -> Term Name DefaultUni DefaultFun ())
-> Quote (Term Name DefaultUni DefaultFun ())
-> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$ do
  Name
x <- Text -> QuoteT Identity Name
forall (m :: * -> *). MonadQuote m => Text -> m Name
freshName Text
"x"
  Term Name DefaultUni DefaultFun ()
-> Quote (Term Name DefaultUni DefaultFun ())
forall a. a -> QuoteT Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Term Name DefaultUni DefaultFun ()
 -> Quote (Term Name DefaultUni DefaultFun ()))
-> Term Name DefaultUni DefaultFun ()
-> Quote (Term Name DefaultUni DefaultFun ())
forall a b. (a -> b) -> a -> b
$
    ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall name (uni :: * -> *) fun ann.
ann
-> Term name uni fun ann
-> Term name uni fun ann
-> Term name uni fun ann
Apply
      ()
      ( 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
          (()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall name (uni :: * -> *) fun ann.
ann -> Term name uni fun ann -> Term name uni fun ann
Force () (() -> DefaultFun -> Term Name DefaultUni DefaultFun ()
forall name (uni :: * -> *) fun ann.
ann -> fun -> Term name uni fun ann
Builtin () DefaultFun
PLC.IfThenElse))
          [ ((), forall a (uni :: * -> *) fun (term :: * -> *) tyname name ann.
(TermLike term tyname name uni fun, HasTermLevel uni a) =>
ann -> a -> term ann
mkConstant @Bool () Bool
True)
          , ((), ()
-> Name
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall name (uni :: * -> *) fun ann.
ann -> name -> Term name uni fun ann -> Term name uni fun ann
LamAbs () Name
x (forall a (uni :: * -> *) fun (term :: * -> *) tyname name ann.
(TermLike term tyname name uni fun, HasTermLevel uni a) =>
ann -> a -> term ann
mkConstant @Integer () Integer
1))
          , ((), ()
-> Name
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall name (uni :: * -> *) fun ann.
ann -> name -> Term name uni fun ann -> Term name uni fun ann
LamAbs () Name
x (forall a (uni :: * -> *) fun (term :: * -> *) tyname name ann.
(TermLike term tyname name uni fun, HasTermLevel uni a) =>
ann -> a -> term ann
mkConstant @Integer () Integer
2))
          ]
      )
      (forall a (uni :: * -> *) fun (term :: * -> *) tyname name ann.
(TermLike term tyname name uni fun, HasTermLevel uni a) =>
ann -> a -> term ann
mkConstant @Integer () Integer
3)

-- Missing an argument, should be left unchanged
underApplicationTerm :: Term Name DefaultUni DefaultFun ()
underApplicationTerm :: Term Name DefaultUni DefaultFun ()
underApplicationTerm =
  ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall name (uni :: * -> *) fun ann.
ann
-> Term name uni fun ann
-> Term name uni fun ann
-> Term name uni fun ann
Apply () (() -> DefaultFun -> Term Name DefaultUni DefaultFun ()
forall name (uni :: * -> *) fun ann.
ann -> fun -> Term name uni fun ann
Builtin () DefaultFun
PLC.AddInteger) (forall a (uni :: * -> *) fun (term :: * -> *) tyname name ann.
(TermLike term tyname name uni fun, HasTermLevel uni a) =>
ann -> a -> term ann
mkConstant @Integer () Integer
1)

-- In both conservative and non-conservative mode: left unchanged because the
-- result (a G2 element) is an unserializable constant
uncompressBlsG2Term :: Term Name DefaultUni DefaultFun ()
uncompressBlsG2Term :: Term Name DefaultUni DefaultFun ()
uncompressBlsG2Term =
  ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall name (uni :: * -> *) fun ann.
ann
-> Term name uni fun ann
-> Term name uni fun ann
-> Term name uni fun ann
Apply () (() -> DefaultFun -> Term Name DefaultUni DefaultFun ()
forall name (uni :: * -> *) fun ann.
ann -> fun -> Term name uni fun ann
Builtin () DefaultFun
PLC.Bls12_381_G2_uncompress) (forall a (uni :: * -> *) fun (term :: * -> *) tyname name ann.
(TermLike term tyname name uni fun, HasTermLevel uni a) =>
ann -> a -> term ann
mkConstant @BS.ByteString () ByteString
blsG2Bytes)
  where
    blsG2Bytes :: ByteString
blsG2Bytes =
      [Char] -> ByteString
decodeHex
        ( [Char]
"c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
            [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
        )

-- In non-conservative mode: left unchanged because intermediate results
-- (G1 elements) are unserializable, so we can't evaluate through them
uncompressAndEqualBlsTerm :: Term Name DefaultUni DefaultFun ()
uncompressAndEqualBlsTerm :: Term Name DefaultUni DefaultFun ()
uncompressAndEqualBlsTerm =
  ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall name (uni :: * -> *) fun ann.
ann
-> Term name uni fun ann
-> Term name uni fun ann
-> Term name uni fun ann
Apply
    ()
    ( ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall name (uni :: * -> *) fun ann.
ann
-> Term name uni fun ann
-> Term name uni fun ann
-> Term name uni fun ann
Apply
        ()
        (() -> DefaultFun -> Term Name DefaultUni DefaultFun ()
forall name (uni :: * -> *) fun ann.
ann -> fun -> Term name uni fun ann
Builtin () DefaultFun
PLC.Bls12_381_G1_equal)
        (()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall name (uni :: * -> *) fun ann.
ann
-> Term name uni fun ann
-> Term name uni fun ann
-> Term name uni fun ann
Apply () (() -> DefaultFun -> Term Name DefaultUni DefaultFun ()
forall name (uni :: * -> *) fun ann.
ann -> fun -> Term name uni fun ann
Builtin () DefaultFun
PLC.Bls12_381_G1_uncompress) Term Name DefaultUni DefaultFun ()
blsG1BytesTerm)
    )
    (()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
-> Term Name DefaultUni DefaultFun ()
forall name (uni :: * -> *) fun ann.
ann
-> Term name uni fun ann
-> Term name uni fun ann
-> Term name uni fun ann
Apply () (() -> DefaultFun -> Term Name DefaultUni DefaultFun ()
forall name (uni :: * -> *) fun ann.
ann -> fun -> Term name uni fun ann
Builtin () DefaultFun
PLC.Bls12_381_G1_uncompress) Term Name DefaultUni DefaultFun ()
blsG1BytesTerm)
  where
    blsG1BytesTerm :: Term Name DefaultUni DefaultFun ()
blsG1BytesTerm =
      forall a (uni :: * -> *) fun (term :: * -> *) tyname name ann.
(TermLike term tyname name uni fun, HasTermLevel uni a) =>
ann -> a -> term ann
mkConstant @BS.ByteString () (ByteString -> Term Name DefaultUni DefaultFun ())
-> ByteString -> Term Name DefaultUni DefaultFun ()
forall a b. (a -> b) -> a -> b
$
        [Char] -> ByteString
decodeHex
          [Char]
"97f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb"

decodeHex :: String -> BS.ByteString
decodeHex :: [Char] -> ByteString
decodeHex [Char]
hex = case ByteString -> Either [Char] ByteString
Base16.decode ([Char] -> ByteString
BS8.pack [Char]
hex) of
  Right ByteString
bs -> ByteString
bs
  Left [Char]
err -> [Char] -> ByteString
forall a. HasCallStack => [Char] -> a
error ([Char] -> ByteString) -> [Char] -> ByteString
forall a b. (a -> b) -> a -> b
$ [Char]
"Transform.EvaluateBuiltins.Spec: invalid hex: " [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Char]
err