Zulip Chat Archive
Stream: new members
Topic: Rewriting inside quantifiers
Daniel Roca González (Dec 28 2021 at 12:11):
I would like this to work, but it doesn't
import topology.metric_space.basic
variables {α : Type*} [metric_space α] {P : α → α → Prop}
lemma test : ∃ x y : α, P x y ∧ dist x y ≤ 2 → ∃ x y : α, P x y ∧ dist y x ≤ 2 :=
begin
rw dist_comm, -- rewrite tactic failed, did not find instance of the pattern in the target expression dist ?m_3 ?m_4
tauto
end
Using dist_comm would make the lemma trivial, but Lean doesn't seem to be able to rewrite "inside quantifiers". Is there a nice way to get it to do this? The obvious solution would be to rcases
to get x
and y
, use
them and rewrite, but that would be disappointing.
Mario Carneiro (Dec 28 2021 at 12:11):
you can either use conv
to enter the binder, or use simp
or simp_rw
, which can rewrite under binders
Daniel Roca González (Dec 28 2021 at 12:22):
I see thank you, I will look into conv
Daniel Roca González (Dec 28 2021 at 12:37):
A version using conv (closer to what I actually need), it's still longer than using intro and cases though...
import topology.metric_space.basic
variables {α : Type*} [metric_space α] {P : α → α → Prop}
lemma test : (∃ r, ∀ x y : α, P x y ∧ dist x y ≤ r) → ∃ r, ∀ x y : α, P y x ∧ dist x y ≤ r :=
begin
conv in (∃ r, ∀ x y : α, P y x ∧ dist x y ≤ r)
begin
congr, funext,
rw forall_swap,
find (dist _ _) {rw dist_comm},
end,
tauto,
end
Stuart Presnell (Dec 28 2021 at 13:26):
Does simp_rw dist_comm
work for this?
Patrick Johnson (Dec 28 2021 at 17:27):
rw
cannot rewrite under binders, but simp_rw
can:
example {α : Type*} [metric_space α] {P : α → α → Prop} :
(∃ (x y : α), P x y ∧ dist x y ≤ 2) →
(∃ (x y : α), P x y ∧ dist y x ≤ 2) :=
by simp_rw dist_comm; exact id
Also, note that your original example is incorrect. Parentheses around the first existential quantifier are not optional. The statement
∃ x y : α, P x y ∧ dist x y ≤ 2 → ∃ x y : α, P x y ∧ dist y x ≤ 2
is interpreted as
∃ x y : α, (P x y ∧ dist x y ≤ 2 → ∃ x y : α, P x y ∧ dist y x ≤ 2)
which is not true, because a metric space can be empty:
example : ¬Π {α : Type*} [h₁ : metric_space α] {P : α → α → Prop}
(dist : α → α → ℝ)
(h₂ : dist = h₁.to_pseudo_metric_space.to_has_dist.dist),
∃ (x y : α), P x y ∧ dist x y ≤ 2 →
(∃ (x y : α), P x y ∧ dist y x ≤ 2) :=
begin
rw not_forall, use empty, push_neg,
refine ⟨by split; intro x; cases x, _⟩,
refine ⟨by intro x; cases x, _⟩,
refine ⟨by intro x; cases x, _⟩,
refine ⟨by ext x; cases x, _⟩,
intro x, cases x,
end
Kyle Miller (Dec 28 2021 at 18:22):
I've been unsure about precisely what it means when we say "rw
cannot rewrite under binders," because it definitely can sometimes.
example (p q : Prop) (h : p ↔ q) : (∀ x : ℕ, p) ↔ (∀ x : ℕ, q) := by rw h -- OK
example (p q : ℕ → Prop) (h : p = q) : (∀ x : ℕ, p x) ↔ (∀ x : ℕ, q x) := by rw h -- OK
example (p q : ℕ → Prop) (h : ∀ x, p x = q x) : (∀ x : ℕ, p x) ↔ (∀ x : ℕ, q x) := by rw h -- fails
Is the rule actually "rw
cannot rewrite subexpressions containing bound variables"?
Ruben Van de Velde (Dec 28 2021 at 18:50):
That sounds like an accurate summary, yeah
Daniel Roca González (Dec 28 2021 at 20:16):
@Stuart Presnell gives me "simplify tactic failed to simplify"
Daniel Roca González (Dec 28 2021 at 20:21):
Patrick Johnson said:
rw
cannot rewrite under binders, butsimp_rw
can:example {α : Type*} [metric_space α] {P : α → α → Prop} : (∃ (x y : α), P x y ∧ dist x y ≤ 2) → (∃ (x y : α), P x y ∧ dist y x ≤ 2) := by simp_rw dist_comm; exact id
That's nice, but it doesn't work in my (second, correct) example, and I have no idea what the diference is. That is how I would expect it to work.
Patrick Johnson (Dec 28 2021 at 20:39):
-- Without using dist_comm
lemma test :
(∃ r, ∀ x y : α, P x y ∧ dist x y ≤ r) →
∃ r, ∀ x y : α, P y x ∧ dist x y ≤ r :=
λ ⟨r, h⟩, ⟨r, λx y, ⟨(h y x).1, (h x y).2⟩⟩
Patrick Johnson (Dec 28 2021 at 20:44):
or if you insist to use dist_comm
:
lemma test :
(∃ r, ∀ x y : α, P x y ∧ dist x y ≤ r) →
∃ r, ∀ x y : α, P y x ∧ dist x y ≤ r :=
begin
rintro ⟨r, h⟩,
rw forall_swap at h,
simp_rw dist_comm at h, -- works
exact ⟨r, h⟩,
end
Patrick Johnson (Dec 28 2021 at 20:53):
Daniel Roca González said:
it doesn't work in my (second, correct) example, and I have no idea what the diference is.
I'm not sure what your question exactly is. The two examples you showed are different statements. I don't think you can simplify the proof of the second one too much further.
Kyle Miller (Dec 28 2021 at 21:01):
Another proof, using the contextual
configuration for simp
(this causes it to use p
in p -> q
when simplifying q
).
example {α : Type*} [metric_space α] {P : α → α → Prop} :
(∃ (x y : α), P x y ∧ dist x y ≤ 2) →
(∃ (x y : α), P x y ∧ dist y x ≤ 2) :=
by simp [dist_comm] { contextual := tt }
Stuart Presnell (Dec 28 2021 at 21:37):
Ah, I think this is the crucial missing piece of the puzzle!
Last updated: Dec 20 2023 at 11:08 UTC