Repository: sagemath/sage

Issue:
Coercion problem with Algebraic Real Field
<div id="comment:0"></div>

The following algebraic number is clearly real, but the AA class seems to have trouble digesting it:

```
----------------------------------------------------------------------
| Sage Version 5.0.beta10, Release Date: 2012-03-23                  |
| Type notebook() for the GUI, and license() for information.        |
----------------------------------------------------------------------
**********************************************************************
*                                                                    *
* Warning: this is a prerelease version, and it may be unstable.     *
*                                                                    *
**********************************************************************
sage: x = exp(2*I*pi/7) + exp(-2*I*pi/7)
sage: QQbar(x) in AA
True
sage: AA(x)
ERROR: An unexpected error occurred while tokenizing input
The following traceback may be corrupted or invalid
The error message is: ('EOF in multi-line statement', (1327, 0))

ERROR: An unexpected error occurred while tokenizing input
The following traceback may be corrupted or invalid
The error message is: ('EOF in multi-line statement', (4541, 0))

ERROR: An unexpected error occurred while tokenizing input
The following traceback may be corrupted or invalid
The error message is: ('EOF in multi-line statement', (1327, 0))

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)

/storage/masiao/sage-5.0.beta10/devel/sage-main/<ipython console> in <module>()

/storage/masiao/sage-5.0.beta10/local/lib/python2.7/site-packages/sage/structure/parent.so in sage.structure.parent.Parent.__call__ (sage/structure/parent.c:7940)()

/storage/masiao/sage-5.0.beta10/local/lib/python2.7/site-packages/sage/structure/coerce_maps.so in sage.structure.coerce_maps.DefaultConvertMap_unique._call_ (sage/structure/coerce_maps.c:3344)()

/storage/masiao/sage-5.0.beta10/local/lib/python2.7/site-packages/sage/structure/coerce_maps.so in sage.structure.coerce_maps.DefaultConvertMap_unique._call_ (sage/structure/coerce_maps.c:3247)()

/storage/masiao/sage-5.0.beta10/local/lib/python2.7/site-packages/sage/rings/qqbar.pyc in _element_constructor_(self, x)
    689                 raise ValueError("Cannot coerce algebraic number with non-zero imaginary part to algebraic real")
    690         elif hasattr(x, '_algebraic_'):
--> 691             return x._algebraic_(AA)
    692         return AlgebraicReal(x)
    693 

/storage/masiao/sage-5.0.beta10/local/lib/python2.7/site-packages/sage/symbolic/expression.so in sage.symbolic.expression.Expression._algebraic_ (sage/symbolic/expression.cpp:6286)()

/storage/masiao/sage-5.0.beta10/local/lib/python2.7/site-packages/sage/symbolic/expression_conversions.pyc in algebraic(ex, field)
    830         0
    831     """
--> 832     return AlgebraicConverter(field)(ex)
    833 
    834 ##############

/storage/masiao/sage-5.0.beta10/local/lib/python2.7/site-packages/sage/symbolic/expression_conversions.pyc in __call__(self, ex)
    212                 div = self.get_fake_div(ex)
    213                 return self.arithmetic(div, div.operator())
--> 214             return self.arithmetic(ex, operator)
    215         elif operator in relation_operators:
    216             return self.relation(ex, operator)

/storage/masiao/sage-5.0.beta10/local/lib/python2.7/site-packages/sage/symbolic/expression_conversions.pyc in arithmetic(self, ex, operator)
    717                 return self.field(base**expt)
    718             else:
--> 719                 return reduce(operator, map(self, ex.operands()))
    720         except TypeError:
    721             if operator is _operator.pow:

/storage/masiao/sage-5.0.beta10/local/lib/python2.7/site-packages/sage/symbolic/expression_conversions.pyc in __call__(self, ex)
    218             return self.derivative(ex, operator)
    219         else:
--> 220             return self.composition(ex, operator)
    221 
    222     def get_fake_div(self, ex):

/storage/masiao/sage-5.0.beta10/local/lib/python2.7/site-packages/sage/symbolic/expression_conversions.pyc in composition(self, ex, operator)
    787             if cmp(res, ex) == 0:
    788                 raise TypeError, "unable to convert %s to %s"%(ex, self.field)
--> 789         return self.field(res)
    790     
    791 def algebraic(ex, field):

/storage/masiao/sage-5.0.beta10/local/lib/python2.7/site-packages/sage/structure/parent.so in sage.structure.parent.Parent.__call__ (sage/structure/parent.c:7940)()

/storage/masiao/sage-5.0.beta10/local/lib/python2.7/site-packages/sage/structure/coerce_maps.so in sage.structure.coerce_maps.DefaultConvertMap_unique._call_ (sage/structure/coerce_maps.c:3344)()

/storage/masiao/sage-5.0.beta10/local/lib/python2.7/site-packages/sage/structure/coerce_maps.so in sage.structure.coerce_maps.DefaultConvertMap_unique._call_ (sage/structure/coerce_maps.c:3247)()

/storage/masiao/sage-5.0.beta10/local/lib/python2.7/site-packages/sage/rings/qqbar.pyc in _element_constructor_(self, x)
    687                 return x.real()
    688             else:
--> 689                 raise ValueError("Cannot coerce algebraic number with non-zero imaginary part to algebraic real")
    690         elif hasattr(x, '_algebraic_'):
    691             return x._algebraic_(AA)

ValueError: Cannot coerce algebraic number with non-zero imaginary part to algebraic real

```

