Ticket #11339: trac_11339_refcount_singular_polynomials.patch

File trac_11339_refcount_singular_polynomials.patch, 65.3 KB (added by vbraun, 10 years ago)

Updated patch

  • sage/libs/singular/ring.pyx

    # HG changeset patch
    # User Volker Braun <vbraun@stp.dias.ie>
    # Date 1317064847 -7200
    # Node ID e4388ef9ba0f236f4dabc62e154235838180e595
    # Parent  dca107e84dc194d9dae39c5e7e5e24c684dcda34
    Trac #11339: Refcount singular rings
    
    This patch switches over the Singular-based multivariate polynomial ring
    and polynomials to the refcounted rings. Lots of cleanup and some minor
    bugfixes.
    
    diff --git a/sage/libs/singular/ring.pyx b/sage/libs/singular/ring.pyx
    a b  
    223223        raise NotImplementedError("Base ring is not supported.")
    224224
    225225    _ring = <ring*>omAlloc0Bin(sip_sring_bin)
     226    if (_ring is NULL):
     227        raise ValueError("Failed to allocate Singular ring.")
    226228    _ring.ch = characteristic
    227229    _ring.ringtype = ringtype
    228230    _ring.N = n
  • sage/rings/polynomial/multi_polynomial_libsingular.pxd

    diff --git a/sage/rings/polynomial/multi_polynomial_libsingular.pxd b/sage/rings/polynomial/multi_polynomial_libsingular.pxd
    a b  
    88
    99cdef class MPolynomial_libsingular(MPolynomial):
    1010    cdef poly *_poly
     11    cdef ring *_parent_ring
    1112    cpdef _repr_short_(self)
    1213    cpdef is_constant(self)
    1314    cpdef _homogenize(self, int var)
  • sage/rings/polynomial/multi_polynomial_libsingular.pyx

    diff --git a/sage/rings/polynomial/multi_polynomial_libsingular.pyx b/sage/rings/polynomial/multi_polynomial_libsingular.pyx
    a b  
    3636- Simon King (2011-03): Use a faster way of conversion from the base
    3737  ring.
    3838
     39- Volker Braun (2011-06): Major cleanup, refcount singular rings.
     40
    3941TODO:
    4042
    4143- implement Real, Complex coefficient rings via libSINGULAR
     
    150152    b - 1728*c
    151153"""
    152154
     155# The Singular API is as follows:
     156#
     157#   pXXX does assume the currRing to be set
     158#   p_XXX does not.
     159#
     160# However, sometimes there are bugs, i.e. you call p_XXX and it
     161# crashes unless currRing is set.
     162#
     163# Notable exceptions:
     164#   * pNext and pIter don't need currRing
     165#   * p_Normalize apparently needs currRing
     166
    153167include "sage/ext/stdsage.pxi"
    154168include "sage/ext/interrupt.pxi"
    155169
     
    157171from sage.libs.singular.decl cimport ring, poly, ideal, intvec, number, currRing
    158172
    159173# singular functions
    160 from sage.libs.singular.decl cimport p_ISet, rChangeCurrRing, p_Copy, p_Init, p_SetCoeff, p_Setm, p_SetExp, p_Add_q
    161 from sage.libs.singular.decl cimport p_NSet, p_GetCoeff, p_Delete, p_GetExp, pNext, rRingVar, omAlloc0, omStrDup
    162 from sage.libs.singular.decl cimport omFree, pDivide, p_SetCoeff0, n_Init, p_DivisibleBy, pLcm, p_LmDivisibleBy
    163 from sage.libs.singular.decl cimport pDivide, p_IsConstant, p_ExpVectorEqual, p_String, p_LmInit, n_Copy
    164 from sage.libs.singular.decl cimport p_IsUnit, pInvers, n_IsOne, p_Head, pSubst, idInit, fast_map, id_Delete
    165 from sage.libs.singular.decl cimport pIsHomogeneous, pHomogen, pTotaldegree, singclap_pdivide, singclap_factorize
    166 from sage.libs.singular.decl cimport delete, idLift, IDELEMS, On, Off, SW_USE_CHINREM_GCD, SW_USE_EZGCD
    167 from sage.libs.singular.decl cimport p_LmIsConstant, pTakeOutComp1, singclap_gcd, pp_Mult_qq, p_GetMaxExp
    168 from sage.libs.singular.decl cimport pLength, kNF, singclap_isSqrFree, p_Neg, p_Minus_mm_Mult_qq, p_Plus_mm_Mult_qq
    169 from sage.libs.singular.decl cimport pDiff, singclap_resultant, p_Normalize
    170 from sage.libs.singular.decl cimport prCopyR, prCopyR_NoSort
     174from sage.libs.singular.decl cimport (
     175    p_ISet, rChangeCurrRing, p_Copy, p_Init, p_SetCoeff, p_Setm, p_SetExp, p_Add_q,
     176    p_NSet, p_GetCoeff, p_Delete, p_GetExp, pNext, rRingVar, omAlloc0, omStrDup,
     177    omFree, pDivide, p_SetCoeff0, n_Init, p_DivisibleBy, pLcm, p_LmDivisibleBy,
     178    pDivide, p_IsConstant, p_ExpVectorEqual, p_String, p_LmInit, n_Copy,
     179    p_IsUnit, pInvers, n_IsOne, p_Head, pSubst, idInit, fast_map, id_Delete,
     180    pIsHomogeneous, pHomogen, pTotaldegree, singclap_pdivide, singclap_factorize,
     181    delete, idLift, IDELEMS, On, Off, SW_USE_CHINREM_GCD, SW_USE_EZGCD,
     182    p_LmIsConstant, pTakeOutComp1, singclap_gcd, pp_Mult_qq, p_GetMaxExp,
     183    pLength, kNF, singclap_isSqrFree, p_Neg, p_Minus_mm_Mult_qq, p_Plus_mm_Mult_qq,
     184    pDiff, singclap_resultant, p_Normalize,
     185    prCopyR, prCopyR_NoSort )
    171186
    172187# singular conversion routines
    173188from sage.libs.singular.singular cimport si2sa, sa2si, overflow_check
    174189
    175190# singular poly arith
    176 from sage.libs.singular.polynomial cimport singular_polynomial_call, singular_polynomial_cmp, singular_polynomial_add, singular_polynomial_sub, singular_polynomial_neg
    177 from sage.libs.singular.polynomial cimport singular_polynomial_rmul, singular_polynomial_mul, singular_polynomial_div_coeff, singular_polynomial_pow
    178 from sage.libs.singular.polynomial cimport singular_polynomial_str, singular_polynomial_latex, singular_polynomial_str_with_changed_varnames
    179 from sage.libs.singular.polynomial cimport singular_polynomial_deg
    180 from sage.libs.singular.polynomial cimport singular_polynomial_length_bounded
     191from sage.libs.singular.polynomial cimport (
     192    singular_polynomial_call, singular_polynomial_cmp, singular_polynomial_add,
     193    singular_polynomial_sub, singular_polynomial_neg, singular_polynomial_rmul,
     194    singular_polynomial_mul, singular_polynomial_div_coeff, singular_polynomial_pow,
     195    singular_polynomial_str, singular_polynomial_latex,
     196    singular_polynomial_str_with_changed_varnames, singular_polynomial_deg,
     197    singular_polynomial_length_bounded )
    181198
    182199# singular rings
    183 from sage.libs.singular.ring cimport singular_ring_new, singular_ring_delete
     200from sage.libs.singular.ring cimport singular_ring_new, singular_ring_reference, singular_ring_delete
    184201
    185202# polynomial imports
    186203from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_polydict_domain
     
    226243import polynomial_element
    227244
    228245cdef class MPolynomialRing_libsingular(MPolynomialRing_generic):
     246
     247    def __cinit__(self):
     248        """
     249        The Cython constructor.
     250
     251        EXAMPLES::
     252
     253            sage: from sage.rings.polynomial.multi_polynomial_libsingular import MPolynomialRing_libsingular
     254            sage: MPolynomialRing_libsingular(QQ, 3, ('x', 'y', 'z'), TermOrder('degrevlex', 3))
     255            Multivariate Polynomial Ring in x, y, z over Rational Field
     256            sage: type(_)
     257            <type 'sage.rings.polynomial.multi_polynomial_libsingular.MPolynomialRing_libsingular'>
     258
     259            sage: P.<x,y,z> = QQ[]; P
     260            Multivariate Polynomial Ring in x, y, z over Rational Field
     261            sage: type(P)
     262            <type 'sage.rings.polynomial.multi_polynomial_libsingular.MPolynomialRing_libsingular'>
     263        """
     264        self._ring = NULL
     265
    229266    def __init__(self, base_ring, n, names, order='degrevlex'):
    230267        """
    231268        Construct a multivariate polynomial ring subject to the
     
    307344            Polynomial base injection morphism:
    308345              From: Integer Ring
    309346              To:   Multivariate Polynomial Ring in x, y over Integer Ring
    310 
    311347        """
    312348        MPolynomialRing_generic.__init__(self, base_ring, n, names, order)
    313349        self._has_singular = True
    314350        assert(n == len(self._names))
    315351        self.__ngens = n
    316352        self._ring = singular_ring_new(base_ring, n, self._names, order)
    317         self._one_element = <MPolynomial_libsingular>new_MP(self,p_ISet(1, self._ring))
    318         self._one_element_poly = (<MPolynomial_libsingular>self._one_element)._poly
    319         self._zero_element = <MPolynomial_libsingular>new_MP(self,NULL)
     353        self._zero_element = new_MP(self, NULL)
     354        cdef MPolynomial_libsingular one = new_MP(self, p_ISet(1, self._ring))
     355        self._one_element = one
     356        self._one_element_poly = one._poly
    320357        # This polynomial ring should belong to Algebras(base_ring).
    321358        # Algebras(...).parent_class, which was called from MPolynomialRing_generic.__init__,
    322359        # tries to provide a conversion from the base ring, if it does not exist.
     
    329366
    330367    def __dealloc__(self):
    331368        r"""
    332         Carefully deallocate the ring, without changing "currRing"
    333         (since this method can be at unpredictable times due to garbage
    334         collection).
     369        Deallocate the ring without changing ``currRing``
    335370
    336371        TESTS:
     372
    337373        This example caused a segmentation fault with a previous version
    338         of this method:
     374        of this method::
     375
    339376            sage: import gc
    340377            sage: from sage.rings.polynomial.multi_polynomial_libsingular import MPolynomialRing_libsingular
    341378            sage: R1 = MPolynomialRing_libsingular(GF(5), 2, ('x', 'y'), TermOrder('degrevlex', 2))
     
    351388            sage: del R3
    352389            sage: _ = gc.collect()
    353390        """
    354         singular_ring_delete(self._ring)
     391        if self._ring != NULL:  # the constructor did not raise an exception
     392            singular_ring_delete(self._ring)
     393
     394    def __copy__(self):
     395        """
     396        Copy ``self``.
     397       
     398        The ring is unique and immutable, so we do not copy.
     399
     400        TESTS::
     401       
     402            sage: import gc
     403            sage: from sage.rings.polynomial.multi_polynomial_libsingular import MPolynomialRing_libsingular
     404            sage: from sage.libs.singular.ring import ring_refcount_dict
     405            sage: n = len(ring_refcount_dict)
     406            sage: R = MPolynomialRing_libsingular(GF(547), 2, ('x', 'y'), TermOrder('degrevlex', 2))
     407            sage: len(ring_refcount_dict) == n + 1
     408            True
     409
     410            sage: Q = copy(R)   # indirect doctest
     411            sage: p = R.gen(0) ^2+R.gen(1)^2
     412            sage: q = copy(p)
     413            sage: del R
     414            sage: del Q
     415            sage: del p
     416            sage: del q
     417            sage: gc.collect() # random output
     418            sage: len(ring_refcount_dict) == n   
     419            True
     420        """
     421        return self
     422
     423    def __deepcopy__(self, memo):
     424        """
     425        Deep copy ``self``.
     426
     427        The ring should be immutable, so we do not copy.
     428
     429        TESTS::
     430       
     431            sage: R.<x,y> = GF(547)[]
     432            sage: R is deepcopy(R)   # indirect doctest
     433            True
     434        """
     435        memo[id(self)] = self
     436        return self
    355437
    356438    cdef _coerce_c_impl(self, element):
    357439        """
     
    440522            5
    441523        """
    442524        cdef poly *_p
    443         cdef ring *_ring
     525        cdef ring *_ring = self._ring
    444526        cdef number *_n
    445527        cdef poly *mon
    446528        cdef int i
    447            
    448         _ring = self._ring
    449529
    450530        base_ring = self.base_ring()
    451531
    452         if(_ring != currRing): rChangeCurrRing(_ring)
    453 
    454         if PY_TYPE_CHECK(element, MPolynomial_libsingular):
    455             if element.parent() is <object>self:
     532        if isinstance(element, MPolynomial_libsingular):
     533            n = (<MPolynomial_libsingular>element)._parent.ngens()
     534            if element.parent() is self:
    456535                return element
    457             elif element.parent() == self:
    458                 # is this safe?
    459                 _p = p_Copy((<MPolynomial_libsingular>element)._poly, _ring)
    460536            elif base_ring is element.base_ring() and \
    461                     self.ngens() >= (<MPolynomial_libsingular>element)._parent.ngens() and \
    462                     self.variable_names()[:(<MPolynomial_libsingular>element)._parent.ngens()] == (<MPolynomial_libsingular>element)._parent.variable_names():
     537                    self.ngens() >= n and \
     538                    self.variable_names()[:n] == (<MPolynomial_libsingular>element)._parent.variable_names():
    463539                if self.term_order() == (<MPolynomial_libsingular>element)._parent.term_order():
    464                     _p = prCopyR_NoSort((<MPolynomial_libsingular>element)._poly, (<MPolynomialRing_libsingular>(<MPolynomial_libsingular>element)._parent)._ring, _ring)
     540                    _p = prCopyR_NoSort((<MPolynomial_libsingular>element)._poly,
     541                                        (<MPolynomial_libsingular>element)._parent_ring,
     542                                        _ring)
    465543                else:
    466                     _p = prCopyR((<MPolynomial_libsingular>element)._poly, (<MPolynomialRing_libsingular>(<MPolynomial_libsingular>element)._parent)._ring, _ring)
     544                    _p = prCopyR((<MPolynomial_libsingular>element)._poly,
     545                                 (<MPolynomial_libsingular>element)._parent_ring, _ring)
    467546            elif base_ring.has_coerce_map_from(element.parent()._mpoly_base_ring(self.variable_names())):
    468547                return self(element._mpoly_dict_recursive(self.variable_names(), base_ring))
    469548            else:
    470549                raise TypeError, "parents do not match"
    471550
    472         elif PY_TYPE_CHECK(element, MPolynomial_polydict):
     551        elif isinstance(element, MPolynomial_polydict):
    473552            if (<Element>element)._parent == self:
    474553                _p = p_ISet(0, _ring)
    475554                for (m,c) in element.element().dict().iteritems():
     
    495574            else:
    496575                raise TypeError("incompatable parents.")
    497576           
    498         elif PY_TYPE_CHECK(element, CommutativeRingElement):
     577        elif isinstance(element, CommutativeRingElement):
    499578            # base ring elements
    500579            if  <Parent>element.parent() is base_ring:
    501580                # shortcut for GF(p)
     
    519598                _p = p_NSet(_n, _ring)
    520599
    521600        # Accepting int
    522         elif PY_TYPE_CHECK(element, int):
     601        elif isinstance(element, int):
    523602            if isinstance(base_ring, FiniteField_prime_modn):
    524603                _p = p_ISet(int(element) % _ring.ch,_ring)
    525604            else:
     
    527606                _p = p_NSet(_n, _ring)
    528607
    529608        # and longs
    530         elif PY_TYPE_CHECK(element, long):
     609        elif isinstance(element, long):
    531610            if isinstance(base_ring, FiniteField_prime_modn):
    532611                element = element % self.base_ring().characteristic()
    533                 _p = p_ISet(int(element),_ring)
     612                _p = p_ISet(int(element), _ring)
    534613            else:
    535614                _n = sa2si(base_ring(element),_ring)
    536615                _p = p_NSet(_n, _ring)
    537616        else:
    538617            raise TypeError, "Cannot coerce element"
    539618
    540         return new_MP(self,_p)
     619        return new_MP(self, _p)
    541620
    542621    def __call__(self, element):
    543622        """
     
    687766            0
    688767            sage: P.<x,y> = Zmod(2^10)[]; P(0)
    689768            0
    690 
    691769        """
    692         cdef poly *_p, *mon, *_element
     770        cdef poly *_p, *mon, *El_poly
    693771        cdef ring *_ring = self._ring
    694772        cdef ring *El_ring
     773        cdef long mpos
    695774        cdef MPolynomial_libsingular Element
    696775        cdef MPolynomialRing_libsingular El_parent
    697776        cdef unsigned int i, j
    698         if _ring!=currRing: rChangeCurrRing(_ring)
    699777        cdef list ind_map = []
    700778        cdef int e
     779        if _ring!=currRing: rChangeCurrRing(_ring)
    701780
    702781        # try to coerce first
    703782        try:
     
    705784        except TypeError:
    706785            pass
    707786
    708         if PY_TYPE_CHECK(element, SingularElement) or \
    709            PY_TYPE_CHECK(element, sage.libs.pari.gen.gen):
     787        if isinstance(element, (SingularElement, sage.libs.pari.gen.gen)):
    710788            element = str(element)
    711789       
    712         if PY_TYPE_CHECK(element, MPolynomial_libsingular) and element.parent() is not self and element.parent() != self:
    713 
     790        if isinstance(element, MPolynomial_libsingular) and element.parent() is not self and element.parent() != self:
    714791            variable_names_s = element.parent().variable_names()
    715792            variable_names_t = self.variable_names()
    716793
     
    726803                K = self.base_ring()
    727804                base = self._base
    728805                Element = <MPolynomial_libsingular>element
    729                 _element = Element._poly
    730                 El_parent = <MPolynomialRing_libsingular>Element.parent()
    731                 El_ring = El_parent._ring
     806                El_poly = Element._poly
     807                El_parent = Element._parent
     808                El_ring = Element._parent_ring
    732809                El_base = El_parent._base
    733810
    734                 while _element:
     811                while El_poly:
    735812                    rChangeCurrRing(El_ring)
    736                     c = si2sa(p_GetCoeff(_element, El_ring), El_ring, El_base)
     813                    c = si2sa(p_GetCoeff(El_poly, El_ring), El_ring, El_base)
    737814                    try:
    738815                        c = K(c)
    739816                    except TypeError, msg:
     
    742819                    if c:
    743820                        rChangeCurrRing(_ring)
    744821                        mon = p_Init(_ring)
    745                         p_SetCoeff(mon, sa2si(c , _ring), _ring)
     822                        p_SetCoeff(mon, sa2si(c, _ring), _ring)
    746823                        for j from 1 <= j <= El_ring.N:
    747                             e = p_GetExp(_element, j, El_ring)
     824                            e = p_GetExp(El_poly, j, El_ring)
    748825                            if e:
    749826                                p_SetExp(mon, ind_map[j-1], e, _ring)
    750827                        p_Setm(mon, _ring)
    751828                        _p = p_Add_q(_p, mon, _ring)
    752                     _element = pNext(_element)
     829                    El_poly = pNext(El_poly)
    753830                return new_MP(self, _p)
    754831
    755         if PY_TYPE_CHECK(element, MPolynomial_polydict):
    756 
     832        if isinstance(element, MPolynomial_polydict):
    757833            variable_names_s = element.parent().variable_names()
    758834            variable_names_t = self.variable_names()
    759835
     
    784860                return new_MP(self, _p)
    785861
    786862        from sage.rings.polynomial.pbori import BooleanPolynomial
    787 
    788         if PY_TYPE_CHECK(element, BooleanPolynomial):
    789 
     863        if isinstance(element, BooleanPolynomial):
    790864            if element.constant():
    791865                if element:
    792866                    return self._one_element
    793867                else:
    794868                    return self._zero_element
    795869
    796 
    797870            variable_names_s = set(element.parent().variable_names())
    798871            variable_names_t = self.variable_names()
    799872
     
    805878                gens_map = dict(zip(Q.variable_names(),self.gens()[:Q.ngens()]))
    806879                return eval(str(element),gens_map)
    807880
    808         if PY_TYPE_CHECK(element, basestring):
     881        if isinstance(element, basestring):
    809882            # let python do the parsing
    810883            d = self.gens_dict()
    811884            if self.base_ring().gen() != 1:
     
    823896            # element in self.
    824897            return self._coerce_c(element)
    825898
    826         if PY_TYPE_CHECK(element, dict):
     899        if isinstance(element, dict):
    827900            _p = p_ISet(0, _ring)
    828901            K = self.base_ring()
    829902            for (m,c) in element.iteritems():
     
    926999            raise ValueError, "Generator not defined."
    9271000
    9281001        rChangeCurrRing(_ring)
    929         _p = p_ISet(1,_ring)
     1002        _p = p_ISet(1, _ring)
    9301003        p_SetExp(_p, n+1, 1, _ring)
    9311004        p_Setm(_p, _ring);
    9321005
    933         return new_MP(self,_p)
     1006        return new_MP(self, _p)
    9341007
    9351008    def ideal(self, *gens, **kwds):
    9361009        """
     
    10981171                return R
    10991172            if self.base_ring().is_prime_field():
    11001173                return R
    1101             if self.base_ring().is_finite()  or (PY_TYPE_CHECK(self.base_ring(), NumberField) and self.base_ring().is_absolute()):
     1174            if self.base_ring().is_finite() \
     1175                    or (isinstance(self.base_ring(), NumberField) and self.base_ring().is_absolute()):
    11021176                R.set_ring() #sorry for that, but needed for minpoly
    11031177                if  singular.eval('minpoly') != "(" + self.__minpoly + ")":
    11041178                    singular.eval("minpoly=%s"%(self.__minpoly))
     
    13071381        - their generator names match and
    13081382        - their term orderings match.
    13091383
    1310 
    13111384        EXAMPLES::
    13121385
    13131386            sage: P.<x,y,z> = QQ[]
     
    13301403        return (<Parent>left)._richcmp(right, op)
    13311404   
    13321405    cdef int _cmp_c_impl(left, Parent right) except -2:
    1333         if PY_TYPE_CHECK(right, MPolynomialRing_libsingular) or PY_TYPE_CHECK(right, MPolynomialRing_polydict_domain):
    1334             return cmp( (left.base_ring(), map(str, left.gens()), left.term_order()),
    1335                         (right.base_ring(), map(str, right.gens()), right.term_order())
    1336                         )
     1406        if isinstance(right, (MPolynomialRing_libsingular, MPolynomialRing_polydict_domain)):
     1407            return cmp((left.base_ring(), map(str, left.gens()), left.term_order()),
     1408                       (right.base_ring(), map(str, right.gens()), right.term_order()))
    13371409        else:
    13381410            return cmp(type(left),type(right))
    13391411
     
    13661438            sage: P == loads(dumps(P))
    13671439            True
    13681440        """
    1369         return sage.rings.polynomial.multi_polynomial_libsingular.unpickle_MPolynomialRing_libsingular, ( self.base_ring(),
    1370                                                                                                map(str, self.gens()),
    1371                                                                                                self.term_order() )
     1441        return sage.rings.polynomial.multi_polynomial_libsingular.unpickle_MPolynomialRing_libsingular, \
     1442            (self.base_ring(), map(str, self.gens()), self.term_order())
    13721443
    13731444    def __temporarily_change_names(self, names, latex_names):
    13741445        """
     
    13821453            ...
    13831454            z^3 + w^3 - z*w
    13841455        """
    1385         cdef ring *_ring = (<MPolynomialRing_libsingular>self)._ring
     1456        cdef ring *_ring = self._ring
    13861457        cdef char **_names, **_orig_names
    13871458        cdef char *_name
    13881459        cdef int i
     
    14941565        if not g._poly:
    14951566            raise ZeroDivisionError
    14961567
    1497         res = pDivide(f._poly,g._poly)
     1568        res = pDivide(f._poly, g._poly)
    14981569        if coeff:
    14991570            if r.ringtype == 0 or r.cf.nDivBy(p_GetCoeff(f._poly, r), p_GetCoeff(g._poly, r)):
    15001571                n = r.cf.nDiv( p_GetCoeff(f._poly, r) , p_GetCoeff(g._poly, r))
     
    15381609        cdef poly *_b
    15391610        cdef ring *_r
    15401611        if a._parent is not b._parent:
    1541             b = (<MPolynomialRing_libsingular>a._parent)._coerce_c(b)
     1612            b = a._parent._coerce_c(b)
    15421613
    15431614        _a = a._poly
    15441615        _b = b._poly
    1545         _r = (<MPolynomialRing_libsingular>a._parent)._ring
     1616        _r = a._parent_ring
    15461617
    15471618        if _a == NULL:
    15481619            raise ZeroDivisionError
     
    16491720            return f,f
    16501721       
    16511722        for g in G:
    1652             if PY_TYPE_CHECK(g, MPolynomial_libsingular) \
     1723            if isinstance(g, MPolynomial_libsingular) \
    16531724                   and (<MPolynomial_libsingular>g) \
     1725                   and g.parent() is self \
    16541726                   and p_LmDivisibleBy((<MPolynomial_libsingular>g)._poly, m, r):
    16551727                flt = pDivide(f._poly, (<MPolynomial_libsingular>g)._poly)
    16561728                #p_SetCoeff(flt, n_Div( p_GetCoeff(f._poly, r) , p_GetCoeff((<MPolynomial_libsingular>g)._poly, r), r), r)
     
    16971769        cdef poly *p, *q
    16981770
    16991771        if h._parent is not g._parent:
    1700             g = (<MPolynomialRing_libsingular>h._parent)._coerce_c(g)
    1701 
    1702         r = (<MPolynomialRing_libsingular>h._parent)._ring
     1772            g = h._parent._coerce_c(g)
     1773
     1774        r = h._parent_ring
    17031775        p = g._poly
    17041776        q = h._poly
    17051777
     
    17081780                return False #GCD(0,0) = 0
    17091781            else:
    17101782                return True #GCD(x,0) = 1
    1711 
    17121783        elif q == NULL:
    17131784            return True # GCD(0,x) = 1
    1714 
    17151785        elif p_IsConstant(p,r) or p_IsConstant(q,r): # assuming a base field
    17161786            return False
    17171787
     
    17531823         
    17541824        while not p_ExpVectorEqual(tempvector, maxvector, _ring):
    17551825          tempvector = addwithcarry(tempvector, maxvector, pos, _ring)
    1756           M.append(new_MP(self, p_Copy(tempvector,_ring)))
     1826          M.append(new_MP(self, p_Copy(tempvector, _ring)))
    17571827        return M
    17581828   
    17591829def unpickle_MPolynomialRing_libsingular(base_ring, names, term_order):
     
    17911861        """
    17921862        self._poly = NULL
    17931863        self._parent = <ParentWithBase>parent
     1864        self._parent_ring = singular_ring_reference(parent._ring)
    17941865
    17951866    def __dealloc__(self):
    1796         # TODO: Warn otherwise!
    1797         # for some mysterious reason, various things may be NULL in some cases
    1798         if self._parent is not <ParentWithBase>None and (<MPolynomialRing_libsingular>self._parent)._ring != NULL and self._poly != NULL:
    1799             p_Delete(&self._poly, (<MPolynomialRing_libsingular>self._parent)._ring)
     1867        # WARNING: the Cython class self._parent is now no longer accessible!
     1868        if self._poly==NULL:
     1869            # e.g. MPolynomialRing_libsingular._zero_element
     1870            singular_ring_delete(self._parent_ring)
     1871            return
     1872        assert self._parent_ring != NULL # the constructor has no way to raise an exception
     1873
     1874        ### If you suspect that the poly data was corrupted, then this is a good way to trigger a segfault:
     1875        rChangeCurrRing(self._parent_ring)
     1876        p_Normalize(self._poly, self._parent_ring)
     1877
     1878        p_Delete(&self._poly, self._parent_ring)
     1879        singular_ring_delete(self._parent_ring)
     1880
     1881    def __copy__(self):
     1882        """
     1883        Copy ``self``.
     1884
     1885        OUTPUT:
     1886
     1887        A copy.
     1888
     1889        EXAMPLES::
     1890
     1891            sage: F.<a> = GF(7^2)
     1892            sage: R.<x,y> = F[]
     1893            sage: p = a*x^2 + y + a^3; p
     1894            (a)*x^2 + y + (-2*a - 3)
     1895            sage: q = copy(p)
     1896            sage: p == q
     1897            True
     1898            sage: p is q
     1899            False
     1900            sage: lst = [p,q];
     1901            sage: matrix(ZZ, 2, 2, lambda i,j: bool(lst[i]==lst[j]))
     1902            [1 1]
     1903            [1 1]
     1904            sage: matrix(ZZ, 2, 2, lambda i,j: bool(lst[i] is lst[j]))
     1905            [1 0]
     1906            [0 1]
     1907        """
     1908        return new_MP(self._parent, p_Copy(self._poly, self._parent_ring))
     1909
     1910    def __deepcopy__(self, memo={}):
     1911        """
     1912        Deep copy ``self``
     1913
     1914        TESTS::
     1915       
     1916            sage: R.<x,y> = QQ[]
     1917            sage: p = x^2 + y^2
     1918            sage: p is deepcopy(p)
     1919            False
     1920            sage: p == deepcopy(p)
     1921            True
     1922            sage: p.parent() is deepcopy(p).parent()
     1923            True
     1924        """
     1925        cpy = self.__copy__()
     1926        memo[id(self)] = cpy
     1927        return cpy
    18001928
    18011929    cpdef MPolynomial_libsingular _new_constant_poly(self, x, MPolynomialRing_libsingular P):
    18021930        r"""
     
    18151943
    18161944        """
    18171945        if not x:
    1818             return <MPolynomial_libsingular>new_MP(P, NULL)
    1819         cdef ring *_ring = P._ring
     1946            return new_MP(P, NULL)
    18201947        cdef poly *_p
    1821         singular_polynomial_rmul(&_p, P._one_element_poly, x, _ring)
    1822         return new_MP(P,_p)
     1948        singular_polynomial_rmul(&_p, P._one_element_poly, x, P._ring)
     1949        return new_MP(P, _p)
    18231950
    18241951    def __call__(self, *x, **kwds):
    18251952        """
     
    18832010            9
    18842011            sage: a.parent() is QQ
    18852012            True
    1886 
    18872013        """
    18882014        if len(kwds) > 0:
    18892015            f = self.subs(**kwds)
     
    18932019                return f
    18942020
    18952021        cdef int l = len(x)
    1896         cdef MPolynomialRing_libsingular parent = (<MPolynomialRing_libsingular>self._parent)
     2022        cdef MPolynomialRing_libsingular parent = self._parent
    18972023        cdef ring *_ring = parent._ring
    18982024
    1899         if l == 1 and (PY_TYPE_CHECK(x[0], tuple) or PY_TYPE_CHECK(x[0], list)):
     2025        if l == 1 and isinstance(x[0], (list, tuple)):
    19002026            x = x[0]
    19012027            l = len(x)
    19022028
     
    19182044        if res == NULL:
    19192045            return parent._base._zero_element
    19202046        if p_LmIsConstant(res, _ring):
    1921             return si2sa( p_GetCoeff(res, _ring), _ring, (<MPolynomialRing_libsingular>self._parent)._base )
     2047            return si2sa(p_GetCoeff(res, _ring), _ring, parent._base)
    19222048        return new_MP(parent, res)
    19232049
    19242050    # you may have to replicate this boilerplate code in derived classes if you override
     
    20072133            return 0
    20082134        cdef poly *p = (<MPolynomial_libsingular>left)._poly
    20092135        cdef poly *q = (<MPolynomial_libsingular>right)._poly
    2010         cdef ring *r = (<MPolynomialRing_libsingular>left._parent)._ring
     2136        cdef ring *r = (<MPolynomial_libsingular>left)._parent_ring
    20112137        return singular_polynomial_cmp(p, q, r)
    20122138
    2013     cpdef ModuleElement _add_( left, ModuleElement right):
     2139    cpdef ModuleElement _add_(left, ModuleElement right):
    20142140        """
    20152141        Add left and right.
    20162142
     
    20192145            sage: P.<x,y,z>=PolynomialRing(QQ,3)
    20202146            sage: 3/2*x + 1/2*y + 1
    20212147            3/2*x + 1/2*y + 1
    2022 
    20232148        """
     2149        cdef ring *r = (<MPolynomial_libsingular>left)._parent_ring
    20242150        cdef poly *_p
    20252151        singular_polynomial_add(&_p, left._poly,
    2026                                  (<MPolynomial_libsingular>right)._poly,
    2027                                  (<MPolynomialRing_libsingular>left._parent)._ring)
    2028         return new_MP((<MPolynomialRing_libsingular>left._parent), _p)
    2029 
    2030     cpdef ModuleElement _sub_( left, ModuleElement right):
     2152                                 (<MPolynomial_libsingular>right)._poly, r)
     2153        return new_MP((<MPolynomial_libsingular>left)._parent, _p)
     2154
     2155    cpdef ModuleElement _sub_(left, ModuleElement right):
    20312156        """
    20322157        Subtract left and right.
    20332158
     
    20362161            sage: P.<x,y,z>=PolynomialRing(QQ,3)
    20372162            sage: 3/2*x - 1/2*y - 1
    20382163            3/2*x - 1/2*y - 1
    2039 
    20402164        """
    2041         cdef ring *_ring = (<MPolynomialRing_libsingular>left._parent)._ring
    2042 
     2165        cdef ring *_ring = (<MPolynomial_libsingular>left)._parent_ring
    20432166        cdef poly *_p
    20442167        singular_polynomial_sub(&_p, left._poly,
    20452168                                (<MPolynomial_libsingular>right)._poly,
    20462169                                _ring)
    2047         return new_MP((<MPolynomialRing_libsingular>left._parent), _p)
     2170        return new_MP((<MPolynomial_libsingular>left)._parent, _p)
    20482171
    20492172    cpdef ModuleElement _rmul_(self, RingElement left):
    20502173        """
     
    20572180            3/2*x
    20582181        """
    20592182
    2060         cdef ring *_ring = (<MPolynomialRing_libsingular>self._parent)._ring
     2183        cdef ring *_ring = (<MPolynomial_libsingular>self)._parent_ring
    20612184        if not left:
    2062             return (<MPolynomialRing_libsingular>self._parent)._zero_element
     2185            return (<MPolynomial_libsingular>self)._parent._zero_element
    20632186        cdef poly *_p
    20642187        singular_polynomial_rmul(&_p, self._poly, left, _ring)
    2065         return new_MP((<MPolynomialRing_libsingular>self._parent),_p)
     2188        return new_MP((<MPolynomial_libsingular>self)._parent, _p)
    20662189       
    20672190    cpdef ModuleElement _lmul_(self, RingElement right):
    20682191        # all currently implemented rings are commutative
    20692192        return self._rmul_(right)
    20702193       
    2071     cpdef RingElement  _mul_(left, RingElement right):
     2194    cpdef RingElement _mul_(left, RingElement right):
    20722195        """
    20732196        Multiply left and right.
    20742197
     
    20882211        cdef poly *_p
    20892212        singular_polynomial_mul(&_p, left._poly,
    20902213                                 (<MPolynomial_libsingular>right)._poly,
    2091                                  (<MPolynomialRing_libsingular>left._parent)._ring)
    2092         return new_MP((<MPolynomialRing_libsingular>left._parent),_p)
    2093 
    2094     cpdef RingElement _div_(left, RingElement right):
     2214                                 (<MPolynomial_libsingular>left)._parent_ring)
     2215        return new_MP((<MPolynomial_libsingular>left)._parent,_p)
     2216
     2217    cpdef RingElement _div_(left, RingElement right_ringelement):
    20952218        """
    20962219        Divide left by right
    20972220
     
    21532276            ...
    21542277            ZeroDivisionError: rational division by zero
    21552278        """
    2156         cdef poly *p
     2279        cdef poly *p
     2280        cdef MPolynomial_libsingular right = <MPolynomial_libsingular>right_ringelement
    21572281        cdef bint is_field = left._parent._base.is_field()
    2158         if p_IsConstant((<MPolynomial_libsingular>right)._poly, (<MPolynomialRing_libsingular>right._parent)._ring):
     2282        if p_IsConstant(right._poly, right._parent_ring):
    21592283            if is_field:
    2160                 singular_polynomial_div_coeff(&p, left._poly, (<MPolynomial_libsingular>right)._poly, (<MPolynomialRing_libsingular>right._parent)._ring)
     2284                singular_polynomial_div_coeff(&p, left._poly, right._poly, right._parent_ring)
    21612285                return new_MP(left._parent, p)
    21622286            else:
    2163                 return left.change_ring(left.base_ring().fraction_field())/right
     2287                return left.change_ring(left.base_ring().fraction_field())/right_ringelement
    21642288        else:
    2165             return (<MPolynomialRing_libsingular>left._parent).fraction_field()(left,right)
     2289            return (left._parent).fraction_field()(left,right_ringelement)
    21662290
    21672291    def __pow__(MPolynomial_libsingular self, exp, ignored):
    21682292        """
     
    22072331        if exp < 0:
    22082332            return 1/(self**(-exp))
    22092333        elif exp == 0:
    2210             return (<MPolynomialRing_libsingular>self._parent)._one_element
    2211 
    2212         cdef ring *_ring = (<MPolynomialRing_libsingular>self._parent)._ring
     2334            return self._parent._one_element
     2335
     2336        cdef ring *_ring = self._parent_ring
    22132337        cdef poly *_p
    22142338        singular_polynomial_pow(&_p, self._poly, exp, _ring)
    2215         return new_MP((<MPolynomialRing_libsingular>self._parent),_p)
     2339        return new_MP(self._parent, _p)
    22162340
    22172341    def __neg__(self):
    22182342        """
     
    22252349            sage: -f
    22262350            -x^3 - y
    22272351        """
    2228         cdef ring *_ring = (<MPolynomialRing_libsingular>self._parent)._ring
     2352        cdef ring *_ring = self._parent_ring
    22292353
    22302354        cdef poly *p
    22312355        singular_polynomial_neg(&p, self._poly, _ring)
    2232         return new_MP((<MPolynomialRing_libsingular>self._parent), p)
     2356        return new_MP(self._parent, p)
    22332357
    22342358    def _repr_(self):
    22352359        """
     
    22402364            sage: f # indirect doctest
    22412365            x^3 + y
    22422366        """
    2243         cdef ring *_ring = (<MPolynomialRing_libsingular>self._parent)._ring
     2367        cdef ring *_ring = self._parent_ring
    22442368        s = singular_polynomial_str(self._poly, _ring)
    22452369        return s
    22462370
     
    22562380            sage: f._repr_short_()
    22572381            'x3+y'
    22582382        """
    2259         cdef ring *_ring = (<MPolynomialRing_libsingular>self._parent)._ring
     2383        cdef ring *_ring = self._parent_ring
    22602384        rChangeCurrRing(_ring)
    22612385        if _ring.CanShortOut:
    22622386            _ring.ShortOut = 1
     
    22772401            sage: latex(f)
    22782402            - x^{2} y - \frac{25}{27} y^{3} - z^{2}
    22792403        """
    2280         cdef ring *_ring = (<MPolynomialRing_libsingular>self._parent)._ring
     2404        cdef ring *_ring = self._parent_ring
    22812405        gens = self.parent().latex_variable_names()
    22822406        base = self.parent().base()
    22832407        return singular_polynomial_latex(self._poly, _ring, base, gens)
     
    22942418            sage: print f._repr_with_changed_varnames(['FOO', 'BAR', 'FOOBAR'])
    22952419            -FOO^2*BAR - 25/27*BAR^3 - FOOBAR^2
    22962420        """
    2297         return  singular_polynomial_str_with_changed_varnames(self._poly, (<MPolynomialRing_libsingular>self._parent)._ring, varnames)
     2421        return  singular_polynomial_str_with_changed_varnames(self._poly, self._parent_ring, varnames)
    22982422           
    22992423    def degree(self, MPolynomial_libsingular x=None):
    23002424        """
     
    23332457            0
    23342458
    23352459        """
    2336         cdef ring *r = (<MPolynomialRing_libsingular>self._parent)._ring
     2460        cdef ring *r = self._parent_ring
    23372461        cdef poly *p = self._poly
    23382462        if not x:
    23392463            return singular_polynomial_deg(p,NULL,r)
     
    23422466        if not x in self._parent.gens():
    23432467            raise TypeError("x must be one of the generators of the parent.")
    23442468
    2345         return singular_polynomial_deg(p, (<MPolynomial_libsingular>x)._poly, r)
     2469        return singular_polynomial_deg(p, x._poly, r)
    23462470
    23472471    def total_degree(self):
    23482472        """
     
    23802504            0
    23812505        """
    23822506        cdef poly *p = self._poly
    2383         cdef ring *r = (<MPolynomialRing_libsingular>self._parent)._ring
    2384         return singular_polynomial_deg(p,NULL,r)
     2507        cdef ring *r = self._parent_ring
     2508        return singular_polynomial_deg(p, NULL, r)
    23852509
    23862510    def degrees(self):
    23872511        """
     
    24002524            (5, 2, 1)
    24012525        """
    24022526        cdef poly *p = self._poly
    2403         cdef ring *r = (<MPolynomialRing_libsingular>self._parent)._ring
     2527        cdef ring *r = self._parent_ring
    24042528        cdef int i
    24052529        cdef list d = [0 for _ in range(r.N)]
    24062530        while p:
     
    24722596        """
    24732597        cdef poly *_degrees = <poly*>0
    24742598        cdef poly *p = self._poly
    2475         cdef ring *r = (<MPolynomialRing_libsingular>self._parent)._ring
     2599        cdef ring *r = self._parent_ring
    24762600        cdef poly *newp = p_ISet(0,r)
    24772601        cdef poly *newptemp
    24782602        cdef int i
     
    24822606        for i from 0<=i<gens:
    24832607            exps[i] = -1
    24842608
    2485         if PY_TYPE_CHECK(degrees, MPolynomial_libsingular) and self._parent is (<MPolynomial_libsingular>degrees)._parent:
     2609        if isinstance(degrees, MPolynomial_libsingular) \
     2610                and self._parent is (<MPolynomial_libsingular>degrees)._parent:
    24862611            _degrees = (<MPolynomial_libsingular>degrees)._poly
    24872612            if pLength(_degrees) != 1:
    24882613                raise TypeError, "degrees must be a monomial"
    24892614            for i from 0<=i<gens:
    24902615                if p_GetExp(_degrees,i+1,r)!=0:
    24912616                    exps[i] = p_GetExp(_degrees,i+1,r)
    2492         elif type(degrees) is list:
     2617        elif isinstance(degrees, list):
    24932618            for i from 0<=i<gens:
    24942619                if degrees[i] is None:
    24952620                    exps[i] = -1
    24962621                else:
    24972622                    exps[i] = int(degrees[i])
    2498         elif type(degrees) is dict:
     2623        elif isinstance(degrees, dict):
    24992624            # Extract the ordered list of degree specifications from the dictionary
    25002625            poly_vars = self.parent().gens()
    25012626            for i from 0<=i<gens:
     
    25242649            p = pNext(p)
    25252650
    25262651        sage_free(exps)
    2527 
    2528         return new_MP(self.parent(),newp)
     2652        return new_MP(self._parent, newp)
    25292653
    25302654    def monomial_coefficient(self, MPolynomial_libsingular mon):
    25312655        """
     
    25702694        """
    25712695        cdef poly *p = self._poly
    25722696        cdef poly *m = mon._poly
    2573         cdef ring *r = (<MPolynomialRing_libsingular>self._parent)._ring
     2697        cdef ring *r = self._parent_ring
    25742698
    25752699        if not mon._parent is self._parent:
    25762700            raise TypeError("mon must have same parent as self.")
    25772701       
    25782702        while(p):
    25792703            if p_ExpVectorEqual(p, m, r) == 1:
    2580                 return si2sa(p_GetCoeff(p, r), r, (<MPolynomialRing_libsingular>self._parent)._base)
     2704                return si2sa(p_GetCoeff(p, r), r, self._parent._base)
    25812705            p = pNext(p)
    25822706
    2583         return (<MPolynomialRing_libsingular>self._parent)._base._zero_element
     2707        return self._parent._base._zero_element
    25842708
    25852709    def dict(self):
    25862710        """
     
    25962720            {(1, 3, 2): 2, (0, 0, 0): 2/3, (2, 0, 0): 1/7}
    25972721        """
    25982722        cdef poly *p
    2599         cdef ring *r
     2723        cdef ring *r = self._parent_ring
    26002724        cdef int n
    26012725        cdef int v
    2602         r = (<MPolynomialRing_libsingular>self._parent)._ring
    26032726        if r!=currRing: rChangeCurrRing(r)
    2604         base = (<MPolynomialRing_libsingular>self._parent)._base
     2727        base = self._parent._base
    26052728        p = self._poly
    26062729        pd = dict()
    26072730        while p:
     
    26202743        """
    26212744        See ``self.__hash__``
    26222745        """
    2623         cdef poly *p
    2624         cdef ring *r
     2746        cdef poly *p = self._poly
     2747        cdef ring *r = self._parent_ring
    26252748        cdef int n
    26262749        cdef int v
    2627         r = (<MPolynomialRing_libsingular>self._parent)._ring
    26282750        if r!=currRing: rChangeCurrRing(r)
    2629         base = (<MPolynomialRing_libsingular>self._parent)._base
    2630         p = self._poly
     2751        base = self._parent._base
    26312752        cdef long result = 0 # store it in a c-int and just let the overflowing additions wrap
    26322753        cdef long result_mon
    26332754        var_name_hash = [hash(vn) for vn in self._parent.variable_names()]
     
    26792800        """
    26802801        cdef poly *m
    26812802        cdef poly *p = self._poly
    2682         cdef ring *r = (<MPolynomialRing_libsingular>self._parent)._ring
     2803        cdef ring *r = self._parent_ring
    26832804        cdef int i
    26842805
    2685         if PY_TYPE_CHECK(x, MPolynomial_libsingular):
     2806        if isinstance(x, MPolynomial_libsingular):
    26862807            return self.monomial_coefficient(x)
    2687         if not PY_TYPE_CHECK(x, tuple):
     2808        if not isinstance(x, tuple):
    26882809            try:
    26892810                x = tuple(x)
    26902811            except TypeError:
    26912812                x = (x,)
    26922813
    2693         if len(x) != (<MPolynomialRing_libsingular>self._parent).__ngens:
     2814        if len(x) != self._parent.ngens():
    26942815            raise TypeError, "x must have length self.ngens()"
    26952816
    26962817        m = p_ISet(1,r)
     
    27042825        while(p):
    27052826            if p_ExpVectorEqual(p, m, r) == 1:
    27062827                p_Delete(&m,r)
    2707                 return si2sa(p_GetCoeff(p, r), r, (<MPolynomialRing_libsingular>self._parent)._base)
     2828                return si2sa(p_GetCoeff(p, r), r, self._parent._base)
    27082829            p = pNext(p)
    27092830
    27102831        p_Delete(&m,r)
    2711         return (<MPolynomialRing_libsingular>self._parent)._base._zero_element
     2832        return self._parent._base._zero_element
    27122833
    27132834    def exponents(self, as_ETuples=True):
    27142835        """
     
    27302851            sage: f.exponents(as_ETuples=False)
    27312852            [(3, 0, 0), (0, 2, 0), (0, 1, 0)]
    27322853        """
    2733         cdef poly *p
    2734         cdef ring *r
     2854        cdef poly *p = self._poly
     2855        cdef ring *r = self._parent_ring
    27352856        cdef int v
    27362857        cdef list pl, ml
    27372858
    2738         r = (<MPolynomialRing_libsingular>self._parent)._ring
    2739         p = self._poly
    2740 
    27412859        pl = list()
    27422860        ml = range(r.N)
    27432861        while p:
     
    27792897        """
    27802898        cdef bint is_field = self._parent._base.is_field()
    27812899        if is_field:
    2782             return bool(p_IsUnit(self._poly, (<MPolynomialRing_libsingular>self._parent)._ring))
     2900            return bool(p_IsUnit(self._poly, self._parent_ring))
    27832901        else:
    2784             return bool(p_IsConstant(self._poly, (<MPolynomialRing_libsingular>self._parent)._ring) and self.constant_coefficient().is_unit())
     2902            return bool(p_IsConstant(self._poly, self._parent_ring) and self.constant_coefficient().is_unit())
    27852903
    27862904    def inverse_of_unit(self):
    27872905        """
     
    27982916            sage: R(1/2).inverse_of_unit()
    27992917            2
    28002918        """
    2801         cdef ring *_ring = (<MPolynomialRing_libsingular>self._parent)._ring
     2919        cdef ring *_ring = self._parent_ring
    28022920        if(_ring != currRing): rChangeCurrRing(_ring)
    28032921
    28042922        if not p_IsUnit(self._poly, _ring):
     
    28262944            sage: (x^2*y + y^2*x).is_homogeneous()
    28272945            True
    28282946        """
    2829         cdef ring *_ring = (<MPolynomialRing_libsingular>self._parent)._ring
     2947        cdef ring *_ring = self._parent_ring
    28302948        if(_ring != currRing): rChangeCurrRing(_ring)
    28312949        return bool(pIsHomogeneous(self._poly))
    28322950
     
    28572975
    28582976        SEE: ``self.homogenize``
    28592977        """
    2860         cdef MPolynomialRing_libsingular parent = <MPolynomialRing_libsingular>self._parent
     2978        cdef MPolynomialRing_libsingular parent = self._parent
    28612979        cdef MPolynomial_libsingular f
    28622980
    28632981        if self.is_homogeneous():
    28642982            return self
    28652983
    28662984        if var < parent._ring.N:
    2867             return new_MP(parent, pHomogen(p_Copy(self._poly, parent._ring), var+1))
     2985            return new_MP(parent, pHomogen(p_Copy(self._poly, self._parent_ring), var+1))
    28682986        else:
    28692987            raise TypeError, "var must be < self.parent().ngens()"
    28702988
     
    28883006        cdef poly *_p
    28893007        cdef ring *_ring
    28903008        cdef number *_n
    2891         _ring = (<MPolynomialRing_libsingular>self._parent)._ring
     3009        _ring = self._parent_ring
    28923010
    28933011        if self._poly == NULL:
    28943012            return True
     
    29803098        """
    29813099        cdef int mi, i, need_map, try_symbolic
    29823100       
    2983         cdef MPolynomialRing_libsingular parent = <MPolynomialRing_libsingular>self._parent
     3101        cdef MPolynomialRing_libsingular parent = self._parent
    29843102        cdef ring *_ring = parent._ring
    29853103
    29863104        if(_ring != currRing): rChangeCurrRing(_ring)
     
    29963114
    29973115        if fixed is not None:
    29983116            for m,v in fixed.iteritems():
    2999                 if PY_TYPE_CHECK(m,int) or PY_TYPE_CHECK(m,Integer):
     3117                if isinstance(m, (int, Integer)):
    30003118                    mi = m+1
    3001                 elif PY_TYPE_CHECK(m,MPolynomial_libsingular) and <MPolynomialRing_libsingular>m.parent() is parent:
     3119                elif isinstance(m,MPolynomial_libsingular) and m.parent() is parent:
    30023120                    for i from 0 < i <= _ring.N:
    30033121                        if p_GetExp((<MPolynomial_libsingular>m)._poly, i, _ring) != 0:
    30043122                            mi = i
     
    30733191
    30743192        if fixed is not None:
    30753193            for m,v in fixed.iteritems():
    3076                 if PY_TYPE_CHECK(m,int) or PY_TYPE_CHECK(m,Integer):
     3194                if isinstance(m, (int, Integer)):
    30773195                    mi = m+1
    3078                 elif PY_TYPE_CHECK(m,MPolynomial_libsingular) and <MPolynomialRing_libsingular>m.parent() is parent:
     3196                elif isinstance(m, MPolynomial_libsingular) and m.parent() is parent:
    30793197                    for i from 0 < i <= _ring.N:
    30803198                        if p_GetExp((<MPolynomial_libsingular>m)._poly, i, _ring) != 0:
    30813199                            mi = i
     
    31413259            [x]
    31423260        """
    31433261        l = list()
    3144         cdef MPolynomialRing_libsingular parent = <MPolynomialRing_libsingular>self._parent
     3262        cdef MPolynomialRing_libsingular parent = self._parent
    31453263        cdef ring *_ring = parent._ring
    31463264        if(_ring != currRing): rChangeCurrRing(_ring)
    31473265        cdef poly *p = p_Copy(self._poly, _ring)
     
    31763294            0
    31773295        """
    31783296        cdef poly *p = self._poly
    3179         cdef ring *r = (<MPolynomialRing_libsingular>self._parent)._ring
     3297        cdef ring *r = self._parent_ring
    31803298        if p == NULL:
    3181             return (<MPolynomialRing_libsingular>self._parent)._base._zero_element
     3299            return self._parent._base._zero_element
    31823300
    31833301        while p.next:
    31843302            p = pNext(p)
    31853303
    31863304        if p_LmIsConstant(p, r):
    3187             return si2sa( p_GetCoeff(p, r), r, (<MPolynomialRing_libsingular>self._parent)._base )
     3305            return si2sa(p_GetCoeff(p, r), r, self._parent._base)
    31883306        else:
    3189             return (<MPolynomialRing_libsingular>self._parent)._base._zero_element
     3307            return self._parent._base._zero_element
    31903308
    31913309    def univariate_polynomial(self, R=None):
    31923310        """
     
    32273345            Univariate Polynomial Ring in x over Rational Field
    32283346        """
    32293347        cdef poly *p = self._poly
    3230         cdef ring *r = (<MPolynomialRing_libsingular>self._parent)._ring
     3348        cdef ring *r = self._parent_ring
    32313349        k = self.base_ring()
    32323350       
    32333351        if not self.is_univariate():
     
    32883406       
    32893407        """
    32903408        cdef poly *p
    3291         cdef ring *r = (<MPolynomialRing_libsingular>self._parent)._ring
     3409        cdef ring *r = self._parent_ring
    32923410        cdef int i
    32933411        s = set()
    32943412        p = self._poly
     
    33143432            (x, z)
    33153433        """
    33163434        cdef poly *p, *v
    3317         cdef ring *r = (<MPolynomialRing_libsingular>self._parent)._ring
     3435        cdef ring *r = self._parent_ring
    33183436        if(r != currRing): rChangeCurrRing(r)
    33193437        cdef int i
    33203438        l = list()
     
    33763494            sage: P(1).is_constant()
    33773495            True
    33783496        """
    3379         return bool(p_IsConstant(self._poly, (<MPolynomialRing_libsingular>self._parent)._ring))
     3497        return bool(p_IsConstant(self._poly, self._parent_ring))
    33803498
    33813499    def lm(MPolynomial_libsingular self):
    33823500        """
     
    34123530
    34133531        """
    34143532        cdef poly *_p
    3415         cdef ring *_ring
    3416         _ring = (<MPolynomialRing_libsingular>self._parent)._ring
     3533        cdef ring *_ring = self._parent_ring
    34173534        if self._poly == NULL:
    3418             return (<MPolynomialRing_libsingular>self._parent)._zero_element
     3535            return self._parent._zero_element
    34193536        _p = p_Head(self._poly, _ring)
    34203537        p_SetCoeff(_p, n_Init(1,_ring), _ring)
    34213538        p_Setm(_p,_ring)
    3422         return new_MP((<MPolynomialRing_libsingular>self._parent), _p)
     3539        return new_MP(self._parent, _p)
    34233540
    34243541    def lc(MPolynomial_libsingular self):
    34253542        """
     
    34393556        """
    34403557
    34413558        cdef poly *_p
    3442         cdef ring *_ring
     3559        cdef ring *_ring = self._parent_ring
    34433560        cdef number *_n
    3444         _ring = (<MPolynomialRing_libsingular>self._parent)._ring
    34453561
    34463562        if self._poly == NULL:
    3447             return (<MPolynomialRing_libsingular>self._parent)._base._zero_element
     3563            return self._parent._base._zero_element
    34483564       
    34493565        if(_ring != currRing): rChangeCurrRing(_ring)
    34503566       
    34513567        _p = p_Head(self._poly, _ring)
    34523568        _n = p_GetCoeff(_p, _ring)
    34533569
    3454         ret =  si2sa(_n, _ring, (<MPolynomialRing_libsingular>self._parent)._base)
     3570        ret =  si2sa(_n, _ring, self._parent._base)
    34553571        p_Delete(&_p, _ring)
    34563572        return ret
    34573573
     
    34723588            -2*x^3*y^2*z^4
    34733589        """
    34743590        if self._poly == NULL:
    3475             return (<MPolynomialRing_libsingular>self._parent)._zero_element
    3476 
    3477         return new_MP((<MPolynomialRing_libsingular>self._parent),
    3478                                            p_Head(self._poly,(<MPolynomialRing_libsingular>self._parent)._ring))
     3591            return self._parent._zero_element
     3592        return new_MP(self._parent, p_Head(self._poly, self._parent_ring))
    34793593
    34803594    def is_zero(self):
    34813595        """
     
    35093623        else:
    35103624            return False
    35113625
    3512     def __floordiv__(self, right):
     3626    def __floordiv__(MPolynomial_libsingular self, right):
    35133627        """
    35143628        Perform division with remainder and return the quotient.
    35153629
     
    35473661            ...
    35483662            NotImplementedError: Division of multivariate polynomials over non fields by non-monomials not implemented.
    35493663        """
    3550         cdef MPolynomialRing_libsingular parent = <MPolynomialRing_libsingular>(<MPolynomial_libsingular>self)._parent
    3551         cdef ring *r = parent._ring
     3664        cdef MPolynomialRing_libsingular parent = self._parent
     3665        cdef ring *r = self._parent_ring
    35523666        if(r != currRing): rChangeCurrRing(r)
    35533667        cdef MPolynomial_libsingular _self, _right
    35543668        cdef poly *quo, *temp, *p
    35553669       
    35563670        _self = self
    35573671
    3558         if not PY_TYPE_CHECK(right, MPolynomial_libsingular) or (<ParentWithBase>parent is not (<MPolynomial_libsingular>right)._parent):
     3672        if not isinstance(right, MPolynomial_libsingular) \
     3673                or (parent is not (<MPolynomial_libsingular>right)._parent):
    35593674            _right = parent._coerce_c(right)
    35603675        else:
    35613676            _right = right
     
    35633678        if right.is_zero():
    35643679            raise ZeroDivisionError
    35653680
    3566         if (<MPolynomial_libsingular>self)._parent._base.is_finite() and (<MPolynomial_libsingular>self)._parent._base.characteristic() > 1<<29:
     3681        if self._parent._base.is_finite() and self._parent._base.characteristic() > 1<<29:
    35673682            raise NotImplementedError, "Division of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented."
    35683683
    35693684        if r.ringtype != 0:
     
    37123827            ...
    37133828            NotImplementedError: proof = True factorization not implemented.  Call factor with proof=False.
    37143829        """
    3715         cdef ring *_ring
     3830        cdef ring *_ring = self._parent_ring
    37163831        cdef poly *ptemp
    37173832        cdef intvec *iv
    37183833        cdef int *ivv
    37193834        cdef ideal *I
    3720         cdef MPolynomialRing_libsingular parent
     3835        cdef MPolynomialRing_libsingular parent = self._parent
    37213836        cdef int i
    37223837
    3723         parent = self._parent
    3724         _ring = parent._ring
    3725 
    37263838        if proof is None:
    37273839            from sage.structure.proof.proof import get_flag
    37283840            proof = get_flag(proof, "polynomial")
     
    37853897
    37863898        cdef ideal *fI = idInit(1,1)
    37873899        cdef ideal *_I
    3788         cdef MPolynomialRing_libsingular parent = <MPolynomialRing_libsingular>self._parent
     3900        cdef MPolynomialRing_libsingular parent = self._parent
    37893901        cdef int i = 0
    37903902        cdef int j
    3791         cdef ring *r = (<MPolynomialRing_libsingular>self._parent)._ring
     3903        cdef ring *r = self._parent_ring
    37923904        cdef ideal *res
    37933905       
    37943906        if PY_TYPE_CHECK(I, MPolynomialIdeal):
     
    37973909        _I = idInit(len(I),1)
    37983910
    37993911        for f in I:
    3800             if not (PY_TYPE_CHECK(f,MPolynomial_libsingular) \
    3801                     and <MPolynomialRing_libsingular>(<MPolynomial_libsingular>f)._parent is parent):
     3912            if not (isinstance(f,MPolynomial_libsingular) \
     3913                    and (<MPolynomial_libsingular>f)._parent is parent):
    38023914                try:
    38033915                    f = parent._coerce_c(f)
    38043916                except TypeError, msg:
     
    38693981            3*x
    38703982        """
    38713983        cdef ideal *_I
    3872         cdef MPolynomialRing_libsingular parent = <MPolynomialRing_libsingular>self._parent
     3984        cdef MPolynomialRing_libsingular parent = self._parent
    38733985        cdef int i = 0
    3874         cdef ring *r = (<MPolynomialRing_libsingular>self._parent)._ring
     3986        cdef ring *r = self._parent_ring
    38753987        cdef poly *res
    38763988       
    38773989        if(r != currRing): rChangeCurrRing(r)
     
    38863998
    38873999        _I = idInit(len(I),1)
    38884000        for f in I:
    3889             if not (PY_TYPE_CHECK(f,MPolynomial_libsingular) \
    3890                    and <MPolynomialRing_libsingular>(<MPolynomial_libsingular>f)._parent is parent):
     4001            if not (isinstance(f,MPolynomial_libsingular) \
     4002                   and (<MPolynomial_libsingular>f)._parent is parent):
    38914003                try:
    38924004                    f = parent._coerce_c(f)
    38934005                except TypeError, msg:
     
    39724084        """
    39734085        cdef MPolynomial_libsingular _right
    39744086        cdef poly *_res
    3975         cdef ring *_ring
     4087        cdef ring *_ring = self._parent_ring
    39764088
    39774089        if algorithm is None:
    39784090            algorithm = "modular"
     
    39864098        else:
    39874099            raise TypeError, "algorithm %s not supported"%(algorithm)
    39884100
    3989         _ring = (<MPolynomialRing_libsingular>self._parent)._ring
    3990 
    3991        
    3992 
    39934101        if _ring.ringtype != 0:
    39944102            if _ring.ringtype == 4:
    39954103                P = self._parent.change_ring(RationalField())
     
    40044112           
    40054113        if(_ring != currRing): rChangeCurrRing(_ring)
    40064114       
    4007         if not (PY_TYPE_CHECK(right, MPolynomial_libsingular) and (<MPolynomial_libsingular>right)._parent is (<MPolynomial_libsingular>self)._parent):
    4008             _right = (<MPolynomialRing_libsingular>self._parent)._coerce_c(right)
     4115        if not (isinstance(right, MPolynomial_libsingular) \
     4116                    and (<MPolynomial_libsingular>right)._parent is self._parent):
     4117            _right = self._parent._coerce_c(right)
    40094118        else:
    4010             _right = (<MPolynomial_libsingular>right)
    4011 
    4012         cdef int count = singular_polynomial_length_bounded(self._poly,20)+singular_polynomial_length_bounded(_right._poly,20)
     4119            _right = <MPolynomial_libsingular>right
     4120
     4121        cdef int count = singular_polynomial_length_bounded(self._poly,20) \
     4122            + singular_polynomial_length_bounded(_right._poly,20)
    40134123        if count >= 20:
    40144124            sig_on()
    40154125        _res = singclap_gcd(p_Copy(self._poly, _ring), p_Copy(_right._poly, _ring))
    40164126        if count >= 20:
    40174127            sig_off()
    40184128
    4019         res = new_MP((<MPolynomialRing_libsingular>self._parent), _res)
     4129        res = new_MP(self._parent, _res)
    40204130        return res
    40214131
    40224132    @coerce_binop
     
    40454155            sage: lcm(p,q)
    40464156            6*x*y*z^4 + 6*y^2*z^4 + 6*x*z^5 + 6*y*z^5 + 12*x*y + 12*y^2 + 12*x*z + 12*y*z
    40474157        """
    4048         cdef ring *_ring = (<MPolynomialRing_libsingular>self._parent)._ring
     4158        cdef ring *_ring = self._parent_ring
    40494159        cdef poly *ret, *prod, *gcd
    40504160        cdef MPolynomial_libsingular _g
    40514161        if(_ring != currRing): rChangeCurrRing(_ring)
     
    40614171                raise TypeError("LCM over non-integral domains not available.")
    40624172
    40634173        if self._parent is not g._parent:
    4064             _g = (<MPolynomialRing_libsingular>self._parent)._coerce_c(g)
     4174            _g = self._parent._coerce_c(g)
    40654175        else:
    40664176            _g = <MPolynomial_libsingular>g
    40674177
    40684178        if self._parent._base.is_finite() and self._parent._base.characteristic() > 1<<29:
    40694179            raise NotImplementedError, "LCM of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented."
    40704180
    4071         cdef int count = singular_polynomial_length_bounded(self._poly,20)+singular_polynomial_length_bounded(_g._poly,20)
     4181        cdef int count = singular_polynomial_length_bounded(self._poly,20) \
     4182            + singular_polynomial_length_bounded(_g._poly,20)
    40724183        if count >= 20:
    40734184            sig_on()
    40744185        gcd = singclap_gcd(p_Copy(self._poly, _ring), p_Copy(_g._poly, _ring))
     
    40944205            sage: h.is_squarefree()
    40954206            False
    40964207        """
    4097         cdef ring *_ring = (<MPolynomialRing_libsingular>self._parent)._ring
     4208        cdef ring *_ring = self._parent_ring
    40984209        if(_ring != currRing): rChangeCurrRing(_ring)
    40994210
    41004211        if self._parent._base.is_finite() and self._parent._base.characteristic() > 1<<29:
     
    41374248       
    41384249        """
    41394250        cdef poly *quo, *rem
    4140         cdef MPolynomialRing_libsingular parent = <MPolynomialRing_libsingular>self._parent
    4141         cdef ring *r = (<MPolynomialRing_libsingular>self._parent)._ring
     4251        cdef MPolynomialRing_libsingular parent = self._parent
     4252        cdef ring *r = self._parent_ring
    41424253        if(r != currRing): rChangeCurrRing(r)
    41434254
    41444255        if right.is_zero():
     
    42144325            sage: x.sub_m_mul_q(Q.gen(1),Q.gen(2))
    42154326            -y*z + x
    42164327         """
    4217         cdef ring *r = (<MPolynomialRing_libsingular>self._parent)._ring
     4328        cdef ring *r = self._parent_ring
    42184329
    42194330        if not self._parent is m._parent:
    42204331            m = self._parent._coerce_c(m)
     
    42934404            sage: x.add_m_mul_q(R.gen(),R.gen(1))
    42944405            x*y + x
    42954406        """
    4296         cdef ring *r = (<MPolynomialRing_libsingular>self._parent)._ring
     4407        cdef ring *r = self._parent_ring
    42974408
    42984409        if not self._parent is m._parent:
    42994410            m = self._parent._coerce_c(m)
     
    44024513        cdef poly *p
    44034514        if var._parent is not self._parent:
    44044515            raise TypeError, "provided variable is not in same ring as self"
    4405         cdef ring *_ring = (<MPolynomialRing_libsingular>self._parent)._ring
     4516        cdef ring *_ring = self._parent_ring
    44064517        if _ring != currRing:
    44074518            rChangeCurrRing(_ring)
    44084519
     
    44784589            sage: f.resultant(g,y)
    44794590            x^2 + x
    44804591        """
    4481         cdef ring *_ring = (<MPolynomialRing_libsingular>self._parent)._ring
     4592        cdef ring *_ring = self._parent_ring
    44824593        cdef poly *rt
    44834594
    44844595        if variable is None:
     
    45014612        elif not self._parent._base.is_field():
    45024613            raise ValueError("Resultants require base fields or integer base ring.")
    45034614
    4504         cdef int count = singular_polynomial_length_bounded(self._poly,20)+singular_polynomial_length_bounded(other._poly,20)
     4615        cdef int count = singular_polynomial_length_bounded(self._poly,20) \
     4616            + singular_polynomial_length_bounded(other._poly,20)
    45054617        if count >= 20:
    45064618            sig_on()
    4507         rt =  singclap_resultant(self._poly, other._poly,(<MPolynomial_libsingular>variable)._poly )
     4619        rt =  singclap_resultant(self._poly, other._poly, (<MPolynomial_libsingular>variable)._poly )
    45084620        if count >= 20:
    45094621            sig_off()
    45104622        return new_MP(self._parent, rt)
     
    45604672        if r == 0 or r == 1:
    45614673            u = 1
    45624674        an = self.coefficient(variable**n)**(n - k - 2)
    4563         return self.parent()(u * self.resultant(d,variable) * an)
     4675        return self.parent()(u * self.resultant(d, variable) * an)
    45644676
    45654677    def coefficients(self):
    45664678        """
     
    45854697        - Didier Deshommes
    45864698        """
    45874699        cdef poly *p
    4588         cdef ring *r
    4589         r = (<MPolynomialRing_libsingular>self._parent)._ring
     4700        cdef ring *r = self._parent_ring
    45904701        if r!=currRing: rChangeCurrRing(r)
    4591         base = (<MPolynomialRing_libsingular>self._parent)._base
     4702        base = self._parent._base
    45924703        p = self._poly
    45934704        coeffs = list()
    45944705        while p:
     
    46084719           sage: f.gradient()
    46094720           [y, x, 0]
    46104721        """
    4611         cdef ring *r
     4722        cdef ring *r = self._parent_ring
    46124723        cdef int k
    46134724
    4614         r = (<MPolynomialRing_libsingular>self._parent)._ring
    46154725        if r!=currRing: rChangeCurrRing(r)
    46164726        i = []
    46174727        for k from 0 < k <= r.N:
    46184728            i.append( new_MP(self._parent, pDiff(self._poly, k)))
    4619 
    46204729        return i
    46214730
    46224731
     
    46284737        numerator is a polynomial whose base_ring is the Integer Ring,
    46294738        this is done for compatibility to the univariate case.
    46304739
    4631     .. warning::
    4632 
    4633         This is not the numerator of the rational function
    4634         defined by self, which would always be self since self is a
    4635         polynomial.
    4636 
    4637     EXAMPLES:
    4638 
    4639     First we compute the numerator of a polynomial with
    4640     integer coefficients, which is of course self.
    4641 
    4642     ::
    4643 
    4644         sage: R.<x, y> = ZZ[]
    4645         sage: f = x^3 + 17*y + 1
    4646         sage: f.numerator()
    4647         x^3 + 17*y + 1
    4648         sage: f == f.numerator()
    4649         True
    4650 
    4651     Next we compute the numerator of a polynomial with rational
    4652     coefficients.
    4653 
    4654     ::
    4655 
    4656         sage: R.<x,y> = PolynomialRing(QQ)
    4657         sage: f = (1/17)*x^19 - (2/3)*y + 1/3; f
    4658         1/17*x^19 - 2/3*y + 1/3
    4659         sage: f.numerator()
    4660         3*x^19 - 34*y + 17
    4661         sage: f == f.numerator()
    4662         False
    4663         sage: f.numerator().base_ring()
    4664         Integer Ring
    4665 
    4666     We check that the computation the numerator and denominator
    4667     are valid
    4668 
    4669     ::
    4670 
    4671         sage: K=QQ['x,y']
    4672         sage: f=K.random_element()
    4673         sage: f.numerator() / f.denominator() == f
    4674         True
     4740        .. warning::
     4741   
     4742            This is not the numerator of the rational function
     4743            defined by self, which would always be self since self is a
     4744            polynomial.
     4745   
     4746        EXAMPLES:
     4747   
     4748        First we compute the numerator of a polynomial with
     4749        integer coefficients, which is of course self.
     4750   
     4751        ::
     4752   
     4753            sage: R.<x, y> = ZZ[]
     4754            sage: f = x^3 + 17*y + 1
     4755            sage: f.numerator()
     4756            x^3 + 17*y + 1
     4757            sage: f == f.numerator()
     4758            True
     4759   
     4760        Next we compute the numerator of a polynomial with rational
     4761        coefficients.
     4762   
     4763        ::
     4764   
     4765            sage: R.<x,y> = PolynomialRing(QQ)
     4766            sage: f = (1/17)*x^19 - (2/3)*y + 1/3; f
     4767            1/17*x^19 - 2/3*y + 1/3
     4768            sage: f.numerator()
     4769            3*x^19 - 34*y + 17
     4770            sage: f == f.numerator()
     4771            False
     4772            sage: f.numerator().base_ring()
     4773            Integer Ring
     4774   
     4775        We check that the computation the numerator and denominator
     4776        are valid
     4777   
     4778        ::
     4779   
     4780            sage: K=QQ['x,y']
     4781            sage: f=K.random_element()
     4782            sage: f.numerator() / f.denominator() == f
     4783            True
    46754784        """
    46764785        if self.base_ring() == RationalField():
    46774786            #This part is for compatibility with the univariate case,
     
    47104819        for i,e in mon.sparse_iter():
    47114820            _i = i
    47124821            if _i >= r.N:
    4713                 p_Delete(&p,r)
    4714                 p_Delete(&m,r)
     4822                p_Delete(&p, r)
     4823                p_Delete(&m, r)
    47154824                raise TypeError, "variable index too big"
    47164825            _e = e
    47174826            if _e <= 0:
    4718                 p_Delete(&p,r)
    4719                 p_Delete(&m,r)
     4827                p_Delete(&p, r)
     4828                p_Delete(&m, r)
    47204829                raise TypeError, "exponent too small"
    47214830            overflow_check(_e)
    4722             p_SetExp(m, _i+1,_e, r)
     4831            p_SetExp(m, _i+1, _e, r)
    47234832        p_SetCoeff(m, sa2si(c, r), r)
    4724         p_Setm(m,r)
    4725         p = p_Add_q(p,m,r)
    4726     return new_MP(R,p)
    4727 
    4728 
    4729 cdef poly *addwithcarry(poly *tempvector, poly *maxvector, int pos, ring *_ring):
     4833        p_Setm(m, r)
     4834        p = p_Add_q(p, m, r)
     4835    return new_MP(R, p)
     4836
     4837
     4838cdef inline poly *addwithcarry(poly *tempvector, poly *maxvector, int pos, ring *_ring):
    47304839    if p_GetExp(tempvector, pos, _ring) < p_GetExp(maxvector, pos, _ring):
    47314840      p_SetExp(tempvector, pos, p_GetExp(tempvector, pos, _ring)+1, _ring)
    47324841    else:
     
    47354844    p_Setm(tempvector, _ring)
    47364845    return tempvector
    47374846
     4847
    47384848cdef inline MPolynomial_libsingular new_MP(MPolynomialRing_libsingular parent, poly *juice):
    47394849    """
    47404850    Construct MPolynomial_libsingular from parent and SINGULAR poly.
     4851
     4852    INPUT:
     4853
     4854    - ``parent`` -- a :class:`MPolynomialRing_libsingular``
     4855      instance. The parent of the polynomial to create.
     4856     
     4857    - ``juice`` -- a pointer to a Singular ``poly`` C struct.
     4858
     4859    OUTPUT:
     4860
     4861    A Python object :class:`MPolynomial_libsingular`.
     4862
     4863    The ownership of ``juice`` will be transferred to the Python
     4864    object. You must not free it yourself. Singular will modify the
     4865    polynomial, so it is your repsonsiblity to make a copy if the
     4866    Singular data structure is used elsewhere.
    47414867    """
    4742     cdef MPolynomial_libsingular p
    4743     p = PY_NEW(MPolynomial_libsingular)
     4868    cdef MPolynomial_libsingular p = PY_NEW(MPolynomial_libsingular)
    47444869    p._parent = <ParentWithBase>parent
     4870    p._parent_ring = singular_ring_reference(parent._ring)
    47454871    p._poly = juice
    4746     p_Normalize(p._poly, parent._ring)
     4872    p_Normalize(p._poly, p._parent_ring)
    47474873    return p
    47484874
    47494875