def check(self, **kwargs):
        """
        Forces simplification and casts as `Equality` to check validity.
        Parameters
        ----------
        kwargs any appropriate for `Equality`.

        Returns
        -------
        True, False or an unevaluated `Equality` if truth cannot be determined.
        """
        from sympy.core.relational import Equality
        return Equality(self.lhs, self.rhs, **kwargs).simplify()
示例#2
0
def apply(x, w=None):
    n = x.shape[0]
    i = Symbol.i(domain=Interval(0, n - 1, integer=True))
    j = Symbol.j(domain=Interval(0, n - 1, integer=True))

    if w is None:
        w = Symbol.w(integer=True,
                     shape=(n, n, n, n),
                     definition=LAMBDA[j, i](Shift(n, i, j)))
    else:
        assert w[i, j] == Shift(n, i, j)

    return Equality(w[i, j].T @ w[i, j] @ x, x)
示例#3
0
    def definition(self):
        e, S = self.args

        from sympy.concrete.expr_with_limits import Exists

        condition_set = S.condition_set()
        if condition_set:
            condition = condition_set.condition
            if condition_set.variable != e:
                condition = condition._subs(condition_set.variable, e)
            return And(condition,
                       self.func(e, condition_set.base_set),
                       equivalent=self)

        image_set = S.image_set()
        if image_set is not None:
            expr, variables, base_set = image_set
            from sympy import Wild
            variables_ = Wild(variables.name, **variables.dtype.dict)
            assert variables_.shape == variables.shape
            e = e.subs_limits_with_epitome(expr)
            dic = e.match(expr.subs(variables, variables_))
            if dic:
                variables_ = dic[variables_]
                if variables.dtype != variables_.dtype:
                    assert len(variables.shape) == 1
                    variables_ = variables_[:variables.shape[-1]]
                return Contains(variables_, base_set, equivalent=self)

            if e._has(variables):
                _variables = base_set.element_symbol(e.free_symbols)
                assert _variables.dtype == variables.dtype
                expr = expr._subs(variables, _variables)
                variables = _variables
            assert not e._has(variables)
            return Exists(Equality(e, expr, evaluate=False),
                          (variables, base_set),
                          equivalent=self)

        if S.is_UNION:
            for v in S.variables:
                if self.lhs._has(v):
                    _v = v.generate_free_symbol(self.free_symbols,
                                                **v.dtype.dict)
                    S = S.limits_subs(v, _v)

            contains = Contains(self.lhs, S.function).simplify()
            contains.equivalent = None
            return Exists(contains, *S.limits, equivalent=self).simplify()

        return self
示例#4
0
def prove(Eq):
    n = Symbol.n(integer=True, positive=True)
    p = Symbol.p(integer=True, shape=(n, ))
    x = Symbol.x(integer=True, shape=(n, ))

    Eq << apply(
        Equality(p.set_comprehension(), Interval(0, n - 1, integer=True)), x)

    A = Symbol.A(definition=Eq[1].lhs)
    B = Symbol.B(definition=Eq[1].rhs)
    Eq.A_definition = A.this.definition

    i = Eq[1].lhs.variable
    _i = Symbol.i(domain=Interval(0, n - 1, integer=True))

    Eq.A_definition = Eq.A_definition.this.rhs.limits_subs(i, _i)
    j = Eq[1].rhs.variable
    _j = Symbol.j(domain=Interval(0, n - 1, integer=True))

    Eq.B_definition = B.this.definition
    Eq.B_definition = Eq.B_definition.this.rhs.limits_subs(
        Eq.B_definition.rhs.variable, _j)

    Eq.subset = Subset(Eq.A_definition.rhs,
                       Eq.B_definition.rhs,
                       plausible=True)

    Eq << Eq.subset.simplify()

    Eq << Eq[-1].definition

    Eq << Eq[-1].subs(Eq[-1].variable, p[_i])

    Eq.supset = Supset(Eq.subset.lhs, Eq.subset.rhs, plausible=True)

    Eq << Eq.supset.simplify()

    Eq.definition = Eq[-1].definition

    Eq << discrete.combinatorics.permutation.index.equality.apply(Eq[0], _j)

    index_j = Eq[-1].lhs.indices[0]
    Eq << Eq.definition.subs(Eq[-1].reversed)

    Eq << Eq[-1].subs(Eq[-1].variable, index_j)

    Eq <<= Eq.subset & Eq.supset

    Eq << Eq[-1].this.lhs.limits_subs(_i, i)

    Eq << Eq[-1].this.rhs.limits_subs(_j, j)
