Zulip Chat Archive

Stream: new members

Topic: Fail to show termination when using universe u


LizBonn (Aug 30 2025 at 14:32):

I want to define the Nat.le relation on a general type α. As an mwe, I first define a type class C, declaring a succ : α → α function on type α. Then I define le exactly as Nat.le :

import Mathlib
set_option autoImplicit false

class C (α : Type*) where
  succ : α  α

inductive le {α : Type*} [C α] : α  α  Prop where
| refl {n : α} : le n n
| step {a b : α} (h : le a b) : le a (C.succ b)

After that, I want to prove the transitivity of le. However, if the underlying type α has type Type u, Lean fails to show termination of the proof. If the underlying type α has type Type* or other concrete types like Type, Lean doesn't complain.

namespace Hidden
theorem le_trans₁.{u} {α : Type u} [C α] {a b c : α} : le a b  le b c  le a c
  | h, .refl => h
  | h, .step h' => .step (le_trans₁ h h')

theorem le_trans₂ {α : Type} [C α] {a b c : α} : le a b  le b c  le a c
  | h, .refl => h
  | h, .step h' => .step (le_trans₂ h h')

theorem le_trans₃ {α : Type*} [C α] {a b c : α} : le a b  le b c  le a c
  | h, .refl => h
  | h, .step h' => .step (le_trans₃ h h')

Error message for le_trans₁:

fail to show termination for
  Hidden.le_trans₁
with errors
failed to infer structural recursion:
Not considering parameter α of Hidden.le_trans₁:
  it is unchanged in the recursive calls
Not considering parameter #2 of Hidden.le_trans₁:
  it is unchanged in the recursive calls
Not considering parameter a of Hidden.le_trans₁:
  it is unchanged in the recursive calls
Not considering parameter b of Hidden.le_trans₁:
  it is unchanged in the recursive calls
Not considering parameter c of Hidden.le_trans₁:
  its type is not an inductive
Cannot use parameter #6:
  application type mismatch
    @le α
  argument
    α
  has type
    Type u : Type (u + 1)
  but is expected to have type
    Type u_1 : Type (u_1 + 1)
Cannot use parameter #7:
  application type mismatch
    @le α
  argument
    α
  has type
    Type u : Type (u + 1)
  but is expected to have type
    Type u_1 : Type (u_1 + 1)


Could not find a decreasing measure.
The basic measures relate at each recursive call as follows:
(<, , =: relation proved, ? all proofs failed, _: no proof attempted)

1) 15:26-40
Please use `termination_by` to specify a decreasing measure.

It is so weird to me. Could someone explain this?

Thanks in advance!

Aaron Liu (Aug 30 2025 at 14:44):

This is a bug in the recursion compiler

Joachim Breitner (Aug 30 2025 at 15:11):

This is structural recursion on inductive predicates? So maybe fixed en passant by @Robin Arnez’s #9995?

Aaron Liu (Aug 30 2025 at 15:41):

lean4#9995

Robin Arnez (Aug 30 2025 at 19:27):

It's not fixed. I'll look into it

Robin Arnez (Aug 30 2025 at 19:31):

Seems like an issue with docs#Lean.Meta.Match.getMkMatcherInputInContext. Shouldn't be too hard to fix

Robin Arnez (Aug 30 2025 at 19:35):

Yup, works now. I added a test based on your example


Last updated: Dec 20 2025 at 21:32 UTC