# HG changeset patch
# User Martin Albrecht <martinralbrecht@googlemail.com>
# Date 1294833697 0
# Node ID a6bf54ca02cfed04282f31c05a63ad530a35791d
# Parent  e561c6d981cbc5abdd1f351ed5aaec858aa586a4
eliminate_linear_variables bugfix + feature enhancement (#10600)

diff -r e561c6d981cb -r a6bf54ca02cf sage/crypto/mq/mpolynomialsystem.py
--- a/sage/crypto/mq/mpolynomialsystem.py	Tue Jan 11 12:00:17 2011 +0000
+++ b/sage/crypto/mq/mpolynomialsystem.py	Wed Jan 12 12:01:37 2011 +0000
@@ -1278,7 +1278,7 @@
     #    format MiniSAT et al. can understand.
     #    """
     #    raise NotImplemented
-    def eliminate_linear_variables(self, maxlength=3, skip=lambda lm,tail: False):
+    def eliminate_linear_variables(self, maxlength=3, skip=lambda lm,tail: False, return_reductors=False):
         """
         Return a new system where "linear variables" are eliminated.
 
@@ -1295,6 +1295,10 @@
           ``False``. The two parameters are the leading term and the
           tail of a polynomial (default: ``lambda lm,tail: False``).
 
+        - ``return_reductors`` - if ``True`` the list of polynomials
+          with linear leading terms which were used for reduction is
+          also returned (default: ``False``).
+
         EXAMPLE::
         
             sage: B.<a,b,c,d> = BooleanPolynomialRing()
@@ -1306,6 +1310,16 @@
             sage: F.eliminate_linear_variables(skip=lambda lm,tail: str(lm)=='a').gens()
             (a + c + d, a*c + a*d + a + c, c*d + c)
 
+        The list of reductors can be requested by setting 'return_reductors' to ``True``::
+
+            sage: B.<a,b,c,d> = BooleanPolynomialRing()
+            sage: F = mq.MPolynomialSystem([a + b + d, a + b + c])
+            sage: F,R = F.eliminate_linear_variables(return_reductors=True)
+            sage: F.gens()
+            (c + d,)
+            sage: R.gens()
+            (a + b + d,)
+
         .. note:: 
           
             This is called "massaging" in [CBJ07]_.
@@ -1333,6 +1347,8 @@
      
         F = self
 
+        elim = []
+
         while True: 
             linear = []
             higher = []
@@ -1351,13 +1367,18 @@
                 else:
                     higher.append(f)
 
-            if linear == []:
+            if not linear:
+                break
+            if not higher:
+                higher = linear
                 break
 
             assert len(set(linear)) == len(linear)
 
             rb = ll_encode(linear)
 
+            elim.extend(linear)
+
             F = []
 
             for f in linear:
@@ -1373,7 +1394,12 @@
                 print ".",
         if get_verbose() > 0:
             print
-        return MPolynomialSystem(R, higher)
+
+        ret = MPolynomialSystem(R, higher)
+        if return_reductors:
+            return ret, MPolynomialSystem(R, elim)
+        else:
+            return ret
 
     def _groebner_strategy(self):
         """
