-
Notifications
You must be signed in to change notification settings - Fork 37
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
Implementing IsLawfulNum
as part of Issue #108
#331
Merged
Merged
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
jespercockx
reviewed
Jun 9, 2024
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like a great start! I've left two small comments.
pmbittner
force-pushed
the
issue-108-Num
branch
5 times, most recently
from
June 10, 2024 12:33
6b4a2f5
to
aa62b43
Compare
This commit adds the new type class IsLawfulNum that contains all the laws the Haskell Num typeclass should satisfy. There currently is one law we cannot formalize here because toInteger is not yet part of our Prelude. This commit is part of issue agda#108.
These functions were formerly private. They had to made accessible to other parts of the library to allow proofs, in particular for the IsLawfulNum instances. Both functions are still "hidden" in an "Internal" module though to signal these functions as not being intended to be used from any Haskell code. This change also redefines subNat based on pattern-matching instead of an if-else-expression with ltNat, to simplify proofs.
pmbittner
commented
Jun 13, 2024
7 tasks
to make it visible for proofs
Haskell.Law.Num should publicly import all available instances as well as the LawfulNum class. To avoid cyclic dependencies, the functions for concluding number laws were move to Haskell.Law.Num.Def.
This PR is now ready to review. |
jespercockx
approved these changes
Jul 9, 2024
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work, thank you very much!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This pull-request adds the laws for the
Num
typeclass in Haskell as part of issue #108.Progress:
Nat
instanceInt
instanceInteger
instanceWord
instanceDouble
instanceThere was one law we cannot formalize yet, which is
fromInteger (toInteger i) == i
because there is notoInteger
function available yet. I documented this law as missing.For the
Nat
instance, I mostly copied code from the Agda standard library for comparability, consistency, and also because it is easy 😅.For
Integer
I had to come up with new proofs because the definitions for this type are slightly different from those in the standard library. I oriented on the proofs from the standard library where possible though. Also I tried to favor equational reasoning in favor ofrewrite
for better readability.Arithmetics of
Word
is mostly relying on arithmetics ofNat
and arithmetics ofInt
is defined solely in terms of arithmetics onWord
. I hence opted to reuse the laws from the other instances, respectively. In fact, reducing the arithmetics for aNum
type in terms of anotherNum
instance is feasible as long as this reduction is homomorphic.To formalize this observation, I added definitions for homomorphisms, embeddings, as well as some other common predicates in a new module
Haskell.Prim.Function
with respective proofs inHaskell.Law.Function
. I thought that such definitions might be useful in other contexts as well, if desired. Using these definitions, we can then define the circumstances under which we may conclude anILawfulNum
instance from another one.The question remains whether such abstractions are desired. On the one hand, these are quite common concepts. On the other hand, they introduce another layer of indirection and abstractions, making some of the proofs harder to comprehend. Also, should we reuse the definitions such as
Associative
,Commutative
, and so on in the definition ofIsLawfulNum
or should we inline those (as it currently is) for readability?Moreover, I had to introduce six new axioms to prove lawfulness of
Word
, all of which are stated inlib/Haskell/Law/Num/Word.agda
. I documented the new axioms and explained why they should be reasonable. It would be good if these could be reviewed. I am not 100% sure that they are correct and minimal.Also, the
Double
instance cannot be proven as of now. It is solely based on primitive functions for which no axioms exist yet. So I left that out for now.