Index: sageSLZ.sage
===================================================================
--- sageSLZ.sage	(revision 124)
+++ sageSLZ.sage	(revision 125)
@@ -97,11 +97,14 @@
     NOTE::
         When number >= 2^(emax+1), we return the "fake" binade 
         [2^(emax+1), +infinity]. Ditto for number <= -2^(emax+1)
-        with interval [-infinity, -2^(emax+1)].
+        with interval [-infinity, -2^(emax+1)]. We want to distinguish
+        this case from that of "really" invalid arguments.
         
     """
     # Check the parameters.
-    # RealNumbers only.
+    # RealNumbers or RealNumber offspring only.
+    # The execption construction is necessary since not all objects have
+    # the mro() method. sage.rings.real_mpfr.RealNumber do.
     try:
         classTree = [number.__class__] + number.mro()
         if not sage.rings.real_mpfr.RealNumber in classTree:
@@ -116,19 +119,19 @@
         return None
     precision = number.precision()
     RF  = RealField(precision)
+    if number == 0:
+        return (RF(0),RF(2^(emin)) - RF(2^(emin-precision)))
     # A more precise RealField is needed to avoid unwanted rounding effects
     # when computing number.log2().
     RRF = RealField(max(2048, 2 * precision))
     # number = 0 special case, the binade bounds are 
     # [0, 2^emin - 2^(emin-precision)]
-    if number == 0:
-        return (RF(0),RF(2^(emin)) - RF(2^(emin-precision)))
     # Begin general case
     l2 = RRF(number).abs().log2()
     # Another special one: beyond largest representable -> "Fake" binade.
     if l2 >= emax + 1:
         if number > 0:
-            return (RF(2^(emax+1)), RRR(+infinity) )
+            return (RF(2^(emax+1)), RF(+infinity) )
         else:
             return (RF(-infinity), -RF(2^(emax+1)))
     offset = int(l2)
@@ -196,9 +199,6 @@
     A list of bivariate integer polynomial obtained using the Coppersmith
     algorithm. The polynomials correspond to the rows of the LLL-reduce
     reduced base that comply with the Coppersmith condition.
-    
-    TODO::
-    Full rewrite, this is barely a draft.
     """
     # Arguments check.
     if iBound == 0 or tBound == 0:
@@ -235,7 +235,7 @@
     reducedMatrix = matrixToReduce.LLL(fp='fp')
     isLLLReduced  = reducedMatrix.is_LLL_reduced()
     if not isLLLReduced:
-        return ()
+        return set()
     monomialsCount     = len(knownMonomials)
     monomialsCountSqrt = sqrt(monomialsCount)
     #print "Monomials count:", monomialsCount, monomialsCountSqrt.n()
@@ -247,7 +247,7 @@
         l2Norm = row.norm(2)
         if (l2Norm * monomialsCountSqrt) < nAtAlpha:
             #print (l2Norm * monomialsCountSqrt).n()
-            print l2Norm.n()
+            #print l2Norm.n()
             ccReducedPolynomial = \
                 slz_compute_reduced_polynomial(row,
                                                knownMonomials,
@@ -258,11 +258,13 @@
             if not ccReducedPolynomial is None:
                 ccReducedPolynomialsList.append(ccReducedPolynomial)
         else:
-            print l2Norm.n() , ">", nAtAlpha
+            #print l2Norm.n() , ">", nAtAlpha
             pass
     if len(ccReducedPolynomialsList) < 2:
-        print "***Less than 2 Coppersmith condition compliant vectors.***"
+        print "Less than 2 Coppersmith condition compliant vectors."
         return ()
+    
+    #print ccReducedPolynomialsList
     return ccReducedPolynomialsList
 # End slz_compute_coppersmith_reduced_polynomials
 
@@ -286,60 +288,14 @@
     # Whatever the 2 variables are actually called, we call them
     # 'i' and 't' in all the variable names.
     (iVariable, tVariable) = inputPolynomial.variables()[:2]
-    #print polyVars[0], type(polyVars[0])
-    initialPolynomial = inputPolynomial.subs({iVariable:iVariable * iBound,
-                                              tVariable:tVariable * tBound})
-    polynomialsList = \
-        spo_polynomial_to_polynomials_list_5(initialPolynomial,
-                                             alpha,
-                                             N,
-                                             iBound,
-                                             tBound,
-                                             0)
-    #print "Polynomials list:", polynomialsList
-    ## Building the proto matrix.
-    knownMonomials = []
-    protoMatrix    = []
-    for poly in polynomialsList:
-        spo_add_polynomial_coeffs_to_matrix_row(poly,
-                                                knownMonomials,
-                                                protoMatrix,
-                                                0)
-    matrixToReduce = spo_proto_to_row_matrix(protoMatrix)
-    #print matrixToReduce
-    ## Reduction and checking.
-    reducedMatrix = matrixToReduce.LLL(fp='fp')
-    isLLLReduced  = reducedMatrix.is_LLL_reduced()
-    if not isLLLReduced:
-        return set()
-    monomialsCount     = len(knownMonomials)
-    monomialsCountSqrt = sqrt(monomialsCount)
-    #print "Monomials count:", monomialsCount, monomialsCountSqrt.n()
-    #print reducedMatrix
-    ## Check the Coppersmith condition for each row and build the reduced 
-    #  polynomials.
-    ccReducedPolynomialsList = []
-    for row in reducedMatrix.rows():
-        l2Norm = row.norm(2)
-        if (l2Norm * monomialsCountSqrt) < nAtAlpha:
-            #print (l2Norm * monomialsCountSqrt).n()
-            #print l2Norm.n()
-            ccReducedPolynomial = \
-                slz_compute_reduced_polynomial(row,
-                                               knownMonomials,
-                                               iVariable,
-                                               iBound,
-                                               tVariable,
-                                               tBound)
-            if not ccReducedPolynomial is None:
-                ccReducedPolynomialsList.append(ccReducedPolynomial)
-        else:
-            #print l2Norm.n() , ">", nAtAlpha
-            pass
-    if len(ccReducedPolynomialsList) < 2:
-        print "Less than 2 Coppersmith condition compliant vectors."
-        return set()
-    #print ccReducedPolynomialsList
+    ccReducedPolynomialsList = \
+        slz_compute_coppersmith_reduced_polynomials (inputPolynomial,
+                                                     alpha,
+                                                     N,
+                                                     iBound,
+                                                     tBound)
+    if len(ccReducedPolynomialsList) == 0:
+        return set()   
     ## Create the valid (poly1 and poly2 are algebraically independent) 
     # resultant tuples (poly1, poly2, resultant(poly1, poly2)).
     # Try to mix and match all the polynomial pairs built from the 
@@ -390,6 +346,85 @@
     return polynomialRootsSet
 # End slz_compute_integer_polynomial_modular_roots.
 #
+def slz_compute_integer_polynomial_modular_roots_2(inputPolynomial,
+                                                 alpha,
+                                                 N,
+                                                 iBound,
+                                                 tBound):
+    """
+    For a given set of arguments (see below), compute the polynomial modular 
+    roots, if any.
+    This version differs in the way resultants are computed.   
+    """
+    # Arguments check.
+    if iBound == 0 or tBound == 0:
+        return set()
+    # End arguments check.
+    nAtAlpha = N^alpha
+    ## Building polynomials for matrix.
+    polyRing   = inputPolynomial.parent()
+    # Whatever the 2 variables are actually called, we call them
+    # 'i' and 't' in all the variable names.
+    (iVariable, tVariable) = inputPolynomial.variables()[:2]
+    #print polyVars[0], type(polyVars[0])
+    ccReducedPolynomialsList = \
+        slz_compute_coppersmith_reduced_polynomials (inputPolynomial,
+                                                     alpha,
+                                                     N,
+                                                     iBound,
+                                                     tBound)
+    if len(ccReducedPolynomialsList) == 0:
+        return set()   
+    ## Create the valid (poly1 and poly2 are algebraically independent) 
+    # resultant tuples (poly1, poly2, resultant(poly1, poly2)).
+    # Try to mix and match all the polynomial pairs built from the 
+    # ccReducedPolynomialsList to obtain non zero resultants.
+    resultantsInTTuplesList = []
+    for polyOuterIndex in xrange(0, len(ccReducedPolynomialsList)-1):
+        for polyInnerIndex in xrange(polyOuterIndex+1, 
+                                     len(ccReducedPolynomialsList)):
+            # Compute the resultant in resultants in the
+            # first variable (is it the optimal choice?).
+            resultantInT = \
+               ccReducedPolynomialsList[polyOuterIndex].resultant(ccReducedPolynomialsList[polyInnerIndex],
+                                                                  ccReducedPolynomialsList[0].parent(str(tVariable)))
+            #print "Resultant", resultantInT
+            # Test algebraic independence.
+            if not resultantInT.is_zero():
+                resultantsInTTuplesList.append((ccReducedPolynomialsList[polyOuterIndex],
+                                                 ccReducedPolynomialsList[polyInnerIndex],
+                                                 resultantInT))
+    # If no non zero resultant was found: we can't get no algebraically 
+    # independent polynomials pair. Give up!
+    if len(resultantsInTTuplesList) == 0:
+        return set()
+    #print resultantsInITuplesList
+    # Compute the roots.
+    Zi = ZZ[str(iVariable)]
+    Zt = ZZ[str(tVariable)]
+    polynomialRootsSet = set()
+    # First, solve in the second variable since resultants are in the first
+    # variable.
+    for resultantInTTuple in resultantsInTTuplesList:
+        iRootsList = Zi(resultantInTTuple[2]).roots()
+        # For each iRoot, compute the corresponding tRoots and check 
+        # them in the input polynomial.
+        for iRoot in iRootsList:
+            #print "iRoot:", iRoot
+            # Roots returned by root() are (value, multiplicity) tuples.
+            tRootsList = \
+                Zt(resultantInTTuple[0].subs({resultantInTTuple[0].variables()[0]:iRoot[0]})).roots()
+            print tRootsList
+            # The tRootsList can be empty, hence the test.
+            if len(tRootsList) != 0:
+                for tRoot in tRootsList:
+                    polyEvalModN = inputPolynomial(iRoot[0],tRoot[0]) / N
+                    # polyEvalModN must be an integer.
+                    if polyEvalModN == int(polyEvalModN):
+                        polynomialRootsSet.add((iRoot[0],tRoot[0]))
+    return polynomialRootsSet
+# End slz_compute_integer_polynomial_modular_roots_2.
+#
 def slz_compute_polynomial_and_interval(functionSo, degreeSo, lowerBoundSa, 
                                         upperBoundSa, approxPrecSa, 
                                         sollyaPrecSa=None):
@@ -482,10 +517,11 @@
                                     var2,
                                     var2Bound):
     """
-    Compute a polynomial from a reduced matrix row.
+    Compute a polynomial from a single reduced matrix row.
     This function was introduced in order to avoid the computation of the
-    polynomials (even those built from rows that do no verify the Coppersmith
-    condition.
+    all the polynomials  from the full matrix (even those built from rows 
+    that do no verify the Coppersmith condition) as this may involves 
+    expensive operations over (large) integer.
     """
     ## Check arguments.
     if len(knownMonomials) == 0:
