-
Notifications
You must be signed in to change notification settings - Fork 103
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
feat: unbundle array size constraint from hash map bucket array #748
base: nightly-testing
Are you sure you want to change the base?
Conversation
Co-authored-by: Joe Hendrix <[email protected]>
I'm concerned about the precedent that this sets. The rules on nested inductives are very strict and also abstraction-breaking, so having such a promise limits our ability to hide implementation details and evolve the library in the future. I think it would be better to support nested inductives of this kind through an external package (or future improvement to the |
@@ -102,8 +110,10 @@ already in the array, which is appropriate when reinserting elements into the ar | |||
-/ | |||
@[inline] def reinsertAux [Hashable α] | |||
(data : Buckets α β) (a : α) (b : β) : Buckets α β := | |||
let ⟨i, h⟩ := mkIdx data.2 (hash a |>.toUSize) | |||
data.update i (.cons a b data.1[i]) h | |||
if hd : 0 < data.1.size then |
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 should be a parameter to the function. There is no need to be doing this check here. You can also avoid having an additional parameter in the IR by smuggling the property in a subtype, as in (data : {b : Buckets α β // 0 < b.size})
.
Here's a counterproposal which includes elements of my other suggestion and also leads to a much smaller diff, while still meeting the goal of having
This way, there is no need for if statements in the main functions, and most of the hard proofs are unaffected. |
Apologies, I needed to reset |
b3f5e60
to
4adcb48
Compare
This PR makes sure that the positivity checker is happy with the following construction:
Users actually want to do this, see this article (search for "recursive datatype") and the code. The users had to build their own primitive map (see here), but arguably the standard
HashMap.Imp
should just support this. Users will have to pass the well-formedness constraints around by hand, but that is much better than nothing.To make this possible,
HashMap.Imp.Buckets
had to lose the constraint that the bucket array has positive size. This is now part ofBuckets.WF
. Without knowing that there is at least one bucket, none of the operations are able to access the bucket array, so they are all wrapped in anif 0 < buckets.size
. It's not pretty, but we should be able to live with the performance hit. I fixed all of the well-formedness lemmas, though I struggled withexpand_size
and ended up rewriting that one into a style that I hope is easier to follow for someone without Mario-level Lean skills :-)This PR targets
nightly-testing
for now because it uses the new functional induction principles from Lean 4.8.