Skip to content
This repository was archived by the owner on Jan 30, 2023. It is now read-only.

Commit 72565f2

Browse files
rwstMatthias Koeppe
authored and
Matthias Koeppe
committed
24171: Formal set membership function
1 parent 30ee8d6 commit 72565f2

File tree

5 files changed

+97
-4
lines changed

5 files changed

+97
-4
lines changed

src/sage/functions/other.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2285,3 +2285,58 @@ def _evalf_(self, poly, index, parent=None, algorithm=None):
22852285

22862286
complex_root_of = Function_crootof()
22872287

2288+
2289+
class Function_elementof(BuiltinFunction):
2290+
"""
2291+
Formal set membership function that is only accessible internally.
2292+
2293+
This function is called to express a set membership statement,
2294+
usually as part of a solution set returned by ``solve()``.
2295+
See :class:`sage.sets.set.Set` and :class:`sage.sets.real_set.RealSet`
2296+
for possible set arguments.
2297+
2298+
EXAMPLES::
2299+
2300+
sage: from sage.functions.other import element_of
2301+
sage: element_of(x, SR(ZZ))
2302+
element_of(x, Integer Ring)
2303+
sage: element_of(sin(x), SR(QQ))
2304+
element_of(sin(x), Rational Field)
2305+
sage: element_of(x, SR(RealSet.open_closed(0,1)))
2306+
element_of(x, (0, 1])
2307+
sage: element_of(x, SR(Set([4,6,8])))
2308+
element_of(x, {8, 4, 6})
2309+
"""
2310+
def __init__(self):
2311+
"""
2312+
EXAMPLES::
2313+
2314+
sage: from sage.functions.other import element_of
2315+
sage: loads(dumps(element_of))
2316+
element_of
2317+
"""
2318+
BuiltinFunction.__init__(self, "element_of", nargs=2)
2319+
2320+
def _latex_(self):
2321+
r"""
2322+
EXAMPLES::
2323+
2324+
sage: from sage.functions.other import element_of
2325+
sage: latex(element_of)
2326+
\in
2327+
"""
2328+
return r'\in'
2329+
2330+
def _print_latex_(self, ex, s):
2331+
r"""
2332+
EXAMPLES::
2333+
2334+
sage: from sage.functions.other import element_of
2335+
sage: latex(element_of(x, SR(ZZ)))
2336+
x \in \Bold{Z}
2337+
sage: latex(element_of(x, SR(Set([4,6,8]))))
2338+
x \in \left\{8, 4, 6\right\}
2339+
"""
2340+
return r"{} \in {}".format(latex(ex), latex(s))
2341+
2342+
element_of = Function_elementof()

src/sage/libs/pynac/pynac.pyx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1190,7 +1190,7 @@ cdef bint py_is_real(a):
11901190
return False
11911191
except NotImplementedError:
11921192
return False
1193-
except AttributeError:
1193+
except (TypeError, AttributeError):
11941194
pass
11951195
return py_imag(a) == 0
11961196

src/sage/sets/real_set.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -986,6 +986,21 @@ def is_empty(self):
986986
"""
987987
return len(self._intervals) == 0
988988

989+
def is_finite(self):
990+
"""
991+
Return whether the set is finite.
992+
993+
EXAMPLES::
994+
995+
sage: RealSet().is_finite()
996+
True
997+
sage: RealSet(0, 0).is_finite()
998+
True
999+
sage: RealSet(0, 1).is_finite()
1000+
False
1001+
"""
1002+
return self.is_empty() or all(i.is_point() for i in self._intervals)
1003+
9891004
def get_interval(self, i):
9901005
"""
9911006
Return the ``i``-th connected component.

src/sage/symbolic/random_tests.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
from sage.symbolic.constants import (pi, e, golden_ratio, log2, euler_gamma,
2121
catalan, khinchin, twinprime, mertens)
2222
from sage.functions.hypergeometric import hypergeometric
23-
from sage.functions.other import cases
23+
from sage.functions.other import (cases, element_of)
2424
from sage.symbolic.comparison import mixed_order
2525

2626
###################################################################
@@ -48,13 +48,13 @@ def _mk_full_functions():
4848
Note that this doctest will produce different output whenever a
4949
symbolic function is added or removed.
5050
"""
51+
excluded = [hypergeometric, cases, element_of]
5152
items = sorted(symbol_table['functions'].items())
5253
return [(1.0, f, f.number_of_arguments())
5354
for (name, f) in items
5455
if hasattr(f, 'number_of_arguments') and
5556
f.number_of_arguments() > 0 and
56-
f != hypergeometric and
57-
f != cases]
57+
f not in excluded]
5858

5959
# For creating simple expressions
6060

src/sage/symbolic/ring.pyx

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,19 @@ cdef class SymbolicRing(CommutativeRing):
254254
sage: SR(complex(2,-3))
255255
(2-3j)
256256
257+
Any proper subset of the complex numbers::
258+
259+
sage: SR(NN)
260+
Non negative integer semiring
261+
sage: SR(ZZ)
262+
Integer Ring
263+
sage: SR(Set([1/2, 2/3, 3/4]))
264+
{3/4, 2/3, 1/2}
265+
sage: SR(QQ.completion(oo, oo))
266+
Real Field
267+
sage: SR(RealSet(0, 1))
268+
(0, 1)
269+
257270
TESTS::
258271
259272
sage: SR._coerce_(int(5))
@@ -364,6 +377,7 @@ cdef class SymbolicRing(CommutativeRing):
364377
from sage.rings.infinity import (infinity, minus_infinity,
365378
unsigned_infinity)
366379
from sage.structure.factorization import Factorization
380+
from sage.categories.sets_cat import Sets
367381

368382
if isinstance(x, RealNumber):
369383
if x.is_NaN():
@@ -392,6 +406,15 @@ cdef class SymbolicRing(CommutativeRing):
392406
elif isinstance(x, Factorization):
393407
from sage.misc.all import prod
394408
return prod([SR(p)**e for p,e in x], SR(x.unit()))
409+
elif x in Sets():
410+
from sage.rings.all import NN, ZZ, QQ, AA
411+
from sage.sets.real_set import RealSet
412+
oo = infinity
413+
if (x.is_finite() or x in (NN, ZZ, QQ, AA, QQ.completion(oo,oo))
414+
or isinstance(x, RealSet)):
415+
exp = x
416+
else:
417+
raise TypeError(f"unable to convert {x!r} to a symbolic expression")
395418
else:
396419
raise TypeError(f"unable to convert {x!r} to a symbolic expression")
397420

0 commit comments

Comments
 (0)