Index: pobysoPythonSage/src/pobyso.py
===================================================================
--- pobysoPythonSage/src/pobyso.py	(revision 208)
+++ pobysoPythonSage/src/pobyso.py	(revision 209)
@@ -1,4 +1,5 @@
 """
+@file pobyso.py
 Actual functions to use in Sage
 ST 2012-11-13
 
@@ -228,22 +229,18 @@
 def pobyso_constant_sa_so(rnArgSa, precisionSa=None):
     """
     Create a Sollya constant from a Sage RealNumber.
+    The sollya_lib_constant() function creates a constant
+    with the same precision as the source.
     """
-    # Precision stuff
-    if precisionSa is None:
-        precisionSa = rnArgSa.parent().precision()
-    currentSollyaPrecisionSo = sollya_lib_get_prec()
-    currentSollyaPrecisionSa = \
-        pobyso_constant_from_int(currentSollyaPrecisionSo)
+    ## Precision stuff. If one wants to change precisions,
+    #  everything takes place in Sage. That only makes
+    #  sense if one wants to reduce the precision.
+    if not precisionSa is None:
+        RRR = RealField(precisionSa)
+        rnArgSa = RRR(rnArgSa)
+    #print rnArgSa, rnArgSa.precision()
     # Sollya constant creation takes place here.
-    if precisionSa > currentSollyaPrecisionSa:
-        pobyso_set_prec_sa_so(precisionSa)
-        constantSo = sollya_lib_constant(get_rn_value(rnArgSa))
-        pobyso_set_prec_so_so(currentSollyaPrecisionSo)
-    else:
-        constantSo = sollya_lib_constant(get_rn_value(rnArgSa))
-    sollya_lib_clear_obj(currentSollyaPrecisionSo)
-    return constantSo
+    return sollya_lib_constant(get_rn_value(rnArgSa))
 # End pobyso_constant_sa_so
      
 def pobyso_constant_0_sa_so():
@@ -285,46 +282,108 @@
     return(constSa.value)
 # End pobyso_constant_from_int_so_sa
 
-def pobyso_constant_from_mpq_sa_so(rationalSa, precision = None):
+def pobyso_constant_from_mpq_sa_so(rationalSa):
     """
     Make a Sollya constant from Sage rational.
