Ticket #11316: trac_11316.4.patch

File trac_11316.4.patch, 76.7 KB (added by klee, 11 years ago)

fixed a bug in dealing with the force argument

  • sage/crypto/mq/sr.py

    # HG changeset patch
    # User Kwankyu Lee <ekwankyu@gmail.com>
    # Date 1305014300 -32400
    # Node ID f12eed9c4855ecee9e3ea1ac0987f243500c74c8
    # Parent  ce324e28c3334398d3552640e2cb1520d22465a3
    #11316: added weighted degree term orders
    
    diff -r ce324e28c333 -r f12eed9c4855 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 ce324e28c333 -r f12eed9c4855 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 ce324e28c333 -r f12eed9c4855 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 ce324e28c333 -r f12eed9c4855 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 ce324e28c333 -r f12eed9c4855 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 ce324e28c333 -r f12eed9c4855 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 ce324e28c333 -r f12eed9c4855 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 ce324e28c333 -r f12eed9c4855 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 old pickled TermOrder objects.
     512
     513        See Trac #11316.
     514
     515        EXAMPLE::
     516
     517            sage: t = TermOrder('lex')
     518            sage: t2 = loads(dumps(t))
     519            sage: t2._weights is None
     520            True
     521        """
     522        if not dict.has_key('_weights'):
     523            name = dict['_TermOrder__name']
     524            n = dict['_TermOrder__length']
     525            t = TermOrder(name,n)
     526            self.__dict__.update(t.__dict__)
     527        else:             
     528            self.__dict__.update(dict)
     529
     530    def __init__(self, name='lex', n=0, blocks=True, force=False):
     531        """
     532        Construct a new term order object.
    391533       
    392534        INPUT:
    393535       
    394         - ``name`` - name of the term ordering (default: lex)
     536        - ``name`` - name of the term order (default: lex)
    395537       
    396         - ``n`` - number of variables in the polynomial ring
    397            (default: 0)
     538        - ``n`` - number of variables (default is `0`) or weights for
     539          weighted degree orders
     540
     541        - ``blocks`` - this is deprecated.
    398542       
    399         - ``blocks`` - controls whether a list of blocks is
    400            maintained (internal use only, default:True)
    401 
    402         - ``force`` - ignore unknown term orderings.
     543        - ``force`` - ignore unknown term orders.
    403544       
    404545        See the ``sage.rings.polynomial.term_order`` module
    405         for help which names and orderings are available.
     546        for help which names and orders are available.
    406547       
    407548        EXAMPLES::
    408549       
     
    412553            sage: loads(dumps(t)) == t
    413554            True
    414555       
    415         We can construct block orderings directly as
     556        We can construct block orders directly as
    416557       
    417558        ::
    418559       
    419560            sage: TermOrder('degrevlex(3),neglex(2)')
    420             degrevlex(3),neglex(2) term order
     561            Block term order with blocks:
     562            (Degree reverse lexicographic term order of length 3,
     563             Negative lexicographic term order of length 2)
    421564       
    422565        or by adding together the blocks::
    423566       
    424567            sage: t1 = TermOrder('degrevlex',3)
    425568            sage: t2 = TermOrder('neglex',2)
    426569            sage: t1 + t2
    427             degrevlex(3),neglex(2) term order
    428             sage: t2 + t1
    429             neglex(2),degrevlex(3) term order
     570            Block term order with blocks:
     571            (Degree reverse lexicographic term order of length 3,
     572             Negative lexicographic term order of length 2)
     573            sage: t3 = TermOrder('wdeglex',(1,2))
     574            sage: t1 + t3
     575            Block term order with blocks:
     576            (Degree reverse lexicographic term order of length 3,
     577             Weighted degree lexicographic term order with weights (1, 2))
    430578       
    431579        .. note::
    432580
    433581           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
     582           non-block orders like `deglex` are
     583           constructed. However, it is useful if block orders are
    436584           to be constructed from this ``TermOrder`` object later.
    437         """
     585        """ 
    438586        if isinstance(name, TermOrder):
    439             if n == 0 and len(name) > 0:
    440                 n = len(name)
     587            self.__copy(name)
     588            if n > 0 and not name.is_block_order() and not name.is_weighted_degree_order():
     589                self._length = n
     590            return 
     591
     592        if isinstance(name, str): 
     593            name = name.lower()
     594        else:
    441595            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()])+')'
     596                if not isinstance(name, (tuple,list)):
     597                    name = name.list() # name may be a matrix
     598                name = tuple(name)
    449599            except:
    450                 pass
    451         name = name.lower()
     600                raise TypeError, "%s is not a valid term order"%(name,)
    452601
    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)
     602        self._blocks = tuple()
     603        self._weights = None
     604        self._matrix = None
    466605
    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
     606        if name == "block": # block term order with blocks in a list
    515607            length = 0
    516608            blocks = []
    517609            name_str = []
    518610            singular_str = []
    519611            macaulay2_str = []
    520612
    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,)
     613            for t in n:
     614                if not isinstance(t, TermOrder):
     615                    try:
     616                        t = TermOrder(t,force=True)
     617                    except:
     618                        raise TypeError
     619                if t.name() == 'block':
     620                    blocks = blocks + list(t.blocks())
     621                    singular_str.append("%s"%(t.singular_str()[1:-1],))  # [1:-1] is needed to remove parenthesis
     622                    macaulay2_str.append("%s"%(t.macaulay2_str()[1:-1],)) 
     623                else:
     624                    if len(t) == 0:
     625                        raise ArithmeticError, "Can only concatenate term orders with length attribute."   
     626                    blocks.append(t)
     627                    if t.is_weighted_degree_order(): # true if t is a matrix order as well
     628                        singular_str.append("%s"%(t.singular_str(),))
     629                    else:
     630                        singular_str.append("%s(%d)"%(t.singular_str(), len(t)))                                           
     631                    macaulay2_str.append("%s => %d"%(t.macaulay2_str(), len(t)))
     632                length += len(t)
    526633
    527                 block_length = int(block_length)
     634            self._length = length
     635            self._name = "block"
     636            self._singular_str = "(" + ",".join(singular_str) + ")"
     637            self._macaulay2_str = "{" + ",".join(macaulay2_str) + "}"
     638            self._magma_str = "" # Magma does not support block order
     639            self._blocks = tuple(blocks)
     640        elif isinstance(name, str) and not (isinstance(n, tuple) or isinstance(n,list)): # string representation of simple or block orders
     641            if force:
     642                self._length = n
     643                self._name = name
     644                self._singular_str = singular_name_mapping.get(name,name)
     645                self._macaulay2_str = macaulay2_name_mapping.get(name,name)
     646                self._magma_str = magma_name_mapping.get(name,name) 
     647            else:
     648                split_pattern = "([^(),]+(?:\([^()]*\)[^(),]*)*)" # split by outermost commas         
     649                block_names = re.findall(split_pattern,name)
    528650
    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))
     651                if len(block_names) == 0:
     652                    raise TypeError, "No term order specified"
     653                elif len(block_names) == 1:
     654                    name = block_names[0]
     655                    match = re.match('m\(([-+0-9,]+)\)$',name)
     656                    if match: # matrix term order
     657                        m = map(int,match.groups()[0].split(',')) # replace match.groups()[0]  with match.group(1) later
     658                        self.__copy(TermOrder(m))
     659                    else: # simple order
     660                        if name not in print_name_mapping.keys() and name not in singular_name_mapping.values():
     661                            raise TypeError, "Unknown term order '%s'"%(name,)
     662                        self._length = n
     663                        self._name = name
     664                        self._singular_str = singular_name_mapping.get(name,name)
     665                        self._macaulay2_str = macaulay2_name_mapping.get(name,name)
     666                        self._magma_str = magma_name_mapping.get(name,name)               
     667                else: # len(block_names) > 1, and hence block order represented by a string
     668                    length = 0
     669                    blocks = []
     670                    name_str = []
     671                    singular_str = []
     672                    macaulay2_str = []
    533673
    534                 length += block_length
     674                    for block in block_names:
     675                        try:
     676                            length_pattern  = re.compile("\(([0-9]+)\)$") # match with parenthesized block length at end                 
     677                            block_name, block_length, _ = re.split(length_pattern,block)
     678                            block_length = int(block_length)
     679                            blocks.append( TermOrder(block_name,block_length,force=force) )
     680                        except:
     681                            raise TypeError, "%s is not a valid term order"%(name,)
     682                        length += block_length
    535683
    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
     684                    if n != 0 and length != n:
     685                        raise TypeError, "Term order length does not match the number of generators"
     686                    self.__copy(TermOrder('block', blocks))
     687        elif isinstance(name, str) and (isinstance(n, tuple) or isinstance(n,list)): # weighted degree term orders
     688            if name not in print_name_mapping.keys() and name not in singular_name_mapping.values() and not force:
     689                raise TypeError, "Unknown term order '%s'"%(name,) 
     690            weights = tuple(n) # n is a tuple of weights
     691           
     692            self._length = len(weights)
     693            self._name = name
     694            self._singular_str = singular_name_mapping.get(name,name) + '(' + ','.join([str(w) for w in weights]) + ')'
     695            self._macaulay2_str = ""
     696            self._magma_str = ""
     697            self._weights = weights # defined only for weighted degree orders                   
     698        elif isinstance(name, tuple): # name represents a matrix 
     699            if n == 0:
     700                from math import sqrt
     701                n = int(sqrt(len(name)))                   
     702            if n**2 != len(name):
     703                raise TypeError, "%s does not specify a square matrix"%(name,)   
    542704
    543             if n != 0 and self.__length != n:
    544                 raise TypeError, "Term order length does not match the number of generators"
     705            int_str = ','.join([str(int(e)) for e in name])
     706
     707            self._length = n
     708            self._name = "matrix"
     709            self._singular_str = "M(%s)"%(int_str,)
     710            self._macaulay2_str = "" # Macaulay2 does not support matrix term order directly
     711            self._magma_str = '"weight",[%s]'%(int_str,)
     712
     713            from sage.matrix.constructor import matrix   
     714            self._matrix = matrix(n,name)  # defined only for matrix term order
     715            self._weights = name[:n] # the first row of the matrix gives weights
     716        else:
     717            raise TypeError, "%s is not a valid term order"%(name,)   
     718
     719        self.__doc__ = description_mapping.get(self._name, "No description available")                 
     720
     721    def __copy(self, other):
     722        """
     723        Copy other term order to self.
     724
     725        EXAMPLE::
     726       
     727            sage: t = TermOrder('lex')
     728            sage: s = TermOrder(t)
     729            sage: t == s            # indirect test
     730            True
     731        """
     732        self.__dict__ = other.__dict__.copy()
    545733
    546734    def __getattr__(self,name):
    547735        """
     
    550738        EXAMPLE::
    551739       
    552740            sage: TermOrder('lex').compare_tuples
    553             <bound method TermOrder.compare_tuples_lp of Lexicographic term order>
     741            <bound method TermOrder.compare_tuples_lex of Lexicographic term order>
    554742       
    555743        ::
    556744       
    557745            sage: TermOrder('deglex').compare_tuples
    558             <bound method TermOrder.compare_tuples_Dp of Degree lexicographic term order>
     746            <bound method TermOrder.compare_tuples_deglex of Degree lexicographic term order>
    559747        """
    560748        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
     749            return getattr(self,'compare_tuples_'+self._name)
    568750        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
     751            return getattr(self,'greater_tuple_'+self._name)
    576752        else:
    577753            raise AttributeError,name
    578754
     
    595771            sage: y > x^3
    596772            False
    597773        """
    598         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        for row in self._matrix:
     775            sf = sum(l*r for (l,r) in zip(row,f))
     776            sg = sum(l*r for (l,r) in zip(row,g))
    601777       
    602             if mf > mg:
     778            if sf > sg:
    603779                return 1
    604             elif mf < mg:
     780            elif sf < sg:
    605781                return -1
    606782        return 0 
    607783
    608     def compare_tuples_lp(self,f,g):
     784    def compare_tuples_lex(self,f,g):
    609785        """
    610786        Compares two exponent tuples with respect to the lexicographical
    611787        term order.
     
    624800            sage: x > 1
    625801            True
    626802        """
    627 
    628         if f>g:
     803        if f > g:
    629804            return 1
    630         elif f<g:
     805        elif f < g:
    631806            return -1
    632807        else:
    633808            return 0
    634809
    635     def compare_tuples_rp(self,f,g):
     810    def compare_tuples_invlex(self,f,g):
    636811        """
    637812        Compares two exponent tuples with respect to the inversed
    638813        lexicographical term order.
     
    651826            sage: x > 1
    652827            True
    653828        """
    654         return self.compare_tuples_lp(f.reversed(),g.reversed())
     829        return self.compare_tuples_lex(f.reversed(),g.reversed())
    655830
    656     def compare_tuples_Dp(self,f,g):
     831    def compare_tuples_deglex(self,f,g):
    657832        """
    658833        Compares two exponent tuples with respect to the degree
    659834        lexicographical term order.
     
    676851        sg = sum(g.nonzero_values(sort=False))
    677852        if sf > sg:
    678853            return 1
    679         elif sf<sg:
     854        elif sf < sg:
    680855            return -1
    681856        elif sf == sg:
    682             return self.compare_tuples_lp(f,g)
     857            return self.compare_tuples_lex(f,g)
    683858
    684     def compare_tuples_dp(self,f,g):
     859    def compare_tuples_degrevlex(self,f,g):
    685860        """
    686861        Compares two exponent tuples with respect to the degree reversed
    687862        lexicographical term order.
     
    704879        sg = sum(g.nonzero_values(sort=False))
    705880        if sf > sg:
    706881            return 1
    707         elif sf<sg:
     882        elif sf < sg:
    708883            return -1
    709884        elif sf == sg:
    710             return (-1)*self.compare_tuples_lp(f.reversed(),g.reversed())
     885            return -self.compare_tuples_lex(f.reversed(),g.reversed())
    711886
    712     def compare_tuples_ls(self,f,g):
     887    def compare_tuples_neglex(self,f,g):
    713888        """
    714889        Compares two exponent tuples with respect to the negative
    715890        lexicographical term order.
     
    728903            sage: x > 1
    729904            False
    730905        """
    731         return -self.compare_tuples_lp(f,g)
     906        return -self.compare_tuples_lex(f,g)
    732907
    733     def compare_tuples_ds(self,f,g):
     908    def compare_tuples_negdegrevlex(self,f,g):
    734909        """
    735910        Compares two exponent tuples with respect to the negative degree
    736911        reverse lexicographical term order.
     
    753928        sg = sum(g.nonzero_values(sort=False))
    754929        if sf > sg:
    755930            return -1
    756         elif sf<sg:
     931        elif sf < sg:
    757932            return 1
    758933        elif sf == sg:
    759             return (-1)*self.compare_tuples_lp(f.reversed(),g.reversed())
     934            return (-1)*self.compare_tuples_lex(f.reversed(),g.reversed())
    760935
    761     def compare_tuples_Ds(self,f,g):
     936    def compare_tuples_negdeglex(self,f,g):
    762937        """
    763938        Compares two exponent tuples with respect to the negative degree
    764939        lexicographical term order.
     
    781956        sg = sum(g.nonzero_values(sort=False))
    782957        if sf > sg:
    783958            return -1
    784         elif sf<sg:
     959        elif sf < sg:
    785960            return 1
    786961        elif sf == sg:
    787             return self.compare_tuples_lp(f,g)
     962            return self.compare_tuples_lex(f,g)
     963
     964    def compare_tuples_wdegrevlex(self,f,g):
     965        """
     966        Compares two exponent tuples with respect to the weighted degree reverse
     967        lexicographical term order.
     968       
     969        INPUT:
     970       
     971        - ``f`` - exponent tuple
     972       
     973        - ``g`` - exponent tuple
     974       
     975        EXAMPLE::
     976 
     977            sage: t = TermOrder('wdegrevlex',(3,2)) 
     978            sage: P.<x,y> = PolynomialRing(QQbar, 2, order=t)
     979            sage: x > y^2 # indirect doctest
     980            False
     981            sage: x^2 > y^3
     982            True
     983        """
     984        sf = sum(l*r for (l,r) in zip(f,self._weights))
     985        sg = sum(l*r for (l,r) in zip(g,self._weights)) 
     986        if sf > sg:
     987            return 1
     988        elif sf < sg:
     989            return -1
     990        elif sf == sg:
     991            return -self.compare_tuples_lex(f.reversed(),g.reversed()) 
     992
     993    def compare_tuples_wdeglex(self,f,g):
     994        """
     995        Compares two exponent tuples with respect to the weighted degree
     996        lexicographical term order.
     997       
     998        INPUT:
     999       
     1000        - ``f`` - exponent tuple
     1001       
     1002        - ``g`` - exponent tuple
     1003       
     1004        EXAMPLE::
     1005       
     1006            sage: t = TermOrder('wdeglex',(3,2))
     1007            sage: P.<x,y> = PolynomialRing(QQbar, 2, order=t)
     1008            sage: x > y^2 # indirect doctest
     1009            False
     1010            sage: x > y
     1011            True
     1012        """
     1013        sf = sum(l*r for (l,r) in zip(f,self._weights))
     1014        sg = sum(l*r for (l,r) in zip(g,self._weights)) 
     1015        if sf > sg:
     1016            return 1
     1017        elif sf < sg:
     1018            return -1
     1019        elif sf == sg:
     1020            return self.compare_tuples_lex(f,g)   
     1021
     1022    def compare_tuples_negwdeglex(self,f,g):
     1023        """
     1024        Compares two exponent tuples with respect to the negative weighted
     1025        degree lexicographical term order.
     1026       
     1027        INPUT:
     1028       
     1029        - ``f`` - exponent tuple
     1030       
     1031        - ``g`` - exponent tuple
     1032       
     1033        EXAMPLE::
     1034
     1035            sage: t = TermOrder('negwdeglex',(3,2)) 
     1036            sage: P.<x,y> = PolynomialRing(QQbar, 2, order=t)
     1037            sage: x > y^2 # indirect doctest
     1038            True
     1039            sage: x^2 > y^3
     1040            True
     1041        """
     1042        sf = sum(l*r for (l,r) in zip(f,self._weights))
     1043        sg = sum(l*r for (l,r) in zip(g,self._weights)) 
     1044        if sf > sg:
     1045            return -1
     1046        elif sf < sg:
     1047            return 1
     1048        elif sf == sg:
     1049            return self.compare_tuples_lex(f,g) 
     1050 
     1051    def compare_tuples_negwdegrevlex(self,f,g):
     1052        """
     1053        Compares two exponent tuples with respect to the negative weighted
     1054        degree reverse lexicographical term order.
     1055       
     1056        INPUT:
     1057       
     1058        - ``f`` - exponent tuple
     1059       
     1060        - ``g`` - exponent tuple
     1061       
     1062        EXAMPLE::
     1063 
     1064             sage: t = TermOrder('negwdegrevlex',(3,2))   
     1065            sage: P.<x,y> = PolynomialRing(QQbar, 2, order=t)
     1066            sage: x > y^2 # indirect doctest
     1067            True
     1068            sage: x^2 > y^3
     1069            True
     1070        """
     1071        sf = sum(l*r for (l,r) in zip(f,self._weights))
     1072        sg = sum(l*r for (l,r) in zip(g,self._weights))   
     1073        if sf > sg:
     1074            return -1
     1075        elif sf < sg:
     1076            return 1
     1077        elif sf == sg:
     1078            return (-1)*self.compare_tuples_lex(f.reversed(),g.reversed())
    7881079
    7891080    def compare_tuples_block(self, f,g):
    7901081        """
    791         Compares two exponent tuples with respect to the block ordering as
     1082        Compares two exponent tuples with respect to the block order as
    7921083        specified when constructing this element.
    7931084       
    7941085        INPUT:
     
    8061097            True
    8071098        """
    8081099        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)])
     1100        for block in self:
     1101            r = getattr(block,"compare_tuples_" + block.name())(f[n:n+len(block)],g[n:n+len(block)])
    8111102            if r != 0:
    8121103                return r
    813             n += len(order)
     1104            n += len(block)
    8141105        return 0
    8151106
    8161107    def greater_tuple_matrix(self,f,g):
     
    8321123            sage: y > x^3
    8331124            False
    8341125        """
    835         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        for row in self._matrix:
     1127            sf = sum(l*r for (l,r) in zip(row,f))
     1128            sg = sum(l*r for (l,r) in zip(row,g))
    8381129       
    839             if mf>mg:
     1130            if sf > sg:
    8401131                return f
    841             elif mf<mg:
     1132            elif sf < sg:
    8421133                return g
    8431134        return g   
    8441135
    845     def greater_tuple_lp(self,f,g):
     1136    def greater_tuple_lex(self,f,g):
    8461137        """
    847         Returns the greater exponent tuple with respect to the
     1138        Return the greater exponent tuple with respect to the
    8481139        lexicographical term order.
    8491140       
    8501141        INPUT:
     
    8641155        """
    8651156        return f > g and f or g
    8661157
    867     def greater_tuple_rp(self,f,g):
     1158    def greater_tuple_invlex(self,f,g):
    8681159        """
    869         Returns the greater exponent tuple with respect to the inversed
     1160        Return the greater exponent tuple with respect to the inversed
    8701161        lexicographical term order.
    8711162       
    8721163        INPUT:
     
    8861177        This method is called by the lm/lc/lt methods of
    8871178        ``MPolynomial_polydict``.
    8881179        """
    889         return f.reversed() > g.reversed()   and f or g
     1180        return f.reversed() > g.reversed() and f or g
    8901181       
    891     def greater_tuple_Dp(self,f,g):
     1182    def greater_tuple_deglex(self,f,g):
    8921183        """
    893         Returns the greater exponent tuple with respect to the total degree
     1184        Return the greater exponent tuple with respect to the total degree
    8941185        lexicographical term order.
    8951186       
    8961187        INPUT:
     
    9101201        This method is called by the lm/lc/lt methods of
    9111202        ``MPolynomial_polydict``.
    9121203        """
    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
     1204        sf = sum(f.nonzero_values(sort=False))
     1205        sg = sum(g.nonzero_values(sort=False))
     1206        return ( sf > sg or ( sf == sg and f  > g )) and f or g
    9151207   
    916     def greater_tuple_dp(self,f,g):
     1208    def greater_tuple_degrevlex(self,f,g):
    9171209        """
    918         Returns the greater exponent tuple with respect to the total degree
     1210        Return the greater exponent tuple with respect to the total degree
    9191211        reversed lexicographical term order.
    9201212       
    9211213        INPUT:
     
    9351227        This method is called by the lm/lc/lt methods of
    9361228        ``MPolynomial_polydict``.
    9371229        """
    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
     1230        sf = sum(f.nonzero_values(sort=False))
     1231        sg = sum(g.nonzero_values(sort=False))
     1232        return ( sf > sg or ( sf == sg and f.reversed() < g.reversed() )) and f or g         
    9411233   
    942     def greater_tuple_ds(self,f,g):
     1234    def greater_tuple_negdegrevlex(self,f,g):
    9431235        """
    944         Returns the greater exponent tuple with respect to the negative
     1236        Return the greater exponent tuple with respect to the negative
    9451237        degree reverse lexicographical term order.
    9461238       
    9471239        INPUT:
     
    9631255        This method is called by the lm/lc/lt methods of
    9641256        ``MPolynomial_polydict``.
    9651257        """
    966         if self.compare_tuples_ds(f,g) >= 0:
    967             return f
    968         else:
    969             return g
     1258        sf = sum(f.nonzero_values(sort=False))
     1259        sg = sum(g.nonzero_values(sort=False))
     1260        return ( sf < sg or ( sf == sg and f.reversed() < g.reversed() )) and f or g
    9701261
    971     def greater_tuple_Ds(self,f,g):
     1262    def greater_tuple_negdeglex(self,f,g):
    9721263        """
    973         Returns the greater exponent tuple with respect to the negative
     1264        Return the greater exponent tuple with respect to the negative
    9741265        degree lexicographical term order.
    9751266       
    9761267        INPUT:
     
    9921283        This method is called by the lm/lc/lt methods of
    9931284        ``MPolynomial_polydict``.
    9941285        """
    995         if self.compare_tuples_Ds(f,g) >= 0:
    996             return f
    997         else:
    998             return g
     1286        sf = sum(f.nonzero_values(sort=False))
     1287        sg = sum(g.nonzero_values(sort=False))
     1288        return ( sf < sg or ( sf == sg and f  > g )) and f or g   
    9991289
    1000     def greater_tuple_ls(self,f,g):
     1290    def greater_tuple_neglex(self,f,g):
    10011291        """
    1002         Returns the greater exponent tuple with respect to the negative
     1292        Return the greater exponent tuple with respect to the negative
    10031293        lexicographical term order.
    10041294       
    10051295        This method is called by the lm/lc/lt methods of
     
    10191309            sage: g = a + e^4; g.lm()
    10201310            a
    10211311        """
    1022         if self.greater_tuple_lp(f,g) is f:
    1023             return g
    1024         else:
    1025             return f
     1312        return (f < g) and f or g
    10261313
     1314    def greater_tuple_wdeglex(self,f,g):
     1315        """
     1316        Return the greater exponent tuple with respect to the weighted degree
     1317        lexicographical term order.
     1318       
     1319        INPUT:
     1320       
     1321        - ``f`` - exponent tuple
     1322       
     1323        - ``g`` - exponent tuple
     1324       
     1325        EXAMPLE::
     1326
     1327            sage: t = TermOrder('wdeglex',(1,2,3))
     1328            sage: P.<x,y,z> = PolynomialRing(QQbar, 3, order=t)
     1329            sage: f = x + y; f.lm() # indirect doctest
     1330            y
     1331            sage: f = x*y + z; f.lm()
     1332            x*y
     1333       
     1334        This method is called by the lm/lc/lt methods of
     1335        ``MPolynomial_polydict``.
     1336        """
     1337        sf = sum(l*r for (l,r) in zip(f,self._weights))
     1338        sg = sum(l*r for (l,r) in zip(g,self._weights))         
     1339        return (sf > sg or ( sf == sg and f  > g )) and f or g   
     1340 
     1341    def greater_tuple_wdegrevlex(self,f,g):
     1342        """
     1343        Return the greater exponent tuple with respect to the weighted degree
     1344        reverse lexicographical term order.
     1345       
     1346        INPUT:
     1347       
     1348        - ``f`` - exponent tuple
     1349       
     1350        - ``g`` - exponent tuple
     1351       
     1352        EXAMPLES::
     1353       
     1354            sage: t = TermOrder('wdegrevlex',(1,2,3))
     1355            sage: P.<x,y,z> = PolynomialRing(QQbar, 3, order=t)
     1356            sage: f = x + y; f.lm() # indirect doctest
     1357            y
     1358            sage: f = x + y^2*z; f.lm()
     1359            y^2*z
     1360       
     1361        This method is called by the lm/lc/lt methods of
     1362        ``MPolynomial_polydict``.
     1363        """
     1364        sf = sum(l*r for (l,r) in zip(f,self._weights))
     1365        sg = sum(l*r for (l,r) in zip(g,self._weights))         
     1366        return (sf > sg or ( sf == sg and f.reversed() < g.reversed())) and f or g 
     1367
     1368    def greater_tuple_negwdeglex(self,f,g):
     1369        """
     1370        Return the greater exponent tuple with respect to the negative
     1371        weighted degree lexicographical term order.
     1372       
     1373        INPUT:
     1374       
     1375        - ``f`` - exponent tuple
     1376       
     1377        - ``g`` - exponent tuple
     1378       
     1379        EXAMPLE::
     1380       
     1381            sage: t = TermOrder('negwdeglex',(1,2,3))
     1382            sage: P.<x,y,z> = PolynomialRing(QQbar, 3, order=t) 
     1383            sage: f = x + y; f.lm() # indirect doctest
     1384            x
     1385            sage: f = x + x^2; f.lm()
     1386            x
     1387            sage: f = x^3 + z; f.lm()
     1388            x^3
     1389       
     1390        This method is called by the lm/lc/lt methods of
     1391        ``MPolynomial_polydict``.
     1392        """
     1393        sf = sum(l*r for (l,r) in zip(f,self._weights))
     1394        sg = sum(l*r for (l,r) in zip(g,self._weights)) 
     1395        return (sf < sg or ( sf == sg and f  > g )) and f or g 
     1396
     1397    def greater_tuple_negwdegrevlex(self,f,g):
     1398        """
     1399        Return the greater exponent tuple with respect to the negative
     1400        weighted degree reverse lexicographical term order.
     1401       
     1402        INPUT:
     1403       
     1404        - ``f`` - exponent tuple
     1405       
     1406        - ``g`` - exponent tuple
     1407       
     1408        EXAMPLE::
     1409       
     1410            sage: t = TermOrder('negwdegrevlex',(1,2,3))
     1411            sage: P.<x,y,z> = PolynomialRing(QQbar, 3, order=t)
     1412            sage: f = x + y; f.lm() # indirect doctest
     1413            x
     1414            sage: f = x + x^2; f.lm()
     1415            x
     1416            sage: f = x^3 + z; f.lm() 
     1417            x^3
     1418       
     1419        This method is called by the lm/lc/lt methods of
     1420        ``MPolynomial_polydict``.
     1421        """
     1422        sf = sum(l*r for (l,r) in zip(f,self._weights))
     1423        sg = sum(l*r for (l,r) in zip(g,self._weights)) 
     1424        return (sf < sg or ( sf == sg and f.reversed() < g.reversed() )) and f or g   
     1425       
    10271426    def greater_tuple_block(self, f,g):
    10281427        """
    1029         Returns the greater exponent tuple with respect to the block
    1030         ordering as specified when constructing this element.
     1428        Return the greater exponent tuple with respect to the block
     1429        order as specified when constructing this element.
    10311430       
    10321431        This method is called by the lm/lc/lt methods of
    10331432        ``MPolynomial_polydict``.
     
    10471446            a
    10481447        """
    10491448        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)])
     1449        for block in self:
     1450            r = getattr(block,"compare_tuples_" + block.name())(f[n:n+len(block)],g[n:n+len(block)])
    10521451            if r != 0:
    10531452                if r < 0:
    10541453                    return g
    10551454                else:
    10561455                    return f
    1057             n += len(order)
     1456            n += len(block)
    10581457        return f
    10591458
     1459    def tuple_weight(self, f):
     1460        """
     1461        Return the weight of tuple f.
     1462
     1463        INPUT:
     1464       
     1465        - ``f`` - exponent tuple 
     1466
     1467        EXAMPLE::   
     1468
     1469            sage: t=TermOrder('wdeglex',(1,2,3))
     1470            sage: P.<a,b,c>=PolynomialRing(QQbar, order=t)
     1471            sage: P.term_order().tuple_weight([3,2,1])
     1472            10
     1473        """
     1474        return sum(l*r for (l,r) in zip(f,self._weights))
     1475
    10601476    def name(self):
    10611477        """
    10621478        EXAMPLE::
     
    10641480            sage: TermOrder('lex').name()
    10651481            'lex'
    10661482        """
    1067         return self.__name
     1483        return self._name
    10681484
    10691485    def _repr_(self):
    10701486        """
     
    10731489            sage: TermOrder('lex') # indirect doctest
    10741490            Lexicographic term order
    10751491        """
    1076         if self.__name[0] == 'M':
    1077             return 'Matrix term order with matrix\n%s'%self.matrix()
     1492        if self._name == 'matrix':
     1493            return 'Matrix term order with matrix\n%s'%(self._matrix,)
     1494        elif self._name == 'block':
     1495            s = []
     1496            for t in self._blocks:
     1497                if not t.is_weighted_degree_order():
     1498                    s.append('%s of length %d'%(t,len(t)))
     1499                else: # includes matrix order
     1500                    s.append('%s'%(t,))
     1501            return 'Block term order with blocks:\n(%s)'%(',\n '.join(s),)
    10781502        else:
    1079             s = print_name_mapping.get(self.__name,self.__name)
    1080             return '%s term order'%s
     1503            s = print_name_mapping.get(self._name,self._name) + ' term order'
     1504            if self.is_weighted_degree_order():
     1505                s = s + ' with weights %s'%(self._weights,)
     1506            return s
    10811507
    10821508    def singular_str(self):
    10831509        """
     
    11021528            //                  : names    x8 x9
    11031529            //        block   4 : ordering C
    11041530        """
    1105         return self.__singular_str
     1531        return self._singular_str
    11061532
    11071533    def macaulay2_str(self):
    11081534        """
     
    11161542            sage: P = PolynomialRing(GF(127), 8,names='x',order='degrevlex(3),lex(5)')
    11171543            sage: T = P.term_order()
    11181544            sage: T.macaulay2_str()
    1119             '(GRevLex => 3,Lex => 5)'
     1545            '{GRevLex => 3,Lex => 5}'
    11201546            sage: P._macaulay2_() # optional - macaulay2
    11211547            ZZ/127 [x0, x1, x2, x3, x4, x5, x6, x7, MonomialOrder => {GRevLex => 3, Lex => 5}, MonomialSize => 16]
    11221548        """
    1123         return self.__macaulay2_str
     1549        return self._macaulay2_str
    11241550
    11251551    def magma_str(self):
    11261552        """
     
    11421568            sage: T.magma_str()
    11431569            '"grevlex"'
    11441570        """
    1145         return self.__magma_str
     1571        return self._magma_str
     1572
     1573    def blocks(self):
     1574        """
     1575        Return the term order blocks of self.
     1576
     1577        EXAMPLE::
     1578
     1579            sage: t=TermOrder('deglex',2)+TermOrder('lex',2)
     1580            sage: t.blocks()
     1581            (Degree lexicographic term order, Lexicographic term order)
     1582        """
     1583        if self._blocks: # self is a block order
     1584            return self._blocks
     1585        else:
     1586            return [self]
    11461587
    11471588    def matrix(self):   
    11481589        """
    1149         Return the matrix defining matrix ordering.
     1590        Return the matrix defining matrix term order.
    11501591
    11511592        EXAMPLE::
    11521593
     
    11561597            [0 1]
    11571598           
    11581599        """
    1159         from sage.matrix.constructor import matrix
    1160         return matrix(self.__matrix)
     1600        return self._matrix
    11611601
    1162     def __cmp__(self, other):
     1602    def weights(self):
    11631603        """
    1164         Only equality testing makes sense here.
    1165        
     1604        Return the weights for weighted term orders.
     1605
     1606        EXAMPLE::
     1607
     1608            sage: t=TermOrder('wdeglex',(2,3))
     1609            sage: t.weights()
     1610            (2, 3)
     1611        """           
     1612        return self._weights
     1613
     1614    def __eq__(self, other):
     1615        """
     1616        Return true if self and other are equal.
     1617
    11661618        EXAMPLE::
    11671619       
    11681620            sage: TermOrder('lex') == TermOrder('lex',3)
     
    11781630            sage: T1 = TermOrder('lex',2)+TermOrder('lex',3)
    11791631            sage: T2 = TermOrder('lex',3)+TermOrder('lex',2)
    11801632            sage: T1 == T2
    1181             False
     1633            True
    11821634       
    11831635        ::
    11841636       
     
    11881640            True
    11891641        """
    11901642        if not isinstance(other, TermOrder):
    1191             if isinstance(other, str):
     1643            try:
    11921644                other = TermOrder(other, force=True)
    1193             else:
    1194                 return cmp(type(self), type(other))
    1195         return cmp(self.singular_str(), other.singular_str())
     1645            except:
     1646                return False
     1647
     1648        return (self._name == other._name       # note that length is not considered.
     1649            and self._blocks == other._blocks
     1650            and self._weights == other._weights
     1651            and self._matrix == other._matrix)
     1652
     1653    def __ne__(self, other):
     1654        """
     1655        Return true if self and other are not equal.
     1656
     1657        EXAMPLE::
     1658       
     1659            sage: T1 = TermOrder('lex',2)+TermOrder('lex',3)
     1660            sage: T2 = TermOrder('lex',3)+TermOrder('lex',2)
     1661            sage: T1 != T2
     1662            False 
     1663        """
     1664        return not self.__eq__(other)
    11961665
    11971666    def __add__(self, other):
    11981667        """
    1199         Block ordering constructor.
     1668        Construct a block order combining self and other.
    12001669       
    12011670        INPUT:
    12021671       
    12031672        - ``other`` - a term order
    12041673       
    1205         OUTPUT: a block ordering
     1674        OUTPUT: a block order
    12061675       
    12071676        EXAMPLE::
    12081677       
    12091678            sage: from sage.rings.polynomial.term_order import TermOrder
    12101679            sage: TermOrder('deglex',2) + TermOrder('degrevlex(3),neglex(3)')
    1211             deglex(2),degrevlex(3),neglex(3) term order
    1212         """
    1213         if other is None:
     1680            Block term order with blocks:
     1681            (Degree lexicographic term order of length 2,
     1682             Degree reverse lexicographic term order of length 3,
     1683             Negative lexicographic term order of length 3)
     1684        """   
     1685        if isinstance(other, TermOrder):
     1686            return TermOrder('block',[self,other])
     1687        else:
    12141688            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)
    12301689
    12311690    def __len__(self):
    12321691        """
    1233         Return the length of this term ordering, i.e. the number of
     1692        Return the length of this term order, i.e. the number of
    12341693        variables it covers. This may be zero for indefinitely many
    12351694        variables.
    12361695       
     
    12431702            sage: len(T)
    12441703            5
    12451704        """
    1246         return self.__length
     1705        return self._length
    12471706
    12481707    def __getitem__(self, i):
    12491708        r"""
    1250         Return the i-th block of this term ordering.
     1709        Return the i-th block of this term order.
    12511710       
    12521711        INPUT:
    12531712       
     
    12731732            sage: T = TermOrder('lex', 2) + TermOrder('degrevlex', 3)
    12741733            sage: T[len(T)-1]
    12751734            Traceback (most recent call last):
    1276             ...
     1735            \dots
    12771736            IndexError: tuple index out of range
    12781737        """
    1279         return self.blocks[i]
     1738        return self.blocks()[i]
    12801739
    12811740    def __iter__(self):
    12821741        r"""
    1283         Iterate over the blocks of this term ordering.
     1742        Iterate over the blocks of this term order.
    12841743       
    12851744        EXAMPLE::
    12861745       
     
    12991758        the number of variables in ``self`` while the latter
    13001759        counts the number of blocks.
    13011760        """
    1302         return iter(self.blocks)
     1761        return iter(self.blocks())
    13031762
    13041763    def is_global(self):
    13051764        r"""
    1306         Return ``True`` if this term ordering is definitely
    1307         global. Return ``False`` otherwise, which includes
    1308         unknown term orderings.
     1765        Return true if this term order is definitely
     1766        global. Return false otherwise, which includes
     1767        unknown term orders.
    13091768       
    13101769        EXAMPLE::
    13111770       
     
    13191778            sage: T.is_global()
    13201779            False
    13211780        """
    1322         if len(self.blocks) == 1:
    1323             if self.singular_str() in ('lp','dp','Dp'):
    1324                 return True
    1325             else:
    1326                 return False
     1781        if self.name() in ('lex','degrevlex','deglex','wdegrevlex','wdeglex'):
     1782            return True
     1783        elif self.name() is 'block':
     1784            return all([t.is_global() for t in self.blocks()])
    13271785        else:
    1328             return all([t.is_global() for t in self.blocks])
    1329            
     1786            return False
     1787
    13301788    def is_local(self):
    13311789        r"""
    1332         Return ``True`` if this term ordering is definitely
    1333         local. Return ``False`` otherwise, which includes
    1334         unknown term orderings.
     1790        Return true if this term order is definitely
     1791        local. Return false otherwise, which includes
     1792        unknown term orders.
    13351793       
    13361794        EXAMPLE::
    13371795       
     
    13451803            sage: T.is_local()
    13461804            False
    13471805        """
    1348         if len(self.blocks) == 1:
    1349             if self.singular_str() in ('rp', 'ls','ds','Ds'):
    1350                 return True
    1351             else:
    1352                 return False
     1806        if (self.name() in ('neglex','negdegrevlex','negdeglex','negwdegrevlex','negwdeglex') or
     1807            self.singular_str() in ('ls','ds','Ds','ws','Ws')):
     1808            return True
     1809        elif self.name() is 'block':
     1810            return all([t.is_local() for t in self.blocks()])
    13531811        else:
    1354             return all([t.is_local() for t in self.blocks])
     1812            return False
     1813
     1814    def is_block_order(self):
     1815        """
     1816        Return true if self is a block term order.
     1817
     1818        EXAMPLE::
     1819
     1820            sage: t=TermOrder('deglex',2)+TermOrder('lex',2)
     1821            sage: t.is_block_order()
     1822            True
     1823        """
     1824        return self._name == 'block'
     1825
     1826    def is_weighted_degree_order(self):
     1827        """
     1828        Return true if self is a weighted degree term order.
     1829
     1830        EXAMPLE::
     1831
     1832            sage: t=TermOrder('wdeglex',(2,3))
     1833            sage: t.is_weighted_degree_order()
     1834            True
     1835        """           
     1836        return self._weights is not None