示例#5
0
def prove(Eq):
    n = Symbol.n(integer=True, positive=True)
    m = Symbol.m(integer=True, positive=True)
    A = Symbol.A(dtype=dtype.integer * n)
    a = Symbol.a(integer=True, shape=(n, ))
    B = Symbol.B(dtype=dtype.integer * m)
    b = Symbol.b(integer=True, shape=(m, ))

    f = Function.f(nargs=(n, ), integer=True, shape=(m, ))
    g = Function.g(nargs=(m, ), integer=True, shape=(n, ))

    assert f.is_integer
    assert g.is_integer
    assert f.shape == (m, )
    assert g.shape == (n, )

    Eq << apply(ForAll[a:A](Contains(f(a), B)), ForAll[b:B](Contains(g(b), A)),
                ForAll[a:A](Equality(a, g(f(a)))))

    Eq << Eq[1].apply(sets.contains.imply.subset, simplify=False)

    Eq.subset_A = Eq[-1].apply(sets.subset.imply.subset,
                               *Eq[-1].limits,
                               simplify=False)

    Eq.supset_A = Eq.subset_A.func.reversed_type(*Eq.subset_A.args,
                                                 plausible=True)

    Eq << Eq.supset_A.definition.definition

    Eq << Eq[-1].subs(Eq[2])

    Eq << ForAll[a:A](Exists[b:B](Equality(f(a), b)), plausible=True)
    Eq << Eq[-1].this.function.simplify()

    Eq << Eq[-1].apply(algebre.scalar.equality.invoke, g)

    Eq <<= Eq.supset_A & Eq.subset_A
示例#6
0
def test_cython_wrapper_inoutarg():
    from sympy.core.relational import Equality
    x, y, z = symbols('x,y,z')
    code_gen = CythonCodeWrapper(C99CodeGen())
    routine = make_routine("test", Equality(z, x + y + z))
    source = get_string(code_gen.dump_pyx, [routine])
    expected = ("cdef extern from 'file.h':\n"
                "    void test(double x, double y, double *z)\n"
                "\n"
                "def test_c(double x, double y, double z):\n"
                "\n"
                "    test(x, y, &z)\n"
                "    return z")
    assert source == expected
示例#7
0
def apply(*given):
    assert len(given) == 2    
    set_comprehension_equality, last_element_equality = given
    
    if last_element_equality.lhs.is_UNION:
        last_element_equality, set_comprehension_equality = set_comprehension_equality, last_element_equality
    p = last_element_equality.lhs.base
    n = last_element_equality.rhs
    
    assert set_comprehension_equality.is_Equality
    assert set_comprehension_equality.lhs._dummy_eq(p[:n].set_comprehension())
    assert set_comprehension_equality.rhs == Interval(0, n - 1, integer=True)
    
    return Equality(p[:n + 1].set_comprehension(), Interval(0, n, integer=True), given=given)
示例#8
0
def apply(x, w=None):
    n = x.shape[0]
    i = Symbol.i(integer=True)
    j = Symbol.j(integer=True)
    if w is None:
        w = Symbol.w(integer=True,
                     shape=(n, n, n, n),
                     definition=LAMBDA[j:n, i:n](Swap(n, i, j)))
    else:
        assert len(w.shape) == 4 and all(s == n for s in w.shape)
        assert w[i, j].is_Swap or w[i, j].definition.is_Swap

    lhs = (w[i, j] @ x).set_comprehension()
    return Equality(lhs, x.set_comprehension(free_symbol=lhs.variable))
示例#9
0
def apply(y, x=None):
    if x is None:
        if not isinstance(y, Integral):
            print('not isinstance(y, Integral)')
            return None
        if len(y.limits) > 1:
            return None
        (x, a, b), *_ = y.limits

        if a != -oo or b != oo:
            return None

        a, b, c = coefficient(y.function, x)
        if a <= 0:
            return None

        return Equality(y, doit(a, b, c))

    a, b, c = coefficient(y, x)

    if a <= 0:
        return None
    return Equality(Integral(y, (x, -oo, oo)), doit(a, b, c))
