The following example type checks in Lean 4, but I am confused why the termination_by declaration is required.
import Mathlib.Tactic.Linarith
def Idx (n:Nat) := Fin n
def sum(k:Idx n) : Nat :=
if p:k.val=0 then 0
else
have p : k.val-1 < k.val := (Nat.pred_lt p);
let km1 : Idx n := {val:=k.val-1,isLt:=(by linarith [k.isLt])};
1+(sum km1)
termination_by sum k => k.val
Specifically, a very similar example does not require it:
def sum2(k:Fin n) : Nat :=
if p:k.val=0 then 0
else
have p : k.val-1 < k.val := (Nat.pred_lt p);
let km1 : Fin n := {val:=k.val-1,isLt:=(by linarith [k.isLt])};
1+(sum2 km1)
Obviously, it has something to do with the fact that I've wrapped the Fin n with Idx n. I tried adding a @[simp] annotation, but that didn't help.
(also am interested in whether the example can be improved)