-    A bit convoluted to take into account precision and the fact
-    that mpq constants in Sollya a non-evaluated expressions.
-    Function building and evaluation is needed to make it a "real"
-    evaluated constant.
+    The Sollya constant is an unevaluated expression.
+    Hence no precision argument is needed.
+    It is better to leave this way since Sollya has its own
+    optimized evaluation mecanism that tries very hard to
+    return exact values or at least faithful ones.
     """
-    ## Deal with precision stuff.
-    curPrecSa = None
-    curPrecSo = None
-    if not precision is None:
-        curPrecSo = pobyso_get_prec_so()
-        curPrecSaSa = c_int(0)
-        sollya_lib_get_constant_as_int(byref(curPrecSaSa), curPrecSo)
-        curPrecSa = int(curPrecSaSa.value)
-        if curPrecSa != precision:
-            pobyso_set_prec_sa_so(precision)
-    ## In Sollya mpq constants are non-evaluated expressions.
-    #  We must force evaluation.
-    zeroSo    = pobyso_constant_0_sa_so()
-    oneSo     = pobyso_constant_1_sa_so()
     ratExprSo = \
         sollya_lib_constant_from_mpq(sgmp_get_rational_value(rationalSa))
-    addExprSo = sollya_lib_build_function_add(zeroSo, ratExprSo)
-    constSo   = sollya_lib_evaluate(addExprSo,oneSo)
-    ## Clears expression and arguments, as the former was created with a
-    #  "build" variant.
-    sollya_lib_clear_obj(addExprSo)
-    sollya_lib_clear_obj(oneSo)
-    if curPrecSa != precision:
-        pobyso_set_prec_so_so(curPrecSo)
-        sollya_lib_clear_obj(curPrecSo)
-    return constSo
+    return ratExprSo
 # End pobyso_constant_from_mpq_sa_so.
 
+def pobyso_constant_sollya_prec_sa_so(rnArgSa):
+    """
+    Create a Sollya constant from a Sage RealNumber at the
+    current precision in Sollya.
+    """
+    currentSollyaPrecSa = pobyso_get_prec_so_sa()
+    return pobyso_constant_sa_so(rnArgSa, currentSollyaPrecSa)
+# End pobyso_constant_sollya_prec_sa_so
+     
 def pobyso_error_so():
     return sollya_lib_error(None)
 # End pobyso_error().
 
+def pobyso_float_poly_sa_so(polySa, precSa = None):
+    """
+    Create a Sollya polynomial from a Sage RealField polynomial.
+    """
+    ## TODO: filter arguments.
+    ## Precision. If a precision is given, convert the polynomial
+    #  into the right polynomial field. If not convert it straight
+    #  to Sollya.
+    if not precSa is None:
+        RRR = RealField(precSa)
+        ## Create a Sage polynomial in the "right" precision.
+        P_RRR = RRR[polySa.variables()[0]]
+        polyFloatSa = P_RRR(polySa)
+    else:
+        polyFloatSa = polySa
+        precSa = polySa.parent().base_ring().precision()
+    ## Get exponents and coefficients.
+    exponentSa = polyFloatSa.exponents()
+    coefficientsSa = polyFloatSa.coefficients()
+    ## Build the polynomial.
+    polySo = None
+    for coefficientSa, exponentSa in zip(coefficientsSa, exponentSa):
+        #print coefficientSa.n(prec=precSa), exponentSa
+        coefficientSo = \
+            pobyso_constant_sa_so(coefficientSa)
+        #pobyso_autoprint(coefficientSo)
+        exponentSo = \
+            pobyso_constant_from_int_sa_so(exponentSa)
+        #pobyso_autoprint(exponentSo)
+        monomialSo = sollya_lib_build_function_pow(
+                       sollya_lib_build_function_free_variable(),
+                       exponentSo)
+        if polySo is None:
+            polySo = sollya_lib_build_function_mul(coefficientSo,
+                                                   monomialSo)
+        else:
+            polyTermSo = sollya_lib_build_function_mul(coefficientSo,
+                                                       monomialSo)
+            polySo = sollya_lib_build_function_add(polySo, polyTermSo)
+    return polySo
+# End pobyso_float_poly_sa_so    
+
+def pobyso_float_poly_so_sa(polySo, realFieldSa=None):
+    """
+    Convert a Sollya polynomial into a Sage floating-point polynomial.
+    We assume that the polynomial is in canonical form.
+    If no realField is given, a RealField corresponding to the maximum 
+    precision of the coefficients is internally computed.
+    The real field is not returned but can be easily retrieved from 
+    the polynomial itself.
+    ALGORITHM:
+    - (optional) compute the RealField of the coefficients;
+    - convert the Sollya expression into a Sage expression;
+    - convert the Sage expression into a Sage polynomial
+    TODO: the canonical thing for the polynomial.
+    """    
+    if realFieldSa is None:
+        expressionPrecSa = pobyso_get_max_prec_of_exp_so_sa(polySo)
+        realFieldSa      = RealField(expressionPrecSa)
+    #print "Sollya expression before...",
+    #pobyso_autoprint(polySo)
+
+    expressionSa = pobyso_get_sage_exp_from_sollya_exp_so_sa(polySo,
+                                                             realFieldSa)
+    #print "...Sollya expression after.",
+    #pobyso_autoprint(polySo)
+    polyVariableSa = expressionSa.variables()[0]
+    polyRingSa     = realFieldSa[str(polyVariableSa)]
+    #print polyRingSa
+    # Do not use the polynomial(expressionSa, ring=polyRingSa) form!
+    polynomialSa = polyRingSa(expressionSa)
+    return polynomialSa
+# End pobyso_float_poly_so_sa
+
+    
 def pobyso_function_type_as_string(funcType):
     """ Legacy function. See pobyso_function_type_as_string_so_sa. """
     return(pobyso_function_type_as_string_so_sa(funcType))
@@ -427,7 +486,8 @@
 
 def pobyso_get_constant(rnArgSa, constSo):
     """ Legacy function. See pobyso_get_constant_so_sa. """
-    return(pobyso_get_constant_so_sa(rnArgSa, constSo))
+    return pobyso_get_constant_so_sa(rnArgSa, constSo)
+# End pobyso_get_constant
 
 def pobyso_get_constant_so_sa(rnArgSa, constSo):
     """