示例#10
0
def prove(Eq):
    n = Symbol.n(domain=Interval(2, oo, integer=True))
    S = Symbol.S(dtype=dtype.integer * n)

    x = Symbol.x(**S.element_symbol().dtype.dict)

    i = Symbol.i(integer=True)
    j = Symbol.j(integer=True)
    k = Symbol.k(integer=True)

    e = Symbol.e(dtype=dtype.integer, given=True)

    p = Symbol.p(shape=(oo, ), integer=True, nonnegative=True)

    P = Symbol.P(dtype=dtype.integer * n,
                 definition=conditionset(
                     p[:n],
                     Equality(p[:n].set_comprehension(),
                              Interval(0, n - 1, integer=True))))

    Eq << apply(ForAll[x:S](Equality(x.set_comprehension(), e)),
                ForAll[x:S, p[:n]:P](Contains(LAMBDA[k:n](x[p[k]]), S)),
                Equality(abs(e), n))
示例#11
0
def _common_new(cls, function, *symbols, **assumptions):
    """Return either a special return value or the tuple,
    (function, limits, orientation). This code is common to
    both ExprWithLimits and AddWithLimits."""
    function = sympify(function)

    if hasattr(function, 'func') and isinstance(function, Equality):
        lhs = function.lhs
        rhs = function.rhs
        return Equality(cls(lhs, *symbols, **assumptions), \
                        cls(rhs, *symbols, **assumptions))

    if function is S.NaN:
        return S.NaN

    if symbols:
        limits, orientation = _process_limits(*symbols)
        for i, li in enumerate(limits):
            if len(li) == 4:
                function = function.subs(li[0], li[-1])
                limits[i] = Tuple(*li[:-1])
    else:
        # symbol not provided -- we can still try to compute a general form
        free = function.free_symbols
        if len(free) != 1:
            raise ValueError("specify dummy variables for %s" % function)
        limits, orientation = [Tuple(s) for s in free], 1

    # denest any nested calls
    while cls == type(function):
        limits = list(function.limits) + limits
        function = function.function

    # Any embedded piecewise functions need to be brought out to the
    # top level. We only fold Piecewise that contain the integration
    # variable.
    reps = {}
    symbols_of_integration = set([i[0] for i in limits])
    for p in function.atoms(Piecewise):
        if not p.has(*symbols_of_integration):
            reps[p] = Dummy()
    # mask off those that don't
    function = function.xreplace(reps)
    # do the fold
    function = piecewise_fold(function)
    # remove the masking
    function = function.xreplace({v: k for k, v in reps.items()})

    return function, limits, orientation
示例#12
0
def prove(Eq):
    n = Symbol.n(integer=True, positive=True)
    m = Symbol.m(integer=True, positive=True)
    f = Function.f(nargs=(n, ), real=True, shape=(m, ))
    x = Symbol.x(real=True, shape=(n, ))
    a = Symbol.a(real=True)
    b = Symbol.b(real=True, shape=(n, ))
    Eq << apply(Equality(x * a, b), f)

    y = Symbol.y(definition=f(a * x))
    Eq << y.this.definition

    Eq << Eq[-1].this.rhs.subs(Eq[0])

    Eq << Eq[-1].subs(Eq[-2])
示例#13
0
def prove(Eq):
    x = Symbol.x(real=True, random=True)
    y = Symbol.y(real=True, random=True)
    z = Symbol.z(real=True, random=True)

    Eq << apply(Equality(x | y.as_boolean() & z.as_boolean(), x | y),
                Equality(z | y, z))

    Eq.yz_nonzero, Eq.y_nonzero = Eq[0].domain_definition().split()

    _, Eq.z_nonzero = bayes.inequality.et.apply(Eq.yz_nonzero).split()

    Eq << bayes.theorem.apply(Eq.yz_nonzero, var=x)

    Eq << Eq[-1].subs(Eq[0])

    Eq << bayes.theorem.apply(Eq.y_nonzero, var=z)

    Eq << Eq[-2].subs(Eq[-1])

    Eq.xy_probability = bayes.theorem.apply(Eq.y_nonzero, var=x)

    Eq << Eq[-1].subs(Eq.xy_probability.reversed)

    Eq << Eq[-1].subs(Eq[1])

    Eq << Eq[-1].lhs.total_probability_theorem(y).subs(
        bayes.theorem.apply(Eq.z_nonzero, var=x))

    Eq << Eq[-2].integrate((pspace(y).symbol, )).subs(Eq[-1])

    Eq << Eq.xy_probability.lhs.total_probability_theorem(y)

    Eq << Eq[-2].subs(Eq[-1])

    Eq << algebre.scalar.inequality.equality.apply(Eq[-1], Eq.z_nonzero)
