undocumented {
    (saturate, Ideal,  Number),
    (saturate, Vector, Number),
    (saturate, Module, Number),
    (saturate, Ideal,  List),
    (saturate, Module, List),
    (saturate, Vector, List)
    }

doc ///
Node
  Key
    saturate
   (saturate, Ideal)
   (saturate, Ideal, Ideal)
   (saturate, Ideal, RingElement)
   (saturate, MonomialIdeal, RingElement)
   (saturate, Module)
   (saturate, Module, Ideal)
   (saturate, Module, RingElement)
   (saturate, Vector)
   (saturate, Vector, Ideal)
   (saturate, Vector, RingElement)
   [saturate, MinimalGenerators]
  Headline
    saturation of ideal or submodule
  Usage
    saturate(I, J)
    saturate I
  Inputs
    I:{Ideal,MonomialIdeal,Module}
    J:{Ideal,MonomialIdeal,Module,RingElement}
      if not present, then the ideal generated by the variables of the ring is used
    Strategy=>Thing
      specifies the algorithm
    MinimalGenerators=>Boolean
      indicates whether the output should be @TO2 {trim, "trimmed"}@
  Outputs
    :{Ideal,Module}
      the saturation $I:J^\infty = \{f | f J^N\subset I \text{ for some } N>0\}$
  Description
    Text
      If $I$ is either an ideal or a submodule of a module $M$, the saturation $I : J^\infty$ is defined to be the
      set of elements $f$ in the ring or $M$ such that $f J^N$ is contained in $I$, for some $N$ large enough.

      For example, one way to homogenize an ideal is to homogenize the generators
      and then saturate with respect to the homogenizing variable.
    Example
      R = ZZ/32003[a..d];
      I = ideal(a^3-b, a^4-c)
      Ih = homogenize(I,d)
      saturate(Ih,d)
    Text
      We can use this command to remove graded submodules of finite length.
    Example
      m = ideal vars R
      M = R^1 / (a * m^2)
      M / saturate 0_M
    Text
      If $I$ and $J$ are both monomial ideals, then a faster algorithm is used.
      Otherwise, when needed, Gröbner bases will be computed, and if the computation succeeds the result
      is cached inside the first argument. Partial computations are not yet cached, but this may change in a future version.
  SeeAlso
    (quotient, Ideal, Ideal)
    annihilator
    "MinimalPrimes::MinimalPrimes"
    "PrimaryDecomposition::PrimaryDecomposition"
  Subnodes
    isSupportedInZeroLocus

Node
  Key
    [saturate, Strategy]
  Description
    Text
      There are four strategy values:
    Code
      SUBSECTION "Iterate",
	TT "saturate(I,J,Strategy => Iterate)", " -- indicates that successive ideal
	or module quotients should be used.",
	PARA{},
	"This value is the default.",
      SUBSECTION "Linear",
	TT "saturate(I,J,Strategy => Linear)",
	TT "Strategy => Linear", " -- indicates that the reverse lex order should
	be used to compute the saturation.",
	PARA{},
	"This presumes that ", TT "J", " is a single, linear polynomial, and that ", TT "I", "
	is homogeneous.",
      SUBSECTION "Bayer",
	TT "saturate(I,f,Strategy => Bayer)", " -- indicates that the method of Bayer's
	thesis should be used.",
	PARA{},
	"The method is to compute ", TT "(I:f)", " for ", TT "I", " and ", TT "f", " homogeneous,
	add a new variable ", TT "z", ", compute a Gröbner basis of ", TT "(I,f-z)", " in reverse
	lex order, divide by ", TT "z", ", and finally replace ", TT "z", " by ", TT "f", ".",
      SUBSECTION "Eliminate",
	TT "saturate(I,f,Strategy => Eliminate)", " -- indicates that the
	saturation ", TT "(I:f)", " should be computed by eliminating
	f", TT "z", " from ", TT "(I,f*z-1)", ", where ", TT "z", " is a new variable."

Node
  Key
     isSupportedInZeroLocus
    (isSupportedInZeroLocus, Ideal, Ideal)
    (isSupportedInZeroLocus, Ideal, Module)
    (isSupportedInZeroLocus, Ideal, GradedModule)
  Headline
    whether support of a module is contained in the zero locus of the (irrelevant) ideal
  Usage
    isSupportedInZeroLocus_B M
  Inputs
    M:Module
    B:Ideal
  Outputs
    :Boolean
      true if $M$ (or $R^1/I$, if an ideal of $R$ is given) is supported only on the zero locus of $B$;
      that is, whether $\mathrm{supp}(M) \subset \mathrm{V}(B)$
  Description
    Text
      Given an module $M$ and an ideal $B$, {\tt isSupportedInZeroLocus} checks whether $\mathrm{ann}(M):B^\infty=R$.
      If it is, {\tt isSupportedInZeroLocus} returns true otherwise it returns false. If the first argument is an ideal,
      $M = R^1/I$ is taken as the module.
    Example
      S = ZZ/32003[x_0..x_4, Degrees=>{2:{1,0}, 3:{0,1}}];
      irr = intersect(ideal(x_0,x_1), ideal(x_2,x_3,x_4));
      M = S^1/(irr^2);
      isSupportedInZeroLocus_irr M
    Text
      This is done without computing saturation of $M$. Instead, we check whether for each generator of $B$ some power
      of it annihilates the module $M$.
///
