Skip to content

Commit 4712cf3

Browse files
committed
[Builtins] add 'constrTermFromConstrData'
1 parent 08fe5f3 commit 4712cf3

File tree

13 files changed

+130
-20
lines changed

13 files changed

+130
-20
lines changed

plutus-core/plutus-core.cabal

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ library
203203
Data.Aeson.THReader
204204
Data.Functor.Foldable.Monadic
205205
PlutusCore.Builtin.HasConstant
206+
PlutusCore.Builtin.HasConstr
206207
PlutusCore.Builtin.KnownKind
207208
PlutusCore.Builtin.KnownType
208209
PlutusCore.Builtin.KnownTypeAst

plutus-core/plutus-core/src/PlutusCore/Builtin.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ module PlutusCore.Builtin
66

77
import PlutusCore.Builtin.Emitter as Export
88
import PlutusCore.Builtin.HasConstant as Export
9+
import PlutusCore.Builtin.HasConstr as Export
910
import PlutusCore.Builtin.KnownKind as Export
1011
import PlutusCore.Builtin.KnownType as Export
1112
import PlutusCore.Builtin.KnownTypeAst as Export

plutus-core/plutus-core/src/PlutusCore/Builtin/HasConstant.hs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ module PlutusCore.Builtin.HasConstant
1414

1515
import PlutusCore.Builtin.Result
1616
import PlutusCore.Core
17-
import PlutusCore.Name
1817

1918
import Universe
2019

@@ -54,7 +53,7 @@ fromValue :: (HasConstant term, UniOf term `HasTermLevel` a) => a -> term
5453
fromValue = fromValueOf knownUni
5554
{-# INLINE fromValue #-}
5655

57-
instance HasConstant (Term TyName Name uni fun ()) where
56+
instance HasConstant (Term tyname name uni fun ()) where
5857
asConstant (Constant _ val) = pure val
5958
asConstant _ = throwNotAConstant
6059

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{-# LANGUAGE ConstraintKinds #-}
2+
{-# LANGUAGE DataKinds #-}
3+
{-# LANGUAGE FlexibleInstances #-}
4+
{-# LANGUAGE FunctionalDependencies #-}
5+
{-# LANGUAGE InstanceSigs #-}
6+
{-# LANGUAGE LambdaCase #-}
7+
{-# LANGUAGE MultiParamTypeClasses #-}
8+
{-# LANGUAGE TypeApplications #-}
9+
{-# LANGUAGE TypeFamilies #-}
10+
{-# LANGUAGE TypeOperators #-}
11+
{-# LANGUAGE UndecidableInstances #-}
12+
13+
module PlutusCore.Builtin.HasConstr
14+
( ToConstr (..)
15+
) where
16+
17+
import PlutusCore.Builtin.KnownTypeAst
18+
import PlutusCore.Builtin.Polymorphism
19+
import PlutusCore.Core
20+
import PlutusCore.Name
21+
22+
import Data.Proxy
23+
import Data.Word
24+
25+
class ToConstr term where
26+
toConstr
27+
:: forall rep. KnownTypeAst TyName (UniOf term) rep
28+
=> Word64 -> [term] -> Opaque term rep
29+
30+
instance ToConstr (Term TyName name uni fun ()) where
31+
toConstr
32+
:: forall rep. KnownTypeAst TyName uni rep
33+
=> Word64 -> [Term TyName name uni fun ()] -> Opaque (Term TyName name uni fun ()) rep
34+
toConstr ix = Opaque . Constr () (toTypeAst $ Proxy @rep) ix

plutus-core/plutus-core/src/PlutusCore/Builtin/Meaning.hs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import PlutusPrelude
2020

2121
import PlutusCore.Builtin.Elaborate
2222
import PlutusCore.Builtin.HasConstant
23+
import PlutusCore.Builtin.HasConstr
2324
import PlutusCore.Builtin.KnownKind
2425
import PlutusCore.Builtin.KnownType
2526
import PlutusCore.Builtin.KnownTypeAst
@@ -67,7 +68,7 @@ data BuiltinMeaning val cost =
6768
(cost -> BuiltinRuntime val)
6869

6970
-- | Constraints available when defining a built-in function.
70-
type HasMeaningIn uni val = (Typeable val, ExMemoryUsage val, HasConstantIn uni val)
71+
type HasMeaningIn uni val = (Typeable val, ExMemoryUsage val, HasConstantIn uni val, ToConstr val)
7172

7273
-- | A type class for \"each function from a set of built-in functions has a 'BuiltinMeaning'\".
7374
class

plutus-core/plutus-core/src/PlutusCore/Core/Type.hs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,8 @@ type HasTermLevel :: forall a. (GHC.Type -> GHC.Type) -> a -> GHC.Constraint
176176
type HasTermLevel uni = Includes uni
177177

178178
-- | Extract the universe from a type.
179-
type family UniOf a :: GHC.Type -> GHC.Type
179+
type UniOf :: GHC.Type -> GHC.Type -> GHC.Type
180+
type family UniOf a
180181

181182
type instance UniOf (Term tyname name uni fun ann) = uni
182183

plutus-core/plutus-core/src/PlutusCore/Default/Builtins.hs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,11 @@ import PlutusCore.Builtin
2020
import PlutusCore.Data (Data (..))
2121
import PlutusCore.Default.Universe
2222
import PlutusCore.Evaluation.Machine.BuiltinCostModel
23-
import PlutusCore.Evaluation.Machine.ExBudgetStream (ExBudgetStream)
23+
import PlutusCore.Evaluation.Machine.ExBudgetStream (ExBudgetStream (..))
2424
import PlutusCore.Evaluation.Machine.ExMemoryUsage (ExMemoryUsage, LiteralByteSize (..),
2525
memoryUsage, singletonRose)
26-
import PlutusCore.Evaluation.Result (EvaluationResult (..))
26+
import PlutusCore.Evaluation.Result (EvaluationResult (..), evaluationFailure)
27+
import PlutusCore.Name (TyName)
2728
import PlutusCore.Pretty (PrettyConfigPlc)
2829

2930
import PlutusCore.Bitwise.Convert as Convert
@@ -107,6 +108,7 @@ data DefaultFun
107108
-- types, hence we include the name of the data type as a suffix.
108109
| ChooseData
109110
| ConstrData
111+
| ConstrTermFromConstrData
110112
| MapData
111113
| ListData
112114
| IData
@@ -1503,6 +1505,20 @@ instance uni ~ DefaultUni => ToBuiltinMeaning uni DefaultFun where
15031505
constrDataDenotation
15041506
(runCostingFunTwoArguments . paramConstrData)
15051507

1508+
toBuiltinMeaning _semvar ConstrTermFromConstrData =
1509+
let constrTermFromConstrDataDenotation
1510+
:: KnownTypeAst TyName DefaultUni sop => Data -> BuiltinResult (Opaque val sop)
1511+
constrTermFromConstrDataDenotation (Constr iInteger ds) = do
1512+
-- What? Lol, surely there should exist a better way to do it. Looks like we need
1513+
-- to separate a big chunk of 'ReadKnown' into 'ReadKnownConstant' or something.
1514+
iWord64 <- either (BuiltinFailure mempty) pure . readKnown $ fromValue @val iInteger
1515+
pure . toConstr iWord64 $ map fromValue ds
1516+
constrTermFromConstrDataDenotation _ = evaluationFailure
1517+
{-# INLINE constrTermFromConstrDataDenotation #-}
1518+
in makeBuiltinMeaning
1519+
constrTermFromConstrDataDenotation
1520+
(\_ _ -> ExBudgetLast mempty)
1521+
15061522
toBuiltinMeaning _semvar MapData =
15071523
let mapDataDenotation :: [(Data, Data)] -> Data
15081524
mapDataDenotation = Map
@@ -1928,6 +1944,7 @@ instance Flat DefaultFun where
19281944

19291945
IntegerToByteString -> 73
19301946
ByteStringToInteger -> 74
1947+
ConstrTermFromConstrData -> 75
19311948

19321949
decode = go =<< decodeBuiltin
19331950
where go 0 = pure AddInteger
@@ -2005,6 +2022,7 @@ instance Flat DefaultFun where
20052022
go 72 = pure Blake2b_224
20062023
go 73 = pure IntegerToByteString
20072024
go 74 = pure ByteStringToInteger
2025+
go 75 = pure ConstrTermFromConstrData
20082026
go t = fail $ "Failed to decode builtin tag, got: " ++ show t
20092027

20102028
size _ n = n + builtinTagWidth

plutus-core/plutus-core/src/PlutusCore/Default/Universe.hs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,22 @@ instance HasConstantIn DefaultUni term => ReadKnownIn DefaultUni term Word8 wher
418418
_ -> throwing_ _EvaluationFailure
419419
{-# INLINE readKnown #-}
420420

421+
instance KnownTypeAst tyname DefaultUni Word64 where
422+
toTypeAst _ = toTypeAst $ Proxy @Integer
423+
424+
-- See Note [Integral types as Integer].
425+
instance HasConstantIn DefaultUni term => MakeKnownIn DefaultUni term Word64 where
426+
makeKnown = makeKnown . toInteger
427+
{-# INLINE makeKnown #-}
428+
429+
instance HasConstantIn DefaultUni term => ReadKnownIn DefaultUni term Word64 where
430+
readKnown term =
431+
inline readKnownConstant term >>= oneShot \(i :: Integer) ->
432+
case toIntegralSized i of
433+
Just w64 -> pure w64
434+
_ -> throwing_ _EvaluationFailure
435+
{-# INLINE readKnown #-}
436+
421437
-- deriving newtype doesn't work here (or at least not easily), so we have an explicit instance.
422438
instance KnownTypeAst tyname DefaultUni LiteralByteSize where
423439
toTypeAst _ = toTypeAst $ Proxy @Integer

plutus-core/plutus-core/src/PlutusCore/Evaluation/Machine/Ck.hs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@
44
{-# LANGUAGE DeriveAnyClass #-}
55
{-# LANGUAGE ExistentialQuantification #-}
66
{-# LANGUAGE FlexibleInstances #-}
7+
{-# LANGUAGE InstanceSigs #-}
78
{-# LANGUAGE LambdaCase #-}
89
{-# LANGUAGE MultiParamTypeClasses #-}
910
{-# LANGUAGE OverloadedStrings #-}
1011
{-# LANGUAGE RankNTypes #-}
12+
{-# LANGUAGE TypeApplications #-}
1113
{-# LANGUAGE TypeFamilies #-}
1214
{-# LANGUAGE TypeOperators #-}
1315
{-# LANGUAGE UndecidableInstances #-}
@@ -44,6 +46,7 @@ import Control.Monad.ST
4446
import Data.DList (DList)
4547
import Data.DList qualified as DList
4648
import Data.List.Extras (wix)
49+
import Data.Proxy
4750
import Data.STRef
4851
import Data.Text (Text)
4952
import Data.Word
@@ -135,6 +138,12 @@ instance HasConstant (CkValue uni fun) where
135138

136139
fromConstant = VCon
137140

141+
instance ToConstr (CkValue uni fun) where
142+
toConstr
143+
:: forall rep. KnownTypeAst TyName uni rep
144+
=> Word64 -> [CkValue uni fun] -> Opaque (CkValue uni fun) rep
145+
toConstr ix = Opaque . VConstr (toTypeAst $ Proxy @rep) ix
146+
138147
data Frame uni fun
139148
= FrameAwaitArg (CkValue uni fun) -- ^ @[V _]@
140149
| FrameAwaitFunTerm (Term TyName Name uni fun ()) -- ^ @[_ N]@
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
all a. data -> a

0 commit comments

Comments
 (0)