Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support random API from the Anoma stdlib #3129

Merged
merged 11 commits into from
Oct 29, 2024
2 changes: 2 additions & 0 deletions package.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,13 @@ dependencies:
- prettyprinter-ansi-terminal == 1.1.*
- primitive == 0.9.*
- process == 1.6.*
- random == 1.2.*
- safe == 0.3.*
- scientific == 0.3.*
- singletons == 3.0.*
- singletons-base == 3.3.*
- singletons-th == 3.3.*
- splitmix == 0.1.*
- stm == 2.5.*
- Stream == 0.4.*
- string-interpolate == 0.3.*
Expand Down
31 changes: 31 additions & 0 deletions src/Juvix/Compiler/Builtins/Anoma.hs
Original file line number Diff line number Diff line change
Expand Up @@ -220,3 +220,34 @@ checkZeroDelta f = do
delta <- getBuiltinNameScoper l BuiltinAnomaDelta
unless (f ^. axiomType === delta) $
builtinsErrorText (getLoc f) "zeroDelta must be of Delta"

checkAnomaRandomGenerator :: (Members '[Error ScoperError] r) => AxiomDef -> Sem r ()
checkAnomaRandomGenerator d =
unless (isSmallUniverse' (d ^. axiomType)) $
builtinsErrorText (getLoc d) "AnomaRandomGenerator should be in the small universe"

checkAnomaRandomGeneratorInit :: (Members '[Reader BuiltinsTable, Error ScoperError] r) => AxiomDef -> Sem r ()
checkAnomaRandomGeneratorInit f = do
let l = getLoc f
gen <- getBuiltinNameScoper l BuiltinAnomaRandomGenerator
nat_ <- getBuiltinNameScoper l BuiltinNat
unless (f ^. axiomType === (nat_ --> gen)) $
builtinsErrorText l "initRandomGenerator must be of type Nat -> AnomaRandomGenerator"

checkAnomaRandomNextBytes :: (Members '[Reader BuiltinsTable, Error ScoperError] r) => AxiomDef -> Sem r ()
checkAnomaRandomNextBytes f = do
let l = getLoc f
gen <- getBuiltinNameScoper l BuiltinAnomaRandomGenerator
nat_ <- getBuiltinNameScoper l BuiltinNat
bytearray <- getBuiltinNameScoper l BuiltinByteArray
pair_ <- getBuiltinNameScoper l BuiltinPair
unless (f ^. axiomType === (nat_ --> gen --> (pair_ @@ bytearray @@ gen))) $
builtinsErrorText l "nextBytes must be of type Nat -> AnomaRandomGenerator -> Pair ByteArray AnomaRandomGenerator"

checkAnomaRandomSplit :: (Members '[Reader BuiltinsTable, Error ScoperError] r) => AxiomDef -> Sem r ()
checkAnomaRandomSplit f = do
let l = getLoc f
gen <- getBuiltinNameScoper l BuiltinAnomaRandomGenerator
pair_ <- getBuiltinNameScoper l BuiltinPair
unless (f ^. axiomType === (gen --> pair_ @@ gen @@ gen)) $
builtinsErrorText l "randomSplit must be of type AnomaRandomGenerator -> Pair AnomaRandomGenerator AnomaRandomGenerator"
12 changes: 12 additions & 0 deletions src/Juvix/Compiler/Concrete/Data/Builtins.hs
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,10 @@ data BuiltinAxiom
| BuiltinAnomaSubDelta
| BuiltinAnomaProveAction
| BuiltinAnomaProveDelta
| BuiltinAnomaRandomGenerator
| BuiltinAnomaRandomGeneratorInit
| BuiltinAnomaRandomNextBytes
| BuiltinAnomaRandomSplit
| BuiltinPoseidon
| BuiltinEcOp
| BuiltinRandomEcPoint
Expand Down Expand Up @@ -311,6 +315,10 @@ instance HasNameKind BuiltinAxiom where
BuiltinAnomaSubDelta -> KNameFunction
BuiltinAnomaProveAction -> KNameFunction
BuiltinAnomaProveDelta -> KNameFunction
BuiltinAnomaRandomGenerator -> KNameInductive
BuiltinAnomaRandomGeneratorInit -> KNameFunction
BuiltinAnomaRandomNextBytes -> KNameFunction
BuiltinAnomaRandomSplit -> KNameFunction
BuiltinPoseidon -> KNameFunction
BuiltinEcOp -> KNameFunction
BuiltinRandomEcPoint -> KNameFunction
Expand Down Expand Up @@ -378,6 +386,10 @@ instance Pretty BuiltinAxiom where
BuiltinAnomaSubDelta -> Str.anomaSubDelta
BuiltinAnomaProveDelta -> Str.anomaProveDelta
BuiltinAnomaProveAction -> Str.anomaProveAction
BuiltinAnomaRandomGenerator -> Str.anomaRandomGenerator
BuiltinAnomaRandomGeneratorInit -> Str.anomaRandomGeneratorInit
BuiltinAnomaRandomNextBytes -> Str.anomaRandomNextBytes
BuiltinAnomaRandomSplit -> Str.anomaRandomSplit
BuiltinPoseidon -> Str.cairoPoseidon
BuiltinEcOp -> Str.cairoEcOp
BuiltinRandomEcPoint -> Str.cairoRandomEcPoint
Expand Down
3 changes: 3 additions & 0 deletions src/Juvix/Compiler/Core/Evaluator.hs
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,9 @@ geval opts herr tab env0 = eval' env0
OpAnomaZeroDelta -> normalizeOrUnsupported opcode
OpAnomaAddDelta -> normalizeOrUnsupported opcode
OpAnomaSubDelta -> normalizeOrUnsupported opcode
OpAnomaRandomGeneratorInit -> normalizeOrUnsupported opcode
OpAnomaRandomNextBytes -> normalizeOrUnsupported opcode
OpAnomaRandomSplit -> normalizeOrUnsupported opcode
OpPoseidonHash -> poseidonHashOp
OpEc -> ecOp
OpRandomEcPoint -> randomEcPointOp
Expand Down
6 changes: 6 additions & 0 deletions src/Juvix/Compiler/Core/Extra/Base.hs
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,12 @@ mkTypeByteArray i = mkTypePrim i PrimByteArray
mkTypeByteArray' :: Type
mkTypeByteArray' = mkTypeByteArray Info.empty

mkTypeRandomGenerator :: Info -> Type
mkTypeRandomGenerator i = mkTypePrim i PrimRandomGenerator

mkTypeRandomGenerator' :: Type
mkTypeRandomGenerator' = mkTypeRandomGenerator Info.empty

mkDynamic :: Info -> Type
mkDynamic i = NDyn (DynamicTy i)

Expand Down
6 changes: 6 additions & 0 deletions src/Juvix/Compiler/Core/Extra/Utils.hs
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,9 @@ isDebugOp = \case
OpAnomaZeroDelta -> False
OpAnomaAddDelta -> False
OpAnomaSubDelta -> False
OpAnomaRandomGeneratorInit -> False
OpAnomaRandomNextBytes -> False
OpAnomaRandomSplit -> False
OpEc -> False
OpFieldAdd -> False
OpFieldDiv -> False
Expand Down Expand Up @@ -504,6 +507,9 @@ builtinOpArgTypes = \case
OpAnomaZeroDelta -> []
OpAnomaAddDelta -> [mkDynamic', mkDynamic']
OpAnomaSubDelta -> [mkDynamic', mkDynamic']
OpAnomaRandomGeneratorInit -> [mkTypeInteger']
OpAnomaRandomNextBytes -> [mkTypeInteger', mkTypeRandomGenerator']
OpAnomaRandomSplit -> [mkTypeRandomGenerator']
OpPoseidonHash -> [mkDynamic']
OpEc -> [mkDynamic', mkTypeField', mkDynamic']
OpRandomEcPoint -> []
Expand Down
3 changes: 3 additions & 0 deletions src/Juvix/Compiler/Core/Keywords.hs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ import Juvix.Data.Keyword.All
kwAnomaEncode,
kwAnomaProveAction,
kwAnomaProveDelta,
kwAnomaRandomGeneratorInit,
kwAnomaRandomNextBytes,
kwAnomaRandomSplit,
kwAnomaResourceCommitment,
kwAnomaResourceDelta,
kwAnomaResourceKind,
Expand Down
14 changes: 13 additions & 1 deletion src/Juvix/Compiler/Core/Language/Builtins.hs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ data BuiltinOp
| OpAnomaZeroDelta
| OpAnomaAddDelta
| OpAnomaSubDelta
| OpAnomaRandomGeneratorInit
| OpAnomaRandomNextBytes
| OpAnomaRandomSplit
| OpPoseidonHash
| OpEc
| OpRandomEcPoint
Expand Down Expand Up @@ -136,6 +139,9 @@ builtinOpArgsNum = \case
OpAnomaZeroDelta -> 0
OpAnomaAddDelta -> 2
OpAnomaSubDelta -> 2
OpAnomaRandomGeneratorInit -> 1
OpAnomaRandomNextBytes -> 2
OpAnomaRandomSplit -> 1
OpPoseidonHash -> 1
OpEc -> 3
OpRandomEcPoint -> 0
Expand Down Expand Up @@ -198,6 +204,9 @@ builtinIsFoldable = \case
OpAnomaAddDelta -> False
OpAnomaSubDelta -> False
OpAnomaSha256 -> False
OpAnomaRandomGeneratorInit -> False
OpAnomaRandomNextBytes -> False
OpAnomaRandomSplit -> False
OpPoseidonHash -> False
OpEc -> False
OpRandomEcPoint -> False
Expand Down Expand Up @@ -234,7 +243,10 @@ builtinsAnoma =
OpAnomaProveDelta,
OpAnomaZeroDelta,
OpAnomaAddDelta,
OpAnomaSubDelta
OpAnomaSubDelta,
OpAnomaRandomGeneratorInit,
OpAnomaRandomNextBytes,
OpAnomaRandomSplit
]

builtinsUInt8 :: [BuiltinOp]
Expand Down
1 change: 1 addition & 0 deletions src/Juvix/Compiler/Core/Language/Primitives.hs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ data Primitive
| PrimString
| PrimField
| PrimByteArray
| PrimRandomGenerator
deriving stock (Eq, Generic)

primitiveUInt8 :: Primitive
Expand Down
13 changes: 13 additions & 0 deletions src/Juvix/Compiler/Core/Pretty/Base.hs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ instance PrettyCode BuiltinOp where
OpAnomaZeroDelta -> return primZeroDelta
OpAnomaAddDelta -> return primAddDelta
OpAnomaSubDelta -> return primSubDelta
OpAnomaRandomGeneratorInit -> return primRandomGeneratorInit
OpAnomaRandomNextBytes -> return primRandomNextBytes
OpAnomaRandomSplit -> return primRandomSplit
OpPoseidonHash -> return primPoseidonHash
OpEc -> return primEc
OpRandomEcPoint -> return primRandomEcPoint
Expand Down Expand Up @@ -105,6 +108,7 @@ instance PrettyCode Primitive where
PrimBool _ -> return $ annotate (AnnKind KNameInductive) (pretty ("Bool" :: String))
PrimString -> return $ annotate (AnnKind KNameInductive) (pretty ("String" :: String))
PrimByteArray -> return $ annotate (AnnKind KNameInductive) (pretty ("ByteArray" :: String))
PrimRandomGenerator -> return $ annotate (AnnKind KNameInductive) (pretty ("RandomGenerator" :: String))

ppName :: NameKind -> Text -> Sem r (Doc Ann)
ppName kind name = return $ annotate (AnnKind kind) (pretty name)
Expand Down Expand Up @@ -954,6 +958,15 @@ primAddDelta = primitive Str.anomaAddDelta
primSubDelta :: Doc Ann
primSubDelta = primitive Str.anomaSubDelta

primRandomGeneratorInit :: Doc Ann
primRandomGeneratorInit = primitive Str.anomaRandomGeneratorInit

primRandomNextBytes :: Doc Ann
primRandomNextBytes = primitive Str.anomaRandomNextBytes

primRandomSplit :: Doc Ann
primRandomSplit = primitive Str.anomaRandomSplit

primPoseidonHash :: Doc Ann
primPoseidonHash = primitive Str.cairoPoseidon

Expand Down
1 change: 1 addition & 0 deletions src/Juvix/Compiler/Core/Transformation/Check/Cairo.hs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ checkCairo md = do
PrimField {} -> True
PrimString {} -> False
PrimByteArray {} -> False
PrimRandomGenerator {} -> False

isRecordOrList :: TypeConstr -> Bool
isRecordOrList TypeConstr {..} = case ii ^. inductiveBuiltin of
Expand Down
3 changes: 3 additions & 0 deletions src/Juvix/Compiler/Core/Transformation/ComputeTypeInfo.hs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,9 @@ computeNodeTypeInfo md = umapL go
OpAnomaZeroDelta -> mkDynamic'
OpAnomaAddDelta -> mkDynamic'
OpAnomaSubDelta -> mkDynamic'
OpAnomaRandomGeneratorInit -> mkTypeRandomGenerator'
OpAnomaRandomNextBytes -> mkDynamic'
OpAnomaRandomSplit -> mkDynamic'
OpPoseidonHash -> case _builtinAppArgs of
[arg] -> Info.getNodeType arg
_ -> error "incorrect poseidon builtin application"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ convertNode md = umap go
Just (BuiltinTypeAxiom BuiltinField) -> mkTypeField'
Just (BuiltinTypeAxiom BuiltinByte) -> mkTypeUInt8'
Just (BuiltinTypeAxiom BuiltinByteArray) -> mkTypeByteArray'
Just (BuiltinTypeAxiom BuiltinAnomaRandomGenerator) -> mkTypeRandomGenerator'
_ -> node
where
ii = lookupInductiveInfo md _typeConstrSymbol
Expand Down
32 changes: 32 additions & 0 deletions src/Juvix/Compiler/Core/Translation/FromInternal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -662,6 +662,10 @@ goAxiomInductive a = whenJust (a ^. Internal.axiomBuiltin) builtinInductive
Internal.BuiltinAnomaZeroDelta -> return ()
Internal.BuiltinAnomaAddDelta -> return ()
Internal.BuiltinAnomaSubDelta -> return ()
Internal.BuiltinAnomaRandomGenerator -> registerInductiveAxiom (Just BuiltinAnomaRandomGenerator) []
Internal.BuiltinAnomaRandomGeneratorInit -> return ()
Internal.BuiltinAnomaRandomNextBytes -> return ()
Internal.BuiltinAnomaRandomSplit -> return ()
Internal.BuiltinPoseidon -> return ()
Internal.BuiltinEcOp -> return ()
Internal.BuiltinRandomEcPoint -> return ()
Expand Down Expand Up @@ -952,6 +956,30 @@ goAxiomDef a = maybe goAxiomNotBuiltin builtinBody (a ^. Internal.axiomBuiltin)
(mkBuiltinApp' OpAnomaSubDelta [mkVar' 1, mkVar' 0])
)
)
Internal.BuiltinAnomaRandomGenerator -> return ()
Internal.BuiltinAnomaRandomGeneratorInit -> do
natType <- getNatType
registerAxiomDef
( mkLambda'
natType
(mkBuiltinApp' OpAnomaRandomGeneratorInit [mkVar' 0])
)
Internal.BuiltinAnomaRandomNextBytes -> do
natType <- getNatType
registerAxiomDef
( mkLambda'
natType
( mkLambda'
mkDynamic'
(mkBuiltinApp' OpAnomaRandomNextBytes [mkVar' 1, mkVar' 0])
)
)
Internal.BuiltinAnomaRandomSplit -> do
registerAxiomDef
( mkLambda'
mkDynamic'
(mkBuiltinApp' OpAnomaRandomSplit [mkVar' 0])
)
Internal.BuiltinPoseidon -> do
psName <- getPoseidonStateName
psSym <- getPoseidonStateSymbol
Expand Down Expand Up @@ -1407,6 +1435,10 @@ goApplication a = do
Just Internal.BuiltinAnomaSubDelta -> app
Just Internal.BuiltinAnomaProveAction -> app
Just Internal.BuiltinAnomaProveDelta -> app
Just Internal.BuiltinAnomaRandomGenerator -> app
Just Internal.BuiltinAnomaRandomGeneratorInit -> app
Just Internal.BuiltinAnomaRandomNextBytes -> app
Just Internal.BuiltinAnomaRandomSplit -> app
Just Internal.BuiltinPoseidon -> app
Just Internal.BuiltinEcOp -> app
Just Internal.BuiltinRandomEcPoint -> app
Expand Down
3 changes: 3 additions & 0 deletions src/Juvix/Compiler/Core/Translation/FromSource.hs
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,9 @@ builtinAppExpr varsNum vars = do
<|> (kw kwAnomaZeroDelta $> OpAnomaZeroDelta)
<|> (kw kwAnomaAddDelta $> OpAnomaAddDelta)
<|> (kw kwAnomaSubDelta $> OpAnomaSubDelta)
<|> (kw kwAnomaRandomGeneratorInit $> OpAnomaRandomGeneratorInit)
<|> (kw kwAnomaRandomNextBytes $> OpAnomaRandomNextBytes)
<|> (kw kwAnomaRandomSplit $> OpAnomaRandomSplit)

args <- P.many (atom varsNum vars)
return $ mkBuiltinApp' op args
Expand Down
4 changes: 4 additions & 0 deletions src/Juvix/Compiler/Core/Translation/Stripped/FromCore.hs
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,10 @@ fromCore fsize tab =
BuiltinAnomaZeroDelta -> False
BuiltinAnomaProveAction -> False
BuiltinAnomaProveDelta -> False
BuiltinAnomaRandomGenerator -> False
BuiltinAnomaRandomGeneratorInit -> False
BuiltinAnomaRandomNextBytes -> False
BuiltinAnomaRandomSplit -> False
BuiltinPoseidon -> False
BuiltinEcOp -> False
BuiltinRandomEcPoint -> False
Expand Down
4 changes: 4 additions & 0 deletions src/Juvix/Compiler/Internal/Translation/FromConcrete.hs
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,10 @@ checkBuiltinAxiom d b = localBuiltins $ case b of
BuiltinAnomaSubDelta -> checkDeltaBinaryOp d
BuiltinAnomaProveDelta -> checkProveDelta d
BuiltinAnomaProveAction -> checkProveAction d
BuiltinAnomaRandomGenerator -> checkAnomaRandomGenerator d
BuiltinAnomaRandomGeneratorInit -> checkAnomaRandomGeneratorInit d
BuiltinAnomaRandomNextBytes -> checkAnomaRandomNextBytes d
BuiltinAnomaRandomSplit -> checkAnomaRandomSplit d
BuiltinPoseidon -> checkPoseidon d
BuiltinEcOp -> checkEcOp d
BuiltinRandomEcPoint -> checkRandomEcPoint d
Expand Down
12 changes: 12 additions & 0 deletions src/Juvix/Compiler/Nockma/AnomaLib.hs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,18 @@ anomaLibPath = \case
1
]
|]
-- Obtained from the urbit dojo using:
--
-- => rm != |= [seed=@] ~(. og seed)
StdlibRandomInitGen -> [nock| [8 [1 0] [1 8 [9 47 0 31] 10 [6 0 14] 0 2] 0 1] |]
-- obtained from the urbit dojo using:
--
-- => rm != |= [rng=* width=@] (raws:`_og`rng width)
StdlibRandomNextBytes -> [nock| [8 [1 0 0] [1 8 [7 [0 12] 9 4 0 1] 9 2 10 [6 0 29] 0 2] 0 1] |]
-- obtained from the urbit dojo using:
--
-- => rm != |= [rng=*] split:`_og`rng
StdlibRandomSplit -> [nock| [8 [1 0] [1 7 [0 6] 9 21 0 1] 0 1] |]
AnomaLibFunction (AnomaRmFunction f) -> case f of
RmCommit -> [nock| [9 94 0 1] |]
RmNullify -> [nock| [9 350 0 1] |]
Expand Down
6 changes: 6 additions & 0 deletions src/Juvix/Compiler/Nockma/AnomaLib/Base.hs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ data StdlibFunction
| StdlibLengthBytes
| StdlibCurry
| StdlibSha256
| StdlibRandomInitGen
| StdlibRandomNextBytes
| StdlibRandomSplit
deriving stock (Show, Lift, Eq, Bounded, Enum, Generic)

instance Hashable StdlibFunction
Expand Down Expand Up @@ -108,6 +111,9 @@ instance Pretty StdlibFunction where
StdlibLengthBytes -> "length-bytes"
StdlibCurry -> "curry"
StdlibSha256 -> "sha256"
StdlibRandomInitGen -> "random-init"
StdlibRandomNextBytes -> "random-next-bytes"
StdlibRandomSplit -> "random-split"

instance Pretty RmFunction where
pretty = \case
Expand Down
Loading
Loading