lean4-htt/tests/lean/run/2810.lean
Joachim Breitner 409c6cac4c
fix: predefinition preprocessing: float .mdata out of non-unary applications (#3204)
Recursive predefinitions contains “rec app” markers as mdata in the
predefinitions,
but sometimes these get in the way of termination checking, when you
have
```
  [mdata (fun x => f)] arg
```

Therefore, the `preprocess` pass floats them out of applications
(originally
only for structural recursion, since #2818 also for well-founded
recursion).

But the code was incomplete: Because `Meta.transform` calls `post` on `f
x y` only
once (and not also on `f x`) one has to float out of nested applications
as well.

A consequence of this can be that in a recursive proof, `rw [foo]` does
not work
although `rw [foo _ _]` does.

Also adding the testcase where @david-christiansen and I stumbled over
this


(Maybe the two preprocess modules can be combined, now that #2973 is
landed, will try that
in a follow-up).
2024-01-24 08:37:16 +00:00

90 lines
1.5 KiB
Text

/-!
Test that parentheses don't get in the way of structural recursion.
https://github.com/leanprover/lean4/issues/2810
-/
namespace Unary
def f (n : Nat) : Nat :=
match n with
| 0 => 0
| n + 1 => (f) n
-- TODO: How can we assert that this was compiled structurally?
-- with beta-reduction
def f2 (n : Nat) : Nat :=
match n with
| 0 => 0
| n + 1 => (fun n' => (f2) n') n
-- structural recursion
def f3 (n : Nat) : Nat :=
match n with
| 0 => 0
| n + 1 => (f3) n
termination_by n
-- Same with rewrite
theorem f_zero (n : Nat) : f n = 0 := by
match n with
| .zero => rfl
| .succ n =>
unfold f
rewrite [f_zero]
rfl
-- Same with simp
theorem f_zero' (n : Nat) : f n = 0 := by
match n with
| .zero => rfl
| .succ n =>
unfold f
simp only [f_zero']
end Unary
namespace Binary
def f (n m : Nat) : Nat :=
match n with
| 0 => 0
| n + 1 => (f) n m
-- TODO: How can we assert that this was compiled structurally?
-- with beta-reduction
def f2 (n m : Nat) : Nat :=
match n with
| 0 => 0
| n + 1 => (fun n' => (f2) n' m) n
-- structural recursion
def f3 (n m : Nat) : Nat :=
match n with
| 0 => 0
| n + 1 => (f3) n m
termination_by n
-- Same with rewrite
theorem f_zero (n m : Nat) : f n m = 0 := by
match n with
| .zero => rfl
| .succ n =>
unfold f
rewrite [f_zero]
rfl
-- Same with simp
theorem f_zero' (n m : Nat) : f n m = 0 := by
match n with
| .zero => rfl
| .succ n =>
unfold f
simp only [f_zero']
end Binary