sets.py 71 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546
  1. from typing import Any, Callable, Optional
  2. from functools import reduce
  3. from collections import defaultdict
  4. import inspect
  5. from sympy.core.basic import Basic
  6. from sympy.core.containers import Tuple
  7. from sympy.core.decorators import sympify_method_args, sympify_return
  8. from sympy.core.evalf import EvalfMixin
  9. from sympy.core.expr import Expr
  10. from sympy.core.function import Lambda
  11. from sympy.core.logic import (FuzzyBool, fuzzy_bool, fuzzy_or, fuzzy_and,
  12. fuzzy_not)
  13. from sympy.core.numbers import Float, Integer
  14. from sympy.core.operations import LatticeOp
  15. from sympy.core.parameters import global_parameters
  16. from sympy.core.relational import Eq, Ne, is_lt
  17. from sympy.core.singleton import Singleton, S
  18. from sympy.core.sorting import ordered
  19. from sympy.core.symbol import symbols, Symbol, Dummy, uniquely_named_symbol
  20. from sympy.core.sympify import _sympify, sympify, _sympy_converter
  21. from sympy.functions.elementary.miscellaneous import Max, Min
  22. from sympy.logic.boolalg import And, Or, Not, Xor, true, false
  23. from sympy.utilities.decorator import deprecated
  24. from sympy.utilities.exceptions import sympy_deprecation_warning
  25. from sympy.utilities.iterables import (iproduct, sift, roundrobin, iterable,
  26. subsets)
  27. from sympy.utilities.misc import func_name, filldedent
  28. from mpmath import mpi, mpf
  29. from mpmath.libmp.libmpf import prec_to_dps
  30. tfn = defaultdict(lambda: None, {
  31. True: S.true,
  32. S.true: S.true,
  33. False: S.false,
  34. S.false: S.false})
  35. @sympify_method_args
  36. class Set(Basic, EvalfMixin):
  37. """
  38. The base class for any kind of set.
  39. Explanation
  40. ===========
  41. This is not meant to be used directly as a container of items. It does not
  42. behave like the builtin ``set``; see :class:`FiniteSet` for that.
  43. Real intervals are represented by the :class:`Interval` class and unions of
  44. sets by the :class:`Union` class. The empty set is represented by the
  45. :class:`EmptySet` class and available as a singleton as ``S.EmptySet``.
  46. """
  47. is_number = False
  48. is_iterable = False
  49. is_interval = False
  50. is_FiniteSet = False
  51. is_Interval = False
  52. is_ProductSet = False
  53. is_Union = False
  54. is_Intersection = None # type: Optional[bool]
  55. is_UniversalSet = None # type: Optional[bool]
  56. is_Complement = None # type: Optional[bool]
  57. is_ComplexRegion = False
  58. is_empty = None # type: FuzzyBool
  59. is_finite_set = None # type: FuzzyBool
  60. @property # type: ignore
  61. @deprecated(
  62. """
  63. The is_EmptySet attribute of Set objects is deprecated.
  64. Use 's is S.EmptySet" or 's.is_empty' instead.
  65. """,
  66. deprecated_since_version="1.5",
  67. active_deprecations_target="deprecated-is-emptyset",
  68. )
  69. def is_EmptySet(self):
  70. return None
  71. @staticmethod
  72. def _infimum_key(expr):
  73. """
  74. Return infimum (if possible) else S.Infinity.
  75. """
  76. try:
  77. infimum = expr.inf
  78. assert infimum.is_comparable
  79. infimum = infimum.evalf() # issue #18505
  80. except (NotImplementedError,
  81. AttributeError, AssertionError, ValueError):
  82. infimum = S.Infinity
  83. return infimum
  84. def union(self, other):
  85. """
  86. Returns the union of ``self`` and ``other``.
  87. Examples
  88. ========
  89. As a shortcut it is possible to use the ``+`` operator:
  90. >>> from sympy import Interval, FiniteSet
  91. >>> Interval(0, 1).union(Interval(2, 3))
  92. Union(Interval(0, 1), Interval(2, 3))
  93. >>> Interval(0, 1) + Interval(2, 3)
  94. Union(Interval(0, 1), Interval(2, 3))
  95. >>> Interval(1, 2, True, True) + FiniteSet(2, 3)
  96. Union({3}, Interval.Lopen(1, 2))
  97. Similarly it is possible to use the ``-`` operator for set differences:
  98. >>> Interval(0, 2) - Interval(0, 1)
  99. Interval.Lopen(1, 2)
  100. >>> Interval(1, 3) - FiniteSet(2)
  101. Union(Interval.Ropen(1, 2), Interval.Lopen(2, 3))
  102. """
  103. return Union(self, other)
  104. def intersect(self, other):
  105. """
  106. Returns the intersection of 'self' and 'other'.
  107. Examples
  108. ========
  109. >>> from sympy import Interval
  110. >>> Interval(1, 3).intersect(Interval(1, 2))
  111. Interval(1, 2)
  112. >>> from sympy import imageset, Lambda, symbols, S
  113. >>> n, m = symbols('n m')
  114. >>> a = imageset(Lambda(n, 2*n), S.Integers)
  115. >>> a.intersect(imageset(Lambda(m, 2*m + 1), S.Integers))
  116. EmptySet
  117. """
  118. return Intersection(self, other)
  119. def intersection(self, other):
  120. """
  121. Alias for :meth:`intersect()`
  122. """
  123. return self.intersect(other)
  124. def is_disjoint(self, other):
  125. """
  126. Returns True if ``self`` and ``other`` are disjoint.
  127. Examples
  128. ========
  129. >>> from sympy import Interval
  130. >>> Interval(0, 2).is_disjoint(Interval(1, 2))
  131. False
  132. >>> Interval(0, 2).is_disjoint(Interval(3, 4))
  133. True
  134. References
  135. ==========
  136. .. [1] https://en.wikipedia.org/wiki/Disjoint_sets
  137. """
  138. return self.intersect(other) == S.EmptySet
  139. def isdisjoint(self, other):
  140. """
  141. Alias for :meth:`is_disjoint()`
  142. """
  143. return self.is_disjoint(other)
  144. def complement(self, universe):
  145. r"""
  146. The complement of 'self' w.r.t the given universe.
  147. Examples
  148. ========
  149. >>> from sympy import Interval, S
  150. >>> Interval(0, 1).complement(S.Reals)
  151. Union(Interval.open(-oo, 0), Interval.open(1, oo))
  152. >>> Interval(0, 1).complement(S.UniversalSet)
  153. Complement(UniversalSet, Interval(0, 1))
  154. """
  155. return Complement(universe, self)
  156. def _complement(self, other):
  157. # this behaves as other - self
  158. if isinstance(self, ProductSet) and isinstance(other, ProductSet):
  159. # If self and other are disjoint then other - self == self
  160. if len(self.sets) != len(other.sets):
  161. return other
  162. # There can be other ways to represent this but this gives:
  163. # (A x B) - (C x D) = ((A - C) x B) U (A x (B - D))
  164. overlaps = []
  165. pairs = list(zip(self.sets, other.sets))
  166. for n in range(len(pairs)):
  167. sets = (o if i != n else o-s for i, (s, o) in enumerate(pairs))
  168. overlaps.append(ProductSet(*sets))
  169. return Union(*overlaps)
  170. elif isinstance(other, Interval):
  171. if isinstance(self, (Interval, FiniteSet)):
  172. return Intersection(other, self.complement(S.Reals))
  173. elif isinstance(other, Union):
  174. return Union(*(o - self for o in other.args))
  175. elif isinstance(other, Complement):
  176. return Complement(other.args[0], Union(other.args[1], self), evaluate=False)
  177. elif other is S.EmptySet:
  178. return S.EmptySet
  179. elif isinstance(other, FiniteSet):
  180. sifted = sift(other, lambda x: fuzzy_bool(self.contains(x)))
  181. # ignore those that are contained in self
  182. return Union(FiniteSet(*(sifted[False])),
  183. Complement(FiniteSet(*(sifted[None])), self, evaluate=False)
  184. if sifted[None] else S.EmptySet)
  185. def symmetric_difference(self, other):
  186. """
  187. Returns symmetric difference of ``self`` and ``other``.
  188. Examples
  189. ========
  190. >>> from sympy import Interval, S
  191. >>> Interval(1, 3).symmetric_difference(S.Reals)
  192. Union(Interval.open(-oo, 1), Interval.open(3, oo))
  193. >>> Interval(1, 10).symmetric_difference(S.Reals)
  194. Union(Interval.open(-oo, 1), Interval.open(10, oo))
  195. >>> from sympy import S, EmptySet
  196. >>> S.Reals.symmetric_difference(EmptySet)
  197. Reals
  198. References
  199. ==========
  200. .. [1] https://en.wikipedia.org/wiki/Symmetric_difference
  201. """
  202. return SymmetricDifference(self, other)
  203. def _symmetric_difference(self, other):
  204. return Union(Complement(self, other), Complement(other, self))
  205. @property
  206. def inf(self):
  207. """
  208. The infimum of ``self``.
  209. Examples
  210. ========
  211. >>> from sympy import Interval, Union
  212. >>> Interval(0, 1).inf
  213. 0
  214. >>> Union(Interval(0, 1), Interval(2, 3)).inf
  215. 0
  216. """
  217. return self._inf
  218. @property
  219. def _inf(self):
  220. raise NotImplementedError("(%s)._inf" % self)
  221. @property
  222. def sup(self):
  223. """
  224. The supremum of ``self``.
  225. Examples
  226. ========
  227. >>> from sympy import Interval, Union
  228. >>> Interval(0, 1).sup
  229. 1
  230. >>> Union(Interval(0, 1), Interval(2, 3)).sup
  231. 3
  232. """
  233. return self._sup
  234. @property
  235. def _sup(self):
  236. raise NotImplementedError("(%s)._sup" % self)
  237. def contains(self, other):
  238. """
  239. Returns a SymPy value indicating whether ``other`` is contained
  240. in ``self``: ``true`` if it is, ``false`` if it isn't, else
  241. an unevaluated ``Contains`` expression (or, as in the case of
  242. ConditionSet and a union of FiniteSet/Intervals, an expression
  243. indicating the conditions for containment).
  244. Examples
  245. ========
  246. >>> from sympy import Interval, S
  247. >>> from sympy.abc import x
  248. >>> Interval(0, 1).contains(0.5)
  249. True
  250. As a shortcut it is possible to use the ``in`` operator, but that
  251. will raise an error unless an affirmative true or false is not
  252. obtained.
  253. >>> Interval(0, 1).contains(x)
  254. (0 <= x) & (x <= 1)
  255. >>> x in Interval(0, 1)
  256. Traceback (most recent call last):
  257. ...
  258. TypeError: did not evaluate to a bool: None
  259. The result of 'in' is a bool, not a SymPy value
  260. >>> 1 in Interval(0, 2)
  261. True
  262. >>> _ is S.true
  263. False
  264. """
  265. from .contains import Contains
  266. other = sympify(other, strict=True)
  267. c = self._contains(other)
  268. if isinstance(c, Contains):
  269. return c
  270. if c is None:
  271. return Contains(other, self, evaluate=False)
  272. b = tfn[c]
  273. if b is None:
  274. return c
  275. return b
  276. def _contains(self, other):
  277. raise NotImplementedError(filldedent('''
  278. (%s)._contains(%s) is not defined. This method, when
  279. defined, will receive a sympified object. The method
  280. should return True, False, None or something that
  281. expresses what must be true for the containment of that
  282. object in self to be evaluated. If None is returned
  283. then a generic Contains object will be returned
  284. by the ``contains`` method.''' % (self, other)))
  285. def is_subset(self, other):
  286. """
  287. Returns True if ``self`` is a subset of ``other``.
  288. Examples
  289. ========
  290. >>> from sympy import Interval
  291. >>> Interval(0, 0.5).is_subset(Interval(0, 1))
  292. True
  293. >>> Interval(0, 1).is_subset(Interval(0, 1, left_open=True))
  294. False
  295. """
  296. if not isinstance(other, Set):
  297. raise ValueError("Unknown argument '%s'" % other)
  298. # Handle the trivial cases
  299. if self == other:
  300. return True
  301. is_empty = self.is_empty
  302. if is_empty is True:
  303. return True
  304. elif fuzzy_not(is_empty) and other.is_empty:
  305. return False
  306. if self.is_finite_set is False and other.is_finite_set:
  307. return False
  308. # Dispatch on subclass rules
  309. ret = self._eval_is_subset(other)
  310. if ret is not None:
  311. return ret
  312. ret = other._eval_is_superset(self)
  313. if ret is not None:
  314. return ret
  315. # Use pairwise rules from multiple dispatch
  316. from sympy.sets.handlers.issubset import is_subset_sets
  317. ret = is_subset_sets(self, other)
  318. if ret is not None:
  319. return ret
  320. # Fall back on computing the intersection
  321. # XXX: We shouldn't do this. A query like this should be handled
  322. # without evaluating new Set objects. It should be the other way round
  323. # so that the intersect method uses is_subset for evaluation.
  324. if self.intersect(other) == self:
  325. return True
  326. def _eval_is_subset(self, other):
  327. '''Returns a fuzzy bool for whether self is a subset of other.'''
  328. return None
  329. def _eval_is_superset(self, other):
  330. '''Returns a fuzzy bool for whether self is a subset of other.'''
  331. return None
  332. # This should be deprecated:
  333. def issubset(self, other):
  334. """
  335. Alias for :meth:`is_subset()`
  336. """
  337. return self.is_subset(other)
  338. def is_proper_subset(self, other):
  339. """
  340. Returns True if ``self`` is a proper subset of ``other``.
  341. Examples
  342. ========
  343. >>> from sympy import Interval
  344. >>> Interval(0, 0.5).is_proper_subset(Interval(0, 1))
  345. True
  346. >>> Interval(0, 1).is_proper_subset(Interval(0, 1))
  347. False
  348. """
  349. if isinstance(other, Set):
  350. return self != other and self.is_subset(other)
  351. else:
  352. raise ValueError("Unknown argument '%s'" % other)
  353. def is_superset(self, other):
  354. """
  355. Returns True if ``self`` is a superset of ``other``.
  356. Examples
  357. ========
  358. >>> from sympy import Interval
  359. >>> Interval(0, 0.5).is_superset(Interval(0, 1))
  360. False
  361. >>> Interval(0, 1).is_superset(Interval(0, 1, left_open=True))
  362. True
  363. """
  364. if isinstance(other, Set):
  365. return other.is_subset(self)
  366. else:
  367. raise ValueError("Unknown argument '%s'" % other)
  368. # This should be deprecated:
  369. def issuperset(self, other):
  370. """
  371. Alias for :meth:`is_superset()`
  372. """
  373. return self.is_superset(other)
  374. def is_proper_superset(self, other):
  375. """
  376. Returns True if ``self`` is a proper superset of ``other``.
  377. Examples
  378. ========
  379. >>> from sympy import Interval
  380. >>> Interval(0, 1).is_proper_superset(Interval(0, 0.5))
  381. True
  382. >>> Interval(0, 1).is_proper_superset(Interval(0, 1))
  383. False
  384. """
  385. if isinstance(other, Set):
  386. return self != other and self.is_superset(other)
  387. else:
  388. raise ValueError("Unknown argument '%s'" % other)
  389. def _eval_powerset(self):
  390. from .powerset import PowerSet
  391. return PowerSet(self)
  392. def powerset(self):
  393. """
  394. Find the Power set of ``self``.
  395. Examples
  396. ========
  397. >>> from sympy import EmptySet, FiniteSet, Interval
  398. A power set of an empty set:
  399. >>> A = EmptySet
  400. >>> A.powerset()
  401. {EmptySet}
  402. A power set of a finite set:
  403. >>> A = FiniteSet(1, 2)
  404. >>> a, b, c = FiniteSet(1), FiniteSet(2), FiniteSet(1, 2)
  405. >>> A.powerset() == FiniteSet(a, b, c, EmptySet)
  406. True
  407. A power set of an interval:
  408. >>> Interval(1, 2).powerset()
  409. PowerSet(Interval(1, 2))
  410. References
  411. ==========
  412. .. [1] https://en.wikipedia.org/wiki/Power_set
  413. """
  414. return self._eval_powerset()
  415. @property
  416. def measure(self):
  417. """
  418. The (Lebesgue) measure of ``self``.
  419. Examples
  420. ========
  421. >>> from sympy import Interval, Union
  422. >>> Interval(0, 1).measure
  423. 1
  424. >>> Union(Interval(0, 1), Interval(2, 3)).measure
  425. 2
  426. """
  427. return self._measure
  428. @property
  429. def boundary(self):
  430. """
  431. The boundary or frontier of a set.
  432. Explanation
  433. ===========
  434. A point x is on the boundary of a set S if
  435. 1. x is in the closure of S.
  436. I.e. Every neighborhood of x contains a point in S.
  437. 2. x is not in the interior of S.
  438. I.e. There does not exist an open set centered on x contained
  439. entirely within S.
  440. There are the points on the outer rim of S. If S is open then these
  441. points need not actually be contained within S.
  442. For example, the boundary of an interval is its start and end points.
  443. This is true regardless of whether or not the interval is open.
  444. Examples
  445. ========
  446. >>> from sympy import Interval
  447. >>> Interval(0, 1).boundary
  448. {0, 1}
  449. >>> Interval(0, 1, True, False).boundary
  450. {0, 1}
  451. """
  452. return self._boundary
  453. @property
  454. def is_open(self):
  455. """
  456. Property method to check whether a set is open.
  457. Explanation
  458. ===========
  459. A set is open if and only if it has an empty intersection with its
  460. boundary. In particular, a subset A of the reals is open if and only
  461. if each one of its points is contained in an open interval that is a
  462. subset of A.
  463. Examples
  464. ========
  465. >>> from sympy import S
  466. >>> S.Reals.is_open
  467. True
  468. >>> S.Rationals.is_open
  469. False
  470. """
  471. return Intersection(self, self.boundary).is_empty
  472. @property
  473. def is_closed(self):
  474. """
  475. A property method to check whether a set is closed.
  476. Explanation
  477. ===========
  478. A set is closed if its complement is an open set. The closedness of a
  479. subset of the reals is determined with respect to R and its standard
  480. topology.
  481. Examples
  482. ========
  483. >>> from sympy import Interval
  484. >>> Interval(0, 1).is_closed
  485. True
  486. """
  487. return self.boundary.is_subset(self)
  488. @property
  489. def closure(self):
  490. """
  491. Property method which returns the closure of a set.
  492. The closure is defined as the union of the set itself and its
  493. boundary.
  494. Examples
  495. ========
  496. >>> from sympy import S, Interval
  497. >>> S.Reals.closure
  498. Reals
  499. >>> Interval(0, 1).closure
  500. Interval(0, 1)
  501. """
  502. return self + self.boundary
  503. @property
  504. def interior(self):
  505. """
  506. Property method which returns the interior of a set.
  507. The interior of a set S consists all points of S that do not
  508. belong to the boundary of S.
  509. Examples
  510. ========
  511. >>> from sympy import Interval
  512. >>> Interval(0, 1).interior
  513. Interval.open(0, 1)
  514. >>> Interval(0, 1).boundary.interior
  515. EmptySet
  516. """
  517. return self - self.boundary
  518. @property
  519. def _boundary(self):
  520. raise NotImplementedError()
  521. @property
  522. def _measure(self):
  523. raise NotImplementedError("(%s)._measure" % self)
  524. def _eval_evalf(self, prec):
  525. dps = prec_to_dps(prec)
  526. return self.func(*[arg.evalf(n=dps) for arg in self.args])
  527. @sympify_return([('other', 'Set')], NotImplemented)
  528. def __add__(self, other):
  529. return self.union(other)
  530. @sympify_return([('other', 'Set')], NotImplemented)
  531. def __or__(self, other):
  532. return self.union(other)
  533. @sympify_return([('other', 'Set')], NotImplemented)
  534. def __and__(self, other):
  535. return self.intersect(other)
  536. @sympify_return([('other', 'Set')], NotImplemented)
  537. def __mul__(self, other):
  538. return ProductSet(self, other)
  539. @sympify_return([('other', 'Set')], NotImplemented)
  540. def __xor__(self, other):
  541. return SymmetricDifference(self, other)
  542. @sympify_return([('exp', Expr)], NotImplemented)
  543. def __pow__(self, exp):
  544. if not (exp.is_Integer and exp >= 0):
  545. raise ValueError("%s: Exponent must be a positive Integer" % exp)
  546. return ProductSet(*[self]*exp)
  547. @sympify_return([('other', 'Set')], NotImplemented)
  548. def __sub__(self, other):
  549. return Complement(self, other)
  550. def __contains__(self, other):
  551. other = _sympify(other)
  552. c = self._contains(other)
  553. b = tfn[c]
  554. if b is None:
  555. # x in y must evaluate to T or F; to entertain a None
  556. # result with Set use y.contains(x)
  557. raise TypeError('did not evaluate to a bool: %r' % c)
  558. return b
  559. class ProductSet(Set):
  560. """
  561. Represents a Cartesian Product of Sets.
  562. Explanation
  563. ===========
  564. Returns a Cartesian product given several sets as either an iterable
  565. or individual arguments.
  566. Can use ``*`` operator on any sets for convenient shorthand.
  567. Examples
  568. ========
  569. >>> from sympy import Interval, FiniteSet, ProductSet
  570. >>> I = Interval(0, 5); S = FiniteSet(1, 2, 3)
  571. >>> ProductSet(I, S)
  572. ProductSet(Interval(0, 5), {1, 2, 3})
  573. >>> (2, 2) in ProductSet(I, S)
  574. True
  575. >>> Interval(0, 1) * Interval(0, 1) # The unit square
  576. ProductSet(Interval(0, 1), Interval(0, 1))
  577. >>> coin = FiniteSet('H', 'T')
  578. >>> set(coin**2)
  579. {(H, H), (H, T), (T, H), (T, T)}
  580. The Cartesian product is not commutative or associative e.g.:
  581. >>> I*S == S*I
  582. False
  583. >>> (I*I)*I == I*(I*I)
  584. False
  585. Notes
  586. =====
  587. - Passes most operations down to the argument sets
  588. References
  589. ==========
  590. .. [1] https://en.wikipedia.org/wiki/Cartesian_product
  591. """
  592. is_ProductSet = True
  593. def __new__(cls, *sets, **assumptions):
  594. if len(sets) == 1 and iterable(sets[0]) and not isinstance(sets[0], (Set, set)):
  595. sympy_deprecation_warning(
  596. """
  597. ProductSet(iterable) is deprecated. Use ProductSet(*iterable) instead.
  598. """,
  599. deprecated_since_version="1.5",
  600. active_deprecations_target="deprecated-productset-iterable",
  601. )
  602. sets = tuple(sets[0])
  603. sets = [sympify(s) for s in sets]
  604. if not all(isinstance(s, Set) for s in sets):
  605. raise TypeError("Arguments to ProductSet should be of type Set")
  606. # Nullary product of sets is *not* the empty set
  607. if len(sets) == 0:
  608. return FiniteSet(())
  609. if S.EmptySet in sets:
  610. return S.EmptySet
  611. return Basic.__new__(cls, *sets, **assumptions)
  612. @property
  613. def sets(self):
  614. return self.args
  615. def flatten(self):
  616. def _flatten(sets):
  617. for s in sets:
  618. if s.is_ProductSet:
  619. yield from _flatten(s.sets)
  620. else:
  621. yield s
  622. return ProductSet(*_flatten(self.sets))
  623. def _contains(self, element):
  624. """
  625. ``in`` operator for ProductSets.
  626. Examples
  627. ========
  628. >>> from sympy import Interval
  629. >>> (2, 3) in Interval(0, 5) * Interval(0, 5)
  630. True
  631. >>> (10, 10) in Interval(0, 5) * Interval(0, 5)
  632. False
  633. Passes operation on to constituent sets
  634. """
  635. if element.is_Symbol:
  636. return None
  637. if not isinstance(element, Tuple) or len(element) != len(self.sets):
  638. return False
  639. return fuzzy_and(s._contains(e) for s, e in zip(self.sets, element))
  640. def as_relational(self, *symbols):
  641. symbols = [_sympify(s) for s in symbols]
  642. if len(symbols) != len(self.sets) or not all(
  643. i.is_Symbol for i in symbols):
  644. raise ValueError(
  645. 'number of symbols must match the number of sets')
  646. return And(*[s.as_relational(i) for s, i in zip(self.sets, symbols)])
  647. @property
  648. def _boundary(self):
  649. return Union(*(ProductSet(*(b + b.boundary if i != j else b.boundary
  650. for j, b in enumerate(self.sets)))
  651. for i, a in enumerate(self.sets)))
  652. @property
  653. def is_iterable(self):
  654. """
  655. A property method which tests whether a set is iterable or not.
  656. Returns True if set is iterable, otherwise returns False.
  657. Examples
  658. ========
  659. >>> from sympy import FiniteSet, Interval
  660. >>> I = Interval(0, 1)
  661. >>> A = FiniteSet(1, 2, 3, 4, 5)
  662. >>> I.is_iterable
  663. False
  664. >>> A.is_iterable
  665. True
  666. """
  667. return all(set.is_iterable for set in self.sets)
  668. def __iter__(self):
  669. """
  670. A method which implements is_iterable property method.
  671. If self.is_iterable returns True (both constituent sets are iterable),
  672. then return the Cartesian Product. Otherwise, raise TypeError.
  673. """
  674. return iproduct(*self.sets)
  675. @property
  676. def is_empty(self):
  677. return fuzzy_or(s.is_empty for s in self.sets)
  678. @property
  679. def is_finite_set(self):
  680. all_finite = fuzzy_and(s.is_finite_set for s in self.sets)
  681. return fuzzy_or([self.is_empty, all_finite])
  682. @property
  683. def _measure(self):
  684. measure = 1
  685. for s in self.sets:
  686. measure *= s.measure
  687. return measure
  688. def __len__(self):
  689. return reduce(lambda a, b: a*b, (len(s) for s in self.args))
  690. def __bool__(self):
  691. return all(self.sets)
  692. class Interval(Set):
  693. """
  694. Represents a real interval as a Set.
  695. Usage:
  696. Returns an interval with end points ``start`` and ``end``.
  697. For ``left_open=True`` (default ``left_open`` is ``False``) the interval
  698. will be open on the left. Similarly, for ``right_open=True`` the interval
  699. will be open on the right.
  700. Examples
  701. ========
  702. >>> from sympy import Symbol, Interval
  703. >>> Interval(0, 1)
  704. Interval(0, 1)
  705. >>> Interval.Ropen(0, 1)
  706. Interval.Ropen(0, 1)
  707. >>> Interval.Ropen(0, 1)
  708. Interval.Ropen(0, 1)
  709. >>> Interval.Lopen(0, 1)
  710. Interval.Lopen(0, 1)
  711. >>> Interval.open(0, 1)
  712. Interval.open(0, 1)
  713. >>> a = Symbol('a', real=True)
  714. >>> Interval(0, a)
  715. Interval(0, a)
  716. Notes
  717. =====
  718. - Only real end points are supported
  719. - ``Interval(a, b)`` with $a > b$ will return the empty set
  720. - Use the ``evalf()`` method to turn an Interval into an mpmath
  721. ``mpi`` interval instance
  722. References
  723. ==========
  724. .. [1] https://en.wikipedia.org/wiki/Interval_%28mathematics%29
  725. """
  726. is_Interval = True
  727. def __new__(cls, start, end, left_open=False, right_open=False):
  728. start = _sympify(start)
  729. end = _sympify(end)
  730. left_open = _sympify(left_open)
  731. right_open = _sympify(right_open)
  732. if not all(isinstance(a, (type(true), type(false)))
  733. for a in [left_open, right_open]):
  734. raise NotImplementedError(
  735. "left_open and right_open can have only true/false values, "
  736. "got %s and %s" % (left_open, right_open))
  737. # Only allow real intervals
  738. if fuzzy_not(fuzzy_and(i.is_extended_real for i in (start, end, end-start))):
  739. raise ValueError("Non-real intervals are not supported")
  740. # evaluate if possible
  741. if is_lt(end, start):
  742. return S.EmptySet
  743. elif (end - start).is_negative:
  744. return S.EmptySet
  745. if end == start and (left_open or right_open):
  746. return S.EmptySet
  747. if end == start and not (left_open or right_open):
  748. if start is S.Infinity or start is S.NegativeInfinity:
  749. return S.EmptySet
  750. return FiniteSet(end)
  751. # Make sure infinite interval end points are open.
  752. if start is S.NegativeInfinity:
  753. left_open = true
  754. if end is S.Infinity:
  755. right_open = true
  756. if start == S.Infinity or end == S.NegativeInfinity:
  757. return S.EmptySet
  758. return Basic.__new__(cls, start, end, left_open, right_open)
  759. @property
  760. def start(self):
  761. """
  762. The left end point of the interval.
  763. This property takes the same value as the ``inf`` property.
  764. Examples
  765. ========
  766. >>> from sympy import Interval
  767. >>> Interval(0, 1).start
  768. 0
  769. """
  770. return self._args[0]
  771. @property
  772. def end(self):
  773. """
  774. The right end point of the interval.
  775. This property takes the same value as the ``sup`` property.
  776. Examples
  777. ========
  778. >>> from sympy import Interval
  779. >>> Interval(0, 1).end
  780. 1
  781. """
  782. return self._args[1]
  783. @property
  784. def left_open(self):
  785. """
  786. True if interval is left-open.
  787. Examples
  788. ========
  789. >>> from sympy import Interval
  790. >>> Interval(0, 1, left_open=True).left_open
  791. True
  792. >>> Interval(0, 1, left_open=False).left_open
  793. False
  794. """
  795. return self._args[2]
  796. @property
  797. def right_open(self):
  798. """
  799. True if interval is right-open.
  800. Examples
  801. ========
  802. >>> from sympy import Interval
  803. >>> Interval(0, 1, right_open=True).right_open
  804. True
  805. >>> Interval(0, 1, right_open=False).right_open
  806. False
  807. """
  808. return self._args[3]
  809. @classmethod
  810. def open(cls, a, b):
  811. """Return an interval including neither boundary."""
  812. return cls(a, b, True, True)
  813. @classmethod
  814. def Lopen(cls, a, b):
  815. """Return an interval not including the left boundary."""
  816. return cls(a, b, True, False)
  817. @classmethod
  818. def Ropen(cls, a, b):
  819. """Return an interval not including the right boundary."""
  820. return cls(a, b, False, True)
  821. @property
  822. def _inf(self):
  823. return self.start
  824. @property
  825. def _sup(self):
  826. return self.end
  827. @property
  828. def left(self):
  829. return self.start
  830. @property
  831. def right(self):
  832. return self.end
  833. @property
  834. def is_empty(self):
  835. if self.left_open or self.right_open:
  836. cond = self.start >= self.end # One/both bounds open
  837. else:
  838. cond = self.start > self.end # Both bounds closed
  839. return fuzzy_bool(cond)
  840. @property
  841. def is_finite_set(self):
  842. return self.measure.is_zero
  843. def _complement(self, other):
  844. if other == S.Reals:
  845. a = Interval(S.NegativeInfinity, self.start,
  846. True, not self.left_open)
  847. b = Interval(self.end, S.Infinity, not self.right_open, True)
  848. return Union(a, b)
  849. if isinstance(other, FiniteSet):
  850. nums = [m for m in other.args if m.is_number]
  851. if nums == []:
  852. return None
  853. return Set._complement(self, other)
  854. @property
  855. def _boundary(self):
  856. finite_points = [p for p in (self.start, self.end)
  857. if abs(p) != S.Infinity]
  858. return FiniteSet(*finite_points)
  859. def _contains(self, other):
  860. if (not isinstance(other, Expr) or other is S.NaN
  861. or other.is_real is False or other.has(S.ComplexInfinity)):
  862. # if an expression has zoo it will be zoo or nan
  863. # and neither of those is real
  864. return false
  865. if self.start is S.NegativeInfinity and self.end is S.Infinity:
  866. if other.is_real is not None:
  867. return other.is_real
  868. d = Dummy()
  869. return self.as_relational(d).subs(d, other)
  870. def as_relational(self, x):
  871. """Rewrite an interval in terms of inequalities and logic operators."""
  872. x = sympify(x)
  873. if self.right_open:
  874. right = x < self.end
  875. else:
  876. right = x <= self.end
  877. if self.left_open:
  878. left = self.start < x
  879. else:
  880. left = self.start <= x
  881. return And(left, right)
  882. @property
  883. def _measure(self):
  884. return self.end - self.start
  885. def to_mpi(self, prec=53):
  886. return mpi(mpf(self.start._eval_evalf(prec)),
  887. mpf(self.end._eval_evalf(prec)))
  888. def _eval_evalf(self, prec):
  889. return Interval(self.left._evalf(prec), self.right._evalf(prec),
  890. left_open=self.left_open, right_open=self.right_open)
  891. def _is_comparable(self, other):
  892. is_comparable = self.start.is_comparable
  893. is_comparable &= self.end.is_comparable
  894. is_comparable &= other.start.is_comparable
  895. is_comparable &= other.end.is_comparable
  896. return is_comparable
  897. @property
  898. def is_left_unbounded(self):
  899. """Return ``True`` if the left endpoint is negative infinity. """
  900. return self.left is S.NegativeInfinity or self.left == Float("-inf")
  901. @property
  902. def is_right_unbounded(self):
  903. """Return ``True`` if the right endpoint is positive infinity. """
  904. return self.right is S.Infinity or self.right == Float("+inf")
  905. def _eval_Eq(self, other):
  906. if not isinstance(other, Interval):
  907. if isinstance(other, FiniteSet):
  908. return false
  909. elif isinstance(other, Set):
  910. return None
  911. return false
  912. class Union(Set, LatticeOp):
  913. """
  914. Represents a union of sets as a :class:`Set`.
  915. Examples
  916. ========
  917. >>> from sympy import Union, Interval
  918. >>> Union(Interval(1, 2), Interval(3, 4))
  919. Union(Interval(1, 2), Interval(3, 4))
  920. The Union constructor will always try to merge overlapping intervals,
  921. if possible. For example:
  922. >>> Union(Interval(1, 2), Interval(2, 3))
  923. Interval(1, 3)
  924. See Also
  925. ========
  926. Intersection
  927. References
  928. ==========
  929. .. [1] https://en.wikipedia.org/wiki/Union_%28set_theory%29
  930. """
  931. is_Union = True
  932. @property
  933. def identity(self):
  934. return S.EmptySet
  935. @property
  936. def zero(self):
  937. return S.UniversalSet
  938. def __new__(cls, *args, **kwargs):
  939. evaluate = kwargs.get('evaluate', global_parameters.evaluate)
  940. # flatten inputs to merge intersections and iterables
  941. args = _sympify(args)
  942. # Reduce sets using known rules
  943. if evaluate:
  944. args = list(cls._new_args_filter(args))
  945. return simplify_union(args)
  946. args = list(ordered(args, Set._infimum_key))
  947. obj = Basic.__new__(cls, *args)
  948. obj._argset = frozenset(args)
  949. return obj
  950. @property
  951. def args(self):
  952. return self._args
  953. def _complement(self, universe):
  954. # DeMorgan's Law
  955. return Intersection(s.complement(universe) for s in self.args)
  956. @property
  957. def _inf(self):
  958. # We use Min so that sup is meaningful in combination with symbolic
  959. # interval end points.
  960. return Min(*[set.inf for set in self.args])
  961. @property
  962. def _sup(self):
  963. # We use Max so that sup is meaningful in combination with symbolic
  964. # end points.
  965. return Max(*[set.sup for set in self.args])
  966. @property
  967. def is_empty(self):
  968. return fuzzy_and(set.is_empty for set in self.args)
  969. @property
  970. def is_finite_set(self):
  971. return fuzzy_and(set.is_finite_set for set in self.args)
  972. @property
  973. def _measure(self):
  974. # Measure of a union is the sum of the measures of the sets minus
  975. # the sum of their pairwise intersections plus the sum of their
  976. # triple-wise intersections minus ... etc...
  977. # Sets is a collection of intersections and a set of elementary
  978. # sets which made up those intersections (called "sos" for set of sets)
  979. # An example element might of this list might be:
  980. # ( {A,B,C}, A.intersect(B).intersect(C) )
  981. # Start with just elementary sets ( ({A}, A), ({B}, B), ... )
  982. # Then get and subtract ( ({A,B}, (A int B), ... ) while non-zero
  983. sets = [(FiniteSet(s), s) for s in self.args]
  984. measure = 0
  985. parity = 1
  986. while sets:
  987. # Add up the measure of these sets and add or subtract it to total
  988. measure += parity * sum(inter.measure for sos, inter in sets)
  989. # For each intersection in sets, compute the intersection with every
  990. # other set not already part of the intersection.
  991. sets = ((sos + FiniteSet(newset), newset.intersect(intersection))
  992. for sos, intersection in sets for newset in self.args
  993. if newset not in sos)
  994. # Clear out sets with no measure
  995. sets = [(sos, inter) for sos, inter in sets if inter.measure != 0]
  996. # Clear out duplicates
  997. sos_list = []
  998. sets_list = []
  999. for _set in sets:
  1000. if _set[0] in sos_list:
  1001. continue
  1002. else:
  1003. sos_list.append(_set[0])
  1004. sets_list.append(_set)
  1005. sets = sets_list
  1006. # Flip Parity - next time subtract/add if we added/subtracted here
  1007. parity *= -1
  1008. return measure
  1009. @property
  1010. def _boundary(self):
  1011. def boundary_of_set(i):
  1012. """ The boundary of set i minus interior of all other sets """
  1013. b = self.args[i].boundary
  1014. for j, a in enumerate(self.args):
  1015. if j != i:
  1016. b = b - a.interior
  1017. return b
  1018. return Union(*map(boundary_of_set, range(len(self.args))))
  1019. def _contains(self, other):
  1020. return Or(*[s.contains(other) for s in self.args])
  1021. def is_subset(self, other):
  1022. return fuzzy_and(s.is_subset(other) for s in self.args)
  1023. def as_relational(self, symbol):
  1024. """Rewrite a Union in terms of equalities and logic operators. """
  1025. if (len(self.args) == 2 and
  1026. all(isinstance(i, Interval) for i in self.args)):
  1027. # optimization to give 3 args as (x > 1) & (x < 5) & Ne(x, 3)
  1028. # instead of as 4, ((1 <= x) & (x < 3)) | ((x <= 5) & (3 < x))
  1029. a, b = self.args
  1030. if (a.sup == b.inf and
  1031. not any(a.sup in i for i in self.args)):
  1032. return And(Ne(symbol, a.sup), symbol < b.sup, symbol > a.inf)
  1033. return Or(*[i.as_relational(symbol) for i in self.args])
  1034. @property
  1035. def is_iterable(self):
  1036. return all(arg.is_iterable for arg in self.args)
  1037. def __iter__(self):
  1038. return roundrobin(*(iter(arg) for arg in self.args))
  1039. class Intersection(Set, LatticeOp):
  1040. """
  1041. Represents an intersection of sets as a :class:`Set`.
  1042. Examples
  1043. ========
  1044. >>> from sympy import Intersection, Interval
  1045. >>> Intersection(Interval(1, 3), Interval(2, 4))
  1046. Interval(2, 3)
  1047. We often use the .intersect method
  1048. >>> Interval(1,3).intersect(Interval(2,4))
  1049. Interval(2, 3)
  1050. See Also
  1051. ========
  1052. Union
  1053. References
  1054. ==========
  1055. .. [1] https://en.wikipedia.org/wiki/Intersection_%28set_theory%29
  1056. """
  1057. is_Intersection = True
  1058. @property
  1059. def identity(self):
  1060. return S.UniversalSet
  1061. @property
  1062. def zero(self):
  1063. return S.EmptySet
  1064. def __new__(cls, *args, **kwargs):
  1065. evaluate = kwargs.get('evaluate', global_parameters.evaluate)
  1066. # flatten inputs to merge intersections and iterables
  1067. args = list(ordered(set(_sympify(args))))
  1068. # Reduce sets using known rules
  1069. if evaluate:
  1070. args = list(cls._new_args_filter(args))
  1071. return simplify_intersection(args)
  1072. args = list(ordered(args, Set._infimum_key))
  1073. obj = Basic.__new__(cls, *args)
  1074. obj._argset = frozenset(args)
  1075. return obj
  1076. @property
  1077. def args(self):
  1078. return self._args
  1079. @property
  1080. def is_iterable(self):
  1081. return any(arg.is_iterable for arg in self.args)
  1082. @property
  1083. def is_finite_set(self):
  1084. if fuzzy_or(arg.is_finite_set for arg in self.args):
  1085. return True
  1086. @property
  1087. def _inf(self):
  1088. raise NotImplementedError()
  1089. @property
  1090. def _sup(self):
  1091. raise NotImplementedError()
  1092. def _contains(self, other):
  1093. return And(*[set.contains(other) for set in self.args])
  1094. def __iter__(self):
  1095. sets_sift = sift(self.args, lambda x: x.is_iterable)
  1096. completed = False
  1097. candidates = sets_sift[True] + sets_sift[None]
  1098. finite_candidates, others = [], []
  1099. for candidate in candidates:
  1100. length = None
  1101. try:
  1102. length = len(candidate)
  1103. except TypeError:
  1104. others.append(candidate)
  1105. if length is not None:
  1106. finite_candidates.append(candidate)
  1107. finite_candidates.sort(key=len)
  1108. for s in finite_candidates + others:
  1109. other_sets = set(self.args) - {s}
  1110. other = Intersection(*other_sets, evaluate=False)
  1111. completed = True
  1112. for x in s:
  1113. try:
  1114. if x in other:
  1115. yield x
  1116. except TypeError:
  1117. completed = False
  1118. if completed:
  1119. return
  1120. if not completed:
  1121. if not candidates:
  1122. raise TypeError("None of the constituent sets are iterable")
  1123. raise TypeError(
  1124. "The computation had not completed because of the "
  1125. "undecidable set membership is found in every candidates.")
  1126. @staticmethod
  1127. def _handle_finite_sets(args):
  1128. '''Simplify intersection of one or more FiniteSets and other sets'''
  1129. # First separate the FiniteSets from the others
  1130. fs_args, others = sift(args, lambda x: x.is_FiniteSet, binary=True)
  1131. # Let the caller handle intersection of non-FiniteSets
  1132. if not fs_args:
  1133. return
  1134. # Convert to Python sets and build the set of all elements
  1135. fs_sets = [set(fs) for fs in fs_args]
  1136. all_elements = reduce(lambda a, b: a | b, fs_sets, set())
  1137. # Extract elements that are definitely in or definitely not in the
  1138. # intersection. Here we check contains for all of args.
  1139. definite = set()
  1140. for e in all_elements:
  1141. inall = fuzzy_and(s.contains(e) for s in args)
  1142. if inall is True:
  1143. definite.add(e)
  1144. if inall is not None:
  1145. for s in fs_sets:
  1146. s.discard(e)
  1147. # At this point all elements in all of fs_sets are possibly in the
  1148. # intersection. In some cases this is because they are definitely in
  1149. # the intersection of the finite sets but it's not clear if they are
  1150. # members of others. We might have {m, n}, {m}, and Reals where we
  1151. # don't know if m or n is real. We want to remove n here but it is
  1152. # possibly in because it might be equal to m. So what we do now is
  1153. # extract the elements that are definitely in the remaining finite
  1154. # sets iteratively until we end up with {n}, {}. At that point if we
  1155. # get any empty set all remaining elements are discarded.
  1156. fs_elements = reduce(lambda a, b: a | b, fs_sets, set())
  1157. # Need fuzzy containment testing
  1158. fs_symsets = [FiniteSet(*s) for s in fs_sets]
  1159. while fs_elements:
  1160. for e in fs_elements:
  1161. infs = fuzzy_and(s.contains(e) for s in fs_symsets)
  1162. if infs is True:
  1163. definite.add(e)
  1164. if infs is not None:
  1165. for n, s in enumerate(fs_sets):
  1166. # Update Python set and FiniteSet
  1167. if e in s:
  1168. s.remove(e)
  1169. fs_symsets[n] = FiniteSet(*s)
  1170. fs_elements.remove(e)
  1171. break
  1172. # If we completed the for loop without removing anything we are
  1173. # done so quit the outer while loop
  1174. else:
  1175. break
  1176. # If any of the sets of remainder elements is empty then we discard
  1177. # all of them for the intersection.
  1178. if not all(fs_sets):
  1179. fs_sets = [set()]
  1180. # Here we fold back the definitely included elements into each fs.
  1181. # Since they are definitely included they must have been members of
  1182. # each FiniteSet to begin with. We could instead fold these in with a
  1183. # Union at the end to get e.g. {3}|({x}&{y}) rather than {3,x}&{3,y}.
  1184. if definite:
  1185. fs_sets = [fs | definite for fs in fs_sets]
  1186. if fs_sets == [set()]:
  1187. return S.EmptySet
  1188. sets = [FiniteSet(*s) for s in fs_sets]
  1189. # Any set in others is redundant if it contains all the elements that
  1190. # are in the finite sets so we don't need it in the Intersection
  1191. all_elements = reduce(lambda a, b: a | b, fs_sets, set())
  1192. is_redundant = lambda o: all(fuzzy_bool(o.contains(e)) for e in all_elements)
  1193. others = [o for o in others if not is_redundant(o)]
  1194. if others:
  1195. rest = Intersection(*others)
  1196. # XXX: Maybe this shortcut should be at the beginning. For large
  1197. # FiniteSets it could much more efficient to process the other
  1198. # sets first...
  1199. if rest is S.EmptySet:
  1200. return S.EmptySet
  1201. # Flatten the Intersection
  1202. if rest.is_Intersection:
  1203. sets.extend(rest.args)
  1204. else:
  1205. sets.append(rest)
  1206. if len(sets) == 1:
  1207. return sets[0]
  1208. else:
  1209. return Intersection(*sets, evaluate=False)
  1210. def as_relational(self, symbol):
  1211. """Rewrite an Intersection in terms of equalities and logic operators"""
  1212. return And(*[set.as_relational(symbol) for set in self.args])
  1213. class Complement(Set):
  1214. r"""Represents the set difference or relative complement of a set with
  1215. another set.
  1216. $$A - B = \{x \in A \mid x \notin B\}$$
  1217. Examples
  1218. ========
  1219. >>> from sympy import Complement, FiniteSet
  1220. >>> Complement(FiniteSet(0, 1, 2), FiniteSet(1))
  1221. {0, 2}
  1222. See Also
  1223. =========
  1224. Intersection, Union
  1225. References
  1226. ==========
  1227. .. [1] http://mathworld.wolfram.com/ComplementSet.html
  1228. """
  1229. is_Complement = True
  1230. def __new__(cls, a, b, evaluate=True):
  1231. a, b = map(_sympify, (a, b))
  1232. if evaluate:
  1233. return Complement.reduce(a, b)
  1234. return Basic.__new__(cls, a, b)
  1235. @staticmethod
  1236. def reduce(A, B):
  1237. """
  1238. Simplify a :class:`Complement`.
  1239. """
  1240. if B == S.UniversalSet or A.is_subset(B):
  1241. return S.EmptySet
  1242. if isinstance(B, Union):
  1243. return Intersection(*(s.complement(A) for s in B.args))
  1244. result = B._complement(A)
  1245. if result is not None:
  1246. return result
  1247. else:
  1248. return Complement(A, B, evaluate=False)
  1249. def _contains(self, other):
  1250. A = self.args[0]
  1251. B = self.args[1]
  1252. return And(A.contains(other), Not(B.contains(other)))
  1253. def as_relational(self, symbol):
  1254. """Rewrite a complement in terms of equalities and logic
  1255. operators"""
  1256. A, B = self.args
  1257. A_rel = A.as_relational(symbol)
  1258. B_rel = Not(B.as_relational(symbol))
  1259. return And(A_rel, B_rel)
  1260. @property
  1261. def is_iterable(self):
  1262. if self.args[0].is_iterable:
  1263. return True
  1264. @property
  1265. def is_finite_set(self):
  1266. A, B = self.args
  1267. a_finite = A.is_finite_set
  1268. if a_finite is True:
  1269. return True
  1270. elif a_finite is False and B.is_finite_set:
  1271. return False
  1272. def __iter__(self):
  1273. A, B = self.args
  1274. for a in A:
  1275. if a not in B:
  1276. yield a
  1277. else:
  1278. continue
  1279. class EmptySet(Set, metaclass=Singleton):
  1280. """
  1281. Represents the empty set. The empty set is available as a singleton
  1282. as ``S.EmptySet``.
  1283. Examples
  1284. ========
  1285. >>> from sympy import S, Interval
  1286. >>> S.EmptySet
  1287. EmptySet
  1288. >>> Interval(1, 2).intersect(S.EmptySet)
  1289. EmptySet
  1290. See Also
  1291. ========
  1292. UniversalSet
  1293. References
  1294. ==========
  1295. .. [1] https://en.wikipedia.org/wiki/Empty_set
  1296. """
  1297. is_empty = True
  1298. is_finite_set = True
  1299. is_FiniteSet = True
  1300. @property # type: ignore
  1301. @deprecated(
  1302. """
  1303. The is_EmptySet attribute of Set objects is deprecated.
  1304. Use 's is S.EmptySet" or 's.is_empty' instead.
  1305. """,
  1306. deprecated_since_version="1.5",
  1307. active_deprecations_target="deprecated-is-emptyset",
  1308. )
  1309. def is_EmptySet(self):
  1310. return True
  1311. @property
  1312. def _measure(self):
  1313. return 0
  1314. def _contains(self, other):
  1315. return false
  1316. def as_relational(self, symbol):
  1317. return false
  1318. def __len__(self):
  1319. return 0
  1320. def __iter__(self):
  1321. return iter([])
  1322. def _eval_powerset(self):
  1323. return FiniteSet(self)
  1324. @property
  1325. def _boundary(self):
  1326. return self
  1327. def _complement(self, other):
  1328. return other
  1329. def _symmetric_difference(self, other):
  1330. return other
  1331. class UniversalSet(Set, metaclass=Singleton):
  1332. """
  1333. Represents the set of all things.
  1334. The universal set is available as a singleton as ``S.UniversalSet``.
  1335. Examples
  1336. ========
  1337. >>> from sympy import S, Interval
  1338. >>> S.UniversalSet
  1339. UniversalSet
  1340. >>> Interval(1, 2).intersect(S.UniversalSet)
  1341. Interval(1, 2)
  1342. See Also
  1343. ========
  1344. EmptySet
  1345. References
  1346. ==========
  1347. .. [1] https://en.wikipedia.org/wiki/Universal_set
  1348. """
  1349. is_UniversalSet = True
  1350. is_empty = False
  1351. is_finite_set = False
  1352. def _complement(self, other):
  1353. return S.EmptySet
  1354. def _symmetric_difference(self, other):
  1355. return other
  1356. @property
  1357. def _measure(self):
  1358. return S.Infinity
  1359. def _contains(self, other):
  1360. return true
  1361. def as_relational(self, symbol):
  1362. return true
  1363. @property
  1364. def _boundary(self):
  1365. return S.EmptySet
  1366. class FiniteSet(Set):
  1367. """
  1368. Represents a finite set of discrete numbers.
  1369. Examples
  1370. ========
  1371. >>> from sympy import FiniteSet
  1372. >>> FiniteSet(1, 2, 3, 4)
  1373. {1, 2, 3, 4}
  1374. >>> 3 in FiniteSet(1, 2, 3, 4)
  1375. True
  1376. >>> members = [1, 2, 3, 4]
  1377. >>> f = FiniteSet(*members)
  1378. >>> f
  1379. {1, 2, 3, 4}
  1380. >>> f - FiniteSet(2)
  1381. {1, 3, 4}
  1382. >>> f + FiniteSet(2, 5)
  1383. {1, 2, 3, 4, 5}
  1384. References
  1385. ==========
  1386. .. [1] https://en.wikipedia.org/wiki/Finite_set
  1387. """
  1388. is_FiniteSet = True
  1389. is_iterable = True
  1390. is_empty = False
  1391. is_finite_set = True
  1392. def __new__(cls, *args, **kwargs):
  1393. evaluate = kwargs.get('evaluate', global_parameters.evaluate)
  1394. if evaluate:
  1395. args = list(map(sympify, args))
  1396. if len(args) == 0:
  1397. return S.EmptySet
  1398. else:
  1399. args = list(map(sympify, args))
  1400. # keep the form of the first canonical arg
  1401. dargs = {}
  1402. for i in reversed(list(ordered(args))):
  1403. if i.is_Symbol:
  1404. dargs[i] = i
  1405. else:
  1406. try:
  1407. dargs[i.as_dummy()] = i
  1408. except TypeError:
  1409. # e.g. i = class without args like `Interval`
  1410. dargs[i] = i
  1411. _args_set = set(dargs.values())
  1412. args = list(ordered(_args_set, Set._infimum_key))
  1413. obj = Basic.__new__(cls, *args)
  1414. obj._args_set = _args_set
  1415. return obj
  1416. def __iter__(self):
  1417. return iter(self.args)
  1418. def _complement(self, other):
  1419. if isinstance(other, Interval):
  1420. # Splitting in sub-intervals is only done for S.Reals;
  1421. # other cases that need splitting will first pass through
  1422. # Set._complement().
  1423. nums, syms = [], []
  1424. for m in self.args:
  1425. if m.is_number and m.is_real:
  1426. nums.append(m)
  1427. elif m.is_real == False:
  1428. pass # drop non-reals
  1429. else:
  1430. syms.append(m) # various symbolic expressions
  1431. if other == S.Reals and nums != []:
  1432. nums.sort()
  1433. intervals = [] # Build up a list of intervals between the elements
  1434. intervals += [Interval(S.NegativeInfinity, nums[0], True, True)]
  1435. for a, b in zip(nums[:-1], nums[1:]):
  1436. intervals.append(Interval(a, b, True, True)) # both open
  1437. intervals.append(Interval(nums[-1], S.Infinity, True, True))
  1438. if syms != []:
  1439. return Complement(Union(*intervals, evaluate=False),
  1440. FiniteSet(*syms), evaluate=False)
  1441. else:
  1442. return Union(*intervals, evaluate=False)
  1443. elif nums == []: # no splitting necessary or possible:
  1444. if syms:
  1445. return Complement(other, FiniteSet(*syms), evaluate=False)
  1446. else:
  1447. return other
  1448. elif isinstance(other, FiniteSet):
  1449. unk = []
  1450. for i in self:
  1451. c = sympify(other.contains(i))
  1452. if c is not S.true and c is not S.false:
  1453. unk.append(i)
  1454. unk = FiniteSet(*unk)
  1455. if unk == self:
  1456. return
  1457. not_true = []
  1458. for i in other:
  1459. c = sympify(self.contains(i))
  1460. if c is not S.true:
  1461. not_true.append(i)
  1462. return Complement(FiniteSet(*not_true), unk)
  1463. return Set._complement(self, other)
  1464. def _contains(self, other):
  1465. """
  1466. Tests whether an element, other, is in the set.
  1467. Explanation
  1468. ===========
  1469. The actual test is for mathematical equality (as opposed to
  1470. syntactical equality). In the worst case all elements of the
  1471. set must be checked.
  1472. Examples
  1473. ========
  1474. >>> from sympy import FiniteSet
  1475. >>> 1 in FiniteSet(1, 2)
  1476. True
  1477. >>> 5 in FiniteSet(1, 2)
  1478. False
  1479. """
  1480. if other in self._args_set:
  1481. return True
  1482. else:
  1483. # evaluate=True is needed to override evaluate=False context;
  1484. # we need Eq to do the evaluation
  1485. return fuzzy_or(fuzzy_bool(Eq(e, other, evaluate=True))
  1486. for e in self.args)
  1487. def _eval_is_subset(self, other):
  1488. return fuzzy_and(other._contains(e) for e in self.args)
  1489. @property
  1490. def _boundary(self):
  1491. return self
  1492. @property
  1493. def _inf(self):
  1494. return Min(*self)
  1495. @property
  1496. def _sup(self):
  1497. return Max(*self)
  1498. @property
  1499. def measure(self):
  1500. return 0
  1501. def __len__(self):
  1502. return len(self.args)
  1503. def as_relational(self, symbol):
  1504. """Rewrite a FiniteSet in terms of equalities and logic operators. """
  1505. return Or(*[Eq(symbol, elem) for elem in self])
  1506. def compare(self, other):
  1507. return (hash(self) - hash(other))
  1508. def _eval_evalf(self, prec):
  1509. dps = prec_to_dps(prec)
  1510. return FiniteSet(*[elem.evalf(n=dps) for elem in self])
  1511. def _eval_simplify(self, **kwargs):
  1512. from sympy.simplify import simplify
  1513. return FiniteSet(*[simplify(elem, **kwargs) for elem in self])
  1514. @property
  1515. def _sorted_args(self):
  1516. return self.args
  1517. def _eval_powerset(self):
  1518. return self.func(*[self.func(*s) for s in subsets(self.args)])
  1519. def _eval_rewrite_as_PowerSet(self, *args, **kwargs):
  1520. """Rewriting method for a finite set to a power set."""
  1521. from .powerset import PowerSet
  1522. is2pow = lambda n: bool(n and not n & (n - 1))
  1523. if not is2pow(len(self)):
  1524. return None
  1525. fs_test = lambda arg: isinstance(arg, Set) and arg.is_FiniteSet
  1526. if not all(fs_test(arg) for arg in args):
  1527. return None
  1528. biggest = max(args, key=len)
  1529. for arg in subsets(biggest.args):
  1530. arg_set = FiniteSet(*arg)
  1531. if arg_set not in args:
  1532. return None
  1533. return PowerSet(biggest)
  1534. def __ge__(self, other):
  1535. if not isinstance(other, Set):
  1536. raise TypeError("Invalid comparison of set with %s" % func_name(other))
  1537. return other.is_subset(self)
  1538. def __gt__(self, other):
  1539. if not isinstance(other, Set):
  1540. raise TypeError("Invalid comparison of set with %s" % func_name(other))
  1541. return self.is_proper_superset(other)
  1542. def __le__(self, other):
  1543. if not isinstance(other, Set):
  1544. raise TypeError("Invalid comparison of set with %s" % func_name(other))
  1545. return self.is_subset(other)
  1546. def __lt__(self, other):
  1547. if not isinstance(other, Set):
  1548. raise TypeError("Invalid comparison of set with %s" % func_name(other))
  1549. return self.is_proper_subset(other)
  1550. def __eq__(self, other):
  1551. if isinstance(other, (set, frozenset)):
  1552. return self._args_set == other
  1553. return super().__eq__(other)
  1554. __hash__ : Callable[[Basic], Any] = Basic.__hash__
  1555. _sympy_converter[set] = lambda x: FiniteSet(*x)
  1556. _sympy_converter[frozenset] = lambda x: FiniteSet(*x)
  1557. class SymmetricDifference(Set):
  1558. """Represents the set of elements which are in either of the
  1559. sets and not in their intersection.
  1560. Examples
  1561. ========
  1562. >>> from sympy import SymmetricDifference, FiniteSet
  1563. >>> SymmetricDifference(FiniteSet(1, 2, 3), FiniteSet(3, 4, 5))
  1564. {1, 2, 4, 5}
  1565. See Also
  1566. ========
  1567. Complement, Union
  1568. References
  1569. ==========
  1570. .. [1] https://en.wikipedia.org/wiki/Symmetric_difference
  1571. """
  1572. is_SymmetricDifference = True
  1573. def __new__(cls, a, b, evaluate=True):
  1574. if evaluate:
  1575. return SymmetricDifference.reduce(a, b)
  1576. return Basic.__new__(cls, a, b)
  1577. @staticmethod
  1578. def reduce(A, B):
  1579. result = B._symmetric_difference(A)
  1580. if result is not None:
  1581. return result
  1582. else:
  1583. return SymmetricDifference(A, B, evaluate=False)
  1584. def as_relational(self, symbol):
  1585. """Rewrite a symmetric_difference in terms of equalities and
  1586. logic operators"""
  1587. A, B = self.args
  1588. A_rel = A.as_relational(symbol)
  1589. B_rel = B.as_relational(symbol)
  1590. return Xor(A_rel, B_rel)
  1591. @property
  1592. def is_iterable(self):
  1593. if all(arg.is_iterable for arg in self.args):
  1594. return True
  1595. def __iter__(self):
  1596. args = self.args
  1597. union = roundrobin(*(iter(arg) for arg in args))
  1598. for item in union:
  1599. count = 0
  1600. for s in args:
  1601. if item in s:
  1602. count += 1
  1603. if count % 2 == 1:
  1604. yield item
  1605. class DisjointUnion(Set):
  1606. """ Represents the disjoint union (also known as the external disjoint union)
  1607. of a finite number of sets.
  1608. Examples
  1609. ========
  1610. >>> from sympy import DisjointUnion, FiniteSet, Interval, Union, Symbol
  1611. >>> A = FiniteSet(1, 2, 3)
  1612. >>> B = Interval(0, 5)
  1613. >>> DisjointUnion(A, B)
  1614. DisjointUnion({1, 2, 3}, Interval(0, 5))
  1615. >>> DisjointUnion(A, B).rewrite(Union)
  1616. Union(ProductSet({1, 2, 3}, {0}), ProductSet(Interval(0, 5), {1}))
  1617. >>> C = FiniteSet(Symbol('x'), Symbol('y'), Symbol('z'))
  1618. >>> DisjointUnion(C, C)
  1619. DisjointUnion({x, y, z}, {x, y, z})
  1620. >>> DisjointUnion(C, C).rewrite(Union)
  1621. ProductSet({x, y, z}, {0, 1})
  1622. References
  1623. ==========
  1624. https://en.wikipedia.org/wiki/Disjoint_union
  1625. """
  1626. def __new__(cls, *sets):
  1627. dj_collection = []
  1628. for set_i in sets:
  1629. if isinstance(set_i, Set):
  1630. dj_collection.append(set_i)
  1631. else:
  1632. raise TypeError("Invalid input: '%s', input args \
  1633. to DisjointUnion must be Sets" % set_i)
  1634. obj = Basic.__new__(cls, *dj_collection)
  1635. return obj
  1636. @property
  1637. def sets(self):
  1638. return self.args
  1639. @property
  1640. def is_empty(self):
  1641. return fuzzy_and(s.is_empty for s in self.sets)
  1642. @property
  1643. def is_finite_set(self):
  1644. all_finite = fuzzy_and(s.is_finite_set for s in self.sets)
  1645. return fuzzy_or([self.is_empty, all_finite])
  1646. @property
  1647. def is_iterable(self):
  1648. if self.is_empty:
  1649. return False
  1650. iter_flag = True
  1651. for set_i in self.sets:
  1652. if not set_i.is_empty:
  1653. iter_flag = iter_flag and set_i.is_iterable
  1654. return iter_flag
  1655. def _eval_rewrite_as_Union(self, *sets):
  1656. """
  1657. Rewrites the disjoint union as the union of (``set`` x {``i``})
  1658. where ``set`` is the element in ``sets`` at index = ``i``
  1659. """
  1660. dj_union = S.EmptySet
  1661. index = 0
  1662. for set_i in sets:
  1663. if isinstance(set_i, Set):
  1664. cross = ProductSet(set_i, FiniteSet(index))
  1665. dj_union = Union(dj_union, cross)
  1666. index = index + 1
  1667. return dj_union
  1668. def _contains(self, element):
  1669. """
  1670. ``in`` operator for DisjointUnion
  1671. Examples
  1672. ========
  1673. >>> from sympy import Interval, DisjointUnion
  1674. >>> D = DisjointUnion(Interval(0, 1), Interval(0, 2))
  1675. >>> (0.5, 0) in D
  1676. True
  1677. >>> (0.5, 1) in D
  1678. True
  1679. >>> (1.5, 0) in D
  1680. False
  1681. >>> (1.5, 1) in D
  1682. True
  1683. Passes operation on to constituent sets
  1684. """
  1685. if not isinstance(element, Tuple) or len(element) != 2:
  1686. return False
  1687. if not element[1].is_Integer:
  1688. return False
  1689. if element[1] >= len(self.sets) or element[1] < 0:
  1690. return False
  1691. return element[0] in self.sets[element[1]]
  1692. def __iter__(self):
  1693. if self.is_iterable:
  1694. iters = []
  1695. for i, s in enumerate(self.sets):
  1696. iters.append(iproduct(s, {Integer(i)}))
  1697. return iter(roundrobin(*iters))
  1698. else:
  1699. raise ValueError("'%s' is not iterable." % self)
  1700. def __len__(self):
  1701. """
  1702. Returns the length of the disjoint union, i.e., the number of elements in the set.
  1703. Examples
  1704. ========
  1705. >>> from sympy import FiniteSet, DisjointUnion, EmptySet
  1706. >>> D1 = DisjointUnion(FiniteSet(1, 2, 3, 4), EmptySet, FiniteSet(3, 4, 5))
  1707. >>> len(D1)
  1708. 7
  1709. >>> D2 = DisjointUnion(FiniteSet(3, 5, 7), EmptySet, FiniteSet(3, 5, 7))
  1710. >>> len(D2)
  1711. 6
  1712. >>> D3 = DisjointUnion(EmptySet, EmptySet)
  1713. >>> len(D3)
  1714. 0
  1715. Adds up the lengths of the constituent sets.
  1716. """
  1717. if self.is_finite_set:
  1718. size = 0
  1719. for set in self.sets:
  1720. size += len(set)
  1721. return size
  1722. else:
  1723. raise ValueError("'%s' is not a finite set." % self)
  1724. def imageset(*args):
  1725. r"""
  1726. Return an image of the set under transformation ``f``.
  1727. Explanation
  1728. ===========
  1729. If this function cannot compute the image, it returns an
  1730. unevaluated ImageSet object.
  1731. .. math::
  1732. \{ f(x) \mid x \in \mathrm{self} \}
  1733. Examples
  1734. ========
  1735. >>> from sympy import S, Interval, imageset, sin, Lambda
  1736. >>> from sympy.abc import x
  1737. >>> imageset(x, 2*x, Interval(0, 2))
  1738. Interval(0, 4)
  1739. >>> imageset(lambda x: 2*x, Interval(0, 2))
  1740. Interval(0, 4)
  1741. >>> imageset(Lambda(x, sin(x)), Interval(-2, 1))
  1742. ImageSet(Lambda(x, sin(x)), Interval(-2, 1))
  1743. >>> imageset(sin, Interval(-2, 1))
  1744. ImageSet(Lambda(x, sin(x)), Interval(-2, 1))
  1745. >>> imageset(lambda y: x + y, Interval(-2, 1))
  1746. ImageSet(Lambda(y, x + y), Interval(-2, 1))
  1747. Expressions applied to the set of Integers are simplified
  1748. to show as few negatives as possible and linear expressions
  1749. are converted to a canonical form. If this is not desirable
  1750. then the unevaluated ImageSet should be used.
  1751. >>> imageset(x, -2*x + 5, S.Integers)
  1752. ImageSet(Lambda(x, 2*x + 1), Integers)
  1753. See Also
  1754. ========
  1755. sympy.sets.fancysets.ImageSet
  1756. """
  1757. from .fancysets import ImageSet
  1758. from .setexpr import set_function
  1759. if len(args) < 2:
  1760. raise ValueError('imageset expects at least 2 args, got: %s' % len(args))
  1761. if isinstance(args[0], (Symbol, tuple)) and len(args) > 2:
  1762. f = Lambda(args[0], args[1])
  1763. set_list = args[2:]
  1764. else:
  1765. f = args[0]
  1766. set_list = args[1:]
  1767. if isinstance(f, Lambda):
  1768. pass
  1769. elif callable(f):
  1770. nargs = getattr(f, 'nargs', {})
  1771. if nargs:
  1772. if len(nargs) != 1:
  1773. raise NotImplementedError(filldedent('''
  1774. This function can take more than 1 arg
  1775. but the potentially complicated set input
  1776. has not been analyzed at this point to
  1777. know its dimensions. TODO
  1778. '''))
  1779. N = nargs.args[0]
  1780. if N == 1:
  1781. s = 'x'
  1782. else:
  1783. s = [Symbol('x%i' % i) for i in range(1, N + 1)]
  1784. else:
  1785. s = inspect.signature(f).parameters
  1786. dexpr = _sympify(f(*[Dummy() for i in s]))
  1787. var = tuple(uniquely_named_symbol(
  1788. Symbol(i), dexpr) for i in s)
  1789. f = Lambda(var, f(*var))
  1790. else:
  1791. raise TypeError(filldedent('''
  1792. expecting lambda, Lambda, or FunctionClass,
  1793. not \'%s\'.''' % func_name(f)))
  1794. if any(not isinstance(s, Set) for s in set_list):
  1795. name = [func_name(s) for s in set_list]
  1796. raise ValueError(
  1797. 'arguments after mapping should be sets, not %s' % name)
  1798. if len(set_list) == 1:
  1799. set = set_list[0]
  1800. try:
  1801. # TypeError if arg count != set dimensions
  1802. r = set_function(f, set)
  1803. if r is None:
  1804. raise TypeError
  1805. if not r:
  1806. return r
  1807. except TypeError:
  1808. r = ImageSet(f, set)
  1809. if isinstance(r, ImageSet):
  1810. f, set = r.args
  1811. if f.variables[0] == f.expr:
  1812. return set
  1813. if isinstance(set, ImageSet):
  1814. # XXX: Maybe this should just be:
  1815. # f2 = set.lambda
  1816. # fun = Lambda(f2.signature, f(*f2.expr))
  1817. # return imageset(fun, *set.base_sets)
  1818. if len(set.lamda.variables) == 1 and len(f.variables) == 1:
  1819. x = set.lamda.variables[0]
  1820. y = f.variables[0]
  1821. return imageset(
  1822. Lambda(x, f.expr.subs(y, set.lamda.expr)), *set.base_sets)
  1823. if r is not None:
  1824. return r
  1825. return ImageSet(f, *set_list)
  1826. def is_function_invertible_in_set(func, setv):
  1827. """
  1828. Checks whether function ``func`` is invertible when the domain is
  1829. restricted to set ``setv``.
  1830. """
  1831. from sympy.functions.elementary.exponential import exp, log
  1832. # Functions known to always be invertible:
  1833. if func in (exp, log):
  1834. return True
  1835. u = Dummy("u")
  1836. fdiff = func(u).diff(u)
  1837. # monotonous functions:
  1838. # TODO: check subsets (`func` in `setv`)
  1839. if (fdiff > 0) == True or (fdiff < 0) == True:
  1840. return True
  1841. # TODO: support more
  1842. return None
  1843. def simplify_union(args):
  1844. """
  1845. Simplify a :class:`Union` using known rules.
  1846. Explanation
  1847. ===========
  1848. We first start with global rules like 'Merge all FiniteSets'
  1849. Then we iterate through all pairs and ask the constituent sets if they
  1850. can simplify themselves with any other constituent. This process depends
  1851. on ``union_sets(a, b)`` functions.
  1852. """
  1853. from sympy.sets.handlers.union import union_sets
  1854. # ===== Global Rules =====
  1855. if not args:
  1856. return S.EmptySet
  1857. for arg in args:
  1858. if not isinstance(arg, Set):
  1859. raise TypeError("Input args to Union must be Sets")
  1860. # Merge all finite sets
  1861. finite_sets = [x for x in args if x.is_FiniteSet]
  1862. if len(finite_sets) > 1:
  1863. a = (x for set in finite_sets for x in set)
  1864. finite_set = FiniteSet(*a)
  1865. args = [finite_set] + [x for x in args if not x.is_FiniteSet]
  1866. # ===== Pair-wise Rules =====
  1867. # Here we depend on rules built into the constituent sets
  1868. args = set(args)
  1869. new_args = True
  1870. while new_args:
  1871. for s in args:
  1872. new_args = False
  1873. for t in args - {s}:
  1874. new_set = union_sets(s, t)
  1875. # This returns None if s does not know how to intersect
  1876. # with t. Returns the newly intersected set otherwise
  1877. if new_set is not None:
  1878. if not isinstance(new_set, set):
  1879. new_set = {new_set}
  1880. new_args = (args - {s, t}).union(new_set)
  1881. break
  1882. if new_args:
  1883. args = new_args
  1884. break
  1885. if len(args) == 1:
  1886. return args.pop()
  1887. else:
  1888. return Union(*args, evaluate=False)
  1889. def simplify_intersection(args):
  1890. """
  1891. Simplify an intersection using known rules.
  1892. Explanation
  1893. ===========
  1894. We first start with global rules like
  1895. 'if any empty sets return empty set' and 'distribute any unions'
  1896. Then we iterate through all pairs and ask the constituent sets if they
  1897. can simplify themselves with any other constituent
  1898. """
  1899. # ===== Global Rules =====
  1900. if not args:
  1901. return S.UniversalSet
  1902. for arg in args:
  1903. if not isinstance(arg, Set):
  1904. raise TypeError("Input args to Union must be Sets")
  1905. # If any EmptySets return EmptySet
  1906. if S.EmptySet in args:
  1907. return S.EmptySet
  1908. # Handle Finite sets
  1909. rv = Intersection._handle_finite_sets(args)
  1910. if rv is not None:
  1911. return rv
  1912. # If any of the sets are unions, return a Union of Intersections
  1913. for s in args:
  1914. if s.is_Union:
  1915. other_sets = set(args) - {s}
  1916. if len(other_sets) > 0:
  1917. other = Intersection(*other_sets)
  1918. return Union(*(Intersection(arg, other) for arg in s.args))
  1919. else:
  1920. return Union(*[arg for arg in s.args])
  1921. for s in args:
  1922. if s.is_Complement:
  1923. args.remove(s)
  1924. other_sets = args + [s.args[0]]
  1925. return Complement(Intersection(*other_sets), s.args[1])
  1926. from sympy.sets.handlers.intersection import intersection_sets
  1927. # At this stage we are guaranteed not to have any
  1928. # EmptySets, FiniteSets, or Unions in the intersection
  1929. # ===== Pair-wise Rules =====
  1930. # Here we depend on rules built into the constituent sets
  1931. args = set(args)
  1932. new_args = True
  1933. while new_args:
  1934. for s in args:
  1935. new_args = False
  1936. for t in args - {s}:
  1937. new_set = intersection_sets(s, t)
  1938. # This returns None if s does not know how to intersect
  1939. # with t. Returns the newly intersected set otherwise
  1940. if new_set is not None:
  1941. new_args = (args - {s, t}).union({new_set})
  1942. break
  1943. if new_args:
  1944. args = new_args
  1945. break
  1946. if len(args) == 1:
  1947. return args.pop()
  1948. else:
  1949. return Intersection(*args, evaluate=False)
  1950. def _handle_finite_sets(op, x, y, commutative):
  1951. # Handle finite sets:
  1952. fs_args, other = sift([x, y], lambda x: isinstance(x, FiniteSet), binary=True)
  1953. if len(fs_args) == 2:
  1954. return FiniteSet(*[op(i, j) for i in fs_args[0] for j in fs_args[1]])
  1955. elif len(fs_args) == 1:
  1956. sets = [_apply_operation(op, other[0], i, commutative) for i in fs_args[0]]
  1957. return Union(*sets)
  1958. else:
  1959. return None
  1960. def _apply_operation(op, x, y, commutative):
  1961. from .fancysets import ImageSet
  1962. d = Dummy('d')
  1963. out = _handle_finite_sets(op, x, y, commutative)
  1964. if out is None:
  1965. out = op(x, y)
  1966. if out is None and commutative:
  1967. out = op(y, x)
  1968. if out is None:
  1969. _x, _y = symbols("x y")
  1970. if isinstance(x, Set) and not isinstance(y, Set):
  1971. out = ImageSet(Lambda(d, op(d, y)), x).doit()
  1972. elif not isinstance(x, Set) and isinstance(y, Set):
  1973. out = ImageSet(Lambda(d, op(x, d)), y).doit()
  1974. else:
  1975. out = ImageSet(Lambda((_x, _y), op(_x, _y)), x, y)
  1976. return out
  1977. def set_add(x, y):
  1978. from sympy.sets.handlers.add import _set_add
  1979. return _apply_operation(_set_add, x, y, commutative=True)
  1980. def set_sub(x, y):
  1981. from sympy.sets.handlers.add import _set_sub
  1982. return _apply_operation(_set_sub, x, y, commutative=False)
  1983. def set_mul(x, y):
  1984. from sympy.sets.handlers.mul import _set_mul
  1985. return _apply_operation(_set_mul, x, y, commutative=True)
  1986. def set_div(x, y):
  1987. from sympy.sets.handlers.mul import _set_div
  1988. return _apply_operation(_set_div, x, y, commutative=False)
  1989. def set_pow(x, y):
  1990. from sympy.sets.handlers.power import _set_pow
  1991. return _apply_operation(_set_pow, x, y, commutative=False)
  1992. def set_function(f, x):
  1993. from sympy.sets.handlers.functions import _set_function
  1994. return _set_function(f, x)