Zulip Chat Archive
Stream: new members
Topic: Use of "let" in tactic mode
Lars Ericson (Nov 26 2020 at 21:03):
The text gives this example of using let
:
example (h : ∃ x, p x ∧ q x) : ∃ x, q x ∧ p x :=
let ⟨w, hpw, hqw⟩ := h in ⟨w, hqw, hpw⟩
I am trying to adapt this to tactic mode. This works:
example (h : ∃ x, p x ∧ q x) : ∃ x, q x ∧ p x :=
begin
exact (let ⟨w, hpw, hqw⟩ := h in ⟨w, hqw, hpw⟩),
end
However, this does not work:
example (h : ∃ x, p x ∧ q x) : ∃ x, q x ∧ p x :=
begin
have h2 := (let ⟨w, hpw, hqw⟩ := h in ⟨w, hqw, hpw⟩),
exact h2,
end
I get this error:
invalid match/convoy expression, expected type is not known
state:
α : Type u_1,
p q : α → Prop,
h : ∃ (x : α), p x ∧ q x
⊢ ∃ (x : α), q x ∧ p x
My prior experience has been that this:
example foo :=
begin
have h := bar,
exact h,
end
is equivalent to this:
example foo :=
begin
exact bar,
end
Why does the equivalence not hold in the above case?
Logan Murphy (Nov 26 2020 at 21:06):
Looking at your tactic state, i think you just need to switch
have h2 := (let ⟨w, hpw, hqw⟩ := h in ⟨w, hqw, hpw⟩),
to
have h2 := (let ⟨w, hpw, hqw⟩ := h in ⟨w, hpw, hqw⟩),
Logan Murphy (Nov 26 2020 at 21:07):
i.e. right now p and q don't match up exactly with the goal, they are swapped
Reid Barton (Nov 26 2020 at 21:08):
The error message sort of tells you the reason. If your goal is foo
and you write exact bar
, then Lean knows that bar
is supposed to have type foo
and it can use this to make sense of bar
. If you write have h := bar
, then Lean doesn't know what you are intending to do with h
and it has to make sense of bar
in isolation, and usually this is harder.
Reid Barton (Nov 26 2020 at 21:08):
If you write have h : foo := bar
then Lean has the same information again.
Lars Ericson (Nov 26 2020 at 21:12):
Thank you @Reid Barton :
example (h : ∃ x, p x ∧ q x) : ∃ x, q x ∧ p x :=
begin
have h2 : ∃ x, q x ∧ p x := (let ⟨w, hpw, hqw⟩ := h in ⟨w, hqw, hpw⟩),
exact h2,
end
Reid Barton (Nov 26 2020 at 21:18):
This is a very unnatural way to write the proof of course
Reid Barton (Nov 26 2020 at 21:18):
The (mathlib) tactic equivalent to let
with a pattern is obtain
Reid Barton (Nov 26 2020 at 21:20):
import tactic.basic
example (a : Type) (p q : a -> Prop) (h : ∃ x, p x ∧ q x) : ∃ x, q x ∧ p x :=
begin
obtain ⟨w, hpw, hqw⟩ := h,
exact ⟨w, hqw, hpw⟩,
end
Lars Ericson (Nov 26 2020 at 21:38):
@Reid Barton if I try to use obtain ⟨w, hpw, hqw⟩ := h
to unpack h : ∃ (x : α), p x ∧ r
where the current goal state is:
27:6: goal
α : Type u_1,
p : α → Prop,
r : Prop,
h : ∃ (x : α), p x ∧ r
⊢ r
in this example:
example : (∃ x, p x ∧ r) ↔ (∃ x, p x) ∧ r :=
begin
split,
{
intro h,
split,
{
cases h with x pxr,
have px := pxr.left,
constructor, -- two open goals at this point
exact px, -- no goals here
},
obtain ⟨w, hpw, hqw⟩ := h,
},
sorry,
end
a lot of errors result:
Display GoalDisplay Messages
27:4: error:
unknown identifier 'obtain'
27:12: error:
unknown identifier 'w'
27:15: error:
unknown identifier 'hpw'
27:20: error:
unknown identifier 'hqw'
27:25: error:
invalid 'begin-end' expression, ',' expected
27:4: error:
don't know how to synthesize placeholder
context:
α : Type u_1,
p : α → Prop,
r : Prop
⊢ Type ?
Reid Barton (Nov 26 2020 at 21:39):
Yes, it's in mathlib
Lars Ericson (Nov 26 2020 at 21:42):
I see tactic.interactive.obtain but I get the same error even if I open it:
open tactic.interactive
example : (∃ x, p x ∧ r) ↔ (∃ x, p x) ∧ r :=
begin
split,
{
intro h,
split,
{
cases h with x pxr,
have px := pxr.left,
constructor, -- two open goals at this point
exact px, -- no goals here
},
obtain ⟨w, hpw, hqw⟩ := h,
},
sorry,
end
If I try to use the full name of obtain
:
open tactic.interactive
example : (∃ x, p x ∧ r) ↔ (∃ x, p x) ∧ r :=
begin
split,
{
intro h,
split,
{
cases h with x pxr,
have px := pxr.left,
constructor, -- two open goals at this point
exact px, -- no goals here
},
tactic.interactive.obtain ⟨w, hpw, hqw⟩ := h,
},
sorry,
end
then I get this:
Display GoalDisplay Messages
29:31: error:
unknown identifier 'w'
29:34: error:
unknown identifier 'hpw'
29:39: error:
unknown identifier 'hqw'
29:44: error:
invalid 'begin-end' expression, ',' expected
29:4: error:
unknown identifier 'tactic.interactive'
29:22: error:
invalid field notation, type is not of the form (C ...) where C is a constant
⁇
has type
?m_1
29:4: error:
don't know how to synthesize placeholder
context:
α : Type u_1,
p : α → Prop,
r : Prop
⊢ Type ?
Reid Barton (Nov 26 2020 at 21:43):
You need to import it, not open it
Reid Barton (Nov 26 2020 at 21:43):
Er, import some module which exports it (basically all of mathlib)
Lars Ericson (Nov 26 2020 at 23:17):
@Reid Barton , switching import
for open
didn't obtain obtain
. It's OK, I did it without it. It turns out I can instantiate an existential with cases
:
open classical
variables (α : Type*) (p q : α → Prop)
variable r : Prop
example : (∃ x, p x ∧ r) ↔ (∃ x, p x) ∧ r :=
begin
split,
{
intro h,
split,
{
cases h with x pxr,
have px := pxr.left,
constructor,
exact px,
},
{
cases h with x pxr,
exact pxr.right,
}
},
{
intro h,
cases h with h1 h2,
cases h1 with x px,
have hpxr := and.intro px h2,
constructor,
exact hpxr,
},
end
Reid Barton (Nov 27 2020 at 00:01):
import tactic.basic
Last updated: Dec 20 2023 at 11:08 UTC