# HG changeset patch
# User Martin Albrecht <malb@informatik.uni-bremen.de>
# Date 1244695664 25200
# Node ID 8037fada5b30c30dc6b36c7fa2d30386b37852ac
# Parent  6c7354ace3b6e0bf4c33ddb730531bd23a9fb92c
enable the various Singular coefficient rings

diff -r 6c7354ace3b6 -r 8037fada5b30 doc/en/reference/polynomial_rings.rst
--- a/doc/en/reference/polynomial_rings.rst	Sat Jun 06 09:55:28 2009 -0700
+++ b/doc/en/reference/polynomial_rings.rst	Wed Jun 10 21:47:44 2009 -0700
@@ -1,3 +1,4 @@
+
 .. _ch:polynomial-rings:
 
 Polynomial Rings
@@ -13,15 +14,21 @@
    sage/rings/polynomial/polynomial_quotient_ring_element
 
    sage/rings/polynomial/term_order
+   sage/rings/polynomial/multi_polynomial_libsingular
+
    sage/rings/polynomial/multi_polynomial_ring
    sage/rings/polynomial/multi_polynomial_element
    sage/rings/polynomial/infinite_polynomial_ring
    sage/rings/polynomial/infinite_polynomial_element
 
    sage/rings/polynomial/multi_polynomial_ideal
+
    sage/rings/polynomial/symmetric_ideal
    sage/rings/polynomial/symmetric_reduction
+
+   sage/rings/polynomial/toy_buchberger
    sage/rings/polynomial/toy_variety
+   sage/rings/polynomial/toy_d_basis
 
    sage/rings/polynomial/pbori
 
diff -r 6c7354ace3b6 -r 8037fada5b30 sage/interfaces/singular.py
--- a/sage/interfaces/singular.py	Sat Jun 06 09:55:28 2009 -0700
+++ b/sage/interfaces/singular.py	Wed Jun 10 21:47:44 2009 -0700
@@ -375,7 +375,13 @@
         Expect._start(self, alt_message)
         # Load some standard libraries.
         self.lib('general')   # assumed loaded by misc/constants.py
-        
+
+        # these options are required by the new coefficient rings
+        # supported by Singular 3-1-0.
+        self.option("redTail")
+        self.option("redThrough")
+        self.option("intStrategy")
+
     def __reduce__(self):
         """
         EXAMPLES::
diff -r 6c7354ace3b6 -r 8037fada5b30 sage/libs/singular/singular-cdefs.pxi
--- a/sage/libs/singular/singular-cdefs.pxi	Sat Jun 06 09:55:28 2009 -0700
+++ b/sage/libs/singular/singular-cdefs.pxi	Wed Jun 10 21:47:44 2009 -0700
@@ -91,6 +91,39 @@
         napoly *n
         int s
 
+    ctypedef struct n_Procs_s:
+
+        number* nDiv(number *, number *)
+        number* nAdd(number *, number *)
+        number* nSub(number *, number *)
+        number* nMul(number *, number *)
+
+        void    (*nNew)(number* * a)
+        number*  (*nInit)(int i)
+        number*  (*nPar)(int i)
+        int     (*nParDeg)(number* n)
+        int     (*nSize)(number* n)
+        int     (*nInt)(number* n)
+        int     (*nDivComp)(number* a,number* b)
+        number*  (*nGetUnit)(number* a)
+        number*  (*nExtGcd)(number* a, number* b, number* *s, number* *t)
+
+        number*  (*nNeg)(number* a)
+        number*  (*nInvers)(number* a)
+        number*  (*nCopy)(number* a)
+        number*  (*nRePart)(number* a)
+        number*  (*nImPart)(number* a)
+        void    (*nWrite)(number* a)
+        void    (*nNormalize)(number* a)
+
+        bint (*nDivBy)(number* a, number* b)
+        bint (*nEqual)(number* a,number* b)
+        bint (*nIsZero)(number* a)
+        bint (*nIsOne)(number* a)
+        bint (*nIsMOne)(number* a)
+        bint (*nGreaterZero)(number* a)
+        void (*nPower)(number* a, int i, number* * result)
+
     # rings
 
     ctypedef struct ring "ip_sring":
@@ -108,8 +141,13 @@
         short N # number of variables
         short P # number of parameters
         int ch # charactersitic (0:QQ, p:GF(p),-p:GF(q), 1:NF)
+        unsigned int ringtype # field etc.
+        mpz_t ringflaga
+        unsigned long ringflagb
         int pCompIndex # index of components
 
+        n_Procs_s*    cf
+
     # available ring orders
 
     cdef enum rRingOrder_t:
@@ -209,6 +247,7 @@
 
 
 
+    void *omAlloc(size_t size)
 
     # calloc
 
@@ -293,6 +332,11 @@
     
     int p_SetCoeff(poly *p, number *n, ring *r) 
 
+    # set the coefficient n for the current list element p in r
+    # without deleting the current coefficient first
+
+    int p_SetCoeff0(poly *p, number *n, ring *r) 
+
     # get the coefficient of the current list element p in r
     
     number *p_GetCoeff(poly *p, ring *r)
@@ -616,6 +660,20 @@
     # map Q -> Q(a)
     number *naMap00(number *c)
 
+
+    # init integer
+    number *nrzInit(int i)
+
+    # init ZmodN from GMP
+    number *nrnMapGMP(number *v)
+
+    #init 2^m from a long
+    number *nr2mMapZp(number *)
+    
+
+    # get C int from ZmodN
+    int nrnInt(number *v)
+
     # ideal constructor
 
     ideal *idInit(int size, int rank)
diff -r 6c7354ace3b6 -r 8037fada5b30 sage/libs/singular/singular.pxd
--- a/sage/libs/singular/singular.pxd	Sat Jun 06 09:55:28 2009 -0700
+++ b/sage/libs/singular/singular.pxd	Wed Jun 10 21:47:44 2009 -0700
@@ -3,6 +3,7 @@
 from sage.rings.rational cimport Rational
 from sage.structure.element cimport Element
 from sage.rings.integer cimport Integer
+from sage.rings.integer_mod cimport IntegerMod_abstract
 from sage.rings.finite_field_givaro cimport FiniteField_givaro,FiniteField_givaroElement
 from sage.rings.finite_field_ntl_gf2e cimport FiniteField_ntl_gf2e,FiniteField_ntl_gf2eElement
 from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomial_libsingular
@@ -10,25 +11,30 @@
 
 from sage.rings.number_field.number_field_base cimport NumberField
 
-cdef class Conversion:
-    cdef extern Rational si2sa_QQ(self, number (*),ring (*))
-    cdef extern Integer si2sa_ZZ(self, number (*),ring (*))
-    cdef extern FiniteField_givaroElement si2sa_GFqGivaro(self, number *n, ring *_ring, FiniteField_givaro base)
-    cdef extern FiniteField_ntl_gf2eElement si2sa_GFqNTLGF2E(self, number *n, ring *_ring, FiniteField_ntl_gf2e base)
-    cdef extern object si2sa_GFqPari(self, number *n, ring *_ring, object base)
-    cdef extern object si2sa_NF(self, number *n, ring *_ring, object base)
-    
-    cdef extern number *sa2si_QQ(self, Rational ,ring (*))
-    cdef extern number *sa2si_ZZ(self, Integer d, ring *_ring)
+# Singular -> Sage
 
-    cdef extern number *sa2si_GFqGivaro(self, int exp ,ring (*))
-    cdef extern number *sa2si_GFqPari(self, object vector, ring *_ring)
-    cdef extern number *sa2si_GFqNTLGF2E(self, FiniteField_ntl_gf2eElement elem, ring *_ring)
+cdef Rational                    si2sa_QQ(number (*),ring (*))
+cdef Integer                     si2sa_ZZ(number (*),ring (*))
 
-    cdef extern number *sa2si_NF(self, object element, ring *_ring)
+cdef FiniteField_givaroElement   si2sa_GFqGivaro(number *n, ring *_ring, FiniteField_givaro base)
+cdef FiniteField_ntl_gf2eElement si2sa_GFqNTLGF2E(number *n, ring *_ring, FiniteField_ntl_gf2e base)
+cdef object                      si2sa_GFqPari(number *n, ring *_ring, object base)
+cdef inline object               si2sa_ZZmod(number *n, ring *_ring, object base)
 
-    cdef extern object si2sa(self, number *n, ring *_ring, object base)
-    cdef extern number *sa2si(self, Element elem, ring * _ring)
+cdef object                       si2sa_NF(number *n, ring *_ring, object base)
 
+cdef object si2sa(number *n, ring *_ring, object base)
 
-    cdef extern  MPolynomial_libsingular new_MP(self, MPolynomialRing_libsingular parent, poly *p)
+# Sage -> Singular
+
+cdef number *sa2si_QQ(Rational ,ring (*))
+cdef number *sa2si_ZZ(Integer d, ring *_ring)
+
+cdef number *sa2si_GFqGivaro(int exp ,ring (*))
+cdef number *sa2si_GFqPari(object vector, ring *_ring)
+cdef number *sa2si_GFqNTLGF2E(FiniteField_ntl_gf2eElement elem, ring *_ring)
+cdef inline number *sa2si_ZZmod(IntegerMod_abstract d, ring *_ring)
+
+cdef number *sa2si_NF(object element, ring *_ring)
+
+cdef number *sa2si(Element elem, ring * _ring)
diff -r 6c7354ace3b6 -r 8037fada5b30 sage/libs/singular/singular.pyx
--- a/sage/libs/singular/singular.pyx	Sat Jun 06 09:55:28 2009 -0700
+++ b/sage/libs/singular/singular.pyx	Wed Jun 10 21:47:44 2009 -0700
@@ -22,6 +22,7 @@
 
 from sage.rings.rational_field import RationalField
 from sage.rings.integer_ring cimport IntegerRing_class
+from sage.rings.integer_mod_ring import IntegerModRing_generic
 from sage.rings.finite_field_prime_modn import FiniteField_prime_modn
 from sage.rings.finite_field_ext_pari import FiniteField_ext_pari
 from sage.libs.pari.all import pari
@@ -29,304 +30,341 @@
 from sage.structure.parent_base cimport ParentWithBase
 from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomial_libsingular
 
+cdef Rational si2sa_QQ(number *n, ring *_ring):
+    """
+    TESTS::
+    
+        sage: P.<x,y,z> = QQ[]
+        sage: P(1/3).lc()
+        1/3
+        sage: P(1).lc()
+        1
+        sage: P(0).lc()
+        0
+        sage: P(-1/3).lc()
+        -1/3
+        sage: type(P(3).lc())
+        <type 'sage.rings.rational.Rational'>
+    """
+    cdef number *nom
+    cdef number *denom
+    cdef mpq_t _z
 
-cdef class Conversion:
+    cdef mpz_t nom_z, denom_z
+
+    cdef Rational z
+
+    mpq_init(_z)
+
+    ##  Immediate integers handles carry the tag 'SR_INT', i.e. the last bit is 1.
+    ##  This distuingishes immediate integers from other handles which  point  to
+    ##  structures aligned on 4 byte boundaries and therefor have last bit  zero.
+    ##  (The second bit is reserved as tag to allow extensions of  this  scheme.)
+    ##  Using immediates as pointers and dereferencing them gives address errors.
+    nom = nlGetNom(n, _ring)
+    mpz_init(nom_z)
+
+    if (SR_HDL(nom) & SR_INT): mpz_set_si(nom_z, SR_TO_INT(nom))
+    else: mpz_set(nom_z,&nom.z)
+
+    mpq_set_num(_z,nom_z)
+    nlDelete(&nom,_ring)
+    mpz_clear(nom_z)
+
+    denom = nlGetDenom(n, _ring)
+    mpz_init(denom_z)
+
+    if (SR_HDL(denom) & SR_INT): mpz_set_si(denom_z, SR_TO_INT(denom))
+    else: mpz_set(denom_z,&denom.z)
+
+    mpq_set_den(_z, denom_z)
+    nlDelete(&denom,_ring)
+    mpz_clear(denom_z)
+
+    z = Rational()
+    z.set_from_mpq(_z)
+    mpq_clear(_z)
+    return z
+
+cdef Integer si2sa_ZZ(number *n, ring *_ring):
     """
-    A work around class to export the contained methods/functions
+    TESTS::
+    
+        sage: P.<x,y,z> = ZZ[]
+        sage: P(3).lc()
+        3
+        sage: P(0).lc()
+        0
+        sage: P(-3).lc()
+        -3
+        sage: P(-1234567890).lc()
+        -1234567890
+        sage: type(P(3).lc())
+        <type 'sage.rings.integer.Integer'>
     """
+    cdef Integer z
+    z = Integer()
+    z.set_from_mpz(<__mpz_struct*>n)
+    return z
 
-    cdef public Rational si2sa_QQ(self, number *n, ring *_ring):
-        """
-        Converts a SINGULAR rational number to a SAGE rational number.
+cdef FiniteField_givaroElement si2sa_GFqGivaro(number *n, ring *_ring, FiniteField_givaro base):
+    """
+    TESTS::
 
-        INPUT:
-            n -- number
-            _ring -- singular ring, used to check type of n
+        sage: K.<a> = GF(5^3)
+        sage: R.<x,y,z> = PolynomialRing(K)
+        sage: K( (4*R(a)^2 + R(a))^3 )
+        a^2
+        sage: K(R(0))
+        0
+    """
+    cdef napoly *z
+    cdef int c, e
+    cdef int a
+    cdef int ret
+    cdef int order
 
-        OUTPUT:
-            SAGE rational number matching n
-        """
-        cdef number *nom
-        cdef number *denom
-        cdef mpq_t _z
+    if naIsZero(n):
+        return base._zero_element
+    elif naIsOne(n):
+        return base._one_element
+    z = (<lnumber*>n).z
 
-        cdef mpz_t nom_z, denom_z
+    a = base.objectptr.sage_generator()
+    ret = base.objectptr.zero
+    order = base.objectptr.cardinality() - 1
 
-        cdef Rational z
+    while z:
+        c = base.objectptr.initi(c,<long>napGetCoeff(z))
+        e = napGetExp(z,1)
+        if e == 0:
+            ret = base.objectptr.add(ret, c, ret)
+        else:
+            a = ( e * base.objectptr.sage_generator() ) % order
+            ret = base.objectptr.axpy(ret, c, a, ret)
+        z = napIter(z)
+    return (<FiniteField_givaroElement>base._zero_element)._new_c(ret)
 
-        mpq_init(_z)
+cdef FiniteField_ntl_gf2eElement si2sa_GFqNTLGF2E(number *n, ring *_ring, FiniteField_ntl_gf2e base):
+    """
+    TESTS::
 
-        ##  Immediate integers handles carry the tag 'SR_INT', i.e. the last bit is 1.
-        ##  This distuingishes immediate integers from other handles which  point  to
-        ##  structures aligned on 4 byte boundaries and therefor have last bit  zero.
-        ##  (The second bit is reserved as tag to allow extensions of  this  scheme.)
-        ##  Using immediates as pointers and dereferencing them gives address errors.
-        nom = nlGetNom(n, _ring)
-        mpz_init(nom_z)
+        sage: K.<a> = GF(2^20)
+        sage: P.<x,y,z> = K[]
+        sage: f = a^21*x^2 + 1 # indirect doctest
+        sage: f.lc()
+        a^11 + a^10 + a^8 + a^7 + a^6 + a^5 + a^2 + a
+        sage: type(f.lc())
+        <type 'sage.rings.finite_field_ntl_gf2e.FiniteField_ntl_gf2eElement'>
+    """
+    cdef napoly *z
+    cdef int c, e
+    cdef FiniteField_ntl_gf2eElement a
+    cdef FiniteField_ntl_gf2eElement ret
 
-        if (SR_HDL(nom) & SR_INT): mpz_set_si(nom_z, SR_TO_INT(nom))
-        else: mpz_set(nom_z,&nom.z)
+    if naIsZero(n):
+        return base._zero_element
+    elif naIsOne(n):
+        return base._one_element
+    z = (<lnumber*>n).z
 
-        mpq_set_num(_z,nom_z)
-        nlDelete(&nom,_ring)
-        mpz_clear(nom_z)
+    a = base.gen()
+    ret = base._zero_element
 
-        denom = nlGetDenom(n, _ring)
-        mpz_init(denom_z)
+    while z:
+        c = <long>napGetCoeff(z)
+        e = napGetExp(z,1)
+        ret += c * a**e
+        z = napIter(z)
+    return ret
 
-        if (SR_HDL(denom) & SR_INT): mpz_set_si(denom_z, SR_TO_INT(denom))
-        else: mpz_set(denom_z,&denom.z)
+cdef object si2sa_GFqPari(number *n, ring *_ring, object base):
+    """
+    TESTS::
+    
+        sage: K.<a> = GF(3^16)
+        sage: P.<x,y,z> = K[]
+        sage: f = a^21*x^2 + 1 # indirect doctest
+        sage: f.lc()
+        a^12 + a^11 + a^9 + a^8 + a^7 + 2*a^6 + a^5
+        sage: type(f.lc())
+        <class 'sage.rings.finite_field_element.FiniteField_ext_pariElement'>
+    """
+    cdef napoly *z
+    cdef int c, e
+    cdef object a
+    cdef object ret
 
-        mpq_set_den(_z, denom_z)
-        nlDelete(&denom,_ring)
-        mpz_clear(denom_z)
+    if naIsZero(n):
+        return base._zero_element
+    elif naIsOne(n):
+        return base._one_element
+    z = (<lnumber*>n).z
 
-        z = Rational()
-        z.set_from_mpq(_z)
-        mpq_clear(_z)
-        return z
+    a = pari("a")
+    ret = pari(int(0)).Mod(int(_ring.ch))
 
+    while z:
+        c = <long>napGetCoeff(z)
+        e = napGetExp(z,1)
+        if e == 0:
+            ret = ret + c
+        elif c != 0:
+            ret = ret  + c * a**e 
+        z = napIter(z)
+    return base(ret)
 
-    cdef public Integer si2sa_ZZ(self, number *n, ring *_ring):
-        r"""
-        Converts a \SINGULAR integer to a \SAGE integer number.
+cdef object si2sa_NF(number *n, ring *_ring, object base):
+    """
+    TESTS::
 
-        INPUT:
-            n -- number
-            _ring -- singular ring, used to check type of n
+        sage: K.<a> = NumberField(x^2 - 2)
+        sage: P.<x,y,z> = K[]
+        sage: f = a^21*x^2 + 1 # indirect doctest
+        sage: f.lc()
+        1024*a
+        sage: type(f.lc())
+        <type 'sage.rings.number_field.number_field_element_quadratic.NumberFieldElement_quadratic'>
+    """
+    cdef napoly *z
+    cdef number *c
+    cdef int e
+    cdef object a
+    cdef object ret
 
-        OUTPUT:
-            SAGE integer matching n
-        """
-        cdef number *nom
-        cdef number *denom
-        cdef mpz_t _z, _denom
-        cdef Integer z
+    if naIsZero(n):
+        return base._zero_element
+    elif naIsOne(n):
+        return base._one_element
+    z = (<lnumber*>n).z
 
-        ##  Immediate integers handles carry the tag 'SR_INT', i.e. the last bit is 1.
-        ##  This distuingishes immediate integers from other handles which  point  to
-        ##  structures aligned on 4 byte boundaries and therefor have last bit  zero.
-        ##  (The second bit is reserved as tag to allow extensions of  this  scheme.)
-        ##  Using immediates as pointers and dereferencing them gives address errors.
-        nom = nlGetNom(n, _ring)
-        mpz_init(_z)
+    a = base.gen()
+    ret = base(0)
 
-        if (SR_HDL(nom) & SR_INT):
-            mpz_set_si(_z, SR_TO_INT(nom))
-        else: 
-            mpz_set(_z,&nom.z)
+    while z:
+        c = napGetCoeff(z)
+        coeff = si2sa_QQ(c, _ring)
+        e = napGetExp(z,1)
+        if e == 0:
+            ret = ret + coeff
+        elif coeff != 0:
+            ret = ret  + coeff * a**e 
+        z = napIter(z)
+    return base(ret)
 
-        nlDelete(&nom,_ring)
+cdef inline object si2sa_ZZmod(number *n, ring *_ring, object base):
+    """
+    TESTS::
 
-        denom = nlGetDenom(n, _ring)
+        sage: P.<x,y,z> = Integers(10)[]
+        sage: P(3).lc()
+        3
+        sage: P(13).lc()
+        3
 
-        mpz_init(_denom)
+        sage: P.<x,y,z> = Integers(16)[]
+        sage: P(3).lc()
+        3
+        sage: P(19).lc()
+        3
 
-        if (SR_HDL(denom) & SR_INT):
-            mpz_set_si(_denom, SR_TO_INT(denom))
-        else: 
-            mpz_set(_denom,&denom.z)
-            
-        mpz_fdiv_q(_z, _z, _denom)
+        sage: P.<x,y,z> = Integers(3**2)[]
+        sage: P(3).lc()
+        3
+        sage: P(12).lc()
+        3
 
-        mpz_clear(_denom)
-        nlDelete(&denom,_ring)
+        sage: P.<x,y,z> = Integers(2^32)[]
+        sage: P(2^32-1).lc()
+        4294967295
 
-        z = Integer()
-        z.set_from_mpz(_z)
-        mpz_clear(_z)
-        return z
+        sage: P(3).lc()
+        3        
 
-    cdef public FiniteField_givaroElement si2sa_GFqGivaro(self, number *n, ring *_ring, FiniteField_givaro base):
-        """
-        Convert a SINGULAR finite extension field element to a SAGE
-        finite extension field element in a field with order
-        $<2^{16}$.
+        sage: P.<x,y,z> = Integers(17^20)[]
+        sage: P(17^19 + 3).lc()
+        239072435685151324847156
 
-        INPUT:
-            n -- SINGULAR representation
-            _ring -- SINGULAR ring
-            base -- SAGE GF(q)
-
-        OUTPUT:
-            An Element in GF(q).
-
-        EXAMPLE:
-            sage: K.<a> = GF(5^3)
-            sage: R.<x,y,z> = PolynomialRing(K)
-            sage: K( (4*R(a)^2 + R(a))^3 )
-            a^2
-        """
-        cdef napoly *z
-        cdef int c, e
-        cdef int a
-        cdef int ret
-        cdef int order
-
-        if naIsZero(n):
-            return base._zero_element
-        elif naIsOne(n):
-            return base._one_element
-        z = (<lnumber*>n).z
-
-        a = base.objectptr.sage_generator()
-        ret = base.objectptr.zero
-        order = base.objectptr.cardinality() - 1
-        
-        while z:
-            c = base.objectptr.initi(c,<long>napGetCoeff(z))
-            e = napGetExp(z,1)
-            if e == 0:
-                ret = base.objectptr.add(ret, c, ret)
-            else:
-                a = ( e * base.objectptr.sage_generator() ) % order
-                ret = base.objectptr.axpy(ret, c, a, ret)
-            z = napIter(z)
-        return (<FiniteField_givaroElement>base._zero_element)._new_c(ret)
-
-    cdef public FiniteField_ntl_gf2eElement si2sa_GFqNTLGF2E(self, number *n, ring *_ring, FiniteField_ntl_gf2e base):
-        """
-        Convert a SINGULAR finite extension field element to a SAGE
-        finite extension field element implemented via NTL's GF2E
-
-        INPUT:
-            n -- SINGULAR representation
-            _ring -- SINGULAR ring
-            base -- SAGE GF(q)
-
-        OUTPUT:
-            An Element in GF(q).
-        
-        """
-        cdef napoly *z
-        cdef int c, e
-        cdef FiniteField_ntl_gf2eElement a
-        cdef FiniteField_ntl_gf2eElement ret
-
-        if naIsZero(n):
-            return base._zero_element
-        elif naIsOne(n):
-            return base._one_element
-        z = (<lnumber*>n).z
-
-        a = base.gen()
-        ret = base._zero_element
-
-        while z:
-            c = <long>napGetCoeff(z)
-            e = napGetExp(z,1)
-            ret += c * a**e
-            z = napIter(z)
-        return ret
-            
-    cdef public object si2sa_GFqPari(self, number *n, ring *_ring, object base):
-        """
-        Convert a SINGULAR finite extension field element to a SAGE
-        finite extension field element in a field.
-
-        INPUT:
-            n -- SINGULAR representation
-            _ring -- SINGULAR ring
-            base -- SAGE GF(q)
-
-        OUTPUT:
-            An Element in GF(q).
-        """
-        cdef napoly *z
-        cdef int c, e
-        cdef object a
-        cdef object ret
-
-        if naIsZero(n):
-            return base._zero_element
-        elif naIsOne(n):
-            return base._one_element
-        z = (<lnumber*>n).z
-
-        a = pari("a")
-        ret = pari(int(0)).Mod(int(_ring.ch))
-
-        while z:
-            c = <long>napGetCoeff(z)
-            e = napGetExp(z,1)
-            if e == 0:
-                ret = ret + c
-            elif c != 0:
-                ret = ret  + c * a**e 
-            z = napIter(z)
+        sage: P(3)
+        3        
+    """
+    cdef Integer ret
+    if _ring.ringtype == 1:
+        return base(<long>n)
+    else:
+        ret = Integer()
+        ret.set_from_mpz(<__mpz_struct*>n)
         return base(ret)
 
-    cdef public object si2sa_NF(self, number *n, ring *_ring, object base):
-        """
-        Convert a SINGULAR number field element to a SAGE absolute
-        number field element.
+    return base(_ring.cf.nInt(n))
 
-        INPUT:
-            n -- SINGULAR representation
-            _ring -- SINGULAR ring
-            base -- SAGE QQ(a)
+cdef number *sa2si_QQ(Rational r, ring *_ring):
+    """
+    TESTS::
 
-        OUTPUT:
-            An Element in QQ(a).
-        """
-        cdef napoly *z
-        cdef number *c
-        cdef int e
-        cdef object a
-        cdef object ret
+        sage: P.<x,y,z> = QQ[]
+        sage: P(0) + 1/2 - 2/4
+        0
+        sage: P(1/2) + 3/5 - 3/5
+        1/2
+        sage: P(2/3) + 1/4 - 1/4
+        2/3
+        sage: P(12345678901234567890/23) + 5/2 - 5/2
+        12345678901234567890/23
+    """
+    return nlInit2gmp( mpq_numref(r.value), mpq_denref(r.value) )
 
-        if naIsZero(n):
-            return base._zero_element
-        elif naIsOne(n):
-            return base._one_element
-        z = (<lnumber*>n).z
+cdef number *sa2si_GFqGivaro(int quo, ring *_ring):
+    """
+    """
+    cdef number *n1, *n2, *a, *coeff, *apow1, *apow2
+    cdef int b
 
-        a = base.gen()
-        ret = base(0)
+    rChangeCurrRing(_ring)
+    b   = - _ring.ch;
 
-        while z:
-            c = napGetCoeff(z)
-            coeff = self.si2sa_QQ(c, _ring)
-            e = napGetExp(z,1)
-            if e == 0:
-                ret = ret + coeff
-            elif coeff != 0:
-                ret = ret  + coeff * a**e 
-            z = napIter(z)
-        return base(ret)
+    a = naPar(1)
 
-    cdef public number *sa2si_QQ(self, Rational r, ring *_ring):
-        """
-        Convert a SAGE rational number to a SINGULAR rational number.
+    apow1 = naInit(1)
+    n1 = naInit(0)
 
-        INPUT:
-            r -- SAGE notation
-            _ring -- SINGULAR ring (ignored)
-        """
-        return nlInit2gmp( mpq_numref(r.value), mpq_denref(r.value) )
+    while quo!=0:
+        coeff = naInit(quo%b)
 
-    cdef number *sa2si_GFqGivaro(self, int quo, ring *_ring):
-        """
-        Convert a SAGE GF(q) element to a SINGULAR GF(q) element.
+        if not naIsZero(coeff):
+            n2 = naAdd( naMult(coeff, apow1),  n1)
+            naDelete(&n1, _ring);
+            n1= n2
 
-        INPUT:
-            quo -- int representing the finite field element
-            _ring -- SINGULAR ring
-        """
-        cdef number *n1, *n2, *a, *coeff, *apow1, *apow2
-        cdef int b
-        
-        rChangeCurrRing(_ring)
-        b   = - _ring.ch;
-        
+        apow2 = naMult(apow1, a)
+        naDelete(&apow1, _ring)
+        apow1 = apow2
+
+        quo = quo/b
+        naDelete(&coeff, _ring)
+
+    naDelete(&apow1, _ring)
+    naDelete(&a, _ring)
+    return n1
+
+cdef number *sa2si_GFqNTLGF2E(FiniteField_ntl_gf2eElement elem, ring *_ring):
+    """
+    """
+    cdef int i
+    cdef number *n1, *n2, *a, *coeff, *apow1, *apow2
+
+    rChangeCurrRing(_ring)
+
+    cdef GF2X_c rep = GF2E_rep(elem.x)
+
+    if GF2X_deg(rep) >= 1:
+        n1 = naInit(0)
         a = naPar(1)
+        apow1 = naInit(1)
 
-        apow1 = naInit(1)
-        n1 = naInit(0)
-        
-        while quo!=0:
-            coeff = naInit(quo%b)
-            
+        for i from 0 <= i <= GF2X_deg(rep):
+            coeff = naInit(GF2_conv_to_long(GF2X_coeff(rep,i)))
+
             if not naIsZero(coeff):
                 n2 = naAdd( naMult(coeff, apow1),  n1)
                 naDelete(&n1, _ring);
@@ -335,193 +373,207 @@
             apow2 = naMult(apow1, a)
             naDelete(&apow1, _ring)
             apow1 = apow2
-            
-            quo = quo/b
+
             naDelete(&coeff, _ring)
-            
+
         naDelete(&apow1, _ring)
         naDelete(&a, _ring)
-        return n1
+    else:
+       n1 = naInit(GF2_conv_to_long(GF2X_coeff(rep,0)))
 
-    cdef number *sa2si_GFqNTLGF2E(self, FiniteField_ntl_gf2eElement elem, ring *_ring):
-        """
-        """
-        cdef int i
-        cdef number *n1, *n2, *a, *coeff, *apow1, *apow2
-        
-        rChangeCurrRing(_ring)
+    return n1
 
-        cdef GF2X_c rep = GF2E_rep(elem.x)
+cdef number *sa2si_GFqPari(object elem, ring *_ring):
+    """
+    """
+    cdef int i
+    cdef number *n1, *n2, *a, *coeff, *apow1, *apow2
 
-        if GF2X_deg(rep) >= 1:
-            n1 = naInit(0)
-            a = naPar(1)
-            apow1 = naInit(1)
+    rChangeCurrRing(_ring)
 
-            for i from 0 <= i <= GF2X_deg(rep):
-                coeff = naInit(GF2_conv_to_long(GF2X_coeff(rep,i)))
+    elem = elem._pari_().lift().lift()
 
-                if not naIsZero(coeff):
-                    n2 = naAdd( naMult(coeff, apow1),  n1)
-                    naDelete(&n1, _ring);
-                    n1= n2
 
-                apow2 = naMult(apow1, a)
-                naDelete(&apow1, _ring)
-                apow1 = apow2
+    if len(elem) > 1:
+        n1 = naInit(0)
+        a = naPar(1)
+        apow1 = naInit(1)
 
-                naDelete(&coeff, _ring)
+        for i from 0 <= i < len(elem):
+            coeff = naInit(int(elem[i]))
 
+            if not naIsZero(coeff):
+                n2 = naAdd( naMult(coeff, apow1),  n1)
+                naDelete(&n1, _ring);
+                n1= n2
+
+            apow2 = naMult(apow1, a)
             naDelete(&apow1, _ring)
-            naDelete(&a, _ring)
-        else:
-           n1 = naInit(GF2_conv_to_long(GF2X_coeff(rep,0)))
-            
-        return n1
+            apow1 = apow2
 
-    cdef number *sa2si_GFqPari(self, object elem, ring *_ring):
-        """
-        """
-        cdef int i
-        cdef number *n1, *n2, *a, *coeff, *apow1, *apow2
-        
-        rChangeCurrRing(_ring)
+            naDelete(&coeff, _ring)
 
-        elem = elem._pari_().lift().lift()
-        
+        naDelete(&apow1, _ring)
+        naDelete(&a, _ring)
+    else:
+        n1 = naInit(int(elem))
 
-        if len(elem) > 1:
-            n1 = naInit(0)
-            a = naPar(1)
-            apow1 = naInit(1)
+    return n1
 
-            for i from 0 <= i < len(elem):
-                coeff = naInit(int(elem[i]))
+cdef number *sa2si_NF(object elem, ring *_ring):
+    """
+    """
+    cdef int i
+    cdef number *n1, *n2, *a, *nlCoeff, *naCoeff, *apow1, *apow2
 
-                if not naIsZero(coeff):
-                    n2 = naAdd( naMult(coeff, apow1),  n1)
-                    naDelete(&n1, _ring);
-                    n1= n2
+    rChangeCurrRing(_ring)
 
-                apow2 = naMult(apow1, a)
-                naDelete(&apow1, _ring)
-                apow1 = apow2
+    elem = list(elem)
 
-                naDelete(&coeff, _ring)
+    if len(elem) > 1:
+        n1 = naInit(0)
+        a = naPar(1)
+        apow1 = naInit(1)
 
+        for i from 0 <= i < len(elem):
+            nlCoeff = nlInit2gmp( mpq_numref((<Rational>elem[i]).value), mpq_denref((<Rational>elem[i]).value) )
+            naCoeff = naMap00(nlCoeff)
+            nlDelete(&nlCoeff, _ring)
+
+            # faster would be to assign the coefficient directly
+            n2 = naAdd( naMult(naCoeff, apow1),  n1)
+            naDelete(&n1, _ring);
+            naDelete(&naCoeff, _ring)
+            n1 = n2
+
+            apow2 = naMult(apow1, a)
             naDelete(&apow1, _ring)
-            naDelete(&a, _ring)
-        else:
-            n1 = naInit(int(elem))
-            
-        return n1
+            apow1 = apow2
 
-    cdef number *sa2si_NF(self, object elem, ring *_ring):
-        """
-        """
-        cdef int i
-        cdef number *n1, *n2, *a, *nlCoeff, *naCoeff, *apow1, *apow2
-        
-        rChangeCurrRing(_ring)
+        naDelete(&apow1, _ring)
+        naDelete(&a, _ring)
+    else:
+        n1 = sa2si_QQ(elem[0], _ring)
 
-        elem = list(elem)
-        
-        if len(elem) > 1:
-            n1 = naInit(0)
-            a = naPar(1)
-            apow1 = naInit(1)
+    return n1
 
-            for i from 0 <= i < len(elem):
-                nlCoeff = nlInit2gmp( mpq_numref((<Rational>elem[i]).value), mpq_denref((<Rational>elem[i]).value) )
-                naCoeff = naMap00(nlCoeff)
-                nlDelete(&nlCoeff, _ring)
-                
-                # faster would be to assign the coefficient directly
-                n2 = naAdd( naMult(naCoeff, apow1),  n1)
-                naDelete(&n1, _ring);
-                naDelete(&naCoeff, _ring)
-                n1 = n2
-                
-                apow2 = naMult(apow1, a)
-                naDelete(&apow1, _ring)
-                apow1 = apow2
+cdef number *sa2si_ZZ(Integer d, ring *_ring):
+    """
+    TESTS::
 
