Zulip Chat Archive
Stream: lean4
Topic: help with termination
Simon Daniel (Sep 01 2025 at 07:48):
Hi all,
im stuck with writing a function definition and maybe someone can help me out, it seems kinda straightforward, but the lean compiler rejects it as being non-computable and non terminating:)
I have a inductive representing datatypes (Ty) and another inductive that represents Types (Lty Θ). Lty Θ is either a datatype, anotated by a sublist of Θ, or a function type.
if Θ' ⊆Θ , then lift is a function that can map an Lty Θ' -> Lty Θ, because all type annotating lists must then also be sublists of Θ.
the denote functions map my types to lean types.
I should be able to define the function f, However i struggle with the .fn case.
I tried matching with α, but the compiler seems to complain.
I think the problem is the dependency of matching α and the goal (α.lift p').den
inductive Ty
| unit
-- Tys get annotated by subsets of Θ
inductive Lty (Θ: List Nat) where
| ty (α: Ty) (ns: List Nat) (p: ps ⊆ Θ)
| fn (a b: Lty Θ)
-- might be needed?
abbrev sizeLty {Θ} : Lty Θ → Nat
| .ty _ _ _ => 1
| .fn a b => 1 + sizeLty a + sizeLty b
abbrev Lty.lift {Θ Θ'} (p: Θ' ⊆ Θ): Lty Θ' -> Lty Θ
| ty α ns p' => .ty α ns (fun _ a => p (p' a))
| fn a b => .fn (a.lift p) (b.lift p)
def Ty.den: Ty -> Type
| .unit => Unit
def Lty.den (lt: Lty Θ) := match lt with
| ty α ps _p => (Θ ⊆ ps) -> α.den
| fn a b => a.den -> b.den
--fail to show termination for f, show: False :(
def f {Θ Θ'} {p': Θ' ⊆ Θ} : (α: Lty Θ') -> (v: α.den) -> (α.lift p').den
| .ty a ns q, v =>
fun h: Θ ⊆ ns =>
v (fun x hx => h (p' hx))
| .fn a b, v =>
fun x =>
f (.fn a b) v x
-- ? termination_by α => sizeLty α
Robin Arnez (Sep 01 2025 at 08:21):
I mean yeah, it doesn't terminate, you defined f (.fn a b) v x = f (.fn a b) v x
Simon Daniel (Sep 01 2025 at 08:35):
ahh okay that should have been obvious... i was playing arround with the proof goal and happy that i found anything that typechecks :sweat_smile:
im still not sure what the right definition for f (.fn a b) v x should be
Simon Daniel (Sep 01 2025 at 11:30):
A colleague suggested to adjust Lty, then defining the function f was straightforward. (i still feel like it should have been possible with my original Lty inductive)
inductive Ty
| unit
-- Tys get annotated by subsets of Θ
inductive Lty : List Nat → Type where
| ty (α: Ty) (ps: List Nat) (p: ps ⊆ Θ) : Lty Θ
| fn (a : Lty Θ') (b : Lty Θ'') (h : Θ ⊆ Θ) (h' : Θ'' ⊆ Θ) : Lty Θ
def Ty.den: Ty -> Type
| .unit => Unit
def Lty.den (lt: Lty Θ) := match lt with
| ty α ps _p => (Θ ⊆ ps) -> α.den
| fn a b _c _d => a.den -> b.den
abbrev Lty.lift {Θ Θ':List Nat} (p: Θ' ⊆ Θ): Lty Θ' -> Lty Θ
| .ty a ps p' => .ty a ps (fun _ a => p (p' a))
| .fn a b c d => .fn a b (by simp) (by grind)
def f {Θ Θ'} {p': Θ' ⊆ Θ}: (α: Lty Θ') -> (v: α.den) -> (α.lift p').den
| .ty a ps q, v =>
fun h: Θ ⊆ ps =>
v (fun x hx => h (p' hx))
| .fn _ _ _ _, v =>
fun h => v h
Last updated: Dec 20 2025 at 21:32 UTC