# HG changeset patch
# User Simon King <simon.king@nuigalway.ie>
# Date 1279223562 -3600
# Node ID ee29319087da1911333c605b9bd5e7c7baa440c0
# Parent  3f6506a65e77a5d12282f0e2c3611466b5b5d0f5
#1396: Allow Singular's options (including prot and degBound) in libSingular; use a method decorator to ensure default options unless requested otherwise.

diff --git a/sage/interfaces/singular.py b/sage/interfaces/singular.py
--- a/sage/interfaces/singular.py
+++ b/sage/interfaces/singular.py
@@ -381,6 +381,7 @@ class Singular(Expect):
         self.option("redTail")
         self.option("redThrough")
         self.option("intStrategy")
+        self._saved_options = self.option('get')
 
     def __reduce__(self):
         """
diff --git a/sage/libs/singular/option.pyx b/sage/libs/singular/option.pyx
--- a/sage/libs/singular/option.pyx
+++ b/sage/libs/singular/option.pyx
@@ -17,7 +17,7 @@ We compute a Groebner basis for Cyclic-5
 By default, tail reductions are performed::
 
     sage: from sage.libs.singular.option import opt, opt_ctx
-    sage: opt['redTail']
+    sage: opt['red_tail']
     True
     sage: std(I)[-1]
     d^2*e^6 + 28*b*c*d + ...
@@ -25,40 +25,40 @@ By default, tail reductions are performe
 If we don't want this, we can create an option context, which disables
 this::
 
-    sage: with opt_ctx(redTail=False,redSB=False):
+    sage: with opt_ctx(red_tail=False, red_sb=False):
     ...      std(I)[-1]
     d^2*e^6 + 8*c^3 + ...
 
 However, this does not affect the global state::
 
-    sage: opt['redTail']
+    sage: opt['red_tail']
     True
 
 On the other hand, any assignment to an option object will immediately
 change the global state::
 
-    sage: opt['redTail'] = False
-    sage: opt['redTail']
+    sage: opt['red_tail'] = False
+    sage: opt['red_tail']
     False
-    sage: opt['redTail'] = True
-    sage: opt['redTail']
+    sage: opt['red_tail'] = True
+    sage: opt['red_tail']
     True
 
 Assigning values within an option context, only affects this context::
 
     sage: with opt_ctx:
-    ...      opt['redTail'] = False
+    ...      opt['red_tail'] = False
 
-    sage: opt['redTail']
+    sage: opt['red_tail']
     True
 
 Option contexts can also be safely stacked::
 
     sage: with opt_ctx:
-    ...       opt['redTail'] = False
+    ...       opt['red_tail'] = False
     ...       print opt
     ...       with opt_ctx:
-    ...           opt['redThrough'] = False
+    ...           opt['red_through'] = False
     ...           print opt
     ...
     general options for libSingular (current value 0x00000082)
@@ -67,17 +67,31 @@ Option contexts can also be safely stack
     sage: print opt
     general options for libSingular (current value 0x02000082)
 
+Furthermore, the integer valued options ``deg_bound`` and
+``mult_bound`` can be used::
+
+    sage: R.<x,y> = QQ[]
+    sage: I = R*[x^3+y^2,x^2*y+1]
+    sage: opt['deg_bound'] = 2
+    sage: std(I)
+    [x^2*y + 1, x^3 + y^2]
+    sage: opt['deg_bound'] = 0
+    sage: std(I)
+    [y^3 - x, x^2*y + 1, x^3 + y^2]
 
 The same interface is available for verbosity options::
 
     sage: from sage.libs.singular.option import opt_verb
-    sage: opt_verb['notWarnSB']
+    sage: opt_verb['not_warn_sb']
     False
+    sage: opt.reset_default()  # needed to avoid side effects
+    sage: opt_verb.reset_default()  # needed to avoid side effects
 
 AUTHOR:
 
 - Martin Albrecht (2009-08): initial implementation
 - Martin Albrecht (2010-01): better interface, verbosity options
+- Simon King (2010-07): Python-ic option names; deg_bound and mult_bound
 """
 #*****************************************************************************
 #       Copyright (C) 2010 Martin Albrecht <M.R.Albrecht@rhul.ac.uk>
@@ -86,9 +100,9 @@ AUTHOR:
 #                  http://www.gnu.org/licenses/
 #*****************************************************************************
 
-from sage.libs.singular.decl cimport singular_options, singular_verbose_options
+from sage.libs.singular.decl cimport singular_options, singular_verbose_options, Kstd1_deg, Kstd1_mu
 
-from sage.libs.singular.decl cimport OPT_PROT, OPT_REDSB, OPT_NOT_BUCKETS, OPT_NOT_SUGAR, OPT_SUGARCRIT, OPT_REDTHROUGH
+from sage.libs.singular.decl cimport OPT_PROT, OPT_REDSB, OPT_NOT_BUCKETS, OPT_NOT_SUGAR, OPT_SUGARCRIT, OPT_REDTHROUGH, OPT_DEGBOUND, OPT_MULTBOUND
 from sage.libs.singular.decl cimport OPT_RETURN_SB, OPT_FASTHC, OPT_OLDSTD, OPT_REDTAIL, OPT_INTSTRATEGY, OPT_NOTREGULARITY
 from sage.libs.singular.decl cimport OPT_WEIGHTM, Sy_bit
 
@@ -96,6 +110,29 @@ from sage.libs.singular.decl cimport V_S
 from sage.libs.singular.decl cimport V_LOAD_PROC, V_DEF_RES, V_DEBUG_MEM, V_SHOW_USE, V_IMAP, V_PROMPT
 from sage.libs.singular.decl cimport V_NSB, V_CONTENTSB, V_CANCELUNIT, V_DEG_STOP
 
+_options_py_to_singular={'return_sb':'returnSB',
+                         'fast_hc':'fastHC',
+                         'inf_red_tail':'infRedTail',
+                         'int_strategy':'intStrategy',
+                         'not_regularity':'notRegularity',
+                         'not_sugar':'notSugar',
+                         'not_buckets':'notBuckets',
+                         'qring_nf':'qringNF',
+                         'redsb':'redSB',
+                         'red_sb':'redSB',
+                         'red_tail':'redTail',
+                         'red_through':'redThrough',
+                         'sugar_crit':'sugarCrit',
+                         'weight_m':'weightM',
+                         'content_sb':'contentSB',
+                         'mult_bound':'multBound',
+                         'deg_bound':'degBound',
+                         'imap':'Imap',
+                         'debug_lib':'debugLib',
+                         'def_res':'defRes',
+                         'load_lib':'loadLib',
+                         'load_proc':'loadProc',
+                         'not_warn_sb':'notWarnSB'}
 
 cdef class LibSingularOptions_abstract:
     """
@@ -120,6 +157,12 @@ cdef class LibSingularOptions_abstract:
             sage: opt['redTail'] = True
             sage: opt['redTail']
             True
+            sage: opt['deg_bound'] = 2
+
+        The options can be named in Python or Singular style::
+
+            sage: opt['degBound']
+            2
         """
         for k,v in kwds.iteritems():
             self[k] = v
