I'm a beginner in the world of proof assistants, and have been taking a look at Lean4 lately.
I wanted to write a function like
def List.index : (x : α) → {xs : List α // x ∈ xs} → Nat
| x, ⟨_ :: xs, ok⟩ =>
match ok with
| List.Mem.head _ => 0
| List.Mem.tail _ t => 1 + List.index x ⟨xs, t⟩
But when I do it, I receive the following error:
tactic 'cases' failed, nested error:
tactic 'induction' failed, recursor 'List.Mem.casesOn' can only eliminate into Prop
α : Type ?u.87469
x : α
xs : List α
head✝ : α
ok✝¹ : x ∈ head✝ :: xs
motive : (head : α) → x ∈ head :: xs → Sort ?u.87826
h_1 : Unit → motive x (_ : Mem x (x :: xs))
h_2 : (x_1 : α) → (t : Mem x xs) → motive x_1 (_ : Mem x (x_1 :: xs))
a✝ : List α
ok✝ : Mem x a✝
⊢ head✝ :: xs = a✝ → HEq ok✝¹ ok✝ → motive head✝ ok✝¹ after processing
_, _
the dependent pattern matcher can solve the following kinds of equations
- <var> = <term> and <term> = <var>
- <term> = <term> where the terms are definitionally equal
- <constructor> = <constructor>, examples: List.cons x xs = List.cons y ys, and List.cons x xs = List.nil
If I write my own instance of Mem
, with it being a Type
, it works perfectly:
inductive MyMem (a : α) : List α → Type
| head (as : List α) : MyMem a (a::as)
| tail (b : α) {as : List α} : MyMem a as → MyMem a (b::as)
def List.index' : (x : α) → (xs : List α) → (ok : MyMem x xs) → Nat
| x, _ :: xs, ok =>
match ok with
| MyMem.head _ => 0
| MyMem.tail _ t => 1 + List.index' x xs t
But, as soon as I set it as a Prop, the same error comes up. Am I doing something wrong? I'm a bit confused about this.