@@ -435,8 +495,13 @@
     rnArg must already exist and belong to some RealField.
     We assume that constSo points to a Sollya constant.
     """
-    return(sollya_lib_get_constant(get_rn_value(rnArgSa), constSo))
-    
+    outcome = sollya_lib_get_constant(get_rn_value(rnArgSa), constSo)
+    if outcome == 0: # Failure because constSo is not a constant expression.
+        return None
+    else:
+        return outcome
+# End  pobyso_get_constant_so_sa
+   
 def pobyso_get_constant_as_rn(ctExpSo):
     """ 
     Legacy function. See pobyso_get_constant_as_rn_so_sa. 
@@ -449,18 +514,26 @@
     The precision of the floating-point number returned is that of the Sollya
     constant.
     """
-    precisionSa  = pobyso_get_prec_of_constant_so_sa(constExpSo) 
+    precisionSa  = pobyso_get_prec_of_constant_so_sa(constExpSo)
+    ## If the expression can not be exactly converted, None is returned.
+    #  In this case opt for the Sollya current expression.
+    if precisionSa is None:
+        precisionSa = pobyso_get_prec_so_sa()
     RRRR = RealField(precisionSa)
     rnSa = RRRR(0)
-    sollya_lib_get_constant(get_rn_value(rnSa), constExpSo)
-    return(rnSa)
+    outcome = sollya_lib_get_constant(get_rn_value(rnSa), constExpSo)
+    if outcome == 0:
+        return None
+    else:
+        return rnSa
 # End pobyso_get_constant_as_rn_so_sa
 
 def pobyso_get_constant_as_rn_with_rf(ctExp, realField):
     """ 
     Legacy function. See pobyso_get_constant_as_rn_with_rf_so_sa.
     """
-    return(pobyso_get_constant_as_rn_with_rf_so_sa(ctExp, realField))
+    return pobyso_get_constant_as_rn_with_rf_so_sa(ctExp, realField)
+# End pobyso_get_constant_as_rn_with_rf
     
 def pobyso_get_constant_as_rn_with_rf_so_sa(ctExpSo, realFieldSa = None):
     """
@@ -470,20 +543,15 @@
     Otherwise is is that of the real field. Hence rounding may happen.
     """
     if realFieldSa is None:
-        sollyaPrecSa = pobyso_get_prec_of_constant_so_sa(ctExpSo)
-        realFieldSa = RealField(sollyaPrecSa)
+        return pobyso_get_constant_as_rn_so_sa(ctExpSo)
     rnSa = realFieldSa(0)
-    sollya_lib_get_constant(get_rn_value(rnSa), ctExpSo)
-    return(rnSa)
+    outcome = sollya_lib_get_constant(get_rn_value(rnSa), ctExpSo)
+    if outcome == 0:
+        return None
+    else:
+        return rnSa
 # End pobyso_get_constant_as_rn_with_rf_so_sa
 
-def pobyso_get_float_poly_sa_so(polySa, realFieldSa=None):
-    """
-    Create a Sollya polynomial from a Sage polynomial.
-    """
-    pass
-# End get_float_poly_sa_so.
-    
 def pobyso_get_free_variable_name():
     """ 
     Legacy function. See pobyso_get_free_variable_name_so_sa.
@@ -491,7 +559,7 @@
     return(pobyso_get_free_variable_name_so_sa())
 
 def pobyso_get_free_variable_name_so_sa():
-    return(sollya_lib_get_free_variable_name())
+    return sollya_lib_get_free_variable_name()
     
 def pobyso_get_function_arity(expressionSo):
     """ 
@@ -502,7 +570,7 @@
 def pobyso_get_function_arity_so_sa(expressionSo):
     arity = c_int(0)
     sollya_lib_get_function_arity(byref(arity),expressionSo)
-    return(int(arity.value))
+    return int(arity.value)
 
 def pobyso_get_head_function(expressionSo):
     """ 
@@ -513,7 +581,7 @@
 def pobyso_get_head_function_so_sa(expressionSo):
     functionType = c_int(0)
     sollya_lib_get_head_function(byref(functionType), expressionSo, None)
-    return(int(functionType.value))
+    return int(functionType.value)
 
 def pobyso_get_interval_from_range_so_sa(soRange, realIntervalFieldSa = None ):
     """
@@ -526,20 +594,20 @@
     if realIntervalFieldSa is None:
         retval = sollya_lib_get_prec_of_range(byref(prec), soRange, None)
         if retval == 0:
-            return(None)
+            return None
         realIntervalFieldSa = RealIntervalField(prec.value)
     intervalSa = realIntervalFieldSa(0,0)
     retval = \
         sollya_lib_get_interval_from_range(get_interval_value(intervalSa),\
                                            soRange)
     if retval == 0:
-        return(None)
-    return(intervalSa)
+        return None
+    return intervalSa
 # End pobyso_get_interval_from_range_so_sa
 
 def pobyso_get_list_elements(soObj):
     """ Legacy function. See pobyso_get_list_elements_so_so. """
-    return(pobyso_get_list_elements_so_so(soObj))
+    return pobyso_get_list_elements_so_so(soObj)
  
 def pobyso_get_list_elements_so_so(objectListSo):
     """