@@ -129,9 +172,25 @@ cdef class LibSingularOptions_abstract:
         EXAMPLE::
 
             sage: from sage.libs.singular.option import opt
-            sage: opt['redTail']
+            sage: opt['red_tail']
             True
+            sage: opt['deg_bound'] = 2
+
+        The options can be named in Python or Singular style::
+
+            sage: opt['degBound']
+            2
+            sage: opt.reset_default()  # needed to avoid side effects
         """
+        name = _options_py_to_singular.get(name,name)
+        if name == "degBound":
+            if bool(self.global_options[0] & self.name_map[name]):
+                return Kstd1_deg
+            return int(0)
+        if name == "multBound":
+            if bool(self.global_options[0] & self.name_map[name]):
+                return Kstd1_mu
+            return int(0)
         try:
             return bool(self.global_options[0] & self.name_map[name])
         except KeyError:
@@ -148,12 +207,22 @@ cdef class LibSingularOptions_abstract:
             ...      opt['redTail'] = False
             ...      opt['redTail']
             False
+            sage: opt['red_tail']
+            True
+            sage: opt.reset_default()  # needed to avoid side effects
         """
+        name = _options_py_to_singular.get(name,name)
         try:
             if value:
                 self.global_options[0] = self.global_options[0] | self.name_map[name]
             else:
                 self.global_options[0] = self.global_options[0] & ~self.name_map[name]
+            if name == 'degBound':
+                global Kstd1_deg
+                Kstd1_deg = value
+            elif name == 'multBound':
+                global Kstd1_mu
+                Kstd1_mu = value
         except KeyError:
             raise NameError("Option '%s' unknown."%(name,))
 
@@ -163,25 +232,58 @@ cdef class LibSingularOptions_abstract:
 
             sage: from sage.libs.singular.option import opt
             sage: hex(int(opt))
-            '0x2000082'
+            '0x6000082'
         """
         return int(self.global_options[0])
 
+    def save(self):
+        """
+        Return a triple of integers that allow reconstruction of the options.
+
+        EXAMPLE::
+
+            sage: from sage.libs.singular.option import opt
+            sage: opt['deg_bound']
+            0
+            sage: opt['red_tail']
+            True
+            sage: s = opt.save()
+            sage: opt['deg_bound'] = 2
+            sage: opt['red_tail'] = False
+            sage: opt['deg_bound']
+            2
+            sage: opt['red_tail']
+            False
+            sage: opt.load(s)
+            sage: opt['deg_bound']
+            0
+            sage: opt['red_tail']
+            True
+            sage: opt.reset_default()  # needed to avoid side effects
+        """
+        return (int(self.global_options[0]), self['deg_bound'], self['mult_bound'])
+
     def load(self, value=None):
         """
         EXAMPLE::
 
             sage: from sage.libs.singular.option import opt as sopt
-            sage: bck = int(sopt); hex(bck)
-            '0x2000082'
+            sage: bck = sopt.save(); hex(bck[0]), bck[1], bck[2]
+            ('0x6000082', 0, 0)
             sage: sopt['redTail'] = False
             sage: hex(int(sopt))
-            '0x82'
+            '0x4000082'
             sage: sopt.load(bck)
             sage: sopt['redTail']
             True
         """
-        self.global_options[0] = int(value)
+        if value == None:
+            value = (None,0,0)
+        self.global_options[0] = int(value[0])
+        global Kstd1_deg
+        global Kstd1_mu
+        Kstd1_deg = value[1]
+        Kstd1_mu  = value[2]
 
     def __repr__(self):
         """
@@ -189,7 +291,7 @@ cdef class LibSingularOptions_abstract:
 
             sage: from sage.libs.singular.option import opt as sopt
             sage: sopt
