  
  [1X1 [33X[0;0YNMO[133X[101X
  
  
  [1X1.1 [33X[0;0YIntroduction[133X[101X
  
  [33X[0;0YWhat  follows  is  a  description  of  the  largely  experimental project of
  providing  arbitrary monomial orderings to the [5XGBNP[105X package. The addition of
  the  orderings  comes  in  the  form  of a library, and a patch to [5XGBNP[105X; the
  patching process being called at the [5XGBNP[105X user's discretion.[133X
  
  [33X[0;0YMore precisely, after a user creates a monomial ordering via the [5XNMO[105X library
  functions,  a  routine  is  called  which  overwrites the two [5XGBNP[105X functions
  "LtNP"  and  "GtNP".  In  [5XGBNP[105X,  these  latter  two functions are explicitly
  length-lexicographic  monomial  comparison functions, and are used in GBNP's
  Gröbner  Basis  routines. Therefore [5XNMO[105X allows for the creation of arbitrary
  monomial  ordering  comparison functions, which, after the patching process,
  will be used by GBNP in place of its native comparison functions.[133X
  
  [33X[0;0Y[5XNMO[105X is an acronym for Noncommutative Monomial Orderings. Such orderings play
  a  key role in research surrounding noncommutative Gröbner basis theory; see
  [Gre99],  [Mor94]. This package is geared primarily toward the use and study
  of   noncommutative   (associative)   free   algebras  with  identity,  over
  computational fields. We have done our best to write code that treats a more
  general  class  of  algebras,  but the routines have not been as extensively
  tested  in  those  cases.  Users  of  the  package are encouraged to provide
  constructive  feedback  about this issue or any others; we have open ears to
  ways to better these research tools.[133X
  
  [33X[0;0YFlexibility in the creation and use of noncommutative monomial orderings has
  been  our  guiding  principle  in  writing  [5XNMO[105X.  For example, two (or more)
  orderings can be chained together to form new orderings. It should be noted,
  however,  that  efficiency has also been considered in the design of [5XNMO[105X for
  commonly  used  monomial  orderings  for  noncommutative  rings (e.g. length
  left-lexicographic).  That  is  to  say,  some monomial orderings that occur
  regularly in the study of noncommutative algebras have already been included
  in [5XNMO[105X.[133X
  
  [33X[0;0YThroughout  this  chapter,  methods  and  functions are generally classed as
  [13XExternal[113X  and [13XInternal[113X routines. [13XExternal[113X routines are methods and functions
  that  will  be  most useful to the average user, and generally work directly
  with native [5XGAP[105X algebraic objects. [13XInternal[113X routines usually concern backend
  operations  and mechanisms, and are often related to operations involving [13XNP
  representations[113X of [5XGAP[105X algebraic elements, or they are related to attributes
  of  monomial  orderings.  Many examples of basic code use are provided; with
  some  examples following the reference material for the functions or methods
  involved.[133X
  
  
  [1X1.2 [33X[0;0YNMO Files within GBNP[133X[101X
  
  [33X[0;0YPer  the  [5XGAP[105X  package  standard,  [5XNMO[105X  library code is read in via the file
  [10Xgbnp/read.g[110X.  The  following  gives  brief descriptions of each of the files
  loaded   by   [10Xgbnp/read.g[110X,   all   of  which  reside  in  the  [10Xgbnp/lib/nmo/[110X
  subdirectory:[133X
  
  [30X    [33X[0;6Y[10Xncalgebra.gd[110X[133X
  
        [33X[0;6YSets up some nice categories and filters in [5XGAP[105X.[133X
  
  [30X    [33X[0;6Y[10Xncordmachine.g*[110X[133X
  
        [33X[0;6YCode  for  creating  the  new  [5XGAP[105X  family  of noncommutative monomial
        orderings, as well as its attending (internal) machinery.[133X
  
  [30X    [33X[0;6Y[10Xncorderings.g*[110X[133X
  
        [33X[0;6YSets  up  actual noncommutative monomial orderings. This is where some
        specific  example  routines  for  monomial orderings are included. The
        less-than functions determining monomial orderings should be collected
        here, e.g. the length left-lexicographic ordering is here.[133X
  
  [30X    [33X[0;6Y[10Xncinterface.g*[110X[133X
  
        [33X[0;6YThese   files   provide  the  interface  to  comparison  routines  for
        determining   equivalence,   less-than,  and  greater-than  comparison
        between two algebraic elements under a given [5XNMO[105X ordering.[133X
  
  [30X    [33X[0;6Y[10Xncutils.g*[110X[133X
  
        [33X[0;6YHelpful  utility  routines, such as: patching [5XGBNP[105X for use with an [5XNMO[105X
        ordering,  unpatching [5XGBNP[105X, as well as a `String' routine for elements
        of an associative algebra not already covered in [5XGAP[105X.[133X
  
  [33X[0;0YThere is a documentation directory in [10Xgbnp/doc/nmo[110X wherein the [5XGAPDoc[105X source
  for this chapter may be found.[133X
  
  [33X[0;0YFinally,  there  is an examples directory in [10Xgbnp/doc/examples/nmo[110X where the
  plain  [5XGAP[105X source can be found for the examples in the Quickstart section of
  this chapter.[133X
  
  
  [1X1.3 [33X[0;0YQuickstart[133X[101X
  
  [33X[0;0YThis  Quickstart  assumes  you've  already installed the [5XGBNP[105X package in its
  proper  home.  If  that's yet to be done, please see the [5XGBNP[105X package manual
  for installation instructions.[133X
  
  [33X[0;0YIf  the  user wishes, cutting and pasting the commands which directly follow
  the  [5XGAP[105X  prompt  [10Xgap>[110X  is  a  good  way to become familiar with [5XNMO[105X via the
  examples  below. Alternatively, code for the following examples may be found
  in [10Xgbnp/doc/examples/nmo/example0*.g[110X.[133X
  
  [33X[0;0YThis  Quickstart  covers  specific use of the [5XNMO[105X package's functionality as
  pertaining  to  computing noncommutative Gröbner bases for various examples.
  There  are  [5XNMO[105X  user-level routines beyond these Gröbner basis applications
  that may be of interest, all of which are documented in later sections.[133X
  
  
  [1X1.3-1 [33X[0;0YNMO Example 1[133X[101X
  
  [33X[0;0YExample  1  is  taken  from  Dr. Edward Green's paper [21XNoncommutative Gröbner
  Bases,  and  Projective Resolutions[121X, and is referenced as [21XExample 2.7[121X there;
  please see [Gre99] for more information.[133X
  
  [33X[0;0YLoad the [5XGBNP[105X package with:[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27XLoadPackage("gbnp");[127X[104X
    [4X[28Xtrue[128X[104X
  [4X[32X[104X
  
  [33X[0;0YCreate  a  noncommutative free algebra on 4 generators over the Rationals in
  [5XGAP[105X:[133X
  
  [4X[32X[104X
    [4Xgap> A := FreeAssociativeAlgebraWithOne(Rationals,"a","b","c","d");[104X
    [4X<algebra-with-one over Rationals, with 4 generators> [104X
  [4X[32X[104X
  
  [33X[0;0YLabel the generators of the algebra:[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27Xa := A.a; b := A.b; c := A.c; d := A.d;[127X[104X
    [4X[28X(1)*a[128X[104X
    [4X[28X(1)*b[128X[104X
    [4X[28X(1)*c[128X[104X
    [4X[28X(1)*d[128X[104X
  [4X[32X[104X
  
  [33X[0;0YSet up our polynomials, and convert them to [5XGBNP[105X NP format:[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27Xpolys := [c*d*a*b-c*b,b*c-d*a];[127X[104X
    [4X[28X[ (-1)*c*b+(1)*c*d*a*b, (1)*b*c+(-1)*d*a ][128X[104X
    [4X[25Xgap>[125X [27Xreps := GP2NPList(polys);[127X[104X
    [4X[28X[ [ [ [ 3, 4, 1, 2 ], [ 3, 2 ] ], [ 1, -1 ] ],[128X[104X
    [4X[28X           [ [ [ 4, 1 ], [ 2, 3 ] ], [ -1, 1 ] ] ][128X[104X
  [4X[32X[104X
  
  [33X[0;0YCompute   the   Gröbner   basis   via   [5XGBNP[105X   using   its  default  (length
  left-lexicographic)  ordering;  that  is,  without patching [5XGBNP[105X with an [5XNMO[105X
  ordering:[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27Xgbreps := Grobner(reps);;[127X[104X
    [4X[25Xgap>[125X [27Xgb := NP2GPList(gbreps,A);[127X[104X
    [4X[28X[ (1)*d*a+(-1)*b*c, (1)*c*b*c*b+(-1)*c*b ][128X[104X
  [4X[32X[104X
  
  [33X[0;0YCreate  length left-lexicographic ordering, with generators ordered: a < b <
  c  <  d. Note: this is the default ordering of generators by [5XNMO[105X, if none is
  provided:[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27Xml := NCMonomialLeftLengthLexOrdering(A);[127X[104X
    [4X[28XNCMonomialLeftLengthLexicographicOrdering([ (1)*a, (1)*b, (1)*c, (1)*d ])[128X[104X
  [4X[32X[104X
  
  [33X[0;0YPatch  [5XGBNP[105X  with  the ordering [10Xml[110X, and then run the same example. We should
  get the same answer as above:[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27XPatchGBNP(ml);[127X[104X
    [4X[28XLtNP patched.[128X[104X
    [4X[28XGtNP patched.[128X[104X
    [4X[25Xgap>[125X [27Xgbreps := Grobner(reps);;[127X[104X
    [4X[25Xgap>[125X [27Xgb := NP2GPList(gbreps,A);[127X[104X
    [4X[28X[ (1)*d*a+(-1)*b*c, (1)*c*b*c*b+(-1)*c*b ][128X[104X
  [4X[32X[104X
  
  [33X[0;0YCreate a Length-Lexicographic ordering on the generators such that d < c < b
  < a:[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27Xml2 := NCMonomialLeftLengthLexOrdering(A,[4,3,2,1]);[127X[104X
    [4X[28XNCMonomialLeftLengthLexicographicOrdering([ (1)*d, (1)*c, (1)*b, (1)*a ])[128X[104X
  [4X[32X[104X
  
  [33X[0;0YCompute  the  Gröbner  basis  with  respect to this new ordering on the same
  algebra:[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27XPatchGBNP(ml2);[127X[104X
    [4X[28XLtNP patched.[128X[104X
    [4X[28XGtNP patched.[128X[104X
    [4X[25Xgap>[125X [27Xgbreps2 := SGrobner(reps);;[127X[104X
    [4X[25Xgap>[125X [27Xgb2 := NP2GPList(gbreps2,A);[127X[104X
    [4X[28X[ (1)*b*c+(-1)*d*a, (1)*c*d*a*b+(-1)*c*b, (1)*d*a*d*a*b+(-1)*d*a*b,[128X[104X
    [4X[28X  (1)*c*d*a*d*a+(-1)*c*d*a, (1)*d*a*d*a*d*a+(-1)*d*a*d*a ][128X[104X
  [4X[32X[104X
  
  
  [1X1.3-2 [33X[0;0YNMO Example 2[133X[101X
  
  [33X[0;0YThis  example  is  the  same  as Example 1 above, except that the length and
  left-lexicographic  orderings  are created independently and then chained to
  form the usual length left-lexicographic ordering. Hence, all results should
  be the same. Note: we assume from this point forward in all further examples
  that GBNP is loaded.[133X
  
  [33X[0;0YCreate  a  noncommutative  free  algebra on 4 generators over the Rationals,
  label, and set up the example:[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27XA := FreeAssociativeAlgebraWithOne(Rationals,"a","b","c","d");;[127X[104X
    [4X[25Xgap>[125X [27Xa := A.a;; b := A.b;; c := A.c;; d := A.d;;[127X[104X
    [4X[25Xgap>[125X [27Xpolys := [c*d*a*b-c*b,b*c-d*a];;[127X[104X
    [4X[25Xgap>[125X [27Xreps := GP2NPList(polys);;[127X[104X
  [4X[32X[104X
  
  [33X[0;0YCreate left-lexicographic ordering with a < b < c < d:[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27Xlexord := NCMonomialLeftLexicographicOrdering(A);[127X[104X
    [4X[28XNCMonomialLeftLexicographicOrdering([ (1)*a, (1)*b, (1)*c, (1)*d ])[128X[104X
  [4X[32X[104X
  
  [33X[0;0YCreate  a  length  ordering  on  monomials  in  [22XA[122X,  with  ties broken by the
  lexicographic order [10Xlexord[110X:[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27Xlenlex := NCMonomialLengthOrdering(A,lexord);[127X[104X
    [4X[28XNCMonomialLengthOrdering([ (1)*a, (1)*b, (1)*c, (1)*d ])[128X[104X
  [4X[32X[104X
  
  [33X[0;0YPatch [5XGBNP[105X and proceed with our example:[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27XPatchGBNP(lenlex);;[127X[104X
    [4X[28XLtNP patched.[128X[104X
    [4X[28XGtNP patched.[128X[104X
    [4X[25Xgap>[125X [27Xgbreps := Grobner(reps);;[127X[104X
    [4X[25Xgap>[125X [27Xgb := NP2GPList(gbreps,A);[127X[104X
    [4X[28X[ (1)*d*a+(-1)*b*c, (1)*c*b*c*b+(-1)*c*b ][128X[104X
  [4X[32X[104X
  
  [33X[0;0YNow,  proceed  similarly, with the lexicographic order such that d < c < b <
  a:[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27Xlexord2 := NCMonomialLeftLexicographicOrdering(A,[4,3,2,1]);[127X[104X
    [4X[28XNCMonomialLeftLexicographicOrdering([ (1)*d, (1)*c, (1)*b, (1)*a ])[128X[104X
    [4X[25Xgap>[125X [27Xlenlex2 := NCMonomialLengthOrdering(A,lexord2);[127X[104X
    [4X[28XNCMonomialLengthOrdering([ (1)*a, (1)*b, (1)*c, (1)*d ])[128X[104X
    [4X[25Xgap>[125X [27XPatchGBNP(lenlex2);;[127X[104X
    [4X[28XLtNP patched.[128X[104X
    [4X[28XGtNP patched.[128X[104X
    [4X[25Xgap>[125X [27Xgbreps2 := Grobner(reps);;[127X[104X
    [4X[25Xgap>[125X [27Xgb2 := NP2GPList(gbreps2,A);[127X[104X
    [4X[28X[ (1)*b*c+(-1)*d*a, (1)*c*d*a*b+(-1)*c*b, (1)*d*a*d*a*b+(-1)*d*a*b,[128X[104X
    [4X[28X  (1)*c*d*a*d*a+(-1)*c*d*a, (1)*d*a*d*a*d*a+(-1)*d*a*d*a ][128X[104X
  [4X[32X[104X
  
  [33X[0;0YAn  important  point  can  be made here. Notice that when the [10Xlenlex2[110X length
  ordering  is created, a lexicographic (generator) ordering table is assigned
  internally  to the ordering since one was not provided to it. This is merely
  a  convenience for lexicographically-dependent orderings, and in the case of
  the  length  order,  it  is not used. Only the lex table for [10Xlexord2[110X is ever
  used. Some clarification may be provided in examining:[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27XHasNextOrdering(lenlex2);[127X[104X
    [4X[28Xtrue[128X[104X
    [4X[25Xgap>[125X [27XNextOrdering(lenlex2);[127X[104X
    [4X[28XNCMonomialLeftLexicographicOrdering([ (1)*d, (1)*c, (1)*b, (1)*a ])[128X[104X
    [4X[25Xgap>[125X [27XLexicographicTable(NextOrdering(lenlex2));[127X[104X
    [4X[28X[ (1)*d, (1)*c, (1)*b, (1)*a ][128X[104X
  [4X[32X[104X
  
  
  [1X1.3-3 [33X[0;0YNMO Example 3[133X[101X
  
  [33X[0;0YExample  3  is  taken  from  the  book  [21XIdeals,  Varieties,  and Algorithms[121X,
  ([CLO97], Example 2, p. 93-94); it is a commutative example.[133X
  
  [33X[0;0YFirst,  we  set  up the problem and find a Gröbner basis with respect to the
  length left-lexicographic ordering implicitly assumed in [5XGBNP[105X:[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27XA := FreeAssociativeAlgebraWithOne(Rationals,"x","y","z");;[127X[104X
    [4X[25Xgap>[125X [27Xx := A.x;; y := A.y;; z := A.z;; id := One(A);;[127X[104X
    [4X[25Xgap>[125X [27Xpolys := [ x^2 + y^2 + z^2 - id, x^2 + z^2 - y, x-z,[127X[104X
    [4X[25X>[125X [27X           x*y-y*x, x*z-z*x, y*z-z*y];;[127X[104X
    [4X[25Xgap>[125X [27Xreps := GP2NPList(polys);;[127X[104X
    [4X[25Xgap>[125X [27Xgb := Grobner(reps);;[127X[104X
    [4X[25Xgap>[125X [27XNP2GPList(gb,A);[127X[104X
    [4X[28X[ (1)*z+(-1)*x, (1)*x^2+(-1/2)*y, (1)*y*x+(-1)*x*y,[128X[104X
    [4X[28X  (1)*y^2+(2)*x^2+(-1)*<identity ...> ][128X[104X
  [4X[32X[104X
  
  [33X[0;0YThe  example,  as  presented in the book, uses a left-lexicographic ordering
  with  z  <  y  <  x.  We create the ordering in [5XNMO[105X, patch [5XGBNP[105X, and get the
  result expected:[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27Xml := NCMonomialLeftLexicographicOrdering(A,[3,2,1]);[127X[104X
    [4X[28XNCMonomialLeftLexicographicOrdering([ (1)*z, (1)*y, (1)*x ])[128X[104X
    [4X[25Xgap>[125X [27XPatchGBNP(ml);[127X[104X
    [4X[28XLtNP patched.[128X[104X
    [4X[28XGtNP patched.[128X[104X
    [4X[25Xgap>[125X [27Xgb := Grobner(reps);;[127X[104X
    [4X[25Xgap>[125X [27XNP2GPList(gb,A);[127X[104X
    [4X[28X[ (1)*z^4+(1/2)*z^2+(-1/4)*<identity ...>, (1)*y+(-2)*z^2, (1)*x+(-1)*z ][128X[104X
  [4X[32X[104X
  
  
  [1X1.3-4 [33X[0;0YNMO Example 4[133X[101X
  
  [33X[0;0YExample 4 was taken from page 339 of the book [21XSome Tapas of Computer Algebra[121X
  by  A.M.  Cohen, H. Cuypers, H. Sterk, [CCS99]; it also appears as Example 6
  in the [5XGBNP[105X example set.[133X
  
  [33X[0;0YA  noncommutative free algebra on 6 generators over the Rationals is created
  in [5XGAP[105X, and the generators are labeled:[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27XA := FreeAssociativeAlgebraWithOne(Rationals,"a","b","c","d","e","f");;[127X[104X
    [4X[25Xgap>[125X [27Xa := A.a;; b := A.b;; c := A.c;; d := A.d;; e := A.e;; f := A.f;;[127X[104X
  [4X[32X[104X
  
  [33X[0;0YSet up list of noncommutative polynomials:[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27Xpolys := [ e*a, a^3 + f*a, a^9 + c*a^3, a^81 + c*a^9 + d*a^3,[127X[104X
    [4X[25X>[125X [27X           a^27 + d*a^81 + e*a^9 + f*a^3, b + c*a^27 + e*a^81 + f*a^9,[127X[104X
    [4X[25X>[125X [27X           c*b + d*a^27 + f*a^81, a + d*b + e*a^27, c*a + e*b + f*a^27,[127X[104X
    [4X[25X>[125X [27X           d*a + f*b, b^3 - b, a*b - b*a, a*c - c*a, a*d - d*a,[127X[104X
    [4X[25X>[125X [27X           a*e - e*a, a*f - f*a, b*c - c*b, b*d - d*b, b*e - e*b,[127X[104X
    [4X[25X>[125X [27X           b*f - f*b, c*d - d*c, c*e - e*c, c*f - f*c, d*e - e*d,[127X[104X
    [4X[25X>[125X [27X           d*f - f*d, e*f - f*e[127X[104X
    [4X[25X>[125X [27X];;[127X[104X
    [4X[25Xgap>[125X [27Xreps := GP2NPList(polys);;[127X[104X
  [4X[32X[104X
  
  [33X[0;0YCreate  a  length left-lex ordering with the following (default) ordering on
  the generators a < b < c < d < e < f:[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27Xml := NCMonomialLeftLengthLexOrdering(A);[127X[104X
    [4X[28XNCMonomialLeftLengthLexicographicOrdering([ (1)*a, (1)*b, (1)*c, (1)*d,[128X[104X
    [4X[28X   (1)*e, (1)*f ])[128X[104X
  [4X[32X[104X
  
  [33X[0;0YPatch [5XGBNP[105X and compute the Gröbner basis with respect to the ordering [10Xml[110X:[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27XPatchGBNP(ml);[127X[104X
    [4X[28XLtNP patched.[128X[104X
    [4X[28XGtNP patched.[128X[104X
    [4X[25Xgap>[125X [27Xgb := Grobner(reps);;[127X[104X
    [4X[25Xgap>[125X [27XNP2GPList(gb,A);[127X[104X
    [4X[28X[ (1)*a, (1)*b, (1)*d*c+(-1)*c*d, (1)*e*c+(-1)*c*e,[128X[104X
    [4X[28X  (1)*e*d+(-1)*d*e, (1)*f*c+(-1)*c*f,[128X[104X
    [4X[28X  (1)*f*d+(-1)*d*f, (1)*f*e+(-1)*e*f ][128X[104X
  [4X[32X[104X
  
  
  [1X1.4 [33X[0;0YOrderings[133X[101X
  
  [33X[0;0YThis section describes the current orderings built into the [5XGAP[105X package [5XNMO[105X,
  and describes some of the internals of the machinery involved.[133X
  
  
  [1X1.4-1 [33X[0;0YInternals[133X[101X
  
  [33X[0;0YThe   orderings   portion   of  [5XNMO[105X  is  divided  codewise  into  the  files
  [10Xncordmachine.gd,  ncordmachine.gi[110X  and  [10Xncorderings.gd,  ncorderings.gi[110X. The
  former  file  pair  contains  code  to  set  up  the machinery to create new
  monomial  orderings  on  noncommutative algebras, whereas the latter sets up
  actual  orderings.  We  will  first  describe the creation and use of length
  lexicographic  ordering, afterward describing more of the details of the new
  [5XGAP[105X family `NoncommutativeMonomialOrdering'.[133X
  
  [33X[0;0YThe  [5XNMO[105X package was built with the mindset of allowing great flexibility in
  creating  new  monomial  orderings  on  noncommutative algebras. All that is
  required  to  install  a  new  ordering  is to create two [5XGAP[105X functions that
  determine  less-than comparisons (one non-indexed, and one indexed) and then
  call  [10XInstallNoncommutativeMonomialOrdering[110X with the comparison functions as
  arguments.  The  comparison  functions  should  be written to compare simple
  lists  of  integers,  these  lists  representing monomials as in [5XGBNP[105X's `NP'
  format,  or  the  letter  representation  format  in  [5XGAP[105X (see "The External
  Representation  for  Associative  Words"  in  the  [5XGAP[105X reference manual). An
  example      follows      the      description      of      the     function
  [10XInstallNoncommutativeMonomialOrdering[110X.[133X
  
  [33X[0;0YA  bit of explanation is due here to address the added complexity introduced
  by  requiring  that two functions [10X(<function>, <function2>)[110X need be supplied
  to  [10XInstallNoncommutativeMonomialOrdering[110X  to  create an ordering. The first
  function  [10X<function>[110X  should be responsible for comparing two given monomial
  list  representations  in  their  unadultered  forms.  The  second, indexed,
  function  [10X<function2>[110X  should  be  capable  of  using  a provided index list
  corresponding  to an order on generators, based on a different lexicographic
  ordering.   This  accomplishes  something  worthwhile:  two  orderings  with
  different lexicographic tables can be applied to the same algebra in [5XGAP[105X.[133X
  
  [33X[0;0YOne more caveat: [10XInstallNoncommutativeMonomialOrdering[110X will create a default
  lexicographic  table  for  all  orderings, despite whether or not it will be
  used  in  the  comparison function. It does this only out of convenience and
  ease of use.[133X
  
  [33X[0;0YFor  example,  in  the creation of the following left-lex ordering, which is
  installed  via the [10XInstallNoncommutativeMonomialOrdering[110X function, a default
  ordering  of  a  <  b  <  c is created for [10Xml[110X even though an ordering on the
  generators is not provided:[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27XA := FreeAssociativeAlgebraWithOne(Rationals,"a","b","c");[127X[104X
    [4X[28X<algebra-with-one over Rationals, with 3 generators>[128X[104X
    [4X[25Xgap>[125X [27Xlexord := NCMonomialLeftLexicographicOrdering(A);[127X[104X
    [4X[28XNCMonomialLeftLexicographicOrdering([ (1)*a, (1)*b, (1)*c ])[128X[104X
  [4X[32X[104X
  
  [33X[0;0YNotice  next  that  when  an  ordering  on the generators is provided, it is
  utilized in the creation of the ordering:[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27Xlexord2 := NCMonomialLeftLexicographicOrdering(A,[2,3,1]);[127X[104X
    [4X[28XNCMonomialLeftLexicographicOrdering([ (1)*b, (1)*c, (1)*a ])[128X[104X
  [4X[32X[104X
  
  
  [1X1.4-2 [33X[0;0YInternal Routines[133X[101X
  
  [29X[2XInstallNoncommutativeMonomialOrdering[102X( [3X<string>[103X, [3X<function>[103X, [3X<function2>[103X ) [32X function
  
  [33X[0;0YGiven  a  name  [10X<string>[110X,  a  direct  comparison function [10X<function>[110X, and an
  indexed             comparison             function             [10X<function2>[110X,
  [10XInstallNoncommutativeMonomialOrdering[110X   will  install  a  monomial  ordering
  function  to allow the creation of a monomial ordering based on the provided
  functions.[133X
  
  [33X[0;0YFor  example,  we  create a length ordering by setting up the two comparison
  functions,   choosing  a  name  for  the  ordering  type  and  then  calling
  [10XInstallNoncommutativeMonomialOrdering[110X.[133X
  
  [4X[32X  Example  [32X[104X
    [4X[28X  gap> f1 := function(a,b,aux)[128X[104X
    [4X[28X  >   return Length(a) < Length(b);[128X[104X
    [4X[28X  > end;[128X[104X
    [4X[28X  function( a, b, aux ) ... end[128X[104X
    [4X[28X  gap> f2 := function(a,b,aux,idx)[128X[104X
    [4X[28X  >   return Length(a) < Length(b);[128X[104X
    [4X[28X  > end;[128X[104X
    [4X[28X  function( a, b, aux, idx ) ... end[128X[104X
    [4X[28X  [128X[104X
    [4X[28X  DeclareGlobalFunction("lenOrdering");[128X[104X
    [4X[28X  InstallNoncommutativeMonomialOrdering("lenOrdering",f1,f2);[128X[104X
    [4X[28X  [128X[104X
  [4X[32X[104X
  
  [33X[0;0YNow  we  create an ordering based on this new function, and make some simple
  comparisons.  (Note:  we  are  passing in an empty [10Xaux[110X table since it is not
  being  used.  Also, the comparison function is the non-indexed version since
  we determined no lex order on the generators):[133X
  
  [4X[32X  Example  [32X[104X
    [4X[28X  gap> A := FreeAssociativeAlgebraWithOne(Rationals,"a","b","c");[128X[104X
    [4X[28X  <algebra-with-one over Rationals, with 3 generators>[128X[104X
    [4X[28X  gap> ml := lenOrdering(A);[128X[104X
    [4X[28X  lenOrdering([ (1)*a, (1)*b, (1)*c ])[128X[104X
    [4X[28X  gap>[128X[104X
    [4X[28X  gap> LtFunctionListRep(ml)([1,2],[1,1,1],[]);[128X[104X
    [4X[28X  true[128X[104X
    [4X[28X  gap> LtFunctionListRep(ml)([1,1],[],[]);[128X[104X
    [4X[28X  false[128X[104X
    [4X[28X  [128X[104X
  [4X[32X[104X
  
  [29X[2XIsNoncommutativeMonomialOrdering[102X( [3X<obj>[103X ) [32X Category
  
  [33X[0;0YA  noncommutative  monomial  ordering  is  an object representing a monomial
  ordering on a noncommutative (associative) algebra. All [5XNMO[105X orderings are of
  this category.[133X
  
  [29X[2XLtFunctionListRep[102X( [3X<NoncommutativeMonomialOrdering>[103X ) [32X attribute
  
  [33X[0;0YReturns  the  low-level  comparison function used by the given ordering. The
  function  returned  is a comparison function on the external representations
  (lists) for monomials in the algebra.[133X
  
  [29X[2XNextOrdering[102X( [3X<NoncommutativeMonomialOrdering>[103X ) [32X attribute
  
  [33X[0;0YReturns  the  next  noncommutative  monomial  ordering  chained to the given
  ordering, if one exists. It is usually called after a [10Xtrue[110X determination has
  been made with a [10XHasNextOrdering[110X call.[133X
  
  [29X[2XParentAlgebra[102X( [3X<NoncommutativeMonomialOrdering>[103X ) [32X attribute
  
  [33X[0;0YReturns the parent algebra used in the creation of the given ordering.[133X
  
  [29X[2XLexicographicTable[102X( [3X<NoncommutativeMonomialOrdering>[103X ) [32X attribute
  
  [33X[0;0YReturns the ordering of the generators of the [10XParentAlgebra[110X, as specified in
  the creation of the given ordering.[133X
  
  [29X[2XLexicographicIndexTable[102X( [3X<NoncommutativeMonomialOrdering>[103X ) [32X attribute
  
  [33X[0;0YReturns the ordering of the generators of the [10XParentAlgebra[110X, as specified in
  the creation of the given ordering.[133X
  
  [33X[0;0YAn  example  here  would  be  useful.  We create a length left-lexicographic
  ordering  on  an algebra [10XA[110X with an order on the generators of [22Xb < a < d < c[122X.
  Then  in  accessing  the  attributes via the atrributes above we see how the
  list given by [10XLexicographicIndexTable[110X indexes the ordered generators:[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27XA := FreeAssociativeAlgebraWithOne(Rationals,"a","b","c","d");[127X[104X
    [4X[28X<algebra-with-one over Rationals, with 4 generators>[128X[104X
    [4X[25Xgap>[125X [27Xml := NCMonomialLeftLengthLexOrdering(A,2,4,1,3);[127X[104X
    [4X[28XNCMonomialLeftLengthLexicographicOrdering([ (1)*b, (1)*d, (1)*a, (1)*c ])[128X[104X
    [4X[25Xgap>[125X [27X LexicographicTable(ml);[127X[104X
    [4X[28X[ (1)*b, (1)*d, (1)*a, (1)*c ][128X[104X
    [4X[25Xgap>[125X [27XLexicographicIndexTable(ml);[127X[104X
    [4X[28X[ 3, 1, 4, 2 ][128X[104X
  [4X[32X[104X
  
  [33X[0;0YThe  index  table  shows  that the generator [22Xa[122X is the third in the generator
  ordering,  [22Xb[122X is the least generator in the ordering, [22Xc[122X is the greatest and [22Xd[122X
  the second least in order.[133X
  
  [29X[2XLexicographicPermutation[102X( [3X<NoncommutativeMonomialOrdering>[103X ) [32X attribute
  
  [33X[0;0YExperimental  permutation  based  on  the information in [10XLexicographicTable[110X,
  could possibly be used to make indexed versions of comparison functions more
  efficient.    Currently   only   used   by   the   [5XNMO[105X   built-in   ordering
  [10XNCMonomialLLLTestOrdering[110X.[133X
  
  [29X[2XAuxilliaryTable[102X( [3X<NoncommutativeMonomialOrdering>[103X ) [32X attribute
  
  [33X[0;0YAn  extra  table  carried  by  the given ordering which can be used for such
  things as weight vectors, etc.[133X
  
  [29X[2XOrderingLtFunctionListRep[102X( [3X<NoncommutativeMonomialOrdering>[103X ) [32X operation
  
  [29X[2XOrderingGtFunctionListRep[102X( [3X<NoncommutativeMonomialOrdering>[103X ) [32X operation
  
  [33X[0;0YGiven  a  noncommutative  monomial  ordering,  [10XOrderingLtFunctionListRep[110X and
  [10XOrderingLtFunctionListRep[110X   return   functions   which  compare  the  `list'
  representations  (NP  representations)  of two monomials from the ordering's
  associated parent algebra. These functions are not typically accessed by the
  user.[133X
  
  
  [1X1.4-3 [33X[0;0YProvided Orderings[133X[101X
  
  [29X[2XNCMonomialLeftLengthLexicographicOrdering[102X( [3X<algebra>[103X, [3X<list>[103X ) [32X function
  
  [33X[0;0YGiven  a  free algebra [22XA[122X, and an optional ordered (possibly partial) ordered
  list        of        generators        for       the       algebra       [22XA[122X,
  [10XNCMonomialLeftLengthLexicographicOrdering[110X  returns  a  noncommutative length
  lexicographic ordering object. If an ordered list of generators is provided,
  its  order  is  used  in  creation  of the ordering object. If a list is not
  provided,  then  the  ordering  object  is created based on the order of the
  generators when the free algebra [22XA[122X was created.[133X
  
  [33X[0;0YNote: the synonym [10XNCMonomialLeftLengthLexOrdering[110X may also be used.[133X
  
  [29X[2XNCMonomialLengthOrdering[102X( [3X<algebra>[103X ) [32X function
  
  [33X[0;0YGiven  a  free  algebra [22XA[122X, [10XNCMonomialLengthOrdering[110X returns a noncommutative
  length  ordering object. Only the lengths of the words of monomials in [22XA[122X are
  compared using this ordering.[133X
  
  [29X[2XNCMonomialLeftLexicographicOrdering[102X( [3X<algebra>[103X, [3X<list>[103X ) [32X function
  
  [33X[0;0YGiven  a  free algebra [22XA[122X, and an optional ordered (possibly partial) ordered
  list  of  generators  for the algebra [22XA[122X, [10XNCMonomialLeftLexicographicOrdering[110X
  returns a simple noncommutative left-lexicographic ordering object.[133X
  
  [29X[2XNCMonomialCommutativeLexicographicOrdering[102X( [3X<algebra>[103X, [3X<list>[103X ) [32X function
  
  [33X[0;0YGiven  a  free algebra [22XA[122X, and an optional ordered (possibly partial) ordered
  list        of        generators        for       the       algebra       [22XA[122X,
  [10XNCMonomialCommutativeLexicographicOrdering[110X     returns     a     commutative
  left-lexicographic  ordering  object.  Under this ordering, monomials from [22XA[122X
  are compared using their respective commutative analogues.[133X
  
  [29X[2XNCMonomialWeightOrdering[102X( [3X<algebra>[103X, [3X<list>[103X, [3X<list2>[103X ) [32X function
  
  [33X[0;0YGiven  a  free  algebra  [22XA[122X,  an ordered (possibly partial) ordered [10X<list>[110X of
  generators  for  the  algebra [22XA[122X, and a [10X<list2>[110X of respective weights for the
  generators,   [10XNCMonomialWeightOrdering[110X   returns   a  noncommutative  weight
  ordering object.[133X
  
  
  [1X1.4-4 [33X[0;0YExternals[133X[101X
  
  [33X[0;0YAll  user-level  interface  routines in the descriptions following allow for
  the  comparison of not only monomials from a given algebra with respect to a
  given  ordering,  but  also  compare  general  elements  from  an algebra by
  comparing  their  leading terms (again, with respect to the given ordering).
  These routines are located in the files [10Xncinterface.gd[110X and [10Xncinterface.gi[110X.[133X
  
  
  [1X1.4-5 [33X[0;0YExternal Routines[133X[101X
  
  [29X[2XNCLessThanByOrdering[102X( [3X<NoncommutativeMonomialOrdering>[103X, [3X<a>[103X, [3X<b>[103X ) [32X operation
  
  [33X[0;0YGiven  a  [10X<NoncommutativeMonomialOrdering>[110X  on  an  algebra  [22XA[122X  and [22Xa,b ∈ A[122X,
  [10XNCLessThanByOrdering[110X  returns  the  (boolean)  result  of  [22Xa  <  b[122X,  where [22X<[122X
  represents       the       comparison       operator      determined      by
  [10X<NoncommutativeMonomialOrdering>[110X.[133X
  
  [29X[2XNCGreaterThanByOrdering[102X( [3X<NoncommutativeMonomialOrdering>[103X, [3X<a>[103X, [3X<b>[103X ) [32X operation
  
  [33X[0;0YGiven  a  [10X<NoncommutativeMonomialOrdering>[110X  on  an  algebra  [22XA[122X  and [22Xa,b ∈ A[122X,
  [10XNCLessThanByOrdering[110X  returns  the  (boolean)  result  of  [22Xa  >  b[122X,  where [22X>[122X
  represents       the       comparison       operator      determined      by
  [10X<NoncommutativeMonomialOrdering>[110X.[133X
  
  [29X[2XNCEquivalentByOrdering[102X( [3X<NoncommutativeMonomialOrdering>[103X, [3X<a>[103X, [3X<b>[103X ) [32X operation
  
  [33X[0;0YGiven  a  [10X<NoncommutativeMonomialOrdering>[110X  on  an  algebra  [22XA[122X  and [22Xa,b ∈ A[122X,
  [10XNCLessThanByOrdering[110X  returns  the  (boolean)  result  of  [22Xa  =  b[122X,  where [22X=[122X
  represents       the       comparison       operator      determined      by
  [10X<NoncommutativeMonomialOrdering>[110X.[133X
  
  [33X[0;0YSome examples of these methods in use:[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27XA := FreeAssociativeAlgebraWithOne(Rationals,"x","y","z");[127X[104X
    [4X[28X<algebra-with-one over Rationals, with 3 generators>[128X[104X
    [4X[25Xgap>[125X [27Xx := A.x;; y := A.y;; z := A.z;; id := One(A);;[127X[104X
    [4X[25Xgap>[125X [27Xw1 := x*x*y;; w2 := x*y*x;; w3 := z*x;;[127X[104X
    [4X[28X[128X[104X
    [4X[25Xgap>[125X [27Xml := NCMonomialLeftLengthLexOrdering(A);[127X[104X
    [4X[28XNCMonomialLeftLengthLexicographicOrdering([ (1)*x, (1)*y, (1)*z ])[128X[104X
    [4X[28X[128X[104X
    [4X[25Xgap>[125X [27Xml2 := NCMonomialLengthOrdering(A);[127X[104X
    [4X[28XNCMonomialLengthOrdering([ (1)*x, (1)*y, (1)*z ])[128X[104X
    [4X[28X[128X[104X
    [4X[25Xgap>[125X [27Xml7 := NCMonomialWeightOrdering(A,[1,2,3],[1,1,2]);[127X[104X
    [4X[28XNCMonomialWeightOrdering([ (1)*x, (1)*y, (1)*z ])[128X[104X
    [4X[28X[128X[104X
    [4X[25Xgap>[125X [27Xml8 := NCMonomialWeightOrdering(A,[2,3,1],[1,1,2]);[127X[104X
    [4X[28XNCMonomialWeightOrdering([ (1)*y, (1)*z, (1)*x ])[128X[104X
    [4X[28X[128X[104X
    [4X[25Xgap>[125X [27X#  Left length-lex ordering, x<y<z:[127X[104X
    [4X[25Xgap>[125X [27XNCEquivalentByOrdering(ml,w1,w2);[127X[104X
    [4X[28Xfalse[128X[104X
    [4X[25Xgap>[125X [27X#  Length ordering:[127X[104X
    [4X[25Xgap>[125X [27XNCEquivalentByOrdering(ml2,w1,w2);[127X[104X
    [4X[28Xtrue[128X[104X
    [4X[25Xgap>[125X [27XNCEquivalentByOrdering(ml2,w3,w2);[127X[104X
    [4X[28Xfalse[128X[104X
    [4X[25Xgap>[125X [27X# Weight ordering ( z=2, x=y=1 ):[127X[104X
    [4X[25Xgap>[125X [27XNCEquivalentByOrdering(ml7,w1,w2);[127X[104X
    [4X[28Xtrue[128X[104X
    [4X[25Xgap>[125X [27XNCEquivalentByOrdering(ml7,w3,w2);[127X[104X
    [4X[28Xtrue[128X[104X
    [4X[25Xgap>[125X [27X# Weight ordering ( z=2, x=y=1 ), different lex:[127X[104X
    [4X[25Xgap>[125X [27XNCEquivalentByOrdering(ml8,w1,w2);[127X[104X
    [4X[28Xtrue[128X[104X
    [4X[25Xgap>[125X [27XNCEquivalentByOrdering(ml8,w3,w2);[127X[104X
    [4X[28Xtrue[128X[104X
  [4X[32X[104X
  
  [29X[2XNCSortNP[102X( [3X<NoncommutativeMonomialOrdering>[103X, [3X<list>[103X, [3X<function>[103X ) [32X operation
  
  [33X[0;0YGiven   a   [10X<list>[110X  of  NP  `list'  representations  for  monomials  from  a
  noncommutative algebra, and an NP comparison (ordering) function [10X<function>[110X,
  [10XNCSortNP[110X  returns  a  sorted  version  of  [10X<list>[110X  (with  respect  to the NP
  comparison  function  [10X<function>[110X).  The sort used here is an insertion sort,
  per the recommendation from [NR02].[133X
  
  
  [1X1.4-6 [33X[0;0YFlexibility vs. Efficiency[133X[101X
  
  [33X[0;0YWe  recall  that  [10XInstallNoncommutativeMonomialOrdering[110X  completes a list of
  generators  if  only  a  partial  one  is  provided. An example will provide
  clarity  here.  It  is  given in terms of length-lex, but the generator list
  completion  functionality is identical for any [5XNMO[105X ordering. Note: If at all
  possible,  users are encouraged to use the default ordering on generators as
  it  is  more  efficient  than  the  indirection  inherent in sorting via the
  indexed  list  [10XLexicographicIndexTable[110X.  Here  is  the  example  showing the
  flexibility in requiring only a partial list of the ordering on generators:[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27XA := FreeAssociativeAlgebraWithOne(Rationals,"a","b","c","d");[127X[104X
    [4X[28X<algebra-with-one over Rationals, with 4 generators>[128X[104X
    [4X[25Xgap>[125X [27Xml2 := NCMonomialLeftLengthLexOrdering(A,[3,1]);[127X[104X
    [4X[28XNCMonomialLeftLengthLexicographicOrdering([ (1)*c, (1)*a, (1)*b, (1)*d ])[128X[104X
    [4X[25Xgap>[125X [27XLexicographicTable(ml2);[127X[104X
    [4X[28X[ (1)*c, (1)*a, (1)*b, (1)*d ][128X[104X
  [4X[32X[104X
  
  
  [1X1.5 [33X[0;0YUtility Routines[133X[101X
  
  
  [1X1.5-1 [33X[0;0YGBNP Patching Routines[133X[101X
  
  [29X[2XPatchGBNP[102X( [3X<NoncommutativeMonomialOrdering>[103X ) [32X operation
  
  [29X[2XUnpatchGBNP[102X(  ) [32X function
  
  [33X[0;0YLet  [10X<NoncommutativeMonomialOrdering>[110X  be a monomial ordering (on an algebra
  [22XA[122X).  [10XPatchGBNP[110X  overwrites  the [5XGBNP[105X Global functions [10XLtNP[110X and [10XGtNP[110X with the
  less-than       and       greater-than       functions      defined      for
  [10X<NoncommutativeMonomialOrdering>[110X. The purpose of such a patching is to force
  [5XGBNP[105X to use [10X<NoncommutativeMonomialOrdering>[110X in its computation of a Gröbner
  basis.  [10XUnpatchGBNP()[110X  simply  restores the [10XLtNP[110X and [10XGtNP[110X functions to their
  original  state.  The  examples in Quickstart section are more illustrative,
  but here is an example of the use of the patching routines above:[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27XA := FreeAssociativeAlgebraWithOne(Rationals,"x","y","z");[127X[104X
    [4X[28X<algebra-with-one over Rationals, with 3 generators>[128X[104X
    [4X[25Xgap>[125X [27Xml := NCMonomialLeftLexicographicOrdering(A,3,2,1);[127X[104X
    [4X[28XNCMonomialLeftLexicographicOrdering([ (1)*z, (1)*y, (1)*x ])[128X[104X
    [4X[25Xgap>[125X [27XPatchGBNP(ml);[127X[104X
    [4X[28XLtNP patched.[128X[104X
    [4X[28XGtNP patched.[128X[104X
    [4X[25Xgap>[125X [27XUnpatchGBNP();[127X[104X
    [4X[28XLtNP restored.[128X[104X
    [4X[28XGtNP restored.[128X[104X
  [4X[32X[104X
  
  
  [1X1.5-2 [33X[0;0YPrinting Routine[133X[101X
  
  [29X[2XString[102X( [3X<obj>[103X ) [32X operation
  
  [33X[0;0Y[5XGAP[105X  seems to be currently lacking a method to convert an object from a free
  associative  ring to a string version of the same object. This routine fills
  that gap.[133X
  
  [33X[0;0YExample (after loading [5XNMO[105X via the [5XGBNP[105X package):[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27XA := FreeAssociativeAlgebraWithOne(ZmodpZ(19),"x","y");[127X[104X
    [4X[28X<algebra-with-one over GF(19), with 2 generators>[128X[104X
    [4X[25Xgap>[125X [27Xx := A.x; y := A.y;[127X[104X
    [4X[28X(Z(19)^0)*x[128X[104X
    [4X[28X(Z(19)^0)*y[128X[104X
    [4X[25Xgap>[125X [27XIsString(String(x^2+x*y*x));[127X[104X
    [4X[28Xtrue[128X[104X
    [4X[25Xgap>[125X [27XString(x^2+x*y*x);[127X[104X
    [4X[28X"(Z(19)^0)*x^2+(Z(19)^0)*x*y*x"[128X[104X
  [4X[32X[104X
  
  [33X[0;0YExample (before loading [5XNMO[105X via the [5XGBNP[105X package):[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27X A := FreeAssociativeAlgebraWithOne(ZmodpZ(19),"x","y");[127X[104X
    [4X[28X<lgebra-with-one over GF(19), with 2 generators>[128X[104X
    [4X[25Xgap>[125X [27Xx := A.x; y := A.y;[127X[104X
    [4X[28X(Z(19)^0)*x[128X[104X
    [4X[28X(Z(19)^0)*y[128X[104X
    [4X[25Xgap>[125X [27X String(x^2+x*y*x);[127X[104X
    [4X[28XError, no method found! For debugging hints type ?Recovery from NoMethodFound[128X[104X
    [4X[28XError, no 1st choice method found for `String' on 1 arguments called from[128X[104X
    [4X[28X<function>( <arguments> ) called from read-eval-loop[128X[104X
    [4X[28XEntering break read-eval-print loop ...[128X[104X
    [4X[28Xyou can 'quit;' to quit to outer loop, or[128X[104X
    [4X[28Xyou can 'return;' to continue[128X[104X
    [4X[26Xbrk>[126X[104X
  [4X[32X[104X
  
