1919# https://www.gnu.org/licenses/
2020# ****************************************************************************
2121
22+ from sage .rings .semirings .non_negative_integer_semiring import NN
2223from sage .rings .integer_ring import ZZ
2324from sage .rings .infinity import infinity
2425from .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