Zulip Chat Archive
Stream: general
Topic: Proving empty vector is nil
Jordan Mitchell Barrett (Jun 26 2021 at 03:52):
Suppose I have a type family vec
parametrised by its length n : nat
:
constant A : Type
inductive vec : nat -> Type
| nil : vec 0
| cons {n:nat} : vec n -> A -> vec (n.succ)
Now, I want to show that any vec 0
has to be nil
:
theorem vec_zero_is_nil (v : vec 0) : v = vec.nil
I can't work out how to prove this, though. The obvious way seems to be to destruct v
. The cons
case gives an easy contradiction, but in the nil
case, I get a hypothesis v == vec.nil
. What does this ==
mean, and how can I deduce that v = vec.nil
?
Mario Carneiro (Jun 26 2021 at 04:51):
The usual way to spell coq's destruct
in lean is cases
and it seems to do the right thing here:
theorem vec_zero_is_nil (v : vec 0) : v = vec.nil :=
by { cases v, refl }
Kyle Miller (Jun 26 2021 at 17:28):
Somewhat amusingly, this is one of those cases where Lean already knows it can only be vec.nil
:
constant A : Type
inductive vec : nat -> Type
| nil : vec 0
| cons {n:nat} : vec n -> A -> vec (n.succ)
theorem vec_zero_is_nil : Π (v : vec 0), v = vec.nil
| vec.nil := rfl
This is relying on the equation compiler doing case analysis and building the proof for you. In this case, I think it deduces that 0 = n.succ
has no solutions since nat.succ
is injective.
Kyle Miller (Jun 26 2021 at 17:28):
The ==
is heterogeneous equality. It appears when you have terms of equal types, and it's usually something you want to avoid since it's rather weak. However, in this case both the terms involved have the same type (not merely equal) so eq_of_heq
will do. (For the second case, I'm forgetting what I'm supposed to do, so I used the low-level nat.no_confusion
. The exfalso
is not necessary here.)
theorem vec_zero_is_nil (v : vec 0) : v = vec.nil :=
begin
destruct v,
{ intros he h,
apply eq_of_heq h, },
{ intros n w a hz,
exfalso,
exact nat.no_confusion hz, },
end
Last updated: Dec 20 2023 at 11:08 UTC