Skip to content

Commit

Permalink
Add function equipartitionTokenBundleWithMaxQuantity.
Browse files Browse the repository at this point in the history
  • Loading branch information
jonathanknowles committed Feb 25, 2021
1 parent 6047e02 commit cd739ce
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 0 deletions.
Expand Up @@ -57,6 +57,7 @@ module Cardano.Wallet.Primitive.CoinSelection.MA.RoundRobin
, equipartitionCoin
, equipartitionTokenBundle
, equipartitionTokenMap
, equipartitionTokenBundleWithMaxQuantity
, equipartitionTokenMapWithMaxQuantity

-- * Grouping and ungrouping
Expand Down Expand Up @@ -1231,6 +1232,27 @@ equipartitionTokenMap m count = NE.reverse $
weights :: NonEmpty Natural
weights = 1 <$ count

-- | Partitions a token bundle into a number of smaller token bundles, where
-- every quantity in the result is guaranteed to not exceed the maximum
-- allowable token quantity.
--
-- This function partitions the given token bundle into 'n' approximately-equal
-- bundles, where 'n' is the minimum value required to achieve the goal that no
-- token quantity in any of the resulting bundles exceeds the maximum allowable
-- token quantity.
--
equipartitionTokenBundleWithMaxQuantity
:: TokenBundle
-> TokenQuantity
-- ^ Maximum allowable token quantity.
-> NonEmpty TokenBundle
-- ^ The partitioned bundles.
equipartitionTokenBundleWithMaxQuantity b maxQuantity =
NE.zipWith TokenBundle cs ms
where
cs = equipartitionCoin (view #coin b) ms
ms = equipartitionTokenMapWithMaxQuantity (view #tokens b) maxQuantity

-- | Partitions a token map into a number of smaller token maps, where every
-- quantity in the result is guaranteed to not exceed the maximum allowable
-- token quantity.
Expand Down
Expand Up @@ -35,6 +35,7 @@ import Cardano.Wallet.Primitive.CoinSelection.MA.RoundRobin
, coinSelectionLens
, equipartitionCoin
, equipartitionTokenBundle
, equipartitionTokenBundleWithMaxQuantity
, equipartitionTokenMap
, equipartitionTokenMapWithMaxQuantity
, fullBalance
Expand Down Expand Up @@ -340,6 +341,15 @@ spec = describe "Cardano.Wallet.Primitive.CoinSelection.MA.RoundRobinSpec" $
it "prop_equipartitionTokenMap_sum" $
property prop_equipartitionTokenMap_sum

parallel $ describe "Partitioning token bundles by max quantity" $ do

it "prop_equipartitionTokenBundleWithMaxQuantity_length" $
property prop_equipartitionTokenBundleWithMaxQuantity_length
it "prop_equipartitionTokenBundleWithMaxQuantity_order" $
property prop_equipartitionTokenBundleWithMaxQuantity_order
it "prop_equipartitionTokenBundleWithMaxQuantity_sum" $
property prop_equipartitionTokenBundleWithMaxQuantity_sum

parallel $ describe "Partitioning token maps by max quantity" $ do

it "prop_equipartitionTokenMapWithMaxQuantity_coverage" $
Expand Down Expand Up @@ -1745,6 +1755,40 @@ prop_equipartitionTokenMap_sum :: TokenMap -> NonEmpty () -> Property
prop_equipartitionTokenMap_sum m count =
F.fold (equipartitionTokenMap m count) === m

--------------------------------------------------------------------------------
-- Partitioning token bundles according to a maximum quantity
--------------------------------------------------------------------------------

-- | Computes the number of parts that 'equipartitionTokenBundleWithMaxQuantity'
-- should return.
--
equipartitionTokenBundleWithMaxQuantity_expectedLength
:: TokenBundle -> TokenQuantity -> Int
equipartitionTokenBundleWithMaxQuantity_expectedLength m =
equipartitionTokenMapWithMaxQuantity_expectedLength
(view #tokens m)

prop_equipartitionTokenBundleWithMaxQuantity_length
:: TokenBundle -> TokenQuantity -> Property
prop_equipartitionTokenBundleWithMaxQuantity_length m maxQuantity =
maxQuantity > TokenQuantity.zero ==>
length (equipartitionTokenBundleWithMaxQuantity m maxQuantity)
=== equipartitionTokenBundleWithMaxQuantity_expectedLength
m maxQuantity

prop_equipartitionTokenBundleWithMaxQuantity_order
:: TokenBundle -> TokenQuantity -> Property
prop_equipartitionTokenBundleWithMaxQuantity_order m maxQuantity =
maxQuantity > TokenQuantity.zero ==>
inAscendingPartialOrder
(equipartitionTokenBundleWithMaxQuantity m maxQuantity)

prop_equipartitionTokenBundleWithMaxQuantity_sum
:: TokenBundle -> TokenQuantity -> Property
prop_equipartitionTokenBundleWithMaxQuantity_sum m maxQuantity =
maxQuantity > TokenQuantity.zero ==>
F.fold (equipartitionTokenBundleWithMaxQuantity m maxQuantity) === m

--------------------------------------------------------------------------------
-- Partitioning token maps according to a maximum quantity
--------------------------------------------------------------------------------
Expand Down

0 comments on commit cd739ce

Please sign in to comment.