|
from sympy.core.singleton import S |
|
from sympy.core.sympify import sympify |
|
from sympy.functions.elementary.miscellaneous import Min, Max |
|
from sympy.sets.sets import (EmptySet, FiniteSet, Intersection, |
|
Interval, ProductSet, Set, Union, UniversalSet) |
|
from sympy.sets.fancysets import (ComplexRegion, Naturals, Naturals0, |
|
Integers, Rationals, Reals) |
|
from sympy.multipledispatch import Dispatcher |
|
|
|
|
|
union_sets = Dispatcher('union_sets') |
|
|
|
|
|
@union_sets.register(Naturals0, Naturals) |
|
def _(a, b): |
|
return a |
|
|
|
@union_sets.register(Rationals, Naturals) |
|
def _(a, b): |
|
return a |
|
|
|
@union_sets.register(Rationals, Naturals0) |
|
def _(a, b): |
|
return a |
|
|
|
@union_sets.register(Reals, Naturals) |
|
def _(a, b): |
|
return a |
|
|
|
@union_sets.register(Reals, Naturals0) |
|
def _(a, b): |
|
return a |
|
|
|
@union_sets.register(Reals, Rationals) |
|
def _(a, b): |
|
return a |
|
|
|
@union_sets.register(Integers, Set) |
|
def _(a, b): |
|
intersect = Intersection(a, b) |
|
if intersect == a: |
|
return b |
|
elif intersect == b: |
|
return a |
|
|
|
@union_sets.register(ComplexRegion, Set) |
|
def _(a, b): |
|
if b.is_subset(S.Reals): |
|
|
|
b = ComplexRegion.from_real(b) |
|
|
|
if b.is_ComplexRegion: |
|
|
|
if (not a.polar) and (not b.polar): |
|
return ComplexRegion(Union(a.sets, b.sets)) |
|
|
|
elif a.polar and b.polar: |
|
return ComplexRegion(Union(a.sets, b.sets), polar=True) |
|
return None |
|
|
|
@union_sets.register(EmptySet, Set) |
|
def _(a, b): |
|
return b |
|
|
|
|
|
@union_sets.register(UniversalSet, Set) |
|
def _(a, b): |
|
return a |
|
|
|
@union_sets.register(ProductSet, ProductSet) |
|
def _(a, b): |
|
if b.is_subset(a): |
|
return a |
|
if len(b.sets) != len(a.sets): |
|
return None |
|
if len(a.sets) == 2: |
|
a1, a2 = a.sets |
|
b1, b2 = b.sets |
|
if a1 == b1: |
|
return a1 * Union(a2, b2) |
|
if a2 == b2: |
|
return Union(a1, b1) * a2 |
|
return None |
|
|
|
@union_sets.register(ProductSet, Set) |
|
def _(a, b): |
|
if b.is_subset(a): |
|
return a |
|
return None |
|
|
|
@union_sets.register(Interval, Interval) |
|
def _(a, b): |
|
if a._is_comparable(b): |
|
|
|
end = Min(a.end, b.end) |
|
start = Max(a.start, b.start) |
|
if (end < start or |
|
(end == start and (end not in a and end not in b))): |
|
return None |
|
else: |
|
start = Min(a.start, b.start) |
|
end = Max(a.end, b.end) |
|
|
|
left_open = ((a.start != start or a.left_open) and |
|
(b.start != start or b.left_open)) |
|
right_open = ((a.end != end or a.right_open) and |
|
(b.end != end or b.right_open)) |
|
return Interval(start, end, left_open, right_open) |
|
|
|
@union_sets.register(Interval, UniversalSet) |
|
def _(a, b): |
|
return S.UniversalSet |
|
|
|
@union_sets.register(Interval, Set) |
|
def _(a, b): |
|
|
|
|
|
|
|
open_left_in_b_and_finite = (a.left_open and |
|
sympify(b.contains(a.start)) is S.true and |
|
a.start.is_finite) |
|
open_right_in_b_and_finite = (a.right_open and |
|
sympify(b.contains(a.end)) is S.true and |
|
a.end.is_finite) |
|
if open_left_in_b_and_finite or open_right_in_b_and_finite: |
|
|
|
open_left = a.left_open and a.start not in b |
|
open_right = a.right_open and a.end not in b |
|
new_a = Interval(a.start, a.end, open_left, open_right) |
|
return {new_a, b} |
|
return None |
|
|
|
@union_sets.register(FiniteSet, FiniteSet) |
|
def _(a, b): |
|
return FiniteSet(*(a._elements | b._elements)) |
|
|
|
@union_sets.register(FiniteSet, Set) |
|
def _(a, b): |
|
|
|
if any(b.contains(x) == True for x in a): |
|
return { |
|
FiniteSet(*[x for x in a if b.contains(x) != True]), b} |
|
return None |
|
|
|
@union_sets.register(Set, Set) |
|
def _(a, b): |
|
return None |
|
|