@@ -578,11 +646,11 @@
        #sollya_lib_clear_obj(listAddress[i])
     # Free the list itself.   
     sollya_lib_free(listAddress)
-    return(listAsSageList, numElements.value, isEndElliptic.value)
+    return (listAsSageList, numElements.value, isEndElliptic.value)
 
 def pobyso_get_max_prec_of_exp(soExp):
     """ Legacy function. See pobyso_get_max_prec_of_exp_so_sa. """
-    return(pobyso_get_max_prec_of_exp_so_sa(soExp))
+    return pobyso_get_max_prec_of_exp_so_sa(soExp)
 
 def pobyso_get_max_prec_of_exp_so_sa(expSo):
     """
@@ -608,25 +676,25 @@
                 pobyso_get_max_prec_of_exp_so_sa(subexpressions[i])
             if maxPrecisionCandidate > maxPrecision:
                 maxPrecision = maxPrecisionCandidate
-        return(maxPrecision)
+        return maxPrecision
     elif operator == SOLLYA_BASE_FUNC_CONSTANT:
         #minConstPrec = pobyso_get_min_prec_of_constant_so_sa(expSo)
         #currentConstPrec = pobyso_get_min_prec_of_constant_so_sa(soExp)
         #print minConstPrec, " - ", currentConstPrec 
-        return(pobyso_get_min_prec_of_constant_so_sa(expSo))
+        return pobyso_get_min_prec_of_constant_so_sa(expSo)
     
     elif operator == SOLLYA_BASE_FUNC_FREE_VARIABLE:
-        return(0)
+        return 0
     else:
         print "pobyso_get_max_prec_of_exp_so_sa: unexepected operator."
-        return(0)
+        return 0
 
 def pobyso_get_min_prec_of_constant_so_sa(constExpSo):
     """
     Get the minimum precision necessary to represent the value of a Sollya
     constant.
     MPFR_MIN_PREC and powers of 2 are taken into account.
-    We assume that constExpSo is a point
+    We assume that constExpSo is a pointer to a Sollay constant expression.
     """
     constExpAsRnSa = pobyso_get_constant_as_rn_so_sa(constExpSo)
     return(min_mpfr_size(get_rn_value(constExpAsRnSa)))
@@ -634,38 +702,14 @@
 def pobyso_get_poly_so_sa(polySo, realFieldSa=None):
     """
     Convert a Sollya polynomial into a Sage polynomial.
-    We assume that the polynomial is in canonical form.
-    If no realField is given, a RealField corresponding to the maximum 
-    precision of the coefficients is internally computed.
-    The real field is not returned but can be easily retrieved from 
-    the polynomial itself.
-    ALGORITHM:
-    - (optional) compute the RealField of the coefficients;
-    - convert the Sollya expression into a Sage expression;
-    - convert the Sage expression into a Sage polynomial
-    TODO: the canonical thing for the polynomial.
+    Legacy function. Use pobyso_float_poly_so_sa() instead.
     """    
-    if realFieldSa is None:
-        expressionPrecSa = pobyso_get_max_prec_of_exp_so_sa(polySo)
-        realFieldSa = RealField(expressionPrecSa)
-    #print "Sollya expression before...",
-    #pobyso_autoprint(polySo)
-
-    expressionSa = pobyso_get_sage_exp_from_sollya_exp_so_sa(polySo, \
-                                                             realFieldSa)
-    #print "...Sollya expression after.",
-    #pobyso_autoprint(polySo)
-    polyVariableSa = expressionSa.variables()[0]
-    polyRingSa = realFieldSa[str(polyVariableSa)]
-    #print polyRingSa
-    # Do not use the polynomial(expressionSa, ring=polyRingSa) form!
-    polynomialSa = polyRingSa(expressionSa)
-    return(polynomialSa)
+    return pobyso_float_poly_so_sa(polySo,realField)
 # End pobyso_get_poly_so_sa
 
 def pobyso_get_prec():
     """ Legacy function. See pobyso_get_prec_so_sa(). """
-    return(pobyso_get_prec_so_sa())
+    return pobyso_get_prec_so_sa()
 
 def pobyso_get_prec_so():
     """
