-- editorconfig-checker-disable-file
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE LambdaCase     #-}

{- | This module contains the code for handling the various kinds of version that we care about:

* Protocol versions
* Plutus ledger languages
* Plutus Core language versions
-}
module PlutusLedgerApi.Common.Versions
    ( -- * Cardano Protocol versions
      module PlutusLedgerApi.Common.ProtocolVersions
      -- * Plutus ledger languages
    , PlutusLedgerLanguage (..)
      -- * Plutus Core language versions
    , Version (..)
      -- * Version-testing functions
    , ledgerLanguageIntroducedIn
    , ledgerLanguagesAvailableIn
    , plcVersionsIntroducedIn
    , plcVersionsAvailableIn
    , builtinsIntroducedIn
    , builtinsAvailableIn
    , batch1
    , batch2
    , batch3
    , batch4a
    , batch4b
    , batch5
    , batch6
    ) where

import PlutusCore
import PlutusLedgerApi.Common.ProtocolVersions
import PlutusPrelude

import Codec.Serialise.Class (Serialise)
import Data.Map qualified as Map
import Data.Set qualified as Set
import NoThunks.Class (NoThunks)
import PlutusCore.Version (plcVersion100, plcVersion110)
import Prettyprinter

{- Note [New builtins/language versions and protocol versions]

Abbreviations: LL = ledger language, PV = (major) protocol version.

When we add a new builtin to the Plutus language, that is a *backwards-compatible* change.
Old scripts will still work (since they don't use the new builtins), we just make some more
scripts possible.

The same is true for new Plutus Core language versions: adding these is also backwards-compatible.

It would be nice, therefore, to get away with just having one definition of the
set of builtin functions/language features. Then the new features will just
"work". However, this neglects the fact that support for the new feature will be
added in the *software update* that brings a new Plutus ledger language, but
they should only be usable after the corresponding *hard fork*. So there is a
period of time in which the feature must be present in the software but not
usable, so we need to decide this conditionally based on the protocol version.

To do this we need to:
- Know which protocol version a feature was introduced in.
- Given the protocol version, check a program for features that should not be usable yet.

To simplify our lives, we pervasively make the assumption that after a feature
is introduced in a particular ledger language and protocol version, it remains
present in the same ledger language in all later protocol versions (but not
necessarily in other ledger languages; there was previously an assumption that
if a feature was available in a given LL then it would also be available in all
later LLs, but this led to complications when we retrospectively introduced
certain features in earlier LLs).

Note that this doesn't currently handle removals, although it fairly straighforwardly
could do, just by tracking when they were removed.

See also Note [Adding new builtins: protocol versions].
-}

{-| The Plutus ledger language. These are entirely different script languages from the ledger's perspective,
which on our side are interpreted in very similar ways.

It is a simple enumerated datatype (there is no major and minor components as in protocol version)
and the __ordering of constructors__ is essential for deriving Enum,Ord,Bounded.

IMPORTANT: this is different from the Plutus Core language version, `PlutusCore.Version`
-}
data PlutusLedgerLanguage =
      PlutusV1 -- ^ introduced in Alonzo HF
    | PlutusV2 -- ^ introduced in Vasil HF
    | PlutusV3 -- ^ introduced in Chang HF
   deriving stock (PlutusLedgerLanguage -> PlutusLedgerLanguage -> Bool
(PlutusLedgerLanguage -> PlutusLedgerLanguage -> Bool)
-> (PlutusLedgerLanguage -> PlutusLedgerLanguage -> Bool)
-> Eq PlutusLedgerLanguage
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: PlutusLedgerLanguage -> PlutusLedgerLanguage -> Bool
== :: PlutusLedgerLanguage -> PlutusLedgerLanguage -> Bool
$c/= :: PlutusLedgerLanguage -> PlutusLedgerLanguage -> Bool
/= :: PlutusLedgerLanguage -> PlutusLedgerLanguage -> Bool
Eq, Eq PlutusLedgerLanguage
Eq PlutusLedgerLanguage =>
(PlutusLedgerLanguage -> PlutusLedgerLanguage -> Ordering)
-> (PlutusLedgerLanguage -> PlutusLedgerLanguage -> Bool)
-> (PlutusLedgerLanguage -> PlutusLedgerLanguage -> Bool)
-> (PlutusLedgerLanguage -> PlutusLedgerLanguage -> Bool)
-> (PlutusLedgerLanguage -> PlutusLedgerLanguage -> Bool)
-> (PlutusLedgerLanguage
    -> PlutusLedgerLanguage -> PlutusLedgerLanguage)
-> (PlutusLedgerLanguage
    -> PlutusLedgerLanguage -> PlutusLedgerLanguage)
-> Ord PlutusLedgerLanguage
PlutusLedgerLanguage -> PlutusLedgerLanguage -> Bool
PlutusLedgerLanguage -> PlutusLedgerLanguage -> Ordering
PlutusLedgerLanguage
-> PlutusLedgerLanguage -> PlutusLedgerLanguage
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: PlutusLedgerLanguage -> PlutusLedgerLanguage -> Ordering
compare :: PlutusLedgerLanguage -> PlutusLedgerLanguage -> Ordering
$c< :: PlutusLedgerLanguage -> PlutusLedgerLanguage -> Bool
< :: PlutusLedgerLanguage -> PlutusLedgerLanguage -> Bool
$c<= :: PlutusLedgerLanguage -> PlutusLedgerLanguage -> Bool
<= :: PlutusLedgerLanguage -> PlutusLedgerLanguage -> Bool
$c> :: PlutusLedgerLanguage -> PlutusLedgerLanguage -> Bool
> :: PlutusLedgerLanguage -> PlutusLedgerLanguage -> Bool
$c>= :: PlutusLedgerLanguage -> PlutusLedgerLanguage -> Bool
>= :: PlutusLedgerLanguage -> PlutusLedgerLanguage -> Bool
$cmax :: PlutusLedgerLanguage
-> PlutusLedgerLanguage -> PlutusLedgerLanguage
max :: PlutusLedgerLanguage
-> PlutusLedgerLanguage -> PlutusLedgerLanguage
$cmin :: PlutusLedgerLanguage
-> PlutusLedgerLanguage -> PlutusLedgerLanguage
min :: PlutusLedgerLanguage
-> PlutusLedgerLanguage -> PlutusLedgerLanguage
Ord, Int -> PlutusLedgerLanguage -> ShowS
[PlutusLedgerLanguage] -> ShowS
PlutusLedgerLanguage -> String
(Int -> PlutusLedgerLanguage -> ShowS)
-> (PlutusLedgerLanguage -> String)
-> ([PlutusLedgerLanguage] -> ShowS)
-> Show PlutusLedgerLanguage
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> PlutusLedgerLanguage -> ShowS
showsPrec :: Int -> PlutusLedgerLanguage -> ShowS
$cshow :: PlutusLedgerLanguage -> String
show :: PlutusLedgerLanguage -> String
$cshowList :: [PlutusLedgerLanguage] -> ShowS
showList :: [PlutusLedgerLanguage] -> ShowS
Show, (forall x. PlutusLedgerLanguage -> Rep PlutusLedgerLanguage x)
-> (forall x. Rep PlutusLedgerLanguage x -> PlutusLedgerLanguage)
-> Generic PlutusLedgerLanguage
forall x. Rep PlutusLedgerLanguage x -> PlutusLedgerLanguage
forall x. PlutusLedgerLanguage -> Rep PlutusLedgerLanguage x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. PlutusLedgerLanguage -> Rep PlutusLedgerLanguage x
from :: forall x. PlutusLedgerLanguage -> Rep PlutusLedgerLanguage x
$cto :: forall x. Rep PlutusLedgerLanguage x -> PlutusLedgerLanguage
to :: forall x. Rep PlutusLedgerLanguage x -> PlutusLedgerLanguage
Generic, Int -> PlutusLedgerLanguage
PlutusLedgerLanguage -> Int
PlutusLedgerLanguage -> [PlutusLedgerLanguage]
PlutusLedgerLanguage -> PlutusLedgerLanguage
PlutusLedgerLanguage
-> PlutusLedgerLanguage -> [PlutusLedgerLanguage]
PlutusLedgerLanguage
-> PlutusLedgerLanguage
-> PlutusLedgerLanguage
-> [PlutusLedgerLanguage]
(PlutusLedgerLanguage -> PlutusLedgerLanguage)
-> (PlutusLedgerLanguage -> PlutusLedgerLanguage)
-> (Int -> PlutusLedgerLanguage)
-> (PlutusLedgerLanguage -> Int)
-> (PlutusLedgerLanguage -> [PlutusLedgerLanguage])
-> (PlutusLedgerLanguage
    -> PlutusLedgerLanguage -> [PlutusLedgerLanguage])
-> (PlutusLedgerLanguage
    -> PlutusLedgerLanguage -> [PlutusLedgerLanguage])
-> (PlutusLedgerLanguage
    -> PlutusLedgerLanguage
    -> PlutusLedgerLanguage
    -> [PlutusLedgerLanguage])
-> Enum PlutusLedgerLanguage
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: PlutusLedgerLanguage -> PlutusLedgerLanguage
succ :: PlutusLedgerLanguage -> PlutusLedgerLanguage
$cpred :: PlutusLedgerLanguage -> PlutusLedgerLanguage
pred :: PlutusLedgerLanguage -> PlutusLedgerLanguage
$ctoEnum :: Int -> PlutusLedgerLanguage
toEnum :: Int -> PlutusLedgerLanguage
$cfromEnum :: PlutusLedgerLanguage -> Int
fromEnum :: PlutusLedgerLanguage -> Int
$cenumFrom :: PlutusLedgerLanguage -> [PlutusLedgerLanguage]
enumFrom :: PlutusLedgerLanguage -> [PlutusLedgerLanguage]
$cenumFromThen :: PlutusLedgerLanguage
-> PlutusLedgerLanguage -> [PlutusLedgerLanguage]
enumFromThen :: PlutusLedgerLanguage
-> PlutusLedgerLanguage -> [PlutusLedgerLanguage]
$cenumFromTo :: PlutusLedgerLanguage
-> PlutusLedgerLanguage -> [PlutusLedgerLanguage]
enumFromTo :: PlutusLedgerLanguage
-> PlutusLedgerLanguage -> [PlutusLedgerLanguage]
$cenumFromThenTo :: PlutusLedgerLanguage
-> PlutusLedgerLanguage
-> PlutusLedgerLanguage
-> [PlutusLedgerLanguage]
enumFromThenTo :: PlutusLedgerLanguage
-> PlutusLedgerLanguage
-> PlutusLedgerLanguage
-> [PlutusLedgerLanguage]
Enum, PlutusLedgerLanguage
PlutusLedgerLanguage
-> PlutusLedgerLanguage -> Bounded PlutusLedgerLanguage
forall a. a -> a -> Bounded a
$cminBound :: PlutusLedgerLanguage
minBound :: PlutusLedgerLanguage
$cmaxBound :: PlutusLedgerLanguage
maxBound :: PlutusLedgerLanguage
Bounded)
   deriving anyclass (PlutusLedgerLanguage -> ()
(PlutusLedgerLanguage -> ()) -> NFData PlutusLedgerLanguage
forall a. (a -> ()) -> NFData a
$crnf :: PlutusLedgerLanguage -> ()
rnf :: PlutusLedgerLanguage -> ()
NFData, Context -> PlutusLedgerLanguage -> IO (Maybe ThunkInfo)
Proxy PlutusLedgerLanguage -> String
(Context -> PlutusLedgerLanguage -> IO (Maybe ThunkInfo))
-> (Context -> PlutusLedgerLanguage -> IO (Maybe ThunkInfo))
-> (Proxy PlutusLedgerLanguage -> String)
-> NoThunks PlutusLedgerLanguage
forall a.
(Context -> a -> IO (Maybe ThunkInfo))
-> (Context -> a -> IO (Maybe ThunkInfo))
-> (Proxy a -> String)
-> NoThunks a
$cnoThunks :: Context -> PlutusLedgerLanguage -> IO (Maybe ThunkInfo)
noThunks :: Context -> PlutusLedgerLanguage -> IO (Maybe ThunkInfo)
$cwNoThunks :: Context -> PlutusLedgerLanguage -> IO (Maybe ThunkInfo)
wNoThunks :: Context -> PlutusLedgerLanguage -> IO (Maybe ThunkInfo)
$cshowTypeOf :: Proxy PlutusLedgerLanguage -> String
showTypeOf :: Proxy PlutusLedgerLanguage -> String
NoThunks, [PlutusLedgerLanguage] -> Encoding
PlutusLedgerLanguage -> Encoding
(PlutusLedgerLanguage -> Encoding)
-> (forall s. Decoder s PlutusLedgerLanguage)
-> ([PlutusLedgerLanguage] -> Encoding)
-> (forall s. Decoder s [PlutusLedgerLanguage])
-> Serialise PlutusLedgerLanguage
forall s. Decoder s [PlutusLedgerLanguage]
forall s. Decoder s PlutusLedgerLanguage
forall a.
(a -> Encoding)
-> (forall s. Decoder s a)
-> ([a] -> Encoding)
-> (forall s. Decoder s [a])
-> Serialise a
$cencode :: PlutusLedgerLanguage -> Encoding
encode :: PlutusLedgerLanguage -> Encoding
$cdecode :: forall s. Decoder s PlutusLedgerLanguage
decode :: forall s. Decoder s PlutusLedgerLanguage
$cencodeList :: [PlutusLedgerLanguage] -> Encoding
encodeList :: [PlutusLedgerLanguage] -> Encoding
$cdecodeList :: forall s. Decoder s [PlutusLedgerLanguage]
decodeList :: forall s. Decoder s [PlutusLedgerLanguage]
Serialise)

instance Pretty PlutusLedgerLanguage where
    pretty :: forall ann. PlutusLedgerLanguage -> Doc ann
pretty = PlutusLedgerLanguage -> Doc ann
forall a ann. Show a => a -> Doc ann
viaShow

{-| Query the protocol version that a specific Plutus ledger language was first introduced in.
-}
ledgerLanguageIntroducedIn :: PlutusLedgerLanguage -> MajorProtocolVersion
ledgerLanguageIntroducedIn :: PlutusLedgerLanguage -> MajorProtocolVersion
ledgerLanguageIntroducedIn = \case
    PlutusLedgerLanguage
PlutusV1 -> MajorProtocolVersion
alonzoPV
    PlutusLedgerLanguage
PlutusV2 -> MajorProtocolVersion
vasilPV
    PlutusLedgerLanguage
PlutusV3 -> MajorProtocolVersion
changPV

{-| Which Plutus language versions are available in the given
'MajorProtocolVersion'?  See Note [New builtins/language versions and protocol
versions].  This function (and others in this module) assumes that once a LL is
available it remains available in all later PVs and that if m <= n, PlutusVm is
introduced no later than PlutusVn.
-}
ledgerLanguagesAvailableIn :: MajorProtocolVersion -> Set.Set PlutusLedgerLanguage
ledgerLanguagesAvailableIn :: MajorProtocolVersion -> Set PlutusLedgerLanguage
ledgerLanguagesAvailableIn MajorProtocolVersion
searchPv =
  [PlutusLedgerLanguage] -> Set PlutusLedgerLanguage
forall a. Ord a => [a] -> Set a
Set.fromList ([PlutusLedgerLanguage] -> Set PlutusLedgerLanguage)
-> [PlutusLedgerLanguage] -> Set PlutusLedgerLanguage
forall a b. (a -> b) -> a -> b
$ (PlutusLedgerLanguage -> Bool)
-> [PlutusLedgerLanguage] -> [PlutusLedgerLanguage]
forall a. (a -> Bool) -> [a] -> [a]
takeWhile (\PlutusLedgerLanguage
ll -> PlutusLedgerLanguage -> MajorProtocolVersion
ledgerLanguageIntroducedIn PlutusLedgerLanguage
ll MajorProtocolVersion -> MajorProtocolVersion -> Bool
forall a. Ord a => a -> a -> Bool
<= MajorProtocolVersion
searchPv) [PlutusLedgerLanguage]
forall a. (Enum a, Bounded a) => [a]
enumerate

-- | Given a map from PVs to a type `a`, return a `Set a` containing all of the
-- entries with PV <= thisPv
collectUpTo
  :: Ord a
  => Map.Map MajorProtocolVersion (Set.Set a)
  -> MajorProtocolVersion
  -> Set.Set a
collectUpTo :: forall a.
Ord a =>
Map MajorProtocolVersion (Set a) -> MajorProtocolVersion -> Set a
collectUpTo Map MajorProtocolVersion (Set a)
m MajorProtocolVersion
thisPv =
  [Set a] -> Set a
forall m. Monoid m => [m] -> m
forall (t :: * -> *) m. (Foldable t, Monoid m) => t m -> m
fold ([Set a] -> Set a) -> [Set a] -> Set a
forall a b. (a -> b) -> a -> b
$  -- ie, iterated `union`
  Map MajorProtocolVersion (Set a) -> [Set a]
forall k a. Map k a -> [a]
Map.elems (Map MajorProtocolVersion (Set a) -> [Set a])
-> Map MajorProtocolVersion (Set a) -> [Set a]
forall a b. (a -> b) -> a -> b
$ (MajorProtocolVersion -> Bool)
-> Map MajorProtocolVersion (Set a)
-> Map MajorProtocolVersion (Set a)
forall k a. (k -> Bool) -> Map k a -> Map k a
Map.takeWhileAntitone (MajorProtocolVersion -> MajorProtocolVersion -> Bool
forall a. Ord a => a -> a -> Bool
<= MajorProtocolVersion
thisPv) Map MajorProtocolVersion (Set a)
m

{- Batches of builtins which were introduced in the same hard fork (but perhaps
   not for all LLs): see the Plutus Core specification and
   `builtinsIntroducedIn` below.
-}

{- If any new builtins are introduced after a batch has been deployed on the chain
  then a new `batch` object MUST be added to contain them and the
  `builtinsIntroducedIn` function must be updated; the contents of batches which
  have already been deployed must NOT be altered.  Also, remember to UPDATE THE
  TESTS in `Spec.Versions` and `Spec.Data.Versions` when a new batch is added.
-}

{- It's tempting to try something like `fmap toEnum [0..50]` here, but that's
   dangerous because the order of the constructors in DefaultFun doesn't
   precisely match the order that the builtins were introduced in.  A safer
   alternative would be to use the flat tags, but they're not directly
   accessible at the moment.
-}
-- DO NOT CHANGE THIS.
batch1 :: [DefaultFun]
batch1 :: [DefaultFun]
batch1 =
  [ DefaultFun
AddInteger, DefaultFun
SubtractInteger, DefaultFun
MultiplyInteger, DefaultFun
DivideInteger, DefaultFun
QuotientInteger
  , DefaultFun
RemainderInteger, DefaultFun
ModInteger, DefaultFun
EqualsInteger, DefaultFun
LessThanInteger, DefaultFun
LessThanEqualsInteger
  , DefaultFun
AppendByteString, DefaultFun
ConsByteString, DefaultFun
SliceByteString, DefaultFun
LengthOfByteString
  , DefaultFun
IndexByteString, DefaultFun
EqualsByteString, DefaultFun
LessThanByteString, DefaultFun
LessThanEqualsByteString
  , DefaultFun
Sha2_256, DefaultFun
Sha3_256, DefaultFun
Blake2b_256, DefaultFun
VerifyEd25519Signature, DefaultFun
AppendString, DefaultFun
EqualsString
  , DefaultFun
EncodeUtf8, DefaultFun
DecodeUtf8, DefaultFun
IfThenElse, DefaultFun
ChooseUnit, DefaultFun
Trace, DefaultFun
FstPair, DefaultFun
SndPair, DefaultFun
ChooseList
  , DefaultFun
MkCons, DefaultFun
HeadList, DefaultFun
TailList, DefaultFun
NullList, DefaultFun
ChooseData, DefaultFun
ConstrData, DefaultFun
MapData, DefaultFun
ListData
  , DefaultFun
IData, DefaultFun
BData, DefaultFun
UnConstrData, DefaultFun
UnMapData, DefaultFun
UnListData, DefaultFun
UnIData, DefaultFun
UnBData, DefaultFun
EqualsData
  , DefaultFun
MkPairData, DefaultFun
MkNilData, DefaultFun
MkNilPairData
  ]

-- DO NOT CHANGE THIS.
batch2 :: [DefaultFun]
batch2 :: [DefaultFun]
batch2 =
  [ DefaultFun
SerialiseData ]

-- DO NOT CHANGE THIS.
batch3 :: [DefaultFun]
batch3 :: [DefaultFun]
batch3 =
  [ DefaultFun
VerifyEcdsaSecp256k1Signature, DefaultFun
VerifySchnorrSecp256k1Signature ]

-- `cekCase` and `cekConstr` costs come between Batch 3 and Batch 4 in the
-- PlutusV3 cost model parameters, although that's irrelevant here.

-- batch4, excluding IntegerToByteString and ByteStringToInteger.
-- DO NOT CHANGE THIS.
batch4a :: [DefaultFun]
batch4a :: [DefaultFun]
batch4a =
  [ DefaultFun
Bls12_381_G1_add, DefaultFun
Bls12_381_G1_neg, DefaultFun
Bls12_381_G1_scalarMul
  , DefaultFun
Bls12_381_G1_equal, DefaultFun
Bls12_381_G1_hashToGroup
  , DefaultFun
Bls12_381_G1_compress, DefaultFun
Bls12_381_G1_uncompress
  , DefaultFun
Bls12_381_G2_add, DefaultFun
Bls12_381_G2_neg, DefaultFun
Bls12_381_G2_scalarMul
  , DefaultFun
Bls12_381_G2_equal, DefaultFun
Bls12_381_G2_hashToGroup
  , DefaultFun
Bls12_381_G2_compress, DefaultFun
Bls12_381_G2_uncompress
  , DefaultFun
Bls12_381_millerLoop, DefaultFun
Bls12_381_mulMlResult, DefaultFun
Bls12_381_finalVerify
  , DefaultFun
Keccak_256, DefaultFun
Blake2b_224
  ]

{- batch4b: IntegerToByteString and ByteStringToInteger.  These were enabled in
 PlutusV3 at PV9, along with batch4a, They were enabled in PlutusV2 at PV10 in
 #6056 and #6065.  They are available on the chain, but they're prohibitively
 expensive because the proposal to update the relevant protocol parameters has
 not (yet) been enacted.  This has left a "gap" in the cost model paramters: for
 PlutusV3, the parameters for Batch 3 are followed those for 4a, then 4b, but
 for PlutusV2 those for Batch3 are followed by those for Batch 4a, and those for
 4b aren't in use yet.  Since you can't actually use the 4b builtins in PlutusV2
 at the moment, it's tempting to insert the 4a parameter before the 4b
 parameters and enable them all at PV11 and with a suitable parameter update.
 However, if we do do this there's a theoretical risk of turning a phase 2
 failure into a phase 1 failure: would that be problematic?
-}
-- DO NOT CHANGE THIS.
batch4b :: [DefaultFun]
batch4b :: [DefaultFun]
batch4b =
  [ DefaultFun
IntegerToByteString, DefaultFun
ByteStringToInteger ]

-- DO NOT CHANGE THIS.
batch4 :: [DefaultFun]
batch4 :: [DefaultFun]
batch4 = [DefaultFun]
batch4a [DefaultFun] -> [DefaultFun] -> [DefaultFun]
forall a. [a] -> [a] -> [a]
++ [DefaultFun]
batch4b

-- DO NOT CHANGE THIS.
batch5 :: [DefaultFun]
batch5 :: [DefaultFun]
batch5 =
  [ DefaultFun
AndByteString, DefaultFun
OrByteString, DefaultFun
XorByteString, DefaultFun
ComplementByteString
  , DefaultFun
ReadBit, DefaultFun
WriteBits, DefaultFun
ReplicateByte
  , DefaultFun
ShiftByteString, DefaultFun
RotateByteString, DefaultFun
CountSetBits, DefaultFun
FindFirstSetBit
  , DefaultFun
Ripemd_160
  ]

batch6 :: [DefaultFun]
batch6 :: [DefaultFun]
batch6 =
  [ DefaultFun
ExpModInteger, DefaultFun
DropList
  , DefaultFun
LengthOfArray, DefaultFun
ListToArray, DefaultFun
IndexArray
  ]

{-| Given a ledger language, return a map indicating which builtin functions were
  introduced in which 'MajorProtocolVersion'.  This __must__ be updated when new
  builtins are added.  It is not necessary to add entries for protocol versions
  where no new builtins are added.  See Note [New builtins/language versions and
  protocol versions]
-}
builtinsIntroducedIn :: PlutusLedgerLanguage -> Map.Map MajorProtocolVersion (Set.Set DefaultFun)
builtinsIntroducedIn :: PlutusLedgerLanguage -> Map MajorProtocolVersion (Set DefaultFun)
builtinsIntroducedIn =
  \case
    PlutusLedgerLanguage
PlutusV1 ->
      [(MajorProtocolVersion, Set DefaultFun)]
-> Map MajorProtocolVersion (Set DefaultFun)
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList
      [ (MajorProtocolVersion
alonzoPV, [DefaultFun] -> Set DefaultFun
forall a. Ord a => [a] -> Set a
Set.fromList [DefaultFun]
batch1)
      , (MajorProtocolVersion
pv11PV,   [DefaultFun] -> Set DefaultFun
forall a. Ord a => [a] -> Set a
Set.fromList ([DefaultFun]
batch2 [DefaultFun] -> [DefaultFun] -> [DefaultFun]
forall a. [a] -> [a] -> [a]
++ [DefaultFun]
batch3 [DefaultFun] -> [DefaultFun] -> [DefaultFun]
forall a. [a] -> [a] -> [a]
++ [DefaultFun]
batch4 [DefaultFun] -> [DefaultFun] -> [DefaultFun]
forall a. [a] -> [a] -> [a]
++ [DefaultFun]
batch5 [DefaultFun] -> [DefaultFun] -> [DefaultFun]
forall a. [a] -> [a] -> [a]
++ [DefaultFun]
batch6))
      ]
    PlutusLedgerLanguage
PlutusV2 ->
      [(MajorProtocolVersion, Set DefaultFun)]
-> Map MajorProtocolVersion (Set DefaultFun)
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList
      [ (MajorProtocolVersion
vasilPV,     [DefaultFun] -> Set DefaultFun
forall a. Ord a => [a] -> Set a
Set.fromList ([DefaultFun]
batch1 [DefaultFun] -> [DefaultFun] -> [DefaultFun]
forall a. [a] -> [a] -> [a]
++ [DefaultFun]
batch2))
      , (MajorProtocolVersion
valentinePV, [DefaultFun] -> Set DefaultFun
forall a. Ord a => [a] -> Set a
Set.fromList [DefaultFun]
batch3)
      , (MajorProtocolVersion
plominPV,    [DefaultFun] -> Set DefaultFun
forall a. Ord a => [a] -> Set a
Set.fromList [DefaultFun]
batch4b)
      , (MajorProtocolVersion
pv11PV ,     [DefaultFun] -> Set DefaultFun
forall a. Ord a => [a] -> Set a
Set.fromList ([DefaultFun]
batch4a [DefaultFun] -> [DefaultFun] -> [DefaultFun]
forall a. [a] -> [a] -> [a]
++ [DefaultFun]
batch5 [DefaultFun] -> [DefaultFun] -> [DefaultFun]
forall a. [a] -> [a] -> [a]
++ [DefaultFun]
batch6))
      ]
    PlutusLedgerLanguage
PlutusV3 ->
      [(MajorProtocolVersion, Set DefaultFun)]
-> Map MajorProtocolVersion (Set DefaultFun)
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList
      [ (MajorProtocolVersion
changPV,  [DefaultFun] -> Set DefaultFun
forall a. Ord a => [a] -> Set a
Set.fromList ([DefaultFun]
batch1 [DefaultFun] -> [DefaultFun] -> [DefaultFun]
forall a. [a] -> [a] -> [a]
++ [DefaultFun]
batch2 [DefaultFun] -> [DefaultFun] -> [DefaultFun]
forall a. [a] -> [a] -> [a]
++ [DefaultFun]
batch3 [DefaultFun] -> [DefaultFun] -> [DefaultFun]
forall a. [a] -> [a] -> [a]
++ [DefaultFun]
batch4))
      , (MajorProtocolVersion
plominPV, [DefaultFun] -> Set DefaultFun
forall a. Ord a => [a] -> Set a
Set.fromList [DefaultFun]
batch5)
      , (MajorProtocolVersion
pv11PV,   [DefaultFun] -> Set DefaultFun
forall a. Ord a => [a] -> Set a
Set.fromList [DefaultFun]
batch6)
      ]

{- | Return a set containing the builtins which are available in a given LL in a
given PV.  All builtins are available in all LLs from `pv11PV` onwards. -}
builtinsAvailableIn :: PlutusLedgerLanguage -> MajorProtocolVersion -> Set.Set DefaultFun
builtinsAvailableIn :: PlutusLedgerLanguage -> MajorProtocolVersion -> Set DefaultFun
builtinsAvailableIn = Map MajorProtocolVersion (Set DefaultFun)
-> MajorProtocolVersion -> Set DefaultFun
forall a.
Ord a =>
Map MajorProtocolVersion (Set a) -> MajorProtocolVersion -> Set a
collectUpTo (Map MajorProtocolVersion (Set DefaultFun)
 -> MajorProtocolVersion -> Set DefaultFun)
-> (PlutusLedgerLanguage
    -> Map MajorProtocolVersion (Set DefaultFun))
-> PlutusLedgerLanguage
-> MajorProtocolVersion
-> Set DefaultFun
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PlutusLedgerLanguage -> Map MajorProtocolVersion (Set DefaultFun)
builtinsIntroducedIn


{-| A map indicating which Plutus Core versions were introduced in which
'MajorProtocolVersion' and 'PlutusLedgerLanguage'. Each version should appear at most once.
This __must__ be updated when new versions are added.
See Note [New builtins/language versions and protocol versions]
-}
plcVersionsIntroducedIn :: PlutusLedgerLanguage -> Map.Map MajorProtocolVersion (Set.Set Version)
plcVersionsIntroducedIn :: PlutusLedgerLanguage -> Map MajorProtocolVersion (Set Version)
plcVersionsIntroducedIn =
  \case
    PlutusLedgerLanguage
PlutusV1 ->
      [(MajorProtocolVersion, Set Version)]
-> Map MajorProtocolVersion (Set Version)
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList
      [ (MajorProtocolVersion
alonzoPV, [Version] -> Set Version
forall a. Ord a => [a] -> Set a
Set.fromList [ Version
plcVersion100 ])
      , (MajorProtocolVersion
pv11PV,   [Version] -> Set Version
forall a. Ord a => [a] -> Set a
Set.fromList [ Version
plcVersion110 ])
      ]
    PlutusLedgerLanguage
PlutusV2 ->
      [(MajorProtocolVersion, Set Version)]
-> Map MajorProtocolVersion (Set Version)
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList
      [ (MajorProtocolVersion
alonzoPV, [Version] -> Set Version
forall a. Ord a => [a] -> Set a
Set.fromList [ Version
plcVersion100 ])
      , (MajorProtocolVersion
pv11PV,   [Version] -> Set Version
forall a. Ord a => [a] -> Set a
Set.fromList [ Version
plcVersion110 ])
      ]
    PlutusLedgerLanguage
PlutusV3 ->
      [(MajorProtocolVersion, Set Version)]
-> Map MajorProtocolVersion (Set Version)
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList
      [(MajorProtocolVersion
changPV, [Version] -> Set Version
forall a. Ord a => [a] -> Set a
Set.fromList [ Version
plcVersion110 ])
      ]

{-| Which Plutus Core language versions are available in the given 'PlutusLedgerLanguage'
and 'MajorProtocolVersion'? -}
plcVersionsAvailableIn :: PlutusLedgerLanguage -> MajorProtocolVersion -> Set.Set Version
plcVersionsAvailableIn :: PlutusLedgerLanguage -> MajorProtocolVersion -> Set Version
plcVersionsAvailableIn = Map MajorProtocolVersion (Set Version)
-> MajorProtocolVersion -> Set Version
forall a.
Ord a =>
Map MajorProtocolVersion (Set a) -> MajorProtocolVersion -> Set a
collectUpTo (Map MajorProtocolVersion (Set Version)
 -> MajorProtocolVersion -> Set Version)
-> (PlutusLedgerLanguage -> Map MajorProtocolVersion (Set Version))
-> PlutusLedgerLanguage
-> MajorProtocolVersion
-> Set Version
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PlutusLedgerLanguage -> Map MajorProtocolVersion (Set Version)
plcVersionsIntroducedIn