Zulip Chat Archive
Stream: new members
Topic: Existsi type mismatch between given term witness and...
Sara Fish (Jul 14 2021 at 21:52):
Extremely basic question. In this simple example
def divides (a b : ℤ ) := ∃ k , b = a * k
lemma a_div_a : ∀ (a : ℤ), divides a a :=
begin
intros a,
unfold divides,
existsi 1,
refl,
end
I get the error
existsi tactic failed, type mismatch between given term witness and expected type
and I am not sure why. Why doesn't the goal turn into this?
⊢ ∃ (k : ℤ), a = a * k
After all, the "expected type" should be in ℤ and 1 is in ℤ.
Andrew Elsey (Jul 14 2021 at 22:08):
Not positive if it will solve your problem, but Lean is finicky about 1's and 0's. I think by default Lean'll assume 1 or 0 is a natural number. You'll have to cast 1 to the type you're expecting (i.e., (1 : Q)). Lifting may also work. It can be misleading as it's just written as 1 or 0 in the goal state, and you'd hope Lean can just figure out which type you're referring to.
Kevin Buzzard (Jul 14 2021 at 22:21):
existsi
is quite a primitive tactic in core Lean which doesn't take any clues from the context about what kind of 1 it needs. If Lean sees a 1 with no extra clues it assumes it's a natural 1. The use
tactic is a more sophisticated tactic available in mathlib so if you add import tactic
to the top of your file then use 1
will work fine. refl
won't work though :-)
Kyle Miller (Jul 14 2021 at 22:27):
@Sara Fish Elaborating what @Andrew Elsey said, here's how you can fix the proof:
lemma a_div_a : ∀ (a : ℤ), divides a a :=
begin
intros a,
unfold divides,
existsi (1 : ℤ),
rw mul_one,
end
Here's @Kevin Buzzard's suggestion:
import tactic
lemma a_div_a : ∀ (a : ℤ), divides a a :=
begin
intros a,
use 1,
rw mul_one,
end
Kyle Miller (Jul 14 2021 at 22:28):
By the way, if a proof starts with intro
, it's common practice to put the argument before the colon:
lemma a_div_a (a : ℤ) : divides a a :=
begin
use 1,
rw mul_one,
end
Kyle Miller (Jul 14 2021 at 22:31):
And if you want to compress it even more, you can use the constructor for Exists
directly:
lemma a_div_a (a : ℤ) : divides a a := ⟨1, by rw mul_one⟩
Angle brackets are a way to use a constructor without specifying its name. Lean will try to figure out which one you mean.
Sara Fish (Jul 14 2021 at 23:12):
Thanks all! This was helpful.
Last updated: Dec 20 2023 at 11:08 UTC