This does not seem to be related to #12665 or to #12727 -- applying the patches at those tickets does not fix the problem.

Component: **symbolics**

Author: **Marc Mezzarobba**

Branch/Commit: **[u/mmezzarobba/12745-SR_to_AA](https://github.com/sagemath/sagetrac-mirror/tree/u/mmezzarobba/12745-SR_to_AA) @ [`8f74a7b`](https://github.com/sagemath/sagetrac-mirror/commit/8f74a7b8af077e27beff9b6f4b663d9deeea728b)**

_Issue created by migration from https://trac.sagemath.org/ticket/12745_




Discussion:
<div id="comment:2" align="right">comment:2</div>

Here's an attempt to fix the bug.

---
New commits:
<table><tr><td><a href="https://github.com/sagemath/sagetrac-mirror/commit/8f74a7b"><code>8f74a7b</code></a></td><td><code>Fix conversion to AA of real symbolic expressions with non-real subexpressions</code></td></tr></table>

Commit: **[`8f74a7b`](https://github.com/sagemath/sagetrac-mirror/commit/8f74a7b8af077e27beff9b6f4b663d9deeea728b)**
Branch: **[u/mmezzarobba/12745-SR_to_AA](https://github.com/sagemath/sagetrac-mirror/tree/u/mmezzarobba/12745-SR_to_AA)**
Author: **Marc Mezzarobba**
<div id="comment:3" align="right">comment:3</div>

Missed some test failures in `qqbar.py`.
<div id="comment:4" align="right">comment:4</div>

I thought it would be a quick fix, but in fact there are at least two deeper issues here:
* Simplification of symbolic powers of negative numbers is completely broken, with inconsistent interpretations all over the place  (see, e.g., #15605).
* Rational powers of negative numbers in `AA` are defined to choose real roots when possible (see the docstring of `sage.rings.qqbar`)

   ```
   sage: AA((-1)^(1/3))
   -1
   sage: AA(-1)^(1/3)
   -1
   ```
   These semantics do not extend well to real expressions with non-real complex subexpressions.
   Note added 2021-08-23: → #12074.
I'm giving up, at least for now.
<div id="comment:8" align="right">comment:8</div>

see also the task ticket #18333

Resolving patch:
diff --git a/src/sage/rings/qqbar.py b/src/sage/rings/qqbar.py
--- a/src/sage/rings/qqbar.py
+++ b/src/sage/rings/qqbar.py
@@ -1646,6 +1646,16 @@ def _element_constructor_(self, x):
             True
             sage: pi in QQbar                                                           # needs sage.symbolic
             False
+
+        TESTS:
+
+        Check if :trac:`12745` is fixed::
+
+            sage: x = exp(2*I*pi/7) + exp(-2*I*pi/7)
+            sage: QQbar(x) in AA
+            True
+            sage: AA(x)
+            1.246979603717467?
         """
         if isinstance(x, AlgebraicNumber):
             return x


Test patch: