Index: sageSLZ.sage
===================================================================
--- sageSLZ.sage	(revision 171)
+++ sageSLZ.sage	(revision 172)
@@ -95,12 +95,12 @@
     2^m <= number < 2^(m+1). If number == 0 return None.
     """
     # Checking the parameter.
-    # The exception construction is used to detect if numbre is a RealNumber
+    # The exception construction is used to detect if number is a RealNumber
     # since not all numbers have
     # the mro() method. sage.rings.real_mpfr.RealNumber do.
     try:
         classTree = [number.__class__] + number.mro()
-        # If the number is not a RealNumber (of offspring thereof) try
+        # If the number is not a RealNumber (or offspring thereof) try
         # to transform it.
         if not sage.rings.real_mpfr.RealNumber in classTree:
             numberAsRR = RR(number)
@@ -624,7 +624,7 @@
     scaled back by dividing by the "right" powers of the variables bounds.
     
     The elements in knownMonomials must be of the "right" polynomial type.
-    They set the polynomial type of the output polynomials list.
+    They set the polynomial type of the output polynomials in list.
     @param reducedMatrix:  the reduced matrix as output from LLL;
     @param kwnonMonomials: the ordered list of the monomials used to
                            build the polynomials;
@@ -1055,6 +1055,138 @@
     return((polynomialSa, polynomialChangedVarSa, intervalSa, centerSa, errorSa))
     # End slz_interval_and_polynomial_to_sage
 
+def slz_is_htrn(argument, function, targetAccuracy, targetRF = None, 
+            targetPlusOnePrecRF = None, quasiExactRF = None):
+    """
+      Check if an element (argument) of the domain of function (function)
+      yields a HTRN case (rounding to next) for the target precision 
+      (as impersonated by targetRF) for a given accuracy (targetAccuraty). 
+    """
+    ## Arguments filtering. TODO: filter the first argument for consistence.
+    ## If no target accuracy is given, assume it is that of the argument.
+    if targetRF is None:
+        targetRF = argument.parent()
+    ## Ditto for the real field holding the midpoints.
+    if targetPlusOnePrecRF is None:
+        targetPlusOnePrecRF = RealField(targetRF.prec()+1)
+    ## Create a high accuracy RealField
+    if quasiExactRF is None:
+        quasiExactRF = RealField(1536)
+        
+    exactArgument                 = quasiExactRF(argument)
+    quasiExactValue               = function(exactArgument)
+    roundedValue                  = targetRF(quasiExactValue)
+    roundedValuePrecPlusOne       = targetPlusOnePrecRF(roundedValue)
+    # Upper midpoint.
+    roundedValuePrecPlusOneNext   = roundedValuePrecPlusOne.nextabove()
+    # Lower midpoint.
+    roundedValuePrecPlusOnePrev   = roundedValuePrecPlusOne.nextbelow()
+    binade                        = slz_compute_binade(roundedValue)
+    binadeCorrectedTargetAccuracy = targetAccuracy * 2^binade
+    #print "Argument:", argument
+    #print "f(x):", roundedValue, binade, floor(binade), ceil(binade)
+    #print "binadeCorrectedTargetAccuracy:", \
+    #  binadeCorrectedTargetAccuracy.n(prec=100)
+    #print "binadeCorrectedTargetAccuracy:", \
+    #  binadeCorrectedTargetAccuracy.n(prec=100).str(base=2)
+    #print "Upper midpoint:", \
+    #  roundedValuePrecPlusOneNext.n(prec=targetPlusOnePrecRF.prec()).str(base=2)
+    #print "Rounded value :", \
+    #  roundedValuePrecPlusOne.n(prec=targetPlusOnePrecRF.prec()).str(base=2), \
+    #  roundedValuePrecPlusOne.ulp().n(prec=2).str(base=2)
+    #print "QuasiEx value :", quasiExactValue.n(prec=250).str(base=2)
+    #print "Lower midpoint:", \
+    #  roundedValuePrecPlusOnePrev.n(prec=targetPlusOnePrecRF.prec()).str(base=2)
+    ## Begining of the general case : check with the midpoint with 
+    #  greatest absolute value.
+    if quasiExactValue > 0:
+        if abs(quasiExactRF(roundedValuePrecPlusOneNext) - quasiExactValue) <\
+           binadeCorrectedTargetAccuracy:
+            #print "Too close to the upper midpoint: ", \ 
+            abs(quasiExactRF(roundedValuePrecPlusOneNext) - quasiExactValue).n(prec=100)
+            #print argument.n().str(base=16, \
+            #  no_sci=False)
+            #print "Lower midpoint:", \
+            #  roundedValuePrecPlusOnePrev.n(prec=targetPlusOnePrecRF.prec()).str(base=2)
+            #print "Value         :", \
+            #  quasiExactValue.n(prec=200).str(base=2)
+            #print "Upper midpoint:", \
+            #  roundedValuePrecPlusOneNext.n(prec=targetPlusOnePrecRF.prec()).str(base=2)
+            #print
+            return True
+    else:
+        if abs(quasiExactRF(roundedValuePrecPlusOnePrev) - quasiExactValue) < \
+           binadeCorrectedTargetAccuracy:
+            #print "Too close to the upper midpoint: ", \
+            #  abs(quasiExactRF(roundedValuePrecPlusOneNext) - quasiExactValue).n(prec=100)
+            #print argument.n().str(base=16, \
+            #  no_sci=False)
+            #print "Lower midpoint:", \
+            #  roundedValuePrecPlusOnePrev.n(prec=targetPlusOnePrecRF.prec()).str(base=2)
+            #print "Value         :", \
+            #  quasiExactValue.n(prec=200).str(base=2)
+            #print "Upper midpoint:", \
+            #  roundedValuePrecPlusOneNext.n(prec=targetPlusOnePrecRF.prec()).str(base=2)
+            #print
+            return True
+#2345678901234567890123456789012345678901234567890123456789012345678901234567890
+    ## For the midpoint of smaller absolute value, 
+    #  split cases with the powers of 2.
+    if sno_abs_is_power_of_two(roundedValue):
+        if quasiExactValue > 0:        
+            if abs(quasiExactRF(roundedValuePrecPlusOnePrev) - quasiExactValue) <\
+               binadeCorrectedTargetAccuracy / 2:
+                #print "Lower midpoint:", \
+                #  roundedValuePrecPlusOnePrev.n(prec=targetPlusOnePrecRF.prec()).str(base=2)
+                #print "Value         :", \
+                #  quasiExactValue.n(prec=200).str(base=2)
+                #print "Upper midpoint:", \
+                #  roundedValuePrecPlusOneNext.n(prec=targetPlusOnePrecRF.prec()).str(base=2)
+                #print
+                return True
+        else:
+            if abs(quasiExactRF(roundedValuePrecPlusOneNext) - quasiExactValue) < \
+              binadeCorrectedTargetAccuracy / 2:
+                #print "Lower midpoint:", \
+                #  roundedValuePrecPlusOnePrev.n(prec=targetPlusOnePrecRF.prec()).str(base=2)
+                #print "Value         :", 
+                #  quasiExactValue.n(prec=200).str(base=2)
+                #print "Upper midpoint:", 
+                #  roundedValuePrecPlusOneNext.n(prec=targetPlusOnePrecRF.prec()).str(base=2)
+                #print
+                return True
+#2345678901234567890123456789012345678901234567890123456789012345678901234567890
+    else: ## Not a power of 2, regular comparison with the midpoint of 
+          #  smaller absolute value.
+        if quasiExactValue > 0:        
+            if abs(quasiExactRF(roundedValuePrecPlusOnePrev) - quasiExactValue) < \
+              binadeCorrectedTargetAccuracy:
+                #print "Lower midpoint:", \
+                #  roundedValuePrecPlusOnePrev.n(prec=targetPlusOnePrecRF.prec()).str(base=2)
+                #print "Value         :", \
+                #  quasiExactValue.n(prec=200).str(base=2)
+                #print "Upper midpoint:", \
+                #  roundedValuePrecPlusOneNext.n(prec=targetPlusOnePrecRF.prec()).str(base=2)
+                #print
+                return True
+        else: # quasiExactValue <= 0
+            if abs(quasiExactRF(roundedValuePrecPlusOneNext) - quasiExactValue) < \
+              binadeCorrectedTargetAccuracy:
+                #print "Lower midpoint:", \
+                #  roundedValuePrecPlusOnePrev.n(prec=targetPlusOnePrecRF.prec()).str(base=2)
+                #print "Value         :", \
+                #  quasiExactValue.n(prec=200).str(base=2)
+                #print "Upper midpoint:", \
+                #  roundedValuePrecPlusOneNext.n(prec=targetPlusOnePrecRF.prec()).str(base=2)
+                #print
+                return True
+    #print "distance to the upper midpoint:", \
+    #  abs(quasiExactRF(roundedValuePrecPlusOneNext) - quasiExactValue).n(prec=100).str(base=2)
+    #print "distance to the lower midpoint:", \
+    #  abs(quasiExactRF(roundedValuePrecPlusOnePrev) - quasiExactValue).n(prec=100).str(base=2)
+    return False
+# End slz_is_htrn
+
 def slz_rat_poly_of_int_to_poly_for_coppersmith(ratPolyOfInt, 
                                                 precision,
                                                 targetHardnessToRound,
