Ejemplo n.º 1
0
                else:
                    return range_len_is_nat.instantiate(
                        {
                            f: range_lambda,
                            i: range_start,
                            j: range_end
                        },
                        assumptions=assumptions)

    def do_reduced_simplification(self, assumptions=USE_DEFAULTS, **kwargs):
        '''
        A simplification of a Len operation computes the length as a sum
        of the lengths of each item of the ExprTuple operand, returning
        the equality between the Len expression and this computation,
        simplified to the extent possible.  An item may be a singular element
        (contribution 1 to the length) or an iteration contributing its length.
        '''
        return self._computation(must_evaluate=False, assumptions=assumptions)

    def do_reduced_evaluation(self, assumptions=USE_DEFAULTS, **kwargs):
        '''
        Return the evaluation of the length which equates that Len expression
        to an irreducible result.
        '''
        return self._computation(must_evaluate=True, assumptions=assumptions)


# Register these expression equivalence methods:
InnerExpr.register_equivalence_method(Len, 'computation', 'computed',
                                      'compute')
Ejemplo n.º 2
0
    if expressions.num_entries() == 0:
        from proveit.logic.booleans.conjunction import \
            empty_conjunction
        return empty_conjunction
    if expressions.is_double():
        from . import and_if_both
        return and_if_both.instantiate({
            A: expressions[0],
            B: expressions[1]
        },
                                       assumptions=assumptions)
    else:
        from . import and_if_all
        _m = expressions.num_elements(assumptions)
        return and_if_all.instantiate({
            m: _m,
            A: expressions
        },
                                      assumptions=assumptions)


# Register these expression equivalence methods:
InnerExpr.register_equivalence_method(And, 'commutation', 'commuted',
                                      'commute')
InnerExpr.register_equivalence_method(And, 'group_commutation',
                                      'group_commuted', 'group_commute')
InnerExpr.register_equivalence_method(And, 'association', 'associated',
                                      'associate')
InnerExpr.register_equivalence_method(And, 'disassociation', 'disassociated',
                                      'disassociate')
Ejemplo n.º 3
0
                elem_in_set, assumptions,
                "Automatic deduction of membership in exponentiated sets is "
                "only supported for an exponent that is a literal integer")
        if exponent_eval.lhs != exponent_eval.rhs:
            # after proving that the element is in the set taken to
            # the evaluation of the exponent, substitute back in the
            # original exponent.
            return exponent_eval.sub_left_side_into(elem_in_set,
                                                    assumptions=assumptions)
        return elem_in_set

    def side_effects(self, judgment):
        return
        yield


# outside any specific class:
# special Exp case of square root


def sqrt(base):
    '''
    Special function for square root version of an exponential.
    '''
    return Exp(base, frac(one, two))


# Register these expression equivalence methods:
InnerExpr.register_equivalence_method(Exp, 'distribution', 'distributed',
                                      'distribute')
