75
75
# http://www.gnu.org/licenses/
76
76
#*****************************************************************************
77
77
78
+ from functools import wraps
79
+
78
80
from sage .misc .cachefunc import cached_method
79
81
from sage .misc .superseded import experimental
80
82
from sage .structure .element import Element
@@ -297,6 +299,75 @@ def prefix_set(self):
297
299
if p + a not in self .elements ]
298
300
299
301
302
+ def minimize_result (operation ):
303
+ r"""
304
+ A decorator for operations that enables control of
305
+ automatic minimization on the result.
306
+
307
+ INPUT:
308
+
309
+ - ``operation`` -- a method
310
+
311
+ OUTPUT:
312
+
313
+ A method with the following additional argument:
314
+
315
+ - ``minimize`` -- (default: ``None``) a boolean or ``None``.
316
+ If ``True``, then :meth:`minimized` is called after the operation,
317
+ if ``False``, then not. If this argument is ``None``, then
318
+ the default specified by the parent's ``minimize_results`` is used.
319
+
320
+ TESTS::
321
+
322
+ sage: from sage.combinat.recognizable_series import minimize_result
323
+ sage: class P(object):
324
+ ....: pass
325
+ sage: p = P()
326
+ sage: class S(object):
327
+ ....: def __init__(self, s):
328
+ ....: self.s = s
329
+ ....: def __repr__(self):
330
+ ....: return self.s
331
+ ....: def parent(self):
332
+ ....: return p
333
+ ....: def minimized(self):
334
+ ....: return S(self.s + ' minimized')
335
+ ....: @minimize_result
336
+ ....: def operation(self):
337
+ ....: return S(self.s + ' result')
338
+
339
+ sage: p.minimize_results = True
340
+ sage: S('some').operation()
341
+ some result minimized
342
+ sage: S('some').operation(minimize=True)
343
+ some result minimized
344
+ sage: S('some').operation(minimize=False)
345
+ some result
346
+
347
+ sage: p.minimize_results = False
348
+ sage: S('some').operation()
349
+ some result
350
+ sage: S('some').operation(minimize=True)
351
+ some result minimized
352
+ sage: S('some').operation(minimize=False)
353
+ some result
354
+ """
355
+ @wraps (operation )
356
+ def minimized (self , * args , ** kwds ):
357
+ minimize = kwds .pop ('minimize' , None )
358
+ if minimize is None :
359
+ minimize = self .parent ().minimize_results
360
+
361
+ result = operation (self , * args , ** kwds )
362
+
363
+ if minimize :
364
+ result = result .minimized ()
365
+
366
+ return result
367
+
368
+ return minimized
369
+
370
+
300
371
class RecognizableSeries (Element ):
301
372
def __init__ (self , parent , mu , left , right ):
302
373
r"""
@@ -1023,8 +1094,8 @@ def dimension(self):
1023
1094
"""
1024
1095
return self .mu .first ().nrows ()
1025
1096
1026
-
1027
- def _add_ (self , other , minimize = True ):
1097
+ @ minimize_result
1098
+ def _add_ (self , other ):
1028
1099
r"""
1029
1100
Return the sum of this recognizable series and the ``other``
1030
1101
recognizable series.
@@ -1034,8 +1105,10 @@ def _add_(self, other, minimize=True):
1034
1105
- ``other`` -- a :class:`RecognizableSeries` with the same parent
1035
1106
as this recognizable series.
1036
1107
1037
- - ``minimize`` -- (default: ``True``) a boolean. If set, then
1038
- :meth:`minimized` is called after the operation.
1108
+ - ``minimize`` -- (default: ``None``) a boolean or ``None``.
1109
+ If ``True``, then :meth:`minimized` is called after the operation,
1110
+ if ``False``, then not. If this argument is ``None``, then
1111
+ the default specified by the parent's ``minimize_results`` is used.
1039
1112
1040
1113
OUTPUT:
1041
1114
@@ -1067,10 +1140,7 @@ def _add_(self, other, minimize=True):
1067
1140
vector (tuple (self .left ) + tuple (other .left )),
1068
1141
vector (tuple (self .right ) + tuple (other .right )))
1069
1142
1070
- if minimize :
1071
- return result .minimized ()
1072
- else :
1073
- return result
1143
+ return result
1074
1144
1075
1145
1076
1146
def _neg_ (self ):
@@ -1165,8 +1235,8 @@ def _lmul_(self, other):
1165
1235
P = self .parent ()
1166
1236
return P .element_class (P , self .mu , other * self .left , self .right )
1167
1237
1168
-
1169
- def hadamard_product (self , other , minimize = True ):
1238
+ @ minimize_result
1239
+ def hadamard_product (self , other ):
1170
1240
r"""
1171
1241
Return the Hadamard product of this recognizable series
1172
1242
and the ``other`` recognizable series, i.e., multiply the two
@@ -1177,8 +1247,10 @@ def hadamard_product(self, other, minimize=True):
1177
1247
- ``other`` -- a :class:`RecognizableSeries` with the same parent
1178
1248
as this recognizable series.
1179
1249
1180
- - ``minimize`` -- (default: ``True``) a boolean. If set, then
1181
- :meth:`minimized` is called after the operation.
1250
+ - ``minimize`` -- (default: ``None``) a boolean or ``None``.
1251
+ If ``True``, then :meth:`minimized` is called after the operation,
1252
+ if ``False``, then not. If this argument is ``None``, then
1253
+ the default specified by the parent's ``minimize_results`` is used.
1182
1254
1183
1255
OUTPUT:
1184
1256
@@ -1259,10 +1331,7 @@ def hadamard_product(self, other, minimize=True):
1259
1331
vector (self .left .outer_product (other .left ).list ()),
1260
1332
vector (self .right .outer_product (other .right ).list ()))
1261
1333
1262
- if minimize :
1263
- return result .minimized ()
1264
- else :
1265
- return result
1334
+ return result
1266
1335
1267
1336
1268
1337
@@ -1349,7 +1418,8 @@ def __classcall__(cls, *args, **kwds):
1349
1418
def __normalize__ (cls ,
1350
1419
coefficient_ring = None ,
1351
1420
alphabet = None , indices = None ,
1352
- category = None ):
1421
+ category = None ,
1422
+ minimize_results = True ):
1353
1423
r"""
1354
1424
Normalizes the input in order to ensure a unique
1355
1425
representation.
@@ -1405,10 +1475,10 @@ def __normalize__(cls,
1405
1475
from sage .categories .modules import Modules
1406
1476
category = category or Modules (coefficient_ring )
1407
1477
1408
- return (coefficient_ring , indices , category )
1478
+ return (coefficient_ring , indices , category , minimize_results )
1409
1479
1410
1480
@experimental (trac_number = 21202 )
1411
- def __init__ (self , coefficient_ring , indices , category ):
1481
+ def __init__ (self , coefficient_ring , indices , category , minimize_results ):
1412
1482
r"""
1413
1483
See :class:`RecognizableSeriesSpace` for details.
1414
1484
@@ -1421,12 +1491,17 @@ def __init__(self, coefficient_ring, indices, category):
1421
1491
- ``category`` -- (default: ``None``) the category of this
1422
1492
space
1423
1493
1494
+ - ``minimize_results`` -- (default: ``True``) a boolean. If set, then
1495
+ :meth:`RecognizableSeries.minimized` is automatically called
1496
+ after performing operations.
1497
+
1424
1498
TESTS::
1425
1499
1426
1500
sage: RecognizableSeriesSpace(ZZ, [0, 1])
1427
1501
Space of recognizable series on {0, 1} with coefficients in Integer Ring
1428
1502
"""
1429
1503
self ._indices_ = indices
1504
+ self ._minimize_results_ = minimize_results
1430
1505
super (RecognizableSeriesSpace , self ).__init__ (
1431
1506
category = category , base = coefficient_ring )
1432
1507
@@ -1480,6 +1555,24 @@ def coefficient_ring(self):
1480
1555
"""
1481
1556
return self .base ()
1482
1557
1558
+ @property
1559
+ def minimize_results (self ):
1560
+ r"""
1561
+ A boolean indicating whether
1562
+ :meth:`RecognizableSeries.minimized` is automatically called
1563
+ after performing operations.
1564
+
1565
+ TESTS::
1566
+
1567
+ sage: RecognizableSeriesSpace(ZZ, [0, 1]).minimize_results
1568
+ True
1569
+ sage: RecognizableSeriesSpace(ZZ, [0, 1], minimize_results=True).minimize_results
1570
+ True
1571
+ sage: RecognizableSeriesSpace(ZZ, [0, 1], minimize_results=False).minimize_results
1572
+ False
1573
+ """
1574
+ return self ._minimize_results_
1575
+
1483
1576
def _repr_ (self ):
1484
1577
r"""
1485
1578
Return a representation string of this recognizable sequence
0 commit comments