-- -*- coding: utf-8 -*-
--- status: DRAFT
--- author(s): kummini, MES
--- notes: 

document { 
     Key => {
	  "methods for normal forms and remainder",
	  (symbol %, RingElement, Ideal),
	  (symbol %, RingElement, MonomialIdeal),
	  (symbol %, RingElement, Matrix),
	  (symbol %, RingElement, RingElement),
	  (symbol %, Matrix, Ideal),
	  (symbol %, Matrix, MonomialIdeal),
	  (symbol %, Matrix, RingElement),
	  (symbol %, Matrix, Module),
	  (symbol %, Matrix, Matrix)	  
	  },
     Headline => "normal form of ring elements and matrices",
     SYNOPSIS(
     	  Usage => "f % I",
     	  Inputs => { "f" => {ofClass{RingElement,Matrix}}, "I" => {ofClass {RingElement,Ideal,MonomialIdeal} }},
     	  Outputs => { Matrix => {"the normal form of ", TT "f", " modulo the ideal ", TT "I", ".  
		    The result is obtained by reducing each entry of ", TT "f", " modulo ", TT "I", "."} },
     ),
     PARA{
	  "To reduce ", TT "f", " with respect to ", TT "I", 
	  ", a (partial) Gröbner basis of ", TT "I", " is computed, unless
	  it has already been done, or unless ", TT "I", " is ", ofClass {MonomialIdeal}, "."
	  },
     EXAMPLE lines ///
	  R = ZZ/1277[x,y];
    	  I = ideal(x^3 - 2*x*y, x^2*y - 2*y^2 + x);
	  (x^3 - 2*x) % I
	  (x^3) % I
	  S = ZZ[x,y];
	  144*x^2*y^2 % (7*x*y-2)
     ///,
     SYNOPSIS(
     	  Usage => "f % M",
     	  Inputs => { "f" => {ofClass{RingElement,Matrix}}, "M" => {ofClass {Module,Matrix}} },
     	  Outputs => { Matrix => {"the normal form of the matrix ", TT "f", " modulo the image of ", TT "M", ",
		    if ", TT "M", " is a matrix with the same target as ", TT "f", ", or modulo ", TT "M", " if ", TT "M", " is a submodule of
		    the target of ", TT "f", ".  The result is obtained by reducing each column of ", TT "f", " modulo ", TT "M", "."  } },
     ),
     EXAMPLE lines ///
     	  S = QQ[a..f]
     	  J = ideal(a*b*c-d*e*f,a*b*d-c*e*f, a*c*e-b*d*f)
	  C = res J
	  F = syz transpose C.dd_4
	  G = transpose C.dd_3
	  ///,
     PARA {
     	  "Since ", TT "C", " is a complex, we know that the image of ", TT "G", " is contained in the image of ", TT "F", "."
	  },
     EXAMPLE lines ///
	  G % F
	  F % G
	  ///,
     PARA {
	  "The inclusion is strict, since ", TT "F % G != 0", " implies that
	  the image of ", TT "F", " is not contained in the image of ", TT "G", "."
	  },
     PARA {
     	  "Normal forms work over quotient rings too."
	  },
     EXAMPLE lines ///
     	  A = QQ[x,y,z]/(x^3-y^2-3)
	  I = ideal(x^4, y^4)
	  J = ideal(x^3*y^2, x^2*y^3)
	  (gens J) % I
     ///,
     PARA{"Here is an example involving rational functions."},
     EXAMPLE lines ///
     	  kk = frac(ZZ[a,b])
	  B = kk[x,y,z]
	  I = ideal(a*x^2-b*x-y-1, 1/b*y^2-z-1)
	  gens gb I
	  x^2*y^2 % I
     ///,
     SeeAlso => {symbol %, "Gröbner bases", generators, (symbol %, Matrix, GroebnerBasis)},
     }

document { 
     Key => {
	  (symbol %, Matrix, GroebnerBasis),
	  (symbol %, RingElement, GroebnerBasis)
	  },
     Headline => "calculate the normal form of ring elements and 
          matrices using a (partially computed) Gröbner basis",
     Usage => "f % G",
     Inputs => { "f" => Nothing => {ofClass RingElement, ", or ",
	       ofClass Matrix},
	     "G"
	     },
     Outputs => {
	  Nothing => {"the normal form of ", TT "f", " with respect 
	       to the partially computed Gröbner basis ", TT "G"}
	  },
     "In the following example, the seventh power of the trace of the matrix M
     is in the ideal generated by the entries of the cube of M.  Since the
     ideal I is homogeneous, it is only required to compute the Gröbner basis
     in degrees at most seven.",
     EXAMPLE lines ///
     	  R = QQ[a..i];
	  M = genericMatrix(R,a,3,3)
	  I = ideal(M^3);
     	  f = trace M
	  G = gb(I, DegreeLimit=>3)
     	  f^7 % G == 0
	  gb(I, DegreeLimit=>7)	  	  
	  f^7 % G
	  gb I
     ///,
     "In these homogeneous situations, Macaulay2 only computes the
     Gröbner basis as far as required, as shown below.",
     EXAMPLE lines ///
	  I = ideal(M^3);
	  G = gb(I, StopBeforeComputation=>true)
	  f^7 % I
	  status G
     ///,
     SeeAlso => {"methods for normal forms and remainder", "Gröbner bases", genericMatrix}
     }
