-
Notifications
You must be signed in to change notification settings - Fork 299
feat(algebra/algebra/non_unital): define non-unital, non-associative algebras #6591
Conversation
af6205e
to
f2db64d
Compare
Despite initial reluctance, I am beginning to be persuaded. The names are not serious suggestions, especially as if this works, what we are really defining is non-unital algebras since we can make the existing `algebra` definition allow for non-associativity for free. For now I just want to see whether this compiles.
_Probably_ a more useful set of ancestors.
For reasons I haven't tried to understand this breaks the proof of `multiset.prod_map_add`. Having seen this, I think it's best to revert this since there's already plenty of surface area in these changes to break things.
If this doesn't work, I think I'll give up on inserting `mul_one_class` / `add_zero_class` into the `monoid` / `add_monoid` definitions.
The most recent build failure (topology/locally_constant/algebra.lean:52:73) has persuaded me to abandon this part of the work. It could be done but it's too much of a diversion / time sink in what is already a tangent.
08435fd
to
accef2a
Compare
Co-authored-by: Eric Wieser <wieser.eric@gmail.com>
…fs of `non_unital_non_assoc_algebra_hom` This has the advantage over the previous of avoiding a typeclass search.
The breakage is due to the instances placed in `algebra/ring/basic` in commit 4601470. I'm yet sure of any of the following: 1. If the fixes here are sufficient 2. Why the instances are apparently causing the elaborator to fail 3. Whether the changes here are the right way to address this issue I'll wait and see the answer to 1 and then try to understand better.
Looking very likely I'll close this PR eventually. In particular see #6723 (comment) |
🎉 Great news! Looks like all the dependencies have been resolved: 💡 To add or remove a dependency please update this issue/PR description. Brought to you by Dependent Issues (:robot: ). Happy coding! |
Do you think it's worth merging the latest master into this anyway to see what's left, or not? |
(smul_mul_assoc' : ∀ (t : R) (a b : A), (t • a) * b = t • (a * b)) | ||
(mul_smul_comm' : ∀ (t : R) (a b : A), a * (t • b) = t • (a * b)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this made it into a zulip message, but is worth recording in this PR too: these two conditions are respectively [is_scalar_tower R A A]
and (modulo symmetry) [smul_comm_class R A A]
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At least, it would be if we added has_mul.to_has_scalar
, since monoid.to_mul_action
can't apply here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, hadn't forgotten but good to get this reminder.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just might take advantage of this approach so I'll record the following snippet for emphasis:
import linear_algebra.basic
variables (R A : Type*) [semiring R] [non_unital_non_assoc_semiring A] [module R A]
variables (t : R) (a b : A)
example [smul_comm_class R A A] : a * (t • b) = t • (a * b) := (smul_comm t a b).symm
example [is_scalar_tower R A A] : (t • a) * b = t • (a * b) := smul_assoc t a b
Incidentally, the scalar action of A
on itself is obtained from the combination of:
non_unital_non_assoc_semiring.to_mul_zero_class
mul_zero_class.to_smul_with_zero
smul_with_zero.to_has_scalar
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I forgot that smul_with_zero.to_has_scalar
applied here!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wait -- so doesn't this just mean that either one doesn't need the class at all, or that one can just make the class by extending other classes?
We had this sort of thing with number fields too --
import linear_algebra.finite_dimensional
variables (K : Type*) [field K] [char_zero K] [finite_dimensional ℚ K]
is mathematically "let K be a number field" so now you start wondering whether you even need a number field typeclass (and indeed I don't think we have one)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Exactly right! Hence my remark at the top of #7847 about it being a plausible replacement for this class.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(although we do face the problem of "exponential term size" if we go too far this way)
Sure, I'll merge master in now since there's still a small chance I'll want this. My goal is to construct the free Lie algebras and I see my current options as one of the following:
Obviously 3 is the best solution but I'm reluctant to take it on for now. I'm going to see if I can get 4 to work neatly before I make a call on which option I'll take. cc @kbuzzard in case you're interested! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks fine to me, but I am not an expert in the subtleties of these things. I've left a couple of other comments.
(smul_mul_assoc' : ∀ (t : R) (a b : A), (t • a) * b = t • (a * b)) | ||
(mul_smul_comm' : ∀ (t : R) (a b : A), a * (t • b) = t • (a * b)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wait -- so doesn't this just mean that either one doesn't need the class at all, or that one can just make the class by extending other classes?
We had this sort of thing with number fields too --
import linear_algebra.finite_dimensional
variables (K : Type*) [field K] [char_zero K] [finite_dimensional ℚ K]
is mathematically "let K be a number field" so now you start wondering whether you even need a number field typeclass (and indeed I don't think we have one)
|
||
lemma smul_mul_assoc (t : R) (a b : A) : | ||
(t • a) * b = t • (a * b) := | ||
non_unital_non_assoc_algebra.smul_mul_assoc' t a b |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Often the point of having a primed field in a structure and an unprimed one directly afterwards is that the unprimed one can take advantage of things like coercions (e.g. it can refer to ⇑f
rather than f.to_fun
) but here it seems to me that the primed and unprimed versions are exactly the same even up to the binders. Is it clear that we need the primed ones?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed. Fortunately this PR is (hopefully) going to be closed in favour of #7847 so this detail can be forgotten. It's old and I'd guess I wrote it before I understood this convention.
Closing this in favour of alternative approach where we declare a import algebra.module.basic
variables {R A : Type*}
variables [semiring R] [non_unital_non_assoc_semiring A] [module R A]
variables [is_scalar_tower R A A] [smul_comm_class R A A] and where we use This has the disadvantage that we have larger term sizes (we need |
With sufficient refactoring effort, the
non_unital_non_assoc_algebra
proposed here could replace our extantalgebra
definition entirely. This would have the advantage that whether we wish to specialize to unital / associative algebras would then be controlled entirely by whether we pass anon_assoc_semiring
/non_unital_semiring
/ ... as the unbundled typeclass.The extant
algebra
definition uses both the existence of units and associativity. However the path to remove its dependence on associativity looks fairly easy since this arises through the redundant requirement of associativity inring_hom
(viamonoid_hom
) in the usual way: an overly proscriptive typeclass. I actually explored relaxing this (i.e., changing[monoid M]
to[has_mul M] [has_one M]
in the definition ofmonoid_hom
) but I quickly ran into difficulties associated withto_additive
magic.I also experimented with using the
mul_one_class
andadd_zero_class
in the definitions ofmonoid
andadd_monoid
and ran into trouble. However I think this could be resolved fairly easily. It's just a slow debug loop because of the long build time. Since the gain from such a change is negligible I gave up.Co-authored-by: Eric Wieser wieser.eric@gmail.com
For what it's worth, I'm defining these with the following plan in mind:
There is now a branch
replace_algebra_def
that builds off this PR and attempts to replace the definition ofalgebra
as described. It is still incomplete.