-            naDelete(&apow1, _ring)
-            naDelete(&a, _ring)
-        else:
-            n1 = self.sa2si_QQ(elem[0], _ring)
-            
-        return n1
+        sage: P.<x,y,z> = ZZ[]
+        sage: P(0) + 1 - 1
+        0
+        sage: P(1) + 1 - 1
+        1
+        sage: P(2) + 1 - 1
+        2
+        sage: P(12345678901234567890) + 2 - 2
+        12345678901234567890
+    """
+    cdef number *n = nrzInit(0)
+    mpz_set(<__mpz_struct*>n, d.value)
+    return <number*>n
 
-    cdef public number *sa2si_ZZ(self, Integer d, ring *_ring):
-        """
-        """
-        cdef number *n
-        if INT_MIN <= d <= INT_MAX:
-            return nlInit(int(d))
-        else:
-            n = nlRInit(0)
-            mpz_init_set(&n.z, d.value)
-            return n
+cdef inline number *sa2si_ZZmod(IntegerMod_abstract d, ring *_ring):
+    """
+    TESTS::
 
-    cdef public object si2sa(self, number *n, ring *_ring, object base):
-        if PY_TYPE_CHECK(base, FiniteField_prime_modn):
+        sage: P.<x,y,z> = Integers(10)[]
+        sage: P(3)
+        3
+        sage: P(13)
+        3
+
+        sage: P.<x,y,z> = Integers(16)[]
+        sage: P(3)
+        3
+        sage: P(19)
+        3
+
+        sage: P.<x,y,z> = Integers(3^2)[]
+        sage: P(3)
+        3
+        sage: P(12)
+        3
+
+        sage: P.<x,y,z> = Integers(2^32)[]
+        sage: P(2^32-1)
+        -1
+
+        sage: P(3)
+        3        
+
+        sage: P.<x,y,z> = Integers(17^20)[]
+        sage: P(17^19 + 3)
+        239072435685151324847156
+
+        sage: P(3)
+        3        
+
+    """
+    cdef long _d
+    if _ring.ringtype == 1:
+        _d = long(d)
+        return nr2mMapZp(<number *>_d)
+    else:
+        return nrnMapGMP(<number *>(<Integer>Integer(d)).value)
+
+cdef object si2sa(number *n, ring *_ring, object base):
+    if PY_TYPE_CHECK(base, FiniteField_prime_modn):
+        return base(nInt(n))
+
+    elif PY_TYPE_CHECK(base, RationalField):
+        return si2sa_QQ(n,_ring)
+
+    elif PY_TYPE_CHECK(base, IntegerRing_class):
+        return si2sa_ZZ(n,_ring)
+
+    elif PY_TYPE_CHECK(base, FiniteField_givaro):
+        return si2sa_GFqGivaro(n, _ring, base)
+
+    elif PY_TYPE_CHECK(base, FiniteField_ext_pari):
+        return si2sa_GFqPari(n, _ring, base)
+
+    elif PY_TYPE_CHECK(base, FiniteField_ntl_gf2e):
+        return si2sa_GFqNTLGF2E(n, _ring, base)
+
+    elif PY_TYPE_CHECK(base, NumberField) and base.is_absolute():
+        return si2sa_NF(n, _ring, base)
+
+    elif PY_TYPE_CHECK(base, IntegerModRing_generic):
+        if _ring.ringtype == 0:
             return base(nInt(n))
-            
-        elif PY_TYPE_CHECK(base, RationalField):
-            return self.si2sa_QQ(n,_ring)
+        return si2sa_ZZmod(n, _ring, base)
 
-        elif PY_TYPE_CHECK(base, IntegerRing_class):
-            return self.si2sa_ZZ(n,_ring)
+    else:
+        raise ValueError, "cannot convert from SINGULAR number"
 
-        elif PY_TYPE_CHECK(base, FiniteField_givaro):
-            return self.si2sa_GFqGivaro(n, _ring, base)
+cdef number *sa2si(Element elem, ring * _ring):
+    cdef int i
+    if PY_TYPE_CHECK(elem._parent, FiniteField_prime_modn):
+        return n_Init(int(elem),_ring)
 
-        elif PY_TYPE_CHECK(base, FiniteField_ext_pari):
-            return self.si2sa_GFqPari(n, _ring, base)
+    elif PY_TYPE_CHECK(elem._parent, RationalField):
+        return sa2si_QQ(elem, _ring)
 
-        elif PY_TYPE_CHECK(base, FiniteField_ntl_gf2e):
-            return self.si2sa_GFqNTLGF2E(n, _ring, base)
+    elif PY_TYPE_CHECK(elem._parent, IntegerRing_class):
+        return sa2si_ZZ(elem, _ring)
 
-        elif PY_TYPE_CHECK(base, NumberField) and base.is_absolute():
-            return self.si2sa_NF(n, _ring, base)
+    elif PY_TYPE_CHECK(elem._parent, FiniteField_givaro):
+        return sa2si_GFqGivaro( (<FiniteField_givaro>elem._parent).objectptr.convert(i, (<FiniteField_givaroElement>elem).element ), _ring )
 
-        else:
-            raise ValueError, "cannot convert from SINGULAR number"
+    elif PY_TYPE_CHECK(elem._parent, FiniteField_ext_pari):
+        return sa2si_GFqPari(elem, _ring)
 
-    cdef public number *sa2si(self, Element elem, ring * _ring):
-        cdef int i
-        if PY_TYPE_CHECK(elem._parent, FiniteField_prime_modn):
+    elif PY_TYPE_CHECK(elem._parent, FiniteField_ntl_gf2e):
+        return sa2si_GFqNTLGF2E(elem, _ring)
+
+    elif PY_TYPE_CHECK(elem._parent, NumberField) and elem._parent.is_absolute():
+        return sa2si_NF(elem, _ring)
+    elif PY_TYPE_CHECK(elem._parent, IntegerModRing_generic):
+        if _ring.ringtype == 0:
             return n_Init(int(elem),_ring)
-            
-        elif PY_TYPE_CHECK(elem._parent, RationalField):
-            return self.sa2si_QQ(elem, _ring)
-
-        elif PY_TYPE_CHECK(elem._parent, IntegerRing_class):
-            return self.sa2si_ZZ(elem, _ring)
-
-        elif PY_TYPE_CHECK(elem._parent, FiniteField_givaro):
-            return self.sa2si_GFqGivaro( (<FiniteField_givaro>elem._parent).objectptr.convert(i, (<FiniteField_givaroElement>elem).element ), _ring )
-
-        elif PY_TYPE_CHECK(elem._parent, FiniteField_ext_pari):
-            return self.sa2si_GFqPari(elem, _ring)
-
-        elif PY_TYPE_CHECK(elem._parent, FiniteField_ntl_gf2e):
-            return self.sa2si_GFqNTLGF2E(elem, _ring)
-
-        elif PY_TYPE_CHECK(elem._parent, NumberField) and elem._parent.is_absolute():
-            return self.sa2si_NF(elem, _ring)
-        else:
-            raise ValueError, "cannot convert to SINGULAR number"
-
-    cdef public  MPolynomial_libsingular new_MP(self, MPolynomialRing_libsingular parent, poly *juice):
-        """
-        Construct MPolynomial_libsingular from parent and SINGULAR poly.
-        """
-        cdef MPolynomial_libsingular p
-        p = PY_NEW(MPolynomial_libsingular)
-        p._parent = <ParentWithBase>parent
-        p._poly = juice
-        p_Normalize(p._poly, parent._ring)
-        return p
-
+        return sa2si_ZZmod(elem, _ring)
+    else:
+        raise ValueError, "cannot convert to SINGULAR number"
diff -r 6c7354ace3b6 -r 8037fada5b30 sage/matrix/matrix_mpolynomial_dense.pyx
--- a/sage/matrix/matrix_mpolynomial_dense.pyx	Sat Jun 06 09:55:28 2009 -0700
+++ b/sage/matrix/matrix_mpolynomial_dense.pyx	Wed Jun 10 21:47:44 2009 -0700
@@ -29,10 +29,7 @@
 include "../ext/interrupt.pxi"
 include "../ext/cdefs.pxi"
 
-from sage.libs.singular.singular cimport Conversion
-
-cdef Conversion co
-co = Conversion()
+from sage.rings.polynomial.multi_polynomial_libsingular cimport new_MP
 
 from sage.matrix.matrix_generic_dense cimport Matrix_generic_dense
 from sage.matrix.matrix2 cimport Matrix
@@ -203,7 +200,7 @@
         # we are transposing here also
         for r from 0 <= r < IDELEMS(m):
             for c from 0 <= c < m.rank:
-                p = co.new_MP(R, pTakeOutComp1(&m.m[r], c+1))
+                p = new_MP(R, pTakeOutComp1(&m.m[r], c+1))
                 self.set_unsafe(r,c,p)
             for c from m.rank <= c < self._ncols:
                 self.set_unsafe(r,c,R._zero_element)
@@ -543,7 +540,7 @@
                 p = singclap_det(m)
                 _sig_off
                 id_Delete(<ideal**>&m, _ring)
-            d = co.new_MP(R, p)
+            d = new_MP(R, p)
 
         elif can_convert_to_singular(self.base_ring()):
             d = R(self._singular_().det())
diff -r 6c7354ace3b6 -r 8037fada5b30 sage/misc/method_decorator.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sage/misc/method_decorator.py	Wed Jun 10 21:47:44 2009 -0700
@@ -0,0 +1,83 @@
+"""
+Base Class to Support Method Decorators
+
+AUTHOR:
+
+- Martin Albrecht (2009-05): inspired by a conversation with and code by Mike Hansen
+"""
+
+from sage.structure.sage_object import SageObject
+
+class MethodDecorator(SageObject):
+    def __init__(self, f):
+        """
+        EXAMPLE::
+            sage: from sage.misc.method_decorator import MethodDecorator
+            sage: class Foo:
+            ...       @MethodDecorator
+            ...       def bar(self, x):
+            ...          return x**2
+            ...
+            sage: J = Foo()
+            sage: J.bar
+            <class 'sage.misc.method_decorator.MethodDecorator'>
+        """
+        self.f = f
+        if hasattr(f, "func_doc"):
+            self.__doc__ = f.func_doc
+        else:
+            self.__doc__ = f.__doc__
+        if hasattr(f, "func_name"):
+            self.__name__ = f.func_name
+        self.__module__ = f.__module__
+
+    def _sage_src_(self):
+        """
+        Returns the source code for the wrapped function.
+
+        EXAMPLE:
+
+        This class is rather abstract so we showcase its features
+        using one of its subclasses::
+
+            sage: P.<x,y,z> = PolynomialRing(ZZ)
+            sage: I = ideal( x^2 - 3*y, y^3 - x*y, z^3 - x, x^4 - y*z + 1 )
+            sage: "primary" in I.primary_decomposition._sage_src_() # indirect doctest
+            True
+        """
+        from sage.misc.sageinspect import sage_getsource
+        return sage_getsource(self.f)
+
+    def __call__(self, *args, **kwds):
+        """
+        EXAMPLE:
+
+        This class is rather abstract so we showcase its features
+        using one of its subclasses::
+
+            sage: P.<x,y,z> = PolynomialRing(Zmod(126))
+            sage: I = ideal( x^2 - 3*y, y^3 - x*y, z^3 - x, x^4 - y*z + 1 )
+            sage: I.primary_decomposition() # indirect doctest
+            Traceback (most recent call last):
+            ...
+            ValueError: Coefficient ring must be a field for function 'primary_decomposition'.
+        """
+        return self.f(self._instance, *args, **kwds)
+
+    def __get__(self, inst, cls=None):
+        """
+        EXAMPLE:
+
+        This class is rather abstract so we showcase its features
+        using one of its subclasses::
+
+            sage: P.<x,y,z> = PolynomialRing(Zmod(126))
+            sage: I = ideal( x^2 - 3*y, y^3 - x*y, z^3 - x, x^4 - y*z + 1 )
+            sage: I.primary_decomposition() # indirect doctest
+            Traceback (most recent call last):
+            ...
+            ValueError: Coefficient ring must be a field for function 'primary_decomposition'.
+        """
+        self._instance = inst
+        return self
+    
diff -r 6c7354ace3b6 -r 8037fada5b30 sage/rings/integer_mod_ring.py
--- a/sage/rings/integer_mod_ring.py	Sat Jun 06 09:55:28 2009 -0700
+++ b/sage/rings/integer_mod_ring.py	Wed Jun 10 21:47:44 2009 -0700
@@ -322,6 +322,20 @@
             True
         """
         return True
+
+    def is_prime_field(self):
+        """
+        Return ``True`` if the order is prime.
+
+        EXAMPLES::
+
+            sage: Zmod(7).is_prime_field()
+            True
+            sage: Zmod(8).is_prime_field()
+            False
+        """
+        return self.__order.is_prime()
+
         
     def _precompute_table(self):
         self._pyx_order.precompute_table(self)
@@ -1031,6 +1045,18 @@
         return 'Integers(%s)'%self.order()
 
 
+    def degree(self):
+        """
+        Return 1.
+
+        EXAMPLE::
+            
+            sage: R = Integers(12345678900)
+            sage: R.degree()
+            1
+        """
+        return integer.Integer(1)
+
 Zmod = IntegerModRing
 Integers = IntegerModRing
 
diff -r 6c7354ace3b6 -r 8037fada5b30 sage/rings/polynomial/multi_polynomial_element.py
--- a/sage/rings/polynomial/multi_polynomial_element.py	Sat Jun 06 09:55:28 2009 -0700
+++ b/sage/rings/polynomial/multi_polynomial_element.py	Wed Jun 10 21:47:44 2009 -0700
@@ -1,5 +1,5 @@
 """
-Multivariate Polynomials
+Generic Multivariate Polynomials
 
 AUTHORS:
 
diff -r 6c7354ace3b6 -r 8037fada5b30 sage/rings/polynomial/multi_polynomial_ideal.py
--- a/sage/rings/polynomial/multi_polynomial_ideal.py	Sat Jun 06 09:55:28 2009 -0700
+++ b/sage/rings/polynomial/multi_polynomial_ideal.py	Wed Jun 10 21:47:44 2009 -0700
@@ -4,7 +4,7 @@
 
 Sage has a powerful system to compute with multivariate polynomial
 rings. Most algorithms dealing with these ideals are centered the
-computation of *Groebner bases*. Sage makes use of Singular to
+computation of *Groebner bases*. Sage mainly uses Singular to
 implement this functionality. Singular is widely regarded as the best
 open-source system for Groebner basis calculation in multivariate
 polynomial rings over fields.
@@ -19,13 +19,14 @@
 - Martin Albrecht (2008,2007): refactoring, many Singular related
   functions
 
+- Martin Albrecht (2009): added Groebner basis over rings
+  functionality from Singular 3.1
+
 EXAMPLES:
 
 We compute a Groebner basis for some given ideal. The type returned by
-the ``groebner_basis`` method is ``Sequence``, i.e. it is not an
-``MPolynomialIdeal``.
-
-::
+the ``groebner_basis`` method is ``Sequence``, i.e. it is not a
+:class:`MPolynomialIdeal`::
 
     sage: x,y,z = QQ['x,y,z'].gens()
     sage: I = ideal(x^5 + y^4 + z^3 - 1,  x^3 + y^3 + z^2 - 1)
@@ -33,9 +34,7 @@
     sage: type(B)
     <class 'sage.structure.sequence.Sequence'>
     
-Groebner bases can be used to solve the ideal membership problem.
-
-::
+Groebner bases can be used to solve the ideal membership problem::
 
     sage: f,g,h = B
     sage: (2*x*f + g).reduce(B)
@@ -50,10 +49,8 @@
     sage: (2*x*f + 2*z*h + y^3) in I
     False
     
-We compute a Groebner basis for cyclic 6, which is a standard
-benchmark and test ideal.
-
-::
+We compute a Groebner basis for Cyclic 6, which is a standard
+benchmark and test ideal.::
 
     sage: R.<x,y,z,t,u,v> = QQ['x,y,z,t,u,v']
     sage: I = sage.rings.ideal.Cyclic(R,6)
@@ -64,35 +61,54 @@
 We compute in a quotient of a polynomial ring over `\ZZ/17\ZZ`::
 
     sage: R.<x,y> = ZZ[]
-    sage: S.<a,b> = R.quotient((x^2 + y^2, 17))     # optional -- macaulay2
-    ...
-    verbose 0 ... Warning: falling back to very slow toy implementation.
-    sage: S                                         # optional -- macaulay2
+    sage: S.<a,b> = R.quotient((x^2 + y^2, 17))
+    sage: S
     Quotient of Multivariate Polynomial Ring in x, y over Integer Ring
     by the ideal (x^2 + y^2, 17)
 
-    sage: a^2 + b^2 == 0                            # optional -- macaulay2
+    sage: a^2 + b^2 == 0
     True
-    sage: a^3 - b^2                                 # optional -- macaulay2
-    a*b^2 - b^2
-    sage: (a+b)^17                                  # optional -- macaulay2
+    sage: a^3 - b^2
+    -a*b^2 - b^2
+
+Note that the result of a computation is not necessarily reduced::
+
+    sage: (a+b)^17
+    256*a*b^16 + 256*b^17
+    sage: S(17) == 0
+    True
+
+Or we can work with `\ZZ/17\ZZ`` directly:: 
+
+    sage: R.<x,y> = Zmod(17)[]
+    sage: S.<a,b> = R.quotient((x^2 + y^2,))
+    sage: S
+    Quotient of Multivariate Polynomial Ring in x, y over Ring of
+    integers modulo 17 by the ideal (x^2 + y^2)
+
+    sage: a^2 + b^2 == 0
+    True
+    sage: a^3 - b^2
+    -a*b^2 - b^2
+    sage: (a+b)^17
     a*b^16 + b^17
-    sage: S(17) == 0                                # optional -- macaulay2
+    sage: S(17) == 0
     True
 
+
 Working with a polynomial ring over `\ZZ`::
 
-    sage: R.<x,y,z,w> = ZZ['x,y,z,w']             
-    sage: i = ideal(x^2 + y^2 - z^2 - w^2, x-y)
-    sage: j = i^2
-    sage: j.groebner_basis('macaulay2')          # optional - macaulay2
+    sage: R.<x,y,z,w> = ZZ[]
+    sage: I = ideal(x^2 + y^2 - z^2 - w^2, x-y)
+    sage: J = I^2
+    sage: J.groebner_basis()
     [4*y^4 - 4*y^2*z^2 + z^4 - 4*y^2*w^2 + 2*z^2*w^2 + w^4, 
      2*x*y^2 - 2*y^3 - x*z^2 + y*z^2 - x*w^2 + y*w^2, 
      x^2 - 2*x*y + y^2]
 
-    sage: y^2 - 2*x*y + x^2 in j                # optional - macaulay2
+    sage: y^2 - 2*x*y + x^2 in J
     True
-    sage: 0 in j                                # optional - macaulay2
+    sage: 0 in J
     True
 
 We do a Groebner basis computation over a number field::
@@ -132,18 +148,14 @@
         sage: ideal(x+y, x^2 - 1, y^2 - 2*x).groebner_basis()
         [1]
 
-The next example shows how we can use Groebner bases over
-`\ZZ` to find the primes modulo which a system of
-equations has a solution, when the system has no solutions over the
-rationals.
+The next example shows how we can use Groebner bases over `\ZZ` to
+find the primes modulo which a system of equations has a solution,
+when the system has no solutions over the rationals.
 
-    We first form a certain ideal `I` in
-    `\ZZ[x, y, z]`, and note that the Groebner basis of
-    `I` over `\QQ` contains 1, so there are no
-    solutions over `\QQ` or an algebraic closure of it
-    (this is not surprising as there are 4 equations in 3 unknowns).
-
-    ::
+    We first form a certain ideal `I` in `\ZZ[x, y, z]`, and note that
+    the Groebner basis of `I` over `\QQ` contains 1, so there are no
+    solutions over `\QQ` or an algebraic closure of it (this is not
+    surprising as there are 4 equations in 3 unknowns).::
 
         sage: P.<x,y,z> = PolynomialRing(ZZ,order='lex')
         sage: I = ideal(-y^2 - 3*y + z^2 + 3, -2*y*z + z^2 + 2*z + 1, \
@@ -152,21 +164,17 @@
         [1]
 
     However, when we compute the Groebner basis of I (defined over
-    $\ZZ$), we note that there is a certain integer in the ideal which
-    is not 1.
+    `\ZZ``), we note that there is a certain integer in the ideal
+    which is not 1.::
 
-    ::
+        sage: I.groebner_basis()
+        [-x - y - z, -y^2 - 3*y + z^2 + 3, -y*z + 14329*y + 6653454247350, 
+         2*y - 1199*z^3 + 74229*z^2 + 31017*z + 106019, -23*z^3 + 953554642851*z + 2034, 
+         19*z^2 + 5357048579, 2*z - 1339262138, 164878]
 
-        sage: I.groebner_basis()          # optional -- macaulay2
-        ...
-        verbose 0 ... Warning: falling back to very slow toy implementation.
-        [x + y + z, y^2 + y + 23234, y*z + y + 26532, 2*y + 158864, z^2 + 17223, 2*z + 41856, 164878]
-
-    Now for each prime `p` dividing this integer 164878, the
-    Groebner basis of I modulo `p` will be non-trivial and will thus
-    give a solution of the original system modulo `p`.
-
-    ::
+    Now for each prime `p` dividing this integer 164878, the Groebner
+    basis of I modulo `p` will be non-trivial and will thus give a
+    solution of the original system modulo `p`.::
 
     
         sage: factor(164878)
@@ -179,13 +187,10 @@
         sage: I.change_ring(P.change_ring( GF(11777 ))).groebner_basis()
         [x + 5633, y - 3007, z - 2626]
 
-    The Groebner basis modulo any product of the prime factors is also non-trivial.
+    The Groebner basis modulo any product of the prime factors is also non-trivial.::
 
-    ::
-
-        sage: I.change_ring(P.change_ring( IntegerModRing(2*7) )).groebner_basis()   # optional -- macaulay2
-        verbose 0 (...: multi_polynomial_ideal.py, groebner_basis) Warning: falling back to very slow toy implementation.
-        [x + y + z, y^2 + y + 8, y*z + y + 2, 2*y + 6, z^2 + 3, 2*z + 10]
+        sage: I.change_ring(P.change_ring( IntegerModRing(2*7) )).groebner_basis()
+        [x*y + 10, x*z + 13*y + 9, 7*x + 7*y + 7*z, y^2 + 3*y, y*z + y + 2, 2*y + 6, z^2 + 3, 2*z + 10]
 
     Modulo any other prime the Groebner basis is trivial so there are
     no other solutions. For example::
@@ -193,14 +198,12 @@
         sage: I.change_ring( P.change_ring( GF(3) ) ).groebner_basis()
         [1]
 
-
 TESTS::
 
     sage: x,y,z = QQ['x,y,z'].gens()
     sage: I = ideal(x^5 + y^4 + z^3 - 1,  x^3 + y^3 + z^2 - 1)
     sage: I == loads(dumps(I))
     True
-
 """
 
 #*****************************************************************************
@@ -208,7 +211,7 @@
 #                               Sage
 #
 #       Copyright (C) 2005 William Stein <wstein@gmail.com>
-#       Copyright (C) 2008 Martin Albrecht <malb@informatik.uni-bremen.de>
+#       Copyright (C) 2008,2009 Martin Albrecht <malb@informatik.uni-bremen.de>
 #
 #  Distributed under the terms of the GNU General Public License (GPL)
 #
@@ -234,6 +237,8 @@
 from sage.misc.cachefunc import cached_method
 from sage.misc.misc import prod, verbose
 from sage.misc.sage_eval import sage_eval
+from sage.misc.method_decorator import MethodDecorator
+
 
 from sage.rings.integer_ring import ZZ
 import sage.rings.polynomial.toy_buchberger as toy_buchberger
@@ -250,16 +255,13 @@
     - Martin Albrecht
     """
     def __init__(self, singular=singular_default):
-        r"""
-        Within this context all Singular Groebner basis calculations are
-        reduced automatically.
+        """
+        Within this context all Singular Groebner basis calculations
+        are reduced automatically.
         
         INPUT:
         
-        
-        -  ``singular`` - Singular instance (default: default
-           instance)
-        
+        -  ``singular`` - Singular instance (default: default instance)
         
         EXAMPLE::
         
@@ -284,13 +286,10 @@
             7*b+210*c^3-79*c^2+3*c,
             7*a-420*c^3+158*c^2+8*c-7
         
-        Note that both bases are Groebner bases because they have pairwise
-        prime leading monomials but that the monic version of the last
-        element in ``rgb`` is smaller than the last element of
-        ``gb`` with respect to the lexicographical term
-        ordering.
-        
-        ::
+        Note that both bases are Groebner bases because they have
+        pairwise prime leading monomials but that the monic version of
+        the last element in ``rgb`` is smaller than the last element
+        of ``gb`` with respect to the lexicographical term ordering.::
         
             sage: (7*a-420*c^3+158*c^2+8*c-7)/7 < (a+2*b+2*c-1)
             True
@@ -359,27 +358,60 @@
     """
     def wrapper(*args, **kwds):
         """
-        execute fucntion in ``RedSBContext``.
+        Execute function in ``RedSBContext``.
         """
         with RedSBContext():
             return func(*args, **kwds)
 
     from sage.misc.sageinspect import sage_getsource 
     wrapper._sage_src_ = lambda: sage_getsource(func)
-    wrapper.__doc__=func.__doc__
+    wrapper.__name__ = func.__name__
+    wrapper.__doc__ = func.__doc__
     return wrapper
 
+class RequireField(MethodDecorator):
+    """
+    Decorator which throws an exception if a computation over a
+    coefficient ring which is not a field is attempted.
+
+    .. note::
+
+       This decorator is used automatically internally so the user
+       does not need to use it manually.
+    """
+    def __call__(self, *args, **kwds):
+        """
+        EXAMPLE::
+            sage: P.<x,y,z> = PolynomialRing(ZZ)
+            sage: I = ideal( x^2 - 3*y, y^3 - x*y, z^3 - x, x^4 - y*z + 1 )
+            sage: from sage.rings.polynomial.multi_polynomial_ideal import RequireField
+            sage: class Foo(I.__class__):
+            ...       @RequireField
+            ...       def bar(I):
+            ...          return I.groebner_basis()
+            ...
+            sage: J = Foo(I.ring(), I.gens())
+            sage: J.bar()
+            Traceback (most recent call last):
+            ...
+            ValueError: Coefficient ring must be a field for function 'bar'.
+        """
+        R = self._instance.ring()
+        if not R.base_ring().is_field():
+            raise ValueError("Coefficient ring must be a field for function '%s'."%(self.f.__name__))
+        return self.f(self._instance, *args, **kwds)
+
+require_field = RequireField
+
 def is_MPolynomialIdeal(x):
-    r"""
-    Return ``True`` if the provided argument
-    ``x`` is an ideal in the multivariate polynomial ring.
+    """
+    Return ``True`` if the provided argument ``x`` is an ideal in the
+    multivariate polynomial ring.
     
     INPUT:
     
-    
     -  ``x`` - an arbitrary object
     
-    
     EXAMPLES::
     
         sage: from sage.rings.polynomial.all import is_MPolynomialIdeal
@@ -387,10 +419,8 @@
         sage: I = [x + 2*y + 2*z - 1, x^2 + 2*y^2 + 2*z^2 - x, 2*x*y + 2*y*z - y]
     
     Sage distinguishes between a list of generators for an ideal and
-    the ideal itself. This distinction is inconsistent with Singular but
-    matches Magma's behavior.
-    
-    ::
+    the ideal itself. This distinction is inconsistent with Singular
+    but matches Magma's behavior.::
     
         sage: is_MPolynomialIdeal(I)
         False
@@ -405,16 +435,14 @@
 
 class MPolynomialIdeal_magma_repr:
     def _magma_init_(self, magma):
-        r"""
-        Returns a Magma ideal matching this ideal if the base ring coerces
-        to Magma and Magma is available.
+        """
+        Returns a Magma ideal matching this ideal if the base ring
+        coerces to Magma and Magma is available.
         
         INPUT:
         
-        
         -  ``magma`` - Magma instance
         
-        
         EXAMPLES::
         
             sage: R.<a,b,c,d,e,f,g,h,i,j> = PolynomialRing(GF(127),10)
@@ -436,15 +464,13 @@
         return 'ideal<%s|%s>'%(P.name(), G._ref())
 
     def _groebner_basis_magma(self, magma=magma_default):
-        r"""
-        Computes a Groebner Basis for self using Magma if available.
+        """
+        Computes a Groebner Basis for this ideal using Magma if
+        available.
         
         INPUT:
         
-        
-        -  ``magma`` - Magma instance or None (default
-           instance) (default: None)
-        
+        -  ``magma`` - Magma instance or None (default instance) (default: None)
         
         EXAMPLES::
         
@@ -465,12 +491,12 @@
         return B
 
 class MPolynomialIdeal_singular_repr:
-    r"""
-    An ideal in a multivariate polynomial ring, which has an underlying
-    Singular ring associated to it.
+    """
+    An ideal in a multivariate polynomial ring, which has an
+    underlying Singular ring associated to it.
     """
     def _singular_(self, singular=singular_default):
-        r"""
+        """
         Return Singular ideal corresponding to this ideal.
         
         EXAMPLES::
@@ -507,9 +533,9 @@
 
     def plot(self, singular=singular_default):
         """
-        If you somehow manage to install surf, perhaps you can use this
-        function to implicitly plot the real zero locus of this ideal (if
-        principal).
+        If you somehow manage to install surf, perhaps you can use
+        this function to implicitly plot the real zero locus of this
+        ideal (if principal).
         
         INPUT:
         
@@ -554,6 +580,7 @@
         I = singular(self)
         I.plot()
 
