예제 #1
0
    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)
예제 #2
0
    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)
예제 #3
0
    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)
예제 #4
0
    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)
예제 #5
0
    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)
예제 #6
0
    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)
예제 #7
0
    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)
예제 #8
0
 def _pretty(self, p):
     return ConditionalBoolean._pretty(self, p, '\N{FOR ALL}')
예제 #9
0
    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)
예제 #10
0
 def _pretty(self, p):
     return ConditionalBoolean._pretty(self, p, '\N{THERE EXISTS}')