Ejemplo n.º 4
0
        '''
        return groupCommutation(self, initIdx, finalIdx, length, disassociate, assumptions)
        
    def association(self, startIdx, length, assumptions=USE_DEFAULTS):
        '''
        Given numerical operands, deduce that this expression is equal to a form in which operands in the
        range [startIdx, startIdx+length) are grouped together.
        For example, (a + b + ... + y + z) = (a + b ... + (l + ... + m) + ... + y + z)
        '''
        from ._theorems_ import association
        return apply_association_thm(self, startIdx, length, association, assumptions)

    def disassociation(self, idx, assumptions=USE_DEFAULTS):
        '''
        Given numerical operands, deduce that this expression is equal to a form in which the operand
        at index idx is no longer grouped together.
        For example, (a + b ... + (l + ... + m) + ... + y+ z) = (a + b + ... + y + z)
        '''
        from ._theorems_ import disassociation
        return apply_disassociation_thm(self, idx, disassociation, assumptions)

# Register these expression equivalence methods:
InnerExpr.register_equivalence_method(Mult, 'commutation', 'commuted', 'commute')
InnerExpr.register_equivalence_method(Mult, 'groupCommutation', 'groupCommuted', 'groupCommute')
InnerExpr.register_equivalence_method(Mult, 'association', 'associated', 'associate')
InnerExpr.register_equivalence_method(Mult, 'disassociation', 'disassociated', 'disassociate')
InnerExpr.register_equivalence_method(Mult, 'distribution', 'distributed', 'distribute')
InnerExpr.register_equivalence_method(Mult, 'factorization', 'factorized', 'factor')
InnerExpr.register_equivalence_method(Mult, 'exponentCombination', 'combinedExponents', 'combineExponents')

Ejemplo n.º 5
0
            else:
                return multNegRightDouble.specialize(
                    {a: mult_expr.operands[0]}, assumptions=assumptions)
        aVal = mult_expr.operands[:idx]
        bVal = mult_expr.operands[idx]
        cVal = mult_expr.operands[idx + 1:]
        mVal = num(len(aVal))
        nVal = num(len(cVal))
        return multNegAnyDouble.specialize(
            {
                m: mVal,
                n: nVal,
                AA: aVal,
                B: bVal,
                CC: cVal
            },
            assumptions=assumptions)


# Register these expression equivalence methods:
InnerExpr.register_equivalence_method(Neg, 'doubleNegSimplification',
                                      'doubleNegSimplified',
                                      'doubleNegSimplify')
InnerExpr.register_equivalence_method(Neg, 'distribution', 'distributed',
                                      'distribute')
InnerExpr.register_equivalence_method(Neg, 'factorization', 'factorized',
                                      'factor')
InnerExpr.register_equivalence_method(Neg, 'innerNegMultSimplification',
                                      'innerNegMultSimplified',
                                      'innerNegMultSimplify')
Ejemplo n.º 6
0
        This works only if the operand x is an instance of the Add
        class at its outermost level, e.g. x = Add(a, b, …, n). The
        operands of that Add class can be other things, but the
        extraction is guaranteed to work only if the inner operands
        a, b, etc., are simple.
        '''
        from . import ceil_of_real_plus_int
        return apply_rounding_extraction(
            self, ceil_of_real_plus_int, idx_to_extract, assumptions)

    def deduce_in_number_set(self, number_set, assumptions=USE_DEFAULTS):
        '''
        Given a number set number_set, attempt to prove that the given
        Ceil expression is in that number set using the appropriate
        closure theorem.
        '''
        from proveit.numbers.rounding import ceil_is_an_int
        from proveit.numbers.rounding import ceil_real_pos_closure

        return rounding_deduce_in_number_set(
            self, number_set, ceil_is_an_int, ceil_real_pos_closure,
            assumptions)


# Register these generic expression equivalence methods:
InnerExpr.register_equivalence_method(
    Ceil, 'rounding_elimination', 'rounding_eliminated', 'rounding_eliminate')
InnerExpr.register_equivalence_method(
    Ceil, 'rounding_extraction', 'rounding_extracted', 'rounding_extract')