@@ -674,7 +718,7 @@
     Usefull when modifying the precision back and forth by avoiding
     extra conversions.
     """
-    return(sollya_lib_get_prec(None))
+    return sollya_lib_get_prec(None)
     
 def pobyso_get_prec_so_sa():
     """
@@ -688,10 +732,20 @@
     return int(precSa.value)
 # End pobyso_get_prec_so_sa.
 
+def pobyso_get_prec_so_so_sa():
+    """
+    Return the current precision both as a Sollya object and a
+    Sage integer as hybrid tuple.
+    To avoid multiple calls for precision manipulations. 
+    """
+    precSo = sollya_lib_get_prec(None)
+    precSa = c_int(0)
+    sollya_lib_get_constant_as_int(byref(precSa), precSo)
+    return (precSo, precSa)
     
 def pobyso_get_prec_of_constant(ctExpSo):
     """ Legacy function. See pobyso_get_prec_of_constant_so_sa. """
-    return(pobyso_get_prec_of_constant_so_sa(ctExpSo))
+    return pobyso_get_prec_of_constant_so_sa(ctExpSo)
 
 def pobyso_get_prec_of_constant_so_sa(ctExpSo):
     """
@@ -701,8 +755,8 @@
     prec = c_int(0)
     retc = sollya_lib_get_prec_of_constant(byref(prec), ctExpSo, None)
     if retc == 0:
-        return(None)
-    return(int(prec.value))
+        return None
+    return int(prec.value)
 
 def pobyso_get_prec_of_range_so_sa(rangeSo):
     """
@@ -712,30 +766,13 @@
     retc = sollya_lib_get_prec_of_range(byref(prec), rangeSo, None)
     if retc == 0:
         return(None)
-    return(int(prec.value))
+    return int(prec.value)
 # End pobyso_get_prec_of_range_so_sa()
 
-def pobyso_get_rat_poly_sa_so(polySa, precSa = None):
-    """
-    Create a Sollya polynomial from a Sage rational polynomial.
-    """
-    ## TODO: filter arguments.
-    ##
-    if not precSa is None:
-        initialPrecSo = pobyso_get_prec_so() 
-    coefficients = polySa.coefficients()
-    exponents    = polySa.exponents()
-    ## TODO: deal with variables names.
-    
-    ## If necessary, return Sollya to its initial default precision.
-    if not precSa is None:
-        pobyso_set_prec_so_so(initialPrecSo)
-# End pobyso_get_rat_poly_sa_so    
-    
 def pobyso_get_sage_exp_from_sollya_exp(sollyaExpSo, realField = RR):
     """ Legacy function. See pobyso_get_sage_exp_from_sollya_exp_so_sa. """
-    return(pobyso_get_sage_exp_from_sollya_exp_so_sa(sollyaExpSo, \
-                                                     realField = RR))
+    return pobyso_get_sage_exp_from_sollya_exp_so_sa(sollyaExpSo, 
+                                                     realField = RR)
 
 def pobyso_get_sage_exp_from_sollya_exp_so_sa(sollyaExpSo, realFieldSa = RR):
     """
@@ -771,13 +808,13 @@
         # (is there any in Sollya anyway?).
         else:
             sageExpSa = eval('None')
-        return(sageExpSa)
+        return sageExpSa
     elif operatorSa == SOLLYA_BASE_FUNC_CONSTANT:
         #print "This is a constant"
         return pobyso_get_constant_as_rn_with_rf_so_sa(sollyaExpSo, realFieldSa)
     elif operatorSa == SOLLYA_BASE_FUNC_FREE_VARIABLE:
         #print "This is free variable"
-        return(eval(sollyaLibFreeVariableName))
+        return eval(sollyaLibFreeVariableName)
     else:
         print "Unexpected"
         return eval('None')
@@ -786,7 +823,7 @@
 
 def pobyso_get_subfunctions(expressionSo):
     """ Legacy function. See pobyso_get_subfunctions_so_sa. """
-    return(pobyso_get_subfunctions_so_sa(expressionSo)) 
+    return pobyso_get_subfunctions_so_sa(expressionSo) 
 # End pobyso_get_subfunctions.
  
 def pobyso_get_subfunctions_so_sa(expressionSo):
@@ -829,7 +866,7 @@
     for i in xrange(arity.value):
         subs.append(int(subfunctions[i].value))
         #print subs[i]
-    return(int(arity.value), subs)
+    return (int(arity.value), subs)
 # End pobyso_get_subfunctions_so_sa
     
 def pobyso_guess_degree_sa_sa(functionSa, intervalSa, approxErrorSa, 
@@ -932,7 +969,7 @@
 
 def pobyso_infnorm_so_so(func, interval, file = None, intervalList = None):
     print "Do not use this function. User pobyso_supnorm_so_so instead."
-    return(None)
+    return None
 
 def pobyso_interval_to_range_sa_so(intervalSa, precisionSa=None):
     if precisionSa is None:
@@ -940,7 +977,7 @@
     intervalSo = pobyso_bounds_to_range_sa_so(intervalSa.lower(),\
                                               intervalSa.upper(),\
                                               precisionSa)
-    return(intervalSo)
+    return intervalSo
 # End pobyso_interval_to_range_sa_so
 
 def pobyso_is_error_so_sa(objSo):
@@ -955,9 +992,15 @@
 
 def pobyso_is_floating_point_number_sa_sa(numberSa):
     """