-            general options for libSingular (current value 0x02000082)
+            general options for libSingular (current value 0x06000082)
         """
         return "%s options for libSingular (current value 0x%08x)"%(self.name, self.global_options[0])
 
@@ -200,74 +302,111 @@ cdef class LibSingularOptions(LibSingula
 
     Supported options are:
 
-     - ``returnSB`` - the functions syz, intersect, quotient, modulo
-       return a standard base instead of a generating set if returnSB
-       is set. This option should not be used for lift.
+     - ``return_sb`` or ``returnSB`` - the functions ``syz``,
+       ``intersect``, ``quotient``, ``modulo`` return a standard
+       base instead of a generating set if ``return_sb``
+       is set. This option should not be used for ``lift``.
 
-     - ``fastHC`` - tries to find the highest corner of the
-       staircase (HC) as fast as possible during a standard basis
-       computation (only used for local orderings).
+     - ``fast_hc`` or ``fastHC`` - tries to find the highest corner
+       of the staircase (HC) as fast as possible during a standard
+       basis computation (only used for local orderings).
 
-     - ``intStrategy`` - avoids division of coefficients during
-       standard basis computations. This option is ring dependent. By
-       default, it is set for rings with characteristic 0 and not set
-       for all other rings.
+     - ``int_strategy`` or ``intStrategy`` - avoids division of
+       coefficients during standard basis computations. This option
+       is ring dependent. By default, it is set for rings with
+       characteristic 0 and not set for all other rings.
 
      - ``lazy`` - uses a more lazy approach in std computations, which
        was used in SINGULAR version before 2-0 (and which may lead to
-       faster or slower computations, depending on the example)
+       faster or slower computations, depending on the example).
 
-     - ``length`` - select shorter reducers in std computations,
+     - ``length`` - select shorter reducers in std computations.
 
-     - ``notRegularity`` - disables the regularity bound for ``res`` and
-       ``mres`` (see regularity).
+     - ``not_regularity`` or ``notRegularity`` - disables the
+       regularity bound for ``res`` and ``mres``.
 
-     - ``notSugar`` - disables the sugar strategy during standard
-       basis computation.
+     - ``not_sugar`` or ``notSugar`` - disables the sugar strategy
+       during standard basis computation.
 
-     - ``notBuckets`` - disables the bucket representation of
-       polynomials during standard basis computations. This option
-       usually decreases the memory usage but increases the
-       computation time. It should only be set for memory-critical
-       standard basis computations.
+     - ``not_buckets`` or ``notBuckets`` - disables the bucket
+       representation of polynomials during standard basis
+       computations. This option usually decreases the memory
+       usage but increases the computation time. It should only
+       be set for memory-critical standard basis computations.
 
-     - ``oldStd`` - uses a more lazy approach in std computations,
-       which was used in SINGULAR version before 2-0 (and which may
-       lead to faster or slower computations, depending on the
-       example)
+     - ``old_std`` or ``oldStd`` - uses a more lazy approach in std
+       computations, which was used in SINGULAR version before 2-0
+       (and which may lead to faster or slower computations, depending
+       on the example).
 
      - ``prot`` - shows protocol information indicating the progress
        during the following computations: ``facstd``, ``fglm``,
        ``groebner``, ``lres``, ``mres``, ``minres``, ``mstd``,
-       ``res``, ``slimgb``,``sres``, ``std``, ``stdfglm``,
+       ``res``, ``slimgb``, ``sres``, ``std``, ``stdfglm``,
        ``stdhilb``, ``syz``.
 
-     - ``redSB`` - computes a reduced standard basis in any standard
-       basis computation.
+     - `red_sb`` or ``redSB`` - computes a reduced standard basis in
+       any standard basis computation.
 
-     - ``redTail`` - reduction of the tails of polynomials during
-       standard basis computations. This option is ring dependent. By
-       default, it is set for rings with global degree orderings and
-       not set for all other rings.
+     - ``red_tail`` or ``redTail`` - reduction of the tails of
+       polynomials during standard basis computations. This option
+       is ring dependent. By default, it is set for rings with global
+       degree orderings and not set for all other rings.
 
-     - ``redThrough`` - for inhomogenous input, polynomial reductions
-       during standard basis computations are never postponed, but
-       always finished through. This option is ring dependent. By
-       default, it is set for rings with global degree orderings and
-       not set for all other rings.
+     - ``red_through`` or ``redThrough`` - for inhomogenous input,
+       polynomial reductions during standard basis computations are
+       never postponed, but always finished through. This option is
+       ring dependent. By default, it is set for rings with global
+       degree orderings and not set for all other rings.
 
-     - ``sugarCrit`` - uses criteria similar to the homogeneous case
-       to keep more useless pairs.
+     - ``sugar_crit`` or ``sugarCrit`` - uses criteria similar to the
+       homogeneous case to keep more useless pairs.
 
-     - ``weightM`` - automatically computes suitable weights for the
-       weighted ecart and the weighted sugar method.
-               
+     - ``weight_m`` or ``weightM`` - automatically computes suitable
+       weights for the weighted ecart and the weighted sugar method.
+    
+    In addition, two integer valued parameters are supported, namely:
+
+    - ``deg_bound`` or ``degBound`` - The standard basis computation
+      is stopped if the total (weighted) degree exceeds ``deg_bound``.
+      ``deg_bound`` should not be used for a global ordering with
+      inhomogeneous input. Reset this bound by setting ``deg_bound``
+      to 0. The exact meaning of "degree" depends on the ring odering
+      and the command: ``slimgb`` uses always the total degree with
+      weights 1, ``std`` does so for block orderings, only. 
+
+    - ``mult_bound`` or ``multBound`` - The standard basis computation
+      is stopped if the ideal is zero-dimensional in a ring with local
+      ordering and its multiplicity is lower than ``mult_bound``.
+      Reset this bound by setting ``mult_bound`` to 0. 
+
     EXAMPLE::
 
         sage: from sage.libs.singular.option import LibSingularOptions
         sage: libsingular_options = LibSingularOptions()
         sage: libsingular_options
-        general options for libSingular (current value 0x02000082)
+        general options for libSingular (current value 0x06000082)
+
+    Here we demonstrate the intended way of using libSingular options::
+
+        sage: R.<x,y> = QQ[]
+        sage: I = R*[x^3+y^2,x^2*y+1]
+        sage: I.groebner_basis(deg_bound=2)
+        [x^3 + y^2, x^2*y + 1]
+        sage: I.groebner_basis()
+        [x^3 + y^2, x^2*y + 1, y^3 - x]
+
+    The option ``mult_bound`` is only relevant in the local case::
+
+        sage: Rlocal.<x,y,z> = PolynomialRing(QQ, order='ds')
+        sage: x^2<x
+        True
+        sage: J = [x^7+y^7+z^6,x^6+y^8+z^7,x^7+y^5+z^8, x^2*y^3+y^2*z^3+x^3*z^2,x^3*y^2+y^3*z^2+x^2*z^3]*Rlocal
+        sage: J.groebner_basis(mult_bound=100)
+        [x^3*y^2 + y^3*z^2 + x^2*z^3, x^2*y^3 + x^3*z^2 + y^2*z^3, y^5, x^6 + x*y^4*z^5, x^4*z^2 - y^4*z^2 - x^2*y*z^3 + x*y^2*z^3, z^6 - x*y^4*z^4 - x^3*y*z^5]
+        sage: J.groebner_basis()
+        [x^3*y^2 + y^3*z^2 + x^2*z^3, x^2*y^3 + x^3*z^2 + y^2*z^3, y^5, x^6, x^4*z^2 - y^4*z^2 - x^2*y*z^3 + x*y^2*z^3, z^6, y^4*z^3 - y^3*z^4 - x^2*z^5, x^3*y*z^4 - x^2*y^2*z^4 + x*y^3*z^4, x^3*z^5, x^2*y*z^5 + y^3*z^5, x*y^3*z^5]
+
     """
     def __init__(self, **kwds):
         """
@@ -278,7 +417,7 @@ cdef class LibSingularOptions(LibSingula
             sage: from sage.libs.singular.option import LibSingularOptions
             sage: libsingular_options = LibSingularOptions()
             sage: libsingular_options
-            general options for libSingular (current value 0x02000082)
+            general options for libSingular (current value 0x06000082)
         """
         self.global_options = &singular_options
         self.name = "general"