Ejemplo n.º 7
0
            if pull == 'left':
                w_etc_sub = factored_numer.operands[:-1]
                x_sub = factored_numer.operands[-1]
                z_etc_sub = []
            elif pull == 'right':
                w_etc_sub = []
                x_sub = factored_numer.operands[0]
                z_etc_sub = factored_numer.operands[1:]
            eqns.append(frac_in_prod_rev.instantiate({w_etc:w_etc_sub, x:x_sub, y:self.denominator, z_etc:z_etc_sub}))
            num = len(the_factor.operands) if isinstance(the_factor, Mult) else 1
            if group_factor and num > 1:
                if pull=='left':
                    eqns.append(eqns[-1].rhs.group(end_idx=num, assumptions=assumptions))
                elif pull=='right':
                    eqns.append(eqns[-1].rhs.group(start_idx=-num, assumptions=assumptions))
        return Equals(eqns[0].lhs, eqns[-1].rhs).prove(assumptions)
    """


def frac(numer, denom):
    return Div(numer, denom)


# Register these expression equivalence methods:
InnerExpr.register_equivalence_method(Div, 'deep_one_eliminations',
                                      'deep_eliminated_ones',
                                      'deep_eliminate_ones')
InnerExpr.register_equivalence_method(Div, 'exponent_combination',
                                      'combined_exponents',
                                      'combine_exponents')
Ejemplo n.º 8
0
            if idx == 0:
                return mult_neg_left_double.instantiate(
                    {a: mult_expr.operands[1]}, assumptions=assumptions)
            else:
                return mult_neg_right_double.instantiate(
                    {a: mult_expr.operands[0]}, assumptions=assumptions)
        _a = mult_expr.operands[:idx]
        _b = mult_expr.operands[idx]
        _c = mult_expr.operands[idx + 1:]
        _m = _a.num_elements(assumptions)
        _n = _c.num_elements(assumptions)
        return mult_neg_any_double.instantiate(
            {m: _m, n: _n, a: _a, b: _b, c: _c}, assumptions=assumptions)


# Register these expression equivalence methods:
InnerExpr.register_equivalence_method(
    Neg,
    'double_neg_simplification',
    'double_neg_simplified',
    'double_neg_simplify')
InnerExpr.register_equivalence_method(
    Neg, 'distribution', 'distributed', 'distribute')
InnerExpr.register_equivalence_method(
    Neg, 'factorization', 'factorized', 'factor')
InnerExpr.register_equivalence_method(
    Neg,
    'inner_neg_mult_simplification',
    'inner_neg_mult_simplified',
    'inner_neg_mult_simplify')
Ejemplo n.º 9
0
        if summand_lambda not in (lesser_lambda, greater_lambda):
            raise ValueError("Expecting summand_relation to be a universally "
                             "quantified number relation (< or <=) "
                             "involving the summand, %d, not %s" %
                             (self.summand, summand_relation))
        _a = lesser_lambda
        _b = greater_lambda
        _S = self.domain
        if isinstance(summand_relation.instance_expr, LessEq):
            # Use weak form
            sum_rel_impl = weak_summation_from_summands_bound.instantiate(
                {
                    a: _a,
                    b: _b,
                    S: _S
                }, assumptions=assumptions)
        else:
            # Use strong form
            sum_rel_impl = strong_summation_from_summands_bound.instantiate(
                {
                    a: _a,
                    b: _b,
                    S: _S
                }, assumptions=assumptions)
        sum_relation = sum_rel_impl.derive_consequent(assumptions)
        if summand_lambda == greater_lambda:
            return sum_relation.with_direction_reversed()
        return sum_relation

InnerExpr.register_equivalence_method(Sum, 'factorization', 'factorized',
                                      'factor')
Ejemplo n.º 10
0
        This works only if the operand x is an instance of the Add
        class at its outermost level, e.g. x = Add(a, b, …, n). The
        operands of that Add class can be other things, but the
        extraction is guaranteed to work only if the inner operands
        a, b, etc., are simple.
        '''
        from ._theorems_ import roundOfRealPlusInt
        return apply_roundingExtraction(self, roundOfRealPlusInt,
                                        idx_to_extract, assumptions)

    def deduceInNumberSet(self, number_set, assumptions=USE_DEFAULTS):
        '''
        Given a number set number_set, attempt to prove that the given
        Round expression is in that number set using the appropriate
        closure theorem.
        '''
        from proveit.number.rounding._axioms_ import roundIsAnInt
        from proveit.number.rounding._theorems_ import roundRealPosClosure

        return rounding_deduceInNumberSet(self, number_set, roundIsAnInt,
                                          roundRealPosClosure, assumptions)


# Register these generic expression equivalence methods:
InnerExpr.register_equivalence_method(Round, 'roundingElimination',
                                      'roundingEliminated',
                                      'roundingEliminate')
InnerExpr.register_equivalence_method(Round, 'roundingExtraction',
                                      'roundingExtracted', 'roundingExtract')
Ejemplo n.º 11
0
            raise IndexError("Index or indices out of bounds: {0}. "
                             "subset indices i should satisfy "
                             "0 ≤ i ≤ {1}.".format(unexpected_indices_set,
                                                   len(valid_indices_set) - 1))
        if len(subset_indices_list) > len(subset_indices_set):
            # we have repeated indices, so let's find them to use in
            # feedback/error message
            repeated_indices_set = set()
            for elem in subset_indices_set:
                if subset_indices_list.count(elem) > 1:
                    repeated_indices_set.add(elem)
            raise ValueError("The subset_indices specification contains "
                             "repeated indices, with repeated index or "
                             "indices: {}. Each index value should appear at "
                             "most 1 time.".format(repeated_indices_set))
        # if we made it this far and proper_subset = True,
        # confirm that the subset indices are compatible with a proper
        # subset instead of an improper subset
        if proper_subset and len(subset_indices_set) == len(valid_indices_set):
            raise ValueError("The subset indices are not compatible with a "
                             "proper subset (too many elements).")


# Register these expression equivalence methods:
InnerExpr.register_equivalence_method(Set, 'permutation', 'permuted',
                                      'permute')
InnerExpr.register_equivalence_method(Set, 'permutation_move', 'moved', 'move')
InnerExpr.register_equivalence_method(Set, 'permutation_swap', 'swapped',
                                      'swap')
InnerExpr.register_equivalence_method(Set, 'reduction', 'reduced', 'reduce')