Macaulay2 / M2

The primary source code repository for Macaulay2, a system for computing in commutative algebra, algebraic geometry and related fields.
https://macaulay2.com
347 stars 231 forks source link

Disappearing synopsis in help #1317

Closed mahrud closed 4 years ago

mahrud commented 4 years ago

First run help "quotient(Ideal,Ideal)" and notice that the synopsis is missing:

i1 : help "quotient(Ideal,Ideal)"

o1 = quotient(Ideal,Ideal) -- ideal or submodule quotient
     ****************************************************

     If I and J are both monomial ideals, then the result will be as well.  If I and J are both submodules of the same module,

...

o1 : DIV

The same is true of quotient(Ideal):

i2 : help "quotient(Ideal)"

o2 = quotient(Ideal)
     ***************

     +-----------------------------+
     |i1 : R = QQ[a..d];           |
     +-----------------------------+
     |i2 : I = ideal(a,b,c,d^3);   |
     |                             |
     |o2 : Ideal of R              |
     +-----------------------------+
     |i3 : comodule I              |
     |                             |
     |o3 = cokernel | a b c d3 |   |
     |                             |
     |                            1|
     |o3 : R-module, quotient of R |
     +-----------------------------+

o2 : DIV

Then run help "quotient" to see a synopsis:

i3 : help "quotient"
--warning: tag has no documentation: User :: quotient(MonomialIdeal,RingElement), key (quotient,MonomialIdeal,RingElement), package Core

o3 = quotient -- quotient or division
     ********************************

     Synopsis
     ========

       * Optional inputs:
           * BasisElementLimit => ..., 
           * DegreeLimit => ..., 
           * MinimalGenerators => ...,  -- Decides whether quotient computes and outputs a trimmed set of generators; default
             is true
           * PairLimit => ..., 
           * Strategy => ...,  -- Possible strategies are: Iterate, Linear, and Quotient

     Ways to use quotient :
     ======================

       * quotient(Ideal), see "comodule" -- submodule to quotient module
       * quotient(Module), see "comodule" -- submodule to quotient module
       * "quotient(Ideal,Ideal)" -- ideal or submodule quotient
       * quotient(Ideal,RingElement), see "quotient(Ideal,Ideal)" -- ideal or submodule quotient
       * quotient(Module,Ideal), see "quotient(Ideal,Ideal)" -- ideal or submodule quotient
       * quotient(Module,Module), see "quotient(Ideal,Ideal)" -- ideal or submodule quotient
       * quotient(Module,RingElement), see "quotient(Ideal,Ideal)" -- ideal or submodule quotient
       * quotient(MonomialIdeal,MonomialIdeal), see "quotient(Ideal,Ideal)" -- ideal or submodule quotient
       * "quotient(Matrix,GroebnerBasis)" -- matrix quotient
       * quotient(Matrix,Matrix), see "quotient(Matrix,GroebnerBasis)" -- matrix quotient
       * "quotient(MonomialIdeal,RingElement)"

o3 : DIV

And here's the bizarre part:

Now both quotient(Ideal,Ideal) and quotient(Ideal) have synopses:

i4 : help "quotient(Ideal,Ideal)"

o4 = quotient(Ideal,Ideal) -- ideal or submodule quotient
     ****************************************************

     Synopsis
     ========

       * Usage: quotient(I,J)I:J
       * Function: "quotient"
       * Inputs:
           * I, an ideal, an ideal, or a module, a submodule
           * J, an ideal, an ideal, a ring element, or a module, a submodule
       * Optional inputs:
           * BasisElementLimit => ..., 
           * DegreeLimit => ..., 
           * MinimalGenerators => ...,  -- Decides whether quotient computes and outputs a trimmed set of generators; default
             is true
           * PairLimit => ..., 
           * Strategy => ...,  -- Possible strategies are: Iterate, Linear, and Quotient
       * Outputs:
           * an ideal, the ideal or submodule $I:J = \{f | fJ\subset I\}$

     Description
     ===========

     If I and J are both monomial ideals, then the result will be as well.  If I and J are both submodules of the same module,

...

o4 : DIV

i5 : help "quotient(Ideal)"

o5 = quotient(Ideal)
     ***************

     Synopsis
     ========

       * Function: "quotient"

     Description
     ===========

     +-----------------------------+
     |i1 : R = QQ[a..d];           |
     +-----------------------------+
     |i2 : I = ideal(a,b,c,d^3);   |
     |                             |
     |o2 : Ideal of R              |
     +-----------------------------+
     |i3 : comodule I              |
     |                             |
     |o3 = cokernel | a b c d3 |   |
     |                             |
     |                            1|
     |o3 : R-module, quotient of R |
     +-----------------------------+

o5 : DIV

The result above is from a distributed M2 v1.14! I spent an hour figuring out how I messed this up before I realized that the recent changes have nothing to do with it.

DanGrayson commented 4 years ago

Good catch: and notice also how the first line (with the key) changes:

Macaulay2, version 1.12
with packages: ConwayPolynomials, Elimination, IntegralClosure, InverseSystems, LLLBases, PrimaryDecomposition, ReesAlgebra, TangentCone

i1 :  help "quotient(Ideal,Ideal)"

o1 = (quotient,Ideal,Ideal) -- ideal or submodule quotient
...

o1 : DIV

i2 : help (quotient,Ideal,Ideal)

o2 = quotient(Ideal,Ideal) -- ideal or submodule quotient
...

o2 : DIV

i3 : help "quotient(Ideal,Ideal)"

o3 = quotient(Ideal,Ideal) -- ideal or submodule quotient
...

o3 : DIV

I think the bug is related to the difference between the formatted key, which is the string "quotient(Ideal,Ideal)", and the key, which is the sequence (quotient,Ideal,Ideal). If you ask for help with the formatted key, then it finds the documentation, but it doesn't know how to generate the synopsis because it doesn't know how to get the key from the formatted key. (It needs the key to deduce that there are two arguments and both are ideals, for example.) If you ask for help with the key, then it formats the key and saves the backward translation from formatted key to key somewhere.

If you could fix that bug of mine, that would be great!

DanGrayson commented 4 years ago

Hmm, the value of o1 in the output I displayed indicates that the string "(quotient,Ideal,Ideal)" is available at that time. Maybe it's a matter of applying value to it.

DanGrayson commented 4 years ago

Mahrud, what about adding another color to the github highlighting, for strings?

asdfasdf "qwerqwer" asdfasfd ///skdfjsldkfjslkdfj///
mahrud commented 4 years ago

If you could fix that bug of mine, that would be great!

I haven't been able to understand this part of Core yet, but I can make this a key result of updating document.m2 if you'd like.

DanGrayson commented 4 years ago

Either that or a new issue would be fine.

mahrud commented 4 years ago

@DanGrayson also, help "Macaulay2" seems to only show the first paragraph and ignore the subnodes. Is this correct?

DanGrayson commented 4 years ago

No, that seems wrong. Also this:

i3 : viewHelp "Macaulay2"
stdio:3:1:(3): error: internal error: html documentation file does not exist: /Applications/Macaulay2-1.12/share/doc/Macaulay2/Macaulay2Doc/html/___Macaulay2.html
mahrud commented 4 years ago

I just realized this is duplicate of #907. I'll close that one, since the discussion here has more information.

mahrud commented 4 years ago

Also a duplicate of #814. Quoting from there to consolidate

And that's probably handled by this code:

-- we need to be able to do this only for the document tags we have shown to the user in formatted form 
unformatTag := new MutableHashTable
record      := f -> x -> (
val := f x; 
if val =!= x then unformatTag#val = x; 
val)