@@ -294,9 +433,38 @@ cdef class LibSingularOptions(LibSingula
                          "redTail":       Sy_bit(OPT_REDTAIL),
                          "intStrategy":   Sy_bit(OPT_INTSTRATEGY),
                          "notRegularity": Sy_bit(OPT_NOTREGULARITY),
-                         "weightM":       Sy_bit(OPT_WEIGHTM)}
+                         "weightM":       Sy_bit(OPT_WEIGHTM),
+                         "degBound":      Sy_bit(OPT_DEGBOUND),
+                         "multBound":     Sy_bit(OPT_MULTBOUND)}
         LibSingularOptions_abstract.__init__(self, **kwds)
 
+    def reset_default(self):
+        """
+        Reset libSingular's default options.
+
+        EXAMPLE::
+
+            sage: from sage.libs.singular.option import opt
+            sage: opt['red_tail']
+            True
+            sage: opt['red_tail'] = False
+            sage: opt['red_tail']
+            False
+            sage: opt['deg_bound']
+            0
+            sage: opt['deg_bound'] = 2
+            sage: opt['deg_bound']
+            2
+            sage: opt.reset_default()
+            sage: opt['red_tail']
+            True
+            sage: opt['deg_bound']
+            0
+        """
+        from sage.libs.singular.singular import _saved_options
+        self.load(_saved_options)
+
+
 
 #############
 
@@ -306,22 +474,28 @@ cdef class LibSingularVerboseOptions(Lib
 
     Supported options are:
 
-     - ``mem`` -
-     - ``yacc`` -
-     - ``redefine`` -
-     - ``reading`` -
-     - ``loadLib`` -
-     - ``debugLib`` -
-     - ``loadProc`` -
-     - ``defRes`` -
-     - ``debugMem`` -
-     - ``usage`` -
-     - ``Imap`` -
-     - ``prompt`` -
-     - ``notWarnSB`` - do not warn if a basis is not a standard basis
-     - ``contentSB`` -
-     - ``cancelunit`` -
-               
+     - ``mem`` - shows memory usage in square brackets.
+     - ``yacc`` - Only available in debug version.
+     - ``redefine`` - warns about variable redefinitions.
+     - ``reading`` - shows the number of characters read from a file.
+     - ``loadLib`` or ``load_lib`` - shows loading of libraries.
+     - ``debugLib`` or ``debug_lib`` - warns about syntax errors
+       when loading a library.
+     - ``loadProc`` or ``load_proc`` - shows loading of procedures
+       from libraries.
+     - ``defRes`` or ``def_res`` - shows the names of the syzygy
+       modules while converting ``resolution`` to ``list``.
+     - ``usage`` - shows correct usage in error messages.
+     - ``Imap`` or ``imap`` - shows the mapping of variables with
+       the ``fetch`` and ``imap`` commands.
+     - ``notWarnSB`` or ``not_warn_sb`` - do not warn if 
+       a basis is not a standard basis
+     - ``contentSB`` or ``content_sb`` - avoids to divide by the
+       content of a polynomial in ``std`` and related algorithms.
+       Should usually not be used. 
+     - ``cancelunit`` - avoids to divide polynomials by non-constant
+       units in ``std`` in the local case. Should usually not be used. 
+          
     EXAMPLE::
 
         sage: from sage.libs.singular.option import LibSingularVerboseOptions
@@ -350,16 +524,36 @@ cdef class LibSingularVerboseOptions(Lib
                          "debugLib": Sy_bit(V_DEBUG_LIB), 
                          "loadProc": Sy_bit(V_LOAD_PROC), 
                          "defRes":   Sy_bit(V_DEF_RES),   
-                         "debugMem": Sy_bit(V_DEBUG_MEM), 
+                         #"debugMem": Sy_bit(V_DEBUG_MEM), 
                          "usage":    Sy_bit(V_SHOW_USE),  
                          "Imap":     Sy_bit(V_IMAP),      
-                         "prompt":   Sy_bit(V_PROMPT),    
-                         "notWarnSB":Sy_bit(V_NSB),       
+                         #"prompt":   Sy_bit(V_PROMPT),    
+                         "notWarnSB":Sy_bit(V_NSB),
                          "contentSB":Sy_bit(V_CONTENTSB), 
-                         "cancelunit":Sy_bit(V_CANCELUNIT),
+                         "cancelunit":Sy_bit(V_CANCELUNIT)
                          }
         LibSingularOptions_abstract.__init__(self, **kwds)
 
+    def reset_default(self):
+        """
+        Return to libSingular's default verbosity options
+
+        EXAMPLE::
+
+            sage: from sage.libs.singular.option import opt_verb
+            sage: opt_verb['not_warn_sb']
+            False
+            sage: opt_verb['not_warn_sb'] = True
+            sage: opt_verb['not_warn_sb']
+            True
+            sage: opt_verb.reset_default()
+            sage: opt_verb['not_warn_sb']
+            False
+
+        """
+        from sage.libs.singular.singular import _saved_verbose_options
+        self.global_options[0] = int(_saved_verbose_options)
+
 cdef class LibSingularOptionsContext:
     """
     Option context
@@ -370,7 +564,7 @@ cdef class LibSingularOptionsContext:
 
         sage: from sage.libs.singular.option import opt, opt_ctx
         sage: opt
-        general options for libSingular (current value 0x02000082)
+        general options for libSingular (current value 0x06000082)
 
     ::
 
@@ -379,13 +573,15 @@ cdef class LibSingularOptionsContext:
         ...       with opt_ctx(redThrough=False):
         ...           print opt
         ...
-        general options for libSingular (current value 0x00000082)
-        general options for libSingular (current value 0x00000002)
+        general options for libSingular (current value 0x04000082)
+        general options for libSingular (current value 0x04000002)
 
         sage: print opt
-        general options for libSingular (current value 0x02000082)
+        general options for libSingular (current value 0x06000082)
     """
     cdef list bck
+    cdef list bck_degBound
+    cdef list bck_multBound
     cdef public LibSingularOptions_abstract opt
     cdef object options
 
@@ -400,6 +596,8 @@ cdef class LibSingularOptionsContext:
             general options context for libSingular
         """
         self.bck = []
+        self.bck_degBound = []
+        self.bck_multBound = []
         self.options = kwds
         self.opt = opt
 
@@ -415,6 +613,8 @@ cdef class LibSingularOptionsContext:
             False
         """
         self.bck.append(self.opt.global_options[0])
+        self.bck_degBound.append(Kstd1_deg)
+        self.bck_multBound.append(Kstd1_mu)
         opt = self.opt.__class__()
         for k,v in self.options.iteritems():
             opt[k] = v
@@ -447,6 +647,10 @@ cdef class LibSingularOptionsContext:
             False
         """
         self.opt.global_options[0] = self.bck.pop()
+        global Kstd1_deg
+        global Kstd1_mu
+        Kstd1_deg = self.bck_degBound.pop()
+        Kstd1_mu  = self.bck_multBound.pop()
 
     def __repr__(self):
         """
@@ -460,6 +664,8 @@ cdef class LibSingularOptionsContext:
 
 
 opt = LibSingularOptions()
+opt.reset_default()
 opt_verb = LibSingularVerboseOptions()
+opt_verb.reset_default()
 opt_ctx = LibSingularOptionsContext(opt)
 opt_verb_ctx = LibSingularOptionsContext(opt_verb)
diff --git a/sage/libs/singular/singular-cdefs.pxi b/sage/libs/singular/singular-cdefs.pxi
--- a/sage/libs/singular/singular-cdefs.pxi
+++ b/sage/libs/singular/singular-cdefs.pxi
@@ -14,7 +14,6 @@ include "sage/ext/cdefs.pxi"
 cdef extern from "stdlib.h":
     void delete "delete" (void *ptr)
 
-
 cdef extern from "factory.h":
 
     #
@@ -997,6 +996,10 @@ cdef extern from "lists.h":
         leftv  *m
         void (*Init)(int n)
 
+cdef extern from "kstd1.h":
+    cdef extern int Kstd1_deg   # degBound, default 0
+    cdef extern int Kstd1_mu    # multBound, default 0
+
 cdef extern from "intvec.h":
     # for the moment we need only new, as we use the cleanup of sleftv
     # to get rid of it again
diff --git a/sage/libs/singular/singular.pyx b/sage/libs/singular/singular.pyx
--- a/sage/libs/singular/singular.pyx
+++ b/sage/libs/singular/singular.pyx
@@ -26,7 +26,7 @@ import os
 from sage.misc.misc_c import is_64_bit
 
 from sage.libs.singular.decl cimport intvec
-from sage.libs.singular.decl cimport SR_HDL, SR_INT, SR_TO_INT, singular_options
+from sage.libs.singular.decl cimport SR_HDL, SR_INT, SR_TO_INT, singular_options, singular_verbose_options
 from sage.libs.singular.decl cimport On, Off, SW_USE_NTL, SW_USE_NTL_GCD_0, SW_USE_EZGCD, SW_USE_NTL_SORT, SW_USE_NTL_GCD_P
 from sage.libs.singular.decl cimport napoly, lnumber, Sy_bit, OPT_REDSB, OPT_INTSTRATEGY, OPT_REDTAIL, OPT_REDTHROUGH
 from sage.libs.singular.decl cimport nlGetNom, nlGetDenom, nlDelete, nlInit2gmp
@@ -48,6 +48,8 @@ from sage.libs.pari.all import pari
 from sage.structure.parent_base cimport ParentWithBase
 from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomial_libsingular
 
+_saved_options = (int(0),0,0)
+
 cdef Rational si2sa_QQ(number *n, ring *_ring):
     """
     TESTS::
@@ -645,6 +647,7 @@ cdef init_libsingular():
     far is to load the library again and to specify ``RTLD_GLOBAL``.
     """
     global singular_options
+    global singular_verbose_options
     global max_exponent_size
 
     cdef void *handle = NULL
@@ -667,9 +670,13 @@ cdef init_libsingular():
 
     dlclose(handle)
 
-    # we set some global Singular options
+    # we set and save some global Singular options
     singular_options = singular_options | Sy_bit(OPT_REDSB) | Sy_bit(OPT_INTSTRATEGY) | Sy_bit(OPT_REDTAIL) | Sy_bit(OPT_REDTHROUGH)
-        
+    global _saved_options
+    global _saved_verbose_options
+    _saved_options = (int(singular_options), 0, 0)
+    _saved_verbose_options = int(singular_verbose_options)
+
     On(SW_USE_NTL)
     On(SW_USE_NTL_GCD_0)
     On(SW_USE_NTL_GCD_P)
diff --git a/sage/rings/polynomial/multi_polynomial_ideal.py b/sage/rings/polynomial/multi_polynomial_ideal.py
--- a/sage/rings/polynomial/multi_polynomial_ideal.py
+++ b/sage/rings/polynomial/multi_polynomial_ideal.py
@@ -244,7 +244,53 @@ import sage.rings.polynomial.toy_buchber
 import sage.rings.polynomial.toy_variety as toy_variety
 import sage.rings.polynomial.toy_d_basis as toy_d_basis
 
-class RedSBContext:
+class LibSingularDefaultContext:
+    def __init__(self, singular=singular_default):
+        from sage.libs.singular.option import opt_ctx
+        self.libsingular_option_context = opt_ctx
+    def __enter__(self):
+        """
+        EXAMPLE::
+
+            sage: from sage.rings.polynomial.multi_polynomial_ideal import SingularDefaultContext
+            sage: P.<a,b,c> = PolynomialRing(QQ,3, order='lex')
+            sage: I = sage.rings.ideal.Katsura(P,3)
+            sage: singular.option('noredTail')
+            sage: singular.option('noredThrough')
+            sage: Is = I._singular_()
+            sage: with SingularDefaultContext(): rgb = Is.groebner()
+            sage: rgb
+            84*c^4-40*c^3+c^2+c,
+            7*b+210*c^3-79*c^2+3*c,
+            7*a-420*c^3+158*c^2+8*c-7
+        """
+        self.libsingular_option_context.__enter__()
+        self.libsingular_option_context.opt.reset_default()
+        self.libsingular_option_context.opt['red_sb'] = True
+        self.libsingular_option_context.opt['red_tail'] = True
+        self.libsingular_option_context.opt['deg_bound'] = 0
+        self.libsingular_option_context.opt['mult_bound'] = 0
+
+    def __exit__(self, typ, value, tb):
+        """
+        EXAMPLE::
+
+            sage: from sage.rings.polynomial.multi_polynomial_ideal import SingularDefaultContext
+            sage: P.<a,b,c> = PolynomialRing(QQ,3, order='lex')
+            sage: I = sage.rings.ideal.Katsura(P,3)
+            sage: singular.option('noredTail')
+            sage: singular.option('noredThrough')
+            sage: Is = I._singular_()
+            sage: with SingularDefaultContext(): rgb = Is.groebner()
+            sage: rgb
+            84*c^4-40*c^3+c^2+c,
+            7*b+210*c^3-79*c^2+3*c,
+            7*a-420*c^3+158*c^2+8*c-7
+        """
+        self.libsingular_option_context.__exit__(typ,value,tb)
+
+
+class SingularDefaultContext:
     """
     Within this context all Singular Groebner basis calculations are
     reduced automatically.
@@ -252,6 +298,7 @@ class RedSBContext:
     AUTHORS:
 
     - Martin Albrecht
+    - Simon King
     """
     def __init__(self, singular=singular_default):
         """
@@ -264,7 +311,7 @@ class RedSBContext:
         
         EXAMPLE::
         
-            sage: from sage.rings.polynomial.multi_polynomial_ideal import RedSBContext
+            sage: from sage.rings.polynomial.multi_polynomial_ideal import SingularDefaultContext
             sage: P.<a,b,c> = PolynomialRing(QQ,3, order='lex')
             sage: I = sage.rings.ideal.Katsura(P,3)
             sage: singular.option('noredTail')
@@ -279,7 +326,7 @@ class RedSBContext:
         ::
         
             sage: from __future__ import with_statement
-            sage: with RedSBContext(): rgb = Is.groebner()
+            sage: with SingularDefaultContext(): rgb = Is.groebner()
             sage: rgb
             84*c^4-40*c^3+c^2+c,
             7*b+210*c^3-79*c^2+3*c,
@@ -299,52 +346,72 @@ class RedSBContext:
            Groebner basis is computed so the user does not need to use
            it manually.
         """
-        from sage.libs.singular.option import opt_ctx
         self.singular = singular
-        self.libsingular_option_context = opt_ctx
 
     def __enter__(self):
         """
         EXAMPLE::
         
-            sage: from sage.rings.polynomial.multi_polynomial_ideal import RedSBContext
+            sage: from sage.rings.polynomial.multi_polynomial_ideal import SingularDefaultContext
             sage: P.<a,b,c> = PolynomialRing(QQ,3, order='lex')
             sage: I = sage.rings.ideal.Katsura(P,3)
             sage: singular.option('noredTail')
             sage: singular.option('noredThrough')
             sage: Is = I._singular_()
-            sage: with RedSBContext(): rgb = Is.groebner()
+            sage: with SingularDefaultContext(): rgb = Is.groebner()
             sage: rgb
             84*c^4-40*c^3+c^2+c,
             7*b+210*c^3-79*c^2+3*c,
             7*a-420*c^3+158*c^2+8*c-7
         """
+        try:
+            self.bck_degBound = int(self.singular.eval('degBound'))
+        except RuntimeError:
+            self.bck_degBound = int(0)
+        try:
+            self.bck_multBound = int(self.singular.eval('multBound'))
+        except RuntimeError:
+            self.bck_multBound = int(0)
         self.o = self.singular.option("get")
+        self.singular.option('set',self.singular._saved_options)
         self.singular.option("redSB")
-        self.libsingular_option_context.__enter__()
-        self.libsingular_option_context.opt['redSB'] = True
-        self.libsingular_option_context.opt['redTail'] = True
+        self.singular.option("redTail")
+        try:
+            self.singular.eval('degBound=0')
+        except RuntimeError:
+            pass
+        try:
+            self.singular.eval('multBound=0')
+        except RuntimeError:
+            pass
 
     def __exit__(self, typ, value, tb):
         """
         EXAMPLE::
         
-            sage: from sage.rings.polynomial.multi_polynomial_ideal import RedSBContext
+            sage: from sage.rings.polynomial.multi_polynomial_ideal import SingularDefaultContext
             sage: P.<a,b,c> = PolynomialRing(QQ,3, order='lex')
             sage: I = sage.rings.ideal.Katsura(P,3)
             sage: singular.option('noredTail')
             sage: singular.option('noredThrough')
             sage: Is = I._singular_()
-            sage: with RedSBContext(): rgb = Is.groebner()
+            sage: with SingularDefaultContext(): rgb = Is.groebner()
             sage: rgb
             84*c^4-40*c^3+c^2+c,
             7*b+210*c^3-79*c^2+3*c,
             7*a-420*c^3+158*c^2+8*c-7
         """
         self.singular.option("set",self.o)
-        self.libsingular_option_context.__exit__(typ,value,tb)
+        try:
+            self.singular.eval('degBound=%d'%self.bck_degBound)
+        except RuntimeError:
+            pass
+        try:
+            self.singular.eval('multBound=%d'%self.bck_multBound)
+        except RuntimeError:
+            pass
 
-def redSB(func):
+def singular_standard_options(func):
     """
     Decorator to force a reduced Singular groebner basis.
     
@@ -363,9 +430,9 @@ def redSB(func):
     """
     def wrapper(*args, **kwds):
         """
-        Execute function in ``RedSBContext``.
+        Execute function in ``SingularDefaultContext``.
         """
-        with RedSBContext():
+        with SingularDefaultContext():
             return func(*args, **kwds)
 
     from sage.misc.sageinspect import sage_getsource 
@@ -374,6 +441,36 @@ def redSB(func):
     wrapper.__doc__ = func.__doc__
     return wrapper
 
+def libsingular_standard_options(func):
+    """
+    Decorator to force a reduced Singular groebner basis.
+
+    TESTS::
+
+        sage: P.<a,b,c,d,e> = PolynomialRing(GF(127))
+        sage: J = sage.rings.ideal.Cyclic(P).homogenize()
+        sage: from sage.misc.sageinspect import sage_getsource
+        sage: "buchberger" in sage_getsource(J.interreduced_basis)
+        True
+
+    .. note::
+
+       This decorator is used automatically internally so the user
+       does not need to use it manually.
+    """
+    def wrapper(*args, **kwds):
+        """
+        Execute function in ``LibSingularDefaultContext``.
+        """
+        with LibSingularDefaultContext():
+            return func(*args, **kwds)
+
+    from sage.misc.sageinspect import sage_getsource
+    wrapper._sage_src_ = lambda: sage_getsource(func)
+    wrapper.__name__ = func.__name__
+    wrapper.__doc__ = func.__doc__
+    return wrapper
+
 class RequireField(MethodDecorator):
     """
     Decorator which throws an exception if a computation over a
@@ -608,7 +705,7 @@ class MPolynomialIdeal_singular_repr:
         I.plot()
 
     @require_field
-    @redSB
+    @libsingular_standard_options
     def complete_primary_decomposition(self, algorithm="sy"):
         r"""
         Return a list of primary ideals and their associated primes such
@@ -772,7 +869,6 @@ class MPolynomialIdeal_singular_repr:
         return [I for I, _ in self.complete_primary_decomposition(algorithm)]
 
     @require_field
-    @redSB
     def associated_primes(self, algorithm='sy'):
         r"""
         Return a list of the associated primes of primary ideals of
@@ -837,6 +933,8 @@ class MPolynomialIdeal_singular_repr:
         return [P for _,P in self.complete_primary_decomposition(algorithm)]
             
     @require_field
+    @singular_standard_options
+    @libsingular_standard_options
     def triangular_decomposition(self, algorithm=None, singular=singular_default):
         """
         Decompose zero-dimensional ideal ``self`` into triangular
@@ -1083,7 +1181,7 @@ class MPolynomialIdeal_singular_repr:
         else:
             return vd
 
-    @redSB
+    @singular_standard_options
     def _groebner_basis_singular(self, algorithm="groebner", *args, **kwds):
         """
         Return the reduced Groebner basis of this ideal. If the
@@ -1146,6 +1244,7 @@ class MPolynomialIdeal_singular_repr:
         S =  Sequence([R(S[i+1]) for i in range(len(S))], R, check=False, immutable=True)
         return S
 
+    @cached_method
     def _groebner_basis_singular_raw(self, algorithm="groebner", singular=singular_default, *args, **kwds):
         r"""
         Return a Groebner basis in Singular format.
@@ -1159,17 +1258,27 @@ class MPolynomialIdeal_singular_repr:
             b*d^4 - b + d^5 - d, b*c - b*d + c^2*d^4 + c*d - 2*d^2,
             b^2 + 2*b*d + d^2, a + b + c + d]
         """
-        try:
-            return self.__gb_singular
-        except AttributeError:
-            pass
-        # singular options are preserved by @redSB so we don't
-        # need to do that here too
-        for o,v in kwds.iteritems(): 
-            if v: 
-                singular.option(o) 
-            else: 
-                singular.option("no"+o)
+        #try:
+        #    return self.__gb_singular
+        #except AttributeError:
+        #    pass
+        # singular options are preserved by @singular_standard_options,
+        # so we don't eed to do that here too
+        from sage.libs.singular.option import _options_py_to_singular
+        S = self._singular_()   # for degBound, we need to ensure
+                                # that a ring is defined
+        for o,v in kwds.iteritems():
+            o = _options_py_to_singular.get(o,o)
+            if v:
+                if o in ['degBound','multBound']:
+                    singular.eval(o+'=%d'%v)
+                else:
+                    singular.option(o) 
+            else:
+                if o in ['degBound','multBound']:
+                    singular.eval(o+'=0')
+                else:
+                    singular.option("no"+o)
 
         if algorithm=="groebner":
             S = self._singular_().groebner()
@@ -1186,8 +1295,8 @@ class MPolynomialIdeal_singular_repr:
         self.__gb_singular = S
         return S
 
-    @redSB
-    def _groebner_basis_libsingular(self, algorithm="groebner", redsb=True, red_tail=True):
+    @libsingular_standard_options
+    def _groebner_basis_libsingular(self, algorithm="groebner", *args, **kwds):
         """
         Return the reduced Groebner basis of this ideal. If the
         Groebner basis for this ideal has been calculated before the
@@ -1243,9 +1352,13 @@ class MPolynomialIdeal_singular_repr:
 
         import sage.libs.singular
         groebner = sage.libs.singular.ff.groebner
+        from sage.all import get_verbose
 
-        opt['redSB'] = redsb
-        opt['redTail'] = red_tail
+        if get_verbose()>=2:
+            opt['prot'] = True
+        for name,value in kwds.iteritems():
+            if value is not None:
+                opt[name] = value
 
         T = self.ring().term_order()
         
@@ -1297,7 +1410,7 @@ class MPolynomialIdeal_singular_repr:
             self.__genus = Integer(genus(self))
             return self.__genus
 
-    @redSB
+    @libsingular_standard_options
     def intersection(self, other):
         """
         Return the intersection of the two ideals.
@@ -1333,7 +1446,7 @@ class MPolynomialIdeal_singular_repr:
         return R.ideal(K)
 
     @require_field
-    @redSB
+    @libsingular_standard_options
     def minimal_associated_primes(self):
         """
         OUTPUT:
@@ -1361,7 +1474,7 @@ class MPolynomialIdeal_singular_repr:
         return [R.ideal(J) for J in M]
 
     @require_field
-    @redSB
+    @libsingular_standard_options
     def radical(self):
         r"""
         The radical of this ideal.
@@ -1414,7 +1527,7 @@ class MPolynomialIdeal_singular_repr:
         return S.ideal(r)
 
     @require_field
-    @redSB
+    @libsingular_standard_options
     def integral_closure(self, p=0, r=True, singular=singular_default):
         """
         Let `I` = ``self``.
@@ -1441,7 +1554,7 @@ class MPolynomialIdeal_singular_repr:
             sage: I.integral_closure()
             [x^2, y^5, -x*y^3]
         
-        ALGORITHM: Use Singular
+        ALGORITHM: Use libSingular
         """
         R = self.ring()
         import sage.libs.singular
@@ -1479,7 +1592,6 @@ class MPolynomialIdeal_singular_repr:
         S = syz(self)
         return matrix(self.ring(), S)
 
-    @redSB
     def reduced_basis(self):
         r"""
         .. warning::
@@ -1523,7 +1635,8 @@ class MPolynomialIdeal_singular_repr:
         deprecation("This function is deprecated. It will be removed in a future release of Sage. Please use the interreduced_basis() function instead.")
         return self.interreduced_basis()
 
-    @redSB
+    @singular_standard_options
+    @libsingular_standard_options
     def interreduced_basis(self):
         r"""
         If this ideal is spanned by `(f_1, ..., f_n)` this method
@@ -1590,6 +1703,7 @@ class MPolynomialIdeal_singular_repr:
         return ret
 
     @cached_method
+    @singular_standard_options
     def basis_is_groebner(self, singular=singular_default):
         r"""
         Returns ``True`` if the generators of this ideal
@@ -1695,7 +1809,8 @@ class MPolynomialIdeal_singular_repr:
         return True
 
     @require_field
