-
Notifications
You must be signed in to change notification settings - Fork 444
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
recursive definitions fail if recursive calls appear in the types of matchers #1694
Comments
I see this goal:
Note that the goal wants Turning |
I found a much smaller, and sorry-free code that may be related. Here, the issue is also termination checking, and it goes away if I comment out a piece of code that, I suppose, is capable of rewriting the context in a way similar to def foo (_: True): Prop := True
def bar (n: Nat): True :=
match n with
| Nat.zero => trivial
| Nat.succ nPred =>
let asdf: foo (bar nPred) := trivial
-- Commenting out the next line hides the issue.
let ⟨⟩ := asdf
trivial The error:
|
Thanks for minimizing. Writing
I see two goals, namely
The first one seems to corresponds to the type of the let binding, and is fine ( The second one comes from
which, if we disable
with
and after the translation we get
where the So the problem is that the match construction yielding to If the matcher would abstract over
then things would be well. Alternatively, we could try to unfold the matcher in this construction, although that is likely to blow up the proof term size. The code to improve to abstract over each applications of free variables separately would be in A work-around is to let-bind the recursive call, on its own, yourself: def bar (n: Nat): True :=
match n with
| Nat.zero => trivial
| Nat.succ nPred =>
let bar_nPred := bar nPred
let asdf: foo bar_nPred := trivial
let ⟨⟩ := asdf
trivial Given that the work-around exists, and it may be hard to fix, maybe not too pressing. |
Just for reference, I found another small piece of code that might be worth looking into if someone ever decides to dedicate their time to this. This time, there isn't any recursion involved at all. structure Asdf where
T: Type
t: T
def foo (asdf: Asdf) :=
let ⟨T, _⟩ := asdf
let a: asdf.T := asdf.t
let b: T := asdf.t
42 It seems that extracting a member of a structure with The error:
|
I think this is unrelated, and probably an instances of the issue described in #5216 |
Prerequisites
Description
In the following code (sorry, tried to make it even smaller, but couldn't), a "failed to prove
termination" error shows up in the definition of variable
asdf
, despite that thestatement proving well-foundedness of the call is directly above in
hereIAm
.The error disappears when the line containing
aaLtA
is commented out,or extracted to another function, which provides a workaround.
As probably a separate issue, when I try to inline
asdf
, Lean won't even noticethe variable
hereIAm
(it won't be shown among other defined variables inthe error description).
Steps to Reproduce
Expected behavior: Termination is proven.
Actual behavior: An error shows up.
Reproduces how often: Always.
Versions
Both Lean 4 stable and nightly
Lean (version 4.0.0-nightly-2022-09-14, commit fccb60f, Release),
Lean (version 4.0.0, commit 7dbfaf9, Release)
Ubuntu 22.04.1 LTS
The text was updated successfully, but these errors were encountered: