-
Notifications
You must be signed in to change notification settings - Fork 122
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
Lean: add support for range types #869
base: sail2
Are you sure you want to change the base?
Conversation
| Typ_app (Id_aux (Id "range", _), [A_aux (A_nexp low, _); A_aux (A_nexp high, _)]) -> | ||
(* The heuristics is that 99% of rages are positive, so we try to | ||
translate them to Nat. *) | ||
if clearly_negative low then string "Int" else string "Nat" |
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.
The idea was to keep two kinds, @Alasdair implemented the Nat
kind specifically to avoid having heuricstics. Not sure how to solve that for ranges, though.
I think your heuristic doensn't have a one-sided error? Nexp_neg
can be a double negation, for example
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.
So I grepped all the uses of range in the models and my understanding is that for the overwhelming majority of them they are clearly non-negative, and a few clearly include negative elements, so this is an optimistic assumption.
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.
The way to do this would be to take an env
representing the context when converting the type, then you can call Type_check.prove env (nc_gteq low (nint 0))
. That avoids any syntactic-restrictions, but Lean might need more explicit conversions to be inserted.
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.
The rule for conversions is generally that Int to Nat would have to be made explicit while Nat to Int would be implicit
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.
@javra what do you think is the best thing to do here?
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.
Have you tried using @Alasdair 's suggestion for implementing clearly_negative
? Otherwise we could just leave it as it is and add a comment to improve the heuristics later on.
But I'd call it provably_positive
and only return Nat
if the lower bound can be proven to be positive, otherwise we'd have to use Int
in order not to run into problems.
dc8a1bd
to
9e9d5f3
Compare
I implemented Alasdair's strategy and it seems to be working. I put the Now, the ranges in parameters are transformed into |
test/lean/range.expected.lean
Outdated
x | ||
|
||
/-- Type quantifiers: x : Int, k_n : Int, 0 ≤ x ∧ x ≤ k_n -/ | ||
def f_nnegvar (x : Int) : Nat := |
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 doesn't go through because it would need an explicit conversion here. I don't immediatly get why the return type is translated as Nat
but the argument type as Int
🤔
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.
See my reply below
In general the type |
I updated the PR to also try to prove that parameters/atoms are non-negative. What do you think? |
No description provided.