Zulip Chat Archive
Stream: general
Topic: is_X_hom
Scott Morrison (Apr 09 2019 at 06:54):
Thanks, @Johan Commelin, for starting to clean these up in #911.
Scott Morrison (Apr 09 2019 at 06:55):
I've long been sad that is_ring_hom.map_one
cannot be a simp
lemma, because there's no fixed symbol for it to catch on.
Scott Morrison (Apr 09 2019 at 06:57):
For other lemmas, each map_mul
and map_add
, it's less clear that they should be simp lemmas. It depends whether you're trying to push all the ring homomorphisms down (in order to use ring
, presumably), or pull them all up (hoping to get to a single homomorphism application).
Scott Morrison (Apr 09 2019 at 06:58):
We probably should have a tactic, however, for doing these rewrites.
Scott Morrison (Apr 09 2019 at 06:58):
I'm imagining hom
by default would just push all homomorphisms down through algebraic operations.
Scott Morrison (Apr 09 2019 at 06:59):
It should probably take an argument, so for example hom ring
would use the laws for ring homomorphisms.
Scott Morrison (Apr 09 2019 at 07:00):
An arrow might suffice for the mode where we want to pull the homomorphism out: either hom ←
or hom ←monoid
.
Johan Commelin (Apr 09 2019 at 07:00):
@Scott Morrison I think such a tactic is a very good idea.
Johan Commelin (Apr 09 2019 at 07:04):
Would it be hard to write such a tactic?
Scott Morrison (Apr 09 2019 at 07:04):
Let's do it. :-)
Scott Morrison (Apr 09 2019 at 07:04):
First of all, however, note the following:
Scott Morrison (Apr 09 2019 at 07:05):
the category theory library gives you an easy way to make these simp lemmas work with the simplifier directly! Observe the following:
Scott Morrison (Apr 09 2019 at 07:05):
@[simp] lemma map_mul {R S : Mon} (f : R ⟶ S) (x y : R) : f (x * y) = f x * f y := by rw is_monoid_hom.map_mul f example {R S : Mon} (f : R ⟶ S) (x y : R) : f (x * y) = f x * f y := by simp --- Lo!
Scott Morrison (Apr 09 2019 at 07:06):
What's going on here? In (x y : R)
, R
is being coerced automatically to its underlying type.
Scott Morrison (Apr 09 2019 at 07:06):
In f (x * y)
, the bundled ring morphism f
is being coerced to its underlying function.
Scott Morrison (Apr 09 2019 at 07:06):
However, because the coercion is still sitting there, simp
has something to hang on to now!
Johan Commelin (Apr 09 2019 at 07:07):
Yep. Bundled homs make simp
work
Johan Commelin (Apr 09 2019 at 07:07):
With linear_map
and alg_hom
this has been quite pleasant.
Johan Commelin (Apr 09 2019 at 07:07):
The problem is that it seems to be non-trivial to make a bundled ring_hom
also act as an add_group_hom
and as a monoid_hom
etc...
Scott Morrison (Apr 09 2019 at 07:08):
But really what I hope might happen is that everyone will stop talking about explicit functions, decorated is is_X_hom
typeclasses, and just write R ⟶ S
(with the \hom
arrow)... :-)
Johan Commelin (Apr 09 2019 at 07:08):
Chris tried unification hints. That didn't work. I don't know if plain coercions would work...
Johan Commelin (Apr 09 2019 at 07:09):
Bundling and mixing are fighting with each other...
Scott Morrison (Apr 09 2019 at 07:09):
Can we define coercions along forget.obj
and forget.map
, for all the different forgetful functors?
Scott Morrison (Apr 09 2019 at 07:11):
(if they work, they could all be generated by @[derive]
at the moment that each forget
is defined)
Scott Morrison (Apr 09 2019 at 07:11):
Anyway, that's something to think about later.
Scott Morrison (Apr 09 2019 at 07:11):
How would we write the hom
tactic?
Johan Commelin (Apr 09 2019 at 07:11):
Can we define coercions along
forget.obj
andforget.map
, for all the different forgetful functors?
I've been meaning to experiment with that. But haven't had the time to do so yet.
Patrick Massot (Apr 09 2019 at 07:12):
I think you can take inspiration from https://github.com/leanprover-community/mathlib/commit/5fe470bb216e7b3fb6639d3b964c4eee36b88713
Patrick Massot (Apr 09 2019 at 07:12):
Which is a stuff pushing tactic
Johan Commelin (Apr 09 2019 at 07:15):
@Scott, how hard is it to gather all symbols from the context that have an is_X_hom
instance?
Scott Morrison (Apr 09 2019 at 07:15):
do you mean local hypotheses that have an is_X_hom
instance?
Scott Morrison (Apr 09 2019 at 07:16):
or just subexpressions of the goal?
Johan Commelin (Apr 09 2019 at 07:16):
I guess we only care about values of X
in (add_)
{semigroup, monoid, group}
.
Scott Morrison (Apr 09 2019 at 07:16):
either is doable
Johan Commelin (Apr 09 2019 at 07:16):
The latter. The instance might not be a local hyp.
Johan Commelin (Apr 09 2019 at 07:16):
Maybe we need to infer it.
Scott Morrison (Apr 09 2019 at 07:17):
No -- the instance of course we'll find by inference. I was asking about the actual function.
Scott Morrison (Apr 09 2019 at 07:17):
By the way, the following works:
example (R S : CommRing) (f : R ⟶ S) : is_monoid_hom (f : R → S) := by apply_instance
Johan Commelin (Apr 09 2019 at 07:18):
After we have that list, we can start trying to erw
(<-
) along is_X_hom.map_Y the_symbol
for Y
in {zero, one, add, mul, pow, smul, gpow, sub, gsmul, gpow, sum, prod}
.
Scott Morrison (Apr 09 2019 at 07:18):
Yes.
Scott Morrison (Apr 09 2019 at 07:19):
That example is an interesting combination of bundling and mixing getting along!
Scott Morrison (Apr 09 2019 at 07:19):
@Johan Commelin, do you want to try out the new VS Code live share mode and write this tactic? I have ~40 minutes now.
Johan Commelin (Apr 09 2019 at 07:20):
Cool. Let me grab a bigger screen.
Kevin Buzzard (Apr 09 2019 at 08:02):
How is this done in Coq?
Kevin Buzzard (Apr 09 2019 at 08:02):
I am spending the next few days with Gonthier but I do not understand the issues in this thread well enough to be able to ask him :-(
Kevin Buzzard (Apr 09 2019 at 08:03):
If people want to teach me, that would work. We could start with "there's no fixed symbol for it to catch on". I am already lost. I don't know how simp
works and I don't know what a symbol is.
Scott Morrison (Apr 09 2019 at 08:59):
Johan, the code we wrote is on the hom-tactic
branch. That was fun. :-) We need to write lots more porcelain, but the minimal plumbing is running!
Keeley Hoek (Apr 09 2019 at 10:54):
example (R S : CommRing) (f : R ⟶ S) : is_monoid_hom (f : R → S) := by apply_instance
(For my information) why does everyone do this instead of ... := infer_instance
?
Johan Commelin (Apr 09 2019 at 10:56):
I've had cases where by apply_instance
worked and infer_instance
didn't. Don't remember the details though...
Mario Carneiro (Apr 09 2019 at 10:56):
I think by apply_instance
predates the other one
Mario Carneiro (Apr 09 2019 at 10:57):
also infer_instance
appears literally in the result term while by apply_instance
only does instance search, just like inference for []
variables
Mario Carneiro (Apr 09 2019 at 10:58):
I think infer_instance
is best used for #check
and example
things
Keeley Hoek (Apr 09 2019 at 10:59):
Cool, good to know
Sebastian Ullrich (Apr 09 2019 at 15:01):
I introduced infer_instance
just so that I could use it before the tactic framework is defined
Kevin Buzzard (Apr 12 2019 at 19:28):
Here's a concrete example of what Mario is saying. I wanted to figure out where the category structure on opens X
was coming from.
import category_theory.instances.Top.opens open category_theory open topological_space variables (X : Type*) [topological_space X] def XYZ : category (opens X) := by apply_instance def ABC : category (opens X) := infer_instance #print ABC -- useless #print XYZ -- what I wanted to know i.e. category_theory.preorder_category #check category_theory.preorder_category -- etc etc
Patrick Massot (Apr 12 2019 at 21:04):
Kevin, you do know the most efficient way would have been #check (by apply_instance : category $ opens X)
instance of this def/print dance right?
Kevin Buzzard (Apr 12 2019 at 23:02):
ha ha yes, I think Kenny showed me this trick once; I keep forgetting it.
Last updated: Dec 20 2023 at 11:08 UTC