+    @require_field
     @redSB
     def complete_primary_decomposition(self, algorithm="sy"):
         r"""
@@ -618,31 +645,30 @@
              (Ideal (z^2 + 1, y + 1) of Multivariate Polynomial Ring in x, y, z over Rational Field,
               Ideal (z^2 + 1, y + 1) of Multivariate Polynomial Ring in x, y, z over Rational Field)]
         
-        ::
-        
             sage: I.complete_primary_decomposition(algorithm = 'gtz')
             [(Ideal (z^6 + 4*z^3 + 4, y - z^2) of Multivariate Polynomial Ring in x, y, z over Rational Field,
               Ideal (z^3 + 2, y - z^2) of Multivariate Polynomial Ring in x, y, z over Rational Field),
              (Ideal (z^2 + 1, y - z^2) of Multivariate Polynomial Ring in x, y, z over Rational Field,
               Ideal (z^2 + 1, y - z^2) of Multivariate Polynomial Ring in x, y, z over Rational Field)]
         
-        ::
-        
             sage: reduce(lambda Qi,Qj: Qi.intersection(Qj), [Qi for (Qi,radQi) in pd]) == I
             True
         
-        ::
-        
             sage: [Qi.radical() == radQi for (Qi,radQi) in pd]
             [True, True]
+
+            sage: P.<x,y,z> = PolynomialRing(ZZ)
+            sage: I = ideal( x^2 - 3*y, y^3 - x*y, z^3 - x, x^4 - y*z + 1 )
+            sage: I.complete_primary_decomposition()
+            Traceback (most recent call last):
+            ...
+            ValueError: Coefficient ring must be a field for function 'complete_primary_decomposition'.
         
         ALGORITHM: Uses Singular.
+
+        .. note::
         
-        REFERENCES:
-
-        - Thomas Becker and Volker Weispfenning. Groebner Bases - A
-          Computational Approach To Commutative Algebra. Springer, New
-          York 1993.
+           See [BW93]_ for an introduction to primary decomposition.
         """
         try:
             return self.__complete_primary_decomposition[algorithm]
@@ -663,6 +689,7 @@
         self.__complete_primary_decomposition[algorithm] = V
         return self.__complete_primary_decomposition[algorithm]
 
+    @require_field
     def primary_decomposition(self, algorithm='sy'):
         r"""
         Return a list of primary ideals such that their intersection is
@@ -690,15 +717,11 @@
         
         INPUT:
         
-        
         -  ``algorithm`` - string:
         
-          -  ``'sy'`` - (default) use the shimoyama-yokoyama
-             algorithm
+        -  ``'sy'`` - (default) use the shimoyama-yokoyama algorithm
         
-          -  ``'gtz'`` - use the gianni-trager-zacharias
-             algorithm
-        
+          -  ``'gtz'`` - use the gianni-trager-zacharias algorithm
         
         EXAMPLES::
         
@@ -724,6 +747,7 @@
         """
         return [I for I, _ in self.complete_primary_decomposition(algorithm)]
 
+    @require_field
     @redSB
     def associated_primes(self, algorithm='sy'):
         r"""
@@ -761,20 +785,16 @@
         
         -  ``algorithm`` - string:
         
-          -  ``'sy'`` - (default) use the shimoyama-yokoyama
-             algorithm
+        -  ``'sy'`` - (default) use the shimoyama-yokoyama algorithm
         
-          -  ``'gtz'`` - use the gianni-trager-zacharias
-             algorithm
+        -  ``'gtz'`` - use the gianni-trager-zacharias algorithm
         
         
         OUTPUT:
         
-        
         -  ``list`` - a list of primary ideals and their
            associated primes [(primary ideal, associated prime), ...]
         
-        
         EXAMPLES::
         
             sage: R.<x,y,z> = PolynomialRing(QQ, 3, order='lex')
@@ -794,59 +814,56 @@
         """
         return [P for _,P in self.complete_primary_decomposition(algorithm)]
             
+    @require_field
     def triangular_decomposition(self, algorithm=None, singular=singular_default):
-        r"""
-            Decompose zero-dimensional ideal ``self`` into
-            triangular sets.
-            
-            This requires that the given basis is reduced w.r.t. to the
-            lexicographical monomial ordering. If the basis of self does not
-            have this property, the required Groebner basis is computed
-            implicitly.
-            
-            INPUT:
-            
-            
-            -  ``algorithm`` - string or None (default: None)
-            
-               ALGORITHMS:
-            
-                 -  ``singular:triangL`` - decomposition of self into
-                    triangular systems (Lazard).
-            
-                 -  ``singular:triangLfak`` - decomp. of self into tri.
-                    systems plus factorization.
-            
-                 -  ``singular:triangM`` - decomposition of self into
-                    triangular systems (Moeller).
-            
-            
-            OUTPUT: a list `T` of lists `t` such that the
-            variety of ``self`` is the union of the varieties of
-            `t` in `L` and each `t` is in triangular
-            form.
-            
-            EXAMPLE::
-            
-                sage: P.<e,d,c,b,a> = PolynomialRing(QQ,5,order='lex')
-                sage: I = sage.rings.ideal.Cyclic(P)
-                sage: GB = Ideal(I.groebner_basis('singular:stdfglm'))
-                sage: GB.triangular_decomposition('singular:triangLfak')
-                [Ideal (a - 1, b - 1, c - 1, d^2 + 3*d + 1, e + d + 3) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field, 
-                Ideal (a - 1, b - 1, c^2 + 3*c + 1, d + c + 3, e - 1) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field, 
-                Ideal (a - 1, b^2 + 3*b + 1, c + b + 3, d - 1, e - 1) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field, 
-                Ideal (a - 1, b^4 + b^3 + b^2 + b + 1, c - b^2, d - b^3, e + b^3 + b^2 + b + 1) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field, 
-                Ideal (a^2 + 3*a + 1, b - 1, c - 1, d - 1, e + a + 3) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field, 
-                Ideal (a^2 + 3*a + 1, b + a + 3, c - 1, d - 1, e - 1) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field, 
-                Ideal (a^4 - 4*a^3 + 6*a^2 + a + 1, 11*b^2 - 6*b*a^3 + 26*b*a^2 - 41*b*a + 4*b + 8*a^3 - 31*a^2 + 40*a + 24, 11*c + 3*a^3 - 13*a^2 + 26*a - 2, 11*d + 3*a^3 - 13*a^2 + 26*a - 2, 11*e + 11*b - 6*a^3 + 26*a^2 - 41*a + 4) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field, 
-                Ideal (a^4 + a^3 + a^2 + a + 1, b - 1, c + a^3 + a^2 + a + 1, d - a^3, e - a^2) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field, 
-                Ideal (a^4 + a^3 + a^2 + a + 1, b - a, c - a, d^2 + 3*d*a + a^2, e + d + 3*a) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field, 
-                Ideal (a^4 + a^3 + a^2 + a + 1, b - a, c^2 + 3*c*a + a^2, d + c + 3*a, e - a) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field, 
-                Ideal (a^4 + a^3 + a^2 + a + 1, b^2 + 3*b*a + a^2, c + b + 3*a, d - a, e - a) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field, 
-                Ideal (a^4 + a^3 + a^2 + a + 1, b^3 + b^2*a + b^2 + b*a^2 + b*a + b + a^3 + a^2 + a + 1, c + b^2*a^3 + b^2*a^2 + b^2*a + b^2, d - b^2*a^2 - b^2*a - b^2 - b*a^2 - b*a - a^2, e - b^2*a^3 + b*a^2 + b*a + b + a^2 + a) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field, 
-                Ideal (a^4 + a^3 + 6*a^2 - 4*a + 1, 11*b^2 - 6*b*a^3 - 10*b*a^2 - 39*b*a - 2*b - 16*a^3 - 23*a^2 - 104*a + 24, 11*c + 3*a^3 + 5*a^2 + 25*a + 1, 11*d + 3*a^3 + 5*a^2 + 25*a + 1, 11*e + 11*b - 6*a^3 - 10*a^2 - 39*a - 2) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field]
-            """
-
+        """
+        Decompose zero-dimensional ideal ``self`` into triangular
+        sets.
+        
+        This requires that the given basis is reduced w.r.t. to the
+        lexicographical monomial ordering. If the basis of self does
+        not have this property, the required Groebner basis is
+        computed implicitly.
+        
+        INPUT:
+        
+        -  ``algorithm`` - string or None (default: None)
+        
+        ALGORITHMS:
+        
+        - ``singular:triangL`` - decomposition of self into triangular
+          systems (Lazard).
+        
+        - ``singular:triangLfak`` - decomp. of self into tri.  systems
+          plus factorization.
+        
+          - ``singular:triangM`` - decomposition of self into
+            triangular systems (Moeller).
+        
+        OUTPUT: a list `T` of lists `t` such that the variety of
+        ``self`` is the union of the varieties of `t` in `L` and each
+        `t` is in triangular form.
+        
+        EXAMPLE::
+        
+            sage: P.<e,d,c,b,a> = PolynomialRing(QQ,5,order='lex')
+            sage: I = sage.rings.ideal.Cyclic(P)
+            sage: GB = Ideal(I.groebner_basis('singular:stdfglm'))
+            sage: GB.triangular_decomposition('singular:triangLfak')
+            [Ideal (a - 1, b - 1, c - 1, d^2 + 3*d + 1, e + d + 3) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field, 
+            Ideal (a - 1, b - 1, c^2 + 3*c + 1, d + c + 3, e - 1) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field, 
+            Ideal (a - 1, b^2 + 3*b + 1, c + b + 3, d - 1, e - 1) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field, 
+            Ideal (a - 1, b^4 + b^3 + b^2 + b + 1, c - b^2, d - b^3, e + b^3 + b^2 + b + 1) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field, 
+            Ideal (a^2 + 3*a + 1, b - 1, c - 1, d - 1, e + a + 3) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field, 
+            Ideal (a^2 + 3*a + 1, b + a + 3, c - 1, d - 1, e - 1) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field, 
+            Ideal (a^4 - 4*a^3 + 6*a^2 + a + 1, 11*b^2 - 6*b*a^3 + 26*b*a^2 - 41*b*a + 4*b + 8*a^3 - 31*a^2 + 40*a + 24, 11*c + 3*a^3 - 13*a^2 + 26*a - 2, 11*d + 3*a^3 - 13*a^2 + 26*a - 2, 11*e + 11*b - 6*a^3 + 26*a^2 - 41*a + 4) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field, 
+            Ideal (a^4 + a^3 + a^2 + a + 1, b - 1, c + a^3 + a^2 + a + 1, d - a^3, e - a^2) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field, 
+            Ideal (a^4 + a^3 + a^2 + a + 1, b - a, c - a, d^2 + 3*d*a + a^2, e + d + 3*a) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field, 
+            Ideal (a^4 + a^3 + a^2 + a + 1, b - a, c^2 + 3*c*a + a^2, d + c + 3*a, e - a) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field, 
+            Ideal (a^4 + a^3 + a^2 + a + 1, b^2 + 3*b*a + a^2, c + b + 3*a, d - a, e - a) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field, 
+            Ideal (a^4 + a^3 + a^2 + a + 1, b^3 + b^2*a + b^2 + b*a^2 + b*a + b + a^3 + a^2 + a + 1, c + b^2*a^3 + b^2*a^2 + b^2*a + b^2, d - b^2*a^2 - b^2*a - b^2 - b*a^2 - b*a - a^2, e - b^2*a^3 + b*a^2 + b*a + b + a^2 + a) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field, 
+            Ideal (a^4 + a^3 + 6*a^2 - 4*a + 1, 11*b^2 - 6*b*a^3 - 10*b*a^2 - 39*b*a - 2*b - 16*a^3 - 23*a^2 - 104*a + 24, 11*c + 3*a^3 + 5*a^2 + 25*a + 1, 11*d + 3*a^3 + 5*a^2 + 25*a + 1, 11*e + 11*b - 6*a^3 - 10*a^2 - 39*a - 2) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field]
+        """
         P = self.ring()
 
         is_groebner = self.basis_is_groebner()
@@ -899,6 +916,7 @@
 
         return T
 
+    @require_field
     def dimension(self, singular=singular_default):
         """
         The dimension of the ring modulo this ideal.
@@ -993,6 +1011,7 @@
                     raise TypeError, "Local/unknown orderings not supported by 'toy_buchberger' implementation."
         return self.__dimension
 
+    @require_field
     def vector_space_dimension(self):
         """
         Return the vector space dimension of the ring modulo this ideal. If
@@ -1021,14 +1040,14 @@
 
     @redSB
     def _groebner_basis_singular(self, algorithm="groebner", *args, **kwds):
-        r"""
-        Return the reduced Groebner basis of this ideal. If the Groebner
-        basis for this ideal has been calculated before, the cached Groebner
-        basis is returned regardless of the requested algorithm.
+        """
+        Return the reduced Groebner basis of this ideal. If the
+        Groebner basis for this ideal has been calculated before, the
+        cached Groebner basis is returned regardless of the requested
+        algorithm.
         
         INPUT:
         
-        
         -  ``algorithm`` - see below for available algorithms
         
         
@@ -1051,13 +1070,10 @@
         'slimgb'
             the *SlimGB* algorithm
         
-        
         EXAMPLES:
         
-        We compute a Groebner basis of 'cyclic 4' relative to lexicographic
-        ordering.
-        
-        ::
+        We compute a Groebner basis of 'cyclic 4' relative to
+        lexicographic ordering.::
         
             sage: R.<a,b,c,d> = PolynomialRing(QQ, 4, order='lex')
             sage: I = sage.rings.ideal.Cyclic(R,4); I
@@ -1079,6 +1095,7 @@
            This method is called by the :meth:`.groebner_basis` method
            and the user usually doesn't need to bother with this one.
         """
+
         R = self.ring()
         S = self._groebner_basis_singular_raw(algorithm=algorithm, *args, **kwds)
         S =  Sequence([R(S[i+1]) for i in range(len(S))], R, check=False, immutable=True)
@@ -1125,17 +1142,16 @@
         return S
 
     def _groebner_basis_libsingular(self, algorithm="std"):
-        r"""
-        Return the reduced Groebner basis of this ideal. If the Groebner
-        basis for this ideal has been calculated before the cached Groebner
-        basis is returned regardless of the requested algorithm.
+        """
+        Return the reduced Groebner basis of this ideal. If the
+        Groebner basis for this ideal has been calculated before the
+        cached Groebner basis is returned regardless of the requested
+        algorithm.
         
         INPUT:
         
-        
         -  ``algorithm`` - see below for available algorithms
         
-        
         ALGORITHMS:
         
         'std'
@@ -1144,13 +1160,10 @@
         'slimgb'
             the *SlimGB* algorithm
         
-        
         EXAMPLES:
         
-        We compute a Groebner basis of 'cyclic 4' relative to lexicographic
-        ordering.
-        
-        ::
+        We compute a Groebner basis of 'cyclic 4' relative to
+        lexicographic ordering.::
         
             sage: R.<a,b,c,d> = PolynomialRing(QQ, 4, order='lex')
             sage: I = sage.rings.ideal.Cyclic(R,4); I
@@ -1176,15 +1189,17 @@
         else:
             raise TypeError, "algorithm '%s' unknown"%algorithm
         return S
-
+    
+    @require_field
     def genus(self):
         """
         Return the genus of the projective curve defined by this ideal,
         which must be 1 dimensional.
         
-        EXAMPLE: Consider the hyperelliptic curve
-        `y^2 = 4x^5 - 30x^3 + 45x - 22` over
-        `\QQ`, it has genus 2::
+        EXAMPLE: 
+
+        Consider the hyperelliptic curve `y^2 = 4x^5 - 30x^3 + 45x -
+        22` over `\QQ`, it has genus 2::
         
             sage: P, x = PolynomialRing(QQ,"x").objgen()
             sage: f = 4*x^5 - 30*x^3 + 45*x - 22
@@ -1222,10 +1237,8 @@
             sage: I.intersection(J)
             Ideal (x*y) of Multivariate Polynomial Ring in x, y over Rational Field
         
-        The following simple example illustrates that the product need not
-        equal the intersection.
-        
-        ::
+        The following simple example illustrates that the product need
+        not equal the intersection.::
         
             sage: I = (x^2, y)*R
             sage: J = (y^2, x)*R
@@ -1245,15 +1258,14 @@
         K = I.intersect(J)
         return R.ideal(K)
 
+    @require_field
     @redSB
     def minimal_associated_primes(self):
-        r"""
+        """
         OUTPUT:
         
-        
         -  ``list`` - a list of prime ideals
         
-        
         EXAMPLES::
         
             sage: R.<x,y,z> = PolynomialRing(QQ, 3, 'xyz')
@@ -1273,6 +1285,7 @@
         R = self.ring()
         return [R.ideal(J) for J in M]
 
