Skip to content

Commit c24b6cb

Browse files
author
Xavier Caruso
committed
improve intersection and union
1 parent 66e5d69 commit c24b6cb

File tree

1 file changed

+35
-11
lines changed

1 file changed

+35
-11
lines changed

src/sage/sets/primes.py

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
# https://www.gnu.org/licenses/
2020
# ****************************************************************************
2121

22+
from sage.rings.semirings.non_negative_integer_semiring import NN
2223
from sage.rings.integer_ring import ZZ
2324
from sage.rings.infinity import infinity
2425
from .set import Set_generic
@@ -840,18 +841,20 @@ def intersection(self, other):
840841
841842
::
842843
844+
sage: P.intersection(NN) == P
845+
True
843846
sage: P.intersection(ZZ) == P
844847
True
845848
sage: P.intersection(RR)
846849
Traceback (most recent call last):
847850
...
848-
NotImplementedError: object does not support iteration
851+
NotImplementedError: intersection with general infinite sets is not implemented
849852
850853
.. SEEALSO::
851854
852855
:meth:`complement_in_primes`, :meth:`union`
853856
"""
854-
if other is ZZ:
857+
if other is NN or other is ZZ:
855858
return self
856859
if isinstance(other, Primes):
857860
modulus = self._modulus.lcm(other._modulus)
@@ -862,15 +865,30 @@ def intersection(self, other):
862865
if not b or x in other}
863866
exceptions.update((x, b) for x, b in other._exceptions.items()
864867
if not b or x in self)
865-
elif self.is_finite():
866-
modulus = 1
867-
classes = []
868-
exceptions = {x: True for x in self if x in other}
869868
else:
870-
# we try to enumerate the elements of "other"
871869
modulus = 1
872870
classes = []
873-
exceptions = {x: True for x in list(other) if x in self}
871+
if isinstance(other, range) and other.step == 1:
872+
exceptions = {}
873+
x = other.start - 1
874+
while True:
875+
try:
876+
x = self.next(x)
877+
except ValueError:
878+
break
879+
if x >= other.stop:
880+
break
881+
exceptions[x] = True
882+
elif self.is_finite() and hasattr(other, "__contains__"):
883+
# this would not work reliably if ``other`` does not
884+
# implement ``__contains__``, because ``x in other``
885+
# then consumes ``other``
886+
exceptions = {x: True for x in self if x in other}
887+
else:
888+
if hasattr(other, "is_finite") and not other.is_finite():
889+
raise NotImplementedError("intersection with general infinite sets is not implemented")
890+
# if other is infinite but does not know it, this will loop forever
891+
exceptions = {x: True for x in other if x in self}
874892
return Primes(modulus, classes, exceptions)
875893

876894
def union(self, other):
@@ -901,17 +919,21 @@ def union(self, other):
901919
902920
::
903921
922+
sage: P.union(NN) == NN
923+
True
904924
sage: P.union(ZZ) == ZZ
905925
True
906926
sage: P.union(RR)
907927
Traceback (most recent call last):
908928
...
909-
NotImplementedError: object does not support iteration
929+
NotImplementedError: union with general infinite sets is not implemented
910930
911931
.. SEEALSO::
912932
913933
:meth:`complement_in_primes`, :meth:`intersection`
914934
"""
935+
if other is NN:
936+
return NN
915937
if other is ZZ:
916938
return ZZ
917939
if isinstance(other, Primes):
@@ -924,11 +946,13 @@ def union(self, other):
924946
exceptions.update((x, b) for x, b in other._exceptions.items()
925947
if b or x not in self)
926948
else:
927-
# we try to enumerate the elements of "other"
949+
# we try to enumerate the elements of "other
950+
if hasattr(other, "is_finite") and not other.is_finite():
951+
raise NotImplementedError("union with general infinite sets is not implemented")
928952
modulus = self._modulus
929953
classes = self._classes
930954
exceptions = self._exceptions.copy()
931-
for x in list(other):
955+
for x in other:
932956
x = ZZ(x)
933957
if x.is_prime():
934958
exceptions[x] = True

0 commit comments

Comments
 (0)