Skip to content

Commit

Permalink
Rename DataMap to Data.AssocList
Browse files Browse the repository at this point in the history
Signed-off-by: Ana Pantilie <ana.pantilie95@gmail.com>
  • Loading branch information
ana-pantilie committed Apr 25, 2024
1 parent 99ea5fc commit fc7c0c1
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 98 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ import PlutusTx.Prelude (AdditiveGroup ((-)), AdditiveSemigroup ((+)), Bool (..)

import PlutusLedgerApi.V2 qualified as Val
import PlutusTx.Builtins qualified as Builtins
import PlutusTx.DataMap qualified as Map
import PlutusTx.Data.AssocList qualified as AssocList
import Prelude qualified as Haskell


Expand Down Expand Up @@ -279,7 +279,7 @@ evalValue env state value = let
-- Marlowe's Isabelle semantics given the precondition that
-- the initial state's `choices` in Isabelle was sorted and
-- did not contain duplicate entries.
case Map.lookup choiceId (choices state) of
case AssocList.lookup choiceId (choices state) of
Just x -> x
Nothing -> 0
TimeIntervalStart -> getPOSIXTime (fst (timeInterval env))
Expand All @@ -290,7 +290,7 @@ evalValue env state value = let
-- Marlowe's Isabelle semantics given the precondition that
-- the initial state's `boundValues` in Isabelle was sorted
-- and did not contain duplicate entries.
case Map.lookup valId (boundValues state) of
case AssocList.lookup valId (boundValues state) of
Just x -> x
Nothing -> 0
Cond cond thn els -> if evalObservation env state cond then eval thn else eval els
Expand All @@ -310,7 +310,7 @@ evalObservation env state obs = let
-- to Marlowe's Isabelle semantics given the precondition that
-- the initial state's `choices` in Isabelle was sorted and did
-- not contain duplicate entries.
ChoseSomething choiceId -> choiceId `Map.member` choices state
ChoseSomething choiceId -> choiceId `AssocList.member` choices state
ValueGE lhs rhs -> evalVal lhs >= evalVal rhs
ValueGT lhs rhs -> evalVal lhs > evalVal rhs
ValueLT lhs rhs -> evalVal lhs < evalVal rhs
Expand All @@ -323,7 +323,7 @@ evalObservation env state obs = let
-- | Pick the first account with money in it.
refundOne :: Accounts -> Maybe ((Party, Token, Integer), Accounts)
refundOne accounts =
if Map.null accounts
if AssocList.null accounts
then Nothing
else
-- SCP-5126: The return value of this function differs from
Expand All @@ -332,7 +332,7 @@ refundOne accounts =
-- lexicographically ordered one. Also, the sequence
-- `Map.fromList . tail . Map.toList` preserves the
-- invariants of order and non-duplication.
let (((accId, token), balance), rest) = Map.unsafeUncons accounts
let (((accId, token), balance), rest) = AssocList.unsafeUncons accounts
in if balance > 0
then Just ((accId, token, balance), rest)
else refundOne rest
Expand All @@ -345,7 +345,7 @@ moneyInAccount accId token accounts =
-- Marlowe's Isabelle semantics given the precondition that
-- the initial state's `accounts` in Isabelle was sorted and
-- did not contain duplicate entries.
case Map.lookup (accId, token) accounts of
case AssocList.lookup (accId, token) accounts of
Just x -> x
Nothing -> 0

Expand All @@ -359,7 +359,7 @@ updateMoneyInAccount accId token amount =
-- Isabelle semantics given the precondition that the initial
-- state's `accounts` in Isabelle was sorted and did not
-- contain duplicate entries.
if amount <= 0 then Map.delete (accId, token) else Map.insert (accId, token) amount
if amount <= 0 then AssocList.delete (accId, token) else AssocList.insert (accId, token) amount


-- | Add the given amount of money to an account (only if it is positive).
Expand Down Expand Up @@ -439,13 +439,13 @@ reduceContractStep env state contract = case contract of
-- (aside from internal ordering) to Marlowe's Isabelle semantics
-- given the precondition that the initial state's `boundValues`
-- in Isabelle was sorted and did not contain duplicate entries.
newState = state { boundValues = Map.insert valId evaluatedValue boundVals }
newState = state { boundValues = AssocList.insert valId evaluatedValue boundVals }
-- SCP-5126: Given the precondition that `boundValues` contains
-- no duplicate entries, this lookup behaves identically to
-- Marlowe's Isabelle semantics given the precondition that the
-- initial state's `boundValues` in Isabelle was sorted and did
-- not contain duplicate entries.
warn = case Map.lookup valId boundVals of
warn = case AssocList.lookup valId boundVals of
Just oldVal -> ReduceShadowing valId oldVal evaluatedValue
Nothing -> ReduceNoWarning
in Reduced warn ReduceNoPayment newState cont
Expand Down Expand Up @@ -502,7 +502,7 @@ applyAction _ state (IChoice choId1 choice) (Choice choId2 bounds) =
-- from internal ordering) to Marlowe's Isabelle semantics
-- given the precondition that the initial state's `choices`
-- in Isabelle was sorted and did not contain duplicate entries.
then let newState = state { choices = Map.insert choId1 choice (choices state) }
then let newState = state { choices = AssocList.insert choId1 choice (choices state) }
in AppliedAction ApplyNoWarning newState
else NotAppliedAction
applyAction env state INotify (Notify obs)
Expand Down Expand Up @@ -624,7 +624,7 @@ computeTransaction tx state contract = let
in case fixInterval (txInterval tx) state of
IntervalTrimmed env fixState -> case applyAllInputs env fixState contract inputs of
ApplyAllSuccess reduced warnings payments newState cont ->
if not reduced && (notClose contract || (Map.null $ accounts state))
if not reduced && (notClose contract || (AssocList.null $ accounts state))
then Error TEUselessTransaction
else TransactionOutput { txOutWarnings = warnings
, txOutPayments = payments
Expand Down Expand Up @@ -684,12 +684,12 @@ contractLifespanUpperBound contract = case contract of
totalBalance :: Accounts -> Money
totalBalance accounts = foldMap
(\((_, Token cur tok), balance) -> Val.singleton cur tok balance)
(Map.toList accounts)
(AssocList.toList accounts)


-- | Check that all accounts have positive balance.
allBalancesArePositive :: State -> Bool
allBalancesArePositive State{..} = all (\(_, balance) -> balance > 0) (Map.toList accounts)
allBalancesArePositive State{..} = all (\(_, balance) -> balance > 0) (AssocList.toList accounts)


instance Eq Payment where
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ import GHC.Generics (Generic)
import PlutusBenchmark.Marlowe.Core.V1.Semantics.Types.Address (Network)
import PlutusLedgerApi.V2 (CurrencySymbol, POSIXTime (..), TokenName)
import PlutusTx.AsData (asData)
import PlutusTx.DataMap (Map)
import PlutusTx.Data.AssocList (AssocList)
import PlutusTx.IsData (FromData, ToData, UnsafeFromData, makeIsDataIndexed, unstableMakeIsData)
import PlutusTx.Lift (makeLift)
import PlutusTx.Prelude (Bool (..), BuiltinByteString, Eq (..), Integer, Ord ((<=), (>=)), any,
Expand All @@ -52,7 +52,7 @@ import PlutusTx.Prelude (Bool (..), BuiltinByteString, Eq (..), Integer, Ord ((<
import PlutusLedgerApi.V1.Value qualified as Val
import PlutusLedgerApi.V2 qualified as Ledger (Address (..), Credential (..), PubKeyHash (..),
ScriptHash (..), StakingCredential (..))
import PlutusTx.DataMap qualified as Map
import PlutusTx.Data.AssocList qualified as AssocList
import Prelude qualified as Haskell

deriving stock instance Data POSIXTime
Expand Down Expand Up @@ -109,7 +109,7 @@ asData
|]

-- | The accounts in a contract.
type Accounts = Map (AccountId, Token) Integer
type Accounts = AssocList (AccountId, Token) Integer

-- | Values, as defined using Let ar e identified by name,
-- and can be used by 'UseValue' construct.
Expand Down Expand Up @@ -300,8 +300,8 @@ asData
[d|
-- | Marlowe contract internal state. Stored in a /Datum/ of a transaction output.
data State = State { accounts :: Accounts
, choices :: Map ChoiceId ChosenNum
, boundValues :: Map ValueId Integer
, choices :: AssocList ChoiceId ChosenNum
, boundValues :: AssocList ValueId Integer
, minTime :: POSIXTime }
deriving stock (Generic, Data)
deriving newtype (ToData, FromData, UnsafeFromData, Haskell.Eq, Haskell.Ord, Haskell.Show, Eq)
Expand Down Expand Up @@ -359,9 +359,9 @@ data IntervalResult = IntervalTrimmed Environment State
-- | Empty State for a given minimal 'POSIXTime'
emptyState :: POSIXTime -> State
emptyState sn = State
{ accounts = Map.empty
, choices = Map.empty
, boundValues = Map.empty
{ accounts = AssocList.empty
, choices = AssocList.empty
, boundValues = AssocList.empty
, minTime = sn }
{-# INLINABLE emptyState #-}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ import PlutusLedgerApi.V1.Value qualified as Val
import PlutusLedgerApi.V2 qualified as Ledger (Address (Address))
import PlutusTx qualified
import PlutusTx.AssocMap qualified as AssocMap
import PlutusTx.DataMap qualified as Map
import PlutusTx.Data.AssocList qualified as Data.AssocList
import PlutusTx.Trace (traceError, traceIfFalse)
import Prelude qualified as Haskell

Expand Down Expand Up @@ -270,11 +270,11 @@ mkMarloweValidator
-- [Marlowe-Cardano Specification: "Constraint 18. Final balance."]
traceIfFalse ("v" <> tag) (totalBalance accounts == expected)
-- [Marlowe-Cardano Specification: "Constraint 13. Positive balances".]
&& traceIfFalse ("b" <> tag) (Map.all (> 0) accounts)
&& traceIfFalse ("b" <> tag) (Data.AssocList.all (> 0) accounts)
-- [Marlowe-Cardano Specification: "Constraint 19. No duplicates".]
&& traceIfFalse ("ea" <> tag) (Map.noDuplicateKeys accounts)
&& traceIfFalse ("ec" <> tag) (Map.noDuplicateKeys choices)
&& traceIfFalse ("eb" <> tag) (Map.noDuplicateKeys boundValues)
&& traceIfFalse ("ea" <> tag) (Data.AssocList.noDuplicateKeys accounts)
&& traceIfFalse ("ec" <> tag) (Data.AssocList.noDuplicateKeys choices)
&& traceIfFalse ("eb" <> tag) (Data.AssocList.noDuplicateKeys boundValues)

-- Look up the Datum hash for specific data.
findDatumHash' :: PlutusTx.ToData o => o -> Maybe DatumHash
Expand Down
32 changes: 16 additions & 16 deletions plutus-ledger-api/src/PlutusLedgerApi/Data/V1/Value.hs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ module PlutusLedgerApi.Data.V1.Value where
import PlutusLedgerApi.V1.Value hiding (Value (..))
import PlutusTx qualified
import PlutusTx.Builtins.Internal qualified as BI
import PlutusTx.DataMap (Map)
import PlutusTx.DataMap qualified as Map
import PlutusTx.Data.AssocList (AssocList)
import PlutusTx.Data.AssocList qualified as AssocList
import PlutusTx.Prelude as PlutusTx

import Prelude qualified as Haskell

newtype Value = Value {getValue :: Map.Map CurrencySymbol (Map.Map TokenName Integer)}
newtype Value = Value {getValue :: AssocList CurrencySymbol (AssocList TokenName Integer)}
deriving stock (Haskell.Show)
deriving newtype (PlutusTx.ToData, PlutusTx.FromData, PlutusTx.UnsafeFromData)

Expand Down Expand Up @@ -65,8 +65,8 @@ unordEqWith ::
) =>
(a -> Bool) ->
(a -> a -> Bool) ->
Map k a ->
Map k a ->
AssocList k a ->
AssocList k a ->
Bool
unordEqWith is0 eqV = goBoth
where
Expand All @@ -75,13 +75,13 @@ unordEqWith is0 eqV = goBoth
-- One spine is longer than the other one, but this still can result in a
-- succeeding equality.
-- check if the non-empty list only contains zero values.
| Map.null kvsL = Map.all is0 kvsR
| AssocList.null kvsL = AssocList.all is0 kvsR
-- Symmetric to the previous case.
| Map.null kvsR = Map.all is0 kvsL
| AssocList.null kvsR = AssocList.all is0 kvsL
-- Both spines are non-empty.
| otherwise =
let ((kL, vL), kvsL') = Map.unsafeUncons kvsL
(kvR0@(kR0, vR0), kvsR0') = Map.unsafeUncons kvsR
let ((kL, vL), kvsL') = AssocList.unsafeUncons kvsL
(kvR0@(kR0, vR0), kvsR0') = AssocList.unsafeUncons kvsR
in if
-- We could've avoided having this clause if we always searched for the
-- right key-value pair using @goRight@, however the sheer act of invoking
Expand All @@ -94,26 +94,26 @@ unordEqWith is0 eqV = goBoth
| kL == kR0 -> if vL `eqV` vR0 then goBoth kvsL' kvsR0' else False
| is0 vL -> goBoth kvsL' kvsR
| otherwise ->
let reassemble :: [(k, a)] -> Map k a -> Map k a
let reassemble :: [(k, a)] -> AssocList k a -> AssocList k a
reassemble [] m = m
reassemble ((k, a) : xs) m =
let tl = Map.toBuiltinList m
let tl = AssocList.toBuiltinList m
hd =
BI.mkPairData
(PlutusTx.toBuiltinData k)
(PlutusTx.toBuiltinData a)
in reassemble xs (Map.unsafeFromBuiltinList (BI.mkCons hd tl))
in reassemble xs (AssocList.unsafeFromBuiltinList (BI.mkCons hd tl))

-- Recurse on the spine of the right list looking for a key-value
-- pair whose key matches @kL@, i.e. the first key in the remaining
-- part of the left list. The accumulator contains (in reverse order)
-- all elements of the right list processed so far whose keys are not
-- equal to @kL@ and values are non-zero.
goRight :: [(k, a)] -> Map k a -> Bool
goRight :: [(k, a)] -> AssocList k a -> Bool
goRight acc kvsR1'
| Map.null kvsR1' = False
| AssocList.null kvsR1' = False
| otherwise =
let (kvR@(kR, vR), kvsR') = Map.unsafeUncons kvsR1'
let (kvR@(kR, vR), kvsR') = AssocList.unsafeUncons kvsR1'
in if kL == kR
then
if vL `eqV` vR
Expand All @@ -131,4 +131,4 @@ currency have multiple entries.
-}
eq :: Value -> Value -> Bool
eq (Value currs1) (Value currs2) =
unordEqWith (Map.all (0 ==)) (unordEqWith (0 ==) (==)) currs1 currs2
unordEqWith (AssocList.all (0 ==)) (unordEqWith (0 ==) (==)) currs1 currs2
31 changes: 17 additions & 14 deletions plutus-tx-plugin/test/Map/Spec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,14 @@

module Map.Spec where

-- TODO: name module to Data.AssocList.Spec? Or keep as is and add tests for AssocMap as well

import Test.Tasty.Extras

import PlutusTx.Builtins qualified as PlutusTx
import PlutusTx.Code
import PlutusTx.DataMap qualified as Map
import PlutusTx.Data.AssocList (AssocList)
import PlutusTx.Data.AssocList qualified as AssocList
import PlutusTx.Lift (liftCodeDef)
import PlutusTx.Prelude qualified as PlutusTx
import PlutusTx.Show qualified as PlutusTx
Expand Down Expand Up @@ -52,18 +55,18 @@ map1 =
$$( compile
[||
\n ->
let m :: Map.Map Integer PlutusTx.BuiltinByteString
let m :: AssocList Integer PlutusTx.BuiltinByteString
m =
foldr
(\i -> Map.insert (n PlutusTx.+ i) (PlutusTx.encodeUtf8 (PlutusTx.show i)))
(Map.singleton n "0")
(\i -> AssocList.insert (n PlutusTx.+ i) (PlutusTx.encodeUtf8 (PlutusTx.show i)))
(AssocList.singleton n "0")
(PlutusTx.enumFromTo 1 10)
m' = Map.delete (n PlutusTx.+ 5) m
in ( Map.lookup n m
, Map.lookup (n PlutusTx.+ 5) m
, Map.lookup (n PlutusTx.+ 10) m
, Map.lookup (n PlutusTx.+ 20) m
, Map.lookup (n PlutusTx.+ 5) m'
m' = AssocList.delete (n PlutusTx.+ 5) m
in ( AssocList.lookup n m
, AssocList.lookup (n PlutusTx.+ 5) m
, AssocList.lookup (n PlutusTx.+ 10) m
, AssocList.lookup (n PlutusTx.+ 20) m
, AssocList.lookup (n PlutusTx.+ 5) m'
)
||]
)
Expand All @@ -74,21 +77,21 @@ map2 =
[||
\n ->
let m1 =
Map.unsafeFromList
AssocList.unsafeFromList
[ (n PlutusTx.+ 1, "one")
, (n PlutusTx.+ 2, "two")
, (n PlutusTx.+ 3, "three")
, (n PlutusTx.+ 4, "four")
, (n PlutusTx.+ 5, "five")
]
m2 =
Map.unsafeFromList
AssocList.unsafeFromList
[ (n PlutusTx.+ 3, "THREE")
, (n PlutusTx.+ 4, "FOUR")
, (n PlutusTx.+ 6, "SIX")
, (n PlutusTx.+ 7, "SEVEN")
]
m = Map.unionWith PlutusTx.appendByteString m1 m2
in PlutusTx.fmap (\(k, v) -> (k, PlutusTx.decodeUtf8 v)) (Map.toList m)
m = AssocList.unionWith PlutusTx.appendByteString m1 m2
in PlutusTx.fmap (\(k, v) -> (k, PlutusTx.decodeUtf8 v)) (AssocList.toList m)
||]
)
2 changes: 1 addition & 1 deletion plutus-tx/plutus-tx.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ library
PlutusTx.Builtins.Internal
PlutusTx.Code
PlutusTx.Coverage
PlutusTx.DataMap
PlutusTx.Data.AssocList
PlutusTx.Either
PlutusTx.Enum
PlutusTx.Eq
Expand Down

0 comments on commit fc7c0c1

Please sign in to comment.