M2
M2 copied to clipboard
LeftIdeal (take two)
(This is a fresh take on https://github.com/Macaulay2/M2/pull/2912)
Ideal is a type of LeftIdeal now.
- Most functions are defined for
LeftIdeal; - the ones that make sense only for a two-sided ideal are defined for Ideal.
- The method
idealconstructs an ideal typical for the given ring: e.g.,LeftIdealfor a Weyl algebra andIdealfor all other algebras: e.g., polynomial ring, skew-commutative ring,AssociativeAlgebra, etc.
Current state:
- there seem to be no errors in the build process
- there still may be methods that can migrate from
IdealtoLeftIdeal; currently- (clean session of M2)
#methods Idealis 223 and# methods LeftIdealis 66 - (after
needsPackage "BernsteinSato")#methods Idealis 271 and# methods LeftIdealis 151
- (clean session of M2)
Whoever is interested in noncommutative things, please look at this.
I still don't understand why we care about left ideals (or right ideals, for that matter), cf my comment in the other PR.
I still don't understand why we care about left ideals (or right ideals, for that matter), cf my comment in the other PR.
In the ideal world (pun intended), one may not care about ideals. Left, right, or two-sided --- all of them are modules (as we know and as you stressed). In the real world of M2, a design decision was made 20+ years ago to incorporate Weyl algebras and make low-level core GB functionality work for left ideals (left ideals is what $D$-modules people care about). No new type was introduced at that point. The purpose of this pull request is to correct the latter.
At some future point, once all kinds of modules are present --- left, right, two-sided, perhaps ones with multiple left/right actions --- one can come back to the discussion of not having ideals (or having all of the ideal types derived from module types).
make low-level core GB functionality work for left ideals
I don't understand. Which core GB functionality is implemented for left ideals specifically, or even ideals for that matter? I think the only GB related methods used in Dmodules and friends (raw or top level) take in the generator matrices of the given ideals, and things like gb Ideal directly call gb module I.
With that in mind, an alternative way to "correct the latter" could be to directly define left modules (for now only modules that are the image of a 1-by-n matrix), add a new subtype called LeftIdeal, redefine all Dmodule methods to take in a LeftIdeal instead of an Ideal, and give an error for ideals in Weyl algebras.
@d-torrance , I'm having problems reproducing the errors (which relate to RInterface) in the builds. I'm using brewed R on MacOS.
That bug was fixed in #3034, so merging/rebasing onto development should work!
My (possibly biased) summary of the discussion we've had. The main concern is the fact that people who only care about commutative algebra (which is probably 95% of users at the moment) could be confused by the lack of methods for Ideal (as obtained by say methods Ideal) because a lot of them have been transferred to LeftIdeal (a type which commutative algebra users don't care about, nor should they need to). It's also clear that something must be done to fix the current situation which is unsatisfactory, and it seems like the alternatives are met with even more resistance...
I do feel it's a bit early to merge this into the next release, but that's just my opinion.
Oh, I couldn't attend the meeting, but I don't think this is ready to be merged either.
I do feel it's a bit early to merge this into the next release, but that's just my opinion.
I agree with Paul's assessment. Mike suggested that we wait with it until the release after the next. It'd be good to set up a small group meeting to talk about it.
I do feel it's a bit early to merge this into the next release, but that's just my opinion.
I agree with Paul's assessment. Mike suggested that we wait with it until the release after the next. It'd be good to set up a small group meeting to talk about it.
Then mark it as a draft.
(I think I converted it back to "Draft".)
A quick comment on what seems to be the main issue with this PR for @mahrud.
What would work is just simple duplicating: e.g.,
Ideal + Ideal := lookup(symbol +,LeftIdeal,LeftIdeal)
makes methods Ideal list +.
There is probably some way to automate this so that all methods for a "vital" subtype both
get listed for the parent type by methods and
appear in the documentation. @DanGrayson, what do you think?
@mahrud, yesterday we talked about this as a general issue: my example, similar to Ideal and LeftIdeal, was List and BasicList. (Several beginners asked me over the years why they don't see apply and scan listed by methods List.) Perhaps we should be doing this duplication trick for selected types where people think "beginner confusion" is perceived to be common.
I thought a little bit about how to make methods work to show methods for ancestors after our meeting on Tuesday. One (probably not very efficient) way is unique \\ join \\ toSequence \\ methods \ ancestors X for a given class X, but I think that would give you some methods that you wouldn't actually be able to call. For example:
i1 : X = new Type of HashTable;
i2 : Y = new Type of X;
i3 : f = method();
i4 : f(X, X) := (x,y) -> 1;
i5 : f(X, Y) := (x,y) -> 2;
i6 : f(Y, X) := (x,y) -> 3;
i7 : f(Y, Y) := (x,y) -> 4;
i8 : unique \\ join \\ toSequence \\ methods \ ancestors Y
o8 = {0 => (f, X, Y) }
{1 => (f, Y, X) }
{2 => (f, Y, Y) }
{3 => (f, X, X) }
{4 => (#, HashTable) }
...
Ideally, we'd remove (f, X, X) from the list since you'll never actually get it if one of the arguments is a Y object. But that seems tricky to check.
A quick comment on what seems to be the main issue with this PR for @mahrud. What would work is just simple duplicating: e.g.,
- duplicating methods is never a good solution in my opinion.
- this is definitely not the "main" issue for me, I just gave
methodsas an example of something a beginner might be confused about. I'm objecting toIdealbeing synonymous with "two-sided ideal" in this PR because I think "a left ideal is an ideal" is a correct statement and it should mean thatLeftIdealis a type that implements some abstract methods ofIdeal.
At least in Dummit & Foote (where I first learned these things from), left ideal and right ideal are more general than ideal:
A subset I that is both a left ideal and a right ideal is called an ideal (or, for added emphasis, a two-sided ideal) of R.
Of course, if we want the inheritance in Macaulay2 to work the same way as the mathematical definitions, we have some issues:
- We don't support multiple inheritance, so there's currently no way for
Idealto be a child of bothLeftIdealandRightIdeal. - Even if we did support multiple inheritance, then what would the parents of
LeftIdealandRightIdealbe?SubsetOfRingor something like that?
Even if we did support multiple inheritance, then what would the parents of LeftIdeal and RightIdeal be? SubsetOfRing or something like that?
Module. What is the reason for differentiating them?
Even if we did support multiple inheritance, then what would the parents of LeftIdeal and RightIdeal be? SubsetOfRing or something like that?
Module. What is the reason for differentiating them?
The parent of LeftIdeal would be LeftModule, and the parent of RightIdeal would be RightModule.
The parent of LeftIdeal would be LeftModule, and the parent of RightIdeal would be RightModule.
What would their parents be? Presumably Module would inherit from LeftModule and RightModule as well. And Ideal maybe should inherit from Module in addition to the two one-sided ideal classes. The class diagram could get pretty ugly!
The parent of LeftIdeal would be LeftModule, and the parent of RightIdeal would be RightModule.
What would their parents be? Presumably
Modulewould inherit fromLeftModuleandRightModuleas well. AndIdealmaybe should inherit fromModulein addition to the two one-sided ideal classes. The class diagram could get pretty ugly!
The parents of LeftModule and RightModule would be ImmutableType.
If we introduce BiModule, then that would inherit from LeftModule and RightModule.
We don't have "QuotientModule" and "FreeModule" and "ImageModule" and "SubquotientModule". We just have "Module".
I'll explain more on Zulip soon.
Yes, but we have to decide whether Module means left module or right module, and convert to LeftModule or RightModule.
We can always introduce BiModule if we wish.
but we have to decide whether Module means left module or right module
No, it can mean both! For the same reason that Module can mean both free module or quotient module or torsion module or whatever else.
but we have to decide whether Module means left module or right module
No, it can mean both! For the same reason that
Modulecan mean both free module or quotient module or torsion module or whatever else.
No, it can't. Consider the method for Hom(Module,Module). What would it do if given a left module and a right module over R?
Either return an error or only define the method on left or right modules.
If $M$ and $N$ are both left and right $R$-modules, what would Hom(M,N) return?
I guess we could have an optional argument LeftModules, or RightModules (or something similar).
If M and N are both left and right R-modules, what would
Hom(M,N)return?
It would return a module with both left and right R-module structures.
The problem is that it eats either the left module structure, or the right module structure, leaving only the other (in the non-commutative case).
The problem is that it eats either the left module structure, or the right module structure, leaving only the other (in the non-commutative case).
I don't understand this comment. I presume you meant the left and right actions on M and N are the same, in which case the left Hom and right Hom should be identical, no?
Otherwise, like I said before, don't define Hom(Module,Module). Only define the methods that make sense, like Hom(LeftModule,LeftModule) and Hom(RightModule, RightModule).
The point is that methods installed on an abstract module type are exactly those that don't care whether it's a left or right module. If Hom cares, then it should only be defined on the appropriate specializations.
So is the idea that Module is the (possibly abstract) class of all modules, LeftModule, RightModule, and perhaps Bimodule, all inherit from Module (maybe Bimodule inherits from both LeftModule, RightModule, maybe not)? We would need Hom(LeftModule, LeftModule), Hom(RightModule, RightModule), and various versions with Bimodule. Actually, if the arguments are 2 bimodules, we would need a way of dis-ambiguating which Hom we wish to consider.
Yes, exactly.