sympy / sympy

A computer algebra system written in pure Python
https://sympy.org/
Other
12.97k stars 4.43k forks source link

Abstract set #18560

Open mlangiu opened 4 years ago

mlangiu commented 4 years ago

Is there any way to represent abtract sets in Sympy?

x = Symbol('x')
X = AbstractSet('X')  # Doesn't exist

Use cases could be sth. like:

set_membership = x in X  # Expecting symbolic representation x \in X here
set_membership.subs(X, FiniteSet(x, y, z))  # True
set_membership.subs(X, FiniteSet(1, 2, 3))  # False

abstract_sum = sympy.Sum(x, x in X)  # Expecting abstract summation here
abstract_sum.subs(X, {1, 5, 6})  # 12
oscarbenjamin commented 4 years ago

There is not. It would be good to have a SetSymbol for this.

mlangiu commented 4 years ago

Too bad... Thanks for the quick reply! Then I suppose I close this issue or do you want to leave it open for reference?

sylee957 commented 4 years ago

Yes, I have also had such inconvenience

But I wonder what kind of APIs would be needed to represent abstract sets in the texts I'd have some ideas like

  1. An abstract set symbol without cardinality
  2. A set symbol defined with cardinality
  3. A finite set symbol with cardinality, and set elements which are assumed to be distinct
oscarbenjamin commented 4 years ago

I would imagine that a SetSymbol could have a few properties like is_finite, is_countable, is_empty. Perhaps cardinality can represent all of those if it can be a symbol.

We should also have some way using the new assumptions with predicates like Subset(A, B), Disjoint(A, B) etc so that unions etc can be simplified with refine. We already have Contains(x, X) for "element of".

sylee957 commented 4 years ago

@oscarbenjamin I see you mention some multi-valued predicates like Subset(A, B), but I don't see anything like that exist yet and it looks like the current architecture doesn't allows to make something like that. For example, AppliedPredicate may only work for a single arg.

oscarbenjamin commented 4 years ago

I mean a symbolic Boolean like Contains:

In [53]: Contains(x, Reals)                                                                                                                    
Out[53]: x ∈ ℝ

In [54]: Contains(x, Reals).subs(x, 1)                                                                                                         
Out[54]: True
sylee957 commented 4 years ago

However, I can't see how to refine the unions with the ordinary Boolean like that. For example, refine has to use AppliedPredicate like refine(sqrt(x**2), Q.real(x)). And it looks like Q.true(x) can handle literally every boolean symbols in sympy, but it may not be a feasible way because it would be ambiguous to put the handlers for.