|
101 | 101 | from sage.misc.lazy_attribute import lazy_attribute |
102 | 102 | from sage.misc.lazy_import import lazy_import |
103 | 103 | from sage.combinat.integer_vector_weighted import iterator_fast as wt_int_vec_iter |
104 | | -from sage.categories.fields import Fields |
105 | | -from sage.categories.functor import Functor |
106 | | -from sage.categories.integral_domains import IntegralDomains |
| 104 | +from sage.categories.action import Action |
107 | 105 | from sage.categories.hopf_algebras_with_basis import HopfAlgebrasWithBasis |
108 | | -from sage.categories.pushout import ConstructionFunctor |
109 | 106 | from sage.categories.quotient_fields import QuotientFields |
110 | 107 | from sage.structure.unique_representation import UniqueRepresentation |
111 | 108 | from sage.rings.polynomial.infinite_polynomial_ring import InfinitePolynomialRing |
@@ -1348,38 +1345,55 @@ def variables(self): |
1348 | 1345 | return self._pool |
1349 | 1346 |
|
1350 | 1347 |
|
1351 | | -class CoefficientRingFunctor(ConstructionFunctor): |
1352 | | - r""" |
1353 | | - A construction functor for the :class:`CoefficientRing`. |
1354 | | -
|
1355 | | - The functor maps the integral domain of coefficients to the field |
1356 | | - of unknown coefficients. |
| 1348 | +class DominatingAction(Action): |
1357 | 1349 | """ |
1358 | | - rank = 0 |
1359 | | - |
1360 | | - def __init__(self): |
1361 | | - r""" |
1362 | | - Initialize the functor. |
| 1350 | + The action defined by ``G`` acting on ``S`` by any operation such that |
| 1351 | + the result is either in ``G`` if ``S`` is in the base ring of ``G`` or |
| 1352 | + ``G`` is the coefficient ring of ``S`` otherwise. |
1363 | 1353 |
|
1364 | | - EXAMPLES:: |
1365 | | -
|
1366 | | - sage: from sage.data_structures.stream import CoefficientRingFunctor |
1367 | | - sage: CoefficientRingFunctor() |
1368 | | - CoefficientRingFunctor |
| 1354 | + This is meant specifically for use by :class:`CoefficientRing` as part |
| 1355 | + of the function solver. This is not a mathematically defined action of |
| 1356 | + ``G`` on ``S`` since the result might not be in ``S``. |
| 1357 | + """ |
| 1358 | + def _act_(self, g, x): |
1369 | 1359 | """ |
1370 | | - Functor.__init__(self, IntegralDomains(), Fields()) |
1371 | | - |
1372 | | - def _apply_functor(self, R): |
1373 | | - r""" |
1374 | | - Apply the functor to an integral domain. |
| 1360 | + Return the action of ``g`` on ``x``. |
1375 | 1361 |
|
1376 | 1362 | EXAMPLES:: |
1377 | 1363 |
|
1378 | | - sage: from sage.data_structures.stream import CoefficientRingFunctor |
1379 | | - sage: CoefficientRingFunctor()(ZZ) # indirect doctest |
| 1364 | + sage: from sage.data_structures.stream import CoefficientRing |
| 1365 | + sage: PF = CoefficientRing(ZZ) |
| 1366 | + sage: g = PF.gen(0) |
| 1367 | + sage: x = g - 2; x |
| 1368 | + FESDUMMY_0 - 2 |
| 1369 | + sage: x.parent() |
1380 | 1370 | CoefficientRing over Integer Ring |
1381 | | - """ |
1382 | | - return CoefficientRing(R) |
| 1371 | + sage: x = 2 - g; x |
| 1372 | + -FESDUMMY_0 + 2 |
| 1373 | + sage: x.parent() |
| 1374 | + CoefficientRing over Integer Ring |
| 1375 | + sage: R = QQ['a'] |
| 1376 | + sage: a = R.gen() |
| 1377 | + sage: S = ZZ['t']['b'] |
| 1378 | + sage: b = S.gen() |
| 1379 | + sage: x = a * g + b; x |
| 1380 | + FESDUMMY_0*a + b |
| 1381 | + sage: x.parent() |
| 1382 | + Univariate Polynomial Ring in a over |
| 1383 | + Fraction Field of Infinite polynomial ring in FESDUMMY over |
| 1384 | + Univariate Polynomial Ring in b over Univariate Polynomial Ring in t over Integer Ring |
| 1385 | + """ |
| 1386 | + G = g.parent() |
| 1387 | + if x in G.base_ring(): |
| 1388 | + if self.is_left(): |
| 1389 | + return self.operation()(g, G(x)) |
| 1390 | + return self.operation()(G(x), g) |
| 1391 | + if x.base_ring() is not G: |
| 1392 | + x = x.change_ring(G) |
| 1393 | + g = x.parent()(g) |
| 1394 | + if self.is_left(): |
| 1395 | + return self.operation()(g, x) |
| 1396 | + return self.operation()(x, g) |
1383 | 1397 |
|
1384 | 1398 |
|
1385 | 1399 | class CoefficientRing(UniqueRepresentation, FractionField_generic): |
@@ -1473,25 +1487,26 @@ def gen(self, i): |
1473 | 1487 | """ |
1474 | 1488 | return self._element_class(self, self._R.gen()[i]) |
1475 | 1489 |
|
1476 | | - def construction(self): |
1477 | | - r""" |
1478 | | - Return a pair ``(F, R)``, where ``F`` is a |
1479 | | - :class:`CoefficientRingFunctor` and `R` is an integral |
1480 | | - domain, such that ``F(R)`` returns ``self``. |
| 1490 | + def _get_action_(self, S, op, self_on_left): |
| 1491 | + """ |
| 1492 | + Return the left/right action of ``S`` on ``self`` given by ``op``. |
1481 | 1493 |
|
1482 | 1494 | EXAMPLES:: |
1483 | 1495 |
|
1484 | 1496 | sage: from sage.data_structures.stream import CoefficientRing |
| 1497 | + sage: R = ZZ['q'] |
| 1498 | + sage: S = QQ['t']['a','q'] |
1485 | 1499 | sage: PF = CoefficientRing(ZZ["q"]) |
1486 | | - sage: F, R = PF.construction() |
1487 | | - sage: F, R |
1488 | | - (CoefficientRingFunctor, |
1489 | | - Univariate Polynomial Ring in q over Integer Ring) |
1490 | | -
|
1491 | | - sage: F(R) |
1492 | | - CoefficientRing over Univariate Polynomial Ring in q over Integer Ring |
1493 | | - """ |
1494 | | - return (CoefficientRingFunctor(), self.base_ring()) |
| 1500 | + sage: PF._get_action_(PF, operator.mul, True) is None |
| 1501 | + True |
| 1502 | + sage: type(PF._get_action_(R, operator.add, False)) |
| 1503 | + <class 'sage.data_structures.stream.DominatingAction'> |
| 1504 | + sage: type(PF._get_action_(S, operator.mul, True)) |
| 1505 | + <class 'sage.data_structures.stream.DominatingAction'> |
| 1506 | + """ |
| 1507 | + if S is not self: |
| 1508 | + return DominatingAction(self, S, op=op, is_left=self_on_left) |
| 1509 | + return super()._get_action_(S, op, self_on_left) |
1495 | 1510 |
|
1496 | 1511 |
|
1497 | 1512 | class Stream_uninitialized(Stream): |
|
0 commit comments