Zulip Chat Archive
Stream: new members
Topic: Nonsensical type mismatch
Kuba (Jul 01 2023 at 00:06):
I am getting a weird application type mismatch
message, where both the actual and expected type are the same:
application type mismatch
Eq.subst (Eq.symm (tmp13 x xs m)) (tmp10 xs (x :: bs) m (Nat.lt_of_succ_lt_succ h))
argument
tmp10 xs (x :: bs) m (Nat.lt_of_succ_lt_succ h)
has type
List.get (List.reverseAux xs (x :: bs))
{ val := List.length xs - 1 - m,
isLt := (_ : List.length xs - 1 - m < List.length (List.reverseAux xs (x :: bs))) } =
List.get xs { val := m, isLt := (_ : m < List.length xs) } : Prop
but is expected to have type
List.get (List.reverseAux xs (x :: bs))
{ val := List.length xs - 1 - m,
isLt := (_ : List.length xs - 1 - m < List.length (List.reverseAux xs (x :: bs))) } =
List.get xs { val := m, isLt := (_ : m < List.length xs) } : Prop
Here is the relevant code snippet:
theorem tmp10.{u} {α : Type u} : ∀ as bs : List α, ∀ n : Nat, (h : n < as.length) →
(List.reverseAux as bs).get ⟨as.length - 1 - n,
Nat.lt_of_lt_of_le (tmp3 as.length n (tmp9 n as.length h)) (tmp7 as bs)⟩ =
as.get ⟨n, h⟩ :=
λ as bs => λ n => λ h =>
match as, n with
| x :: xs, Nat.succ m => (Eq.subst
(motive := λ y => (List.reverseAux xs (x :: bs) ).get ⟨y, _⟩ = xs.get ⟨m, _⟩)
(Eq.symm (tmp13 x xs m))
(tmp10 xs (x :: bs) m (Nat.lt_of_succ_lt_succ h)))
| [], _ => ()
What I am trying to prove is List.reverse_aux2
which is already part of Mathlib, but I wanted to have a go myself as an exercise. Therefore this question is not about how to prove the theorem, but how to interpret the weird error message.
Kevin Buzzard (Jul 01 2023 at 00:15):
can you post a #mwe ? The code above doesn't run. Put by convert
in front of your proof to get more detailed information about the part that Lean is stuck on.
Kuba (Jul 01 2023 at 00:23):
Sorry, here is all you should need (no imports required, I only used stuff that is part of Init):
theorem tmp1 : ∀ n : Nat, n > 0 → n - 1 < n :=
λ _ => λ h => Nat.sub_lt h (Nat.zero_lt_succ 0)
theorem tmp2 : ∀ n m k : Nat, n < m → n - k < m :=
λ n _ k => λ h => Nat.lt_of_le_of_lt (Nat.sub_le n k) h
theorem tmp3 : ∀ n m : Nat, 0 < n → n - 1 - m < n :=
λ n m => λ h => tmp2 (n - 1) n m (tmp1 n h)
theorem tmp6.{u} {α : Type u} :
∀ as bs : List α, (List.reverseAux as bs).length = as.length + bs.length :=
λ as bs =>
match as with
| [] => Eq.symm (Nat.zero_add bs.length)
| a :: as =>
Eq.trans (tmp6 as (a :: bs)) (
Eq.trans (Nat.add_succ as.length bs.length) (
Eq.symm (Nat.succ_add as.length bs.length)))
theorem tmp7.{u} {α : Type u} : ∀ as bs : List α,
as.length <= (List.reverseAux as bs).length :=
λ as bs => Eq.subst (Eq.symm (tmp6 as bs)) (Nat.le_add_right as.length bs.length)
theorem tmp9 : ∀ m n : Nat, m < n → n > 0 :=
λ m _ => λ h => Nat.lt_of_le_of_lt (Nat.zero_le m) h
theorem tmp14 : ∀ n m k : Nat, n - m - k = n - k - m :=
λ n m k => Eq.trans
(Eq.subst (motive := λ x => n - m - k = n - x)
(Nat.add_comm m k) (Nat.sub_sub n m k))
(Eq.symm (Nat.sub_sub n k m))
theorem tmp13.{u} {α : Type u} : ∀ a : α, ∀ as : List α, ∀ n : Nat,
(a :: as).length - 1 - (Nat.succ n) = as.length - 1 - n :=
λ a => λ as => λ n => Eq.trans
(Eq.subst (motive := λ x => (a::as).length - 1 - (Nat.succ n) = x - 1)
(Nat.succ_sub_succ as.length n) (tmp14 (a :: as).length 1 (Nat.succ n)))
(tmp14 as.length n 1)
theorem tmp10.{u} {α : Type u} : ∀ as bs : List α, ∀ n : Nat, (h : n < as.length) →
(List.reverseAux as bs).get ⟨as.length - 1 - n,
Nat.lt_of_lt_of_le (tmp3 as.length n (tmp9 n as.length h)) (tmp7 as bs)⟩ =
as.get ⟨n, h⟩ :=
λ as bs => λ n => λ h =>
match as, n with
| x :: xs, Nat.succ m => (Eq.subst
(motive := λ y => (List.reverseAux xs (x :: bs) ).get ⟨y, _⟩ = xs.get ⟨m, _⟩)
(Eq.symm (tmp13 x xs m))
(tmp10 xs (x :: bs) m (Nat.lt_of_succ_lt_succ h)))
| [], _ => ()
Kuba (Jul 04 2023 at 22:09):
I tried using the convert
tactic. Since 'convert' is part of Mathlib, I cloned and tried building it on my machine (not sure whether that was successful). However, I can't import it into the file that contains my failing code, I get: unknown package 'Mathlib'
.
Alex J. Best (Jul 04 2023 at 23:43):
You shouldn't manually clone mathlib, rather you need to add a dependency on mathlib inside your lakefile.lean
by adding the lines
require mathlib from git
"https://github.com/leanprover-community/mathlib4.git"
just before the default target
Alex J. Best (Jul 04 2023 at 23:44):
Then run lake update
, lake exe cache get
Kuba (Jul 05 2023 at 00:12):
Thank you for the help with importing Mathlib, it works now.
I inserted by convert
before the proof and this is what I got (code+infoview contents in the comments):
import Mathlib.Tactic.Convert
theorem tmp1 : ∀ n : Nat, n > 0 → n - 1 < n :=
λ _ => λ h => Nat.sub_lt h (Nat.zero_lt_succ 0)
theorem tmp2 : ∀ n m k : Nat, n < m → n - k < m :=
λ n _ k => λ h => Nat.lt_of_le_of_lt (Nat.sub_le n k) h
theorem tmp3 : ∀ n m : Nat, 0 < n → n - 1 - m < n :=
λ n m => λ h => tmp2 (n - 1) n m (tmp1 n h)
theorem tmp6.{u} {α : Type u} :
∀ as bs : List α, (List.reverseAux as bs).length = as.length + bs.length :=
λ as bs =>
match as with
| [] => Eq.symm (Nat.zero_add bs.length)
| a :: as =>
Eq.trans (tmp6 as (a :: bs)) (
Eq.trans (Nat.add_succ as.length bs.length) (
Eq.symm (Nat.succ_add as.length bs.length)))
theorem tmp7.{u} {α : Type u} : ∀ as bs : List α,
as.length <= (List.reverseAux as bs).length :=
λ as bs => Eq.subst (Eq.symm (tmp6 as bs)) (Nat.le_add_right as.length bs.length)
theorem tmp9 : ∀ m n : Nat, m < n → n > 0 :=
λ m _ => λ h => Nat.lt_of_le_of_lt (Nat.zero_le m) h
theorem tmp14 : ∀ n m k : Nat, n - m - k = n - k - m :=
λ n m k => Eq.trans
(Eq.subst (motive := λ x => n - m - k = n - x)
(Nat.add_comm m k) (Nat.sub_sub n m k))
(Eq.symm (Nat.sub_sub n k m))
theorem tmp13.{u} {α : Type u} : ∀ a : α, ∀ as : List α, ∀ n : Nat,
(a :: as).length - 1 - (Nat.succ n) = as.length - 1 - n :=
λ a => λ as => λ n => Eq.trans
(Eq.subst (motive := λ x => (a::as).length - 1 - (Nat.succ n) = x - 1)
(Nat.succ_sub_succ as.length n) (tmp14 (a :: as).length 1 (Nat.succ n)))
(tmp14 as.length n 1)
theorem tmp10.{u} {α : Type u} : ∀ as bs : List α, ∀ n : Nat, (h : n < as.length) →
(List.reverseAux as bs).get ⟨as.length - 1 - n,
Nat.lt_of_lt_of_le (tmp3 as.length n (tmp9 n as.length h)) (tmp7 as bs)⟩ =
as.get ⟨n, h⟩ := by convert
λ as bs => λ n => λ h =>
match as, n with
| x :: xs, Nat.succ m => (Eq.subst
(motive := λ y => (List.reverseAux xs (x :: bs) ).get ⟨y, _⟩ = xs.get ⟨m, _⟩)
(Eq.symm (tmp13 x xs m))
(tmp10 xs (x :: bs) m (Nat.lt_of_succ_lt_succ h)))
| [], _ => ()
/-
α : Type u
⊢ ∀ (as bs : List α) (n : Nat) (h : n < List.length as),
List.get (List.reverseAux as bs)
{ val := List.length as - 1 - n, isLt := (_ : List.length as - 1 - n < List.length (List.reverseAux as bs)) } =
List.get as { val := n, isLt := h }
-/
/-
application type mismatch
Nat.lt_of_succ_lt_succ h
argument
h
has type
?m.1775 : Sort ?u.1766
but is expected to have type
Nat.succ m < Nat.succ (List.length xs) : Prop
-/
/-
unknown free variable '_uniq.1808'
-/
/-
type mistmatch, alternative has type
(fun y =>
List.get (List.reverseAux xs (x :: bs))
{ val := y, isLt := (_ : y < List.length (List.reverseAux xs (x :: bs))) } =
List.get xs { val := m, isLt := (_ : m < List.length xs) })
(List.length (x :: xs) - 1 - Nat.succ m) : Prop
but is expected to have type
?m.1576 (x :: xs) bs (Nat.succ m) h : Sort ?u.1547
-/
which is not that helpful.
Kyle Miller (Jul 05 2023 at 00:19):
"_uniq.1808
" points to a bug somewhere (maybe the convert
tactic? maybe from some interaction between convert
and match
?)
Kuba (Jul 05 2023 at 00:20):
Do you mean a bug in my code, or in the Mathlib?
Kyle Miller (Jul 05 2023 at 00:21):
mathlib or Lean
Kyle Miller (Jul 05 2023 at 00:22):
though it could be your code too
Kyle Miller (Jul 05 2023 at 00:22):
Why is the second case of the match ()
? That's Unit
, but it looks like the goal is an equality
Kuba (Jul 05 2023 at 00:24):
It is just a stub, I have not done the other cases yet.
Kyle Miller (Jul 05 2023 at 00:27):
You'd better put sorry
rather than something that's type incorrect then
Kuba (Jul 05 2023 at 00:30):
Here is a corrected version:
import Mathlib.Tactic.Convert
theorem tmp1 : ∀ n : Nat, n > 0 → n - 1 < n :=
λ _ => λ h => Nat.sub_lt h (Nat.zero_lt_succ 0)
theorem tmp2 : ∀ n m k : Nat, n < m → n - k < m :=
λ n _ k => λ h => Nat.lt_of_le_of_lt (Nat.sub_le n k) h
theorem tmp3 : ∀ n m : Nat, 0 < n → n - 1 - m < n :=
λ n m => λ h => tmp2 (n - 1) n m (tmp1 n h)
theorem tmp6.{u} {α : Type u} :
∀ as bs : List α, (List.reverseAux as bs).length = as.length + bs.length :=
λ as bs =>
match as with
| [] => Eq.symm (Nat.zero_add bs.length)
| a :: as =>
Eq.trans (tmp6 as (a :: bs)) (
Eq.trans (Nat.add_succ as.length bs.length) (
Eq.symm (Nat.succ_add as.length bs.length)))
theorem tmp7.{u} {α : Type u} : ∀ as bs : List α,
as.length <= (List.reverseAux as bs).length :=
λ as bs => Eq.subst (Eq.symm (tmp6 as bs)) (Nat.le_add_right as.length bs.length)
theorem tmp9 : ∀ m n : Nat, m < n → n > 0 :=
λ m _ => λ h => Nat.lt_of_le_of_lt (Nat.zero_le m) h
theorem tmp14 : ∀ n m k : Nat, n - m - k = n - k - m :=
λ n m k => Eq.trans
(Eq.subst (motive := λ x => n - m - k = n - x)
(Nat.add_comm m k) (Nat.sub_sub n m k))
(Eq.symm (Nat.sub_sub n k m))
theorem tmp13.{u} {α : Type u} : ∀ a : α, ∀ as : List α, ∀ n : Nat,
(a :: as).length - 1 - (Nat.succ n) = as.length - 1 - n :=
λ a => λ as => λ n => Eq.trans
(Eq.subst (motive := λ x => (a::as).length - 1 - (Nat.succ n) = x - 1)
(Nat.succ_sub_succ as.length n) (tmp14 (a :: as).length 1 (Nat.succ n)))
(tmp14 as.length n 1)
theorem tmp10.{u} {α : Type u} : ∀ as bs : List α, ∀ n : Nat, (h : n < as.length) →
(List.reverseAux as bs).get ⟨as.length - 1 - n,
Nat.lt_of_lt_of_le (tmp3 as.length n (tmp9 n as.length h)) (tmp7 as bs)⟩ =
as.get ⟨n, h⟩ :=
λ as bs => λ n => λ h => by convert
match as, n with
| x :: xs, Nat.succ m => (Eq.subst
(motive := λ y => (List.reverseAux xs (x :: bs) ).get ⟨y, _⟩ = xs.get ⟨m, _⟩)
(Eq.symm (tmp13 x xs m))
(tmp10 xs (x :: bs) m (Nat.lt_of_succ_lt_succ h)))
| _, _ => sorry
/-
-/
/-
application type mismatch
Nat.lt_of_succ_lt_succ h
argument
h
has type
n < List.length as : Prop
but is expected to have type
Nat.succ m < Nat.succ (List.length xs) : Prop
-/
/-
unknown free variable '_uniq.1850'
-/
/-
type mistmatch, alternative has type
(fun y =>
List.get (List.reverseAux xs (x :: bs))
{ val := y, isLt := (_ : y < List.length (List.reverseAux xs (x :: bs))) } =
List.get xs { val := m, isLt := (_ : m < List.length xs) })
(List.length (x :: xs) - 1 - Nat.succ m) : Prop
but is expected to have type
?m.1806 h : Prop
-/
Kuba (Jul 05 2023 at 00:34):
The tactic state changed to No goals
and the first message looks more helpful now. But you still have the _uniq
thingy.
Last updated: Dec 20 2023 at 11:08 UTC