示例#14
0
def prove(Eq):
    A = Symbol.A(dtype=dtype.integer)
    B = Symbol.B(dtype=dtype.integer)

    Eq << apply(Equality(A & B, A | B))

    Eq << Subset(A, A | B, plausible=True).subs(Eq[0].reversed)
    Eq << Subset(A & B, B, plausible=True)

    Eq.subset = Eq[-2].subs(Eq[-1])

    Eq << Subset(B, A | B, plausible=True).subs(Eq[0].reversed)
    Eq << Subset(A & B, A, plausible=True)

    Eq << Eq[-2].subs(Eq[-1]).subs(Eq.subset).reversed
示例#15
0
def prove(Eq):
    A = Symbol.A(dtype=dtype.integer)
    i = Symbol.i(integer=True)
    k = Symbol.k(integer=True, positive=True)
    x = Symbol.x(shape=(k + 1, ), dtype=dtype.integer)

    Eq << apply(Equality(UNION[i:0:k](x[i]) & A, S.EmptySet))

    Eq << Eq[-1].simplify()

    Eq << UNION[i:0:k](x[i] & A).this.simplify()

    Eq << Eq[-1].this.rhs.subs(Eq[0])

    Eq << Eq[-1].apply(sets.equality.imply.forall_equality.union_comprehension)
示例#16
0
    def _matches(self):
        r"""
        Matches any differential equation that nth_algebraic can solve. Uses
        `sympy.solve` but teaches it how to integrate derivatives.

        This involves calling `sympy.solve` and does most of the work of finding a
        solution (apart from evaluating the integrals).
        """
        eq = self.ode_problem.eq
        func = self.ode_problem.func
        var = self.ode_problem.sym

        # Derivative that solve can handle:
        diffx = self._get_diffx(var)

        # Replace derivatives wrt the independent variable with diffx
        def replace(eq, var):
            def expand_diffx(*args):
                differand, diffs = args[0], args[1:]
                toreplace = differand
                for v, n in diffs:
                    for _ in range(n):
                        if v == var:
                            toreplace = diffx(toreplace)
                        else:
                            toreplace = Derivative(toreplace, v)
                return toreplace

            return eq.replace(Derivative, expand_diffx)

        # Restore derivatives in solution afterwards
        def unreplace(eq, var):
            return eq.replace(diffx, lambda e: Derivative(e, var))

        subs_eqn = replace(eq, var)
        try:
            # turn off simplification to protect Integrals that have
            # _t instead of fx in them and would otherwise factor
            # as t_*Integral(1, x)
            solns = solve(subs_eqn, func, simplify=False)
        except NotImplementedError:
            solns = []

        solns = [simplify(unreplace(soln, var)) for soln in solns]
        solns = [Equality(func, soln) for soln in solns]

        self.solutions = solns
        return len(solns) != 0
示例#17
0
    def marginalize_condition(cls, condition, given):
        if condition.is_And:
            expr = []
            hit = False
            for eq in condition.args:
                if eq.is_Equality:
                    lhs, rhs = eq.args
                    if lhs.is_symbol and pspace(lhs).symbol == rhs:
                        if lhs._has(given):
                            if lhs == given:
                                hit = True
                                continue

                            if given.is_Indexed:
                                start = given.indices[0]
                                stop = start + 1
                            elif given.is_Slice:
                                start, stop = given.indices
                            else:
                                expr.append(eq)
                                continue

                            lhs = lhs.bisect(Slice[start:stop])
                            if not lhs.is_Concatenate:
                                hit = True
                            else:
                                rhs = rhs.bisect(Slice[start:stop])
                                for lhs, rhs in zip(lhs.args, rhs.args):
                                    eq = Equality(lhs, rhs)
                                    if lhs == given:
                                        hit = True
                                    else:
                                        expr.append(eq)
                            continue
                expr.append(eq)
            if hit:
                return cls(And(*expr))
        elif condition.is_Conditioned:
            self = cls(condition.lhs).marginalize(given)
            return self.func(self.arg, given=condition.rhs)
        elif condition.is_Equal:
            if given.is_Slice:
                start, stop = given.indices
                condition = condition.bisect(Slice[start:stop])
            elif given.is_Indexed:
                condition = condition.bisect(Slice[given.indices])
            if condition.is_And:
                return cls.marginalize_condition(condition, given)
