Zulip Chat Archive
Stream: general
Topic: forall congr
Violeta Hernández (Jun 30 2022 at 12:40):
I have not once gotten forall_congr
to fire with congr
Violeta Hernández (Jun 30 2022 at 12:40):
Anyone knows what's up with that?
Violeta Hernández (Jun 30 2022 at 12:40):
It really stifles the tactic
Eric Wieser (Jun 30 2022 at 13:08):
Does congr even work on iffs?
Violeta Hernández (Jun 30 2022 at 13:10):
Wait, it doesn't?
Violeta Hernández (Jun 30 2022 at 13:10):
I thought I was just unlucky at getting it to fire
Violeta Hernández (Jun 30 2022 at 13:10):
Are you supposed to do propext, congr
then?
Eric Wieser (Jun 30 2022 at 13:37):
import tactic
example {a b c : ℕ} : a = b ↔ a = c :=
begin
congr', -- only the primed version works
sorry
end
Eric Wieser (Jun 30 2022 at 13:44):
You could change docs#tactic.congr_core' to support this
Eric Wieser (Jun 30 2022 at 13:45):
I assume you want it to do intros
too?
Eric Wieser (Jun 30 2022 at 13:45):
What should it do if the variables have different names on each side?
Eric Wieser (Jun 30 2022 at 13:47):
That is, what do you want the goal state to be here?
example {b d : ℕ} : (∀a, a = b) ↔ (∀ c, c = d) :=
begin
my_congr,
-- ???
end
Violeta Hernández (Jun 30 2022 at 13:51):
I'd expect it to use either of the possible names
Violeta Hernández (Jun 30 2022 at 13:51):
Wouldn't matter too much which one
Damiano Testa (Jun 30 2022 at 13:52):
According to congrm
, this is what you get:
import tactic.congrm
example {b d : ℕ} : (∀a, a = b) ↔ (∀ c, c = d) :=
begin
congrm ∀a, _ = _,
-- ⊢ b = d
end
Violeta Hernández (Jun 30 2022 at 13:52):
By the way, am I doing something wrong? congr'
isn't doing anything here:
import order.order_iso_nat
example {α : Type*} [partial_order α] :
(∀ (a : ℕ →o α), ∃ (n : ℕ), ∀ (m : ℕ), n ≤ m → ¬a n < a m) ↔
∀ (a : ℕ →o α), ∃ (n : ℕ), ∀ (m : ℕ), n ≤ m → a n = a m :=
by { congr', sorry }
Eric Wieser (Jun 30 2022 at 13:53):
congr'
doesn't know about forall either, but we can trivially modify it so that it does
Damiano Testa (Jun 30 2022 at 13:57):
Again, congrm
, though with some help:
example {α : Type*} [partial_order α] :
(∀ (a : ℕ →o α), ∃ (n : ℕ), ∀ (m : ℕ), n ≤ m → ¬a n < a m) ↔
∀ (a : ℕ →o α), ∃ (n : ℕ), ∀ (m : ℕ), n ≤ m → a n = a m :=
by { congrm (∀ (a : ℕ →o α), ∃ (n : ℕ), ∀ (m : ℕ), n ≤ m → (_ : Prop)),
-- ⊢ ¬⇑a n < ⇑a m ↔ ⇑a n = ⇑a m
sorry }
Violeta Hernández (Jun 30 2022 at 14:15):
Thanks! This is precisely what I was looking for
Damiano Testa (Jun 30 2022 at 14:18):
Great to hear this! Heather wanted this "congr
extension" and I think that it is a very good idea. It works on the assumption that the lhs and rhs have a similar pattern and it gives you the possibility of putting underscores on the "differing" parts, to create side-goals.
Since it works mostly up to defeq, being "the same" can be stronger or weaker than you pretty-print.
Eric Wieser (Jun 30 2022 at 14:28):
I think it would stil
Damiano Testa said:
According to
congrm
, this is what you get:
This nicely sidesteps the problem of coming up with names due to the pattern containing the names in the first place
Kyle Miller (Jun 30 2022 at 15:47):
Violeta Hernández said:
I have not once gotten
forall_congr
to fire withcongr
The short answer to this is that congr
does not use user @[congr]
lemmas. It only uses congr lemmas generated by docs#tactic.mk_congr_lemma and friends -- these are the automatically synthesized lemmas that simp
uses to navigate equalities and heterogeneous equalities.
Kyle Miller (Jun 30 2022 at 15:48):
User @[congr]
lemmas are only used in the inner workings of simp
, so they're not useless. (I was surprised they weren't used by congr
-- I'd spent a good amount of time trying to figure out what I was doing wrong to get them to fire before I realized this).
Damiano Testa (Jun 30 2022 at 15:49):
While I do not understand how the mk_congr_lemma
s are generated, the same is also true of congrm
. Except, that since the user provides a canvas to congrm
for how to snake through the congruences, it can reach where congr
does not.
Kyle Miller (Jun 30 2022 at 15:49):
I had started modifying congr'
to make use of user congruence lemmas, but it had far-reaching effects since it's used in many places and I didn't want to go through mathlib to fix everything at the time.
Kyle Miller (Jun 30 2022 at 15:51):
mk_congr_lemma
lemmas are generated in the C++ side. Roughly, it looks at a function application, sees what kinds of arguments it has, then generates a custom congruence lemma for the situation. It takes into account things like decidable
being a subsingleton.
Damiano Testa (Jun 30 2022 at 15:53):
Kyle, thanks, this helps a bit! I had explored those C++ generated congr_lemma
s via trace
ing them, but it was somewhat inefficient and left several doubts. In particular, I had completely missed decidable
issues.
Kyle Miller (Jun 30 2022 at 15:59):
Here's a description of each of the argument kinds: https://github.com/leanprover-community/lean/blob/master/src/library/congr_lemma.h#L13
Here's the same thing on the Lean side (though the docstring is a bit out of date): docs#congr_arg_kind
Damiano Testa (Jun 30 2022 at 16:01):
Thanks! Honestly, I still find it cryptic, but having seen them in action, made me accept them "a little"! :upside_down:
Last updated: Dec 20 2023 at 11:08 UTC