+    @require_field
     @redSB
     def radical(self):
         r"""
@@ -1287,9 +1300,7 @@
             sage: I.radical()
             Ideal (y, x) of Multivariate Polynomial Ring in x, y, z over Rational Field
         
-        That the radical is correct is clear from the Groebner basis.
-        
-        ::
+        That the radical is correct is clear from the Groebner basis.::
         
             sage: I.groebner_basis()
             [y^3, x^2]
@@ -1321,29 +1332,26 @@
         r = I.radical()
         return S.ideal(r)
 
+    @require_field
     @redSB
     def integral_closure(self, p=0, r=True, singular=singular_default):
-        r"""
+        """
         Let `I` = ``self``.
         
-        Returns the integral closure of `I, ..., I^p`, where
-        `sI` is an ideal in the polynomial ring
-        `R=k[x(1),...x(n)]`. If `p` is not given, or
-        `p=0`, compute the closure of all powers up to the maximum
-        degree in t occurring in the closure of `R[It]` (so this is
-        the last power whose closure is not just the sum/product of the
-        smaller). If `r` is given and ``r is True``,
-        ``I.integral_closure()`` starts with a check whether I
+        Returns the integral closure of `I, ..., I^p`, where `sI` is
+        an ideal in the polynomial ring `R=k[x(1),...x(n)]`. If `p` is
+        not given, or `p=0`, compute the closure of all powers up to
+        the maximum degree in t occurring in the closure of `R[It]`
+        (so this is the last power whose closure is not just the
+        sum/product of the smaller). If `r` is given and ``r is
+        True``, ``I.integral_closure()`` starts with a check whether I
         is already a radical ideal.
         
         INPUT:
         
+        - ``p`` - powers of I (default: 0)
         
-        -  ``p`` - powers of I (default: 0)
-        
-        -  ``r`` - check whether self is a radical ideal first
-           (default: True)
-        
+        - ``r`` - check whether self is a radical ideal first (default: ``True``)
         
         EXAMPLE::
         
@@ -1362,6 +1370,7 @@
                        check=False, immutable=True)
         return ret
 
+    @require_field
     def syzygy_module(self):
         r"""
         Computes the first syzygy (i.e., the module of relations of the
@@ -1436,14 +1445,14 @@
         returns `(g_1, ..., g_s)` such that:
         
         
-        -  `(f_1,...,f_n) = (g_1,...,g_s)`
+        - `(f_1,...,f_n) = (g_1,...,g_s)`
         
-        -  `LT(g_i) != LT(g_j)` for all `i != j`
+        - `LT(g_i) != LT(g_j)` for all `i != j`
         
-        -  `LT(g_i)` does not divide `m` for all monomials
-           `m` of `\{g_1,...,g_{i-1},g_{i+1},...,g_s\}`
+        - `LT(g_i)` does not divide `m` for all monomials `m` of
+           `\{g_1,...,g_{i-1},g_{i+1},...,g_s\}`
         
-        -  `LC(g_i) == 1` for all `i`.
+        - `LC(g_i) == 1` for all `i` if the coefficient ring is a field.
         
         
         EXAMPLE::
@@ -1453,16 +1462,14 @@
             sage: I.interreduced_basis()
             [x*z - z, x*y + z, y^3 + z]
         
-        ::
-        
             sage: R.<x,y,z> = PolynomialRing(QQ,order='negdegrevlex')
             sage: I = Ideal([z*x+y^3,z+y^3,z+x*y])
             sage: I.interreduced_basis()
             [x*z + y^3, x*y - y^3, z + y^3]
         
         ALGORITHM: Uses Singular's interred command or
-        ``toy_buchberger.inter_reduction`` if conversion to
-        Singular fails.
+        :func:`sage.rings.polynomial.toy_buchberger.inter_reduction``
+        if conversion to Singular fails.
         """
         from sage.rings.polynomial.multi_polynomial_ideal_libsingular import interred_libsingular
         from sage.rings.polynomial.multi_polynomial_libsingular import MPolynomialRing_libsingular
@@ -1487,22 +1494,20 @@
         ret = Sequence( ret, R, check=False, immutable=True)
         return ret
 
+    @require_field
     def basis_is_groebner(self, singular=singular_default):
         r"""
-        Returns ``True`` if the generators of
-        ``self`` (``self.gens()``) form a Groebner
-        basis.
+        Returns ``True`` if the generators of this ideal
+        (``self.gens()``) form a Groebner basis.
         
-        Let `I` be the set of generators of this ideal. The check
-        is performed by trying to lift `Syz(LM(I))` to
-        `Syz(I)` as `I` forms a Groebner basis if and only
-        if for every element `S` in `Syz(LM(I))`:
+        Let `I` be the set of generators of this ideal. The check is
+        performed by trying to lift `Syz(LM(I))` to `Syz(I)` as `I`
+        forms a Groebner basis if and only if for every element `S` in
+        `Syz(LM(I))`:
         
         .. math::
         
-            S \cdot G = \sum_{i=0}^{m} h_ig_i         \rightarrow_G 0.
-        
-        .
+            S * G = \sum_{i=0}^{m} h_ig_i ---->_G 0.
         
         ALGORITHM: Uses Singular
         
@@ -1573,20 +1578,19 @@
         self._singular_().attrib('isSB',1)
         return True
 
+    @require_field
     @redSB
     def transformed_basis(self, algorithm="gwalk", other_ring=None, singular=singular_default):
-        r"""
-        Returns a lex or ``other_ring`` Groebner Basis for
-        this ideal.
+        """
+        Returns a lex or ``other_ring`` Groebner Basis for this ideal.
         
         INPUT:
         
-        
         -  ``algorithm`` - see below for options.
         
-        -  ``other_ring`` - only valid for algorithm 'fglm',
-           if provided conversion will be performed to this ring. Otherwise a
-           lex Groebner basis will be returned.
+        - ``other_ring`` - only valid for algorithm 'fglm', if
+           provided conversion will be performed to this
+           ring. Otherwise a lex Groebner basis will be returned.
         
         
         ALGORITHMS:
@@ -1676,10 +1680,7 @@
         
         INPUT:
         
-        
-        -  ``variables`` - a list or tuple of variables in
-           ``self.ring()``
-        
+        - ``variables`` - a list or tuple of variables in ``self.ring()``
         
         EXAMPLE::
         
@@ -1706,20 +1707,17 @@
     @redSB
     def quotient(self, J):
         r"""
-        Given ideals `I` = ``self`` and `J` in
-        the same polynomial ring `P`, return the ideal quotient of
-        `I` by `J` consisting of the polynomials `a` of
-        `P` such that `\{aJ \subset I\}`.
+        Given ideals `I` = ``self`` and `J` in the same polynomial
+        ring `P`, return the ideal quotient of `I` by `J` consisting
+        of the polynomials `a` of `P` such that `\{aJ \subset I\}`.
         
         This is also referred to as the colon ideal
         (`I`:`J`).
         
         INPUT:
         
-        
         -  ``J`` - multivariate polynomial ideal
         
-        
         EXAMPLE::
         
             sage: R.<x,y,z> = PolynomialRing(GF(181),3)
@@ -1743,6 +1741,7 @@
 
         return R.ideal([f.sage_poly(R) for f in self._singular_().quotient(J._singular_())])
 
+    @require_field
     def variety(self, ring=None, proof=True):
         r"""
         Return the variety of ``self``.
@@ -1912,8 +1911,6 @@
             {x14: 0, x24: 0, x16: 1, x1: 1, x3: 1, x2: 0, x5: 0, x4: 0, x19: 0, x18: 1, x7: 1, x6: 0, x10: 1, x30: 0, x28: 1, x29: 1, x13: 0, x27: 1, x11: 0, x25: 1, x9: 0, x8: 0, x20: 0, x17: 0, x23: 0, x26: 0, x15: 0, x21: 1, x12: 0, x22: 0}
             {x14: 0, x24: 0, x16: 1, x1: 1, x3: 1, x2: 0, x5: 0, x4: 1, x19: 0, x18: 1, x7: 1, x6: 0, x10: 1, x30: 0, x28: 1, x29: 1, x13: 0, x27: 1, x11: 0, x25: 1, x9: 0, x8: 0, x20: 0, x17: 0, x23: 0, x26: 0, x15: 0, x21: 1, x12: 0, x22: 0}
 
-
-                                  
         ALGORITHM: Uses triangular decomposition.
         """
         def _variety(T, V, v=None):
@@ -1964,6 +1961,7 @@
         V.sort()
         return Sequence(V)
 
+    @require_field
     def hilbert_polynomial(self):
         r"""
         Return the Hilbert polynomial of this ideal.
@@ -1990,6 +1988,7 @@
         fp = ZZ(len(hp)-1).factorial()
         return sum([ZZ(hp[i+1])*t**i for i in xrange(len(hp))])/fp
 
+    @require_field
     def hilbert_series(self, singular=singular_default):
         r"""
         Return the Hilbert series of this ideal.
@@ -2127,14 +2126,11 @@
         
         INPUT:
         
+        - ``ring`` - the ring the ideal is defined in
         
-        -  ``ring`` - the ring the ideal is defined in
+        - ``gens`` - a list of generators for the ideal
         
-        -  ``gens`` - a list of generators for the ideal
-        
-        -  ``coerce`` - coerce elements to the ring
-           ``ring``?
-        
+        - ``coerce`` - coerce elements to the ring ``ring``?
         
         EXAMPLES::
         
@@ -2396,21 +2392,16 @@
             sage: I.groebner_basis('magma:GroebnerBasis') # optional - magma
             [a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/21*c^3 + 1/84*c^2 + 1/84*c]
         
-        Groebner bases over `\ZZ` can be computed. However,
-        the native implementation is very slow. If available Macaulay2 is
-        used, which is an optional Sage package.
-        
-        ::
+        Groebner bases over `\ZZ` can be computed.::
         
             sage: P.<a,b,c> = PolynomialRing(ZZ,3)
             sage: I = P * (a + 2*b + 2*c - 1, a^2 - a + 2*b^2 + 2*c^2, 2*a*b + 2*b*c - b)
-            sage: I.groebner_basis()                               # optional - macaulay2
-            ...
-            [b^3 - b*c^2 - 24*c^3 - b^2 - 6*b*c + 2*c^2 + 2*c,
-             2*b*c^2 + 36*c^3 - 9*b*c - 24*c^2 + 2*b + 4*c, 
-             42*c^3 + b^2 + 2*b*c - 14*c^2 + b, 
-             2*b^2 - 4*b*c - 6*c^2 + 2*c,
-             10*b*c + 12*c^2 - b - 4*c, 
+            sage: I.groebner_basis()
+            [-b^3 + 23*b*c^2 - 3*b^2 - 5*b*c, 
+             2*b*c^2 - 6*c^3 - b^2 - b*c + 2*c^2, 
+             42*c^3 + 5*b^2 + 4*b*c - 14*c^2, 
+             2*b^2 + 6*b*c + 6*c^2 - b - 2*c, 
+             -10*b*c - 12*c^2 + b + 4*c, 
              a + 2*b + 2*c - 1]
         
         ::
@@ -2422,6 +2413,17 @@
              2*b^2 - 4*b*c - 6*c^2 + 2*c, 10*b*c + 12*c^2 - b - 4*c, 
              a + 2*b + 2*c - 1]
         
+        Groebner bases over `\ZZ/n\ZZ` are also supported::
+
+            sage: P.<a,b,c> = PolynomialRing(Zmod(1000),3)
+            sage: I = P * (a + 2*b + 2*c - 1, a^2 - a + 2*b^2 + 2*c^2, 2*a*b + 2*b*c - b)
+            sage: I.groebner_basis()
+            [b*c^2 + 992*b*c + 712*c^2 + 332*b + 96*c, 
+             2*c^3 + 589*b*c + 862*c^2 + 762*b + 268*c, 
+             b^2 + 438*b*c + 281*b, 
+             5*b*c + 156*c^2 + 112*b + 948*c, 
+             50*c^2 + 600*b + 650*c, a + 2*b + 2*c + 999, 125*b]
+
         Sage also supports local orderings::
         
             sage: P.<x,y,z> = PolynomialRing(QQ,3,order='negdegrevlex')
@@ -2460,16 +2462,10 @@
             algorithm = "toy:buchberger2"
 
         if algorithm is '':
-            if self.ring().base_ring() is ZZ:
-#                 try:
-#                     gb = self._groebner_basis_macaulay2()
-#                 except TypeError:
-                verbose("Warning: falling back to very slow toy implementation.", level=0)
-                gb = toy_d_basis.d_basis(self, *args, **kwds)
-            elif is_IntegerModRing(self.ring().base_ring()) and not self.ring().base_ring().is_field():
-                try:
-                    gb = self._groebner_basis_macaulay2()
-                except TypeError:
+            try:
+                gb = self._groebner_basis_singular("groebner", *args, **kwds)
+            except TypeError, msg: # conversion to Singular not supported
+                if self.ring().term_order().is_global() and is_IntegerModRing(self.ring().base_ring()) and not self.ring().base_ring().is_field():
                     verbose("Warning: falling back to very slow toy implementation.", level=0)
 
                     ch = self.ring().base_ring().characteristic()
@@ -2480,15 +2476,13 @@
 
                     R = self.ring()
                     gb = filter(lambda f: f,[R(f) for f in gb])
-            else:
-                try:
-                    gb = self._groebner_basis_singular("groebner", *args, **kwds)
-                except TypeError, msg: # conversion to Singular not supported
+                else:
                     if self.ring().term_order().is_global():
                         verbose("Warning: falling back to very slow toy implementation.", level=0)
                         gb = toy_buchberger.buchberger_improved(self, *args, **kwds)
                     else:
                         raise TypeError, "Local/unknown orderings not supported by 'toy_buchberger' implementation."
+
         elif algorithm.startswith('singular:'):
             gb = self._groebner_basis_singular(algorithm[9:])
         elif algorithm.startswith('libsingular:'):
@@ -2696,6 +2690,7 @@
                 return False
         return True
 
+    @require_field
     def _normal_basis_libsingular(self):
         r"""
         Returns the normal basis for a given groebner basis. It will use
@@ -2714,6 +2709,7 @@
         
         return kbase_libsingular(self.ring().ideal(gb))
         
+    @require_field
     def normal_basis(self, algorithm='libsingular', singular=singular_default):
         """
         Returns a vector space basis (consisting of monomials) of the
@@ -2746,18 +2742,16 @@
         
         INPUT:
         
+        - ``self`` - a principal ideal in 2 variables
         
-        -  ``self`` - a principal ideal in 2 variables
+        - ``algorithm`` - set this to 'surf' if you want 'surf' to
+           plot the ideal (default: None)
         
-        -  ``algorithm`` - set this to 'surf' if you want
-           'surf' to plot the ideal (default: None)
+        - ``*args`` - optional tuples ``(variable, minimum, maximum)``
+           for plotting dimensions
         
-        -  ``*args`` - optional tuples ``(variable,
-           minimum, maximum)`` for plotting dimensions
-        
-        -  ``**kwds`` - optional keyword arguments passed on
-           to ``implicit_plot``
-        
+        - ``**kwds`` - optional keyword arguments passed on to
+           ``implicit_plot``
         
         EXAMPLES:
 
@@ -2860,7 +2854,7 @@
         else:
             raise TypeError, "Ideal generator may not have either 2 or 3 variables."
             
-
+    @require_field
     def weil_restriction(self):
         """
         Compute the Weil restriction of this ideal over some extension
diff -r 6c7354ace3b6 -r 8037fada5b30 sage/rings/polynomial/multi_polynomial_ideal_libsingular.pyx
--- a/sage/rings/polynomial/multi_polynomial_ideal_libsingular.pyx	Sat Jun 06 09:55:28 2009 -0700
+++ b/sage/rings/polynomial/multi_polynomial_ideal_libsingular.pyx	Wed Jun 10 21:47:44 2009 -0700
@@ -56,10 +56,7 @@
 
 from sage.structure.parent_base cimport ParentWithBase
 
-from sage.libs.singular.singular cimport Conversion
-
-cdef Conversion co
-co = Conversion()
+from sage.rings.polynomial.multi_polynomial_libsingular cimport new_MP
 
 from sage.rings.polynomial.multi_polynomial_ideal import MPolynomialIdeal
 from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomial_libsingular
@@ -82,7 +79,7 @@
     l = []
 
     for j from 0 <= j < IDELEMS(i):
-        p = co.new_MP(parent, p_Copy(i.m[j], r))
+        p = new_MP(parent, p_Copy(i.m[j], r))
         l.append( p )
 
     return Sequence(l, check=False, immutable=True)
@@ -232,6 +229,18 @@
 
     INPUT:
         I -- a SAGE ideal
+
+    EXAMPLE::
+    
+        sage: P.<x,y,z> = PolynomialRing(ZZ)
+        sage: I = ideal( x^2 - 3*y, y^3 - x*y, z^3 - x, x^4 - y*z + 1 )
+        sage: I.interreduced_basis()
+        [9*y^2 - y*z + 1, x^2 - 3*y, z^3 - x, y^3 - x*y]
+
+        sage: P.<x,y,z> = PolynomialRing(QQ)
+        sage: I = ideal( x^2 - 3*y, y^3 - x*y, z^3 - x, x^4 - y*z + 1 )
+        sage: I.interreduced_basis()
+        [y^2 - 1/9*y*z + 1/9, x^2 - 3*y, z^3 - x, y*z^2 - 81*x*y - 9*y - z]
     """
     global singular_options
     
@@ -258,13 +267,14 @@
 
 
     # divide head by coefficents
-    for j from 0 <= j < IDELEMS(result):
-        p = result.m[j]
-        n = p_GetCoeff(p,r)
-        n = nInvers(n)
-        result.m[j] = pp_Mult_nn(p, n, r)
-        p_Delete(&p,r)
-        n_Delete(&n,r)
+    if r.ringtype == 0:
+        for j from 0 <= j < IDELEMS(result):
+            p = result.m[j]
+            n = p_GetCoeff(p,r)
+            n = nInvers(n)
+            result.m[j] = pp_Mult_nn(p, n, r)
+            p_Delete(&p,r)
+            n_Delete(&n,r)
 
     id_Delete(&i,r)
     
@@ -272,3 +282,5 @@
     
     id_Delete(&result,r)
     return res
+
+
diff -r 6c7354ace3b6 -r 8037fada5b30 sage/rings/polynomial/multi_polynomial_libsingular.pxd
--- a/sage/rings/polynomial/multi_polynomial_libsingular.pxd	Sat Jun 06 09:55:28 2009 -0700
+++ b/sage/rings/polynomial/multi_polynomial_libsingular.pxd	Wed Jun 10 21:47:44 2009 -0700
@@ -19,3 +19,8 @@
     cdef ring *_ring
     cdef int _cmp_c_impl(left, Parent right) except -2
 
+    #cpdef MPolynomial_libsingular _element_constructor_(self, element)
+
+# new polynomials
+
+cdef MPolynomial_libsingular new_MP(MPolynomialRing_libsingular parent, poly *p)
diff -r 6c7354ace3b6 -r 8037fada5b30 sage/rings/polynomial/multi_polynomial_libsingular.pyx
--- a/sage/rings/polynomial/multi_polynomial_libsingular.pyx	Sat Jun 06 09:55:28 2009 -0700
+++ b/sage/rings/polynomial/multi_polynomial_libsingular.pyx	Wed Jun 10 21:47:44 2009 -0700
@@ -1,27 +1,142 @@
-"""
-Multivariate polynomials via libSINGULAR.
-
-This file implements multivariate polynomials over certain fields via
-the shared library interface to \SINGULAR and thus this implementation
-is quite efficient. Supported base fields are $\QQ$, $\ZZ$, $\F_{p^n}$
-and absolute number fields.
-
-However, in this shared library mode no support for the \Singular
-interpreter is provided which means that only a basic subset of
-\Singular's capabilities are available, i.e. those written in
-C/C++. All of \Singular's capabilities are however available through
-the pexpect interface and convenient conversion methods are provided.
+r"""
+Multivariate Polynomials
+
+Sage implements multivariate polynomial rings through several
+backends. The most generic implementation used the classes
+:class:`PolyDict` and :class:`ETuple` to construct a dictionary with
+exponent tuples as keys and coefficients as values.
+
+Additionally, specialized and optimized implementations over many
+coefficient rings are implemented via a shared library interface to
+SINGULAR. In particular, the following coefficient rings are supported
+by this impelementation:
+
+- the rational numbers `\QQ`,
+
+- the ring of integers `\ZZ`,
+
+- `\ZZ/n\ZZ` for any integer `n`,
+
+- finite fields `\GF{p^n}` for `p` prime and `n > 0` 
+
+- and absolute number fields `\QQ(a)`.
+
+Polynomials in the boolean polynomial ring
+
+.. math::
+
+    \GF{2}[x_1,...,x_n]/<x_1^2+x_1,...,x_n^2+x_n>.
+
+are implemented using the PolyBoRi library (cf. :mod:`sage.rings.polynomial.pbori`).
 
 AUTHORS:
-    -- Martin Albrecht (2007-01): initial implementation
-    -- Joel Mohler (2008-01): misc improvements, polishing
-    -- Martin Albrecht (2008-08): added QQ(a) and ZZ support
-    -- Simon King (2009-04): improved coercion
+
+The libSINGULAR interface was implemented by
+
+- Martin Albrecht (2007-01): initial implementation
+
+- Joel Mohler (2008-01): misc improvements, polishing
+
+- Martin Albrecht (2008-08): added `\QQ(a)` and `\ZZ` support
+
+- Simon King (2009-04): improved coercion
+
+- Martin Albrecht (2009-05): added `\ZZ/n\ZZ` support, refactoring
+
+The generic implementation was provided by
+
+- David Joyner and William Stein
+
+- Kiran S. Kedlaya (2006-02-12): added Macaulay2 analogues of Singular
+  features
+
+- Martin Albrecht (2006-04-21): reorganize class hiearchy for singular
+  rep
+
+- Martin Albrecht (2007-04-20): reorganized class hierarchy to support
+  Pyrex implementations
+
+- Robert Bradshaw (2007-08-15): Coercions from rings in a subset of
+  the variables.
 
 TODO:
-   -- implement Real, Complex
-
-TESTS:
+
+- implement Real, Complex coefficient rings via libSINGULAR
+
+EXAMPLES:
+
+We show how to construct various multivariate polynomial rings::
+
+    sage: P.<x,y,z> = QQ[]
+    sage: P
+    Multivariate Polynomial Ring in x, y, z over Rational Field
+
+    sage: f = 27/113 * x^2 + y*z + 1/2; f
+    27/113*x^2 + y*z + 1/2
+
+    sage: P.term_order()
+    Degree reverse lexicographic term order
+
+    sage: P = PolynomialRing(GF(127),3,names='abc', order='lex')
+    sage: P
+    Multivariate Polynomial Ring in a, b, c over Finite Field of size 127
+
+    sage: a,b,c = P.gens()
+    sage: f = 57 * a^2*b + 43 * c + 1; f
+    57*a^2*b + 43*c + 1
+
+    sage: P.term_order()
+    Lexicographic term order
+
+    sage: z = QQ['z'].0
+    sage: K.<s> = NumberField(z^2 - 2)
+    sage: P.<x,y> = PolynomialRing(K, 2)
+    sage: 1/2*s*x^2 + 3/4*s
+    (1/2*s)*x^2 + (3/4*s)
+
+    sage: P.<x,y,z> = ZZ[]; P
+    Multivariate Polynomial Ring in x, y, z over Integer Ring
+
+    sage: P.<x,y,z> = Zmod(2^10)[]; P
+    Multivariate Polynomial Ring in x, y, z over Ring of integers modulo 1024
+
+    sage: P.<x,y,z> = Zmod(3^10)[]; P
+    Multivariate Polynomial Ring in x, y, z over Ring of integers modulo 59049
+
+    sage: P.<x,y,z> = Zmod(2^100)[]; P
+    Multivariate Polynomial Ring in x, y, z over Ring of integers modulo 1267650600228229401496703205376
+
+    sage: P.<x,y,z> = Zmod(2521352)[]; P
+    Multivariate Polynomial Ring in x, y, z over Ring of integers modulo 2521352
+    sage: type(P)
+    <type 'sage.rings.polynomial.multi_polynomial_libsingular.MPolynomialRing_libsingular'>
+
+    sage: P.<x,y,z> = Zmod(25213521351515232)[]; P
+    Multivariate Polynomial Ring in x, y, z over Ring of integers modulo 25213521351515232
+    sage: type(P)
+    <class 'sage.rings.polynomial.multi_polynomial_ring.MPolynomialRing_polydict'>
+
+We construct the Frobenius morphism on `\GF{5}[x,y,z]` over `\GF{5}`::
+
+    sage: R.<x,y,z> = PolynomialRing(GF(5), 3)
+    sage: frob = R.hom([x^5, y^5, z^5])
+    sage: frob(x^2 + 2*y - z^4)
+    -z^20 + x^10 + 2*y^5
+    sage: frob((x + 2*y)^3)
+    x^15 + x^10*y^5 + 2*x^5*y^10 - 2*y^15
+    sage: (x^5 + 2*y^5)^3
+    x^15 + x^10*y^5 + 2*x^5*y^10 - 2*y^15
+
+We make a polynomial ring in one variable over a polynomial ring in
+two variables::
+
+    sage: R.<x, y> = PolynomialRing(QQ, 2)
+    sage: S.<t> = PowerSeriesRing(R)
+    sage: t*(x+y)
+    (x + y)*t
+
+TESTS::
+
     sage: P.<x,y,z> = QQ[]
     sage: loads(dumps(P)) == P
     True
@@ -48,10 +163,8 @@
     sage: R.<u,v> = PolynomialRing(QQ, 2)
     sage: p(u/v)
     (u + v)/v
-
 """
 
-
 include "sage/ext/stdsage.pxi"
 include "sage/ext/interrupt.pxi"
 
@@ -67,9 +180,7 @@
 import sage.rings.memory
 
 # conversion routines
-from sage.libs.singular.singular cimport Conversion
-cdef Conversion co
-co = Conversion()
+from sage.libs.singular.singular cimport si2sa, sa2si
 
 # polynomial imports
 from sage.rings.polynomial.term_order import TermOrder
@@ -88,7 +199,8 @@
 from sage.rings.rational cimport Rational
 from sage.rings.complex_field import is_ComplexField
 from sage.rings.real_mpfr import is_RealField
-from sage.rings.integer_ring import is_IntegerRing
+from sage.rings.integer_ring import is_IntegerRing, ZZ
+from sage.rings.integer_mod_ring import is_IntegerModRing
 from sage.rings.integer_ring cimport IntegerRing_class
 from sage.rings.integer cimport Integer
 
@@ -114,11 +226,11 @@
 from sage.misc.misc import mul
 from sage.misc.sage_eval import sage_eval
 from sage.misc.latex import latex
+from sage.misc.misc_c import is_64_bit
 
 import sage.libs.pari.gen
 import polynomial_element
 
-
 # shared library loading
 cdef extern from "dlfcn.h":
     void *dlopen(char *, long)
@@ -134,21 +246,20 @@
 cdef unsigned long max_exponent_size
 
 cdef init_singular():
-    r"""
-    This initializes the \Singular library. Right now, this is a hack.
-
-    \SINGULAR has a concept of compiled extension modules similar to
-    \SAGE. For this, the compiled modules need to see the symbols from
-    the main programm. However, \SINGULAR is a shared library in this
+    """
+    This initializes the SINGULAR library. This is a hack.
+
+    SINGULAR has a concept of compiled extension modules similar to
+    Sage. For this, the compiled modules need to see the symbols from
+    the main programm. However, SINGULAR is a shared library in this
     context these symbols are not known globally. The work around so
-    far is to load the library again and to specifiy RTLD_GLOBAL.
+    far is to load the library again and to specifiy ``RTLD_GLOBAL``.
     """
     global singular_options
     global max_exponent_size
 
     cdef void *handle = NULL
 
-
     for extension in ["so", "dylib", "dll"]:
         lib = os.environ['SAGE_LOCAL']+"/lib/libsingular."+extension
         if os.path.exists(lib):
@@ -167,7 +278,7 @@
 
     dlclose(handle)
 
-    singular_options = singular_options | Sy_bit(OPT_REDSB)
+    singular_options = singular_options | Sy_bit(OPT_REDSB) | Sy_bit(OPT_INTSTRATEGY) | Sy_bit(OPT_REDTAIL) | Sy_bit(OPT_REDTHROUGH)
         
     On(SW_USE_NTL)
     On(SW_USE_NTL_GCD_0)
@@ -175,8 +286,6 @@
     On(SW_USE_EZGCD)
     Off(SW_USE_NTL_SORT)
 
-    from sage.misc.misc_c import is_64_bit
-    
     if is_64_bit:
         max_exponent_size = 1<<31-1;
     else:
@@ -185,7 +294,6 @@
  # call it
 init_singular()
 
-
 # mapping str --> SINGULAR representation
 order_dict = {"dp":ringorder_dp,
               "Dp":ringorder_Dp,
@@ -203,13 +311,18 @@
         following conditions:
 
         INPUT:
-            base_ring -- base ring (must be either GF(q), ZZ, QQ or
-                         absolute number field)
-            n -- number of variables (must be at least 1)
-            names -- names of ring variables, may be string of list/tuple
-            order -- term order (default: degrevlex)
-
-        EXAMPLES:
+
+        - ``base_ring`` - base ring (must be either GF(q), ZZ, ZZ/nZZ,
+                          QQ or absolute number field)
+
+        - ``n`` - number of variables (must be at least 1)
+
+        - ``names`` - names of ring variables, may be string of list/tuple
+        
+        - ``order`` - term order (default: ``degrevlex``)
+
+        EXAMPLES::
+
             sage: P.<x,y,z> = QQ[]
             sage: P
             Multivariate Polynomial Ring in x, y, z over Rational Field
@@ -236,6 +349,28 @@
             sage: P.<x,y> = PolynomialRing(K, 2)
             sage: 1/2*s*x^2 + 3/4*s
             (1/2*s)*x^2 + (3/4*s)
+
+            sage: P.<x,y,z> = ZZ[]; P
+            Multivariate Polynomial Ring in x, y, z over Integer Ring
+
+            sage: P.<x,y,z> = Zmod(2^10)[]; P
+            Multivariate Polynomial Ring in x, y, z over Ring of integers modulo 1024
+
+            sage: P.<x,y,z> = Zmod(3^10)[]; P
+            Multivariate Polynomial Ring in x, y, z over Ring of integers modulo 59049
+
+            sage: P.<x,y,z> = Zmod(2^100)[]; P
+            Multivariate Polynomial Ring in x, y, z over Ring of integers modulo 1267650600228229401496703205376
+
+            sage: P.<x,y,z> = Zmod(2521352)[]; P
+            Multivariate Polynomial Ring in x, y, z over Ring of integers modulo 2521352
+            sage: type(P)
+            <type 'sage.rings.polynomial.multi_polynomial_libsingular.MPolynomialRing_libsingular'>
+
+            sage: P.<x,y,z> = Zmod(25213521351515232)[]; P
+            Multivariate Polynomial Ring in x, y, z over Ring of integers modulo 25213521351515232
+            sage: type(P)
+            <class 'sage.rings.polynomial.multi_polynomial_ring.MPolynomialRing_polydict'>
         """
         cdef char **_names
         cdef char *_name
@@ -243,10 +378,14 @@
         cdef int nblcks
         cdef int offset
         cdef int characteristic
+        cdef int ringtype = 0
         cdef MPolynomialRing_libsingular k
         cdef MPolynomial_libsingular minpoly
         cdef lnumber *nmp 
 
+        cdef __mpz_struct* ringflaga
+        cdef unsigned long ringflagb
+
         is_extension = False
 
         n = int(n)
@@ -280,15 +419,21 @@
         ##         p   -p : Fp(a)           *names         FALSE             (done)
         ##         q    q : GF(q=p^n)       *names         TRUE              (todo)
 
-        if PY_TYPE_CHECK(base_ring, FiniteField_prime_modn):
+        if base_ring.is_field() and base_ring.is_finite() and base_ring.is_prime_field():
             if base_ring.characteristic() <= 2147483629:
                 characteristic = base_ring.characteristic()
             else:
                 raise TypeError, "Characteristic p must be <= 2147483629."
             
-        elif PY_TYPE_CHECK(base_ring, RationalField) or PY_TYPE_CHECK(base_ring, IntegerRing_class):
+        elif PY_TYPE_CHECK(base_ring, RationalField):
             characteristic = 0
 
+        elif PY_TYPE_CHECK(base_ring, IntegerRing_class):
+            ringflaga = <__mpz_struct*>omAlloc(sizeof(__mpz_struct))
+            mpz_init_set_ui(ringflaga, 0)
+            characteristic = 0
+            ringtype = 4 # integer ring
+
         elif PY_TYPE_CHECK(base_ring, FiniteField_generic):
             if base_ring.characteristic() <= 2147483629:
                 characteristic = -base_ring.characteristic() # note the negative characteristic
@@ -303,21 +448,57 @@
             k = MPolynomialRing_libsingular(RationalField(), 1, base_ring.variable_name(), 'lex')
             minpoly = base_ring.polynomial()(k.gen())
             is_extension = True
-        else:
-            raise NotImplementedError, "Only GF(q), QQ, ZZ and absolute number fields are supported."
+
+        elif is_IntegerModRing(base_ring):
+            ch = base_ring.characteristic()
+            if ch.is_power_of(2):
+                exponent = ch.nbits() -1
+                if is_64_bit:
+                    if exponent <= 62: ringtype = 1
+                    else: ringtype = 3
+                else:
+                    if exponent <= 30: ringtype = 1
+                    else: ringtype = 3
+                characteristic = exponent
+                ringflaga = <__mpz_struct*>omAlloc(sizeof(__mpz_struct))
+                mpz_init_set_ui(ringflaga, 2)
+                ringflagb = exponent
+
+            elif base_ring.characteristic().is_prime_power()  and ch < ZZ(2)**160:
+                F = ch.factor()
+                assert(len(F)==1)
+
+                ringtype = 3
+                ringflaga = <__mpz_struct*>omAlloc(sizeof(__mpz_struct))
+                mpz_init_set(ringflaga, (<Integer>F[0][0]).value)
+                ringflagb = F[0][1]
+                characteristic = F[0][1]
+                
+            else:
+                # normal modulus
+                try:
+                    characteristic = ch
+                except OverflowError:
+                    raise NotImplementedError("Characteristic %d too big."%ch)
+                ringtype = 2
+                ringflaga = <__mpz_struct*>omAlloc(sizeof(__mpz_struct))
+                mpz_init_set_ui(ringflaga, characteristic)
+                ringflagb = 1
+        else:
+            raise NotImplementedError("Base ring is not supported.")
 
         self._ring = <ring*>omAlloc0Bin(sip_sring_bin)
         self._ring.ch = characteristic
+        self._ring.ringtype = ringtype
         self._ring.N = n
         self._ring.names  = _names
         
         if is_extension:
             rChangeCurrRing(k._ring)
             self._ring.algring = rCopy0(k._ring)
-            rComplete(self._ring.algring,1)
+            rComplete(self._ring.algring, 1)
             self._ring.algring.pCompIndex = -1 
             self._ring.P = self._ring.algring.N
-            #self._ring.parameter = self._ring.algring.names
             self._ring.parameter = <char**>omAlloc0(sizeof(char*)*2)
             self._ring.parameter[0] = omStrDup(self._ring.algring.names[0])
 
@@ -336,7 +517,6 @@
         self._ring.block1 = <int *>omAlloc0((nblcks + 2) * sizeof(int *))
         self._ring.OrdSgn = 1
 
-
         for i from 0 <= i < nblcks:
             self._ring.order[i] = order_dict.get(order[i].singular_str(), ringorder_lp)
             self._ring.block0[i] = offset + 1
@@ -348,12 +528,16 @@
 
         self._ring.order[nblcks] = ringorder_C
 
+        if ringtype != 0:
+            self._ring.ringflaga = ringflaga
+            self._ring.ringflagb = ringflagb
+
         rComplete(self._ring, 1)
         self._ring.ShortOut = 0
 
         rChangeCurrRing(self._ring)
-        self._one_element = <MPolynomial_libsingular>co.new_MP(self,p_ISet(1, self._ring))
-        self._zero_element = <MPolynomial_libsingular>co.new_MP(self,NULL)
+        self._one_element = <MPolynomial_libsingular>new_MP(self,p_ISet(1, self._ring))
+        self._zero_element = <MPolynomial_libsingular>new_MP(self,NULL)
 
     def __dealloc__(self):
         r"""
@@ -393,14 +577,17 @@
         """
         Coerces elements to this multivariate polynomial ring.
 
-        EXAMPLES:
-            sage: P.<x,y,z> = QQ[]
-
-        We can coerce elements of self to self
+        EXAMPLES::
+
+            sage: P.<x,y,z> = QQ[]
+
+        We can coerce elements of self to self::
+
             sage: P._coerce_(x*y + 1/2)
             x*y + 1/2
 
-        We can coerce elements for a ring with the same algebraic properties
+        We can coerce elements for a ring with the same algebraic properties::
+
             sage: from sage.rings.polynomial.multi_polynomial_libsingular import MPolynomialRing_libsingular
             sage: R.<x,y,z> = MPolynomialRing_libsingular(QQ,3)
             sage: P == R
@@ -412,10 +599,13 @@
             sage: P._coerce_(x*y + 1)
             x*y + 1
 
-        We can coerce base ring elements
+        We can coerce base ring elements::
+
             sage: P._coerce_(3/2)
             3/2
 
+        and all kinds of integers::
+
             sage: P._coerce_(ZZ(1))
             1
 
@@ -433,7 +623,8 @@
             sage: P._coerce_(1/2*s)
             (1/2*s)
 
-        TESTS:
+        TESTS::
+
             sage: P.<x,y> = PolynomialRing(GF(127))
             sage: P("111111111111111111111111111111111111111111111111111111111")
             21
@@ -451,6 +642,8 @@
             
         _ring = self._ring
 
+        base_ring = self.base_ring()
+
         if(_ring != currRing): rChangeCurrRing(_ring)
 
         if PY_TYPE_CHECK(element, MPolynomial_libsingular):
@@ -459,8 +652,8 @@
             elif element.parent() == self:
                 # is this safe?
                 _p = p_Copy((<MPolynomial_libsingular>element)._poly, _ring)
-            elif self.base_ring().has_coerce_map_from(element.parent()._mpoly_base_ring(self.variable_names())):
-                return self(element._mpoly_dict_recursive(self.variable_names(), self.base_ring()))
+            elif base_ring.has_coerce_map_from(element.parent()._mpoly_base_ring(self.variable_names())):
+                return self(element._mpoly_dict_recursive(self.variable_names(), base_ring))
             else:
                 raise TypeError, "parents do not match"
 
@@ -469,58 +662,58 @@
                 _p = p_ISet(0, _ring)
                 for (m,c) in element.element().dict().iteritems():
                     mon = p_Init(_ring)
-                    p_SetCoeff(mon, co.sa2si(c, _ring), _ring)
+                    p_SetCoeff(mon, sa2si(c, _ring), _ring)
                     for pos in m.nonzero_positions():
                         assert(m[pos] <= max_exponent_size)
                         p_SetExp(mon, pos+1, m[pos], _ring)
                     p_Setm(mon, _ring)
                     _p = p_Add_q(_p, mon, _ring)
-            elif self.base_ring().has_coerce_map_from(element.parent()._mpoly_base_ring(self.variable_names())):
-                return self(element._mpoly_dict_recursive(self.variable_names(), self.base_ring()))
-            else:
-                raise TypeError, "parents do not match"
+            elif base_ring.has_coerce_map_from(element.parent()._mpoly_base_ring(self.variable_names())):
+                return self(element._mpoly_dict_recursive(self.variable_names(), base_ring))
+            else:
+                raise TypeError("Parents do not match.")
 
         elif isinstance(element, polynomial_element.Polynomial):
-            if self.base_ring().has_coerce_map_from(element.parent()._mpoly_base_ring(self.variable_names())):
-                return self(element._mpoly_dict_recursive(self.variable_names(), self.base_ring()))
-            else:
-                raise TypeError, "incompatable parents"
+            if base_ring.has_coerce_map_from(element.parent()._mpoly_base_ring(self.variable_names())):
+                return self(element._mpoly_dict_recursive(self.variable_names(), base_ring))
+            else:
+                raise TypeError("incompatable parents.")
             
         elif PY_TYPE_CHECK(element, CommutativeRingElement):
             # base ring elements
-            if  <Parent>element.parent() is self.base_ring():
+            if  <Parent>element.parent() is base_ring:
                 # shortcut for GF(p)
-                if PY_TYPE_CHECK(self.base_ring(), FiniteField_prime_modn):
-                    _p = p_ISet(int(element), _ring)
+                if PY_TYPE_CHECK(base_ring, FiniteField_prime_modn):
+                    _p = p_ISet(int(element) % _ring.ch, _ring)
                 else: 
-                    _n = co.sa2si(element,_ring)
+                    _n = sa2si(element,_ring)
                     _p = p_NSet(_n, _ring)
 
             # also accepting ZZ
             elif is_IntegerRing(element.parent()):
-                if PY_TYPE_CHECK(self.base_ring(), RationalField):
-                    _n = co.sa2si_ZZ(element,_ring)
+                if PY_TYPE_CHECK(base_ring, FiniteField_prime_modn):
+                    _p = p_ISet(int(element),_ring)
+                else:
+                    _n = sa2si(base_ring(element),_ring)
                     _p = p_NSet(_n, _ring)
-                else: # GF(p)
-                    _p = p_ISet(int(element),_ring)
             else:
                 # fall back to base ring
-                element = self.base_ring()._coerce_c(element)
-                _n = co.sa2si(element,_ring)
+                element = base_ring._coerce_c(element)
+                _n = sa2si(element,_ring)
                 _p = p_NSet(_n, _ring)
 
         # Accepting int
         elif PY_TYPE_CHECK(element, int):
-            if PY_TYPE_CHECK(self.base_ring(), RationalField):
-                _n = co.sa2si_ZZ(Integer(element),_ring)
+            if PY_TYPE_CHECK(base_ring, FiniteField_prime_modn):
+                _p = p_ISet(int(element) % _ring.ch,_ring)
+            else:
+                _n = sa2si(base_ring(element),_ring)
                 _p = p_NSet(_n, _ring)
-            else: # GF(p)
-                _p = p_ISet(int(element),_ring)
 
         # and longs
         elif PY_TYPE_CHECK(element, long):
             if PY_TYPE_CHECK(self.base_ring(), RationalField):
-                _n = co.sa2si_ZZ(Integer(element),_ring)
+                _n = sa2si(Rational(element),_ring)
                 _p = p_NSet(_n, _ring)
             else: # GF(p)
                 element = element % self.base_ring().characteristic()
@@ -528,24 +721,28 @@
         else:
             raise TypeError, "Cannot coerce element"
 
-        return co.new_MP(self,_p)
+        return new_MP(self,_p)
 
     def __call__(self, element):
-        r"""
+        """
         Construct a new element in this polynomial ring, i.e. try to
-        coerce in \var{element} if at all possible.
-
-        INPUT:
-            element -- several types are supported, see below
-        
-        EXAMPLE:
+        coerce in ``element`` if at all possible.
+
+        INPUT::
+
+        - ``element`` - several types are supported, see below
+        
+        EXAMPLE::
+
         Call supports all conversions _coerce_ supports, plus:
-        coercion from strings:
+        coercion from strings::
+
             sage: P.<x,y,z> = QQ[]
             sage: P('x+y + 1/4')
             x + y + 1/4
 
-        , coercion from \SINGULAR elements:
+        , coercion from SINGULAR elements::
+
             sage: P._singular_()
             //   characteristic : 0
             //   number of vars : 3
@@ -557,46 +754,55 @@
             sage: P(singular('x + 3/4'))
             x + 3/4
 
-        , coercion from symbolic variables:
+        , coercion from symbolic variables::
+
             sage: x,y,z = var('x,y,z')
             sage: R = QQ[x,y,z]
             sage: R(x)
             x
 
-        , coercion from 'similar' rings:
+        , coercion from 'similar' rings::
+
             sage: P.<x,y,z> = QQ[]
             sage: R.<a,b,c> = ZZ[]
             sage: P(a)
             x
 
-        , coercion from \PARI objects:
+        , coercion from PARI objects::
+
             sage: P.<x,y,z> = QQ[]
             sage: P(pari('x^2 + y'))
             x^2 + y
             sage: P(pari('x*y'))
             x*y  
 
-        , coercion from boolean polynomials:
+        , coercion from boolean polynomials::
+
             sage: B.<x,y,z> = BooleanPolynomialRing(3)
             sage: P.<x,y,z> = QQ[]
             sage: P(B.gen(0))
             x
               
-        . If everything else fails, we try to coerce to the base ring:
+        . If everything else fails, we try to coerce to the base ring::
+
             sage: R.<x,y,z> = GF(3)[]
             sage: R(1/2)
             -1
 
-        TESTS:
-        Coerce in a polydict where a coefficient reduces to 0 but isn't 0.
+        TESTS::
+
+        Coerce in a polydict where a coefficient reduces to 0 but isn't 0.::
+
             sage: R.<x,y> = QQ[]; S.<xx,yy> = GF(5)[]; S( (5*x*y + x + 17*y)._mpoly_dict_recursive() )
             xx + 2*yy
 
-        Coerce in a polynomial one of whose coefficients reduces to 0.
+        Coerce in a polynomial one of whose coefficients reduces to 0.::
+
             sage: R.<x,y> = QQ[]; S.<xx,yy> = GF(5)[]; S(5*x*y + x + 17*y)
             xx + 2*yy
 
-        Some other examples that illustrate the same coercion idea:
+        Some other examples that illustrate the same coercion idea::
+
             sage: R.<x,y> = ZZ[]
             sage: S.<xx,yy> = GF(25,'a')[]
             sage: S(5*x*y + x + 17*y)
@@ -606,7 +812,8 @@
             sage: S(5*x*y + x + 17*y)
             xx + 2*yy
 
-        See trac 5292:
+        See trac 5292::
+
             sage: R.<x> = QQ[]; S.<q,t> = QQ[]; F = FractionField(S);
             sage: x in S 
             False
@@ -666,7 +873,7 @@
 
                 while _element:
                     rChangeCurrRing(El_ring)
-                    c = co.si2sa(p_GetCoeff(_element, El_ring), El_ring, El_base)
+                    c = si2sa(p_GetCoeff(_element, El_ring), El_ring, El_base)
                     try:
                         c = K(c)
                     except TypeError, msg:
@@ -675,7 +882,7 @@
                     if c:
                         rChangeCurrRing(_ring)
                         mon = p_Init(_ring)
-                        p_SetCoeff(mon, co.sa2si(c , _ring), _ring)
+                        p_SetCoeff(mon, sa2si(c , _ring), _ring)
                         for j from 1 <= j <= _ring.N:
                             mpos = p_GetExp(_element,j,_ring)
                             if mpos:
@@ -683,7 +890,7 @@
                         p_Setm(mon, _ring)
                         _p = p_Add_q(_p, mon, _ring)
                     _element = pNext(_element)
-                return co.new_MP(self, _p)
+                return new_MP(self, _p)
 
         if PY_TYPE_CHECK(element, MPolynomial_polydict):
             if element.parent().ngens() == self.ngens():
@@ -701,13 +908,13 @@
                         p_Delete(&_p, _ring)
                         raise TypeError, msg
                     mon = p_Init(_ring)
-                    p_SetCoeff(mon, co.sa2si(c , _ring), _ring)
+                    p_SetCoeff(mon, sa2si(c , _ring), _ring)
                     for pos in m.nonzero_positions():
                         assert(m[pos] <= max_exponent_size)
                         p_SetExp(mon, pos+1, m[pos], _ring)
                     p_Setm(mon, _ring)
                     _p = p_Add_q(_p, mon, _ring)
-                return co.new_MP(self, _p)
+                return new_MP(self, _p)
 
         from sage.rings.polynomial.pbori import BooleanPolynomial
 
@@ -732,7 +939,7 @@
                     p_Delete(&_p, _ring)
                     raise TypeError, msg
                 mon = p_Init(_ring)
-                p_SetCoeff(mon, co.sa2si(c , _ring), _ring)
+                p_SetCoeff(mon, sa2si(c , _ring), _ring)
                 if len(m) != self.ngens():
                     raise TypeError, "tuple key must have same length as ngens"
                 for pos from 0 <= pos < len(m):
@@ -742,7 +949,7 @@
                 p_Setm(mon, _ring)
                 _p = p_Add_q(_p, mon, _ring)
 
-            return co.new_MP(self, _p)
+            return new_MP(self, _p)
 
         if hasattr(element,'_polynomial_'):
             # SymbolicVariable
@@ -758,12 +965,13 @@
 
         # now try calling the base ring's __call__ methods
         element = self.base_ring()(element)
-        _p = p_NSet(co.sa2si(element,_ring), _ring)
-        return co.new_MP(self,_p)
+        _p = p_NSet(sa2si(element,_ring), _ring)
+        return new_MP(self,_p)
 
     def _repr_(self):
         """
-        EXAMPLE:
+        EXAMPLE::
+
             sage: P.<x,y> = QQ[]
             sage: P # indirect doctest
             Multivariate Polynomial Ring in x, y over Rational Field
@@ -773,9 +981,10 @@
 
     def ngens(self):
         """
-        Returns the number of variables in self.
-
-        EXAMPLES:
+        Returns the number of variables in this multivariate polynomial ring.
+
+        EXAMPLES::
+
             sage: P.<x,y> = QQ[]
             sage: P.ngens()
             2
@@ -789,12 +998,15 @@
 
     def gen(self, int n=0):
         """
-        Returns the n-th generator of self.
-
-        INPUT:
-            n -- an integer >= 0
-
-        EXAMPLES:
+        Returns the ``n``-th generator of this multivariate polynomial
+        ring.
+
+        INPUT:
+
+        - ``n`` -- an integer ``>= 0``
+
+        EXAMPLES::
+
             sage: P.<x,y,z> = QQ[]
             sage: P.gen(),P.gen(1)
             (x, y)          
@@ -818,27 +1030,28 @@
         p_SetExp(_p, n+1, 1, _ring)
         p_Setm(_p, _ring);
 
-        return co.new_MP(self,_p)
+        return new_MP(self,_p)
 
     def ideal(self, *gens, **kwds):
         """
         Create an ideal in this polynomial ring.
 
         INPUT:
-            *gens -- list or tuple of generators (or several input
-                  arguments)
-            coerce -- bool (default: True); this must be a keyword
-                  argument. Only set it to False if you are certain
-                  that each generator is already in the ring.
-
-        EXAMPLE:
+ 
+        - ``*gens`` - list or tuple of generators (or several input arguments)
+
+        - ``coerce`` - bool (default: ``True``); this must be a
+          keyword argument. Only set it to ``False`` if you are certain
+          that each generator is already in the ring.
+
+        EXAMPLE::
+
             sage: P.<x,y,z> = QQ[]
             sage: sage.rings.ideal.Katsura(P)
             Ideal (x + 2*y + 2*z - 1, x^2 + 2*y^2 + 2*z^2 - x, 2*x*y + 2*y*z - y) of Multivariate Polynomial Ring in x, y, z over Rational Field
 
             sage: P.ideal([x + 2*y + 2*z-1, 2*x*y + 2*y*z-y, x^2 + 2*y^2 + 2*z^2-x])
             Ideal (x + 2*y + 2*z - 1, 2*x*y + 2*y*z - y, x^2 + 2*y^2 + 2*z^2 - x) of Multivariate Polynomial Ring in x, y, z over Rational Field
-
         """
         coerce = kwds.get('coerce', True)
         if len(gens) == 1:
@@ -861,9 +1074,11 @@
         Macaulay2 is installed.
 
         INPUT:
-            macaulay2 -- M2 interpreter (default: macaulay2_default)
-
-        EXAMPLES:
+        
+        - ``macaulay2`` - M2 interpreter (default: ``macaulay2_default``)
+
+        EXAMPLES::
+
             sage: R.<x,y> = ZZ[]
             sage: macaulay2(R)        # optional
             ZZ [x, y, MonomialOrder => GRevLex, MonomialSize => 16]
@@ -893,9 +1108,11 @@
         Set the associated M2 ring.
 
         INPUT:
-            macaulay2 -- M2 instance
-
-        EXAMPLE:
+        
+        - ``macaulay2`` - M2 instance
+
+        EXAMPLE::
+
             sage: P.<x,y> = PolynomialRing(QQ)
             sage: M2 = P._macaulay2_set_ring() # optional, requires M2
         """
@@ -917,14 +1134,16 @@
         return macaulay2.ring(base_str, gens, order)
 
     def _singular_(self, singular=singular_default):
-        r"""
-        Create a \SINGULAR (as in the computer algebra system)
+        """
+        Create a SINGULAR (as in the computer algebra system)
         representation of this polynomial ring. The result is cached.
 
         INPUT:
-            singular -- \SINGULAR interpreter (default: \code{singular_default})
-
-        EXAMPLES:
+
+        - ``singular`` - SINGULAR interpreter (default: ``singular_default``)
+
+        EXAMPLES::
+
             sage: P.<x,y,z> = QQ[]
             sage: P._singular_()
             //   characteristic : 0
@@ -970,6 +1189,8 @@
             if R is None or not (R.parent() is singular):
                 raise ValueError
             R._check_valid()
+            if not self.base_ring().is_field():
+                return R
             if self.base_ring().is_prime_field():
                 return R
             if self.base_ring().is_finite()  or (PY_TYPE_CHECK(self.base_ring(), NumberField) and self.base_ring().is_absolute()):
@@ -982,15 +1203,17 @@
             return self._singular_init_(singular)
 
     def _singular_init_(self, singular=singular_default):
-        r"""
-        Create a \SINGULAR (as in the computer algebra system)
+        """
+        Create a SINGULAR (as in the computer algebra system)
         representation of this polynomial ring. The result is NOT
         cached.
 
         INPUT:
-            singular -- SINGULAR interpreter (default: \code{singular_default})
-
-        EXAMPLES:
+
+        - ``singular`` - SINGULAR interpreter (default: ``singular_default``)
+
+        EXAMPLES::
+
             sage: P.<x,y,z> = QQ[]
             sage: P._singular_init_()
             //   characteristic : 0
@@ -1006,7 +1229,7 @@
 
             sage: w = var('w')
             sage: R.<x,y> = PolynomialRing(NumberField(w^2+1,'s'))
-            sage: R._singular_()
+            sage: singular(R)
             //   characteristic : 0
             //   1 parameter    : s
             //   minpoly        : (s^2+1)
@@ -1015,8 +1238,8 @@
             //                  : names    x y
             //        block   2 : ordering C
 
-            sage: r = PolynomialRing(GF(2**8,'a'),10,'x', order='invlex')
-            sage: r._singular_()
+            sage: R = PolynomialRing(GF(2**8,'a'),10,'x', order='invlex')
+            sage: singular(R)
             //   characteristic : 2
             //   1 parameter    : a
             //   minpoly        : (a^8+a^4+a^3+a^2+1)
@@ -1025,39 +1248,64 @@
             //                  : names    x0 x1 x2 x3 x4 x5 x6 x7 x8 x9
             //        block   2 : ordering C
 
-            sage: r = PolynomialRing(GF(127),2,'x', order='invlex')
-            sage: r._singular_()
+            sage: R = PolynomialRing(GF(127),2,'x', order='invlex')
+            sage: singular(R)
             //   characteristic : 127
             //   number of vars : 2
             //        block   1 : ordering rp
             //                  : names    x0 x1
             //        block   2 : ordering C
 
-            sage: r = PolynomialRing(QQ,2,'x', order='invlex')
-            sage: r._singular_()
+            sage: R = PolynomialRing(QQ,2,'x', order='invlex')
+            sage: singular(R)
             //   characteristic : 0
             //   number of vars : 2
             //        block   1 : ordering rp
             //                  : names    x0 x1
             //        block   2 : ordering C
 
-            sage: r = PolynomialRing(QQ,'x')
-            sage: r._singular_()
+            sage: R = PolynomialRing(QQ,'x')
+            sage: singular(R)
             //   characteristic : 0
             //   number of vars : 1
             //        block   1 : ordering lp
             //                  : names    x
             //        block   2 : ordering C
 
-            sage: r = PolynomialRing(GF(127),'x')
-            sage: r._singular_()
+            sage: R = PolynomialRing(GF(127),'x')
+            sage: singular(R)
             //   characteristic : 127
             //   number of vars : 1
             //        block   1 : ordering lp
             //                  : names    x
             //        block   2 : ordering C
 
-        TESTS:
+            sage: R = ZZ['x,y']
+            sage: singular(R)
+            //   coeff. ring is : Integers
+            //   number of vars : 2
+            //        block   1 : ordering dp
+            //                  : names    x y
+            //        block   2 : ordering C
+
+            sage: R = IntegerModRing(1024)['x,y']
+            sage: singular(R)
+            //   coeff. ring is : Z/2^10
+            //   number of vars : 2
+            //        block   1 : ordering dp
+            //                  : names    x y
+            //        block   2 : ordering C
+
+            sage: R = IntegerModRing(15)['x,y']
+            sage: singular(R)
+            //   coeff. ring is : Z/15
+            //   number of vars : 2
+            //        block   1 : ordering dp
+            //                  : names    x y
+            //        block   2 : ordering C
+            
+        TESTS::
+
             sage: P.<x> = QQ[]
             sage: P._singular_init_()
             //   characteristic : 0
@@ -1076,35 +1324,37 @@
             _vars = str(self.gens())
             order = self.term_order().singular_str()
             
-        if is_RealField(self.base_ring()):
+        base_ring = self.base_ring()
+
+        if is_RealField(base_ring):
             # singular converts to bits from base_10 in mpr_complex.cc by:
             #  size_t bits = 1 + (size_t) ((float)digits * 3.5);
-            precision = self.base_ring().precision()
+            precision = base_ring.precision()
             digits = sage.rings.arith.ceil((2*precision - 2)/7.0)
             self.__singular = singular.ring("(real,%d,0)"%digits, _vars, order=order)
 
-        elif is_ComplexField(self.base_ring()):
+        elif is_ComplexField(base_ring):
             # singular converts to bits from base_10 in mpr_complex.cc by:
             #  size_t bits = 1 + (size_t) ((float)digits * 3.5);
-            precision = self.base_ring().precision()
+            precision = base_ring.precision()
             digits = sage.rings.arith.ceil((2*precision - 2)/7.0)
             self.__singular = singular.ring("(complex,%d,0,I)"%digits, _vars,  order=order)
 
-        elif self.base_ring().is_prime_field():
+        elif base_ring.is_prime_field():
             self.__singular = singular.ring(self.characteristic(), _vars, order=order)
         
-        elif self.base_ring().is_finite(): #must be extension field
-            gen = str(self.base_ring().gen())
+        elif base_ring.is_field() and base_ring.is_finite(): #must be extension field
+            gen = str(base_ring.gen())
             r = singular.ring( "(%s,%s)"%(self.characteristic(),gen), _vars, order=order)
-            self.__minpoly = (str(self.base_ring().modulus()).replace("x",gen)).replace(" ","")
+            self.__minpoly = (str(base_ring.modulus()).replace("x",gen)).replace(" ","")
             if  singular.eval('minpoly') != "(" + self.__minpoly + ")":
                 singular.eval("minpoly=%s"%(self.__minpoly) )
                 self.__minpoly = singular.eval('minpoly')[1:-1]
             self.__singular = r
 
-        elif PY_TYPE_CHECK(self.base_ring(), NumberField) and self.base_ring().is_absolute():
-            gen = str(self.base_ring().gen())
-            poly = self.base_ring().polynomial()
+        elif PY_TYPE_CHECK(base_ring, NumberField) and base_ring.is_absolute():
+            gen = str(base_ring.gen())
+            poly = base_ring.polynomial()
             poly_gen = str(poly.parent().gen())
             poly_str = str(poly).replace(poly_gen,gen)
             r = singular.ring( "(%s,%s)"%(self.characteristic(),gen), _vars, order=order, check=False)
@@ -1114,13 +1364,24 @@
                 self.__minpoly = singular.eval('minpoly')[1:-1]
             self.__singular = r
 
+        elif is_IntegerRing(base_ring):
+            self.__singular = singular.ring("(integer)", _vars, order=order)
+
+        elif is_IntegerModRing(base_ring):
+            ch = base_ring.characteristic()
+            if ch.is_power_of(2):
+                exp = ch.nbits() -1
+                self.__singular = singular.ring("(integer,2,%d)"%(exp,), _vars, order=order, check=False)
+            else:
+                self.__singular = singular.ring("(integer,%d)"%(ch,), _vars, order=order, check=False)
+
         else:    
             raise TypeError, "no conversion to a Singular ring defined"
 
         return self.__singular
 
     def __hash__(self):
-        r"""
+        """
         Return a hash for this ring, that is, a hash of the string
         representation of this polynomial ring.
 
@@ -1135,13 +1396,14 @@
     def __richcmp__(left, right, int op):
         r"""
         Multivariate polynomial rings are said to be equal if:
-        \begin{itemize}
-        \item their base rings match,
-        \item their generator names match and
-        \item their term orderings match.
-        \end{itemize}
-
-        EXAMPLES:
+        
+        - their base rings match,
+        - their generator names match and
+        - their term orderings match.
+
+
+        EXAMPLES::
+
             sage: P.<x,y,z> = QQ[]
             sage: R.<x,y,z> = QQ[]
             sage: P == R
@@ -1207,7 +1469,8 @@
         """
         This is used by the variable names context manager.
 
-        EXAMPLES:
+        EXAMPLES::
+
             sage: R.<x,y> = QQ[] # indirect doctest
             sage: with localvars(R, 'z,w'):
             ...       print x^3 + y^3 - x*y
@@ -1245,15 +1508,19 @@
 
     def monomial_quotient(self, MPolynomial_libsingular f, MPolynomial_libsingular g, coeff=False):
         r"""
-        Return f/g, where both f and g are treated as
-        monomials. Coefficients are ignored by default.
-
-        INPUT:
-            f -- monomial
-            g -- monomial
-            coeff -- divide coefficents as well (default: False)
-
-        EXAMPLE:
+        Return ``f/g``, where both ``f`` and`` ``g`` are treated as
+        monomials. 
+
+        Coefficients are ignored by default.
+
+        INPUT:
+
+        - ``f`` - monomial
+        - ``g`` - monomial
+        - ``coeff`` - divide coefficents as well (default: ``False``)
+
+        EXAMPLE::
+
             sage: P.<x,y,z> = QQ[]
             sage: P.monomial_quotient(3/2*x*y,x)
             y
@@ -1261,7 +1528,7 @@
             sage: P.monomial_quotient(3/2*x*y,x,coeff=True)
             3/2*y
 
-        Note, that \ZZ behaves different if \code{coeff=True}
+        Note, that `\ZZ` behaves different if ``coeff=True``::
 
             sage: P.monomial_quotient(2*x,3*x)
             1
@@ -1272,7 +1539,8 @@
             ...
             ArithmeticError: Cannot divide these coefficents.
 
-        TESTS:
+        TESTS::
+
             sage: R.<x,y,z> = QQ[]
             sage: P.<x,y,z> = QQ[]
             sage: P.monomial_quotient(x*y,x)
@@ -1299,10 +1567,11 @@
             sage: P.monomial_quotient(x,P(1))
             x
 
-        NOTE: Assumes that the head term of f is a multiple of the
-        head term of g and return the multiplicant m. If this rule is
-        violated, funny things may happen.
-
+        .. warning::
+
+           Assumes that the head term of f is a multiple of the head
+           term of g and return the multiplicant m. If this rule is
+           violated, funny things may happen.
         """
         cdef poly *res
         cdef ring *r = self._ring
@@ -1319,44 +1588,46 @@
             return self._zero_element
         if not g._poly:
             raise ZeroDivisionError
-        
+
         res = pDivide(f._poly,g._poly)
         if coeff:
-            n = n_Div( p_GetCoeff(f._poly, r) , p_GetCoeff(g._poly, r), r)
-            if not self._base.is_field():
-                denom = nlGetDenom(n, r)
-                if not n_IsOne(denom, r):
-                    nlDelete(&denom, r)
-                    raise ArithmeticError, "Cannot divide these coefficents."
-                nlDelete(&denom, r)
-            p_SetCoeff(res, n, r)
-        else:
-            p_SetCoeff(res, n_Init(1, r), r)
-        return co.new_MP(self, res)
+            if r.ringtype == 0 or r.cf.nDivBy(p_GetCoeff(f._poly, r), p_GetCoeff(g._poly, r)):
+                n = r.cf.nDiv( p_GetCoeff(f._poly, r) , p_GetCoeff(g._poly, r))
+                p_SetCoeff0(res, n, r)
+            else:
+                raise ArithmeticError("Cannot divide these coefficents.")
+        else:
+            p_SetCoeff0(res, n_Init(1, r), r)
+        return new_MP(self, res)
     
     def monomial_divides(self, MPolynomial_libsingular a, MPolynomial_libsingular b):
-        r"""
-        Return \code{False} if a does not divide b and \code{True}
-        otherwise. Coefficients are ignored.
-        
-        INPUT:
-            a -- monomial
-            b -- monomial
-
-        EXAMPLES:
+        """
+        Return ``False`` if a does not divide b and ``True``
+        otherwise. 
+
+        Coefficients are ignored.
+        
+        INPUT:
+
+        - ``a`` -- monomial
+
+        - ``b`` -- monomial
+
+        EXAMPLES::
+
             sage: P.<x,y,z> = QQ[]
             sage: P.monomial_divides(x*y*z, x^3*y^2*z^4)
             True
             sage: P.monomial_divides(x^3*y^2*z^4, x*y*z)
             False
 
-        TESTS:
+        TESTS::
+
             sage: P.<x,y,z> = QQ[]
             sage: P.monomial_divides(P(1), P(0))
             True
             sage: P.monomial_divides(P(1), x)
             True
-
         """
         cdef poly *_a
         cdef poly *_b
@@ -1384,15 +1655,19 @@
         LCM for monomials. Coefficients are ignored.
         
         INPUT:
-            f -- monomial
-            g -- monomial
-
-        EXAMPLE:
+
+        - ``f`` - monomial
+        
+        - ``g`` - monomial
+
+        EXAMPLE::
+
             sage: P.<x,y,z> = QQ[]
             sage: P.monomial_lcm(3/2*x*y,x)
             x*y
 
-        TESTS:
+        TESTS::
+
             sage: R.<x,y,z> = QQ[]
             sage: P.<x,y,z> = QQ[]
             sage: P.monomial_lcm(x*y,R.gen())
@@ -1403,7 +1678,6 @@
 
             sage: P.monomial_lcm(x,P(1))
             x
-
         """
         cdef poly *m = p_ISet(1,self._ring)
         
@@ -1424,31 +1698,34 @@
         
         pLcm(f._poly, g._poly, m)
         p_Setm(m, self._ring)
-        return co.new_MP(self,m)
+        return new_MP(self,m)
         
     def monomial_reduce(self, MPolynomial_libsingular f, G):
-        r"""
-        Try to find a \code{g} in \code{G} where \code{g.lm()} divides
-        \code{f}. If found \code{(flt,g)} is returned, (0,0)
-        otherwise, where \code{flt} is \code{f/g.lm()}.
-
-        It is assumed that \code{G} is iterable and contains \emph{ONLY}
-        elements in this polynomial ring. 
+        """
+        Try to find a ``g`` in ``G`` where ``g.lm()`` divides
+        ``f``. If found ``(flt,g)`` is returned, ``(0,0)`` otherwise,
+        where ``flt`` is ``f/g.lm()``.
+
+        It is assumed that ``G`` is iterable and contains *only*
+        elements in this polynomial ring.
 
         Coefficents are ignored.
         
         INPUT:
-            f -- monomial
-            G -- list/set of mpolynomials
-            
-        EXAMPLES:
+
+        - ``f`` - monomial
+        - ``G`` - list/set of mpolynomials
+            
+        EXAMPLES::
+
             sage: P.<x,y,z> = QQ[]
             sage: f = x*y^2
             sage: G = [ 3/2*x^3 + y^2 + 1/2, 1/4*x*y + 2/7, 1/2  ]
             sage: P.monomial_reduce(f,G)
             (y, 1/4*x*y + 2/7)
 
-        TESTS:
+        TESTS::
+
             sage: P.<x,y,z> = QQ[]
             sage: f = x*y^2
             sage: G = [ 3/2*x^3 + y^2 + 1/2, 1/4*x*y + 2/7, 1/2  ]
@@ -1458,7 +1735,6 @@
 
             sage: P.monomial_reduce(f,[P(0)])
             (0, 0)
-            
         """
         cdef poly *m = f._poly
         cdef ring *r = self._ring
@@ -1474,21 +1750,23 @@
                 flt = pDivide(f._poly, (<MPolynomial_libsingular>g)._poly)
                 #p_SetCoeff(flt, n_Div( p_GetCoeff(f._poly, r) , p_GetCoeff((<MPolynomial_libsingular>g)._poly, r), r), r)
                 p_SetCoeff(flt, n_Init(1, r), r)
-                return co.new_MP(self,flt), g
+                return new_MP(self,flt), g
         return self._zero_element,self._zero_element
 
     def monomial_pairwise_prime(self, MPolynomial_libsingular g, MPolynomial_libsingular h):
-        r"""
-        Return True if \code{h} and \code{g} are pairwise prime. Both
+        """
+        Return ``True`` if ``h`` and ``g`` are pairwise prime. Both
         are treated as monomials.
 
         Coefficients are ignored.
 
         INPUT:
-            h -- monomial
-            g -- monomial
-
-        EXAMPLES:
+
+        - ``h`` - monomial
+        - ``g`` - monomial
+
+        EXAMPLES::
+
             sage: P.<x,y,z> = QQ[]
             sage: P.monomial_pairwise_prime(x^2*z^3, y^4)
             True
@@ -1496,7 +1774,8 @@
             sage: P.monomial_pairwise_prime(1/2*x^3*y^2, 3/4*y^3)
             False
 
-        TESTS:
+        TESTS::
+
             sage: Q.<x,y,z> = QQ[]
             sage: P.<x,y,z> = QQ[]
             sage: P.monomial_pairwise_prime(x^2*z^3, Q('y^4'))
@@ -1507,8 +1786,6 @@
 
             sage: P.monomial_pairwise_prime(P(1/2),x)
             False
-
-        
         """
         cdef int i
         cdef ring *r
@@ -1539,19 +1816,21 @@
         return True
 
     def monomial_all_divisors(self, MPolynomial_libsingular t):
-        r"""
-        Return a list of all monomials that divide \code{t}. 
+        """
+        Return a list of all monomials that divide ``t``.
 
         Coefficients are ignored.
           
         INPUT:
-            t -- a monomial
+
+        - ``t`` - a monomial
   
         OUTPUT:
             a list of monomials
 
 
-        EXAMPLE:
+        EXAMPLE::
+
             sage: P.<x,y,z> = QQ[]
             sage: P.monomial_all_divisors(x^2*z^3)
             [x, x^2, z, x*z, x^2*z, z^2, x*z^2, x^2*z^2, z^3, x*z^3, x^2*z^3]
@@ -1569,7 +1848,7 @@
          
         while not p_ExpVectorEqual(tempvector, maxvector, _ring):
           tempvector = addwithcarry(tempvector, maxvector, pos, _ring)
-          M.append(co.new_MP(self, p_Copy(tempvector,_ring)))
+          M.append(new_MP(self, p_Copy(tempvector,_ring)))
         return M
 
 cdef inline int polyLengthBounded(poly *p, int bound):
@@ -1581,10 +1860,11 @@
     return count
     
 def unpickle_MPolynomialRing_libsingular(base_ring, names, term_order):
-    r"""
-    inverse function for \code{MPolynomialRing_libsingular.__reduce__}
-
-    EXAMPLE:
+    """
+    inverse function for ``MPolynomialRing_libsingular.__reduce__``
+
+    EXAMPLE::
+
         sage: P.<x,y> = PolynomialRing(QQ)
         sage: loads(dumps(P)) == P # indirect doctest
         True
@@ -1597,16 +1877,6 @@
 
     return MPolynomialRing_libsingular(base_ring, len(names), names, term_order)
 
-cdef inline MPolynomial_libsingular new_MP(MPolynomialRing_libsingular parent, poly *juice):
-    """
-    Construct a new MPolynomial_libsingular element
-    """
-    cdef MPolynomial_libsingular p
-    p = PY_NEW(MPolynomial_libsingular)
-    p._parent = <ParentWithBase>parent
-    p._poly = juice
-    return p
-
 cdef class MPolynomial_libsingular(sage.rings.polynomial.multi_polynomial.MPolynomial):
     """
     A multivariate polynomial implemented using libSINGULAR.
@@ -1615,7 +1885,8 @@
         """
         Construct a zero element in parent.
 
-        EXAMPLE:
+        EXAMPLE::
+
             sage: from sage.rings.polynomial.multi_polynomial_libsingular import MPolynomial_libsingular
             sage: P = PolynomialRing(GF(32003),3,'x')
             sage: MPolynomial_libsingular(P)
@@ -1630,17 +1901,19 @@
             p_Delete(&self._poly, (<MPolynomialRing_libsingular>self._parent)._ring)
 
     def __call__(self, *x, **kwds):
-        r"""
-        Evaluate this multi-variate polynomial at $x$, where $x$ is
-        either the tuple of values to substitute in, or one can use
-        functional notation $f(a_0,a_1,a_2, \ldots)$ to evaluate $f$
-        with the ith variable replaced by $a_i$.
-
-        INPUT:
-            x -- a list of elements in self.parent()
-            or **kwds -- a dictionary of variable-name:value pairs.
-
-        EXAMPLES:
+        """
+        Evaluate this multi-variate polynomial at ``x``, where ``x``
+        is either the tuple of values to substitute in, or one can use
+        functional notation ``f(a_0,a_1,a_2, \ldots)`` to evaluate
+        ``f`` with the ith variable replaced by ``a_i``.
+
+        INPUT:
+        
+        - ``x`` - a list of elements in ``self.parent()``
+        - or ``**kwds`` - a dictionary of ``variable-name:value`` pairs.
+
+        EXAMPLES::
+
             sage: P.<x,y,z> = QQ[]
             sage: f = 3/2*x^2*y + 1/7 * y^2 + 13/27
             sage: f(0,0,0)
@@ -1657,7 +1930,8 @@
             sage: f(1,2,3).parent()
             Rational Field
 
-        TESTS:
+        TESTS::
+
             sage: P.<x,y,z> = QQ[]
             sage: P(0)(1,2,3)
             0
@@ -1719,23 +1993,24 @@
         
         if p_IsConstant(res, _ring) and all([e in parent._base for e in x]):
             # I am sure there must be a better way to do this...
-            return parent._base(co.new_MP(parent, res))
-        else:
-            return co.new_MP(parent, res)
+            return parent._base(new_MP(parent, res))
+        else:
+            return new_MP(parent, res)
 
     # you may have to replicate this boilerplate code in derived classes if you override 
     # __richcmp__.  The python documentation at  http://docs.python.org/api/type-structs.html 
     # explains how __richcmp__, __hash__, and __cmp__ are tied together.
+
     def __hash__(self):
-        r"""
+        """
         This hash incorporates the variable name in an effort to
         respect the obvious inclusions into multi-variable polynomial
         rings.
 
-        The tuple algorithm is borrowed from
-        \url{http://effbot.org/zone/python-hash.htm}.
-
-        EXAMPLES:
+        The tuple algorithm is borrowed from http://effbot.org/zone/python-hash.htm.
+
+        EXAMPLES::
+
             sage: R.<x>=QQ[]
             sage: S.<x,y>=QQ[]
             sage: hash(S(1/2))==hash(1/2)  # respect inclusions of the rationals
@@ -1754,7 +2029,8 @@
         Compare left and right and return -1, 0, and 1 for <,==, and >
         respectively.
 
-        EXAMPLES:
+        EXAMPLES::
+
             sage: P.<x,y,z> = PolynomialRing(QQ,order='degrevlex')
             sage: x == x
             True
@@ -1767,7 +2043,8 @@
             sage: (2/3*x^2 + 1/2*y + 3) > (2/3*x^2 + 1/4*y + 10)
             True
 
-        TESTS:
+        TESTS::
+
             sage: P.<x,y,z> = PolynomialRing(QQ, order='degrevlex')
             sage: x > P(0)
             True
@@ -1836,7 +2113,7 @@
             if ret==0:
                 h = n_Sub(p_GetCoeff(p, r),p_GetCoeff(q, r), r)
                 # compare coeffs 
-                ret = -1+n_IsZero(h, r)+2*n_GreaterZero(h, r) # -1: <, 0:==, 1: > 
+                ret = -1+r.cf.nIsZero(h)+2*r.cf.nGreaterZero(h) # -1: <, 0:==, 1: > 
                 n_Delete(&h, r)
             p = pNext(p)
             q = pNext(q)
@@ -1873,7 +2150,7 @@
 
         _p= p_Add_q(_l, _r, _ring)
 
-        return co.new_MP((<MPolynomialRing_libsingular>left._parent),_p)
+        return new_MP((<MPolynomialRing_libsingular>left._parent),_p)
 
     cpdef ModuleElement _iadd_( left, ModuleElement right):
         """
@@ -1925,7 +2202,7 @@
         if(_ring != currRing): rChangeCurrRing(_ring)
         _p= p_Add_q(_l, p_Neg(_r, _ring), _ring)
 
-        return co.new_MP((<MPolynomialRing_libsingular>left._parent),_p)
+        return new_MP((<MPolynomialRing_libsingular>left._parent),_p)
 
     cpdef ModuleElement _isub_( left, ModuleElement right):
         """
@@ -1973,11 +2250,11 @@
         if not left:
             return (<MPolynomialRing_libsingular>self._parent)._zero_element
         
-        _n = co.sa2si(left,_ring)
+        _n = sa2si(left,_ring)
 
         _p = pp_Mult_nn(self._poly,_n,_ring)
         n_Delete(&_n, _ring)
-        return co.new_MP((<MPolynomialRing_libsingular>self._parent),_p)
+        return new_MP((<MPolynomialRing_libsingular>self._parent),_p)
         
     cpdef ModuleElement _lmul_(self, RingElement right):
         # all currently implemented rings are commutative
@@ -2013,7 +2290,7 @@
             raise OverflowError("Exponent overflow.")
 
         _p = pp_Mult_qq(left._poly, (<MPolynomial_libsingular>right)._poly, _ring)
-        return co.new_MP(left._parent,_p)
+        return new_MP(left._parent,_p)
 
     cpdef RingElement  _imul_(left, RingElement right):
         # all currently implemented rings are commutative
@@ -2047,7 +2324,8 @@
         """
         Divide left by right
 
-        EXAMPLES:
+        EXAMPLES::
+
             sage: R.<x,y>=PolynomialRing(QQ,2)
             sage: f = (x + y)/3
             sage: f.parent()
@@ -2055,7 +2333,7 @@
 
         Note that / is still a constructor for elements of the
         fraction field in all cases as long as both arguments have the
-        same parent and right is not constant.
+        same parent and right is not constant.::
 
             sage: R.<x,y>=PolynomialRing(QQ,2)
             sage: f = x^3 + y
@@ -2065,8 +2343,8 @@
             sage: h.parent()
             Fraction Field of Multivariate Polynomial Ring in x, y over Rational Field
 
-        If we divide over $\ZZ$ the result is the same as 
-        multiplying by 1/3 (i.e. base extension).
+        If we divide over `\ZZ` the result is the same as multiplying
+        by 1/3 (i.e. base extension).::
         
             sage: R.<x,y> = ZZ[]
             sage: f = (x + y)/3      
@@ -2076,20 +2354,33 @@
             sage: f.parent()
             Multivariate Polynomial Ring in x, y over Rational Field
             
-        But we get a true fraction field if the denominator is not in 
-        the fration field of the basering. 
+        But we get a true fraction field if the denominator is not in
+        the fration field of the basering.""
         
             sage: f = x/y
             sage: f.parent()
             Fraction Field of Multivariate Polynomial Ring in x, y over Integer Ring
 
-        TESTS:
+        Division will fail for non-integral domains::
+
+            sage: P.<x,y> = Zmod(1024)[]
+            sage: x/P(3)
+            Traceback (most recent call last):
+            ...
+            TypeError: self must be an integral domain.
+
+            sage: x/3
+            Traceback (most recent call last):
+            ...
+            TypeError: unsupported operand parent(s) for '/': 'Multivariate Polynomial Ring in x, y over Ring of integers modulo 1024' and 'Integer Ring'
+
+        TESTS::
+
             sage: R.<x,y>=PolynomialRing(QQ,2)
             sage: x/0
             Traceback (most recent call last):
             ...
             ZeroDivisionError: rational division by zero
-
         """
         cdef poly *p 
         cdef ring *r
@@ -2105,19 +2396,20 @@
                 n = nInvers(n)
                 p = pp_Mult_nn(left._poly, n,  r)
                 n_Delete(&n,r)
-                return co.new_MP(left._parent, p)
+                return new_MP(left._parent, p)
             else:
                 return left.change_ring(left.base_ring().fraction_field())/right
         else:
             return (<MPolynomialRing_libsingular>left._parent).fraction_field()(left,right)
 
     def __pow__(MPolynomial_libsingular self, exp, ignored):
-        r"""
-        Return \code{self**(exp)}.
+        """
+        Return ``self**(exp)``.
 
         The exponent must be an integer.
 
-        EXAMPLE:
+        EXAMPLE::
+
             sage: R.<x,y> = PolynomialRing(QQ,2)
             sage: f = x^3 + y
             sage: f^2
@@ -2175,11 +2467,11 @@
         _p = pPower( p_Copy(self._poly,_ring),_exp)
         if count >= 15 or _exp > 15:
             _sig_off
-        return co.new_MP((<MPolynomialRing_libsingular>self._parent),_p)
+        return new_MP((<MPolynomialRing_libsingular>self._parent),_p)
 
     def __neg__(self):
-        r"""
-        Return -\code{self}.
+        """
+        Return ``-self``.
 
         EXAMPLE:
             sage: R.<x,y>=PolynomialRing(QQ,2)
@@ -2191,7 +2483,7 @@
         _ring = (<MPolynomialRing_libsingular>self._parent)._ring
         if(_ring != currRing): rChangeCurrRing(_ring)
 
-        return co.new_MP((<MPolynomialRing_libsingular>self._parent),\
+        return new_MP((<MPolynomialRing_libsingular>self._parent),\
                                            p_Neg(p_Copy(self._poly,_ring),_ring))
 
     def _repr_(self):
@@ -2211,11 +2503,12 @@
         return s
 
     cpdef _repr_short_(self):
-        r"""
+        """
         This is a faster but less pretty way to print polynomials. If
-        available it uses the short \SINGULAR notation.
-        
-        EXAMPLES:
+        available it uses the short SINGULAR notation.
+        
+        EXAMPLES::
+
             sage: R.<x,y>=PolynomialRing(QQ,2)
             sage: f = x^3 + y
             sage: f._repr_short_()
@@ -2233,15 +2526,14 @@
                                            
     
     def _latex_(self):
-        r"""
-        Return a polynomial \LaTeX representation of this polynomial.
+        """
+        Return a polynomial LaTeX representation of this polynomial.
 
         EXAMPLE:
             sage: P.<x,y,z> = QQ[]
             sage: f = - 1*x^2*y - 25/27 * y^3 - z^2
             sage: latex(f)
             - x^{2} y - \frac{25}{27} y^{3} - z^{2}
-    
         """
         cdef ring *_ring = (<MPolynomialRing_libsingular>self._parent)._ring
         cdef int n = _ring.N
@@ -2265,7 +2557,7 @@
             multi = multi.lstrip().rstrip()
 
             # Next determine coefficient of multinomial
-            c =  co.si2sa( p_GetCoeff(p, _ring), _ring, base) 
+            c =  si2sa( p_GetCoeff(p, _ring), _ring, base) 
             if len(multi) == 0:
                 multi = latex(c)
             elif c != 1:
@@ -2295,16 +2587,16 @@
         return poly
     
     def _repr_with_changed_varnames(self, varnames):
-        r"""
+        """
         Return string representing this polynomial but change the
-        variable names to \var{varnames}.
-
-        EXAMPLE:
+        variable names to ``varnames``.
+
+        EXAMPLE::
+
             sage: P.<x,y,z> = QQ[]
             sage: f = - 1*x^2*y - 25/27 * y^3 - z^2
             sage: print f._repr_with_changed_varnames(['FOO', 'BAR', 'FOOBAR'])
             -FOO^2*BAR - 25/27*BAR^3 - FOOBAR^2
-
         """
         cdef ring *_ring = (<MPolynomialRing_libsingular>self._parent)._ring
         cdef char **_names
@@ -2333,20 +2625,22 @@
         return s
             
     def degree(self, MPolynomial_libsingular x=None):
-        r"""
-        Return the maximal degree of this polynomial in \var{x}, where
-        \var{x} must be one of the generators for the parent of this
+        """
+        Return the maximal degree of this polynomial in ``x``, where
+        ``x`` must be one of the generators for the parent of this
         polynomial.
 
         INPUT:
-            x -- multivariate polynmial (a generator of the parent of self)
-                 If x is not specified (or is None), return the total degree,
-                 which is the maximum degree of any monomial.
+
+        - ``x`` - multivariate polynmial (a generator of the parent of
+          self) If x is not specified (or is ``None``), return the total
+          degree, which is the maximum degree of any monomial.
 
         OUTPUT:
             integer
         
-        EXAMPLE:
+        EXAMPLE::
+
             sage: R.<x, y> = QQ[]
             sage: f = y^2 - x^9 - x
             sage: f.degree(x)
@@ -2358,7 +2652,8 @@
             sage: (y^10*x - 7*x^2*y^5 + 5*x^3).degree(y)
             10
 
-        TESTS:
+        TESTS::
+
             sage: P.<x, y> = QQ[]
             sage: P(0).degree(x)
             -1
@@ -2379,7 +2674,7 @@
 
         # TODO: we can do this faster
         if not x in self._parent.gens():
-            raise TypeError, "x must be one of the generators of the parent."
+            raise TypeError("x must be one of the generators of the parent.")
         for i from 1 <= i <= r.N:
             if p_GetExp(x._poly, i, r):
                 break
@@ -2393,10 +2688,11 @@
 
     def total_degree(self):
         """
-        Return the total degree of self, which is the maximum degree
-        of all monomials in self.
-
-        EXAMPLES:
+        Return the total degree of ``self``, which is the maximum degree
+        of all monomials in ``self``.
+
+        EXAMPLES::
+
             sage: R.<x,y,z> = QQ[]
             sage: f=2*x*y^3*z^2
             sage: f.total_degree()
@@ -2417,7 +2713,8 @@
             sage: f.total_degree()
             10
 
-        TESTS:
+        TESTS::
+
             sage: R.<x,y,z> = QQ[]
             sage: R(0).total_degree()
             -1
@@ -2433,12 +2730,13 @@
         return pLDeg(p,&l,r)
 
     def degrees(self):
-        r""" 
+        """ 
         Returns a tuple with the maximal degree of each variable in
         this polynomial.  The list of degrees is ordered by the order
         of the generators.
 
-        EXAMPLE:
+        EXAMPLE::
+
             sage: R.<y0,y1,y2> = PolynomialRing(QQ,3)
             sage: q = 3*y0*y1*y1*y2; q 
             3*y0*y1^2*y2 
@@ -2459,28 +2757,33 @@
 
     def coefficient(self, degrees):
         """
-        Return the coefficient of the variables with the degrees 
-        specified in the python dictionary \code{degrees}.  Mathematically, 
-        this is the coefficient in the base ring adjoined by the variables 
-        of this ring not listed in \code{degrees}.  However, the result 
-        has the same parent as this polynomial.
-
-        This function contrasts with the function \code{monomial_coefficient} 
-        which returns the coefficient in the base ring of a monomial.
-
-        INPUT:
-            degrees -- Can be any of:
-                -- a dictionary of degree restrictions
-                -- a list of degree restrictions (with None in the unrestricted variables)
-                -- a monomial (very fast, but not as flexible)
-
-        OUTPUT:
-            element of the parent of self
-
-        SEE ALSO:
-            For coefficients of specific monomials, look at \ref{monomial_coefficient}.
-
-        EXAMPLES:
+        Return the coefficient of the variables with the degrees
+        specified in the python dictionary ``degrees``.
+        Mathematically, this is the coefficient in the base ring
+        adjoined by the variables of this ring not listed in
+        ``degrees``.  However, the result has the same parent as this
+        polynomial.
+
+        This function contrasts with the function
+        ``monomial_coefficient`` which returns the coefficient in the
+        base ring of a monomial.
+
+        INPUT:
+
+        - ``degrees`` - Can be any of:
+                - a dictionary of degree restrictions
+                - a list of degree restrictions (with None in the unrestricted variables)
+                - a monomial (very fast, but not as flexible)
+
+        OUTPUT:
+            element of the parent of this element.
+
+        .. note::
+           
+           For coefficients of specific monomials, look at :meth:`monomial_coefficient`.
+
+        EXAMPLES::
+
             sage: R.<x,y> = QQ[]
             sage: f=x*y+y+5
             sage: f.coefficient({x:0,y:1})
@@ -2494,8 +2797,12 @@
             y^2 + y + 1
             sage: f.coefficient(x)
             y^2 + y + 1
-            sage: # Be aware that this may not be what you think!
-            sage: # The physical appearance of the variable x is deceiving -- particularly if the exponent would be a variable.
+           
+
+        Be aware that this may not be what you think! The physical
+        appearance of the variable x is deceiving -- particularly if
+        the exponent would be a variable.::
+
             sage: f.coefficient(x^0) # outputs the full polynomial
             x^2*y^2 + x^2*y + x*y^2 + x^2 + x*y + y^2 + x + y + 1
             sage: R.<x,y> = GF(389)[]
@@ -2506,7 +2813,8 @@
             Multivariate Polynomial Ring in x, y over Finite Field of size 389
 
         AUTHOR:
-            -- Joel B. Mohler (2007.10.31)
+
+        - Joel B. Mohler (2007.10.31)
         """
         cdef poly *_degrees = <poly*>0
         cdef poly *p = self._poly
@@ -2563,27 +2871,30 @@
 
         sage_free(exps)
 
-        return co.new_MP(self.parent(),newp)
+        return new_MP(self.parent(),newp)
 
     def monomial_coefficient(self, MPolynomial_libsingular mon):
         """
-        Return the coefficient in the base ring of the monomial mon in self, where mon
-        must have the same parent as self.
-
-        This function contrasts with the function \code{coefficient} 
-        which returns the coefficient of a monomial viewing this polynomial in a 
-        polynomial ring over a base ring having fewer variables.
-
-        INPUT:
-            mon -- a monomial
+        Return the coefficient in the base ring of the monomial mon in
+        ``self``, where mon must have the same parent as self.
+
+        This function contrasts with the function ``coefficient``
+        which returns the coefficient of a monomial viewing this
+        polynomial in a polynomial ring over a base ring having fewer
+        variables.
+
+        INPUT:
+
+        - ``mon`` - a monomial
 
         OUTPUT:
             coefficient in base ring
 
         SEE ALSO:
-            For coefficients in a base ring of fewer variables, look at \ref{coefficient}.
-
-        EXAMPLES:
+            For coefficients in a base ring of fewer variables, look at ``coefficient``.
+
+        EXAMPLES::
+
             sage: P.<x,y> = QQ[]
 
             The parent of the return is a member of the base ring.
@@ -2608,11 +2919,11 @@
         cdef ring *r = (<MPolynomialRing_libsingular>self._parent)._ring
 
         if not mon._parent is self._parent:
-            raise TypeError, "mon must have same parent as self"
+            raise TypeError("mon must have same parent as self.")
         
         while(p):
             if p_ExpVectorEqual(p, m, r) == 1:
-                return co.si2sa(p_GetCoeff(p, r), r, (<MPolynomialRing_libsingular>self._parent)._base)
+                return si2sa(p_GetCoeff(p, r), r, (<MPolynomialRing_libsingular>self._parent)._base)
             p = pNext(p)
 
         return (<MPolynomialRing_libsingular>self._parent)._base._zero_element
@@ -2621,9 +2932,10 @@
         """
         Return a dictionary representing self. This dictionary is in
         the same format as the generic MPolynomial: The dictionary
-        consists of ETuple:coefficient pairs.
-
-        EXAMPLE:
+        consists of ``ETuple:coefficient`` pairs.
+
+        EXAMPLE::
+
             sage: R.<x,y,z> = QQ[]
             sage: f=2*x*y^3*z^2 + 1/7*x^2 + 2/3
             sage: f.dict()
@@ -2645,14 +2957,14 @@
                 if n!=0:
                     d[v-1] = n 
                 
-            pd[ETuple(d,r.N)] = co.si2sa(p_GetCoeff(p, r), r, base)
+            pd[ETuple(d,r.N)] = si2sa(p_GetCoeff(p, r), r, base)
 
             p = pNext(p)
         return pd
 
     cdef long _hash_c(self):
-        r"""
-        See \code{self.__hash__}
+        """
+        See ``self.__hash__``
         """
         cdef poly *p
         cdef ring *r
@@ -2667,7 +2979,7 @@
         var_name_hash = [hash(vn) for vn in self._parent.variable_names()]
         cdef long c_hash
         while p:
-            c_hash = hash(co.si2sa(p_GetCoeff(p, r), r, base))
+            c_hash = hash(si2sa(p_GetCoeff(p, r), r, base))
             if c_hash != 0: # this is always going to be true, because we are sparse (correct?)
                 # Hash (self[i], gen_a, exp_a, gen_b, exp_b, gen_c, exp_c, ...) as a tuple according to the algorithm.
                 # I omit gen,exp pairs where the exponent is zero.
@@ -2685,15 +2997,16 @@
         return result
 
     def __getitem__(self,x):
-        r"""
-        Same as \code{self.monomial_coefficent} but for exponent
-        vectors.
-        
-        INPUT:
-            x -- a tuple or, in case of a single-variable MPolynomial
-                 ring x can also be an integer.
-        
-        EXAMPLES:
+        """
+        Same as ``self.monomial_coefficent`` but for exponent vectors.
+        
+        INPUT:
+
+        - ``x`` - a tuple or, in case of a single-variable MPolynomial
+          ring x can also be an integer.
+        
+        EXAMPLES::
+
             sage: R.<x, y> = QQ[]
             sage: f = -10*x^3*y + 17*x*y
             sage: f[3,1]
@@ -2710,7 +3023,6 @@
             sage: f[2]
             5
         """
-
         cdef poly *m 
         cdef poly *p = self._poly
         cdef ring *r = (<MPolynomialRing_libsingular>self._parent)._ring
@@ -2738,7 +3050,7 @@
         while(p):
             if p_ExpVectorEqual(p, m, r) == 1:
                 p_Delete(&m,r)
-                return co.si2sa(p_GetCoeff(p, r), r, (<MPolynomialRing_libsingular>self._parent)._base)
+                return si2sa(p_GetCoeff(p, r), r, (<MPolynomialRing_libsingular>self._parent)._base)
             p = pNext(p)
 
         p_Delete(&m,r)
@@ -2749,7 +3061,8 @@
         Return the exponents of the monomials appearing in this
         polynomial.
         
-        EXAMPLES:
+        EXAMPLES::
+
             sage: R.<a,b,c> = QQ[]
             sage: f = a^3 + b + 2*b^2
             sage: f.exponents()
@@ -2773,10 +3086,11 @@
         return pl
 
     def is_unit(self):
-        r"""
-        Return \code{True} if self is a unit.
-
-        EXAMPLES:
+        """
+        Return ``True`` if self is a unit.
+
+        EXAMPLES::
+
             sage: R.<x,y> = QQ[]
             sage: (x+y).is_unit()
             False 
@@ -2803,10 +3117,11 @@
             return bool(p_IsConstant(self._poly, (<MPolynomialRing_libsingular>self._parent)._ring) and self.constant_coefficient().is_unit())
 
     def inverse_of_unit(self):
-        r"""
+        """
         Return the inverse of this polynomial if it is a unit.
 
-        EXAMPLES:
+        EXAMPLES::
+
             sage: R.<x,y> = QQ[]
             sage: x.inverse_of_unit()
             Traceback (most recent call last):
@@ -2822,13 +3137,14 @@
         if not p_IsUnit(self._poly, _ring):
             raise ArithmeticError, "Element is not a unit."
         else:
-            return co.new_MP(self._parent,pInvers(0,self._poly,NULL))
+            return new_MP(self._parent,pInvers(0,self._poly,NULL))
 
     def is_homogeneous(self):
-        r"""
-        Return \code{True} if this polynomial is homogeneous.
-
-        EXAMPLES:
+        """
+        Return ``True`` if this polynomial is homogeneous.
+
+        EXAMPLES::
+
             sage: P.<x,y> = PolynomialRing(RationalField(), 2)
             sage: (x+y).is_homogeneous()
             True
@@ -2848,19 +3164,21 @@
         return bool(pIsHomogeneous(self._poly))
 
     cpdef _homogenize(self, int var):
-        r"""
-        Return \code{self} if \code{self} is homogeneous.  Otherwise
-        return a homogenized polynomial constructed by modifying the
-        degree of the variable with index \code{var}.
-        
-        INPUT:
-            var -- an integer indicating which variable to use to
-                    homogenize (0 <= var < parent(self).ngens())
+        """
+        Return ``self`` if ``self`` is homogeneous.  Otherwise return
+        a homogenized polynomial constructed by modifying the degree
+        of the variable with index ``var``.
+        
+        INPUT:
+        
+        - ``var`` - an integer indicating which variable to use to
+          homogenize (``0 <= var < parent(self).ngens()``)
 
         OUTPUT:
             a multivariate polynomial
             
-        EXAMPLES:
+        EXAMPLES::
+
             sage: P.<x,y> = QQ[]
             sage: f = x^2 + y + 1 + 5*x*y^10
             sage: g = f.homogenize('z'); g # indirect doctest
@@ -2870,7 +3188,7 @@
             sage: f._homogenize(0)
             2*x^11 + x^10*y + 5*x*y^10
 
-        SEE: \code{self.homogenize}
+        SEE: ``self.homogenize``
         """
         cdef MPolynomialRing_libsingular parent = <MPolynomialRing_libsingular>self._parent
         cdef MPolynomial_libsingular f
@@ -2879,16 +3197,17 @@
             return self
 
         if var < parent._ring.N:
-            return co.new_MP(parent, pHomogen(p_Copy(self._poly, parent._ring), var+1))
+            return new_MP(parent, pHomogen(p_Copy(self._poly, parent._ring), var+1))
         else:
             raise TypeError, "var must be < self.parent().ngens()"
 
     def is_monomial(self):
-        r"""
-        Return \code{True} if this polynomial is a monomial.  A monomial
+        """
+        Return ``True`` if this polynomial is a monomial.  A monomial
         is defined to be a product of generators with coefficient 1.
 
-        EXAMPLE:
+        EXAMPLE::
+
             sage: P.<x,y,z> = PolynomialRing(QQ)
             sage: x.is_monomial()
             True
@@ -2919,23 +3238,27 @@
 
     def subs(self, fixed=None, **kw):
         """
-        Fixes some given variables in a given multivariate polynomial and
-        returns the changed multivariate polynomials. The polynomial
-        itself is not affected.  The variable,value pairs for fixing are
-        to be provided as dictionary of the form {variable:value}.
-
-        This is a special case of evaluating the polynomial with some of
-        the variables constants and the others the original variables, but
-        should be much faster if only few variables are to be fixed.
-
-        INPUT:
-            fixed -- (optional) dict with variable:value pairs
-            **kw -- names parameters
+        Fixes some given variables in a given multivariate polynomial
+        and returns the changed multivariate polynomials. The
+        polynomial itself is not affected.  The variable,value pairs
+        for fixing are to be provided as dictionary of the form
+        ``{variable:value}``.
+
+        This is a special case of evaluating the polynomial with some
+        of the variables constants and the others the original
+        variables, but should be much faster if only few variables are
+        to be fixed.
+
+        INPUT:
+        
+        - ``fixed`` - (optional) dict with variable:value pairs
+        - ``**kw`` - names parameters
 
         OUTPUT:
             new MPolynomial
 
-        EXAMPLES:
+        EXAMPLES::
+
             sage: R.<x,y> = QQ[]
             sage: f = x^2 + y + x^2*y^2 + 5 
             sage: f(5,y) 
@@ -2963,17 +3286,19 @@
             sage: f.subs({x:1/y})
             (y^2 + y + 1)/y
 
-        TESTS:
+        TESTS::
+
             sage: P.<x,y,z> = QQ[]
             sage: f = y
             sage: f.subs({y:x}).subs({x:z})
             z
 
-        NOTE: The evaluation is performed by evalutating every
-        variable:value pair separately.  This has side effects if
-        e.g. x=y, y=z is provided. If x=y is evaluated first, all x
-        variables will be replaced by z eventually.
-            
+        .. note:: 
+
+           The evaluation is performed by evalutating every
+           ``variable:value`` pair separately.  This has side effects
+           if e.g. x=y, y=z is provided. If x=y is evaluated first,
+           all x variables will be replaced by z eventually.
         """
         cdef int mi, i, need_map, try_symbolic
         
@@ -3062,7 +3387,7 @@
         id_Delete(&to_id, _ring)
 
         if not try_symbolic:
-            return co.new_MP(parent,_p)
+            return new_MP(parent,_p)
 
         # now as everything else failed, try to do it symbolically as in call
 
@@ -3100,9 +3425,11 @@
     def monomials(self):
         """
         Return the list of monomials in self. The returned list is
-        decreasingly ordered by the term ordering of self.parent().
-
-        EXAMPLE:
+        decreasingly ordered by the term ordering of
+        ``self.parent()``.
+
+        EXAMPLE::
+
             sage: P.<x,y,z> = QQ[]
             sage: f = x + 3/2*y*z^2 + 2/3
             sage: f.monomials()
@@ -3111,7 +3438,8 @@
             sage: f.monomials()
             [1]
 
-        TESTS:
+        TESTS::
+
             sage: P.<x,y,z> = QQ[]
             sage: f = x
             sage: f.monomials()
@@ -3119,8 +3447,6 @@
             sage: f = P(0)
             sage: f.monomials()
             [0]
-        
-        
         """
         l = list()
         cdef MPolynomialRing_libsingular parent = <MPolynomialRing_libsingular>self._parent
@@ -3136,16 +3462,18 @@
             p.next = NULL
             p_SetCoeff(p, n_Init(1,_ring), _ring)
             p_Setm(p, _ring)
-            l.append( co.new_MP(parent,p) )
+            l.append( new_MP(parent,p) )
             p = t
 
         return l
 
     def constant_coefficient(self):
         """
-        Return the constant coefficient of this multivariate polynomial.
-
-        EXAMPLES:
+        Return the constant coefficient of this multivariate
+        polynomial.
+
+        EXAMPLES::
+
             sage: P.<x, y> = QQ[]
             sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5
             sage: f.constant_coefficient()
@@ -3163,7 +3491,7 @@
             p = pNext(p)
 
         if p_LmIsConstant(p, r):
-            return co.si2sa( p_GetCoeff(p, r), r, (<MPolynomialRing_libsingular>self._parent)._base )
+            return si2sa( p_GetCoeff(p, r), r, (<MPolynomialRing_libsingular>self._parent)._base )
         else:
             return (<MPolynomialRing_libsingular>self._parent)._base._zero_element
 
@@ -3173,15 +3501,17 @@
         multivariate polynomial.
 
         INPUT:
-            R -- (default: None) PolynomialRing
+
+        - ``R`` - (default: ``None``) PolynomialRing
 
         If this polynomial is not in at most one variable, then a
-        ValueError exception is raised.  This is checked using the
-        is_univariate() method.  The new Polynomial is over the same
-        base ring as the given MPolynomial and in the variable 'x' if
-        no ring 'ring' is provided.
-
-        EXAMPLES:
+        ``ValueError`` exception is raised.  This is checked using the
+        :meth:`is_univariate()` method.  The new Polynomial is over
+        the same base ring as the given ``MPolynomial`` and in the
+        variable ``x`` if no ring ``R`` is provided.
+
+        EXAMPLES::
+
             sage: R.<x, y> = QQ[]
             sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5
             sage: f.univariate_polynomial()
@@ -3195,7 +3525,8 @@
             sage: g.univariate_polynomial(PolynomialRing(QQ,'z'))
             700*z^2 - 2*z + 305
 
-        Here's an example with a constant multivariate polynomial:
+        Here's an example with a constant multivariate polynomial::
+
             sage: g = R(1)
             sage: h = g.univariate_polynomial(); h
             1
@@ -3220,17 +3551,18 @@
         coefficients = [zero] * (self.degree() + 1)
 
         while p:
-            coefficients[pTotaldegree(p, r)] = co.si2sa(p_GetCoeff(p, r), r, k)
+            coefficients[pTotaldegree(p, r)] = si2sa(p_GetCoeff(p, r), r, k)
             p = pNext(p)
     
         return R(coefficients)
 
     def is_univariate(self):
         """
-        Return True if self is a univariate polynomial, that is if
+        Return ``True`` if self is a univariate polynomial, that is if
         self contains only one variable.
 
-        EXAMPLE:
+        EXAMPLE::
+
             sage: P.<x,y,z> = GF(2)[]
             sage: f = x^2 + 1
             sage: f.is_univariate()
@@ -3246,14 +3578,16 @@
 
     def _variable_indices_(self, sort=True):
         """
-        Return the indices of all variables occuring in self.
-        This index is the index as SAGE uses them (starting at zero), not
+        Return the indices of all variables occuring in self.  This
+        index is the index as Sage uses them (starting at zero), not
         as SINGULAR uses them (starting at one).
 
         INPUT:
-            sort -- specifies whether the indices shall be sorted
-
-        EXAMPLE:
+
+        - ``sort`` - specifies whether the indices shall be sorted
+
+        EXAMPLE::
+
             sage: P.<x,y,z> = GF(2)[]
             sage: f = x*z^2 + z + 1
             sage: f._variable_indices_()
@@ -3279,7 +3613,8 @@
         """
         Return a list of all variables occuring in self.
 
-        EXAMPLE:
+        EXAMPLE::
+
             sage: P.<x,y,z> = GF(2)[]
             sage: f = x*z^2 + z + 1
             sage: f.variables()
@@ -3298,17 +3633,19 @@
                     v = p_ISet(1,r)
                     p_SetExp(v, i, 1, r)
                     p_Setm(v, r)
-                    l.append(co.new_MP(self._parent, v))
+                    l.append(new_MP(self._parent, v))
                     si.add(i)
             p = pNext(p)
         return sorted(l,reverse=True)
 
     def variable(self, i=0):
         """
+
         Return the i-th variable occuring in self. The index i is the
-        index in self.variables().
-
-        EXAMPLE:
+        index in ``self.variables()``.
+
+        EXAMPLE::
+
             sage: P.<x,y,z> = GF(2)[]
             sage: f = x*z^2 + z + 1
             sage: f.variables()
@@ -3322,7 +3659,8 @@
         """
         Return the number variables in this polynomial.
 
-        EXAMPLE:
+        EXAMPLE::
+
             sage: P.<x,y,z> = PolynomialRing(GF(127))
             sage: f = x*y + z
             sage: f.nvariables()
@@ -3334,8 +3672,8 @@
         return len(self._variable_indices_(sort=False))
 
     cpdef is_constant(self):
-        r"""
-        Return \code{True} if this polynomial is constant.
+        """
+        Return ``True`` if this polynomial is constant.
 
         EXAMPLE:
             sage: P.<x,y,z> = PolynomialRing(GF(127))
@@ -3349,10 +3687,11 @@
     def lm(MPolynomial_libsingular self):
         """
         Returns the lead monomial of self with respect to the term
-        order of self.parent(). In SAGE a monomial is a product of
+        order of ``self.parent()``. In Sage a monomial is a product of
         variables in some power without a coefficient.
 
-        EXAMPLES:
+        EXAMPLES::
+
             sage: R.<x,y,z>=PolynomialRing(GF(7),3,order='lex')
             sage: f = x^1*y^2 + y^3*z^4
             sage: f.lm()
@@ -3386,14 +3725,15 @@
         _p = p_Head(self._poly, _ring)
         p_SetCoeff(_p, n_Init(1,_ring), _ring)
         p_Setm(_p,_ring)
-        return co.new_MP((<MPolynomialRing_libsingular>self._parent), _p)
+        return new_MP((<MPolynomialRing_libsingular>self._parent), _p)
 
     def lc(MPolynomial_libsingular self):
-        r"""
+        """
         Leading coefficient of this polynomial with respect to the
-        term order of \code{self.parent()}.
-
-        EXAMPLE:
+        term order of ``self.parent()``.
+
+        EXAMPLE::
+
             sage: R.<x,y,z>=PolynomialRing(GF(7),3,order='lex')
             sage: f = 3*x^1*y^2 + 2*y^3*z^4
             sage: f.lc()
@@ -3417,16 +3757,17 @@
         _p = p_Head(self._poly, _ring) 
         _n = p_GetCoeff(_p, _ring)
 
-        ret =  co.si2sa(_n, _ring, (<MPolynomialRing_libsingular>self._parent)._base)
+        ret =  si2sa(_n, _ring, (<MPolynomialRing_libsingular>self._parent)._base)
         p_Delete(&_p, _ring)
         return ret
 
     def lt(MPolynomial_libsingular self):
-        r"""
-        Leading term of this polynomial. In \SAGE a term is a product
+        """
+        Leading term of this polynomial. In Sage a term is a product
         of variables in some power and a coefficient.
 
-        EXAMPLE:
+        EXAMPLE::
+
             sage: R.<x,y,z>=PolynomialRing(GF(7),3,order='lex')
             sage: f = 3*x^1*y^2 + 2*y^3*z^4
             sage: f.lt()
@@ -3439,14 +3780,15 @@
         if self._poly == NULL:
             return (<MPolynomialRing_libsingular>self._parent)._zero_element
 
-        return co.new_MP((<MPolynomialRing_libsingular>self._parent),
+        return new_MP((<MPolynomialRing_libsingular>self._parent),
                                            p_Head(self._poly,(<MPolynomialRing_libsingular>self._parent)._ring))
 
     def is_zero(self):
-        r"""
-        Return \code{True} if this polynomial is zero.
-
-        EXAMPLE:
+        """
+        Return ``True`` if this polynomial is zero.
+
+        EXAMPLE::
+
             sage: P.<x,y> = PolynomialRing(QQ)
             sage: x.is_zero()
             False
@@ -3460,7 +3802,8 @@
 
     def __nonzero__(self):
         """
-        EXAMPLE:
+        EXAMPLE::
+
             sage: P.<x,y> = PolynomialRing(QQ)
             sage: bool(x) # indirect doctest
             True
@@ -3478,22 +3821,43 @@
 
         INPUT:
 
-            right -- something coercable to an MPolynomial_libsingular
-                     in self.parent()
-
-        EXAMPLES:
+        - ``right`` - something coercable to an MPolynomial_libsingular
+          in ``self.parent()``
+
+        EXAMPLES::
+
             sage: R.<x,y,z> = GF(32003)[]
             sage: f = y*x^2 + x + 1
             sage: f//x
             x*y + 1
             sage: f//y
             x^2
+
+            sage: P.<x,y> = ZZ[]
+            sage: x//y
+            0
+            sage: (x+y)//y
+            1
+
+            sage: P.<x,y> = QQ[]
+            sage: (x+y)//y
+            1
+            sage: (x)//y
+            0
+
+            sage: P.<x,y> = Zmod(1024)[]
+            sage: (x+y)//x
+            1
+            sage: (x+y)//(2*x)
+            Traceback (most recent call last):
+            ...
+            NotImplementedError: Division of multivariate polynomials over non fields by non-monomials not implemented.
         """
         cdef MPolynomialRing_libsingular parent = <MPolynomialRing_libsingular>(<MPolynomial_libsingular>self)._parent
         cdef ring *r = parent._ring
         if(r != currRing): rChangeCurrRing(r)
         cdef MPolynomial_libsingular _self, _right
-        cdef poly *quo
+        cdef poly *quo, *temp, *p
         
         _self = self
 
@@ -3508,24 +3872,40 @@
         if (<MPolynomial_libsingular>self)._parent._base.is_finite() and (<MPolynomial_libsingular>self)._parent._base.characteristic() > 1<<29:
             raise NotImplementedError, "Division of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented."
 
+        if r.ringtype != 0:
+            if r.ringtype == 4:
+                P = parent.change_ring(RationalField())
+                f = P(self)//P(right)
+                CM = list(f)
+                return parent(sum([c.floor()*m for c,m in CM]))
+            if _right.is_monomial():
+                p = _self._poly
+                quo = p_ISet(0,r)
+                while p:
+                    if p_DivisibleBy(_right._poly, p, r):
+                        temp = pDivide(p, _right._poly)
+                        p_SetCoeff0(temp, n_Copy(p_GetCoeff(p, r), r), r)
+                        quo = p_Add_q(quo, temp, r)
+                    p = pNext(p)
+                return new_MP(parent, quo)
+            raise NotImplementedError("Division of multivariate polynomials over non fields by non-monomials not implemented.")
+
         cdef int count = polyLengthBounded(_self._poly,15)
         if count >= 15:  # note that _right._poly must be of shorter length than self._poly for us to care about this call
             _sig_on
         quo = singclap_pdivide( _self._poly, _right._poly )
         if count >= 15:
             _sig_off
-        f = co.new_MP(parent, quo)
-        if PY_TYPE_CHECK(_self._parent._base, IntegerRing_class):
-            CM = list(f)
-            f = parent(sum([c.floor()*m for c,m in CM]))
+        f = new_MP(parent, quo)
 
         return f
 
     def factor(self, proof=True):
         r"""
-        Return the factorization of \code{self}.
-
-        EXAMPLE:
+        Return the factorization of this polynomial.
+
+        EXAMPLE::
+
             sage: R.<x, y> = QQ[]
             sage: f = (x^3 + 2*y^2*x) * (x^2 + x + 1); f
             x^5 + 2*x^3*y^2 + x^4 + 2*x^2*y^2 + x^3 + 2*x*y^2
@@ -3534,7 +3914,7 @@
             x * (x^2 + x + 1) * (x^2 + 2*y^2)
 
         Next we factor the same polynomial, but over the finite field
-        of order $3$.
+        of order 3.::
         
             sage: R.<x, y> = GF(3)[]
             sage: f = (x^3 + 2*y^2*x) * (x^2 + x + 1); f
@@ -3543,7 +3923,7 @@
             sage: F # order is somewhat random
             (-1) * x * (-x + y) * (x + y) * (x - 1)^2
 
-        Next we factor a polynomial over a number field.
+        Next we factor a polynomial over a number field.::
 
             sage: p = var('p')
             sage: K.<s> = NumberField(p^3-2)
@@ -3554,8 +3934,8 @@
             sage: k.factor()
             ((s^2 + 2/3)) * (x + (s)*y)^2 * (x + (-s)*y)^5 * (x^2 + (s)*x*y + (s^2)*y^2)^5
 
-        This shows that ticket \#2780 is fixed, i.e. that the unit part of
-        the factorization is set correctly:
+        This shows that ticket \#2780 is fixed, i.e. that the unit
+        part of the factorization is set correctly::
 
             sage: x = var('x')
             sage: K.<a> = NumberField(x^2 + 1)
@@ -3564,7 +3944,7 @@
             sage: F = f.factor(); F.unit()
             2
 
-        Another example:
+        Another example::
 
             sage: R.<x,y,z> = GF(32003)[]
             sage: f = 9*(x-1)^2*(y+z)
@@ -3584,7 +3964,7 @@
             sage: F.unit()
             -2
 
-        Constant elements are factorized in the base rings.
+        Constant elements are factorized in the base rings.::
 
             sage: P.<x,y> = ZZ[]
             sage: P(2^3*7).factor()
@@ -3593,7 +3973,7 @@
         Factorization of multivariate polynomials over non-prime
         finite fields is only implemented in Singular, and
         unfortunately Singular is currently very buggy at this
-        computation.  So we disable it in Sage:
+        computation.  So we disable it in Sage::
         
             sage: k.<a> = GF(9)
             sage: R.<x,y> = PolynomialRing(k)
@@ -3606,7 +3986,7 @@
             (y + (-a)) * (x + (-a))
 
         Also, factorization for finite prime fields with
-        characteristic $> 2^{29}$ is not supported either.
+        characteristic `> 2^{29}` is not supported either.::
 
             sage: q = 1073741789
             sage: T.<aa, bb> = PolynomialRing(GF(q))
@@ -3616,7 +3996,7 @@
             ...
             NotImplementedError: Factorization of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented.
 
-        Finally, factorization over the integers is not supported.
+        Finally, factorization over the integers is not supported.::
 
             sage: P.<x,y> = PolynomialRing(ZZ)
             sage: f = (3*x + 4)*(5*x - 2)
@@ -3663,9 +4043,9 @@
             _sig_off
 
         ivv = iv.ivGetVec()
-        v = [(co.new_MP(parent, p_Copy(I.m[i],_ring)) , ivv[i])   for i in range(1,I.ncols)]
+        v = [(new_MP(parent, p_Copy(I.m[i],_ring)) , ivv[i])   for i in range(1,I.ncols)]
         v = [(f,m) for f,m in v if f!=0] # we might have zero in there
-        unit = co.new_MP(parent, p_Copy(I.m[0],_ring))
+        unit = new_MP(parent, p_Copy(I.m[0],_ring))
         
         F = Factorization(v,unit)
         F.sort()
@@ -3678,10 +4058,11 @@
 
     def lift(self, I):
         """
-        given an ideal I = (f_1,...,f_r) and some g (== self) in I,
-        find s_1,...,s_r such that g = s_1 f_1 + ... + s_r f_r
-
-        EXAMPLE:
+        given an ideal ``I = (f_1,...,f_r)`` and some ``g (== self)`` in ``I``,
+        find ``s_1,...,s_r`` such that ``g = s_1 f_1 + ... + s_r f_r``.
+
+        EXAMPLE::
+
             sage: A.<x,y> = PolynomialRing(QQ,2,order='degrevlex')
             sage: I = A.ideal([x^10 + x^9*y^2, y^8 - x^2*y^7 ])
             sage: f = x*y^13 + y^12
@@ -3726,7 +4107,7 @@
         l = []
         for i from 0 <= i < IDELEMS(res):
             for j from 1 <= j <= IDELEMS(_I):
-                l.append( co.new_MP(parent, pTakeOutComp1(&res.m[i], j)) )
+                l.append( new_MP(parent, pTakeOutComp1(&res.m[i], j)) )
 
         id_Delete(&fI, r)
         id_Delete(&_I, r)
@@ -3734,21 +4115,22 @@
         return Sequence(l, check=False, immutable=True)
 
     def reduce(self,I):
-        r"""
-        Return the normal form of self w.r.t. \var{I}, i.e. return the
+        """
+        Return the normal form of self w.r.t. ``I``, i.e. return the
         remainder of this polynomial with respect to the polynomials
-        in \var{I}. If the polynomial set/list \var{I} is not a
-        (strong) Groebner basis the result is not canonical.
-
-        A strong Groebner basis $G$ of $I$ implies that for every
-        leading term $t$ of $I$ there exists an element $g$ of $G$,
-        such that the leading term of $g$ divides $t$.
-
-        INPUT:
-            I -- a list/set of polynomials in self.parent(). If I is an ideal,
-                 the generators are used.
-
-        EXAMPLE:
+        in ``I``. If the polynomial set/list ``I`` is not a (strong)
+        Groebner basis the result is not canonical.
+
+        A strong Groebner basis ``G`` of ``I`` implies that for every
+        leading term ``t`` of ``I`` there exists an element ``g`` of ``G``,
+        such that the leading term of ``g`` divides ``t``.
+
+        INPUT: 
+
+        - ``I`` - a list/set of polynomials. If ``I`` is an ideal, the
+          generators are used.
+
+        EXAMPLE::
                     
             sage: P.<x,y,z> = QQ[]
             sage: f1 = -2 * x^2 + x^3
@@ -3761,7 +4143,7 @@
             sage: g.reduce(F.gens())
             -6*y^2 + 2*y
 
-        \ZZ is also supported, but much slower.
+        `\ZZ` is also supported.::
             
             sage: P.<x,y,z> = ZZ[]
             sage: f1 = -2 * x^2 + x^3
@@ -3770,13 +4152,13 @@
             sage: F = Ideal([f1,f2,f3])
             sage: g = x*y - 3*x*y^2
             sage: g.reduce(F)
-            6*y^2 - 2*y
+            -6*y^2 + 2*y
             sage: g.reduce(F.gens())
-            6*y^2 - 2*y
+            -6*y^2 + 2*y
 
             sage: f = 3*x
             sage: f.reduce([2*x,y])
-            x
+            3*x
         """
         cdef ideal *_I
         cdef MPolynomialRing_libsingular parent = <MPolynomialRing_libsingular>self._parent
@@ -3789,32 +4171,32 @@
         if PY_TYPE_CHECK(I, MPolynomialIdeal):
             I = I.gens()
 
-        if PY_TYPE_CHECK(self._parent._base, IntegerRing_class):
-            lI = len(I)
-            I = list(I)
-            pres = 0
-            p = self
-            P = self._parent
-
-            if p.lc() < 0:
-                p = (-1)*p
-            while p != 0:
-                for i in xrange(lI):
-                    gi = I[i]
-                    plm = p.lm()
-                    gilm = gi.lm()
-                    plc = p.lc()
-                    gilc = gi.lc()
-                    if P.monomial_divides(gilm, plm):
-                        if gilc.abs() <= plc.abs():
-                            quot = plc//gilc * P.monomial_quotient(plm, gilm)
-                            p -= quot*I[i]
-                            break
-                else:
-                    plt = p.lt()
-                    pres += plt
-                    p -= plt
-            return pres
+#         if PY_TYPE_CHECK(self._parent._base, IntegerRing_class):
+#             lI = len(I)
+#             I = list(I)
+#             pres = 0
+#             p = self
+#             P = self._parent
+
+#             if p.lc() < 0:
+#                 p = (-1)*p
+#             while p != 0:
+#                 plm = p.lm()
+#                 for i in xrange(lI):
+#                     gi = I[i]
+#                     gilm = gi.lm()
+#                     plc = p.lc()
+#                     gilc = gi.lc()
+#                     if P.monomial_divides(gilm, plm):
+#                         if gilc.abs() <= plc.abs():
+#                             quot = plc//gilc * P.monomial_quotient(plm, gilm)
+#                             p -= quot*I[i]
+#                             break
+#                 else:
+#                     plt = p.lt()
+#                     pres += plt
+#                     p -= plt
+#             return pres
 
         _I = idInit(len(I),1)
         for f in I:
@@ -3832,18 +4214,21 @@
         #the second parameter would be qring!
         res = kNF(_I, NULL, self._poly)
         id_Delete(&_I,r)
-        return co.new_MP(parent,res)
+        return new_MP(parent,res)
 
     def gcd(self, right, algorithm=None):
         """
         Return the greates common divisor of self and right.
 
         INPUT:
-            right -- polynomial
-            algorithm -- 'ezgcd' -- EZGCD algorithm
-                         'modular' -- multi-modular algorithm (default)
-
-        EXAMPLES:
+        
+        - ``right`` - polynomial
+        - ``algorithm`` 
+          - ``ezgcd`` - EZGCD algorithm
+          - ``modular`` - multi-modular algorithm (default)
+
+        EXAMPLES::
+
             sage: P.<x,y,z> = QQ[]
             sage: f = (x*y*z)^6 - 1
             sage: g = (x*y*z)^4 - 1
@@ -3858,7 +4243,7 @@
             sage: f.gcd(g)
             x^2
 
-        We compute a gcd over a finite field.
+        We compute a gcd over a finite field::
 
             sage: F.<u> = GF(31^2)
             sage: R.<x,y,z> = F[]
@@ -3869,7 +4254,7 @@
             sage: gcd(p,q)  # yes, twice -- tests that singular ring is properly set.
             x^3 + (u + 1)*y^3 + z^3
 
-        We compute a gcd over a number field:
+        We compute a gcd over a number field::
 
             sage: x = polygen(QQ)
             sage: F.<u> = NumberField(x^3 - 2)
@@ -3879,7 +4264,8 @@
             sage: gcd(p,q)
             x^3 + (u + 1)*y^3 + z^3        
 
-        TESTS:
+        TESTS::
+
             sage: Q.<x,y,z> = QQ[]
             sage: P.<x,y,z> = QQ[]
             sage: P(0).gcd(Q(0))
@@ -3914,6 +4300,17 @@
 
         _ring = (<MPolynomialRing_libsingular>self._parent)._ring
 
+        
+
+        if _ring.ringtype != 0:
+            if _ring.ringtype == 4:
+                P = self._parent.change_ring(RationalField())
+                res = P(self).gcd(P(right))
+                coef = sage.rings.integer.GCD_list(self.coefficients() + right.coefficients())
+                return self._parent(coef*res)
+
+            raise NotImplementedError("GCD over rings not implemented.")
+
         if self._parent._base.is_finite() and self._parent._base.characteristic() > 1<<29:
             raise NotImplementedError, "GCD of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented."
             
@@ -3931,12 +4328,7 @@
         if count >= 20:
             _sig_off
 
-        res = co.new_MP((<MPolynomialRing_libsingular>self._parent), _res)
-
-        if PY_TYPE_CHECK(self._parent._base, IntegerRing_class):
-            coef = sage.rings.integer.GCD_list(self.coefficients() + right.coefficients())
-            return coef*res
-
+        res = new_MP((<MPolynomialRing_libsingular>self._parent), _res)
         return res
 
     def lcm(self, MPolynomial_libsingular g):
@@ -3944,12 +4336,14 @@
         Return the least common multiple of self and g.
 
         INPUT:
-            g -- polynomial
+
+        - ``g`` - polynomial
 
         OUTPUT:
             polynomial
 
-        EXAMPLE:
+        EXAMPLE::
+
             sage: P.<x,y,z> = QQ[]
             sage: p = (x+y)*(y+z)
             sage: q = (z^4+2)*(y+z)
@@ -3967,10 +4361,15 @@
         cdef MPolynomial_libsingular _g
         if(_ring != currRing): rChangeCurrRing(_ring)
 
-        if not self._parent._base.is_field():
-            py_gcd = self.gcd(g)
-            py_prod = self*g
-            return py_prod//py_gcd
+
+        if _ring.ringtype != 0:
+            if _ring.ringtype == 4:
+                P = self.parent().change_ring(RationalField())
+                py_gcd = P(self).gcd(P(g))
+                py_prod = P(self*g)
+                return self.parent(py_prod//py_gcd)
+            else:
+                raise TypeError("LCM over non-integral domains not available.")
 
         if self._parent is not g._parent:
             _g = (<MPolynomialRing_libsingular>self._parent)._coerce_c(g)
@@ -3990,13 +4389,14 @@
         p_Delete(&gcd, _ring)
         if count >= 20:
             _sig_off
-        return co.new_MP(self._parent, ret)
+        return new_MP(self._parent, ret)
 
     def is_squarefree(self):
-        r"""
-        Return \code{True} if this polynomial is square free.
-
-        EXAMPLE:
+        """
+        Return ``True`` if this polynomial is square free.
+
+        EXAMPLE::
+
             sage: P.<x,y,z> = PolynomialRing(QQ)
             sage: f= x^2 + 2*x*y + 1/2*z
             sage: f.is_squarefree()
@@ -4017,7 +4417,8 @@
         """
         Returns quotient and remainder of self and right.
 
-        EXAMPLES:
+        EXAMPLES::
+
             sage: R.<x,y> = QQ[]
             sage: f = y*x^2 + x + 1
             sage: f.quo_rem(x)
@@ -4034,7 +4435,8 @@
             sage: f.quo_rem(3*x)
             (0, 2*x^2*y + x + 1)
 
-        TESTS:
+        TESTS::
+
             sage: R.<x,y> = QQ[]
             sage: R(0).quo_rem(R(1))
             (0, 0)
@@ -4044,7 +4446,6 @@
             ZeroDivisionError
         
         """
-        #cdef ideal *selfI, *rightI, *R, *res
         cdef poly *quo, *rem
         cdef MPolynomialRing_libsingular parent = <MPolynomialRing_libsingular>self._parent
         cdef ring *r = (<MPolynomialRing_libsingular>self._parent)._ring
@@ -4071,27 +4472,30 @@
         rem = p_Add_q(p_Copy(self._poly, r), p_Neg(pp_Mult_qq(right._poly, quo, r), r), r)
         if count >= 15:
             _sig_off
-        return co.new_MP(parent, quo), co.new_MP(parent, rem)
+        return new_MP(parent, quo), new_MP(parent, rem)
 
     def _singular_init_(self, singular=singular_default):
-        r"""
-        Return a \SINGULAR (as in the computer algebra system) string
+        """
+        Return a SINGULAR (as in the computer algebra system) string
         representation for this element.
 
         INPUT:
-            singular -- interpreter (default: singular_default)
-
-            have_ring -- should the correct ring not be set in
-                         \SINGULAR first (default: \code{False})
-
-        EXAMPLES:
+
+        - ``singular`` - interpreter (default: ``singular_default``)
+
+        - ``have_ring`` - should the correct ring not be set in
+           SINGULAR first (default: ``False``)
+
+        EXAMPLES::
+
             sage: P.<x,y,z> = PolynomialRing(GF(127),3)
             sage: x._singular_init_()
             'x'
             sage: (x^2+37*y+128)._singular_init_()
             'x2+37y+1'
 
-        TESTS:
+        TESTS::
+
             sage: P(0)._singular_init_()
             '0'
         """
@@ -4100,19 +4504,22 @@
     
     def sub_m_mul_q(self, MPolynomial_libsingular m, MPolynomial_libsingular q):
         """
-        Return self - m*q, where m must be a monomial and q a
-        polynomial.
-
-        INPUT:
-            m -- a monomial
-            q -- a polynomial
-
-        EXAMPLE:
+        Return ``self - m*q``, where ``m`` must be a monomial and
+        ``q`` a polynomial.
+
+        INPUT:
+        
+        - ``m`` - a monomial
+        - ``q`` - a polynomial
+
+        EXAMPLE::
+
             sage: P.<x,y,z>=PolynomialRing(QQ,3)
             sage: x.sub_m_mul_q(y,z)
             -y*z + x
 
-        TESTS:
+        TESTS::
+
             sage: Q.<x,y,z>=PolynomialRing(QQ,3)
             sage: P.<x,y,z>=PolynomialRing(QQ,3)
             sage: P(0).sub_m_mul_q(P(0),P(1))
@@ -4139,18 +4546,21 @@
         if unlikely(esum > max_exponent_size):
             raise OverflowError("Exponent overflow.")
 
-        return co.new_MP(self._parent, p_Minus_mm_Mult_qq(p_Copy(self._poly, r), m._poly, q._poly, r))
+        return new_MP(self._parent, p_Minus_mm_Mult_qq(p_Copy(self._poly, r), m._poly, q._poly, r))
 
     def _macaulay2_(self, macaulay2=macaulay2):
         """
         Return a Macaulay2 string representation of this polynomial.
 
-        WARNING: Two identical rings are not canonically isomorphic in
-        M2, so we require the user to explicitly set the ring, since
-        there is no way to know if the ring has been set or not, and
-        setting it twice screws everything up. 
-        
-        EXAMPLES:
+        .. note:: 
+        
+           Two identical rings are not canonically isomorphic in M2,
+           so we require the user to explicitly set the ring, since
+           there is no way to know if the ring has been set or not,
+           and setting it twice screws everything up.
+        
+        EXAMPLES::
+
             sage: R.<x,y> = PolynomialRing(GF(7), 2)
             sage: f = (x^3 + 2*y^2*x)^7; f
             x^21 + 2*x^7*y^14
@@ -4173,20 +4583,23 @@
         return macaulay2(repr(self))
 
     def add_m_mul_q(self, MPolynomial_libsingular m, MPolynomial_libsingular q):
-        r"""
-        Return \code{self} $+ m*q$, where $m$ must be a monomial and
-        $q$ a polynomial.
-
-       INPUT:
-            m -- a monomial
-            q -- a polynomial
-
-        EXAMPLE:
+        """
+        Return ``self + m*q``, where ``m`` must be a monomial and
+        ``q`` a polynomial.
+
+        INPUT:
+        
+        - ``m`` - a monomial
+        - ``q``  - a polynomial
+
+        EXAMPLE::
+
             sage: P.<x,y,z>=PolynomialRing(QQ,3)
             sage: x.add_m_mul_q(y,z)
             y*z + x
 
-        TESTS:
+        TESTS::
+
             sage: R.<x,y,z>=PolynomialRing(QQ,3)
             sage: P.<x,y,z>=PolynomialRing(QQ,3)
             sage: P(0).add_m_mul_q(P(0),P(1))
@@ -4213,13 +4626,14 @@
         if unlikely(esum > max_exponent_size):
             raise OverflowError("Exponent overflow.")
 
-        return co.new_MP(self._parent, p_Plus_mm_Mult_qq(p_Copy(self._poly, r), m._poly, q._poly, r))
+        return new_MP(self._parent, p_Plus_mm_Mult_qq(p_Copy(self._poly, r), m._poly, q._poly, r))
         
     def __reduce__(self):
         """
         Serialize this polynomial.
 
-        EXAMPLES:
+        EXAMPLES::
+
             sage: P.<x,y,z> = PolynomialRing(QQ,3, order='degrevlex')
             sage: f = 27/113 * x^2 + y*z + 1/2
             sage: f == loads(dumps(f))
@@ -4237,10 +4651,12 @@
     def _im_gens_(self, codomain, im_gens):
         """
         INPUT:
-            codomain
-            im_gens
-
-        EXAMPLES:
+
+        - ``codomain``
+        - ``im_gens``
+
+        EXAMPLES::
+
             sage: R.<x,y> = PolynomialRing(QQ, 2)
             sage: f = R.hom([y,x], R)
             sage: f(x^2 + 3*y^5)
@@ -4269,13 +4685,15 @@
         over finite fields.
         
         INPUT:
-            variable -- the derivative is taken with respect to variable
-            have_ring -- ignored, accepted for compatibility reasons
-
-        SEE ALSO:
-            self.derivative()
-
-        EXAMPLES: 
+        
+        - ``variable`` - the derivative is taken with respect to variable
+
+        - ``have_ring`` - ignored, accepted for compatibility reasons
+
+        .. note:: See also :meth:`derivative` 
+
+        EXAMPLES::
+
             sage: R.<x,y> = PolynomialRing(QQ,2)
             sage: f = 3*x^3*y^2 + 5*y^2 + 3*x + 2
             sage: f._derivative(x)
@@ -4283,7 +4701,7 @@
             sage: f._derivative(y)
             6*x^3*y + 10*y
             
-        The derivative is also defined over finite fields:
+        The derivative is also defined over finite fields::
 
             sage: R.<x,y> = PolynomialRing(GF(2**8, 'a'),2)
             sage: f = x^3*y^2 + y^2 + x + 2
@@ -4315,24 +4733,26 @@
             raise TypeError, "provided variable is constant"
 
         p = pDiff(self._poly, var_i)
-        return co.new_MP(self._parent,p)
+        return new_MP(self._parent,p)
 
 
     def resultant(self, MPolynomial_libsingular other, variable=None):
-        r"""
-        computes the resultant of this polynomial and the first
+        """
+        Compute the resultant of this polynomial and the first
         argument with respect to the variable given as the second
         argument.
 
         If a second argument is not provide the first variable of
-        \code{self.parent()} is chosen.
-
-        INPUT:
-            other -- polynomial in \code{self.parent()}
-            variable -- optional variable (of type polynomial) in
-                        \code{self.parent()} (default: \code{None})
-
-        EXAMPLE:
+        the parent is chosen.
+
+        INPUT:
+
+        - ``other`` - polynomial
+
+        - ``variable`` - optional variable (default: ``None``)
+
+        EXAMPLE::
+
             sage: P.<x,y> = PolynomialRing(QQ,2)
             sage: a = x+y
             sage: b = x^3-y^3
@@ -4341,7 +4761,7 @@
             sage: d = a.resultant(b,y); d
             2*x^3
 
-        The \SINGULAR example:
+        The SINGULAR example::
 
             sage: R.<x,y,z> = PolynomialRing(GF(32003),3)
             sage: f = 3 * (x+2)^3 + y
@@ -4349,7 +4769,8 @@
             sage: f.resultant(g,x)
             3*y^3 + 9*y^2*z + 9*y*z^2 + 3*z^3 - 18*y^2 - 36*y*z - 18*z^2 + 35*y + 36*z - 24
 
-        TESTS:
+        TESTS::
+
             sage: P.<x,y> = PolynomialRing(QQ, order='degrevlex')
             sage: a = x+y
             sage: b = x^3-y^3
@@ -4381,15 +4802,16 @@
         rt =  singclap_resultant(self._poly, other._poly, (<MPolynomial_libsingular>variable)._poly )
         if count >= 20:
             _sig_off
-        return co.new_MP(self._parent, rt)
+        return new_MP(self._parent, rt)
 
     def coefficients(self):
-        r"""
+        """
         Return the nonzero coefficients of this polynomial in a list.
         The returned list is decreasingly ordered by the term ordering
-        of \code{self.parent()}.
-        
-        EXAMPLES:
+        of the parent.
+        
+        EXAMPLES::
+
             sage: R.<x,y,z> = PolynomialRing(QQ, order='degrevlex')
             sage: f=23*x^6*y^7 + x^3*y+6*x^7*z
             sage: f.coefficients()
@@ -4401,7 +4823,8 @@
             [6, 23, 1]
 
         AUTHOR:
-            -- didier deshommes
+        
+        - Didier Deshommes
         """
         cdef poly *p
         cdef ring *r
@@ -4411,16 +4834,17 @@
         p = self._poly
         coeffs = list()
         while p:
-            coeffs.append(co.si2sa(p_GetCoeff(p, r), r, base))
+            coeffs.append(si2sa(p_GetCoeff(p, r), r, base))
             p = pNext(p)
         return coeffs
 
     def gradient(self):
-        r"""
+        """
         Return a list of partial derivatives of this polynomial,
-        ordered by the variables of \code{self.parent()}.
-
-        EXAMPLE:
+        ordered by the variables of the parent.
+
+        EXAMPLE::
+
            sage: P.<x,y,z> = PolynomialRing(QQ,3)
            sage: f= x*y + 1
            sage: f.gradient()
@@ -4433,19 +4857,21 @@
         if r!=currRing: rChangeCurrRing(r)
         i = []
         for k from 0 < k <= r.N:
-            i.append( co.new_MP(self._parent, pDiff(self._poly, k)))
+            i.append( new_MP(self._parent, pDiff(self._poly, k)))
 
         return i
         
 def unpickle_MPolynomial_libsingular(MPolynomialRing_libsingular R, d):
-    r"""
-    Deserialize an \code{MPolynomial_libsingular} object
+    """
+    Deserialize an ``MPolynomial_libsingular`` object
 
     INPUT:
-        R -- the base ring
-        d -- a Python dictionary as returned by MPolynomial_libsingular.dict
-
-    EXAMPLE:
+    
+    - ``R`` - the base ring
+    - ``d`` - a Python dictionary as returned by :meth:`MPolynomial_libsingular.dict`
+
+    EXAMPLE::
+
         sage: P.<x,y> = PolynomialRing(QQ)
         sage: loads(dumps(x)) == x # indirect doctest
         True
@@ -4470,10 +4896,10 @@
                 raise TypeError, "exponent too small"
             assert(_e <= max_exponent_size)
             p_SetExp(m, _i+1,_e, r)
-        p_SetCoeff(m, co.sa2si(c, r), r)
+        p_SetCoeff(m, sa2si(c, r), r)
         p_Setm(m,r)
         p = p_Add_q(p,m,r)
-    return co.new_MP(R,p)
+    return new_MP(R,p)
 
 
 cdef poly *addwithcarry(poly *tempvector, poly *maxvector, int pos, ring *_ring):
@@ -4485,4 +4911,15 @@
     p_Setm(tempvector, _ring)
     return tempvector
 
-
+cdef inline MPolynomial_libsingular new_MP(MPolynomialRing_libsingular parent, poly *juice):
+    """
+    Construct MPolynomial_libsingular from parent and SINGULAR poly.
+    """
+    cdef MPolynomial_libsingular p
+    p = PY_NEW(MPolynomial_libsingular)
+    p._parent = <ParentWithBase>parent
+    p._poly = juice
+    p_Normalize(p._poly, parent._ring)
+    return p
+
+
diff -r 6c7354ace3b6 -r 8037fada5b30 sage/rings/polynomial/multi_polynomial_ring.py
--- a/sage/rings/polynomial/multi_polynomial_ring.py	Sat Jun 06 09:55:28 2009 -0700
+++ b/sage/rings/polynomial/multi_polynomial_ring.py	Wed Jun 10 21:47:44 2009 -0700
@@ -1,17 +1,10 @@
 r"""
-Multivariate Polynomial Rings
+Multivariate Polynomial Rings over Generic Rings
 
 Sage implements multivariate polynomial rings through several
-backends. The generic implementation used the classes
-``PolyDict`` and ``ETuple`` to construct a
-dictionary with exponent tuples as keys and coefficients as
-values.
-
-Additionally, specialized and optimized implementations are
-provided for multivariate polynomials over `\QQ` and
-`\GF{p}`. These are implemented in the classes
-``MPolynomialRing_libsingular`` and
-``MPolynomial_libsingular``
+backends. This generic implementation uses the classes ``PolyDict``
+and ``ETuple`` to construct a dictionary with exponent tuples as keys
+and coefficients as values.
 
 AUTHORS:
 
@@ -31,8 +24,8 @@
 
 EXAMPLES:
 
-We construct the Frobenius morphism on
-`\mbox{\rm F}_{5}[x,y,z]` over `\GF{5}`::
+We construct the Frobenius morphism on `\GF{5}[x,y,z]` over
+`\GF{5}`::
 
     sage: R, (x,y,z) = PolynomialRing(GF(5), 3, 'xyz').objgens()
     sage: frob = R.hom([x^5, y^5, z^5])
@@ -130,7 +123,7 @@
         return self.base_ring().is_exact()
         
 
-class MPolynomialRing_polydict( MPolynomialRing_macaulay2_repr, MPolynomialRing_generic):
+class MPolynomialRing_polydict( MPolynomialRing_macaulay2_repr, PolynomialRing_singular_repr, MPolynomialRing_generic):
     """
     Multivariable polynomial ring.
     
@@ -142,6 +135,7 @@
         True
     """
     def __init__(self, base_ring, n, names, order):
+        from sage.rings.polynomial.polynomial_singular_interface import can_convert_to_singular
         order = TermOrder(order,n)
         MPolynomialRing_generic.__init__(self, base_ring, n, names, order)
         # Construct the generators
@@ -155,6 +149,7 @@
             v[i] = 0
         self._gens = tuple(self._gens)
         self._zero_tuple = tuple(v)
+        self._has_singular = can_convert_to_singular(self)
 
     def _monomial_order_function(self):
         return self.__monomial_order_function
@@ -467,13 +462,10 @@
 
 class MPolynomialRing_polydict_domain(integral_domain.IntegralDomain,
                                       MPolynomialRing_polydict,
-                                      PolynomialRing_singular_repr,
                                       MPolynomialRing_macaulay2_repr):
     def __init__(self, base_ring, n, names, order):
-        from sage.rings.polynomial.polynomial_singular_interface import can_convert_to_singular
         order = TermOrder(order, n)
         MPolynomialRing_polydict.__init__(self, base_ring, n, names, order)
-        self._has_singular = can_convert_to_singular(self)
 
     def is_integral_domain(self):
         return True
diff -r 6c7354ace3b6 -r 8037fada5b30 sage/rings/polynomial/multi_polynomial_ring_generic.pxd
--- a/sage/rings/polynomial/multi_polynomial_ring_generic.pxd	Sat Jun 06 09:55:28 2009 -0700
+++ b/sage/rings/polynomial/multi_polynomial_ring_generic.pxd	Wed Jun 10 21:47:44 2009 -0700
@@ -6,7 +6,7 @@
 cdef class MPolynomialRing_generic(sage.rings.ring.CommutativeRing):
     cdef object __ngens
     cdef object __term_order
-    cdef object _has_singular
+    cdef public object _has_singular
     cdef public object _magma_gens, _magma_cache
 
     cdef _coerce_c_impl(self, x)
diff -r 6c7354ace3b6 -r 8037fada5b30 sage/rings/polynomial/polynomial_ring_constructor.py
--- a/sage/rings/polynomial/polynomial_ring_constructor.py	Sat Jun 06 09:55:28 2009 -0700
+++ b/sage/rings/polynomial/polynomial_ring_constructor.py	Wed Jun 10 21:47:44 2009 -0700
@@ -397,7 +397,10 @@
             except ( TypeError, NotImplementedError ):
                 R = m.MPolynomialRing_polydict_domain(base_ring, n, names, order)
     else:
-        R = m.MPolynomialRing_polydict(base_ring, n, names, order)
+        try:
+            R = MPolynomialRing_libsingular(base_ring, n, names, order)
+        except ( TypeError, NotImplementedError ):
+            R = m.MPolynomialRing_polydict(base_ring, n, names, order)
 
     _save_in_cache(key, R)
     return R
diff -r 6c7354ace3b6 -r 8037fada5b30 sage/rings/polynomial/polynomial_singular_interface.py
--- a/sage/rings/polynomial/polynomial_singular_interface.py	Sat Jun 06 09:55:28 2009 -0700
+++ b/sage/rings/polynomial/polynomial_singular_interface.py	Wed Jun 10 21:47:44 2009 -0700
@@ -42,6 +42,7 @@
 from sage.rings.complex_field import is_ComplexField
 from sage.rings.real_mpfr import is_RealField
 from sage.rings.complex_double import is_ComplexDoubleField
+from sage.rings.integer_mod_ring import is_IntegerModRing
 from sage.rings.real_double import is_RealDoubleField
 from sage.rings.rational_field import is_RationalField
 from sage.rings.integer_ring import ZZ
@@ -57,24 +58,21 @@
     polynomial rings which support conversion from and to Singular
     rings.
     """
-    def _singular_(self, singular=singular_default, force=False):
+    def _singular_(self, singular=singular_default):
         """
         Returns a singular ring for this polynomial ring over a field.
-        Currently QQ, GF(p), and GF(p^n), CC, and RR are supported.
+        Currently QQ, GF(p), GF(p^n), CC, RR, ZZ and ZZ/nZZ are
+        supported.
 
         INPUT:
             singular -- Singular instance
-            force -- polynomials over ZZ may be coerced to Singular by
-                     treating them as polynomials over RR. This is
-                     inexact but works for some cases where the
-                     coeffients are not considered (default: False).
 
         OUTPUT:
             singular ring matching this ring
 
         EXAMPLES:
             sage: R.<x,y> = PolynomialRing(CC,'x',2)
-            sage: R._singular_()
+            sage: singular(R)
             //   characteristic : 0 (complex:15 digits, additional 0 digits)
             //   1 parameter    : I
             //   minpoly        : (I^2+1)
@@ -83,7 +81,7 @@
             //                  : names    x y
             //        block   2 : ordering C
             sage: R.<x,y> = PolynomialRing(RealField(100),'x',2)
-            sage: R._singular_()
+            sage: singular(R)
             //   characteristic : 0 (real:29 digits, additional 0 digits)
             //   number of vars : 2
             //        block   1 : ordering dp
@@ -92,7 +90,7 @@
 
             sage: w = var('w')
             sage: R.<x> = PolynomialRing(NumberField(w^2+1,'s'))
-            sage: R._singular_()
+            sage: singular(R)
             //   characteristic : 0
             //   1 parameter    : s
             //   minpoly        : (s^2+1)
@@ -101,40 +99,40 @@
             //                  : names    x
             //        block   2 : ordering C
 
-            sage: r = PolynomialRing(GF(127),1,'x')
-            sage: r._singular_()
+            sage: R = PolynomialRing(GF(127),1,'x')
+            sage: singular(R)
             //   characteristic : 127
             //   number of vars : 1
             //        block   1 : ordering lp
             //                  : names    x
             //        block   2 : ordering C
 
-            sage: r = PolynomialRing(QQ,1,'x')
-            sage: r._singular_()
+            sage: R = PolynomialRing(QQ,1,'x')
+            sage: singular(R)
             //   characteristic : 0
             //   number of vars : 1
             //        block   1 : ordering lp
             //                  : names    x
             //        block   2 : ordering C
 
-            sage: r = PolynomialRing(QQ,'x')
-            sage: r._singular_()
+            sage: R = PolynomialRing(QQ,'x')
+            sage: singular(R)
             //   characteristic : 0
             //   number of vars : 1
             //        block   1 : ordering lp
             //                  : names    x
             //        block   2 : ordering C
 
-            sage: r = PolynomialRing(GF(127),'x')
-            sage: r._singular_()
+            sage: R = PolynomialRing(GF(127),'x')
+            sage: singular(R)
             //   characteristic : 127
             //   number of vars : 1
             //        block   1 : ordering lp
             //                  : names    x
             //        block   2 : ordering C
 
-            sage: r = Frac(ZZ['a,b'])['x,y']
-            sage: r._singular_()
+            sage: R = Frac(ZZ['a,b'])['x,y']
+            sage: singular(R)
             //   characteristic : 0
             //   2 parameter    : a b 
             //   minpoly        : 0
@@ -143,6 +141,31 @@
             //                  : names    x y 
             //        block   2 : ordering C
 
+
+            sage: R = IntegerModRing(1024)['x,y']
+            sage: singular(R)
+            //   coeff. ring is : Z/2^10
+            //   number of vars : 2
+            //        block   1 : ordering dp
+            //                  : names    x y
+            //        block   2 : ordering C
+
+            sage: R = IntegerModRing(15)['x,y']
+            sage: singular(R)
+            //   coeff. ring is : Z/15
+            //   number of vars : 2
+            //        block   1 : ordering dp
+            //                  : names    x y
+            //        block   2 : ordering C
+
+            sage: R = ZZ['x,y']
+            sage: singular(R)
+            //   coeff. ring is : Integers
+            //   number of vars : 2
+            //        block   1 : ordering dp
+            //                  : names    x y
+            //        block   2 : ordering C
+
         WARNING:
            If the base ring is a finite extension field or a number field
            the ring will not only be returned but also be set as the current
@@ -168,13 +191,13 @@
 
             return R
         except (AttributeError, ValueError):
-            return self._singular_init_(singular, force)
+            return self._singular_init_(singular)
             
-    def _singular_init_(self, singular=singular_default, force=False):
+    def _singular_init_(self, singular=singular_default):
         """
         Return a newly created Singular ring matching this ring.
         """
-        if not can_convert_to_singular(self) and not force:
+        if not can_convert_to_singular(self):
             raise TypeError, "no conversion of this ring to a Singular ring defined"
         
         if self.ngens()==1:
@@ -186,48 +209,50 @@
             _vars = str(self.gens())
             order = self.term_order().singular_str()
             
-        if is_RealField(self.base_ring()):
+        base_ring = self.base_ring()
+
+        if is_RealField(base_ring):
             # singular converts to bits from base_10 in mpr_complex.cc by:
             #  size_t bits = 1 + (size_t) ((float)digits * 3.5);
-            precision = self.base_ring().precision()
+            precision = base_ring.precision()
             digits = sage.rings.arith.integer_ceil((2*precision - 2)/7.0)
             self.__singular = singular.ring("(real,%d,0)"%digits, _vars, order=order, check=False)
 
-        elif is_ComplexField(self.base_ring()):
+        elif is_ComplexField(base_ring):
             # singular converts to bits from base_10 in mpr_complex.cc by:
             #  size_t bits = 1 + (size_t) ((float)digits * 3.5);
-            precision = self.base_ring().precision()
+            precision = base_ring.precision()
             digits = sage.rings.arith.integer_ceil((2*precision - 2)/7.0)
             self.__singular = singular.ring("(complex,%d,0,I)"%digits, _vars,  order=order, check=False)
 
-        elif is_RealDoubleField(self.base_ring()):
+        elif is_RealDoubleField(base_ring):
             # singular converts to bits from base_10 in mpr_complex.cc by:
             #  size_t bits = 1 + (size_t) ((float)digits * 3.5);
             self.__singular = singular.ring("(real,15,0)", _vars, order=order, check=False)
 
-        elif is_ComplexDoubleField(self.base_ring()):
+        elif is_ComplexDoubleField(base_ring):
             # singular converts to bits from base_10 in mpr_complex.cc by:
             #  size_t bits = 1 + (size_t) ((float)digits * 3.5);
             self.__singular = singular.ring("(complex,15,0,I)", _vars,  order=order, check=False)
 
-        elif self.base_ring().is_prime_field() or (self.base_ring() is ZZ and force):
+        elif base_ring.is_prime_field():
             self.__singular = singular.ring(self.characteristic(), _vars, order=order, check=False)
         
-        elif sage.rings.ring.is_FiniteField(self.base_ring()):
+        elif sage.rings.ring.is_FiniteField(base_ring):
             # not the prime field!
-            gen = str(self.base_ring().gen())
+            gen = str(base_ring.gen())
             r = singular.ring( "(%s,%s)"%(self.characteristic(),gen), _vars, order=order, check=False)
-            self.__minpoly = (str(self.base_ring().modulus()).replace("x",gen)).replace(" ","")
+            self.__minpoly = (str(base_ring.modulus()).replace("x",gen)).replace(" ","")
             if  singular.eval('minpoly') != "(" + self.__minpoly + ")":
                 singular.eval("minpoly=%s"%(self.__minpoly) )
                 self.__minpoly = singular.eval('minpoly')[1:-1]
         
             self.__singular = r
         
-        elif number_field.all.is_NumberField(self.base_ring()) and self.base_ring().is_absolute():
+        elif number_field.all.is_NumberField(base_ring) and base_ring.is_absolute():
             # not the rationals!
-            gen = str(self.base_ring().gen())
-            poly=self.base_ring().polynomial()
+            gen = str(base_ring.gen())
+            poly=base_ring.polynomial()
             poly_gen=str(poly.parent().gen())
             poly_str=str(poly).replace(poly_gen,gen)
             r = singular.ring( "(%s,%s)"%(self.characteristic(),gen), _vars, order=order, check=False)
@@ -238,13 +263,23 @@
         
             self.__singular = r
 
-        elif sage.rings.fraction_field.is_FractionField(self.base_ring()) and (self.base_ring().base_ring() is ZZ or self.base_ring().base_ring().is_prime_field()):
-            if self.base_ring().ngens()==1:
-              gens = str(self.base_ring().gen())
+        elif sage.rings.fraction_field.is_FractionField(base_ring) and (base_ring.base_ring() is ZZ or base_ring.base_ring().is_prime_field()):
+            if base_ring.ngens()==1:
+              gens = str(base_ring.gen())
             else:
-              gens = str(self.base_ring().gens())
-            self.__singular = singular.ring( "(%s,%s)"%(self.base_ring().characteristic(),gens), _vars, order=order, check=False)
-            
+              gens = str(base_ring.gens())
+            self.__singular = singular.ring( "(%s,%s)"%(base_ring.characteristic(),gens), _vars, order=order, check=False)
+
+        elif is_IntegerModRing(base_ring):
+            ch = base_ring.characteristic()
+            if ch.is_power_of(2):
+                exp = ch.nbits() -1
+                self.__singular = singular.ring("(integer,2,%d)"%(exp,), _vars, order=order, check=False)
+            else:
+                self.__singular = singular.ring("(integer,%d)"%(ch,), _vars, order=order, check=False)
+
+        elif base_ring is ZZ:
+            self.__singular = singular.ring("(integer)", _vars, order=order, check=False)
         else:    
             raise TypeError, "no conversion to a Singular ring defined"
 
@@ -282,7 +317,8 @@
              or is_ComplexDoubleField(base_ring)
              or number_field.all.is_NumberField(base_ring)
              or ( sage.rings.fraction_field.is_FractionField(base_ring) and ( base_ring.base_ring().is_prime_field() or base_ring.base_ring() is ZZ ) )
-             or base_ring is ZZ )
+             or base_ring is ZZ
+             or is_IntegerModRing(base_ring) )
 
 
 class Polynomial_singular_repr:
@@ -296,16 +332,16 @@
     Due to the incompatibility of Python extension classes and multiple inheritance, 
     this just defers to module-level functions. 
     """
-    def _singular_(self, singular=singular_default, have_ring=False, force=False):
-        return _singular_func(self, singular, have_ring, force)
-    def _singular_init_func(self, singular=singular_default, have_ring=False, force=False):
-        return _singular_init_func(self, singular, have_ring, force)
+    def _singular_(self, singular=singular_default, have_ring=False):
+        return _singular_func(self, singular, have_ring)
+    def _singular_init_func(self, singular=singular_default, have_ring=False):
+        return _singular_init_func(self, singular, have_ring)
     def lcm(self, singular=singular_default, have_ring=False):
         return lcm_func(self, singular, have_ring)
     def resultant(self, other, variable=None):
         return resultant_func(self, other, variable)
 
-def _singular_func(self, singular=singular_default, have_ring=False, force=False):
+def _singular_func(self, singular=singular_default, have_ring=False):
     """
     Return Singular polynomial matching this polynomial.
 
@@ -320,12 +356,6 @@
                      ring is singluar.current_ring().  (default:
                      False)
 
-        force -- polynomials over ZZ may be coerced to Singular by
-                 treating them as polynomials over QQ. This is
-                 inexact but works for some cases where the
-                 coeffients are not considered (default: False).
-
-
     EXAMPLES:
         sage: P.<a,b> = PolynomialRing(GF(7), 2)
         sage: f = (a^3 + 2*b^2*a)^7; f
@@ -349,7 +379,7 @@
         True
     """
     if not have_ring:
-        self.parent()._singular_(singular,force=force).set_ring() #this is expensive
+        self.parent()._singular_(singular).set_ring() #this is expensive
 
     try:
         self.__singular._check_valid()
@@ -360,7 +390,7 @@
 #    return self._singular_init_(singular,have_ring=have_ring)
     return _singular_init_func(self, singular,have_ring=have_ring)
 
-def _singular_init_func(self, singular=singular_default, have_ring=False, force=False):
+def _singular_init_func(self, singular=singular_default, have_ring=False):
     """
     Return corresponding Singular polynomial but enforce that a new
     instance is created in the Singular interpreter.
@@ -368,7 +398,7 @@
     Use self._singular_() instead.
     """
     if not have_ring:
-        self.parent()._singular_(singular,force=force).set_ring() #this is expensive
+        self.parent()._singular_(singular).set_ring() #this is expensive
 
     self.__singular = singular(str(self))
 
diff -r 6c7354ace3b6 -r 8037fada5b30 sage/rings/polynomial/polynomial_template.pxi
--- a/sage/rings/polynomial/polynomial_template.pxi	Sat Jun 06 09:55:28 2009 -0700
+++ b/sage/rings/polynomial/polynomial_template.pxi	Wed Jun 10 21:47:44 2009 -0700
@@ -687,14 +687,13 @@
         celement_delete(gen, _parent)
         return r
 
-    def _singular_(self, singular=singular_default, have_ring=False, force=False):
+    def _singular_(self, singular=singular_default, have_ring=False):
         r"""
         Return \Singular representation of this polynomial
 
         INPUT:
             singular -- \Singular interpreter (default: default interpreter)
             have_ring -- set to True if the ring was already set in \Singular
-            force -- ignored.
 
         EXAMPLE:
             sage: P.<x> = PolynomialRing(GF(7))
@@ -703,7 +702,7 @@
             3*x^2+2*x-2
         """
         if not have_ring:
-            self.parent()._singular_(singular,force=force).set_ring() #this is expensive
+            self.parent()._singular_(singular).set_ring() #this is expensive
         return singular(self._singular_init_())
 
     def _derivative(self, var=None):
diff -r 6c7354ace3b6 -r 8037fada5b30 sage/rings/polynomial/toy_buchberger.py
--- a/sage/rings/polynomial/toy_buchberger.py	Sat Jun 06 09:55:28 2009 -0700
+++ b/sage/rings/polynomial/toy_buchberger.py	Wed Jun 10 21:47:44 2009 -0700
@@ -1,42 +1,38 @@
 """
-Educational versions of Groebner basis algorithms.
+Educational Versions of Groebner Basis Algorithms.
 
-Following
-
-    [BW93] Thomas Becker and Volker Weispfenning. Groebner Bases - A
-           Computational Approach To Commutative Algebra. Springer,
-           New York 1993.
-
-the original Buchberger algorithm (c.f. algorithm GROEBNER in [BW93])
-and an improved version of Buchberger's algorithm (c.g. algorithm
-GROEBNERNEW2 in [BW93]) are presented.
+Following [BW93]_ the original Buchberger algorithm (c.f. algorithm
+GROEBNER in [BW93]_) and an improved version of Buchberger's algorithm
+(c.g. algorithm GROEBNERNEW2 in [BW93]_) are implemented.
 
 No attempt was made to optimize either algorithm as the emphasis of
 these implementations is a clean and easy presentation. To compute a
-Groebner basis in \SAGE efficently use the \code{groebner_basis}
-method on multivariate polynomial objects. 
+Groebner basis in Sage efficently use the ``groebner_basis()``
+method on multivariate polynomial objects.
 
-NOTE: the notion of 'term' and 'monomial' in [BW93] is swapped
-from the notion of those words in \SAGE (or the other way around,
-however you prefer it). In \SAGE a term is a monomial multiplied by a
-coefficient, while in [BW93] a monomial is a term multiplied by a
-coefficient. Also, what is called LM (the leading monomial) in \SAGE
-is called HT (the head term) in [BW93].
+
+.. note::
+
+   The notion of 'term' and 'monomial' in [BW93]_ is swapped from the
+   notion of those words in Sage (or the other way around, however you
+   prefer it). In Sage a term is a monomial multiplied by a
+   coefficient, while in [BW93]_ a monomial is a term multiplied by a
+   coefficient. Also, what is called LM (the leading monomial) in
+   Sage is called HT (the head term) in [BW93]_.
 
 EXAMPLES:
-    Consider Katsura-6 w.r.t. a $degrevlex$ ordering.
+
+Consider Katsura-6 w.r.t. a ``degrevlex`` ordering.::
 
     sage: from sage.rings.polynomial.toy_buchberger import *
     sage: P.<a,b,c,e,f,g,h,i,j,k> = PolynomialRing(GF(32003),10)
     sage: I = sage.rings.ideal.Katsura(P,6)
 
     sage: g1 = buchberger(I)
-
     sage: g2 = buchberger_improved(I)
-
     sage: g3 = I.groebner_basis()
 
-    All algorithms actually compute a Groebner basis:
+All algorithms actually compute a Groebner basis::
 
     sage: Ideal(g1).basis_is_groebner()
     True
@@ -45,12 +41,12 @@
     sage: Ideal(g3).basis_is_groebner()
     True
 
-    The results are correct:
+The results are correct::
 
     sage: Ideal(g1) == Ideal(g2) == Ideal(g3)
     True
 
-    If get_verbose() is $>= 1$ a protocol is provided:
+If ``get_verbose()`` is `>= 1` a protocol is provided::
 
     sage: set_verbose(1)
     sage: P.<a,b,c> = PolynomialRing(GF(127),3)
@@ -60,7 +56,8 @@
     sage: I
     Ideal (a + 2*b + 2*c - 1, a^2 + 2*b^2 + 2*c^2 - a, 2*a*b + 2*b*c - b) of Multivariate Polynomial Ring in a, b, c over Finite Field of size 127
 
-    The original Buchberger algorithm performs 15 useless reductions to zero for this example:
+The original Buchberger algorithm performs 15 useless reductions to
+zero for this example::
 
     sage: buchberger(I)
     (a + 2*b + 2*c - 1, a^2 + 2*b^2 + 2*c^2 - a) => -2*b^2 - 6*b*c - 6*c^2 + b + 2*c
@@ -120,7 +117,7 @@
     15 reductions to zero.
     [a + 2*b + 2*c - 1, -22*c^3 + 24*c^2 - 60*b - 62*c, 2*a*b + 2*b*c - b, a^2 + 2*b^2 + 2*c^2 - a, -2*b^2 - 6*b*c - 6*c^2 + b + 2*c, -5*b*c - 6*c^2 - 63*b + 2*c]
 
-    The 'improved' Buchberger algorithm in constrast only performs 3 reductions to zero:
+The 'improved' Buchberger algorithm in constrast only performs 3 reductions to zero:
 
     sage: buchberger_improved(I)
     (b^2 - 26*c^2 - 51*b + 51*c, b*c + 52*c^2 + 38*b + 25*c) => 11*c^3 - 12*c^2 + 30*b + 31*c
@@ -132,8 +129,15 @@
     1 reductions to zero.
     [a + 2*b + 2*c - 1, b^2 - 26*c^2 - 51*b + 51*c, c^3 + 22*c^2 - 55*b + 49*c, b*c + 52*c^2 + 38*b + 25*c]
 
+REFERENCES:
+
+.. [BW93] Thomas Becker and Volker Weispfenning. *Groebner Bases - A
+  Computational Approach To Commutative Algebra*. Springer, New York
+  1993.
+
 AUTHOR:
-    -- Martin Albrecht (2007-05-24): initial version
+
+- Martin Albrecht (2007-05-24): initial version
 """
 
 from sage.misc.misc import get_verbose
@@ -148,17 +152,20 @@
 def buchberger(F):
     """
     The original version of Buchberger's algorithm as presented in
-    [BW93], page 214.
+    [BW93]_, page 214.
 
     INPUT:
-        F -- an ideal in a multivariate polynomial ring
+
+    - ``F`` - an ideal in a multivariate polynomial ring
 
     OUTPUT:
         a Groebner basis for F
 
-    NOTE: The verbosity of this function may be controlled with a
-    \code{set_verbose()} call. Any value >=1 will result in this
-    function printing intermediate bases.
+    .. note:: 
+    
+       The verbosity of this function may be controlled with a
+       ``set_verbose()`` call. Any value >=1 will result in this
+       function printing intermediate bases.
     
     """
     G = set(F.gens())
@@ -190,17 +197,23 @@
 def buchberger_improved(F):
     """
     An improved version of Buchberger's algorithm as presented in
-    [BW93], page 232.
+    [BW93]_, page 232.
+
+    This variant uses the Gebauer-Moeller Installation to apply
+    Buchberger's first and second criterion to avoid useless pairs.
 
     INPUT:
-        F -- an ideal in a multivariate polynomial ring
+    
+    - ``F`` - an ideal in a multivariate polynomial ring
 
     OUTPUT:
         a Groebner basis for F
 
-    NOTE: The verbosity of this function may be controlled with a
-    \code{set_verbose()} call. Any value >=1 will result in this
-    function printing intermediate Groebner bases.
+    .. note:: 
+
+       The verbosity of this function may be controlled with a
+       ``set_verbose()`` call. Any value ``>=1`` will result in this
+       function printing intermediate Groebner bases.
     """
     F = inter_reduction(F.gens())
 
@@ -235,19 +248,21 @@
 
 def update(G,B,h):
     """
-    Update $G$ using the list of critical pairs $B$ and the polynomial
-    $h$ as presented in [BW93], page 230. For this, Buchberger's first
-    and second criterion are tested.
+    Update ``G`` using the list of critical pairs ``B`` and the
+    polynomial ``h`` as presented in [BW93]_, page 230. For this,
+    Buchberger's first and second criterion are tested.
+
+    This function implements the Gebauer-Moeller Installation.
 
     INPUT:
-        G -- an intermediate Groebner basis
-        B -- a list of critical pairs
-        h -- a polynomial
+
+    - ``G`` - an intermediate Groebner basis
+    - ``B`` - a list of critical pairs
+    - ``h`` - a polynomial
 
     OUTPUT:
         a tuple of an intermediate Groebner basis and a list of
         critical pairs
-
     """
     R = h.parent()
 
@@ -301,7 +316,8 @@
     The normal selection strategy
 
     INPUT:
-        P -- a list of critical pairs
+
+    - ``P`` - a list of critical pairs
 
     OUTPUT:
         an element of P
@@ -311,19 +327,21 @@
 
 def inter_reduction(Q):
     """
-    If $Q$ is the set $(f_1, ..., f_n)$ this method
-    returns $(g_1, ..., g_s)$ such that:
+    If ``Q`` is the set `(f_1, ..., f_n)` this method
+    returns `(g_1, ..., g_s)` such that:
 
-    * $(f_1,...,f_n) = (g_1,...,g_s)$
-    * $LT(g_i) != LT(g_j)$ for all $i != j$
-    * $LT(g_i)$ does not divide $m$ for all monomials m of
-      $\{g_1,...,g_{i-1},g_{i+1},...,g_s\}$
-    * $LC(g_i) == 1$ for all $i$.
+    - `<f_1,...,f_n> = <g_1,...,g_s>`
+    - `LM(g_i) != LM(g_j)` for all `i != j`
+    - `LM(g_i)` does not divide `m` for all monomials `m` of
+      `\{g_1,...,g_{i-1}, g_{i+1},...,g_s\}`
+    - `LC(g_i) == 1` for all `i`.
 
     INPUT:
-        Q -- a set of polynomials
+    
+    - ``Q`` - a set of polynomials
 
-    EXAMPLE:
+    EXAMPLE::
+
         sage: from sage.rings.polynomial.toy_buchberger import inter_reduction
         sage: inter_reduction(set())
         set([])
diff -r 6c7354ace3b6 -r 8037fada5b30 sage/rings/polynomial/toy_d_basis.py
--- a/sage/rings/polynomial/toy_d_basis.py	Sat Jun 06 09:55:28 2009 -0700
+++ b/sage/rings/polynomial/toy_d_basis.py	Wed Jun 10 21:47:44 2009 -0700
@@ -1,25 +1,23 @@
 r"""
-Educational versions of the $d$-Groebner basis algorithm from
+Educational version of the `d`-Groebner Basis Algorithm over PIDs.
 
- [BW93] Thomas Becker and Volker Weispfenning. Groebner Bases - A
-           Computational Approach To Commutative Algebra. Springer,
-           New York 1993.
+No attempt was made to optimize this algorithm as the emphasis of this
+implementation is a clean and easy presentation.
 
-No attempt was made to optimize this algorithm as the emphasis of
-this implementation is a clean and easy presentation.
+.. note::
 
-NOTE: the notion of 'term' and 'monomial' in [BW93] is swapped
-from the notion of those words in \SAGE (or the other way around,
-however you prefer it). In \SAGE a term is a monomial multiplied by a
-coefficient, while in [BW93] a monomial is a term multiplied by a
-coefficient. Also, what is called LM (the leading monomial) in \SAGE
-is called HT (the head term) in [BW93].
+   The notion of 'term' and 'monomial' in [BW93]_ is swapped from the
+   notion of those words in Sage (or the other way around, however you
+   prefer it). In Sage a term is a monomial multiplied by a
+   coefficient, while in [BW93]_ a monomial is a term multiplied by a
+   coefficient. Also, what is called LM (the leading monomial) in
+   Sage is called HT (the head term) in [BW93]_.
 
-EXAMPLE:
+EXAMPLE::
 
     sage: from sage.rings.polynomial.toy_d_basis import d_basis
 
-First, consider an example from arithmetic geometry:
+First, consider an example from arithmetic geometry::
 
     sage: A.<x,y> = PolynomialRing(ZZ, 2)
     sage: B.<X,Y> = PolynomialRing(Rationals(),2)
@@ -34,24 +32,24 @@
 singularities.
 
 To look at the singularities of the arithmetic surface, we need to do
-the corresponding computation over \ZZ:
+the corresponding computation over `\ZZ`::
  
     sage: I = A.ideal([f,fx,fy])
     sage: gb = d_basis(I); gb
-    [x - 2020, y + 11314, 22627]
+    [x - 2020, y - 11313, 22627]
     
     sage: gb[-1].factor()
     11^3 * 17
 
 This Groebner Basis gives a lot of information.  First, the only
-fibers (over \ZZ) that are not smooth are at 11 = 0, and 17 = 0.
+fibers (over `\ZZ`) that are not smooth are at 11 = 0, and 17 = 0.
 Examining the Groebner Basis, we see that we have a simple node in
 both the fiber at 11 and at 17.  From the factorization, we see that
-the node at 17 is regular on the surface (an $I_1$ node), but the node
+the node at 17 is regular on the surface (an `I_1` node), but the node
 at 11 is not.  After blowing up this non-regular point, we find that
-it is an $I_3$ node.
+it is an `I_3` node.
 
-Another example. This one is from the \Magma Handbook:
+Another example. This one is from the Magma Handbook::
 
     sage: P.<x, y, z> = PolynomialRing(IntegerRing(), 3, order='lex')
     sage: I = ideal( x^2 - 1, y^2 - 1, 2*x*y - z)
@@ -61,39 +59,39 @@
     sage: (2*x).reduce(I)
     y*z
 
-To compute modulo 4, we can add the generator 4 to our basis.
+To compute modulo 4, we can add the generator 4 to our basis.::
 
     sage: I = ideal( x^2 - 1, y^2 - 1, 2*x*y - z, 4)
     sage: gb = d_basis(I)
     sage: R = P.change_ring(IntegerModRing(4))
     sage: gb = [R(f) for f in gb if R(f)]; gb
-    [x^2 + 3, x*z + 2*y, 2*x - y*z, y^2 + 3, z^2, 2*z]
+    [x^2 - 1, x*z + 2*y, 2*x - y*z, y^2 - 1, z^2, 2*z]
 
-A third example is also from the \Magma Handbook:
+A third example is also from the Magma Handbook.
 
 This example shows how one can use Groebner bases over the integers to
 find the primes modulo which a system of equations has a solution,
 when the system has no solutions over the rationals.
 
-We first form a certain ideal $I$ in $\ZZ[x, y, z]$, and note that the
-Groebner basis of $I$ over \QQ contains 1, so there are no solutions
-over \QQ or an algebraic closure of it (this is not surprising as
-there are 4 equations in 3 unknowns).
+We first form a certain ideal `I` in `\ZZ[x, y, z]`, and note that the
+Groebner basis of `I` over `\QQ` contains 1, so there are no solutions
+over `\QQ` or an algebraic closure of it (this is not surprising as
+there are 4 equations in 3 unknowns).::
 
     sage: P.<x, y, z> = PolynomialRing(IntegerRing(), 3)
     sage: I = ideal( x^2 - 3*y, y^3 - x*y, z^3 - x, x^4 - y*z + 1 )
     sage: I.change_ring( P.change_ring( RationalField() ) ).groebner_basis()
     [1]
 
-However, when we compute the Groebner basis of I (defined over \ZZ), we
-note that there is a certain integer in the ideal which is not 1.
+However, when we compute the Groebner basis of I (defined over `\ZZ`), we
+note that there is a certain integer in the ideal which is not 1.::
 
     sage: d_basis(I)
     [x + 170269749119, y + 2149906854, z + ..., 282687803443]
 
-Now for each prime $p$ dividing this integer 282687803443, the Groebner
-basis of I modulo $p$ will be non-trivial and will thus give a solution
-of the original system modulo $p$.
+Now for each prime `p` dividing this integer 282687803443, the Groebner
+basis of I modulo `p` will be non-trivial and will thus give a solution
+of the original system modulo `p`.::
 
     sage: factor(282687803443)
     101 * 103 * 27173681
@@ -108,13 +106,14 @@
     [x - 536027, y + 3186055, z + 10380032]
 
 Of course, modulo any other prime the Groebner basis is trivial so
-there are no other solutions. For example:
+there are no other solutions. For example::
 
     sage: I.change_ring( P.change_ring( GF(3) ) ).groebner_basis()
     [1]
 
 AUTHOR:
-    -- Martin Albrecht (2008-08): initial version
+
+- Martin Albrecht (2008-08): initial version
 """
 
 from sage.rings.integer_ring import ZZ
@@ -123,18 +122,20 @@
 from sage.structure.sequence import Sequence
 
 def spol(g1,g2):
-    r"""
-    Return S-Polynomial of $g_1$ and $g_2$.
+    """
+    Return S-Polynomial of ``g_1`` and ``g_2``.
 
-    Let $a_it_i$ be $LT(g_i)$, $b_i = a/a_i$ with $a = LCM(a_i,a_j)$,
-    and $s_i = t/t_i$ with $t = LCM(t_i,t_j)$. Then the S-Polynomial
-    is defined as: $b_1s_1g_1 - b_2s_2g_2$.
+    Let `a_i t_i` be `LT(g_i)`, `b_i = a/a_i` with `a = LCM(a_i,a_j)`,
+    and `s_i = t/t_i` with `t = LCM(t_i,t_j)`. Then the S-Polynomial
+    is defined as: `b_1s_1g_1 - b_2s_2g_2`.
 
     INPUT:
-        g1 -- polynomial
-        g2 -- polynomial
 
-    EXAMPLE:
+    - ``g1`` - polynomial
+    - ``g2`` - polynomial
+
+    EXAMPLE::
+
         sage: from sage.rings.polynomial.toy_d_basis import spol
         sage: P.<x, y, z> = PolynomialRing(IntegerRing(), 3, order='lex')
         sage: f = x^2 - 1
@@ -154,17 +155,19 @@
 
 def gpol(g1,g2):
     """
-    Return G-Polynomial of $g_1$ and $g_2$.
+    Return G-Polynomial of ``g_1`` and ``g_2``.
 
-    Let $a_i*t_i$ be $LT(g_i)$, $a = a_i*c_i + a_j*c_j$ with $a =
-    GCD(a_i,a_j)$, and $s_i = t/t_i$ with $t = LCM(t_i,t_j)$. Then the
-    S-Polynomial is defined as: $c_1s_1g_1 - c_2s_2g_2$.
+    Let `a_i t_i` be `LT(g_i)`, `a = a_i*c_i + a_j*c_j` with `a =
+    GCD(a_i,a_j)`, and `s_i = t/t_i` with `t = LCM(t_i,t_j)`. Then the
+    G-Polynomial is defined as: `c_1s_1g_1 - c_2s_2g_2`.
 
     INPUT:
-        g1 -- polynomial
-        g2 -- polynomial
 
-    EXAMPLE:
+    - ``g1`` - polynomial
+    - ``g2`` - polynomial
+
+    EXAMPLE::
+
         sage: from sage.rings.polynomial.toy_d_basis import gpol
         sage: P.<x, y, z> = PolynomialRing(IntegerRing(), 3, order='lex')
         sage: f = x^2 - 1
@@ -187,17 +190,15 @@
 
 def d_basis(F, strat=True):
     r"""
-    Return the d-basis for the Ideal \var{F} as defined in 
-
-    [BW93] Thomas Becker and Volker Weispfenning. Groebner Bases - A
-           Computational Approach To Commutative Algebra. Springer,
-           New York 1993.
+    Return the `d`-basis for the Ideal ``F`` as defined in [BW93]_.
 
     INPUT:
-        F -- an ideal
-        strat -- use update strategy (default: \code{True})
 
-    EXAMPLE:
+    - ``F`` - an ideal
+    - ``strat`` - use update strategy (default: ``True``)
+
+    EXAMPLE::
+
         sage: from sage.rings.polynomial.toy_d_basis import d_basis
         sage: A.<x,y> = PolynomialRing(ZZ, 2)
         sage: f = -y^2 - y + x^3 + 7*x + 1
@@ -205,7 +206,7 @@
         sage: fy = f.derivative(y)
         sage: I = A.ideal([f,fx,fy])
         sage: gb = d_basis(I); gb
-        [x - 2020, y + 11314, 22627]
+        [x - 2020, y - 11313, 22627]
     """
     R = F.ring()
     K = R.base_ring()
@@ -260,15 +261,17 @@
 
 def select(P):
     """
-    The normal selection strategy
+    The normal selection strategy.
 
     INPUT:
-        P -- a list of critical pairs
+
+    - ``P`` - a list of critical pairs
 
     OUTPUT:
         an element of P
 
-    EXAMPLE:
+    EXAMPLE::
+
         sage: from sage.rings.polynomial.toy_d_basis import select
         sage: A.<x,y> = PolynomialRing(ZZ, 2)
         sage: f = -y^2 - y + x^3 + 7*x + 1
@@ -290,19 +293,23 @@
 
 def update(G,B,h):
     """
-    Update $G$ using the list of critical pairs $B$ and the polynomial
-    $h$ as presented in [BW93], page 230. For this, Buchberger's first
-    and second criterion are tested.
+    Update ``G`` using the list of critical pairs ``B`` and the
+    polynomial ``h`` as presented in [BW93]_, page 230. For this,
+    Buchberger's first and second criterion are tested.
+
+    This function uses the Gebauer-Moeller Installation.
 
     INPUT:
-        G -- an intermediate Groebner basis
-        B -- a list of critical pairs
-        h -- a polynomial
+
+    - ``G`` - an intermediate Groebner basis
+    - ``B`` - a list of critical pairs
+    - ``h`` - a polynomial
 
     OUTPUT:
-        G,B where G and B are updated
+        ``G,B`` where ``G`` and ``B`` are updated
 
-    EXAMPLE:
+    EXAMPLE::
+
         sage: from sage.rings.polynomial.toy_d_basis import update
         sage: A.<x,y> = PolynomialRing(ZZ, 2)
         sage: G = set([3*x^2 + 7, 2*y + 1, x^3 - y^2 + 7*x - y + 1])
