Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/sets/finite_enumerated_set.py
4072 views
1
"""
2
Finite Enumerated Sets
3
"""
4
#*****************************************************************************
5
# Copyright (C) 2009 Florent Hivert <[email protected]>
6
#
7
# Distributed under the terms of the GNU General Public License (GPL)
8
#
9
# This code is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
# General Public License for more details.
13
#
14
# The full text of the GPL is available at:
15
#
16
# http://www.gnu.org/licenses/
17
#******************************************************************************
18
19
from sage.structure.parent import Parent
20
from sage.structure.unique_representation import UniqueRepresentation
21
from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets
22
from sage.categories.sets_cat import EmptySetError
23
from sage.rings.integer import Integer
24
25
#################################################################
26
class FiniteEnumeratedSet(UniqueRepresentation, Parent):
27
"""
28
A class for finite enumerated set.
29
30
Returns the finite enumerated set with elements in ``elements``
31
where ``element`` is any (finite) iterable object.
32
33
The main purpose is to provide a variant of ``list`` or ``tuple``,
34
which is a parent with an interface consistent with
35
``EnumeratedSets`` and has unique representation.
36
The list of the elements is expanded in memory.
37
38
39
EXAMPLES::
40
41
sage: S = FiniteEnumeratedSet([1, 2, 3])
42
sage: S
43
{1, 2, 3}
44
sage: S.list()
45
[1, 2, 3]
46
sage: S.cardinality()
47
3
48
sage: S.random_element()
49
1
50
sage: S.first()
51
1
52
sage: S.category()
53
Category of facade finite enumerated sets
54
sage: TestSuite(S).run()
55
56
Note that being and enumerated set, the result depends on the order::
57
58
sage: S1 = FiniteEnumeratedSet((1, 2, 3))
59
sage: S1
60
{1, 2, 3}
61
sage: S1.list()
62
[1, 2, 3]
63
sage: S1 == S
64
True
65
sage: S2 = FiniteEnumeratedSet((2, 1, 3))
66
sage: S2 == S
67
False
68
69
As an abuse, repeated entries in ``elements`` are allowed to model
70
multisets::
71
72
sage: S1 = FiniteEnumeratedSet((1, 2, 1, 2, 2, 3))
73
sage: S1
74
{1, 2, 1, 2, 2, 3}
75
76
Finaly the elements are not aware of their parent::
77
78
sage: S.first().parent()
79
Integer Ring
80
81
TESTS::
82
83
sage: TestSuite(FiniteEnumeratedSet([])).run()
84
"""
85
86
@staticmethod
87
def __classcall__(cls, iterable):
88
"""
89
Standard trick to expand the iterable upon input, and
90
guarantees unique representation, independently of the type of
91
the iterable. See ``UniqueRepresentation``.
92
93
TESTS::
94
95
sage: S1 = FiniteEnumeratedSet([1, 2, 3])
96
sage: S2 = FiniteEnumeratedSet((1, 2, 3))
97
sage: S3 = FiniteEnumeratedSet((x for x in range(1,4)))
98
sage: S1 is S2
99
True
100
sage: S2 is S3
101
True
102
"""
103
return super(FiniteEnumeratedSet, cls).__classcall__(cls, tuple(iterable))
104
105
def __init__(self, elements):
106
"""
107
TESTS::
108
109
sage: S = FiniteEnumeratedSet([1,2,3])
110
sage: TestSuite(S).run()
111
"""
112
self._elements = elements
113
Parent.__init__(self, facade = True, category = FiniteEnumeratedSets())
114
115
def _repr_(self):
116
"""
117
TESTS::
118
119
sage: S = FiniteEnumeratedSet([1,2,3])
120
sage: repr(S)
121
'{1, 2, 3}'
122
sage: S = FiniteEnumeratedSet([1])
123
sage: repr(S)
124
'{1}'
125
"""
126
if len(self._elements) == 1: # avoid printing '{1,}'
127
return "{" + str(self._elements[0]) + '}'
128
return "{" + str(self._elements)[1:-1] + '}'
129
130
def __contains__(self, x):
131
"""
132
TESTS::
133
134
sage: S = FiniteEnumeratedSet([1,2,3])
135
sage: 1 in S
136
True
137
sage: 2 in S
138
True
139
sage: 4 in S
140
False
141
sage: ZZ in S
142
False
143
144
sage: S.is_parent_of(2)
145
True
146
sage: S.is_parent_of(4)
147
False
148
"""
149
return x in self._elements
150
is_parent_of = __contains__
151
152
def list(self):
153
"""
154
TESTS::
155
156
sage: S = FiniteEnumeratedSet([1,2,3])
157
sage: S.list()
158
[1, 2, 3]
159
"""
160
return list(self._elements)
161
162
def an_element(self):
163
"""
164
TESTS::
165
166
sage: S = FiniteEnumeratedSet([1,2,3])
167
sage: S.an_element()
168
1
169
"""
170
if not self._elements:
171
raise EmptySetError
172
return self._elements[0]
173
174
def cardinality(self):
175
"""
176
TESTS::
177
178
sage: S = FiniteEnumeratedSet([1,2,3])
179
sage: S.cardinality()
180
3
181
"""
182
return Integer(len(self._elements))
183
184
def index(self, x):
185
"""
186
Returns the index of ``x`` in this finite enumerated set.
187
188
EXAMPLES::
189
190
sage: S = FiniteEnumeratedSet(['a','b','c'])
191
sage: S.index('b')
192
1
193
"""
194
return self._elements.index(x)
195
196
def _element_constructor_(self, el):
197
"""
198
TESTS::
199
200
sage: S = FiniteEnumeratedSet([1,2,3])
201
sage: S(1)
202
1
203
sage: S(0)
204
Traceback (most recent call last):
205
...
206
ValueError: 0 not in {1, 2, 3}
207
"""
208
if el in self:
209
return el
210
else:
211
raise ValueError, "%s not in %s"%(el, self)
212
213