{-# OPTIONS_GHC -fno-warn-redundant-constraints #-}
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE StandaloneKindSignatures #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
module PlutusCore.Builtin.Meaning where
import PlutusPrelude
import PlutusCore.Builtin.Elaborate
import PlutusCore.Builtin.HasConstant
import PlutusCore.Builtin.KnownKind
import PlutusCore.Builtin.KnownType
import PlutusCore.Builtin.KnownTypeAst
import PlutusCore.Builtin.Runtime
import PlutusCore.Builtin.TypeScheme
import PlutusCore.Core
import PlutusCore.Name
import Control.Monad.Except
import Data.Array
import Data.Kind qualified as GHC
import Data.Proxy
import Data.Some.GADT
import GHC.Exts (inline)
import GHC.TypeLits
type family FoldArgs args res where
FoldArgs '[] res = res
FoldArgs (arg ': args) res = arg -> FoldArgs args res
data BuiltinMeaning val cost =
forall args res. BuiltinMeaning
(TypeScheme val args res)
(FoldArgs args res)
(BuiltinRuntimeOptions (Length args) val cost)
class (Bounded fun, Enum fun, Ix fun) => ToBuiltinMeaning uni fun where
type CostingPart uni fun
toBuiltinMeaning :: HasConstantIn uni val => fun -> BuiltinMeaning val (CostingPart uni fun)
typeOfBuiltinFunction :: ToBuiltinMeaning uni fun => fun -> Type TyName uni ()
typeOfBuiltinFunction :: fun -> Type TyName uni ()
typeOfBuiltinFunction fun
fun = case fun
-> BuiltinMeaning
(Term TyName Name uni Any ()) (CostingPart uni fun)
forall (uni :: * -> *) fun val.
(ToBuiltinMeaning uni fun, HasConstantIn uni val) =>
fun -> BuiltinMeaning val (CostingPart uni fun)
toBuiltinMeaning @_ @_ @(Term TyName Name _ _ ()) fun
fun of
BuiltinMeaning TypeScheme (Term TyName Name uni Any ()) args res
sch FoldArgs args res
_ BuiltinRuntimeOptions
(Length args) (Term TyName Name uni Any ()) (CostingPart uni fun)
_ -> TypeScheme (Term TyName Name uni Any ()) args res
-> Type TyName (UniOf (Term TyName Name uni Any ())) ()
forall val (args :: [*]) res.
TypeScheme val args res -> Type TyName (UniOf val) ()
typeSchemeToType TypeScheme (Term TyName Name uni Any ()) args res
sch
type Length :: forall a. [a] -> Peano
type family Length xs where
Length '[] = 'Z
Length (_ ': xs) = 'S (Length xs)
type GetArgs :: GHC.Type -> [GHC.Type]
type family GetArgs a where
GetArgs (a -> b) = a ': GetArgs b
GetArgs _ = '[]
class KnownMonotype val args res a | args res -> a, a -> res where
knownMonotype :: TypeScheme val args res
knownMonoruntime :: RuntimeScheme (Length args)
toImmediateF :: FoldArgs args res -> ToRuntimeDenotationType val (Length args)
toDeferredF :: ReadKnownM () (FoldArgs args res) -> ToRuntimeDenotationType val (Length args)
instance (res ~ res', KnownTypeAst (UniOf val) res, MakeKnown val res) =>
KnownMonotype val '[] res res' where
knownMonotype :: TypeScheme val '[] res
knownMonotype = TypeScheme val '[] res
forall val res.
(KnownTypeAst (UniOf val) res, MakeKnown val res) =>
TypeScheme val '[] res
TypeSchemeResult
knownMonoruntime :: RuntimeScheme (Length '[])
knownMonoruntime = RuntimeScheme 'Z
RuntimeScheme (Length '[])
RuntimeSchemeResult
toImmediateF :: FoldArgs '[] res -> ToRuntimeDenotationType val (Length '[])
toImmediateF = Maybe () -> res' -> MakeKnownM () val
forall (uni :: * -> *) val a cause.
MakeKnownIn uni val a =>
Maybe cause -> a -> MakeKnownM cause val
makeKnown (() -> Maybe ()
forall a. a -> Maybe a
Just ())
{-# INLINE toImmediateF #-}
toDeferredF :: ReadKnownM () (FoldArgs '[] res)
-> ToRuntimeDenotationType val (Length '[])
toDeferredF ReadKnownM () (FoldArgs '[] res)
getRes = Either (ErrorWithCause KnownTypeError ()) res'
-> ExceptT (ErrorWithCause KnownTypeError ()) Emitter res'
forall e (m :: * -> *) a. MonadError e m => Either e a -> m a
liftEither Either (ErrorWithCause KnownTypeError ()) res'
ReadKnownM () (FoldArgs '[] res)
getRes ExceptT (ErrorWithCause KnownTypeError ()) Emitter res'
-> (res' -> MakeKnownM () val) -> MakeKnownM () val
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Maybe () -> res' -> MakeKnownM () val
forall (uni :: * -> *) val a cause.
MakeKnownIn uni val a =>
Maybe cause -> a -> MakeKnownM cause val
makeKnown (() -> Maybe ()
forall a. a -> Maybe a
Just ())
{-# INLINE toDeferredF #-}
instance
( KnownTypeAst (UniOf val) arg, MakeKnown val arg, ReadKnown val arg
, KnownMonotype val args res a
) => KnownMonotype val (arg ': args) res (arg -> a) where
knownMonotype :: TypeScheme val (arg : args) res
knownMonotype = TypeScheme val args res -> TypeScheme val (arg : args) res
forall val arg (args :: [*]) res.
(KnownTypeAst (UniOf val) arg, MakeKnown val arg,
ReadKnown val arg) =>
TypeScheme val args res -> TypeScheme val (arg : args) res
TypeSchemeArrow TypeScheme val args res
forall k val (args :: [*]) res (a :: k).
KnownMonotype val args res a =>
TypeScheme val args res
knownMonotype
knownMonoruntime :: RuntimeScheme (Length (arg : args))
knownMonoruntime = RuntimeScheme (Length args) -> RuntimeScheme ('S (Length args))
forall (n :: Peano). RuntimeScheme n -> RuntimeScheme ('S n)
RuntimeSchemeArrow (RuntimeScheme (Length args) -> RuntimeScheme ('S (Length args)))
-> RuntimeScheme (Length args) -> RuntimeScheme ('S (Length args))
forall a b. (a -> b) -> a -> b
$ forall a.
KnownMonotype val args res a =>
RuntimeScheme (Length args)
forall k val (args :: [*]) res (a :: k).
KnownMonotype val args res a =>
RuntimeScheme (Length args)
knownMonoruntime @val @args @res
toImmediateF :: FoldArgs (arg : args) res
-> ToRuntimeDenotationType val (Length (arg : args))
toImmediateF FoldArgs (arg : args) res
f = (arg -> ToRuntimeDenotationType val (Length args))
-> Either (ErrorWithCause KnownTypeError ()) arg
-> Either
(ErrorWithCause KnownTypeError ())
(ToRuntimeDenotationType val (Length args))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall a.
KnownMonotype val args res a =>
FoldArgs args res -> ToRuntimeDenotationType val (Length args)
forall k val (args :: [*]) res (a :: k).
KnownMonotype val args res a =>
FoldArgs args res -> ToRuntimeDenotationType val (Length args)
toImmediateF @val @args @res (FoldArgs args res -> ToRuntimeDenotationType val (Length args))
-> (arg -> FoldArgs args res)
-> arg
-> ToRuntimeDenotationType val (Length args)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FoldArgs (arg : args) res
arg -> FoldArgs args res
f) (Either (ErrorWithCause KnownTypeError ()) arg
-> Either
(ErrorWithCause KnownTypeError ())
(ToRuntimeDenotationType val (Length args)))
-> (val -> Either (ErrorWithCause KnownTypeError ()) arg)
-> val
-> Either
(ErrorWithCause KnownTypeError ())
(ToRuntimeDenotationType val (Length args))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe () -> val -> Either (ErrorWithCause KnownTypeError ()) arg
forall (uni :: * -> *) val a cause.
ReadKnownIn uni val a =>
Maybe cause -> val -> ReadKnownM cause a
readKnown (() -> Maybe ()
forall a. a -> Maybe a
Just ())
{-# INLINE toImmediateF #-}
toDeferredF :: ReadKnownM () (FoldArgs (arg : args) res)
-> ToRuntimeDenotationType val (Length (arg : args))
toDeferredF ReadKnownM () (FoldArgs (arg : args) res)
getF = \val
arg ->
ToRuntimeDenotationType val (Length args)
-> Either
(ErrorWithCause KnownTypeError ())
(ToRuntimeDenotationType val (Length args))
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ToRuntimeDenotationType val (Length args)
-> Either
(ErrorWithCause KnownTypeError ())
(ToRuntimeDenotationType val (Length args)))
-> (Either (ErrorWithCause KnownTypeError ()) (FoldArgs args res)
-> ToRuntimeDenotationType val (Length args))
-> Either (ErrorWithCause KnownTypeError ()) (FoldArgs args res)
-> Either
(ErrorWithCause KnownTypeError ())
(ToRuntimeDenotationType val (Length args))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a.
KnownMonotype val args res a =>
Either (ErrorWithCause KnownTypeError ()) (FoldArgs args res)
-> ToRuntimeDenotationType val (Length args)
forall k val (args :: [*]) res (a :: k).
KnownMonotype val args res a =>
ReadKnownM () (FoldArgs args res)
-> ToRuntimeDenotationType val (Length args)
toDeferredF @val @args @res (Either (ErrorWithCause KnownTypeError ()) (FoldArgs args res)
-> Either
(ErrorWithCause KnownTypeError ())
(ToRuntimeDenotationType val (Length args)))
-> Either (ErrorWithCause KnownTypeError ()) (FoldArgs args res)
-> Either
(ErrorWithCause KnownTypeError ())
(ToRuntimeDenotationType val (Length args))
forall a b. (a -> b) -> a -> b
$! ReadKnownM () (FoldArgs (arg : args) res)
Either
(ErrorWithCause KnownTypeError ()) (arg -> FoldArgs args res)
getF Either
(ErrorWithCause KnownTypeError ()) (arg -> FoldArgs args res)
-> Either (ErrorWithCause KnownTypeError ()) arg
-> Either (ErrorWithCause KnownTypeError ()) (FoldArgs args res)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Maybe () -> val -> Either (ErrorWithCause KnownTypeError ()) arg
forall (uni :: * -> *) val a cause.
ReadKnownIn uni val a =>
Maybe cause -> val -> ReadKnownM cause a
readKnown (() -> Maybe ()
forall a. a -> Maybe a
Just ()) val
arg
{-# INLINE toDeferredF #-}
class KnownMonotype val args res a =>
KnownPolytype (binds :: [Some TyNameRep]) val args res a | args res -> a, a -> res where
knownPolytype :: TypeScheme val args res
knownPolyruntime :: RuntimeScheme (Length args)
instance KnownMonotype val args res a => KnownPolytype '[] val args res a where
knownPolytype :: TypeScheme val args res
knownPolytype = TypeScheme val args res
forall k val (args :: [*]) res (a :: k).
KnownMonotype val args res a =>
TypeScheme val args res
knownMonotype
knownPolyruntime :: RuntimeScheme (Length args)
knownPolyruntime = forall (a :: k).
KnownMonotype val args res a =>
RuntimeScheme (Length args)
forall k val (args :: [*]) res (a :: k).
KnownMonotype val args res a =>
RuntimeScheme (Length args)
knownMonoruntime @val @args @res
instance (KnownSymbol name, KnownNat uniq, KnownKind kind, KnownPolytype binds val args res a) =>
KnownPolytype ('Some ('TyNameRep @kind name uniq) ': binds) val args res a where
knownPolytype :: TypeScheme val args res
knownPolytype = Proxy '(name, uniq, kind)
-> TypeScheme val args res -> TypeScheme val args res
forall (text :: Symbol) (uniq :: Nat) kind val (args :: [*]) res.
(KnownSymbol text, KnownNat uniq, KnownKind kind) =>
Proxy '(text, uniq, kind)
-> TypeScheme val args res -> TypeScheme val args res
TypeSchemeAll @name @uniq @kind Proxy '(name, uniq, kind)
forall k (t :: k). Proxy t
Proxy (TypeScheme val args res -> TypeScheme val args res)
-> TypeScheme val args res -> TypeScheme val args res
forall a b. (a -> b) -> a -> b
$ forall val (args :: [*]) res (a :: k).
KnownPolytype binds val args res a =>
TypeScheme val args res
forall k (binds :: [Some TyNameRep]) val (args :: [*]) res
(a :: k).
KnownPolytype binds val args res a =>
TypeScheme val args res
knownPolytype @binds
knownPolyruntime :: RuntimeScheme (Length args)
knownPolyruntime = RuntimeScheme (Length args) -> RuntimeScheme (Length args)
forall (n :: Peano). RuntimeScheme n -> RuntimeScheme n
RuntimeSchemeAll (RuntimeScheme (Length args) -> RuntimeScheme (Length args))
-> RuntimeScheme (Length args) -> RuntimeScheme (Length args)
forall a b. (a -> b) -> a -> b
$ forall (a :: k).
KnownPolytype binds val args res a =>
RuntimeScheme (Length args)
forall k (binds :: [Some TyNameRep]) val (args :: [*]) res
(a :: k).
KnownPolytype binds val args res a =>
RuntimeScheme (Length args)
knownPolyruntime @binds @val @args @res
makeBuiltinMeaning
:: forall a val cost binds args res j.
( binds ~ ToBinds a, args ~ GetArgs a, a ~ FoldArgs args res
, ElaborateFromTo 0 j val a, KnownPolytype binds val args res a
)
=> a -> (cost -> ToCostingType (Length args)) -> BuiltinMeaning val cost
makeBuiltinMeaning :: a
-> (cost -> ToCostingType (Length args)) -> BuiltinMeaning val cost
makeBuiltinMeaning a
f cost -> ToCostingType (Length args)
toExF =
TypeScheme val args res
-> FoldArgs args res
-> BuiltinRuntimeOptions (Length args) val cost
-> BuiltinMeaning val cost
forall val cost (args :: [*]) res.
TypeScheme val args res
-> FoldArgs args res
-> BuiltinRuntimeOptions (Length args) val cost
-> BuiltinMeaning val cost
BuiltinMeaning (forall a.
KnownPolytype binds val args res a =>
TypeScheme val args res
forall k (binds :: [Some TyNameRep]) val (args :: [*]) res
(a :: k).
KnownPolytype binds val args res a =>
TypeScheme val args res
knownPolytype @binds @val @args @res) a
FoldArgs args res
f (BuiltinRuntimeOptions (Length args) val cost
-> BuiltinMeaning val cost)
-> BuiltinRuntimeOptions (Length args) val cost
-> BuiltinMeaning val cost
forall a b. (a -> b) -> a -> b
$
BuiltinRuntimeOptions :: forall (n :: Peano) val cost.
RuntimeScheme n
-> ToRuntimeDenotationType val n
-> ToRuntimeDenotationType val n
-> (cost -> ToCostingType n)
-> BuiltinRuntimeOptions n val cost
BuiltinRuntimeOptions
{ _broRuntimeScheme :: RuntimeScheme (Length args)
_broRuntimeScheme = forall a.
KnownPolytype binds val args res a =>
RuntimeScheme (Length args)
forall k (binds :: [Some TyNameRep]) val (args :: [*]) res
(a :: k).
KnownPolytype binds val args res a =>
RuntimeScheme (Length args)
knownPolyruntime @binds @val @args @res
, _broImmediateF :: ToRuntimeDenotationType val (Length args)
_broImmediateF = FoldArgs args res -> ToRuntimeDenotationType val (Length args)
forall k val (args :: [*]) res (a :: k).
KnownMonotype val args res a =>
FoldArgs args res -> ToRuntimeDenotationType val (Length args)
toImmediateF @val @args @res a
FoldArgs args res
f
, _broDeferredF :: ToRuntimeDenotationType val (Length args)
_broDeferredF = forall a.
KnownMonotype val args res a =>
ReadKnownM () (FoldArgs args res)
-> ToRuntimeDenotationType val (Length args)
forall k val (args :: [*]) res (a :: k).
KnownMonotype val args res a =>
ReadKnownM () (FoldArgs args res)
-> ToRuntimeDenotationType val (Length args)
toDeferredF @val @args @res (ReadKnownM () (FoldArgs args res)
-> ToRuntimeDenotationType val (Length args))
-> ReadKnownM () (FoldArgs args res)
-> ToRuntimeDenotationType val (Length args)
forall a b. (a -> b) -> a -> b
$ a -> Either (ErrorWithCause KnownTypeError ()) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
f
, _broToExF :: cost -> ToCostingType (Length args)
_broToExF = cost -> ToCostingType (Length args)
toExF
}
{-# INLINE makeBuiltinMeaning #-}
toBuiltinRuntime :: UnliftingMode -> cost -> BuiltinMeaning val cost -> BuiltinRuntime val
toBuiltinRuntime :: UnliftingMode
-> cost -> BuiltinMeaning val cost -> BuiltinRuntime val
toBuiltinRuntime UnliftingMode
unlMode cost
cost (BuiltinMeaning TypeScheme val args res
_ FoldArgs args res
_ BuiltinRuntimeOptions (Length args) val cost
runtimeOpts) =
UnliftingMode
-> cost
-> BuiltinRuntimeOptions (Length args) val cost
-> BuiltinRuntime val
forall cost (n :: Peano) val.
UnliftingMode
-> cost -> BuiltinRuntimeOptions n val cost -> BuiltinRuntime val
fromBuiltinRuntimeOptions UnliftingMode
unlMode cost
cost BuiltinRuntimeOptions (Length args) val cost
runtimeOpts
{-# INLINE toBuiltinRuntime #-}
toBuiltinsRuntime
:: (cost ~ CostingPart uni fun, HasConstantIn uni val, ToBuiltinMeaning uni fun)
=> UnliftingMode -> cost -> BuiltinsRuntime fun val
toBuiltinsRuntime :: UnliftingMode -> cost -> BuiltinsRuntime fun val
toBuiltinsRuntime UnliftingMode
unlMode cost
cost =
let arr :: Array fun (BuiltinRuntime val)
arr = (fun -> BuiltinRuntime val) -> Array fun (BuiltinRuntime val)
forall i a. (Bounded i, Enum i, Ix i) => (i -> a) -> Array i a
tabulateArray ((fun -> BuiltinRuntime val) -> Array fun (BuiltinRuntime val))
-> (fun -> BuiltinRuntime val) -> Array fun (BuiltinRuntime val)
forall a b. (a -> b) -> a -> b
$ UnliftingMode
-> cost -> BuiltinMeaning val cost -> BuiltinRuntime val
forall cost val.
UnliftingMode
-> cost -> BuiltinMeaning val cost -> BuiltinRuntime val
toBuiltinRuntime UnliftingMode
unlMode cost
cost (BuiltinMeaning val cost -> BuiltinRuntime val)
-> (fun -> BuiltinMeaning val cost) -> fun -> BuiltinRuntime val
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (fun -> BuiltinMeaning val cost) -> fun -> BuiltinMeaning val cost
forall a. a -> a
inline fun -> BuiltinMeaning val cost
forall (uni :: * -> *) fun val.
(ToBuiltinMeaning uni fun, HasConstantIn uni val) =>
fun -> BuiltinMeaning val (CostingPart uni fun)
toBuiltinMeaning
in
(BuiltinRuntime val
-> BuiltinsRuntime fun val -> BuiltinsRuntime fun val)
-> BuiltinsRuntime fun val
-> Array fun (BuiltinRuntime val)
-> BuiltinsRuntime fun val
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr BuiltinRuntime val
-> BuiltinsRuntime fun val -> BuiltinsRuntime fun val
seq (Array fun (BuiltinRuntime val) -> BuiltinsRuntime fun val
forall fun val.
Array fun (BuiltinRuntime val) -> BuiltinsRuntime fun val
BuiltinsRuntime Array fun (BuiltinRuntime val)
arr) Array fun (BuiltinRuntime val)
arr
{-# INLINE toBuiltinsRuntime #-}