Zulip Chat Archive
Stream: general
Topic: beefing up `convert`
Kevin Buzzard (Jan 22 2022 at 18:35):
I might have asked this before but I can't find the thread; perhaps someone already told me why this can't happen. I can imagine a beefed-up convert
which makes much more progress on the goals below.
import tactic
import data.real.basic
-- proof that aₙ → t implies -aₙ → -t
example {a : ℕ → ℝ} {t : ℝ}
(ha : ∀ (ε : ℝ), 0 < ε → (∃ (B : ℕ), ∀ (n : ℕ), B ≤ n → |a n - t| < ε)) :
∀ (ε : ℝ), 0 < ε → (∃ (B : ℕ), ∀ (n : ℕ), B ≤ n → | -a n - -t| < ε) :=
begin
convert ha, -- using 4 or whatever
-- want: ∀ n, |a n - t| = | -a n - -t|
-- but get
-- ⊢ ∀ ε, ... = ∀ ε, ...
sorry,
--
end
-- workaround
example {a : ℕ → ℝ} {t : ℝ}
(ha : ∀ (ε : ℝ), 0 < ε → (∃ (B : ℕ), ∀ (n : ℕ), B ≤ n → |a n - t| < ε)) :
∀ (ε : ℝ), 0 < ε → (∃ (B : ℕ), ∀ (n : ℕ), B ≤ n → | -a n - -t| < ε) :=
begin
-- I want this to be the goal so I don't have to type it
have : ∀ n : ℕ, |a n - t| = | -a n - -t|,
{ intro n,
rw abs_sub_comm,
congr' 1,
ring },
simpa [this] using ha,
end
-- minimised convert "failure"
example (P Q R : Prop) (h : P → Q) : P → R :=
begin
convert h,
-- ⊢ (P → R) = (P → Q)
-- Why not `R = Q` or `R ↔ Q`?
sorry,
end
example (f : ℕ → ℝ) (a b : ℝ) (h : ∀ n, f n = a) : ∀ n, f n = b :=
begin
convert h, -- expecting `b = a`
-- ⊢ (∀ (n : ℕ), f n = b) = ∀ (n : ℕ), f n = a
sorry
end
Reid Barton (Jan 22 2022 at 18:46):
So the first-order explanation is that congr
checks for a function application, and a Pi/forall/function type (P → R
) is not a function application
Reid Barton (Jan 22 2022 at 18:47):
But, I don't see why congr
couldn't also try applying a suitable version of docs#forall_congr (followed by intro
) and then continuing
Kyle Miller (Jan 22 2022 at 18:51):
This reminds me of a tactic I wrote as an exercise that does sort of what you want here. https://leanprover.zulipchat.com/#narrow/stream/217875-Is-there.20code.20for.20X.3F/topic/Automatic.20intro.2Fcases.2Fspecialize.2Fuse.20dance/near/203997071
Kyle Miller (Jan 22 2022 at 18:51):
example {a : ℕ → ℝ} {t : ℝ}
(ha : ∀ (ε : ℝ), 0 < ε → (∃ (B : ℕ), ∀ (n : ℕ), B ≤ n → |a n - t| < ε)) :
∀ (ε : ℝ), 0 < ε → (∃ (B : ℕ), ∀ (n : ℕ), B ≤ n → | -a n - -t| < ε) :=
begin
enter ha with ε εpos B n hB,
/-
a : ℕ → ℝ,
t ε : ℝ,
εpos : 0 < ε,
B n : ℕ,
hB : B ≤ n,
ha : |a n - t| < ε
⊢ | -a n - -t| < ε
-/
sorry
end
example (P Q R : Prop) (h : P → Q) : P → R :=
begin
enter h with hP,
/-
P Q R : Prop,
hP : P,
h : Q
⊢ R
-/
sorry,
end
example (f : ℕ → ℝ) (a b : ℝ) (h : ∀ n, f n = a) : ∀ n, f n = b :=
begin
enter h with n,
/-
f : ℕ → ℝ,
a b : ℝ,
n : ℕ,
h : f n = a
⊢ f n = b
-/
sorry
end
Kyle Miller (Jan 22 2022 at 18:51):
Code
Kyle Miller (Jan 22 2022 at 19:01):
Reid Barton said:
But, I don't see why
congr
couldn't also try applying a suitable version of docs#forall_congr (followed byintro
) and then continuing
Maybe convert
/congr
could get a with
clause so you can name those variables being introduced?
Eric Wieser (Jan 22 2022 at 21:41):
congr'
already has such a clause
Last updated: Dec 20 2023 at 11:08 UTC