-    @redSB
+    @singular_standard_options
+    @libsingular_standard_options
     def transformed_basis(self, algorithm="gwalk", other_ring=None, singular=singular_default):
         """
         Returns a lex or ``other_ring`` Groebner Basis for this ideal.
@@ -1788,7 +1903,7 @@ class MPolynomialIdeal_singular_repr:
         else:
             raise TypeError, "Cannot convert basis with given algorithm"
 
-    @redSB
+    @libsingular_standard_options
     def elimination_ideal(self, variables):
         r"""
         Returns the elimination ideal this ideal with respect to the
@@ -1823,7 +1938,7 @@ class MPolynomialIdeal_singular_repr:
         Is = MPolynomialIdeal(R,self.groebner_basis())
         return MPolynomialIdeal(R, eliminate(Is, prod(variables)) )
 
-    @redSB
+    @libsingular_standard_options
     def quotient(self, J):
         r"""
         Given ideals `I` = ``self`` and `J` in the same polynomial
@@ -2405,18 +2520,21 @@ class MPolynomialIdeal( MPolynomialIdeal
                                         symmetry=symmetry, verbose=verbose)
 
     @cached_method
-    def groebner_basis(self, algorithm='', *args, **kwds):
+    def groebner_basis(self, algorithm='', deg_bound=None, mult_bound=None, *args, **kwds):
         """
-        Return the reduced Groebner basis of this ideal. A Groebner
-        basis `g_1,...,g_n` for an ideal `I` is a basis such that
-        `<LM(g_i)> = LM(I)`, i.e., the leading monomial ideal of
-        `I` is spanned by the leading terms of
-        `g_1,...,g_n`. Groebner bases are the key concept in
-        computational ideal theory in multivariate polynomial rings
-        which allows a variety of problems to be solved.
+        Return the reduced Groebner basis of this ideal.
+
+        A Groebner basis `g_1,...,g_n` for an ideal `I` is a
+        generating set such that `<LM(g_i)> = LM(I)`, i.e.,
+        the leading monomial ideal of `I` is spanned by the
+        leading terms of `g_1,...,g_n`. Groebner bases are
+        the key concept in computational ideal theory in
+        multivariate polynomial rings which allows a variety
+        of problems to be solved.
+
         Additionally, a *reduced* Groebner basis `G` is a unique
-        representation for the ideal `<G>` with respect to the chosen
-        monomial ordering.
+        representation for the ideal `<G>` with respect to the
+        chosen monomial ordering.
         
         INPUT:
         
@@ -2566,6 +2684,48 @@ class MPolynomialIdeal( MPolynomialIdeal
             sage: I.groebner_basis('magma:GroebnerBasis') # optional - magma
             [a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/21*c^3 + 1/84*c^2 + 1/84*c]
         
+        Singular and libSingular can compute Groebner basis with degree
+        restrictions::
+
+            sage: R.<x,y> = QQ[]
+            sage: I = R*[x^3+y^2,x^2*y+1]
+            sage: I.groebner_basis(algorithm='singular')
+            [x^3 + y^2, x^2*y + 1, y^3 - x]
+            sage: I.groebner_basis(algorithm='singular',deg_bound=2)
+            [x^3 + y^2, x^2*y + 1]
+            sage: I.groebner_basis()
+            [x^3 + y^2, x^2*y + 1, y^3 - x]
+            sage: I.groebner_basis(deg_bound=2)
+            [x^3 + y^2, x^2*y + 1]
+
+        In the case of libSingular, a protocol is printed, if the
+        verbosity level is at least 2, or if the argument ``prot``
+        is provided. For some reason, the protocol does not appear
+        during doctests, so, we skip the examples with protocol
+        output.
+        ::
+
+            sage: set_verbose(2)
+            sage: I = R*[x^3+y^2,x^2*y+1]
+            sage: I.groebner_basis()  # not tested
+            std in (0),(x,y),(dp(2),C)
+            [4294967295:2]3ss4s6
+            (S:2)--
+            product criterion:1 chain criterion:0
+            [x^3 + y^2, x^2*y + 1, y^3 - x]
+            sage: I.groebner_basis(prot=False)
+            [x^3 + y^2, x^2*y + 1, y^3 - x]
+            sage: set_verbose(0)
+            sage: I.groebner_basis(prot=True)  # not tested
+            std in (0),(x,y),(dp(2),C)
+            [4294967295:2]3ss4s6
+            (S:2)--
+            product criterion:1 chain criterion:0
+            [x^3 + y^2, x^2*y + 1, y^3 - x]
+
+        The list of available options is provided at
+        :class:`~sage.libs.singular.option.LibSingularOptions`.
+
         Groebner bases over `\ZZ` can be computed. ::
         
             sage: P.<a,b,c> = PolynomialRing(ZZ,3)
@@ -2648,10 +2808,10 @@ class MPolynomialIdeal( MPolynomialIdeal
 
         if algorithm is '':
             try:
-                gb = self._groebner_basis_libsingular("groebner", *args, **kwds)
+                gb = self._groebner_basis_libsingular("groebner", deg_bound=deg_bound, mult_bound=mult_bound, *args, **kwds)
             except (TypeError,NameError), msg: # conversion to Singular not supported
                 try:
-                    gb = self._groebner_basis_singular("groebner", *args, **kwds)
+                    gb = self._groebner_basis_singular("groebner", deg_bound=deg_bound, mult_bound=mult_bound, *args, **kwds)
                 except (TypeError,NameError), msg: # conversion to Singular not supported
                     if self.ring().term_order().is_global() and is_IntegerModRing(self.ring().base_ring()) and not self.ring().base_ring().is_field():
                         verbose("Warning: falling back to very slow toy implementation.", level=0)
@@ -2672,9 +2832,9 @@ class MPolynomialIdeal( MPolynomialIdeal
                             raise TypeError, "Local/unknown orderings not supported by 'toy_buchberger' implementation."
 
         elif algorithm.startswith('singular:'):
-            gb = self._groebner_basis_singular(algorithm[9:])
+            gb = self._groebner_basis_singular(algorithm[9:], deg_bound=deg_bound, mult_bound=mult_bound, *args, **kwds)
         elif algorithm.startswith('libsingular:'):
-            gb = self._groebner_basis_libsingular(algorithm[len('libsingular:'):], *args, **kwds)
+            gb = self._groebner_basis_libsingular(algorithm[len('libsingular:'):], deg_bound=deg_bound, mult_bound=mult_bound, *args, **kwds)
         elif algorithm == 'macaulay2:gb':
             gb = self._groebner_basis_macaulay2(*args, **kwds)
         elif algorithm == 'magma:GroebnerBasis':
