Zulip Chat Archive
Stream: new members
Topic: Contradiction fails when context contains proof of false
Josiah Eldon Bills (Oct 04 2022 at 04:59):
I am working on a fairly complex proof where in part of the proof I get a contradiction by simplifying using x=a
at a hypothesis not (a = x)
, thus yielding a term of type false
. Normally I can just close the current goal with contradiction
, but in this case I get an error. Below you can see my context, my goal, and the (quite unhelpful) error I get:
contradiction tactic failed
state:
4 goals
case or.inl
α : Type u_1,
_inst_1 : decidable_eq α,
a : α,
this : ∀ (l : list (list α)), l.length > 1 → [a].intercalate [l.head, [a].intercalate l.tail] = [a].intercalate l,
hd : α,
tl : list α,
ih :
∀ (l : list α),
a ∈ l → (let s : list α × list α := list.split_on_first a l in l = tl → (list.split_on a tl).length > 1),
l : list α,
s : list α × list α := list.split_on_first a l,
h : l = hd :: tl,
list_contains : a ∈ hd :: tl,
or : a = hd,
h_1 : false
⊢ (let or : a = hd ∨ a ∈ tl := list.eq_or_mem_of_mem_cons list_contains in a ∈ tl) (_root_.or.inl or)
I can post the full context if need be, but it is quite long.
Damiano Testa (Oct 04 2022 at 05:12):
Does exact h_1.elim
work at that point?
Damiano Testa (Oct 04 2022 at 05:14):
(At least for me, a #mwe, even if not too minimized), would be helpful.)
Josiah Eldon Bills (Oct 04 2022 at 05:18):
I get the following error when I try that. Similarly, if I try to use exact absurd
:
infer type failed, function expected at
(let or : a = hd ∨ a ∈ tl := list.eq_or_mem_of_mem_cons list_contains in a ∈ tl) (or.inl hypothesis)
term
let or : a = hd ∨ a ∈ tl := _
in a ∈ tl
has type
Prop
Damiano Testa (Oct 04 2022 at 05:21):
and also refine false.elim _,
gives an error?
Damiano Testa (Oct 04 2022 at 05:21):
or apply false.elim,
?
Josiah Eldon Bills (Oct 04 2022 at 05:23):
The former gives
infer type failed, function expected at
(let or : a = hd ∨ a ∈ tl := list.eq_or_mem_of_mem_cons list_contains in a ∈ tl) (or.inl hypothesis)
term
let or : a = hd ∨ a ∈ tl := _
in a ∈ tl
has type
Prop
again, while the latter gives
invalid apply tactic, failed to unify
(let or : a = hd ∨ a ∈ tl := list.eq_or_mem_of_mem_cons list_contains in a ∈ tl) (or.inl hypothesis)
with
?m_1
Josiah Eldon Bills (Oct 04 2022 at 05:25):
Here is the theorem:
def list.split_on_first {α: Type*} [decidable_eq α] (a: α) (l: list α) : list α × list α :=
let s := l.split_on a in
(s.head, [a].intercalate s.tail)
theorem list.split_on_first.infix {α: Type*} [decidable_eq α] (a: α) (l: list α) : a ∈ l → let s := list.split_on_first a l in l = s.1 ++ [a] ++ s.2 :=
begin
intros list_contains s,
suffices : [a].intercalate [s.1, s.2] = l,
{
let intercalate_append : [a].intercalate [s.1, s.2] = s.1 ++ [a] ++ s.2 := by simp [list.intercalate],
rw ←intercalate_append,
symmetry,
exact this,
},
suffices : ∀l: list (list α), l.length > 1 → [a].intercalate [l.head, [a].intercalate l.tail] = [a].intercalate l,
{
suffices split_len : (list.split_on a l).length > 1,
{
specialize this (list.split_on a l) split_len,
rw list.intercalate_split_on l a at this,
exact this
},
induction h: l generalizing l,
simp [h] at list_contains,
contradiction,
simp only [list.split_on, list.split_on_p_cons],
split_ifs,
{
simp [list.split_on_p_ne_nil],
cases th: list.split_on_p (λ (_x : α), _x = a) tl,
simp [list.split_on_p_ne_nil] at th,
contradiction,
simp [th]
},
rw h at list_contains,
let : a ∈ tl,
{
let or := list.eq_or_mem_of_mem_cons list_contains,
cases or with hypothesis,
simp [hypothesis] at h_1,
contradiction,
exact h_2,
},
let induction := ih tl this (eq.refl _),
rw ←list.split_on,
cases (list.split_on a tl),
simp at induction,
contradiction,
simp at induction,
simp [induction],
},
intros lol lol_size_2,
cases lol,
simp at lol_size_2,
contradiction,
cases lol_tl,
simp at lol_size_2,
contradiction,
simp [list.intercalate],
end
The error occurs in the proof of let : a ∈ tl,
.
Josiah Eldon Bills (Oct 04 2022 at 05:27):
I found that if you use cases dont_care: or with hypothesis,
then this works just fine.
Josiah Eldon Bills (Oct 04 2022 at 05:28):
If you do this then the goal remains a ∈ tl
, while if you don't then the goal gets a whole bunch of garbage thrown in it.
Damiano Testa (Oct 04 2022 at 05:29):
what happens if you type intros
first?
Damiano Testa (Oct 04 2022 at 05:32):
This works:
{
have or := list.eq_or_mem_of_mem_cons list_contains,
cases or with hypothesis,
simp [hypothesis] at h_1,
contradiction,
exact or,
},
I used have
instead of let
.
Damiano Testa (Oct 04 2022 at 05:33):
Even though this does not seem to be causing problems, I am very skeptical about calling a variable with the name of an existing function such as or
...
Damiano Testa (Oct 04 2022 at 05:35):
Briefly, let
is for introducing "shorthand" notation for something, while have
is for introducing extra hypotheses. In your situation, I think that you used let
to mean "let us call or
the hypothesis a = hd ∨ a ∈ tl
". In Lean, this is done by using have
, not let
.
Josiah Eldon Bills (Oct 04 2022 at 05:37):
The name point is well made, I will change it. It isn't the cause of the issue though. Why does this bubble down to cause issues in cases
?
Damiano Testa (Oct 04 2022 at 05:48):
I do not know, but the cases
on the let
mangles the type of the target. I am actually not sure about what the precise effect is, but Lean is not very happy with it either.
Damiano Testa (Oct 04 2022 at 06:37):
When you use let
you are informing Lean that you will use or
to mean whatever you say it is. At this stage, I suspect that lean thinks that or
is the Prop that it displays, not its proof.
I imagine that, to Lean, what you wrote was not very different than let or := A ∨ B
, with A B : Prop
completely arbitrary, with no indication that actually at least one of them is true.
Kevin Buzzard (Oct 04 2022 at 07:36):
let
changes the goal. It's not the correct tactic to use when defining a proof, have
is.
Damiano Testa (Oct 04 2022 at 07:45):
Indeed, here is a smaller version of the same issue as above:
import logic.basic
example {p : Prop} : true :=
begin
let or1 : p ∨ ¬ p := em p,
cases or1,
trivial, -- fails
end
Last updated: Dec 20 2023 at 11:08 UTC