11# sage.doctest: needs sage.libs.pari
22"""
3- The set of prime numbers and its subsets defined by congruence conditions
3+ Set and subsets of prime numbers
44
55AUTHORS:
66
2929from sage .categories .sets_cat import EmptySetError
3030
3131
32+ def repr_list (items , left = 4 , right = 2 ):
33+ if len (items ) <= left + right + 1 :
34+ s = [str (item ) for item in items ]
35+ else :
36+ s = [str (item ) for item in items [:left ]]
37+ s += ["..." ]
38+ s += [str (item ) for item in items [- right :]]
39+ return ", " .join (s )
40+
41+
3242class Primes (Set_generic , UniqueRepresentation ):
3343 r"""
3444 The set of prime numbers and some of its subsets.
@@ -129,7 +139,7 @@ def __classcall__(cls, modulus=1, classes=None, exceptions=None):
129139
130140 if modulus == 0 :
131141 for c in classes :
132- exceptions [c ] = True
142+ exceptions [ZZ ( c ) ] = True
133143 modulus = ZZ (1 )
134144 classes = []
135145
@@ -230,6 +240,110 @@ def __init__(self, modulus, classes, exceptions):
230240 self ._elements = [x for x , _ in exceptions ]
231241 self ._elements .sort ()
232242
243+ def congruence_classes (self ):
244+ r"""
245+ Return the congruence classes selected in the subset
246+ of prime numbers.
247+
248+ OUTPUT:
249+
250+ A pair ``(modulus, list of classes)``
251+
252+ EXAMPLES::
253+
254+ sage: P = Primes(modulus=4)
255+ sage: P
256+ Set of prime numbers congruent to 1 modulo 4: 5, 13, 17, 29, ...
257+ sage: P.congruence_classes()
258+ (4, [1])
259+
260+ If possible, the congruence classes are simplified::
261+
262+ sage: P = Primes(modulus=10, classes=[1, 3])
263+ sage: P
264+ Set of prime numbers congruent to 1, 3 modulo 5: 3, 11, 13, 23, ...
265+ sage: P.congruence_classes()
266+ (5, [1, 3])
267+
268+ If this subset is finite, the output of this method is always `(1, [])`.
269+ The elements of the subset can be retreived using the method :meth:`list`
270+ or :meth:`included`::
271+
272+ sage: P = Primes(modulus=0, classes=range(50))
273+ sage: P
274+ Finite set of prime numbers: 2, 3, 5, 7, ..., 43, 47
275+ sage: P.congruence_classes()
276+ (1, [])
277+ sage: list(P)
278+ [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]
279+
280+ .. SEEALSO::
281+
282+ :meth:`included`, :meth:`excluded`
283+ """
284+ classes = list (self ._classes )
285+ classes .sort ()
286+ return (self ._modulus , classes )
287+
288+ def included (self ):
289+ r"""
290+ Return the list of elements which are additionally included
291+ (that are, outside the congruence classes) to this set.
292+
293+ EXAMPLES::
294+
295+ sage: P = Primes(modulus=4)
296+ sage: P
297+ Set of prime numbers congruent to 1 modulo 4: 5, 13, 17, 29, ...
298+ sage: P.included()
299+ []
300+
301+ ::
302+
303+ sage: Q = P.include(2)
304+ sage: Q
305+ Set of prime numbers congruent to 1 modulo 4 with 2 included: 2, 5, 13, 17, ...
306+ sage: Q.included()
307+ [2]
308+
309+ .. SEEALSO::
310+
311+ :meth:`excluded`, :meth:`congruence_classes`
312+ """
313+ included = [x for x , b in self ._exceptions .items () if b ]
314+ included .sort ()
315+ return included
316+
317+ def excluded (self ):
318+ r"""
319+ Return the list of elements which are excluded, that are the
320+ elements in the congruence classes defining this subset but
321+ not in this subset.
322+
323+ EXAMPLES::
324+
325+ sage: P = Primes(modulus=4)
326+ sage: P
327+ Set of prime numbers congruent to 1 modulo 4: 5, 13, 17, 29, ...
328+ sage: P.excluded()
329+ []
330+
331+ ::
332+
333+ sage: Q = P.exclude(5)
334+ sage: Q
335+ Set of prime numbers congruent to 1 modulo 4 with 5 excluded: 13, 17, 29, 37, ...
336+ sage: Q.excluded()
337+ [5]
338+
339+ .. SEEALSO::
340+
341+ :meth:`included`, :meth:`congruence_classes`
342+ """
343+ excluded = [x for x , b in self ._exceptions .items () if not b ]
344+ excluded .sort ()
345+ return excluded
346+
233347 def _repr_ (self ):
234348 r"""
235349 Return a string representation of this subset.
@@ -244,35 +358,27 @@ def _repr_(self):
244358 Empty set of prime numbers
245359
246360 sage: E.include(range(50), check=False) # indirect doctest
247- Finite set of prime numbers: 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41 , 43, 47
361+ Finite set of prime numbers: 2, 3, 5, 7, ... , 43, 47
248362 """
249- classes = sorted (list (self ._classes ))
250- sc = ", " .join ([str (c ) for c in classes ])
251- included = []
252- excluded = []
253- for x , b in self ._exceptions .items ():
254- if b :
255- included .append (x )
256- else :
257- excluded .append (x )
258- si = ", " .join ([str (i ) for i in sorted (included )])
259- se = ", " .join ([str (e ) for e in sorted (excluded )])
363+ _ , classes = self .congruence_classes ()
364+ included = self .included ()
365+ excluded = self .excluded ()
260366 if not classes :
261367 if not included :
262368 return "Empty set of prime numbers"
263369 else :
264- return "Finite set of prime numbers: %s" % si
370+ return "Finite set of prime numbers: %s" % repr_list ( included )
265371 if self ._modulus == 1 :
266372 s = "Set of all prime numbers"
267373 else :
268- s = "Set of prime numbers congruent to %s modulo %s" % (sc , self ._modulus )
374+ s = "Set of prime numbers congruent to %s modulo %s" % (repr_list ( classes ) , self ._modulus )
269375 if included :
270- s += " with %s included" % si
376+ s += " with %s included" % repr_list ( included )
271377 if excluded :
272378 if not included :
273- s += " with %s excluded" % se
379+ s += " with %s excluded" % repr_list ( excluded )
274380 else :
275- s += " and %s excluded" % se
381+ s += " and %s excluded" % repr_list ( excluded )
276382 s += ": %s, ..." % (", " .join ([str (n ) for n in self [:4 ]]))
277383 return s
278384
0 commit comments