lean4-htt/tests/elab/issue13444.lean
Joachim Breitner 03bd8847dc
fix: distinguish recursive applications by source position (#13645)
This PR fixes the termination checker reporting errors at the wrong
recursive call site when a function contains structurally-identical
recursive calls at different source locations.

The `_recApp` `MData` attached to recursive applications carried the
attached `Syntax`, but two structurally-equal `MData` wrappers could be
merged by hashconsing/simplification, so the syntax of the first call
ended up associated with both call sites. We now also store the source
byte position as `_recAppPos`, which keeps the wrappers distinct.

Closes #13444.
2026-05-05 16:40:29 +00:00

32 lines
975 B
Text

module
/-!
The termination error should be reported at the second recursive call, not the first.
The two calls `f heapsize (lCh i)` are structurally identical syntax; without recording
the source position in the `_recApp` mdata, hashconsing/simplification merged them and
the error was attributed to the wrong call.
-/
def lCh := (· * 2 + 1)
/--
@ +7:6...24
error: failed to prove termination, possible solutions:
- Use `have`-expressions to prove the remaining goals
- Use `termination_by` to specify a different well-founded relation
- Use `decreasing_by` to specify your own tactic for discharging this kind of goal
heapsize i : Nat
h✝¹ : i < heapsize
h✝ : ¬i = 0
⊢ heapsize - lCh i < heapsize - i
-/
#guard_msgs (positions := true) in
def f (heapsize i : Nat) : Nat :=
if i < heapsize then
if i = 0 then
have : i < lCh i := by simp [lCh]; omega
f heapsize (lCh i)
else
f heapsize (lCh i)
else 0
termination_by heapsize - i