def subs(self, *args, **kwargs): if all(isinstance(arg, Boolean) for arg in args): return ConditionalBoolean.subs(self, *args, **kwargs) old, new = args if old.is_Slice: return self._subs_slice(old, new) new = sympify(new) if old in self.variables: wrt, *ab = self.limits[self.variables.index(old)] if len(ab) == 1: domain = ab[0] else: a, b = ab if b.is_set: domain = b & old.domain_conditioned(a) else: from sympy import Range domain = (Range if wrt.is_integer else Interval)(a, b) eqs = [] if not domain.is_set: domain = old.domain_conditioned(domain) from sympy.sets.contains import NotContains limit_cond = NotContains(new, domain).simplify() eqs.append(limit_cond) if self.function.is_Or: for equation in self.function.args: eqs.append(equation._subs(old, new)) else: eqs.append(self.function._subs(old, new)) limits = self.limits_delete(old) if limits: for i, (x, *ab) in enumerate(limits): if ab: limits[i] = (x, *(expr._subs(old, new) for expr in ab)) return self.func(Or(*eqs), *limits, given=self) else: return Or(*eqs, given=self).simplify() return ConditionalBoolean.subs(self, *args, **kwargs)
def simplify(self, local=None, **kwargs): deletes = [] for i in range(len(self.limits) - 1, -1, -1): x, *ab = self.limits[i] if not ab: deletes.append(x) continue if len(ab) == 1: domain = ab[0] else: a, b = ab if b.is_set: continue from sympy import Range domain = (Range if x.is_integer else Interval)(a, b) if self.function._has(x) and domain.is_set: _eval_domain_defined = self.function.domain_defined(x) if _eval_domain_defined in domain: deletes.append(x) domain &= _eval_domain_defined if domain.is_FiniteSet: if len(domain) == 1: x0, *_ = domain function = self.function._subs(x, x0) if function.is_BooleanAtom: return function limits = [*self.limits] del limits[i] for j in range(i): limits[j] = limits[j]._subs(x, x0) if limits: return self.func(function, *limits) else: return function.simplify() if deletes: limits = self.limits_delete(deletes) if limits: return self.func(self.function, *limits).simplify() if local: limits = [(x, ) for x, *_ in self.limits if self.function._has(x)] return self.func(self.function, *limits) return self.function this = self.function.func.simplify_All(self, *self.args) if this is not None: return this return ConditionalBoolean.simplify(self, **kwargs)
def apply(self, axiom, *args, **kwargs): for arg in args: if isinstance(arg, tuple): x, *_ = arg from sympy import Basic if isinstance(x, Basic) and x.is_symbol: if x in self.variables_set: print('variables are given in Any context!') return self return ConditionalBoolean.apply(self, axiom, *args, **kwargs)
def __or__(self, eq): """Overloading for | operator""" if eq.is_Any: if self.limits == eq.limits: return self.func(self.function | eq.function, *self.limits) if self.function == eq.function: limits = self.limits_union(eq) return self.func(self.function, *limits).simplify() return ConditionalBoolean.__or__(self, eq)
def subs(self, *args, **kwargs): if all(isinstance(arg, Boolean) for arg in args): if 'var' in kwargs: assert len(args) == 0 args = [self.limits_dict[kwargs.pop('var')]] if len(args) == 1: eq, *_ = args if self.function.is_And: if eq in self.function.args: function = self.function.subs(eq) clue = function.clue kwargs.clear() kwargs[clue] = self return self.func(function, *self.limits, **kwargs).simplify() return ConditionalBoolean.subs(self, *args, **kwargs)
def __and__(self, eq): """Overloading for & operator""" if eq.is_All: if self.function == eq.function: limits = self.limits_union(eq) return self.func(self.function, *limits).simplify() if self.limits == eq.limits: return All(self.function & eq.function, *self.limits) for i, (x, *ab) in enumerate(self.limits): if len(ab) == 1: cond, *_ = ab if cond.is_Unequal: invert = cond.invert() if self.function._subs(*invert.args) == eq: limits = [self.limits] del limits[i] return self.func(self.function, *limits).simplify() return ConditionalBoolean.__and__(self, eq)
def apply(self, axiom, *args, **kwargs): for arg in args: if isinstance(arg, tuple): x, *_ = arg from sympy import Basic if isinstance(x, Basic) and x.is_symbol: if x in self.free_symbols: return self elif x in self.variables_set: index = self.variables.index(x) x, domain = Tuple.as_setlimit(arg) x, domain_given = Tuple.as_setlimit(self.limits[index]) if domain.is_set and domain_given.is_set: if domain in domain_given: ... else: print( "variables' are beyond the bound given in All context!" ) return self return ConditionalBoolean.apply(self, axiom, *args, **kwargs)
def _pretty(self, p): return ConditionalBoolean._pretty(self, p, '\N{FOR ALL}')
def simplify(self, **kwargs): from sympy import S from sympy.sets.contains import Contains, NotContains if self.function.is_Equal: limits_dict = self.limits_dict x = None if self.function.lhs in limits_dict: x = self.function.lhs y = self.function.rhs elif self.function.rhs in limits_dict: x = self.function.rhs y = self.function.lhs if x is not None and not y.has(x): domain = limits_dict[x] if isinstance(domain, list): if len(self.limits) == 1: if all(not var.is_given for var in y.free_symbols): return S.BooleanTrue elif domain.is_set: t = self.variables.index(x) if not any(limit._has(x) for limit in self.limits[:t]): function = Contains(y, domain) if function: return function limits = self.limits_delete(x) if limits: return self.func(function, *limits) return function from sympy import Unequal, Equal if self.function.is_Contains: limits_dict = self.limits_dict x = None if self.function.lhs in limits_dict: x = self.function.lhs S = self.function.rhs if x is not None: domain = limits_dict[x] if isinstance(domain, list): return self # function = Unequal(S, x.emptySet) elif domain.is_set: if domain.is_FiniteSet: function = Contains(domain.arg, S) else: function = Unequal(S & domain, x.emptySet) else: function = None if function is not None: limits = self.limits_delete((x, )) if limits: return self.func(function, *limits).simplify() else: if function.is_BooleanAtom: return function return function elif self.function.is_NotContains: limits_dict = self.limits_dict x = None if self.function.lhs in limits_dict: x = self.function.lhs S = self.function.rhs if x is not None: domain = limits_dict[x] if isinstance(domain, list): function = Equal(S, x.emptySet) elif domain.is_set: if domain.is_FiniteSet: function = NotContains(domain.arg, S) else: function = Unequal(domain // S, x.emptySet) else: function = None if function is not None: limits = self.limits_delete((x, )) if limits: return self.func(function, *limits).simplify() else: if function.is_BooleanAtom: return function return function if self.function.is_And: limits_dict = self.limits_dict for i, eq in enumerate(self.function.args): if eq.is_Contains and eq.lhs in limits_dict: domain = limits_dict[eq.lhs] if isinstance(domain, list): eqs = [*self.function.args] del eqs[i] if not eq.rhs.has(*self.variables[:i]): return self.func( And(*eqs), *self.limits_update(eq.lhs, eq.rhs)).simplify() elif domain == eq.rhs: eqs = [*self.function.args] del eqs[i] return self.func(And(*eqs), *self.limits) if eq.is_Equal: if eq.lhs in limits_dict: old, new = eq.args elif eq.rhs in limits_dict: new, old = eq.args else: continue continue if self.function.is_Or: limits_dict = self.limits_dict for i, eq in enumerate(self.function.args): if eq.is_NotContains and eq.lhs in limits_dict: domain = limits_dict[eq.lhs] if not isinstance(domain, list) and domain in eq.rhs: eqs = [*self.function.args] del eqs[i] return self.func(And(*eqs), *self.limits) if eq.is_Unequal: continue if eq.lhs in limits_dict: old, new = eq.args elif eq.rhs in limits_dict: new, old = eq.args else: continue limits = self.limits_delete(old) if any(limit._has(old) for limit in limits): continue eqs = [*self.function.args] del eqs[i] eqs = [eq._subs(old, new) for eq in eqs] domain = limits_dict[old] if isinstance(domain, list): limit = (old, ) else: limit = (old, domain) eq = self.func(eq, limit).simplify() eqs.append(eq) return self.func(And(*eqs), *limits).simplify() if self.function.is_Equal: limits_dict = self.limits_dict x = None if self.function.lhs in limits_dict: x = self.function.lhs y = self.function.rhs elif self.function.rhs in limits_dict: x = self.function.rhs y = self.function.lhs return ConditionalBoolean.simplify(self, **kwargs)
def _pretty(self, p): return ConditionalBoolean._pretty(self, p, '\N{THERE EXISTS}')