Reputation: 771
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)
Upvotes: 3
Views: 93
Reputation: 25782
The problem is that by writing
def Idx (n:Nat) := Fin n
that type class search won’t find instances for Idx
that it would find for Fin
, in particular not the SizeOf
instance used for recursion.
As @jthulhu mentioned, using abbrev
is the appropriate fix for this.
Upvotes: 1