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

Add generalized property tests for coin selection algorithms. #81

Merged
merged 10 commits into from
May 14, 2020

Conversation

jonathanknowles
Copy link
Contributor

@jonathanknowles jonathanknowles commented May 14, 2020

Related Issue

#21

Summary

This PR adds missing tests for properties that apply to all algorithms implementing the CoinSelectionAlgorithm interface, as defined by the coin selection specification:

  • Pre-conditions:
    • value inputsAvailable ≥ value outputsRequested
  • Post-conditions:
    • outputsSelected = outputsRequested
    • inputsSelected ⊆ inputsAvailable
    • inputsRemaining ⊆ inputsAvailable
    • inputsSelected ⋂ inputsRemaining = ∅
    • inputsSelected ⋃ inputsRemaining = inputsAvailable
    • value inputsSelected = value outputsSelected + value change

This PR validates the above set of properties against the following algorithms:

  • Largest-First
  • Random-Improve

@jonathanknowles jonathanknowles self-assigned this May 14, 2020
@jonathanknowles jonathanknowles changed the title Add Properties from Specification. Add Specification Properties. May 14, 2020
-- A collection of general properties that should apply to all algorithms
-- that implement the 'CoinSelectionAlgorithm' interface.
--
coinSelectionAlgorithmGeneralProperties
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not to use Common or Generic ? it sounds better to me (I know you know better as you are native speaker :-) )

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not to use Common or Generic ? it sounds better to me (I know you know better as you are native speaker :-) )

Good question!

I'm trying to capture a contrast between specialized and generalized.

We already have tests for properties that are specific (or specialized) to particular algorithms. For example, for Largest-First, we have a specialized property test that checks that all selected inputs are greater than or equal (in coin value) to the remaining inputs not selected.

However, the properties in this PR are all general (non-specific), as they apply to all implementations.

We could also use the term "common" here. I tried to avoid the word "generic" as it could be confused with the concept of generic programming.

intersection :: Ord k => CoinMap k -> CoinMap k -> CoinMap k
intersection (CoinMap a) (CoinMap b) = CoinMap $ a `Map.intersection` b

union :: Ord k => CoinMap k -> CoinMap k -> CoinMap k
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah, ok. you wanted to make it explicit

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this really needed when we have https://github.com/input-output-hk/cardano-coin-selection/blob/master/src/library/Cardano/CoinSelection.hs#L123 ?

Strictly speaking it's not needed!

Here my motivation was to make the tests more readable. Defining union (arguably) makes the test more readable at the call site.

In particular, the following two lines are now directly comparable to one another:

(selected `intersection` remaining) `shouldBe` mempty
(selected `union`        remaining) `shouldBe` available

Whereas if we just use <> instead of union, it's no longer immediately clear that we're invoking a union operation (IMO).

Copy link
Contributor

@paweljakubas paweljakubas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

finding and extracting common properties for any coin selection algorithm sounds like a good idea

@jonathanknowles jonathanknowles merged commit e4b16d5 into master May 14, 2020
@jonathanknowles jonathanknowles deleted the jonathanknowles/specification-properties branch May 14, 2020 07:42
@jonathanknowles jonathanknowles changed the title Add Specification Properties. Add General Properties from Specification. May 14, 2020
@jonathanknowles jonathanknowles changed the title Add General Properties from Specification. Add generalized property tests for coin selection algorithms. May 14, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants