Ticket #11316: trac_11316.2.patch

File trac_11316.2.patch, 75.8 KB (added by klee, 11 years ago)

fixed the unpickling failures

  • sage/crypto/mq/sr.py

    # HG changeset patch
    # User Kwankyu Lee <ekwankyu@gmail.com>
    # Date 1305014300 -32400
    # Node ID fd7a5da7638734a9632f07d94511680ba467de3f
    # Parent  11a88d11c83eefcdc419688d754a49d26c3f4601
    #11316: added weighted degree term orders
    
    diff -r 11a88d11c83e -r fd7a5da76387 sage/crypto/mq/sr.py
    a b  
    16651665       
    16661666            sage: sr = mq.SR(2, 1, 1, 4)
    16671667            sage: sr.block_order()
    1668             degrevlex(16),degrevlex(16),degrevlex(4) term order
     1668            Block term order with blocks:
     1669            (Degree reverse lexicographic term order of length 16,
     1670             Degree reverse lexicographic term order of length 16,
     1671             Degree reverse lexicographic term order of length 4)
    16691672       
    16701673        ::
    16711674       
  • sage/libs/singular/ring.pyx

    diff -r 11a88d11c83e -r fd7a5da76387 sage/libs/singular/ring.pyx
    a b  
    2222from sage.libs.singular.decl cimport number, lnumber, napoly, ring, currRing
    2323from sage.libs.singular.decl cimport rChangeCurrRing, rCopy0, rComplete, rDelete
    2424from sage.libs.singular.decl cimport omAlloc0, omStrDup, omAlloc, omAlloc0Bin,  sip_sring_bin, rnumber_bin
    25 from sage.libs.singular.decl cimport ringorder_dp, ringorder_Dp, ringorder_lp, ringorder_rp, ringorder_ds, ringorder_Ds, ringorder_ls, ringorder_M, ringorder_C
     25from sage.libs.singular.decl cimport ringorder_dp, ringorder_Dp, ringorder_lp, ringorder_rp, ringorder_ds, ringorder_Ds, ringorder_ls, ringorder_M, ringorder_C, ringorder_wp, ringorder_Wp, ringorder_ws, ringorder_Ws
    2626from sage.libs.singular.decl cimport p_Copy
    2727
    2828from sage.rings.integer cimport Integer
     
    4141
    4242
    4343# mapping str --> SINGULAR representation
    44 order_dict = {"dp":ringorder_dp,
    45               "Dp":ringorder_Dp,
    46               "lp":ringorder_lp,
    47               "rp":ringorder_rp,
    48               "ds":ringorder_ds,
    49               "Ds":ringorder_Ds,
    50               "ls":ringorder_ls,
    51               }
     44order_dict = {
     45    "dp": ringorder_dp,
     46    "Dp": ringorder_Dp,
     47    "lp": ringorder_lp,
     48    "rp": ringorder_rp,
     49    "ds": ringorder_ds,
     50    "Ds": ringorder_Ds,
     51    "ls": ringorder_ls,
     52    "wp": ringorder_wp,
     53    "Wp": ringorder_Wp,
     54    "ws": ringorder_ws,
     55    "Ws": ringorder_Ws,
     56}
    5257
    5358cdef ring *singular_ring_new(base_ring, n, names, term_order) except NULL:
    5459    """
     
    236241
    237242        _ring.minpoly=<number*>nmp
    238243
    239     nblcks = len(order.blocks)
     244    nblcks = len(order.blocks())
    240245    offset = 0
    241246
    242247    _ring.wvhdl  = <int **>omAlloc0((nblcks + 2) * sizeof(int *))
     
    250255        _ring.OrdSgn = 1
    251256
    252257    for i from 0 <= i < nblcks:
    253         if order[i].singular_str()[0] == 'M':
     258        s = order[i].singular_str()
     259        if s[0] == 'M': # matrix order
    254260            _ring.order[i] = ringorder_M
    255261            mtx = order[i].matrix().list()
    256             m = <int *>omAlloc0(len(mtx)*sizeof(int))
     262            wv = <int *>omAlloc0(len(mtx)*sizeof(int))
    257263            for j in range(len(mtx)):
    258                 m[j] = int(mtx[j])
    259             _ring.wvhdl[i] = m
    260         else:
    261             _ring.order[i] = order_dict.get(order[i].singular_str(), ringorder_dp)
     264                wv[j] = int(mtx[j])
     265            _ring.wvhdl[i] = wv
     266        elif s[0] == 'w' or s[0] == 'W': # weighted degree orders
     267            _ring.order[i] = order_dict.get(s[:2], ringorder_dp)
     268            wts = order[i].weights()
     269            wv = <int *>omAlloc0(len(wts)*sizeof(int))
     270            for j in range(len(wts)):
     271                wv[j] = int(wts[j])
     272            _ring.wvhdl[i] = wv   
     273        else: # ordinary orders
     274            _ring.order[i] = order_dict.get(s, ringorder_dp)
    262275        _ring.block0[i] = offset + 1
    263276        if len(order[i]) == 0: # may be zero in some cases
    264277            _ring.block1[i] = offset + n
  • sage/rings/polynomial/multi_polynomial_ring.py

    diff -r 11a88d11c83e -r fd7a5da76387 sage/rings/polynomial/multi_polynomial_ring.py
    a b  
    468468            c = self.base_ring()(x)
    469469            return MPolynomial_polydict(self, {self._zero_tuple:c})
    470470
    471 
    472 
    473471class MPolynomialRing_polydict_domain(integral_domain.IntegralDomain,
    474472                                      MPolynomialRing_polydict,
    475473                                      MPolynomialRing_macaulay2_repr):
    476474    def __init__(self, base_ring, n, names, order):
    477         order = TermOrder(order, n)
     475        order = TermOrder(order,n) 
    478476        MPolynomialRing_polydict.__init__(self, base_ring, n, names, order)
    479477
    480478    def is_integral_domain(self, proof = True):
     
    513511            gens = [self(x) for x in gens]  # this will even coerce from singular ideals correctly!
    514512        return multi_polynomial_ideal.MPolynomialIdeal(self, gens, **kwds)
    515513
    516 
    517514    def monomial_quotient(self,f, g, coeff=False):
    518515        """
    519516        Return f/g, where both f and g are treated as monomials.
     
    716713                return 0,0
    717714        return 0,0
    718715
    719 
    720716    def monomial_divides(self, a, b):
    721717        """
    722718        Return False if a does not divide b and True otherwise.
  • sage/rings/polynomial/multi_polynomial_ring_generic.pyx

    diff -r 11a88d11c83e -r fd7a5da76387 sage/rings/polynomial/multi_polynomial_ring_generic.pyx
    a b  
    4848            sage: A1(a) in A2
    4949            True
    5050        """
    51         order = TermOrder(order,n)
     51        order = TermOrder(order,n) 
     52
    5253        if not base_ring.is_commutative():
    5354            raise TypeError, "Base ring must be a commutative ring."
    5455        n = int(n)
     
    252253        _repr += "       Size : %d Variables\n"%(n,)
    253254        offset = 0
    254255        i = 0
    255         for order in T.blocks:
     256        for order in T.blocks():
    256257            _repr += "   Block % 2d : Ordering : %s\n"%(i,inv_singular_name_mapping.get(order.singular_str(), order.singular_str()))
    257258            _repr += "              Names    : %s\n"%(", ".join(names[offset:offset + len(order)]))
    258259            offset += len(order)
  • sage/rings/polynomial/pbori.pyx

    diff -r 11a88d11c83e -r fd7a5da76387 sage/rings/polynomial/pbori.pyx
    a b  
    263263
    264264        sage: R = BooleanPolynomialRing(5,'x',order='deglex(3),deglex(2)')
    265265        sage: R.term_order()
    266         deglex(3),deglex(2) term order
     266        Block term order with blocks:
     267        (Degree lexicographic term order of length 3,
     268         Degree lexicographic term order of length 2)
    267269
    268270    ::
    269271
     
    326328        except KeyError:
    327329            raise ValueError, "Only lex, deglex, degrevlex orders are supported."
    328330
    329         if len(order.blocks) > 1:
     331        if order.is_block_order():
    330332            if pb_order_code is pblp:
    331333                raise ValueError, "Only deglex and degrevlex are supported for block orders."
    332334            elif pb_order_code is pbdlex:
    333335                pb_order_code = pbblock_dlex
    334336            elif pb_order_code is pbdp_asc:
    335337                pb_order_code = pbblock_dp_asc
    336             for i in range(1, len(order.blocks)):
    337                 if order[0] != order[i]:
    338                     raise ValueError, "Each block must have the same order type (deglex or degrevlex) for block orderings."
     338            for i in range(1, len(order.blocks())):
     339                if order[0].name() != order[i].name():
     340                    raise ValueError, "Each block must have the same order type (deglex or degrevlex) for block orders."
    339341
    340342        if (pb_order_code is pbdlex) or (pb_order_code is pblp) or \
    341343                (pb_order_code is pbblock_dlex):
     
    347349        else:
    348350            # pb_order_code is block_dp_asc:
    349351            bstart = 0
    350             for i from 0 <= i < len(order.blocks):
     352            for i from 0 <= i < len(order.blocks()):
    351353                bsize = len(order[i])
    352354                for j from 0 <= j < bsize:
    353355                    self.pbind[bstart + j] = bstart + bsize - j -1
     
    357359        MPolynomialRing_generic.__init__(self, GF(2), n, names, order)
    358360
    359361        counter = 0
    360         for i in range(len(order.blocks)-1):
     362        for i in range(len(order.blocks())-1):
    361363            counter += len(order[i])
    362364            pb_append_block(counter)
    363365
     
    70567058        sage: change_ordering(block_dp_asc)
    70577059        sage: append_ring_block(5)
    70587060        sage: get_cring().term_order()
    7059         deglex_asc(5),deglex_asc(5) term order
     7061        Block term order with blocks:
     7062        (deglex_asc term order of length 5,
     7063         deglex_asc term order of length 5) 
    70607064        sage: change_ordering(lp)
    70617065 
    70627066        sage: from polybori.blocks import *
     
    71297133    else:
    71307134        # pb_order_code is block_dp_asc:
    71317135        bstart = 0
    7132         for i from 0 <= i < len(T.blocks):
     7136        for i from 0 <= i < len(T.blocks()):
    71337137            bsize = len(T[i])
    71347138            for j from 0 <= j < bsize:
    71357139                self.pbind[bstart + j] = bstart + j
  • sage/rings/polynomial/polynomial_ring.py

    diff -r 11a88d11c83e -r fd7a5da76387 sage/rings/polynomial/polynomial_ring.py
    a b  
    688688            except AttributeError:
    689689                return self.base_ring()
    690690       
    691            
    692691    def characteristic(self):
    693692        """
    694693        Return the characteristic of this polynomial ring, which is the
  • sage/rings/polynomial/polynomial_ring_constructor.py

    diff -r 11a88d11c83e -r fd7a5da76387 sage/rings/polynomial/polynomial_ring_constructor.py
    a b  
    494494
    495495        sage: R = BooleanPolynomialRing(5,'x',order='deglex(3),deglex(2)')
    496496        sage: R.term_order()
    497         deglex(3),deglex(2) term order
     497        Block term order with blocks:
     498        (Degree lexicographic term order of length 3,
     499         Degree lexicographic term order of length 2)
    498500
    499501        sage: R = BooleanPolynomialRing(3,'x',order='degrevlex')
    500502        sage: R.term_order()
     
    531533
    532534    from sage.rings.polynomial.term_order import TermOrder
    533535    from sage.rings.polynomial.pbori import set_cring
     536
    534537    order = TermOrder(order, n)
    535538
    536539    key = ("pbori", names, n, order)
  • sage/rings/polynomial/term_order.py

    diff -r 11a88d11c83e -r fd7a5da76387 sage/rings/polynomial/term_order.py
    a b  
    11r"""
    2 Term Orderings
     2Term orders
    33
    4 Sage supports the following term orderings:
     4Sage supports the following term orders:
    55
    6 Lexicographic (*lex*)
    7     `x^a < x^b \Leftrightarrow \exists\; 0 \le i < n : a_0 = b_0, \ldots, a_{i-1} = b_{i-1}, a_i < b_i`
     6Lexicographic (lex)
     7    `x^a < x^b` if and only if there exists `1 \le i \le n` such that `a_1 = b_1, \dots, a_{i-1} = b_{i-1}, a_i < b_i`. 
     8    This term order is called 'lp' in Singular.
    89
    910    EXAMPLES:
    1011
     
    2223        sage: x^3*y^2*z^4 < x^3*y^2*z^1
    2324        False
    2425
    25     This term ordering is called 'lp' in Singular.
    26 
    27 Degree reverse lexicographic (*degrevlex*)
    28     Let `deg(x^a) = a_0 + \cdots + a_{n-1},` then
    29     `x^a < x^b \Leftrightarrow deg(x^a) < deg(x^b)` or
    30     `deg(x^a) = deg(x^b)` and
    31     `\exists\ 0 \le i < n: a_{n-1} = b_{n-1}, \ldots, a_{i+1} = b_{i+1}, a_i > b_i.`
     26Degree reverse lexicographic (degrevlex)
     27    Let `\deg(x^a) = a_1 + a_2 + \dots + a_n`, then
     28    `x^a < x^b` if and only if `\deg(x^a) < \deg(x^b)` or `\deg(x^a) = \deg(x^b)` and 
     29    there exists `1 \le i \le n` such that `a_n = b_n, \dots, a_{i+1} = b_{i+1}, a_i > b_i`. 
     30    This term order is called 'dp' in Singular.   
    3231
    3332    EXAMPLES:
    3433
     
    4645        sage: x^2*y*z^2 > x*y^3*z
    4746        False
    4847
    49     This term ordering is called 'dp' in Singular.
    50 
    51 Degree lexicographic (*deglex*)
    52     Let `deg(x^a) = a_0 + \cdots + a_{n-1},` then
    53     `x^a < x^b \Leftrightarrow deg(x^a) < deg(x^b)` or
    54     `deg(x^a) = deg(x^b)` and
    55     `\exists\ 0 \le i < n:a_0 = b_0, \ldots, a_{i-1} = b_{i-1}, a_i < b_i.`
     48Degree lexicographic (deglex)
     49    Let `\deg(x^a) = a_1 + a_2 + \dots + a_n`, then
     50    `x^a < x^b` if and only if `\deg(x^a) < \deg(x^b)` or `\deg(x^a) = \deg(x^b)` and 
     51    there exists `1 \le i \le n` such that `a_1 = b_1, \dots, a_{i-1} = b_{i-1}, a_i < b_i`. 
     52    This term order is called 'Dp' in Singular.
    5653
    5754    EXAMPLES:
    5855
     
    7067        sage: x^2*y*z^2 > x*y^3*z
    7168        True
    7269
    73     This term order is called 'Dp' in Singular.
    74 
    75 Inverse lexicographic (*invlex*)
    76     `x^a < x^b \Leftrightarrow \exists\; 0 \le i < n : a_{n-1} = b_{n-1}, \ldots, a_{i+1} = b_{i+1}, a_i < b_i.`
     70Inverse lexicographic (invlex)
     71    `x^a < x^b` if and only if there exists `1 \le i \le n` such that `a_n = b_n, \dots, a_{i+1} = b_{i+1}, a_i < b_i`.
     72    This order is called 'rp' in Singular.
    7773
    7874    EXAMPLES:
    7975
     
    8985        sage: x*y > z
    9086        False
    9187
    92     This term ordering only makes sense in a non-commutative setting
     88    This term order only makes sense in a non-commutative setting
    9389    because if P is the ring `k[x_1, \dots, x_n]` and term
    94     ordering 'invlex' then it is equivalent to the ring
    95     `k[x_n, \dots, x_1]` with term ordering 'lex'.
     90    order 'invlex' then it is equivalent to the ring
     91    `k[x_n, \dots, x_1]` with term order 'lex'.
    9692
    97     This ordering is called 'rp' in Singular.
    98 
    99 Negative lexicographic (*neglex*)
    100     `x^a < x^b \Leftrightarrow \exists\; 0 \le i < n : a_0 = b_0, \ldots, a_{i-1} = b_{i-1}, a_i > b_i`
     93Negative lexicographic (neglex)
     94    `x^a < x^b` if and only if there exists `1 \le i \le n` such that `a_1 = b_1, \dots, a_{i-1} = b_{i-1}, a_i > b_i`.   
     95    This term order is called 'ls' in Singular.
    10196
    10297    EXAMPLES:
    10398
     
    115110        sage: x*y > z
    116111        False
    117112
    118     This term ordering is called 'ls' in Singular.
    119 
    120 Negative degree reverse lexicographic (*negdegrevlex*)
    121     Let `deg(x^a) = a_0 + \cdots + a_{n-1},` then
    122     `x^a < x^b \Leftrightarrow deg(x^a) > deg(x^b)` or
    123     `deg(x^a) = deg(x^b)` and
    124     `\exists\ 0 \le i < n: a_{n-1} = b_{n-1}, \ldots, a_{i+1} = b_{i+1}, a_i > b_i.`
     113Negative degree reverse lexicographic (negdegrevlex)
     114    Let `\deg(x^a) = a_1 + a_2 + \dots + a_n`, then
     115    `x^a < x^b` if and only if `\deg(x^a) > \deg(x^b)` or `\deg(x^a) = \deg(x^b)` and 
     116    there exists `1 \le i \le n` such that `a_n = b_n, \dots, a_{i+1} = b_{i+1}, a_i > b_i`. 
     117    This term order is called 'ds' in Singular.
    125118
    126119    EXAMPLES:
    127120
     
    139132        sage: x^2*y*z^2 > x*y^3*z
    140133        False
    141134
    142     This term ordering is called 'ds' in Singular.
    143 
    144 Negative degree lexicographic (*negdeglex*)
    145     Let `deg(x^a) = a_0 + \cdots + a_{n-1},` then
    146     `x^a < x^b \Leftrightarrow deg(x^a) > deg(x^b)` or
    147     `deg(x^a) = deg(x^b)` and
    148     `\exists\ 0 \le i < n: a_0 = b_0, \ldots, a_{i-1} = b_{i-1}, a_i < b_i.`
     135Negative degree lexicographic (negdeglex)
     136    Let `\deg(x^a) = a_1 + a_2 + \dots + a_n`, then
     137    `x^a < x^b` if and only if `\deg(x^a) > \deg(x^b)` or `\deg(x^a) = \deg(x^b)` and
     138    there exists `1 \le i \le n` such that `a_1 = b_1, \dots, a_{i-1} = b_{i-1}, a_i < b_i`. 
     139    This term order is called 'Ds' in Singular.
    149140
    150141    EXAMPLES:
    151142
     
    163154        sage: x^2*y*z^2 > x*y^3*z
    164155        True
    165156
    166     This term ordering is called 'Ds' in Singular.
     157Weighted degree reverse lexicographic (wdegrevlex)
     158    Let `\deg_w(x^a) = a_1w_1 + a_2w_2 + \dots + a_nw_n` with weights `w`, then
     159    `x^a < x^b` if and only if `\deg_w(x^a) < \deg_w(x^b)` or `\deg_w(x^a) = \deg_w(x^b)` and 
     160    there exists `1 \le i \le n` such that `a_n = b_n, \dots, a_{i+1} = b_{i+1}, a_i > b_i`.   
     161    This term order is called 'wp' in Singular.     
    167162
     163    EXAMPLES:
    168164
    169 Of these, only 'degrevlex', 'deglex', 'invlex' and 'lex' are global
    170 orderings.
     165    ::
    171166
    172 Additionally all these monomial orderings may be combined to
    173 product or block orderings, defined as:
     167        sage: P.<x,y,z> = PolynomialRing(QQ, 3, order=TermOrder('wdegrevlex',(1,2,3)))   
     168        sage: x > y
     169        False
     170        sage: x > x^2
     171        False
     172        sage: x > 1
     173        True
     174        sage: x^1*y^2 > x^2*z
     175        True
     176        sage: y*z > x^3*y
     177        False
    174178
    175 Let `x = (x_0, \ldots, x_{n-1})` and
    176 `y = (y_0, \ldots, y_{m-1})` be two ordered sets of
    177 variables, `<_1` a monomial ordering on `k[x]` and
    178 `<_2` a monomial ordering on `k[y]`.
     179Weighted degree lexicographic (wdeglex)
     180    Let `\deg_w(x^a) = a_1w_1 + a_2w_2 + \dots + a_nw_n` with weights `w`, then
     181    `x^a < x^b` if and only if `\deg_w(x^a) < \deg_w(x^b)` or `\deg_w(x^a) = \deg_w(x^b)` and
     182    there exists `1 \le i \le n` such that `a_1 = b_1, \dots, a_{i-1} = b_{i-1}, a_i < b_i`. 
     183    This term order is called 'Wp' in Singular.     
    179184
    180 The product ordering (or block ordering)
    181 `<\ := (<_1,<_2)` on `k[x,y]` is defined as:
    182 `x^a y^b < x^A y^B \Leftrightarrow x^a <_1 x^A` or
    183 `(x^a =x^A \textrm{ and } y^b <_2 y^B)`.
     185    EXAMPLES:
    184186
    185 These block orderings are constructed in Sage by giving a comma
    186 separated list of monomial orderings with the length of each block
    187 attached to them.
     187    ::
     188
     189        sage: P.<x,y,z> = PolynomialRing(QQ, 3, order=TermOrder('wdeglex',(1,2,3)))
     190        sage: x > y
     191        False
     192        sage: x > x^2
     193        False
     194        sage: x > 1
     195        True
     196        sage: x^1*y^2 > x^2*z
     197        False
     198        sage: y*z > x^3*y
     199        False
     200
     201Negative weighted degree reverse lexicographic (negwdegrevlex)
     202    Let `\deg_w(x^a) = a_1w_1 + a_2w_2 + \dots + a_nw_n` with weights `w`, then
     203    `x^a < x^b` if and only if `\deg_w(x^a) > \deg_w(x^b)` or `\deg_w(x^a) = \deg_w(x^b)` and 
     204    there exists `1 \le i \le n` such that `a_n = b_n, \dots, a_{i+1} = b_{i+1}, a_i > b_i`. 
     205    This term order is called 'ws' in Singular.     
     206
     207    EXAMPLES:
     208
     209    ::
     210
     211        sage: P.<x,y,z> = PolynomialRing(QQ, 3, order=TermOrder('negwdegrevlex',(1,2,3))) 
     212        sage: x > y
     213        True
     214        sage: x > x^2
     215        True
     216        sage: x > 1
     217        False
     218        sage: x^1*y^2 > x^2*z
     219        True
     220        sage: y*z > x^3*y
     221        False
     222
     223Negative weighted degree lexicographic (negwdeglex)
     224    Let `\deg_w(x^a) = a_1w_1 + a_2w_2 + \dots + a_nw_n` with weights `w`, then
     225    `x^a < x^b` if and only if `\deg_w(x^a) > \deg_w(x^b)` or `\deg_w(x^a) = \deg_w(x^b)` and
     226    there exists `1 \le i \le n` such that `a_1 = b_1, \dots, a_{i-1} = b_{i-1}, a_i < b_i`.   
     227    This term order is called 'Ws' in Singular.     
     228
     229    EXAMPLES:
     230
     231    ::
     232
     233        sage: P.<x,y,z> = PolynomialRing(QQ, 3, order=TermOrder('negwdeglex',(1,2,3)))     
     234        sage: x > y
     235        True
     236        sage: x > x^2
     237        True
     238        sage: x > 1
     239        False
     240        sage: x^1*y^2 > x^2*z
     241        False
     242        sage: y*z > x^3*y
     243        False
     244
     245Of these, only 'degrevlex', 'deglex', 'wdegrevlex', 'wdeglex', 'invlex' and 'lex' are global
     246orders.   
     247
     248Sage also supports matrix term order. Given a square matrix `A`,
     249
     250    `x^a <_A x^b` if and only if `Aa < Ab`
     251
     252where `<` is the lexicographic term order.
     253
     254EXAMPLE::
     255
     256    sage: m = matrix(2,[2,3,0,1]); m
     257    [2 3]
     258    [0 1]
     259    sage: T = TermOrder(m); T
     260    Matrix term order with matrix
     261    [2 3]
     262    [0 1]   
     263    sage: P.<a,b> = PolynomialRing(QQ,2,order=T)
     264    sage: P
     265    Multivariate Polynomial Ring in a, b over Rational Field
     266    sage: a > b
     267    False
     268    sage: a^3 < b^2
     269    True
     270    sage: S = TermOrder('M(2,3,0,1)')
     271    sage: T == S
     272    True   
     273
     274Additionally all these monomial orders may be combined to product or block orders, defined as:
     275
     276Let `x = (x_1, x_2, \dots, x_n)` and `y = (y_1, y_2, \dots, y_m)` be two ordered sets of
     277variables, `<_1` a monomial order on `k[x]` and `<_2` a monomial order on `k[y]`.
     278
     279The product order (or block order) `<` `:=` `(<_1,<_2)` on `k[x,y]` is defined as:
     280`x^a y^b < x^A y^B` if and only if `x^a <_1 x^A` or (`x^a =x^A` and `y^b <_2 y^B`).
     281
     282These block orders are constructed in Sage by giving a comma separated list of monomial orders
     283with the length of each block attached to them.
    188284
    189285EXAMPLE:
    190286
    191 As an example, consider constructing a block ordering where the
     287As an example, consider constructing a block order where the
    192288first four variables are compared using the degree reverse
    193 lexicographical ordering while the last two variables in the second
    194 block are compared using negative lexicographical ordering.
     289lexicographical order while the last two variables in the second
     290block are compared using negative lexicographical order.
    195291
    196292::
    197293
     
    214310    sage: a > e^4
    215311    True
    216312
    217 Finally Sage supports matrix term order. Given a square matrix `A`,
     313If any other unsupported term order is given the provided string
     314can be forced to be passed through as is to Singular, Macaulay2, and Magma.
     315This ensures that it is for example possible to calculate a Groebner
     316basis with respect to some term order Singular supports but Sage
     317doesn't::
    218318
    219     `x^a < x^b \Leftrightarrow x^{Aa} <_{\mathrm{lex}} x^{Ab}`
    220 
    221 where `<_{\mathrm{lex}}` is the lexicographic term order.
    222 
    223 EXAMPLE::
    224 
    225     sage: m = matrix(2,[2,3,0,1]); m
    226     [2 3]
    227     [0 1]
    228     sage: T = TermOrder(m); T
    229     Matrix term order with matrix
    230     [2 3]
    231     [0 1]   
    232     sage: P.<a,b> = PolynomialRing(QQ,2,order=T)
    233     sage: P
    234     Multivariate Polynomial Ring in a, b over Rational Field
    235     sage: a > b
    236     False
    237     sage: a^3 < b^2
    238     True
    239     sage: S = TermOrder('M(2,3,0,1)')
    240     sage: T == S
    241     True
    242 
    243 A matrix term ordering is not allowed in block ordering yet::
    244 
    245     sage: T+S
     319    sage: T = TermOrder("royalorder")
    246320    Traceback (most recent call last):
    247321    ...
    248     NotImplementedError: Cannot use a matrix term order as a block.
    249 
    250 If any other unsupported term ordering is given the provided string
    251 is passed through as is to Singular, Macaulay2, and Magma. This
    252 ensures that it is for example possible to calculate a Groebner
    253 basis with respect to some term ordering Singular supports but Sage
    254 doesn't. However a warning is issued to make the user aware of the
    255 situation and potential typos::
    256 
    257     sage: T = TermOrder("royalorder")
    258     verbose 0 (...: term_order.py, __init__) Term ordering 'royalorder' unknown.
    259 
     322    TypeError: Unknown term order 'royalorder'
     323    sage: T = TermOrder("royalorder",force=True)
     324    sage: T
     325    royalorder term order
     326    sage: T.singular_str()
     327    'royalorder'
     328   
    260329AUTHORS:
    261330
    262 - David Joyner and William Stein: initial version
    263   multi_polynomial_ring
     331- David Joyner and William Stein: initial version of multi_polynomial_ring
    264332
    265333- Kiran S. Kedlaya: added macaulay2 interface
    266334
    267 - Martin Albrecht: implemented native term orderings, refactoring
     335- Martin Albrecht: implemented native term orders, refactoring
    268336
    269 - Kwankyu Lee (2010-06): implemented matrix term ordering
     337- Kwankyu Lee: implemented matrix and weighted degree term orders, refactoring
    270338"""
    271339
    272 import re
    273 from sage.structure.sage_object import SageObject
     340import re 
     341from sage.structure.sage_object import SageObject   
    274342
    275343print_name_mapping = {
    276     'lex'          :'Lexicographic',
    277     'invlex'       :'Inverse Lexicographic',
    278     'degrevlex'    :'Degree reverse lexicographic',
    279     'deglex'       :'Degree lexicographic',
    280     'neglex'       :'Negative lexicographic',
    281     'negdegrevlex' :'Negative degree reverse lexicographic',
    282     'negdeglex'    :'Negative degree lexicographic'}
     344    'lex'           : 'Lexicographic',
     345    'invlex'        : 'Inverse lexicographic',
     346    'degrevlex'     : 'Degree reverse lexicographic',   
     347    'deglex'        : 'Degree lexicographic',       
     348    'neglex'        : 'Negative lexicographic',
     349    'negdegrevlex'  : 'Negative degree reverse lexicographic',
     350    'negdeglex'     : 'Negative degree lexicographic',
     351    'wdegrevlex'    : 'Weighted degree reverse lexicographic', 
     352    'wdeglex'       : 'Weighted degree lexicographic',
     353    'negwdegrevlex' : 'Negative weighted degree reverse lexicographic',
     354    'negwdeglex'    : 'Negative weighted degree lexicographic',       
     355}
    283356
    284357singular_name_mapping = {
    285     'lex'          :'lp',
    286     'invlex'       :'rp',
    287     'degrevlex'    :'dp',
    288     'deglex'       :'Dp',
    289     'neglex'       :'ls',
    290     'negdegrevlex' :'ds',
    291     'negdeglex'    :'Ds'}
     358    'lex'           : 'lp',
     359    'invlex'        : 'rp',
     360    'degrevlex'     : 'dp',
     361    'deglex'        : 'Dp',
     362    'neglex'        : 'ls',
     363    'negdegrevlex'  : 'ds',
     364    'negdeglex'     : 'Ds',
     365    'wdegrevlex'    : 'wp', 
     366    'wdeglex'       : 'Wp',
     367    'negwdegrevlex' : 'ws',
     368    'negwdeglex'    : 'Ws',     
     369}
    292370
    293 inv_singular_name_mapping = {
    294     'lp'           :'lex',
    295     'rp'           :'invlex',
    296     'dp'           :'degrevlex',
    297     'Dp'           :'deglex',
    298     'ls'           :'neglex',
    299     'ds'           :'negdegrevlex',
    300     'Ds'           :'negdeglex'}
     371inv_singular_name_mapping = dict(zip(singular_name_mapping.values(),singular_name_mapping.keys()))
    301372
    302373macaulay2_name_mapping = {
    303     'lex'          :'Lex',
    304     'revlex'       :'RevLex, Global=>false',
    305     'degrevlex'    :'GRevLex',
    306     'deglex'       :'GLex'}
     374    'lex'           : 'Lex',
     375    'revlex'        : 'RevLex, Global=>false',
     376    'degrevlex'     : 'GRevLex',
     377    'deglex'        : 'GLex',
     378}
    307379
    308 inv_macaulay2_name_mapping = {
    309     'Lex'          :'lex',
    310     'RevLex,Global=>false' :'revlex',
    311     'GRevLex'      :"degrevlex",
    312     'GLex'         :'deglex'}
     380inv_macaulay2_name_mapping = dict(zip(macaulay2_name_mapping.values(),macaulay2_name_mapping.keys()))
    313381
    314 magma_name_mapping =     {
    315     'lex'          :'"lex"',
    316     'degrevlex'    :'"grevlex"',
    317     'deglex'       :'"glex"'}
     382magma_name_mapping = {
     383    'lex'           : '"lex"',
     384    'degrevlex'     : '"grevlex"',
     385    'deglex'        : '"glex"',
     386}
    318387
    319 lp_description = """
    320 Lexicographic (lex) term ordering.
     388inv_magma_name_mapping = dict(zip(magma_name_mapping.values(),magma_name_mapping.keys()))
    321389
    322 $x^a < x^b <=> \exists\; 0 <= i < n : a_0 = b_0, ..., a_{i-1} = b_{i-1}, a_i < b_i$
     390lex_description = """
     391Lexicographic (lex) term order.
     392
     393`x^a < x^b` if and only if there exists `1 \le i \le n` such that `a_1 = b_1, \dots, a_{i-1} = b_{i-1}, a_i < b_i`. 
    323394"""
    324395
    325 dp_description = """
    326 Degree reverse lexicographic (degrevlex) term ordering.
     396invlex_description = """
     397Inverse lexicographic (invlex) term order.
    327398
    328 Let $deg(x^a) = a_0 + ... + a_{n-1},$ then $x^a < x^b <=> deg(x^a) < deg(x^b)$ or
    329 $deg(x^a) = deg(x^b)$ and $\exists\ 0 <= i < n: a_{n-1} = b_{n-1}, ..., a_{i+1} = b_{i+1}, a_i > b_i.$
     399`x^a < x^b` if and only if there exists `1 \le i \le n` such that `a_n = b_n, \dots, a_{i+1} = b_{i+1}, a_i < b_i`. 
     400""" 
     401
     402degrevlex_description = """
     403Degree reverse lexicographic (degrevlex) term order.
     404
     405Let `\deg(x^a) = a_1 + a_2 + \dots + a_n`, then
     406`x^a < x^b` if and only if `\deg(x^a) < \deg(x^b)` or `\deg(x^a) = \deg(x^b)` and 
     407there exists `1 \le i \le n` such that `a_n = b_n, \dots, a_{i+1} = b_{i+1}, a_i > b_i`.
    330408"""
    331409
    332 Dp_description = """
    333 Degree lexicographic (deglex) term ordering.
     410deglex_description = """
     411Degree lexicographic (deglex) term order.
    334412
    335 Let $deg(x^a) = a_0 + \cdots + a_{n-1},$ then $x^a < x^b \Leftrightarrow deg(x^a) < deg(x^b)$ or
    336 $deg(x^a) = deg(x^b)$ and $\exists\ 0 \le i < n:a_0 = b_0, \ldots, a_{i-1} = b_{i-1}, a_i < b_i.$
     413Let `\deg(x^a) = a_1 + a_2 + \dots + a_n`, then
     414`x^a < x^b` if and only if `\deg(x^a) < \deg(x^b)` or `\deg(x^a) = \deg(x^b)` and 
     415there exists `1 \le i \le n` such that `a_1 = b_1, \dots, a_{i-1} = b_{i-1}, a_i < b_i`.   
    337416"""
    338417
    339 rp_description = """
    340 Inverse lexicographic (invlex) term ordering.
     418neglex_description = """
     419Negative lexicographic (neglex) term order.
    341420
    342 $x^a < x^b \Leftrightarrow \exists\; 0 \le i < n : a_{n-1} = b_{n-1}, \ldots, a_{i+1} = b_{i+1}, a_i < b_i.$
     421`x^a < x^b` if and only if there exists `1 \le i \le n` such that `a_1 = b_1, \dots, a_{i-1} = b_{i-1}, a_i > b_i`.
    343422"""
    344423
    345 ls_description = """
    346 Negative lexicographic (neglex) term ordering.
     424negdegrevlex_description = """
     425Negative degree reverse lexicographic (negdegrevlex) term order.
    347426
    348 $x^a < x^b \Leftrightarrow \exists\; 0 \le i < n : a_0 = b_0, \ldots, a_{i-1} = b_{i-1}, a_i > b_i$
     427Let `\deg(x^a) = a_1 + a_2 + \dots + a_n`, then
     428`x^a < x^b` if and only if `\deg(x^a) > \deg(x^b)` or `\deg(x^a) = \deg(x^b)` and 
     429there exists `1 \le i \le n` such that `a_n = b_n, \dots, a_{i+1} = b_{i+1}, a_i > b_i`.   
     430"""   
     431
     432negdeglex_description = """
     433Negative degree lexicographic (negdeglex) term order.
     434
     435Let `\deg(x^a) = a_1 + a_2 + \dots + a_n`, then
     436`x^a < x^b` if and only if `\deg(x^a) > \deg(x^b)` or `\deg(x^a) = \deg(x^b)` and
     437there exists `1 \le i \le n` such that `a_1 = b_1, \dots, a_{i-1} = b_{i-1}, a_i < b_i`.
     438""" 
     439
     440wdegrevlex_description = """ 
     441Weighted degree reverse lexicographic (wdegrevlex) term order.
     442 
     443Let `\deg_w(x^a) = a_1w_1 + a_2w_2 + \dots + a_nw_n` with weights `w`, then
     444`x^a < x^b` if and only if `\deg_w(x^a) < \deg_w(x^b)` or `\deg_w(x^a) = \deg_w(x^b)` and 
     445there exists `1 \le i \le n` such that `a_n = b_n, \dots, a_{i+1} = b_{i+1}, a_i > b_i`.   
    349446"""
     447 
     448wdeglex_description = r""" 
     449Weighted degree lexicographic (wdeglex) term order.
    350450
    351 ds_description = """
    352 Negative degree reverse lexicographic (negdegrevlex) term ordering.
     451Let `\deg_w(x^a) = a_1w_1 + a_2w_2 + \dots + a_nw_n` with weights `w`, then
     452`x^a < x^b` if and only if `\deg_w(x^a) < \deg_w(x^b)` or `\deg_w(x^a) = \deg_w(x^b)` and
     453there exists `1 \le i \le n` such that `a_1 = b_1, \dots, a_{i-1} = b_{i-1}, a_i < b_i`. 
     454""" 
    353455
    354 Let $deg(x^a) = a_0 + \cdots + a_{n-1},$ then $x^a < x^b \Leftrightarrow deg(x^a) > deg(x^b)$ or
    355 $deg(x^a) = deg(x^b)$ and $\exists\ 0 \le i < n: a_{n-1} = b_{n-1}, \ldots, a_{i+1} = b_{i+1}, a_i > b_i.$
     456negwdegrevlex_description = """ 
     457Negative weighted degree reverse lexicographic (negwdegrevlex) term order.
     458
     459Let `\deg_w(x^a) = a_1w_1 + a_2w_2 + \dots + a_nw_n` with weights `w`, then
     460`x^a < x^b` if and only if `\deg_w(x^a) > \deg_w(x^b)` or `\deg_w(x^a) = \deg_w(x^b)` and 
     461there exists `1 \le i \le n` such that `a_n = b_n, \dots, a_{i+1} = b_{i+1}, a_i > b_i`. 
    356462"""
     463 
     464negwdeglex_description = """ 
     465Negative weighted degree lexicographic (negwdeglex) term order.
    357466
    358 Ds_description = """
    359 Negative degree lexicographic (negdeglex) term ordering.
     467Let `\deg_w(x^a) = a_1w_1 + a_2w_2 + \dots + a_nw_n` with weights `w`, then
     468`x^a < x^b` if and only if `\deg_w(x^a) > \deg_w(x^b)` or `\deg_w(x^a) = \deg_w(x^b)` and
     469there exists `1 \le i \le n` such that `a_1 = b_1, \dots, a_{i-1} = b_{i-1}, a_i < b_i`.   
     470"""   
    360471
    361 Let $deg(x^a) = a_0 + \cdots + a_{n-1},$ then $x^a < x^b \Leftrightarrow deg(x^a) > deg(x^b)$ or
    362 $deg(x^a) = deg(x^b)$ and $\exists\ 0 \le i < n: a_0 = b_0, \ldots, a_{i-1} = b_{i-1}, a_i < b_i.$
    363 """
     472matrix_description = """
     473Matrix term order defined by a matrix A.
     474
     475`x^a < x^b` if and only if `x^{Aa} < x^{Ab}` where `<` is the lexicographic term order.
     476""" 
     477
     478block_description = """
     479Block term order defined by term orders `<_1, <_2, \dots, <_n`.
     480
     481`x^a < x^b` if and only if `a = b` with respect to the first `n-1` term orders and `a <_n b`
     482with respect to the `n`th term order `<_n`.
     483"""   
    364484
    365485description_mapping = {
    366     "lp":lp_description,
    367     "dp":dp_description,
    368     "Dp":Dp_description,
    369     "rp":rp_description,
    370     "ls":ls_description,
    371     "Ds":Ds_description,
    372     "ds":ds_description}
     486    'lex'           : lex_description,
     487    'invlex'        : invlex_description,
     488    'degrevlex'     : degrevlex_description,
     489    'deglex'        : deglex_description,
     490    'neglex'        : neglex_description,
     491    'negdegrevlex'  : negdegrevlex_description,
     492    'negdeglex'     : negdeglex_description,
     493    'wdeglex'       : wdeglex_description,
     494    'wdegrevlex'    : wdegrevlex_description, 
     495    'negwdegrevlex' : negwdegrevlex_description,
     496    'negwdeglex'    : negwdeglex_description,
     497    'matrix'        : matrix_description,
     498    'block'         : block_description,
    373499
    374 M_description = """
    375 Matrix term ordering defined by a matrix A.
    376 
    377 $x^a < x^b \Leftrightarrow x^{Aa} <_{\mathrm{lex}} x^{Ab}$
    378 where $<_{\mathrm{lex}}$ is the lexicographic term ordering
    379 """ 
     500}
    380501
    381502class TermOrder(SageObject):
    382503    r"""
    383504    A term order.
    384505   
    385506    See ``sage.rings.polynomial.term_order`` for details
    386     on supported term orderings.
     507    on supported term orders.
    387508    """
    388     def __init__(self, name='lex', n = 0, blocks=True, force=False):
     509    def __setstate__(self, dict):
    389510        """
    390         Construct a new term ordering object.
     511        Translate pickled TermOrder objects with old data structure.
     512
     513        EXAMPLE::
     514
     515            sage: t = TermOrder('lex')
     516            sage: t2 = loads(dumps(t))
     517            sage: t2._TermOrder__weights is None
     518            True
     519        """
     520        if not dict.has_key('_TermOrder__weights'):
     521            name = dict['_TermOrder__name']
     522            n = dict['_TermOrder__length']
     523            t = TermOrder(name,n)
     524            self.__dict__.update(t.__dict__)
     525        else:
     526            self.__dict__.update(dict)
     527
     528    def __init__(self, name='lex', n=0, blocks=True, force=False):
     529        """
     530        Construct a new term order object.
    391531       
    392532        INPUT:
    393533       
    394         - ``name`` - name of the term ordering (default: lex)
     534        - ``name`` - name of the term order (default: lex)
    395535       
    396         - ``n`` - number of variables in the polynomial ring
    397            (default: 0)
     536        - ``n`` - number of variables (default is `0`) or weights for
     537          weighted degree orders
     538
     539        - ``blocks`` - this is deprecated.
    398540       
    399         - ``blocks`` - controls whether a list of blocks is
    400            maintained (internal use only, default:True)
    401 
    402         - ``force`` - ignore unknown term orderings.
     541        - ``force`` - ignore unknown term orders.
    403542       
    404543        See the ``sage.rings.polynomial.term_order`` module
    405         for help which names and orderings are available.
     544        for help which names and orders are available.
    406545       
    407546        EXAMPLES::
    408547       
     
    412551            sage: loads(dumps(t)) == t
    413552            True
    414553       
    415         We can construct block orderings directly as
     554        We can construct block orders directly as
    416555       
    417556        ::
    418557       
    419558            sage: TermOrder('degrevlex(3),neglex(2)')
    420             degrevlex(3),neglex(2) term order
     559            Block term order with blocks:
     560            (Degree reverse lexicographic term order of length 3,
     561             Negative lexicographic term order of length 2)
    421562       
    422563        or by adding together the blocks::
    423564       
    424565            sage: t1 = TermOrder('degrevlex',3)
    425566            sage: t2 = TermOrder('neglex',2)
    426567            sage: t1 + t2
    427             degrevlex(3),neglex(2) term order
    428             sage: t2 + t1
    429             neglex(2),degrevlex(3) term order
     568            Block term order with blocks:
     569            (Degree reverse lexicographic term order of length 3,
     570             Negative lexicographic term order of length 2)
     571            sage: t3 = TermOrder('wdeglex',(1,2))
     572            sage: t1 + t3
     573            Block term order with blocks:
     574            (Degree reverse lexicographic term order of length 3,
     575             Weighted degree lexicographic term order with weights (1, 2))
    430576       
    431577        .. note::
    432578
    433579           The optional `n` parameter is not necessary if only
    434            non-block orderings like `deglex` are
    435            constructed. However, it is useful if block orderings are
     580           non-block orders like `deglex` are
     581           constructed. However, it is useful if block orders are
    436582           to be constructed from this ``TermOrder`` object later.
    437         """
     583        """ 
    438584        if isinstance(name, TermOrder):
    439             if n == 0 and len(name) > 0:
    440                 n = len(name)
     585            self.__copy(name)
     586            if n > 0 and not name.is_block_order() and not name.is_weighted_degree_order():
     587                self.__length = n
     588            return 
     589
     590        if isinstance(name, str): 
     591            name = name.lower()
     592        else:
    441593            try:
    442                 force = name.__force
    443             except AttributeError: # pickled old TermOrders don't have this field
    444                 force = False
    445             name = name.name()
    446         else:
    447             try: # name is a matrix
    448                 name = 'M('+','.join(["%i"%(i,) for i in name.list()])+')'
     594                if not isinstance(name, (tuple,list)):
     595                    name = name.list() # name may be a matrix
     596                name = tuple(name)
    449597            except:
    450                 pass
    451         name = name.lower()
     598                raise TypeError, "%s is not a valid term order"%(name,)
    452599
    453         split_pattern = "([^(),]+(?:\([^()]*\)[^(),]*)*)" # split by outermost commas
    454         length_pattern  = re.compile("\(([0-9]+)\)$") # match with parenthesized block length at end
    455         matrix_pattern = "([0-9,]+)" # match with list of integers
    456        
    457         self.__force = force
    458         self.__length = 0
    459         self.__name = ""
    460         self.__singular_str = ""
    461         self.__macaulay2_str = ""
    462         self.__magma_str = ""
    463         self.__matrix = None # only for matrix ordering
    464          
    465         block_names = re.findall(split_pattern,name)
     600        self.__blocks = tuple()
     601        self.__weights = None
     602        self.__matrix = None
    466603
    467         if len(block_names) == 0:
    468             raise TypeError, "No term ordering specified"
    469         elif len(block_names) == 1:
    470             name = block_names[0]
    471             if re.match('m\(([0-9,]+)\)$',name) != None: # matrix ordering
    472                 integers_str = re.search(matrix_pattern,name).group()
    473                 integers = map(int,integers_str.split(','))
    474 
    475                 if n == 0:
    476                     from math import sqrt
    477                     n = int(sqrt(len(integers)))
    478 
    479                 if len(integers) != n**2:
    480                     raise TypeError, "%s does not specify a square matrix"%(name,)
    481 
    482                 self.__matrix = []
    483                 for idx in range(0,len(integers),n):
    484                     self.__matrix.append(integers[idx:idx+n])
    485 
    486                 self.__length = n
    487                 self.__name = "M(%s)"%(integers_str,)
    488                 self.__singular_str = "M(%s)"%(integers_str,)
    489                 self.__macaulay2_str = "" # Macaulay2 does not support matrix term order directly
    490                 self.__magma_str = '"weight",[%s]'%(integers_str,)
    491                 self.__doc__ = M_description
    492 
    493             else: # simple ordering
    494                 self.__length = n
    495                 self.__name = name
    496                 self.__singular_str = singular_name_mapping.get(name,name)
    497                 self.__macaulay2_str = macaulay2_name_mapping.get(name,name)
    498                 self.__magma_str = magma_name_mapping.get(name,name)
    499 
    500                 if self.__singular_str in description_mapping:
    501                     self.__doc__ = description_mapping[self.__singular_str]                 
    502            
    503             from sage.misc.misc import verbose
    504             if blocks:
    505                 # we allow deglex_asc here which is used by PolyBoRi
    506                 if self.__matrix == None and \
    507                    name not in singular_name_mapping.keys() and \
    508                    name not in singular_name_mapping.values() and not force:
    509                     verbose("Term ordering '%s' unknown."%name,level=0)
    510                 self.blocks = (TermOrder(self.__name,n,blocks=False,force=force),)
    511             else:
    512                 self.blocks = tuple()   
    513 
    514         else: # block ordering
     604        if name == "block": # block term order with blocks in a list
    515605            length = 0
    516606            blocks = []
    517607            name_str = []
    518608            singular_str = []
    519609            macaulay2_str = []
    520610
    521             for block in block_names:
    522                 try:
    523                     block_name, block_length, _ = re.split(length_pattern,block)
    524                 except ValueError:
    525                     raise TypeError, "%s is not a valid term ordering"%(name,)
     611            for t in n:
     612                if not isinstance(t, TermOrder):
     613                    try:
     614                        t = TermOrder(t,force=True)
     615                    except:
     616                        raise TypeError
     617                if t.name() == 'block':
     618                    blocks = blocks + list(t.blocks())
     619                    singular_str.append("%s"%(t.singular_str()[1:-1],))  # [1:-1] is needed to remove parenthesis
     620                    macaulay2_str.append("%s"%(t.macaulay2_str()[1:-1],)) 
     621                else:
     622                    if len(t) == 0:
     623                        raise ArithmeticError, "Can only concatenate term orders with length attribute."   
     624                    blocks.append(t)
     625                    if t.is_weighted_degree_order(): # true if t is a matrix order as well
     626                        singular_str.append("%s"%(t.singular_str(),))
     627                    else:
     628                        singular_str.append("%s(%d)"%(t.singular_str(), len(t)))                                           
     629                    macaulay2_str.append("%s => %d"%(t.macaulay2_str(), len(t)))
     630                length += len(t)
    526631
    527                 block_length = int(block_length)
     632            self.__length = length
     633            self.__name = "block"
     634            self.__singular_str = "(" + ",".join(singular_str) + ")"
     635            self.__macaulay2_str = "{" + ",".join(macaulay2_str) + "}"
     636            self.__magma_str = "" # Magma does not support block order
     637            self.__blocks = tuple(blocks)
     638        elif isinstance(name, str) and not (isinstance(n, tuple) or isinstance(n,list)): # string representation of simple or block orders
     639            split_pattern = "([^(),]+(?:\([^()]*\)[^(),]*)*)" # split by outermost commas         
     640            block_names = re.findall(split_pattern,name)
    528641
    529                 blocks.append( TermOrder(block_name,block_length,force=force) )
    530                 name_str.append("%s(%d)"%(block_name,block_length))
    531                 singular_str.append("%s(%d)"%(singular_name_mapping.get(block_name, block_name), block_length))
    532                 macaulay2_str.append("%s => %d"%(macaulay2_name_mapping.get(block_name, block_name), block_length))
     642            if len(block_names) == 0:
     643                raise TypeError, "No term order specified"
     644            elif len(block_names) == 1:
     645                name = block_names[0]
     646                match = re.match('m\(([-+0-9,]+)\)$',name)
     647                if match: # matrix term order
     648                    m = map(int,match.groups()[0].split(',')) # replace match.groups()[0]  with match.group(1) later
     649                    self.__copy(TermOrder(m))
     650                else: # simple order
     651                    if name not in print_name_mapping.keys() and name not in singular_name_mapping.values() and not force:
     652                        raise TypeError, "Unknown term order '%s'"%(name,)
     653                    self.__length = n
     654                    self.__name = name
     655                    self.__singular_str = singular_name_mapping.get(name,name)
     656                    self.__macaulay2_str = macaulay2_name_mapping.get(name,name)
     657                    self.__magma_str = magma_name_mapping.get(name,name)               
     658            else: # len(block_names) > 1, and hence block order represented by a string
     659                length = 0
     660                blocks = []
     661                name_str = []
     662                singular_str = []
     663                macaulay2_str = []
    533664
    534                 length += block_length
     665                for block in block_names:
     666                    try:
     667                        length_pattern  = re.compile("\(([0-9]+)\)$") # match with parenthesized block length at end                 
     668                        block_name, block_length, _ = re.split(length_pattern,block)
     669                        block_length = int(block_length)
     670                        blocks.append( TermOrder(block_name,block_length,force=force) )
     671                    except:
     672                        raise TypeError, "%s is not a valid term order"%(name,)
     673                    length += block_length
    535674
    536             self.blocks = tuple(blocks)
    537             self.__length = length
    538             self.__name = ",".join(name_str)
    539             self.__singular_str = "(" + ",".join(singular_str) + ")"
    540             self.__macaulay2_str = "(" + ",".join(macaulay2_str) + ")"
    541             self.__magma_str = "" # Magma does not support block order
     675                if n != 0 and length != n:
     676                    raise TypeError, "Term order length does not match the number of generators"
     677                self.__copy(TermOrder('block', blocks))
     678        elif isinstance(name, str) and (isinstance(n, tuple) or isinstance(n,list)): # weighted degree term orders
     679            if name not in print_name_mapping.keys() and name not in singular_name_mapping.values() and not force:
     680                raise TypeError, "Unknown term order '%s'"%(name,) 
     681            weights = tuple(n) # n is a tuple of weights
     682           
     683            self.__length = len(weights)
     684            self.__name = name
     685            self.__singular_str = singular_name_mapping.get(name,name) + '(' + ','.join([str(w) for w in weights]) + ')'
     686            self.__macaulay2_str = ""
     687            self.__magma_str = ""
     688            self.__weights = weights # defined only for weighted degree orders                   
     689        elif isinstance(name, tuple): # name represents a matrix 
     690            if n == 0:
     691                from math import sqrt
     692                n = int(sqrt(len(name)))                   
     693            if n**2 != len(name):
     694                raise TypeError, "%s does not specify a square matrix"%(name,)   
    542695
    543             if n != 0 and self.__length != n:
    544                 raise TypeError, "Term order length does not match the number of generators"
     696            int_str = ','.join([str(int(e)) for e in name])
     697
     698            self.__length = n
     699            self.__name = "matrix"
     700            self.__singular_str = "M(%s)"%(int_str,)
     701            self.__macaulay2_str = "" # Macaulay2 does not support matrix term order directly
     702            self.__magma_str = '"weight",[%s]'%(int_str,)
     703
     704            from sage.matrix.constructor import matrix   
     705            self.__matrix = matrix(n,name)  # defined only for matrix term order
     706            self.__weights = name[:n] # the first row of the matrix gives weights
     707        else:
     708            raise TypeError, "%s is not a valid term order"%(name,)   
     709
     710        self.__doc__ = description_mapping.get(self.__name, "No description available")                 
     711
     712    def __copy(self, other):
     713        """
     714        Copy other term order to self.
     715
     716        EXAMPLE::
     717       
     718            sage: t = TermOrder('lex')
     719            sage: s = TermOrder(t)
     720            sage: t == s            # indirect test
     721            True
     722        """
     723        self.__length = other._TermOrder__length
     724        self.__name = other._TermOrder__name
     725        self.__singular_str = other._TermOrder__singular_str
     726        self.__macaulay2_str = other._TermOrder__macaulay2_str
     727        self.__magma_str = other._TermOrder__magma_str
     728        self.__blocks = other._TermOrder__blocks
     729
     730        self.__matrix = other._TermOrder__matrix
     731        self.__weights = other._TermOrder__weights
    545732
    546733    def __getattr__(self,name):
    547734        """
     
    550737        EXAMPLE::
    551738       
    552739            sage: TermOrder('lex').compare_tuples
    553             <bound method TermOrder.compare_tuples_lp of Lexicographic term order>
     740            <bound method TermOrder.compare_tuples_lex of Lexicographic term order>
    554741       
    555742        ::
    556743       
    557744            sage: TermOrder('deglex').compare_tuples
    558             <bound method TermOrder.compare_tuples_Dp of Degree lexicographic term order>
     745            <bound method TermOrder.compare_tuples_deglex of Degree lexicographic term order>
    559746        """
    560747        if name == 'compare_tuples':
    561             if len(self.blocks) <= 1:
    562                 if self.__matrix != None:
    563                     return self.compare_tuples_matrix
    564                 else:
    565                     return getattr(self,'compare_tuples_'+self.__singular_str)
    566             else:
    567                 return self.compare_tuples_block
     748            return getattr(self,'compare_tuples_'+self.__name)
    568749        elif name == 'greater_tuple':
    569             if len(self.blocks) <= 1:
    570                 if self.__matrix != None:
    571                     return self.greater_tuple_matrix
    572                 else:
    573                     return getattr(self,'greater_tuple_'+self.__singular_str)
    574             else:
    575                 return self.greater_tuple_block
     750            return getattr(self,'greater_tuple_'+self.__name)
    576751        else:
    577752            raise AttributeError,name
    578753
     
    596771            False
    597772        """
    598773        for row in self.__matrix:
    599             mf = sum(l*r for (l,r) in zip(row,f))
    600             mg = sum(l*r for (l,r) in zip(row,g))
     774            sf = sum(l*r for (l,r) in zip(row,f))
     775            sg = sum(l*r for (l,r) in zip(row,g))
    601776       
    602             if mf > mg:
     777            if sf > sg:
    603778                return 1
    604             elif mf < mg:
     779            elif sf < sg:
    605780                return -1
    606781        return 0 
    607782
    608     def compare_tuples_lp(self,f,g):
     783    def compare_tuples_lex(self,f,g):
    609784        """
    610785        Compares two exponent tuples with respect to the lexicographical
    611786        term order.
     
    624799            sage: x > 1
    625800            True
    626801        """
    627 
    628         if f>g:
     802        if f > g:
    629803            return 1
    630         elif f<g:
     804        elif f < g:
    631805            return -1
    632806        else:
    633807            return 0
    634808
    635     def compare_tuples_rp(self,f,g):
     809    def compare_tuples_invlex(self,f,g):
    636810        """
    637811        Compares two exponent tuples with respect to the inversed
    638812        lexicographical term order.
     
    651825            sage: x > 1
    652826            True
    653827        """
    654         return self.compare_tuples_lp(f.reversed(),g.reversed())
     828        return self.compare_tuples_lex(f.reversed(),g.reversed())
    655829
    656     def compare_tuples_Dp(self,f,g):
     830    def compare_tuples_deglex(self,f,g):
    657831        """
    658832        Compares two exponent tuples with respect to the degree
    659833        lexicographical term order.
     
    676850        sg = sum(g.nonzero_values(sort=False))
    677851        if sf > sg:
    678852            return 1
    679         elif sf<sg:
     853        elif sf < sg:
    680854            return -1
    681855        elif sf == sg:
    682             return self.compare_tuples_lp(f,g)
     856            return self.compare_tuples_lex(f,g)
    683857
    684     def compare_tuples_dp(self,f,g):
     858    def compare_tuples_degrevlex(self,f,g):
    685859        """
    686860        Compares two exponent tuples with respect to the degree reversed
    687861        lexicographical term order.
     
    704878        sg = sum(g.nonzero_values(sort=False))
    705879        if sf > sg:
    706880            return 1
    707         elif sf<sg:
     881        elif sf < sg:
    708882            return -1
    709883        elif sf == sg:
    710             return (-1)*self.compare_tuples_lp(f.reversed(),g.reversed())
     884            return -self.compare_tuples_lex(f.reversed(),g.reversed())
    711885
    712     def compare_tuples_ls(self,f,g):
     886    def compare_tuples_neglex(self,f,g):
    713887        """
    714888        Compares two exponent tuples with respect to the negative
    715889        lexicographical term order.
     
    728902            sage: x > 1
    729903            False
    730904        """
    731         return -self.compare_tuples_lp(f,g)
     905        return -self.compare_tuples_lex(f,g)
    732906
    733     def compare_tuples_ds(self,f,g):
     907    def compare_tuples_negdegrevlex(self,f,g):
    734908        """
    735909        Compares two exponent tuples with respect to the negative degree
    736910        reverse lexicographical term order.
     
    753927        sg = sum(g.nonzero_values(sort=False))
    754928        if sf > sg:
    755929            return -1
    756         elif sf<sg:
     930        elif sf < sg:
    757931            return 1
    758932        elif sf == sg:
    759             return (-1)*self.compare_tuples_lp(f.reversed(),g.reversed())
     933            return (-1)*self.compare_tuples_lex(f.reversed(),g.reversed())
    760934
    761     def compare_tuples_Ds(self,f,g):
     935    def compare_tuples_negdeglex(self,f,g):
    762936        """
    763937        Compares two exponent tuples with respect to the negative degree
    764938        lexicographical term order.
     
    781955        sg = sum(g.nonzero_values(sort=False))
    782956        if sf > sg:
    783957            return -1
    784         elif sf<sg:
     958        elif sf < sg:
    785959            return 1
    786960        elif sf == sg:
    787             return self.compare_tuples_lp(f,g)
     961            return self.compare_tuples_lex(f,g)
     962
     963    def compare_tuples_wdegrevlex(self,f,g):
     964        """
     965        Compares two exponent tuples with respect to the weighted degree reverse
     966        lexicographical term order.
     967       
     968        INPUT:
     969       
     970        - ``f`` - exponent tuple
     971       
     972        - ``g`` - exponent tuple
     973       
     974        EXAMPLE::
     975 
     976            sage: t = TermOrder('wdegrevlex',(3,2)) 
     977            sage: P.<x,y> = PolynomialRing(QQbar, 2, order=t)
     978            sage: x > y^2 # indirect doctest
     979            False
     980            sage: x^2 > y^3
     981            True
     982        """
     983        sf = sum(l*r for (l,r) in zip(f,self.__weights))
     984        sg = sum(l*r for (l,r) in zip(g,self.__weights)) 
     985        if sf > sg:
     986            return 1
     987        elif sf < sg:
     988            return -1
     989        elif sf == sg:
     990            return -self.compare_tuples_lex(f.reversed(),g.reversed()) 
     991
     992    def compare_tuples_wdeglex(self,f,g):
     993        """
     994        Compares two exponent tuples with respect to the weighted degree
     995        lexicographical term order.
     996       
     997        INPUT:
     998       
     999        - ``f`` - exponent tuple
     1000       
     1001        - ``g`` - exponent tuple
     1002       
     1003        EXAMPLE::
     1004       
     1005            sage: t = TermOrder('wdeglex',(3,2))
     1006            sage: P.<x,y> = PolynomialRing(QQbar, 2, order=t)
     1007            sage: x > y^2 # indirect doctest
     1008            False
     1009            sage: x > y
     1010            True
     1011        """
     1012        sf = sum(l*r for (l,r) in zip(f,self.__weights))
     1013        sg = sum(l*r for (l,r) in zip(g,self.__weights)) 
     1014        if sf > sg:
     1015            return 1
     1016        elif sf < sg:
     1017            return -1
     1018        elif sf == sg:
     1019            return self.compare_tuples_lex(f,g)   
     1020
     1021    def compare_tuples_negwdeglex(self,f,g):
     1022        """
     1023        Compares two exponent tuples with respect to the negative weighted
     1024        degree lexicographical term order.
     1025       
     1026        INPUT:
     1027       
     1028        - ``f`` - exponent tuple
     1029       
     1030        - ``g`` - exponent tuple
     1031       
     1032        EXAMPLE::
     1033
     1034            sage: t = TermOrder('negwdeglex',(3,2)) 
     1035            sage: P.<x,y> = PolynomialRing(QQbar, 2, order=t)
     1036            sage: x > y^2 # indirect doctest
     1037            True
     1038            sage: x^2 > y^3
     1039            True
     1040        """
     1041        sf = sum(l*r for (l,r) in zip(f,self.__weights))
     1042        sg = sum(l*r for (l,r) in zip(g,self.__weights)) 
     1043        if sf > sg:
     1044            return -1
     1045        elif sf < sg:
     1046            return 1
     1047        elif sf == sg:
     1048            return self.compare_tuples_lex(f,g) 
     1049 
     1050    def compare_tuples_negwdegrevlex(self,f,g):
     1051        """
     1052        Compares two exponent tuples with respect to the negative weighted
     1053        degree reverse lexicographical term order.
     1054       
     1055        INPUT:
     1056       
     1057        - ``f`` - exponent tuple
     1058       
     1059        - ``g`` - exponent tuple
     1060       
     1061        EXAMPLE::
     1062 
     1063             sage: t = TermOrder('negwdegrevlex',(3,2))   
     1064            sage: P.<x,y> = PolynomialRing(QQbar, 2, order=t)
     1065            sage: x > y^2 # indirect doctest
     1066            True
     1067            sage: x^2 > y^3
     1068            True
     1069        """
     1070        sf = sum(l*r for (l,r) in zip(f,self.__weights))
     1071        sg = sum(l*r for (l,r) in zip(g,self.__weights))   
     1072        if sf > sg:
     1073            return -1
     1074        elif sf < sg:
     1075            return 1
     1076        elif sf == sg:
     1077            return (-1)*self.compare_tuples_lex(f.reversed(),g.reversed())
    7881078
    7891079    def compare_tuples_block(self, f,g):
    7901080        """
    791         Compares two exponent tuples with respect to the block ordering as
     1081        Compares two exponent tuples with respect to the block order as
    7921082        specified when constructing this element.
    7931083       
    7941084        INPUT:
     
    8061096            True
    8071097        """
    8081098        n = 0
    809         for order in self:
    810             r = getattr(self,"compare_tuples_"+order.singular_str())(f[n:n+len(order)],g[n:n+len(order)])
     1099        for block in self:
     1100            r = getattr(block,"compare_tuples_" + block.name())(f[n:n+len(block)],g[n:n+len(block)])
    8111101            if r != 0:
    8121102                return r
    813             n += len(order)
     1103            n += len(block)
    8141104        return 0
    8151105
    8161106    def greater_tuple_matrix(self,f,g):
     
    8331123            False
    8341124        """
    8351125        for row in self.__matrix:
    836             mf = sum(l*r for (l,r) in zip(row,f))
    837             mg = sum(l*r for (l,r) in zip(row,g))
     1126            sf = sum(l*r for (l,r) in zip(row,f))
     1127            sg = sum(l*r for (l,r) in zip(row,g))
    8381128       
    839             if mf>mg:
     1129            if sf > sg:
    8401130                return f
    841             elif mf<mg:
     1131            elif sf < sg:
    8421132                return g
    8431133        return g   
    8441134
    845     def greater_tuple_lp(self,f,g):
     1135    def greater_tuple_lex(self,f,g):
    8461136        """
    847         Returns the greater exponent tuple with respect to the
     1137        Return the greater exponent tuple with respect to the
    8481138        lexicographical term order.
    8491139       
    8501140        INPUT:
     
    8641154        """
    8651155        return f > g and f or g
    8661156
    867     def greater_tuple_rp(self,f,g):
     1157    def greater_tuple_invlex(self,f,g):
    8681158        """
    869         Returns the greater exponent tuple with respect to the inversed
     1159        Return the greater exponent tuple with respect to the inversed
    8701160        lexicographical term order.
    8711161       
    8721162        INPUT:
     
    8861176        This method is called by the lm/lc/lt methods of
    8871177        ``MPolynomial_polydict``.
    8881178        """
    889         return f.reversed() > g.reversed()   and f or g
     1179        return f.reversed() > g.reversed() and f or g
    8901180       
    891     def greater_tuple_Dp(self,f,g):
     1181    def greater_tuple_deglex(self,f,g):
    8921182        """
    893         Returns the greater exponent tuple with respect to the total degree
     1183        Return the greater exponent tuple with respect to the total degree
    8941184        lexicographical term order.
    8951185       
    8961186        INPUT:
     
    9101200        This method is called by the lm/lc/lt methods of
    9111201        ``MPolynomial_polydict``.
    9121202        """
    913         return (sum(f.nonzero_values(sort=False))>sum(g.nonzero_values(sort=False))
    914                 or (sum(f.nonzero_values(sort=False))==sum(g.nonzero_values(sort=False)) and f  > g )) and f or g
     1203        sf = sum(f.nonzero_values(sort=False))
     1204        sg = sum(g.nonzero_values(sort=False))
     1205        return ( sf > sg or ( sf == sg and f  > g )) and f or g
    9151206   
    916     def greater_tuple_dp(self,f,g):
     1207    def greater_tuple_degrevlex(self,f,g):
    9171208        """
    918         Returns the greater exponent tuple with respect to the total degree
     1209        Return the greater exponent tuple with respect to the total degree
    9191210        reversed lexicographical term order.
    9201211       
    9211212        INPUT:
     
    9351226        This method is called by the lm/lc/lt methods of
    9361227        ``MPolynomial_polydict``.
    9371228        """
    938         return (sum(f.nonzero_values(sort=False))>sum(g.nonzero_values(sort=False))
    939                 or (sum(f.nonzero_values(sort=False))==sum(g.nonzero_values(sort=False))
    940                     and f.reversed() < g.reversed())) and f or g
     1229        sf = sum(f.nonzero_values(sort=False))
     1230        sg = sum(g.nonzero_values(sort=False))
     1231        return ( sf > sg or ( sf == sg and f.reversed() < g.reversed() )) and f or g         
    9411232   
    942     def greater_tuple_ds(self,f,g):
     1233    def greater_tuple_negdegrevlex(self,f,g):
    9431234        """
    944         Returns the greater exponent tuple with respect to the negative
     1235        Return the greater exponent tuple with respect to the negative
    9451236        degree reverse lexicographical term order.
    9461237       
    9471238        INPUT:
     
    9631254        This method is called by the lm/lc/lt methods of
    9641255        ``MPolynomial_polydict``.
    9651256        """
    966         if self.compare_tuples_ds(f,g) >= 0:
    967             return f
    968         else:
    969             return g
     1257        sf = sum(f.nonzero_values(sort=False))
     1258        sg = sum(g.nonzero_values(sort=False))
     1259        return ( sf < sg or ( sf == sg and f.reversed() < g.reversed() )) and f or g
    9701260
    971     def greater_tuple_Ds(self,f,g):
     1261    def greater_tuple_negdeglex(self,f,g):
    9721262        """
    973         Returns the greater exponent tuple with respect to the negative
     1263        Return the greater exponent tuple with respect to the negative
    9741264        degree lexicographical term order.
    9751265       
    9761266        INPUT:
     
    9921282        This method is called by the lm/lc/lt methods of
    9931283        ``MPolynomial_polydict``.
    9941284        """
    995         if self.compare_tuples_Ds(f,g) >= 0:
    996             return f
    997         else:
    998             return g
     1285        sf = sum(f.nonzero_values(sort=False))
     1286        sg = sum(g.nonzero_values(sort=False))
     1287        return ( sf < sg or ( sf == sg and f  > g )) and f or g   
    9991288
    1000     def greater_tuple_ls(self,f,g):
     1289    def greater_tuple_neglex(self,f,g):
    10011290        """
    1002         Returns the greater exponent tuple with respect to the negative
     1291        Return the greater exponent tuple with respect to the negative
    10031292        lexicographical term order.
    10041293       
    10051294        This method is called by the lm/lc/lt methods of
     
    10191308            sage: g = a + e^4; g.lm()
    10201309            a
    10211310        """
    1022         if self.greater_tuple_lp(f,g) is f:
    1023             return g
    1024         else:
    1025             return f
     1311        return (f < g) and f or g
    10261312
     1313    def greater_tuple_wdeglex(self,f,g):
     1314        """
     1315        Return the greater exponent tuple with respect to the weighted degree
     1316        lexicographical term order.
     1317       
     1318        INPUT:
     1319       
     1320        - ``f`` - exponent tuple
     1321       
     1322        - ``g`` - exponent tuple
     1323       
     1324        EXAMPLE::
     1325
     1326            sage: t = TermOrder('wdeglex',(1,2,3))
     1327            sage: P.<x,y,z> = PolynomialRing(QQbar, 3, order=t)
     1328            sage: f = x + y; f.lm() # indirect doctest
     1329            y
     1330            sage: f = x*y + z; f.lm()
     1331            x*y
     1332       
     1333        This method is called by the lm/lc/lt methods of
     1334        ``MPolynomial_polydict``.
     1335        """
     1336        sf = sum(l*r for (l,r) in zip(f,self.__weights))
     1337        sg = sum(l*r for (l,r) in zip(g,self.__weights))         
     1338        return (sf > sg or ( sf == sg and f  > g )) and f or g   
     1339 
     1340    def greater_tuple_wdegrevlex(self,f,g):
     1341        """
     1342        Return the greater exponent tuple with respect to the weighted degree
     1343        reverse lexicographical term order.
     1344       
     1345        INPUT:
     1346       
     1347        - ``f`` - exponent tuple
     1348       
     1349        - ``g`` - exponent tuple
     1350       
     1351        EXAMPLES::
     1352       
     1353            sage: t = TermOrder('wdegrevlex',(1,2,3))
     1354            sage: P.<x,y,z> = PolynomialRing(QQbar, 3, order=t)
     1355            sage: f = x + y; f.lm() # indirect doctest
     1356            y
     1357            sage: f = x + y^2*z; f.lm()
     1358            y^2*z
     1359       
     1360        This method is called by the lm/lc/lt methods of
     1361        ``MPolynomial_polydict``.
     1362        """
     1363        sf = sum(l*r for (l,r) in zip(f,self.__weights))
     1364        sg = sum(l*r for (l,r) in zip(g,self.__weights))         
     1365        return (sf > sg or ( sf == sg and f.reversed() < g.reversed())) and f or g 
     1366
     1367    def greater_tuple_negwdeglex(self,f,g):
     1368        """
     1369        Return the greater exponent tuple with respect to the negative
     1370        weighted degree lexicographical term order.
     1371       
     1372        INPUT:
     1373       
     1374        - ``f`` - exponent tuple
     1375       
     1376        - ``g`` - exponent tuple
     1377       
     1378        EXAMPLE::
     1379       
     1380            sage: t = TermOrder('negwdeglex',(1,2,3))
     1381            sage: P.<x,y,z> = PolynomialRing(QQbar, 3, order=t) 
     1382            sage: f = x + y; f.lm() # indirect doctest
     1383            x
     1384            sage: f = x + x^2; f.lm()
     1385            x
     1386            sage: f = x^3 + z; f.lm()
     1387            x^3
     1388       
     1389        This method is called by the lm/lc/lt methods of
     1390        ``MPolynomial_polydict``.
     1391        """
     1392        sf = sum(l*r for (l,r) in zip(f,self.__weights))
     1393        sg = sum(l*r for (l,r) in zip(g,self.__weights)) 
     1394        return (sf < sg or ( sf == sg and f  > g )) and f or g 
     1395
     1396    def greater_tuple_negwdegrevlex(self,f,g):
     1397        """
     1398        Return the greater exponent tuple with respect to the negative
     1399        weighted degree reverse lexicographical term order.
     1400       
     1401        INPUT:
     1402       
     1403        - ``f`` - exponent tuple
     1404       
     1405        - ``g`` - exponent tuple
     1406       
     1407        EXAMPLE::
     1408       
     1409            sage: t = TermOrder('negwdegrevlex',(1,2,3))
     1410            sage: P.<x,y,z> = PolynomialRing(QQbar, 3, order=t)
     1411            sage: f = x + y; f.lm() # indirect doctest
     1412            x
     1413            sage: f = x + x^2; f.lm()
     1414            x
     1415            sage: f = x^3 + z; f.lm() 
     1416            x^3
     1417       
     1418        This method is called by the lm/lc/lt methods of
     1419        ``MPolynomial_polydict``.
     1420        """
     1421        sf = sum(l*r for (l,r) in zip(f,self.__weights))
     1422        sg = sum(l*r for (l,r) in zip(g,self.__weights)) 
     1423        return (sf < sg or ( sf == sg and f.reversed() < g.reversed() )) and f or g   
     1424       
    10271425    def greater_tuple_block(self, f,g):
    10281426        """
    1029         Returns the greater exponent tuple with respect to the block
    1030         ordering as specified when constructing this element.
     1427        Return the greater exponent tuple with respect to the block
     1428        order as specified when constructing this element.
    10311429       
    10321430        This method is called by the lm/lc/lt methods of
    10331431        ``MPolynomial_polydict``.
     
    10471445            a
    10481446        """
    10491447        n = 0
    1050         for order in self:
    1051             r = getattr(self,"compare_tuples_"+order.singular_str())(f[n:n+len(order)],g[n:n+len(order)])
     1448        for block in self:
     1449            r = getattr(block,"compare_tuples_" + block.name())(f[n:n+len(block)],g[n:n+len(block)])
    10521450            if r != 0:
    10531451                if r < 0:
    10541452                    return g
    10551453                else:
    10561454                    return f
    1057             n += len(order)
     1455            n += len(block)
    10581456        return f
    10591457
     1458    def tuple_weight(self, f):
     1459        """
     1460        Return the weight of tuple f.
     1461
     1462        INPUT:
     1463       
     1464        - ``f`` - exponent tuple 
     1465
     1466        EXAMPLE::   
     1467
     1468            sage: t=TermOrder('wdeglex',(1,2,3))
     1469            sage: P.<a,b,c>=PolynomialRing(QQbar, order=t)
     1470            sage: P.term_order().tuple_weight([3,2,1])
     1471            10
     1472        """
     1473        return sum(l*r for (l,r) in zip(f,self.__weights))
     1474
    10601475    def name(self):
    10611476        """
    10621477        EXAMPLE::
     
    10731488            sage: TermOrder('lex') # indirect doctest
    10741489            Lexicographic term order
    10751490        """
    1076         if self.__name[0] == 'M':
    1077             return 'Matrix term order with matrix\n%s'%self.matrix()
     1491        if self.__name == 'matrix':
     1492            return 'Matrix term order with matrix\n%s'%(self.__matrix,)
     1493        elif self.__name == 'block':
     1494            s = []
     1495            for t in self.__blocks:
     1496                if not t.is_weighted_degree_order():
     1497                    s.append('%s of length %d'%(t,len(t)))
     1498                else: # includes matrix order
     1499                    s.append('%s'%(t,))
     1500            return 'Block term order with blocks:\n(%s)'%(',\n '.join(s),)
    10781501        else:
    1079             s = print_name_mapping.get(self.__name,self.__name)
    1080             return '%s term order'%s
     1502            s = print_name_mapping.get(self.__name,self.__name) + ' term order'
     1503            if self.is_weighted_degree_order():
     1504                s = s + ' with weights %s'%(self.__weights,)
     1505            return s
    10811506
    10821507    def singular_str(self):
    10831508        """
     
    11161541            sage: P = PolynomialRing(GF(127), 8,names='x',order='degrevlex(3),lex(5)')
    11171542            sage: T = P.term_order()
    11181543            sage: T.macaulay2_str()
    1119             '(GRevLex => 3,Lex => 5)'
     1544            '{GRevLex => 3,Lex => 5}'
    11201545            sage: P._macaulay2_() # optional - macaulay2
    11211546            ZZ/127 [x0, x1, x2, x3, x4, x5, x6, x7, MonomialOrder => {GRevLex => 3, Lex => 5}, MonomialSize => 16]
    11221547        """
     
    11441569        """
    11451570        return self.__magma_str
    11461571
     1572    def blocks(self):
     1573        """
     1574        Return the term order blocks of self.
     1575
     1576        EXAMPLE::
     1577
     1578            sage: t=TermOrder('deglex',2)+TermOrder('lex',2)
     1579            sage: t.blocks()
     1580            (Degree lexicographic term order, Lexicographic term order)
     1581        """
     1582        if self.__blocks: # self is a block order
     1583            return self.__blocks
     1584        else:
     1585            return [self]
     1586
    11471587    def matrix(self):   
    11481588        """
    1149         Return the matrix defining matrix ordering.
     1589        Return the matrix defining matrix term order.
    11501590
    11511591        EXAMPLE::
    11521592
     
    11561596            [0 1]
    11571597           
    11581598        """
    1159         from sage.matrix.constructor import matrix
    1160         return matrix(self.__matrix)
     1599        return self.__matrix
    11611600
    1162     def __cmp__(self, other):
     1601    def weights(self):
    11631602        """
    1164         Only equality testing makes sense here.
    1165        
     1603        Return the weights for weighted term orders.
     1604
     1605        EXAMPLE::
     1606
     1607            sage: t=TermOrder('wdeglex',(2,3))
     1608            sage: t.weights()
     1609            (2, 3)
     1610        """           
     1611        return self.__weights
     1612
     1613    def __eq__(self, other):
     1614        """
     1615        Return true if self and other are equal.
     1616
    11661617        EXAMPLE::
    11671618       
    11681619            sage: TermOrder('lex') == TermOrder('lex',3)
     
    11781629            sage: T1 = TermOrder('lex',2)+TermOrder('lex',3)
    11791630            sage: T2 = TermOrder('lex',3)+TermOrder('lex',2)
    11801631            sage: T1 == T2
    1181             False
     1632            True
    11821633       
    11831634        ::
    11841635       
     
    11881639            True
    11891640        """
    11901641        if not isinstance(other, TermOrder):
    1191             if isinstance(other, str):
     1642            try:
    11921643                other = TermOrder(other, force=True)
    1193             else:
    1194                 return cmp(type(self), type(other))
    1195         return cmp(self.singular_str(), other.singular_str())
     1644            except:
     1645                return False
     1646
     1647        return (self.__name == other.__name       # note that length is not considered.
     1648            and self.__blocks == other.__blocks
     1649            and self.__weights == other.__weights
     1650            and self.__matrix == other.__matrix)
     1651
     1652    def __ne__(self, other):
     1653        """
     1654        Return true if self and other are not equal.
     1655
     1656        EXAMPLE::
     1657       
     1658            sage: T1 = TermOrder('lex',2)+TermOrder('lex',3)
     1659            sage: T2 = TermOrder('lex',3)+TermOrder('lex',2)
     1660            sage: T1 != T2
     1661            False 
     1662        """
     1663        return not self.__eq__(other)
    11961664
    11971665    def __add__(self, other):
    11981666        """
    1199         Block ordering constructor.
     1667        Construct a block order combining self and other.
    12001668       
    12011669        INPUT:
    12021670       
    12031671        - ``other`` - a term order
    12041672       
    1205         OUTPUT: a block ordering
     1673        OUTPUT: a block order
    12061674       
    12071675        EXAMPLE::
    12081676       
    12091677            sage: from sage.rings.polynomial.term_order import TermOrder
    12101678            sage: TermOrder('deglex',2) + TermOrder('degrevlex(3),neglex(3)')
    1211             deglex(2),degrevlex(3),neglex(3) term order
    1212         """
    1213         if other is None:
     1679            Block term order with blocks:
     1680            (Degree lexicographic term order of length 2,
     1681             Degree reverse lexicographic term order of length 3,
     1682             Negative lexicographic term order of length 3)
     1683        """   
     1684        if isinstance(other, TermOrder):
     1685            return TermOrder('block',[self,other])
     1686        else:
    12141687            return self
    1215        
    1216         if not isinstance(other,TermOrder):
    1217             other = TermOrder(other, force = self.__force)
    1218         if len(self) == 0 or len(other) == 0:
    1219             raise ArithmeticError, "Can only concatenate term orders with length attribute."
    1220 
    1221         name = []
    1222         for block_order in self.blocks + other.blocks:
    1223             if 'M' in block_order.singular_str():
    1224                 raise NotImplementedError, "Cannot use a matrix term order as a block."
    1225             nom = block_order.singular_str()
    1226             name.append("%s(%d)"%(inv_singular_name_mapping.get(nom,nom), len(block_order)))
    1227 
    1228         name = ",".join(name)
    1229         return TermOrder(name, len(self)+len(other), force=self.__force)
    12301688
    12311689    def __len__(self):
    12321690        """
    1233         Return the length of this term ordering, i.e. the number of
     1691        Return the length of this term order, i.e. the number of
    12341692        variables it covers. This may be zero for indefinitely many
    12351693        variables.
    12361694       
     
    12471705
    12481706    def __getitem__(self, i):
    12491707        r"""
    1250         Return the i-th block of this term ordering.
     1708        Return the i-th block of this term order.
    12511709       
    12521710        INPUT:
    12531711       
     
    12731731            sage: T = TermOrder('lex', 2) + TermOrder('degrevlex', 3)
    12741732            sage: T[len(T)-1]
    12751733            Traceback (most recent call last):
    1276             ...
     1734            \dots
    12771735            IndexError: tuple index out of range
    12781736        """
    1279         return self.blocks[i]
     1737        return self.blocks()[i]
    12801738
    12811739    def __iter__(self):
    12821740        r"""
    1283         Iterate over the blocks of this term ordering.
     1741        Iterate over the blocks of this term order.
    12841742       
    12851743        EXAMPLE::
    12861744       
     
    12991757        the number of variables in ``self`` while the latter
    13001758        counts the number of blocks.
    13011759        """
    1302         return iter(self.blocks)
     1760        return iter(self.blocks())
    13031761
    13041762    def is_global(self):
    13051763        r"""
    1306         Return ``True`` if this term ordering is definitely
    1307         global. Return ``False`` otherwise, which includes
    1308         unknown term orderings.
     1764        Return true if this term order is definitely
     1765        global. Return false otherwise, which includes
     1766        unknown term orders.
    13091767       
    13101768        EXAMPLE::
    13111769       
     
    13191777            sage: T.is_global()
    13201778            False
    13211779        """
    1322         if len(self.blocks) == 1:
    1323             if self.singular_str() in ('lp','dp','Dp'):
    1324                 return True
    1325             else:
    1326                 return False
     1780        if self.name() in ('lex','degrevlex','deglex','wdegrevlex','wdeglex'):
     1781            return True
     1782        elif self.name() is 'block':
     1783            return all([t.is_global() for t in self.blocks()])
    13271784        else:
    1328             return all([t.is_global() for t in self.blocks])
    1329            
     1785            return False
     1786
    13301787    def is_local(self):
    13311788        r"""
    1332         Return ``True`` if this term ordering is definitely
    1333         local. Return ``False`` otherwise, which includes
    1334         unknown term orderings.
     1789        Return true if this term order is definitely
     1790        local. Return false otherwise, which includes
     1791        unknown term orders.
    13351792       
    13361793        EXAMPLE::
    13371794       
     
    13451802            sage: T.is_local()
    13461803            False
    13471804        """
    1348         if len(self.blocks) == 1:
    1349             if self.singular_str() in ('rp', 'ls','ds','Ds'):
    1350                 return True
    1351             else:
    1352                 return False
     1805        if (self.name() in ('neglex','negdegrevlex','negdeglex','negwdegrevlex','negwdeglex') or
     1806            self.singular_str() in ('ls','ds','Ds','ws','Ws')):
     1807            return True
     1808        elif self.name() is 'block':
     1809            return all([t.is_local() for t in self.blocks()])
    13531810        else:
    1354             return all([t.is_local() for t in self.blocks])
     1811            return False
     1812
     1813    def is_block_order(self):
     1814        """
     1815        Return true if self is a block term order.
     1816
     1817        EXAMPLE::
     1818
     1819            sage: t=TermOrder('deglex',2)+TermOrder('lex',2)
     1820            sage: t.is_block_order()
     1821            True
     1822        """
     1823        return self.__name == 'block'
     1824
     1825    def is_weighted_degree_order(self):
     1826        """
     1827        Return true if self is a weighted degree term order.
     1828
     1829        EXAMPLE::
     1830
     1831            sage: t=TermOrder('wdeglex',(2,3))
     1832            sage: t.is_weighted_degree_order()
     1833            True
     1834        """           
     1835        return self.__weights is not None