-    Check whether a Sage number is floating point
+    Check whether a Sage number is floating point.
+    Exception stuff added because numbers other than
+    floating-point ones do not have the is_real() attribute.
     """
-    return numberSa.parent().__class__ is RR.__class__
+    try:
+        return numberSa.is_real()
+    except AttributeError:
+        return False
+# End pobyso_is_floating_piont_number_sa_sa
 
 def pobyso_lib_init():
     sollya_lib_init(None)
@@ -977,16 +1020,24 @@
 
 def pobyso_parse_string(string):
     """ Legacy function. See pobyso_parse_string_sa_so. """
-    return(pobyso_parse_string_sa_so(string))
+    return pobyso_parse_string_sa_so(string)
  
 def pobyso_parse_string_sa_so(string):
     """
     Get the Sollya expression computed from a Sage string or
     a Sollya error object if parsing failed.
     """
-    return(sollya_lib_parse_string(string))
+    return sollya_lib_parse_string(string)
 
 def pobyso_precision_so_sa(ctExpSo):
+    """
+    Computes the necessary precision to represent a number.
+    If x is not zero, it can be uniquely written as x = m · 2e 
+    where m is an odd integer and e is an integer. 
+    precision(x) returns the number of bits necessary to write m 
+    in binary (i.e. ceil(log2(m))).
+    """
+    #TODO: take care of the special case: 0, @NaN@, @Inf@
     precisionSo = sollya_lib_precision(ctExpSo)
     precisionSa = pobyso_constant_from_int_so_sa(precisionSo)
     sollya_lib_clear_obj(precisionSo)
@@ -995,7 +1046,7 @@
     
 def pobyso_range(rnLowerBound, rnUpperBound):
     """ Legacy function. See pobyso_range_sa_so. """
-    return(pobyso_range_sa_so(rnLowerBound, rnUpperBound)) 
+    return pobyso_range_sa_so(rnLowerBound, rnUpperBound) 
 
 
 def pobyso_range_to_interval_so_sa(rangeSo, realIntervalFieldSa = None):
@@ -1011,8 +1062,28 @@
         realIntervalFieldSa = RealIntervalField(precSa)
     intervalSa = \
         pobyso_get_interval_from_range_so_sa(rangeSo, realIntervalFieldSa) 
-    return(intervalSa)
+    return intervalSa
+# End pobyso_range_to_interval_so_sa
 
+def pobyso_rat_poly_sa_so(polySa, precSa = None):
+    """
+    Create a Sollya polynomial from a Sage rational polynomial.
+    """
+    ## TODO: filter arguments.
+    ## Precision. If no precision is given, use the current precision
+    #  of Sollya.
+    if precSa is None:
+        precSa =  pobyso_get_prec_so_sa()
+    #print "Precision:",  precSa
+    RRR = RealField(precSa)
+    ## Create a Sage polynomial in the "right" precision.
+    P_RRR = RRR[polySa.variables()[0]]
+    polyFloatSa = P_RRR(polySa)
+    ## Make sure no precision is provided.
+    return pobyso_float_poly_sa_so(polyFloatSa)
+    
+# End pobyso_rat_poly_sa_so    
+    
 def pobyso_remez_canonical_sa_sa(func, \
                                  degree, \
                                  lowerBound, \
