Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagesmc
Path: blob/master/src/sage/sets/totally_ordered_finite_set.py
8817 views
1
"""
2
Totally Ordered Finite Sets
3
4
AUTHORS:
5
6
- Stepan Starosta (2012): Initial version
7
"""
8
#*****************************************************************************
9
# Copyright (C) 2012 Stepan Starosta <[email protected]>
10
#
11
# Distributed under the terms of the GNU General Public License (GPL)
12
#
13
# This code is distributed in the hope that it will be useful,
14
# but WITHOUT ANY WARRANTY; without even the implied warranty of
15
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16
# General Public License for more details.
17
#
18
# The full text of the GPL is available at:
19
#
20
# http://www.gnu.org/licenses/
21
#******************************************************************************
22
23
from sage.structure.element import Element
24
from sage.structure.parent import Parent
25
from sage.sets.finite_enumerated_set import FiniteEnumeratedSet
26
from sage.categories.posets import Posets
27
from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets
28
29
class TotallyOrderedFiniteSetElement(Element):
30
"""
31
Element of a finite totally ordered set.
32
33
EXAMPLES::
34
35
sage: S = TotallyOrderedFiniteSet([2,7], facade=False)
36
sage: x = S(2)
37
sage: print x
38
2
39
sage: x.parent()
40
{2, 7}
41
"""
42
def __init__(self, parent, data):
43
r"""
44
TESTS::
45
46
sage: T = TotallyOrderedFiniteSet([3,2,1],facade=False)
47
sage: TestSuite(T.an_element()).run()
48
"""
49
Element.__init__(self, parent)
50
self.value = data
51
52
def __eq__(self, other):
53
r"""
54
Equality.
55
56
EXAMPLES::
57
58
sage: A = TotallyOrderedFiniteSet(['gaga',1], facade=False)
59
sage: A('gaga') == 'gaga' #indirect doctest
60
False
61
sage: 'gaga' == A('gaga')
62
False
63
sage: A('gaga') == A('gaga')
64
True
65
"""
66
try:
67
same_parent = self.parent() is other.parent()
68
except AttributeError:
69
return False
70
71
if not same_parent:
72
return False
73
return other.value == self.value
74
75
def __ne__(self, other):
76
r"""
77
Non-equality.
78
79
EXAMPLES::
80
81
sage: A = TotallyOrderedFiniteSet(['gaga',1], facade=False)
82
sage: A('gaga') != 'gaga' #indirect doctest
83
True
84
"""
85
return not (self == other)
86
87
def __cmp__(self, other):
88
r"""
89
Comparison.
90
91
For ``self`` and ``other`` that have the same parent the method compares
92
their rank. Otherwise, it compares their types as it is for the generic
93
comparison in :class:`sage.structure.element.Element`.
94
95
TESTS::
96
97
sage: A = TotallyOrderedFiniteSet([3,2,7], facade=False)
98
sage: A(3) < A(2) and A(3) <= A(2) and A(2) <= A(2)
99
True
100
sage: A(2) > A(3) and A(2) >= A(3) and A(7) >= A(7)
101
True
102
sage: A(3) >= A(7) or A(2) > A(2)
103
False
104
sage: A(7) < A(2) or A(2) <= A(3) or A(2) < A(2)
105
False
106
"""
107
try:
108
test = self.parent() == other.parent()
109
except AttributeError:
110
test = False
111
if not test:
112
return cmp(type(self),type(other))
113
114
if self.value == other.value:
115
return 0
116
return cmp(self.rank(),other.rank())
117
118
def _repr_(self):
119
r"""
120
String representation.
121
122
TESTS::
123
124
sage: A = TotallyOrderedFiniteSet(['gaga',1], facade=False)
125
sage: repr(A('gaga')) #indirect doctest
126
"'gaga'"
127
128
"""
129
return repr(self.value)
130
131
def __str__(self):
132
r"""
133
String that represents self.
134
135
EXAMPLES::
136
137
sage: A = TotallyOrderedFiniteSet(['gaga',1], facade=False)
138
sage: str(A('gaga')) #indirect doctest
139
'gaga'
140
"""
141
return str(self.value)
142
143
class TotallyOrderedFiniteSet(FiniteEnumeratedSet):
144
"""
145
Totally ordered finite set.
146
147
This is a finite enumerated set assuming that the elements are
148
ordered based upon their rank (i.e. their position in the set).
149
150
INPUT:
151
152
- ``elements`` -- A list of elements in the set
153
154
- ``facade`` -- (default: ``True``) if ``True``, a facade is used; it
155
should be set to ``False`` if the elements do not inherit from
156
:class:`~sage.structure.element.Element` or if you want a funny order. See
157
examples for more details.
158
159
.. SEEALSO::
160
161
:class:`FiniteEnumeratedSet`
162
163
EXAMPLES::
164
165
sage: S = TotallyOrderedFiniteSet([1,2,3])
166
sage: S
167
{1, 2, 3}
168
sage: S.cardinality()
169
3
170
171
By default, totally ordered finite set behaves as a facade::
172
173
sage: S(1).parent()
174
Integer Ring
175
176
It makes comparison fails when it is not the standard order::
177
178
sage: T1 = TotallyOrderedFiniteSet([3,2,5,1])
179
sage: T1(3) < T1(1)
180
False
181
sage: T2 = TotallyOrderedFiniteSet([3,var('x')])
182
sage: T2(3) < T2(var('x'))
183
3 < x
184
185
To make the above example work, you should set the argument facade to
186
``False`` in the constructor. In that case, the elements of the set have a
187
dedicated class::
188
189
sage: A = TotallyOrderedFiniteSet([3,2,0,'a',7,(0,0),1], facade=False)
190
sage: A
191
{3, 2, 0, 'a', 7, (0, 0), 1}
192
sage: x = A.an_element()
193
sage: x
194
3
195
sage: x.parent()
196
{3, 2, 0, 'a', 7, (0, 0), 1}
197
sage: A(3) < A(2)
198
True
199
sage: A('a') < A(7)
200
True
201
sage: A(3) > A(2)
202
False
203
sage: A(1) < A(3)
204
False
205
sage: A(3) == A(3)
206
True
207
208
But then, the equality comparison is always False with elements outside of
209
the set::
210
211
sage: A(1) == 1
212
False
213
sage: 1 == A(1)
214
False
215
sage: 'a' == A('a')
216
False
217
sage: A('a') == 'a'
218
False
219
220
and comparisons are comparisons of types::
221
222
sage: for e in [1,'a',(0, 0)]:
223
... f = A(e)
224
... print e == f,
225
... print cmp(e,f) == cmp(type(e),type(f)),
226
... print cmp(f,e) == cmp(type(f),type(e))
227
False True True
228
False True True
229
False True True
230
231
This behavior of comparison is the same as the one of
232
:class:`~sage.structure.element.Element`.
233
234
When you build a totally ordered set whose elements do not inherit from
235
:class:`sage.structure.element.Element`, the following happens::
236
237
sage: S = TotallyOrderedFiniteSet(['a','b'])
238
sage: S('a')
239
Traceback (most recent call last):
240
...
241
TypeError: Cannot convert str to sage.structure.element.Element
242
sage: S = TotallyOrderedFiniteSet(['a','b'], facade = False)
243
sage: S('a')
244
'a'
245
246
Multiple elements are automatically deleted::
247
248
sage: TotallyOrderedFiniteSet([1,1,2,1,2,2,5,4])
249
{1, 2, 5, 4}
250
"""
251
Element = TotallyOrderedFiniteSetElement
252
253
@staticmethod
254
def __classcall__(cls, iterable, facade=True):
255
"""
256
Standard trick to expand the iterable upon input, and
257
guarantees unique representation, independently of the type of
258
the iterable. See ``UniqueRepresentation``.
259
260
TESTS::
261
262
sage: S1 = TotallyOrderedFiniteSet([1, 2, 3])
263
sage: S2 = TotallyOrderedFiniteSet((1, 2, 3))
264
sage: S3 = TotallyOrderedFiniteSet((x for x in range(1,4)))
265
sage: S1 is S2
266
True
267
sage: S2 is S3
268
True
269
"""
270
elements = []
271
seen = set()
272
for x in iterable:
273
if x not in seen:
274
elements.append(x)
275
seen.add(x)
276
return super(FiniteEnumeratedSet, cls).__classcall__(
277
cls,
278
tuple(elements),
279
facade)
280
281
def __init__(self, elements, facade=True):
282
"""
283
Initialize ``self``.
284
285
TESTS::
286
287
sage: TestSuite(TotallyOrderedFiniteSet([1,2,3])).run()
288
sage: TestSuite(TotallyOrderedFiniteSet([1,2,3],facade=False)).run()
289
sage: TestSuite(TotallyOrderedFiniteSet([1,3,2],facade=False)).run()
290
sage: TestSuite(TotallyOrderedFiniteSet([])).run()
291
"""
292
Parent.__init__(self, facade = facade, category = (Posets(),FiniteEnumeratedSets()))
293
self._elements = elements
294
if facade:
295
self._facade_elements = None
296
else:
297
self._facade_elements = self._elements
298
self._elements = [self.element_class(self,x) for x in elements]
299
300
def _element_constructor_(self, data):
301
r"""
302
Build an element of that set from ``data``.
303
304
EXAMPLES::
305
306
sage: S1 = TotallyOrderedFiniteSet([1,2,3])
307
sage: x = S1(1); x # indirect doctest
308
1
309
sage: x.parent()
310
Integer Ring
311
312
313
sage: S2 = TotallyOrderedFiniteSet([3,2,1], facade=False)
314
sage: y = S2(1); y # indirect doctest
315
1
316
sage: y.parent()
317
{3, 2, 1}
318
sage: y in S2
319
True
320
sage: S2(y) is y
321
True
322
"""
323
if self._facade_elements is None:
324
return FiniteEnumeratedSet._element_constructor_(self, data)
325
326
try:
327
i = self._facade_elements.index(data)
328
except ValueError:
329
raise ValueError("%s not in %s"%(data, self))
330
331
return self._elements[i]
332
333
def le(self, x, y):
334
r"""
335
Return ``True`` if `x \le y` for the order of ``self``.
336
337
EXAMPLES::
338
339
sage: T = TotallyOrderedFiniteSet([1,3,2], facade=False)
340
sage: T1, T3, T2 = T.list()
341
sage: T.le(T1,T3)
342
True
343
sage: T.le(T3,T2)
344
True
345
"""
346
try:
347
return self._elements.index(x) <= self._elements.index(y)
348
except Exception:
349
raise ValueError("arguments must be elements of the set")
350
351
352