Open urkud opened 1 year ago
From another Zulip thread:
I'm somewhat wary of the (p : (A → B) → Prop)
predicates as parameters to the classes. These can have quite nontrivial equalities and equivalences that typeclasses cannot see through, or see through only very slowly. For example: if someone writes a monoid hom when an additive hom is expected, will Lean end up trying to unify *
with +
? This tends to get expensive quite quickly. Quite probably, we're okay as long as we stick to predicates of the form structure IsMonoidHom extends IsMulHom, IsOneHom
(rather than IsMonoidHom := IsMulHom ∧ IsOneHom
; we'd also avoid issues that would arise if someone writes the predicate as IsOneHom ∧ IsMulHom
).
I tried rewriting Algebra.Hom.Group
, replacing the bundled hom structure
s with abbrev
s for BundledHom
.
It was quite tedious to replace the nice where
syntax with property := { map_mul := sorry, map_one := sorry }
. Is there a way to define a "custom constructor" for an abbrev
type, of the form MonoidHom.mk : ∀ (f : A → B) (map_one : f 1 = 1) (map_mul : ∀ x y, f (x * y) = f x * f y), BundledHom A B IsMonoidHom
?
I kept the HomClass
es around, which saved a lot of refactoring. Of course that meant that there wasn't much improvement in actual ease of use over the existing situation.
Some notes:
ComposablePred
instances for conjunctions of predicates (like IsMonoidHom
from IsMulHom
and IsOneHom
) gets tedious very quickly. Can we automate this somehow?outParam
in my attempts at ComposablePred
and InvertiblePred
, it seems even in basic files each parameter has to be inferred. In Lean 4 metavariables are allowed in instance search goals, so we could choose to use no outParam
s at all (as long as we keep the search space small enough).MulHom
with a MonoidHom
by adding an instance for ComposablePred p q r
from ComposablePred p' q' r
that takes in WeakerPred p p'
and WeakerPred q q'
? (Or maybe weaken p
and q
separately?)It was quite tedious to replace the nice
where
syntax withproperty := { map_mul := sorry, map_one := sorry }
. Is there a way to define a "custom constructor" for anabbrev
type, of the formMonoidHom.mk : ∀ (f : A → B) (map_one : f 1 = 1) (map_mul : ∀ x y, f (x * y) = f x * f y), BundledHom A B IsMonoidHom
?
If we want to do this, then we'll need an extended syntax. E.g., an ability to write something like
structure BundledHom α β (p : (α → β) → Prop) where
toFun : α → β
structure prop : p toFun -- or some other marker
structure IsMulHom [Mul α] [Mul β] (f : α → β) : Prop where
map_mul : ∀ x y, f (x * y) = f x * f y
def f [Mul α] : BundledHom α α IsMulHom where
toFun := id
map_mul x y := rfl
* Defining `ComposablePred` instances for conjunctions of predicates (like `IsMonoidHom` from `IsMulHom` and `IsOneHom`) gets tedious very quickly. Can we automate this somehow?
We can put mk_iff
on IsMonoidHom
, then rw [isMonoidHom_iff]; infer_instance
with an otherwise unused instance for And
.
* I struggled in Lean 3 with choosing which params to make `outParam` in my attempts at `ComposablePred`
I thought that [ComposablePred p q r]
should have r
as an outParam
, the same way we deal with ring_hom_triple
. But I never did an experiment.
* Should we allow composition of a `MulHom` with a `MonoidHom` by adding an instance for `ComposablePred p q r` from `ComposablePred p' q' r` that takes in `WeakerPred p p'` and `WeakerPred q q'`? (Or maybe weaken `p` and `q` separately?)
IMHO, we should require explicit coercions, otherwise we'll have a huge search space (e.g., how Lean should decide which predicate to use for a composition of a ring homomorphism and a linear map?).
Draft proposal, see also Zulip
Then main "pro" of this approach is that we can use a generic construction to define, e.g.,
*.comp
,*.id
, and*.End
withpow = iterate
. Also,map_mul
can be stated for aBundledHom
because coercions ofBundledEmbedding
s andBundledEquiv
s are unfolded toBundledHom
s (with two and three arrows, resp.).There are a few things I don't know how to do with this approach yet:
MulEquiv
toMonoidHom
; maybe,instead of
WeakerPred
?FunLike
s that have other data fields (e.g.,Finsupp
).MulHom
with nicewhere
syntax instead ofA similar redesign can be done with
SetLike
. Then we can haveCanMap
/CanComap
classes (inProp
) that say something likep s → p (f '' s)
withp
in different universes.