Support #548
Printing rings with ID
Description
for some rings there is a unique implementation: RingQQ(), RingZZ(), RingQQt(n).
For all the others the constructor NewRing.. creates a new copy of the ring (in some more elaborate ring constructions it would impossible to determine whether two rings are the same).
In CoCoA-5 this fact is hidden by the friendly syntax K ::= ZZ/(3)[x,y] which calls NewRingFp(3).
I think it would be handy, when printing a ring, to print also its address, something like
/**/ Print(NewRingFp(3)); FFp(3) ("1234567") /**/ Print(NewRingFp(3)); FFp(3) ("1897634")
This would make it easier for the user to understand which rings are the same, and to highlight that is not usable as input.
Later suggestion: in CoCoALib rings have an ID, so could be printed as
/**/ Print NewRingFp(3); FFp(3)[ID=3] /**/ Print NewRingFp(3); FFp(3)[ID=4]
Latest suggestion:
# S ::= ZZ/(3)[x,y,z]; S; RingWithID(4, "RingID(3)[x,y,z]") # CoeffRing(S); RingID(3, "FFp(3)")
Related issues
History
#1 Updated by John Abbott almost 10 years ago
- Category set to Incomplete function
Each ring in CoCoA has an ID number (they start at 1 and are assigned incrementally). It'd be better to print those than the internal addresses!
#2 Updated by Anna Maria Bigatti almost 10 years ago
- Status changed from New to In Progress
- % Done changed from 0 to 10
I tried to see how it looks (just in RingFp.C).
This would be the output for test-RingHom1 .... not bad, I think
Composite homomorphism is RingHom(ZZ --> FFp(7)[ID=2]) Using composite hom: 1 maps to 1 in FFp(7)[ID=2] Using composite hom: 2 maps to 2 in FFp(7)[ID=2] Using composite hom: 3 maps to 3 in FFp(7)[ID=2]
#3 Updated by Anna Maria Bigatti almost 10 years ago
And in CoCoA-5 would look like this:
/**/ Print NewRingFp(3); FFp(3)[ID=3] /**/ Print NewRingFp(3); FFp(3)[ID=4] /**/ Print NewRingFp(3); FFp(3)[ID=5]
In case we do this change: how to make it elegantly so that it prints the ID for all rings except ZZ and QQ?
20140625 That should be easy because there are CoCoALib fns
IsZZ
and IsQQ
#4 Updated by John Abbott almost 10 years ago
Should this topic be in CoCoALib rather than CoCoA-5?
From the point of a user it would be very handy if the C5 expression ZZ/(3)
always produced the same ring (and similarly for NewZZmod(3)
in CoCoALib). This can be achieved using a global table of rings, though there is some risk that it might fill up with "junk"...
#5 Updated by John Abbott almost 10 years ago
- a ring prints out simply as
ring(1)
,ring(2)
etc describe RingOf(M)
produces a full description of the ring (similar to what is currently printed)
This would make it very clear when two rings are the same, but forces use of a "special" command to find out what the ring really is. How often does one really want to print out all the information about the structure of a ring?
Do we want printing of rings to be valid as input? (e.g. in the printed form of a matrix)
#6 Updated by Anna Maria Bigatti almost 10 years ago
John Abbott wrote:
Here is an idea: simple to implement, but perhaps not so nice to use?
- a ring prints out simply as
ring(1)
,ring(2)
etcdescribe RingOf(M)
produces a full description of the ring (similar to what is currently printed)
I like it, it could be RingWithID(6). Maybe that could also be used as input?
#7 Updated by Anna Maria Bigatti almost 10 years ago
- Subject changed from Printing rings to Printing rings with ID
#8 Updated by John Abbott almost 10 years ago
- % Done changed from 10 to 20
If we go with the idea of printing simply RingWithID(...)
then I presume the describe
command should fully describe the ring, rather than just the topmost level:
P ::= QQ[x,y,z]; Print P; RingWithID(4); describe P; ???
In this case the nicest output would be QQ[x,y,z]
.
Suppose the session continues like this:
Use P; I := ideal(x^100+lots-of-terms); PmodI := P/I; P2 ::= PmodI[a,b,c]; describe P2; ???
Here we probably do not want one huge line of the form QQ[x,y,z]/(ideal(x^100+lots-of-terms))[a,b,c]
It would be more comprehensible to have an output of the form:
RingWithID(9): RingWithID(8)[a,b,c] RingWithID(8): RingWithID(4)/(ideal(x^100+lots-of-terms)) RingWithID(4): RingWithID(2)[x,y,z] RingWithID(2): QQ
What do you think?
#9 Updated by John Abbott almost 10 years ago
The name RingWithID
is longer than I would like; I originally suggested ring(3)
but that is not so clear. Maybe RingID(3)
.
We could even regard RingID
as an indexable value rather than a function, so the user would write RingID[3]
. Not sure if this is a good idea... maybe it makes no difference?
15:07 I think it'd be easier for the user if RingID
is a function; to me it would feel like an "exceptional case" if it were like a (read-only) list...
#10 Updated by John Abbott almost 10 years ago
How will rings be printed in resolutions?
I recall that CoCoA used a syntax like ring#7
; we could do this (but it would a new syntax, and thus require changes to lexer/parser).
#11 Updated by John Abbott almost 10 years ago
Talked about this with Christof. Here's an idea we had:
allow RingID
to have an optional second arg which is a string giving some info about the ring (this 2nd arg could be ignored when reading RingID(...)
).
For instance we could get behaviour like this...
P ::= QQ[a,b]; P2 := P[x,y]; PrintLn P2; RingID(7, "RingID(6)[x,y]");
#12 Updated by Anna Maria Bigatti almost 10 years ago
John Abbott wrote:
allow
RingID
to have an optional second arg which is a string giving some info about the ring (this 2nd arg could be ignored when readingRingID(...)
).
YES!! I'll try it immediately!
[Later]
# S ::= ZZ/(3)[x,y,z]; # S; RingID(4,"RingID(3)[x, y, z]") # CoeffRing(S); RingID(3,"FFp(3)")
#13 Updated by Anna Maria Bigatti almost 10 years ago
- % Done changed from 20 to 40
mostly done.... now I should update all the failing tests.... tomorrow
#14 Updated by Anna Maria Bigatti almost 10 years ago
fixed all tests, but we should still discuss on the output.
For example
RingID(2,"RingID(0)[x, y]")
would be more readable as
RingID(2,"ZZ[x,y]")
so:
1 - write "by hand" the printing of the indets without spaces
2 - write ring "name" for rings with unique copies (there is something similar for printing matrices)
#15 Updated by John Abbott almost 10 years ago
Yesterday Christof suggested that ZZ
and QQ
should always be printed that way (rather than ring(0)
and ring(1)
). We were undecided about rings like ZZ/(3)
; one idea was to print it nicely if the nice form is sufficiently short (e.g. less than 10 chars).
#16 Updated by Anna Maria Bigatti almost 10 years ago
John Abbott wrote:
Yesterday Christof suggested that
ZZ
andring(0)
andring(1)
). We were undecided about rings likeZZ/(3)
; one idea was to print it nicely if the nice form is sufficiently short (e.g. less than 10 chars).
OK, I'll make some experiments.
Meanwhile, we should also think of implementing RingID(N)
.
I think there is a table in GlobalManager
. (wild guess)
#17 Updated by Anna Maria Bigatti almost 10 years ago
what about this: (verbose, but not more than before the ID change)
I like it! .... but there is the problem of too many quotes :-(
# NewFractionField(NewPolyRing(QQ,SymbolRange("t",3,5))); RingID(4,"FractionField(RingID(3,"QQ[t[3],t[4],t[5]]"))")
20140703-13:38 Your example seems too verbose to me; I think I would expect just RingID(4,"FrF(RingID(3))")
. Hmm, this is tricky. I wonder whether this might be acceptable RingID(4, "FrF(RingID(3), "QQ[3indets]"))
#18 Updated by Anna Maria Bigatti almost 10 years ago
added function ID for RING
#19 Updated by John Abbott almost 10 years ago
I'm still not happy with the name of RingID
; the name makes me think that it gets the ID from a ring, rather than gets the ring from its ID. RingWithID
is clearer but is too long...
Puzzled.
#20 Updated by Anna Maria Bigatti almost 10 years ago
John Abbott wrote:
I'm still not happy with the name of
RingID
; the name makes me think that it gets the ID from a ring, rather than gets the ring from its ID.RingWithID
is clearer but is too long...
In fact, it is not too long (and it's very expressive), because at the end it [rints a shorter string than the "old-style" printing.
I think we need an extra function (I was trying to avoid that) saying whether the ring has a unique implementation (therefore it's better printed explicitely) or not (therefore printed with ID)
I had a look at GlobalManager and now I think that currently there is no way (yet) to see if "RingWithID(5)" exists and get its value.
#21 Updated by John Abbott almost 10 years ago
Should this issue be in CoCoA-5 or CoCoALib?
You are right that there is no global register of rings currently. We would need one if we want to avoid creating two identical rings. As you know, I do not much like globals, though they are sometimes necessary. Some care will be needed to make a global work properly in a multithreaded environment.
Should all rings appear in the global registry? Even temporary rings which exist only inside a fn?
Am I correct in deducing that you want a fn which given a ring ID produces the corresponding ring?
#22 Updated by Anna Maria Bigatti almost 10 years ago
John Abbott wrote:
Should this issue be in CoCoA-5 or CoCoALib?
I think it can stay in CoCoA-5 because it is easier re-create rings.
You are right that there is no global register of rings currently. We would need one if we want to avoid creating two identical rings. As you know, I do not much like globals, though they are sometimes necessary. Some care will be needed to make a global work properly in a multithreaded environment.
I think that trying to catch identical constructions might be tricky, and if it works 90% of the cases it might be even more confusing. I think that printing with ID helps the user understand better what a ring is and so avoid to make unncecessary (and costly, if we need to do all checks every time) re-creation of rings
Should all rings appear in the global registry? Even temporary rings which exist only inside a fn?
hmmmm, now I'm not sure we should do this.
A ring occupies lots of memory and we'd better get rid of the unused ones (everytime we compute a Groebner basis we create a temporary ring!)
Maybe the function "RingWithID(n)" should return an error saying something like:
"this is not a function: give names to rings or use RingOf(object)" ;-)
(I like that! it's an easy way to tell the user how to be more careful)
If we allow the user to write RingWithID(7)
, that will have a totally different meaning next time cocoa is started. So it fails the utility of being "re-usable" and saved output cannot be read again anyway.
Am I correct in deducing that you want a fn which given a ring ID produces the corresponding ring?
more than "want" was a "wondering". Now I'm getting convinced it should not be implemented.
#23 Updated by John Abbott over 9 years ago
- % Done changed from 40 to 50
#24 Updated by John Abbott over 9 years ago
- Target version changed from CoCoA-5.1.1 Seoul14 to CoCoA-5.1.2 summer 2015
I think the current implementation is adequate (rather than fully satisfactory); but I'd like time to think more about the issue before declaring it fully resolved. So, I'm changing the target version to 5.1.2.
#25 Updated by Anna Maria Bigatti over 9 years ago
I have implemented in CoCoALib
void ***RingBase::myOutputSelfLong(std::ostream& out) const
I think it should be called by describe
in CoCoA-5, which currently returns only
A value of type RING
Have I just forgotten do it, or did we decide not to? (and why?)
... maybe I just didn't find how to access the interpreter code for
describe
...#26 Updated by John Abbott over 9 years ago
I think it has just been forgotten; it seems like a good idea to me. Indeed now that direct printing produces a very compact(incomplete) form, CoCoA-5 really needs a way to get the full details of a ring.
I note that describe
could produce several lines of output if we want it to. For instance, the description of a ring could be like this: (copied from comment 8)
RingWithID(9): RingWithID(8)[a,b,c] RingWithID(8): RingWithID(4)/(ideal(x^100+lots-of-terms)) RingWithID(4): RingWithID(2)[x,y,z] RingWithID(2): QQ
#27 Updated by Anna Maria Bigatti almost 9 years ago
- Status changed from In Progress to Resolved
- Assignee set to Anna Maria Bigatti
John Abbott wrote:
I think it has just been forgotten; it seems like a good idea to me. Indeed now that direct printing produces a very compact(incomplete) form, CoCoA-5 really needs a way to get the full details of a ring.
I note that
describe
could produce several lines of output if we want it to. For instance, the description of a ring could be like this: (copied from comment 8)
[...]
I'm thinking how to achieve this. We haven't yet designed a describe
mechanism for cocoalib.
The easiest (without messing too much with the Interpreter) is to write a description
function in cocoalib returning a string (i.e. which does not print). Then the cocoa-5 describe
would just print that string.
Should I do it like that? (then I could also do it for RINGHOM)
#28 Updated by Anna Maria Bigatti over 8 years ago
- Description updated (diff)
Anna Maria Bigatti wrote:
Maybe the function "RingWithID(n)" should return an error saying something like:
"this is not a function: give names to rings or use RingOf(object)" ;-)
(I like that! it's an easy way to tell the user how to be more careful)
done
#29 Updated by Anna Maria Bigatti over 8 years ago
- Status changed from Resolved to Closed
- % Done changed from 50 to 100
- Estimated time set to 7.50 h
All the relevant code is done. I find it quite satisfactory (even though I'm not entirely convinced with the design of the functions myOutputSelfShort
and myOutputSelfLong
)
The function R->myOutputSelfLong(out)
gives a more complete description of the ring, and should be the code for describe R
in CoCoA-5, so I move the discussion on details and refinements to a dedicated issue.