示例#18
0
def apply(*given):
    given_equality, unequal = given
    assert unequal.is_Unequality
    assert unequal.lhs.is_Probability
    assert unequal.rhs.is_zero

    assert given_equality.is_Equality
    lhs, rhs = given_equality.args
    assert lhs.is_Conditioned
    x, y = lhs.args
    assert x == rhs

    if y.is_Equality:
        y = y.lhs
    assert y.is_random and y.is_symbol
    return Equality(y | x, y, given=given)
示例#19
0
def apply(given, x):
    assert given.is_Equality
    p_set_comprehension, interval = given.args
    assert len(p_set_comprehension.limits) == 1
    i, zero, n_1 = p_set_comprehension.limits[0]
    assert zero.is_zero
    n = n_1 + 1
    assert p_set_comprehension.function.is_FiniteSet
    p = p_set_comprehension.function.arg.base
    assert p_set_comprehension == p[:n].set_comprehension()
    zero, _n, _ = interval.args
    assert zero.is_zero
    assert _n == n and interval.right_open
    return Equality(UNION[i:n](x[p[i]].set),
                    x[:n].set_comprehension(),
                    given=given)
示例#20
0
def prove(Eq):
    p = Symbol.p(complex=True)    
    n = Symbol.n(domain=Interval(1, oo, integer=True))
    x = Symbol.x(shape=(n,), given=True, complex=True)
    y = Symbol.y(shape=(n,), given=True, complex=True)
    k = Symbol.k(domain=Interval(1, oo, integer=True))
    
    given = Equality(x @ LAMBDA[k:n](p ** k), y @ LAMBDA[k:n](p ** k))
    
    Eq << apply(given)
    Eq << algebre.vector.cosine_similarity.apply(*given.lhs.args)
    Eq << algebre.vector.cosine_similarity.apply(*given.rhs.args)
    
    Eq << given.subs(Eq[-1], Eq[-2])
    
    Eq << matmul_equality.apply(Eq[-1])
示例#21
0
def apply(given):
    assert given.is_ForAll
    assert given.function.is_Equality
    assert given.function.lhs.is_Limit
    f, z, xi, direction = given.function.lhs.args
    assert direction.name == '+-'
    assert len(given.limits) == 1
    limit = given.limits[0]
    _xi, a, b = limit
    assert xi == _xi
    _f = f._subs(z, xi)
    assert given.function.rhs == _f

    return Exists(Equality(Integral(f, (z, a, b)), (b - a) * _f),
                  limit,
                  given=given)
示例#22
0
def test_jl_matrixsymbol_slice_autoname():
    A = MatrixSymbol('A', 2, 3)
    B = MatrixSymbol('B', 1, 3)
    name_expr = ("test", [Equality(B, A[0,:]), A[1,:], A[:,0], A[:,1]])
    result, = codegen(name_expr, "Julia", header=False, empty=False)
    source = result[1]
    expected = (
        "function test(A)\n"
        "    B = A[1,:]\n"
        "    out2 = A[2,:]\n"
        "    out3 = A[:,1]\n"
        "    out4 = A[:,2]\n"
        "    return B, out2, out3, out4\n"
        "end\n"
    )
    assert source == expected
示例#23
0
def apply(n, k, s2=None, B=None):
    if s2 is None:
        x = Symbol.x(shape=(oo, ), dtype=dtype.integer, finite=True)
        s2 = Symbol.s2(
            definition=UNION[x[:k + 1]:Stirling.conditionset(n + 1, k + 1, x)](
                x[:k + 1].set_comprehension().set))
    e = Symbol.e(**s2.element_type.dict)

    if B is None:
        x = s2.definition.variable.base
        s0 = Symbol.s0(definition=UNION[x[:k]:Stirling.conditionset(n, k, x)](
            x[:k].set_comprehension().set))

        B = Symbol.B(definition=UNION[e:s0]({e | {n.set}}))

    return Equality(conditionset(e, Contains({n}, e), s2), B)
示例#24
0
def apply(x, d, w=None):
    n = x.shape[0]
    assert d.shape == (n, )
    i = Symbol.i(integer=True)
    j = Symbol.j(integer=True)
    k = Symbol.k(integer=True)

    if w is None:
        w = Symbol.w(integer=True,
                     shape=(n, n, n, n),
                     definition=LAMBDA[j:n, i:n](Swap(n, i, j)))
    else:
        assert len(w.shape) == 4 and all(s == n for s in w.shape)
        assert w[i, j].is_Swap or w[i, j].definition.is_Swap

    return Equality(x[d @ w[i, j, k]], LAMBDA[k:n](x[d[k]]) @ w[i, j, k])
示例#25
0
def prove(Eq):
    S = Symbol.S(dtype=dtype.integer)

    Eq << apply(Equality(abs(S), 1))

    Eq << StrictGreaterThan(abs(S), 0, plausible=True)

    Eq << Eq[-1].subs(Eq[0])

    Eq << sets.strict_greater_than.imply.inequality.apply(Eq[-1])

    Eq << sets.inequality.imply.exists.contains.apply(Eq[-1])

    Eq << Eq[-1].apply(sets.contains.imply.subset, simplify=False)

    Eq << Eq[-1].apply(sets.subset.equality.imply.equality, Eq[0])
示例#26
0
def prove(Eq):
    k = Symbol.k(integer=True, positive=True)
    n = Symbol.n(integer=True, positive=True)
    Eq << apply(n, k)

    i, j = Eq[1].rhs.args[0].cond.args
    x = Eq[1].rhs.args[1].expr.base
    x_hat = Symbol(r"\hat{x}",
                   definition=LAMBDA[i:k + 1](Piecewise(
                       (x[i] - {n}, Equality(i, j)), (x[i], True))))

    Eq.x_hat_definition = x_hat.this.definition[i]

    s1 = Eq[0].lhs
    x_quote = Eq[1].lhs.base
    Aj = Eq[3].lhs
    e = Symbol.e(**s1.element_type.dict)
示例#27
0
def prove(Eq):
    A = Symbol.A(dtype=dtype.integer)
    B = Symbol.B(dtype=dtype.integer)
    C = Symbol.C(dtype=dtype.integer)

    subset = Subset(A, B, evaluate=False)
    equality = Equality(B & C, S.EmptySet, evaluate=False)

    Eq << apply(equality, subset)

    Eq << subset.intersect(C)

    Eq << Eq[-1].subs(equality)

    Eq << Supset(*Eq[-1].args, plausible=True)

    Eq << Eq[-1].subs(Eq[-2])
示例#28
0
def apply(*given):
    forall_A, forall_B = given
    assert forall_A.is_ForAll and forall_B.is_ForAll
    assert len(forall_A.limits) == len(forall_B.limits) == 1
    x, A = forall_A.limits[0]
    _x, B = forall_B.limits[0]
    assert x == _x
    
    assert forall_A.function.is_Contains
    _x, _B = forall_A.function.args
    
    assert x == _x and B == _B
    assert forall_B.function.is_Contains
    _x, _A = forall_B.function.args
    assert x == _x and A == _A
    
    return Equality(A, B, given=given)
示例#29
0
def apply(*given):
    if given[0].is_Equality and given[1].is_Subset:
        given = [*given]
        given[0], given[1] = given[1], given[0]
    else:
        assert given[0].is_Subset and given[1].is_Equality

    A, B = given[0].args

    A_abs, B_abs = abs(A), abs(B)
    _A_abs, _B_abs = given[1].args
    if A_abs == _A_abs:
        assert _B_abs == B_abs
    else:
        assert _B_abs == A_abs

    return Equality(A, B, given=given)
示例#30
0
def apply(given, j=None):
    assert given.is_Equality
    x_set_comprehension, interval = given.args
    n = interval.max() + 1
    assert interval.min() == 0
    assert len(x_set_comprehension.limits) == 1
    k, a, b = x_set_comprehension.limits[0]
    assert b - a == n - 1
    x = LAMBDA(x_set_comprehension.function.arg,
               *x_set_comprehension.limits).simplify()

    if j is None:
        j = Symbol.j(domain=[0, n - 1], integer=True)

    assert j >= 0 and j < n

    return Exists[k:n](Equality(x[k], j), given=given)