예제 #1
0
    def conclude(self, assumptions):
        from proveit.logic import InSet, NotEquals
        from proveit.numbers import (Rational, RationalNonZero, RationalPos,
                                     RationalNeg, RationalNonNeg, Less,
                                     greater, greater_eq, zero)

        # If we known the element is in Q, we may be able to
        # prove that is in RationalNonZero, RationalPos, RationalNeg, or
        # RationalNonNeg if we know its relation to zero.
        if (self.number_set != Rational
                and InSet(self.element, Rational).proven(assumptions)):
            if self.number_set == RationalNonZero:
                if NotEquals(self.element, zero).proven(assumptions):
                    from . import non_zero_rational_is_rational_non_zero
                    return non_zero_rational_is_rational_non_zero.instantiate(
                        {q: self.element}, assumptions=assumptions)
            if self.number_set == RationalPos:
                if greater(self.element, zero).proven(assumptions):
                    from . import positive_rational_is_rational_pos
                    return positive_rational_is_rational_pos.instantiate(
                        {q: self.element}, assumptions=assumptions)
            if self.number_set == RationalNeg:
                if Less(self.element, zero).proven():
                    from . import negative_rational_is_rational_neg
                    return negative_rational_is_rational_neg.instantiate(
                        {q: self.element}, assumptions=assumptions)
            if self.number_set == RationalNonNeg:
                if greater_eq(self.element, zero).proven():
                    from . import non_neg_rational_in_rational_neg
                    return non_neg_rational_in_rational_neg.instantiate(
                        {q: self.element}, assumptions=assumptions)

        # Resort to the default NumberMembership.conclude strategies.
        return NumberMembership.conclude(self, assumptions)
예제 #2
0
 def conclude(self, **defaults_config):
     from proveit.logic import NotEquals, InSet
     from proveit.numbers import zero
     if (InSet(self.element, Complex).proven()
             and NotEquals(self.element, zero).proven()):
         return self.conclude_as_last_resort()
     return NumberMembership.conclude(self)
예제 #3
0
 def not_equal(self, rhs, assumptions=USE_DEFAULTS):
     # accessed from conclude() method in not_equals.py
     from . import abs_not_eq_zero
     from proveit.logic import NotEquals
     from proveit.numbers import zero
     if rhs == zero:
         return abs_not_eq_zero.instantiate({a: self.operand},
                                            assumptions=assumptions)
     raise NotEquals(self, zero).conclude_as_folded(assumptions)
예제 #4
0
 def not_equal(self, other, **defaults_config):
     '''
     Attempt to prove that self is not equal to other.
     '''
     from proveit.logic import NotEquals
     from proveit.numbers import zero
     if other == zero:
         return self.deduce_not_zero()
     # If it isn't a special case treated here, just use
     # conclude-as-folded.
     return NotEquals(self, other).conclude_as_folded()
예제 #5
0
 def exp_factorization(self, exp_factor, **defaults_config):
     '''
     Pull out one of the exponent factors to an exponent at
     another level.  For example,
         a^{b*n} = (a^b)^n
         a^{-b*n} = (a^{-b})^n
     '''
     # Note: this is out-of-date.  Distribution handles this now,
     # except it doesn't deal with the negation part
     # (do we need it to?)
     from proveit.numbers import deduce_in_number_set, Neg
     # from .theorems import int_exp_of_exp, int_exp_of_neg_exp
     from . import int_exp_of_exp, int_exp_of_neg_exp
     if isinstance(self.exponent, Neg):
         b_times_c = self.exponent.operand
         thm = int_exp_of_neg_exp
     else:
         b_times_c = self.exponent
         thm = int_exp_of_exp
     # if not hasattr(b_times_c, 'factor'):
     #     raise ValueError('Exponent not factorable, may not raise the '
     #                      'exponent factor.')
     # factor_eq = b_times_c.factor(exp_factor, pull='right',
     #                              group_remainder=True,
     #                              assumptions=assumptions)
     if not hasattr(b_times_c, 'factorization'):
         raise ValueError('Exponent {0} not factorable (for example, it '
                          'does not appear to be in the Mult class); may '
                          'not raise the exponent factor.'.
                          format(b_times_c))
     factor_eq = b_times_c.factorization(exp_factor, pull='right',
                                  group_remainder=True)
     if factor_eq.lhs != factor_eq.rhs:
         # factor the exponent first, then raise this exponent factor
         factored_exp_eq = factor_eq.substitution(self)
         return factored_exp_eq.apply_transitivity(
             factored_exp_eq.rhs.exp_factorization(exp_factor))
     n_sub = b_times_c.operands[1]
     a_sub = self.base
     b_sub = b_times_c.operands[0]
     # deduce_not_zero(a_sub, assumptions)
     NotEquals(a_sub, zero).prove()
     # deduce_in_integer(n_sub, assumptions)
     deduce_in_number_set(n_sub, Integer)
     # deduce_in_complex([a_sub, b_sub], assumptions)
     deduce_in_number_set(a_sub, Complex)
     deduce_in_number_set(b_sub, Complex)
     return thm.instantiate({n: n_sub}).instantiate(
         {a: a_sub, b: b_sub}).derive_reversed()
예제 #6
0
    def eliminate_common_factor(self, assumptions=USE_DEFAULTS):
        '''
        From self of the form (k a)|(k b), derive and return a|b.
        k must be a non-zero complex number. This method
        is called from the DividesRelation side_effects() method.
        Need to generalize this later for more than two operands on
        each side! Could use sets for detecting common factors.
        '''
        if (isinstance(self.lhs, Mult) and isinstance(self.rhs, Mult)):

            if (self.lhs.operands.is_double()
                    and self.rhs.operands.is_double()):

                lhs1 = self.lhs.operands[0]
                lhs2 = self.lhs.operands[1]
                rhs1 = self.rhs.operands[0]
                rhs2 = self.rhs.operands[1]

                if (lhs1 == rhs1 and InSet(lhs1, Complex).proven()
                        and NotEquals(lhs1, zero).proven()):

                    from . import common_factor_elimination
                    from proveit import a, b, k
                    return common_factor_elimination.instantiate(
                        {
                            a: lhs2,
                            b: rhs2,
                            k: lhs1
                        }, assumptions=assumptions)

                else:
                    err_msg = ("Error!")

            else:
                err_msg = ("In using Divides.eliminate_common_factor(), "
                           "each product can have only two multiplicands.")
        else:
            err_msg = ("In using Divides.eliminate_common_factor(), "
                       "the lhs {0} and rhs {1} must both be products.".format(
                           self.lhs, self.rhs))

        raise ValueError(err_msg)
예제 #7
0
    def conclude(self, assumptions):
        '''
        Try to automatically conclude this implication by reducing its
        operands to true/false, or by doing a "transitivity" search
        amongst known true implications whose assumptions are covered by
        the given assumptions.
        '''
        from . import (
            true_implies_true, false_implies_true, false_implies_false,
            false_antecedent_implication, falsified_antecedent_implication,
            untrue_antecedent_implication)
        from proveit.logic import TRUE, FALSE, NotEquals, EvaluationError
        if self.antecedent == self.consequent:
            return self.conclude_self_implication()

        if self in {
                true_implies_true,
                false_implies_true,
                false_implies_false}:
            # should be proven via one of the imported theorems as a simple
            # special case
            try:
                return self.evaluation(assumptions)
            except BaseException:
                return self.prove()

        if self.antecedent == FALSE:
            # The antecedent is FALSE, so we should try to prove the
            # implication via false_antecedent_implication.
            return false_antecedent_implication.instantiate(
                {A: self.consequent}, assumptions=assumptions)
        elif NotEquals(self.antecedent, TRUE).proven(assumptions):
            # The antecedent is known to be not equal to true, so
            # prove the implication via untrue_antecedent_implication.
            return untrue_antecedent_implication.instantiate(
                {A: self.antecedent, B: self.consequent},
                assumptions=assumptions)
        elif (self.antecedent.disproven(assumptions) or
              self.consequent.disproven(assumptions)):
            # Either the consequent or the antecedent has been disproven
            # so we should try to prove the implication via
            # falsified_antecedent_implication.
            return falsified_antecedent_implication.instantiate(
                {A: self.antecedent, B: self.consequent},
                assumptions=assumptions)
        elif self.consequent.proven(assumptions):
            # The consequent is proven, so we can prove the implication
            # via Deduction.
            return self.consequent.prove(assumptions).as_implication(
                self.antecedent)

        try:
            antecedent_eval = self.antecedent.evaluated(assumptions)
            if antecedent_eval == FALSE:
                # try again with the antecedent disproven
                return self.conclude(assumptions)
        except (EvaluationError, ProofFailure):
            pass

        try:
            consequent_eval = self.consequent.evaluated(assumptions)
            if consequent_eval in (FALSE, TRUE):
                # try again with the consequent proven or disproven.
                return self.conclude(assumptions)
        except (EvaluationError, ProofFailure):
            pass

        try:
            # try to prove the implication via deduction.
            return self.consequent.prove(
                tuple(assumptions) + (self.antecedent,)).as_implication(self.antecedent)
        except ProofFailure:
            raise ProofFailure(self, assumptions,
                               "Unable to automatically conclude by "
                               "standard means.  To try to prove this via "
                               "transitive implication relations, try "
                               "'conclude_via_transitivity'.")
예제 #8
0
    def eliminate_common_factors(self, **defaults_config):
        '''
        Eliminate all factors in common between the divisor and the
        dividend.  For example, from (k a)|(k b), derive and return a|b.
        k must be a non-zero complex number.
        '''
        from . import common_factor_elimination
        from proveit.numbers import Mult, one
        if self.lhs == self.rhs:
            # From x | x return 1 | 1.  It's vacuous, but whatever.
            return Divides(one, one).prove()
        elif (isinstance(self.lhs, Mult) and isinstance(self.rhs, Mult)):

            # Handle the basic case in which the divisor and
            # the dividend are each the product of two factors and
            # the first of these is in common between them.
            if (self.lhs.operands.is_double()
                    and self.rhs.operands.is_double()):
                lhs1 = self.lhs.operands[0]
                lhs2 = self.lhs.operands[1]
                rhs1 = self.rhs.operands[0]
                rhs2 = self.rhs.operands[1]
                deduce_number_set(lhs1)

                if (lhs1 == rhs1 and InSet(lhs1, Complex).proven()
                        and NotEquals(lhs1, zero).proven()):
                    return common_factor_elimination.instantiate({
                        a: lhs2,
                        b: rhs2,
                        k: lhs1
                    })

            # Try to convert it to the basic case via factorization
            # and try again.
            rhs_factors = set(self.rhs.operands.entries)
            common_factors = [
                factor for factor in self.lhs.factors if factor in rhs_factors
            ]
            # Pull the common factors out to the front.
            if len(common_factors) == 0:
                return self.prove()  # No common factors to eliminate.
            lhs_factorization = self.lhs.factorization(common_factors,
                                                       pull='left',
                                                       group_factors=True,
                                                       group_remainder=True,
                                                       preserve_all=True)
            rhs_factorization = self.rhs.factorization(common_factors,
                                                       pull='left',
                                                       group_factors=True,
                                                       group_remainder=True,
                                                       preserve_all=True)
            # Prove this "divides" but the substitute factorized forms.
            divides_proof = self.prove()
            if lhs_factorization.lhs != lhs_factorization.rhs:
                divides_proof = lhs_factorization.sub_right_side_into(
                    divides_proof)
            if rhs_factorization.lhs != rhs_factorization.rhs:
                divides_proof = rhs_factorization.sub_right_side_into(
                    divides_proof)
            lhs1, lhs2 = lhs_factorization.rhs.operands
            rhs1, rhs2 = rhs_factorization.rhs.operands
            return common_factor_elimination.instantiate({
                a: lhs2,
                b: rhs2,
                k: lhs1
            })
        elif isinstance(self.lhs, Mult) and self.rhs in self.lhs.factors:
            # From (k z) | k return z | 1.  Why not?
            dividend = Mult(self.rhs, one)
            divides = Divides(self.lhs, dividend)
            divides_proof = divides.eliminate_common_factors()
            return divides_proof.inner_expr().lhs.dividend.one_elimination(1)
        elif isinstance(self.rhs, Mult) and self.lhs in self.rhs.factors:
            # From (k z) | k return z | 1.  Why not?
            divisor = Mult(self.lhs, one)
            divides = Divides(divisor, self.rhs)
            divides_proof = divides.eliminate_common_factors()
            return divides_proof.inner_expr().lhs.divisor.one_elimination(1)

        # There are no common factors.
        return self.prove()
예제 #9
0
def deduceNotZero(exprOrList,
                  assumptions=frozenset(),
                  dontTryPos=False,
                  dontTryNeg=False):
    '''
    For each given expression, attempt to derive that it is not equal to zero
    under the given assumptions.  If successful, returns the deduced statement,
    otherwise raises an Exception.  
    '''
    from proveit.number import num
    import real.theorems
    if not isinstance(assumptions, set) and not isinstance(
            assumptions, frozenset):
        raise Exception('assumptions should be a set')
    if not isinstance(exprOrList, Expression) or isinstance(
            exprOrList, ExpressionList):
        # If it isn't an Expression, assume it's iterable and deduce each
        return [
            deduceNotZero(expr, assumptions=assumptions) for expr in exprOrList
        ]
    # A single Expression:
    expr = exprOrList
    try:
        # may be done before we started
        return NotEquals(expr, num(0)).checked(assumptions)
    except:
        pass  # not so simple

    if not dontTryPos:
        try:
            # see if we can deduce in positive first
            deducePositive(expr, assumptions)
            isPos = True
        except:
            isPos = False  # not so simple
        if isPos:
            deduceInReals(expr, assumptions)
            return real.theorems.positive_implies_notzero.specialize({
                a: expr
            }).checked(assumptions)

    if not dontTryNeg:
        try:
            # see if we can deduce in negative first
            deduceNegative(expr, assumptions)
            isNeg = True
        except:
            isNeg = False  # not so simple
        if isNeg:
            deduceInReals(expr, assumptions)
            return real.theorems.negative_implies_notzero.specialize({
                a: expr
            }).checked(assumptions)

    # Try using notEqZeroTheorem
    if not isinstance(expr, NumberOp):
        # See of the Expression class has deduceNotZero method (as a last resort):
        if hasattr(expr, 'deduceNotZero'):
            return expr.deduceNotZero()
        raise DeduceNotZeroException(expr, assumptions)
    notEqZeroThm = expr._notEqZeroTheorem()
    if notEqZeroThm is None:
        raise DeduceNotZeroException(expr, assumptions)
    assert isinstance(
        notEqZeroThm,
        Forall), 'Expecting notEqZero theorem to be a Forall expression'
    iVars = notEqZeroThm.instanceVars
    # Specialize the closure theorem differently for AccociativeOperation compared with other cases
    if isinstance(expr, AssociativeOperation):
        assert len(
            iVars
        ) == 1, 'Expecting one instance variables for the notEqZero theorem of an AssociativeOperation'
        assert isinstance(
            iVars[0], Etcetera
        ), 'Expecting the instance variable for the notEqZero theorem of an AssociativeOperation to be an Etcetera Variable'
        notEqZeroSpec = notEqZeroThm.specialize({iVars[0]: expr.operands})
    else:
        if len(iVars) != len(expr.operands):
            raise Exception(
                'Expecting the number of instance variables for the closure theorem to be the same as the number of operands of the Expression'
            )
        notEqZeroSpec = notEqZeroThm.specialize(
            {iVar: operand
             for iVar, operand in zip(iVars, expr.operands)})
    # deduce any of the requirements for the notEqZeroThm application
    _deduceRequirements(notEqZeroThm, notEqZeroSpec, assumptions)
    try:
        return NotEquals(expr, num(0)).checked(assumptions)
    except:
        raise DeduceNotZeroException(expr, assumptions)
예제 #10
0
greaterThanInBools = Forall([a, b],
                            InSet(GreaterThan(a, b), Booleans),
                            domain=Reals)
greaterThanInBools

greaterThanEqualsInBools = Forall([a, b],
                                  InSet(GreaterThanEquals(a, b), Booleans),
                                  domain=Reals)
greaterThanEqualsInBools

notEqualsIsLessThanOrGreaterThan = Forall((a, x),
                                          Or(LessThan(x, a), GreaterThan(x,
                                                                         a)),
                                          domain=Reals,
                                          conditions=[NotEquals(x, a)])
notEqualsIsLessThanOrGreaterThan

shiftLessThanToLessThanEquals = Forall((a, b),
                                       LessThanEquals(a, b),
                                       domain=Integers,
                                       conditions=[LessThan(Sub(a, one), b)])
shiftLessThanToLessThanEquals

lessThanEqualsAddRight = Forall([a, b, c],
                                LessThanEquals(Add(a, c), Add(b, c)),
                                domain=Reals,
                                conditions=[LessThanEquals(a, b)])
lessThanEqualsAddRight

lessThanEqualsAddLeft = Forall([a, b, c],
예제 #11
0
from proveit import Etcetera
from proveit.logic import Forall, InSet, Equals, NotEquals, Implies
from proveit.numbers import Integer, NaturalPos, Real, RealPos, Complex
from proveit.numbers import Divide, frac, Add, Sub, Sum, Mult, Exp
from proveit.common import a, b, c, n, w, x, y, z, P, S, x_multi, w_etc, x_etc, y_etc, z_etc, Py_etc
from proveit.numbers.common import zero, one, ComplexSansZero
from proveit import begin_theorems, end_theorems

begin_theorems(locals())

divide_real_closure = Forall([a, b],
                             InSet(Divide(a, b), Real),
                             domain=Real,
                             conditions=[NotEquals(b, zero)])
divide_real_closure

divide_real_pos_closure = Forall([a, b],
                                 InSet(Divide(a, b), RealPos),
                                 domain=RealPos,
                                 conditions=[NotEquals(b, zero)])
divide_real_pos_closure

fraction_real_closure = Forall([a, b],
                               InSet(frac(a, b), Real),
                               domain=Real,
                               conditions=[NotEquals(b, zero)])
fraction_real_closure

fraction_pos_closure = Forall([a, b],
                              InSet(frac(a, b), RealPos),
                              domain=RealPos,
예제 #12
0
from proveit.logic import Forall, Exists, NotExists, Booleans, TRUE, FALSE, inBool, Not, And, Or, Implies, Iff, Equals, NotEquals
from proveit.common import A, B, C, P, Q, R, S, x, y, PofA, Qetc, Retc, xEtc, yEtc, zEtc, PxEtc, PyEtc, PxyEtc, etc_QxEtc, etc_QyEtc, etc_RyEtc
from proveit.logic.common import PofTrue, PofFalse
from proveit import beginTheorems, endTheorems

beginTheorems(locals())

trueEqTrue = Equals(TRUE, TRUE)

trueEqTrueEval = Equals(Equals(TRUE, TRUE), TRUE)

falseEqFalse = Equals(FALSE, FALSE)

falseEqFalseEval = Equals(Equals(FALSE, FALSE), TRUE)

trueNotFalse = NotEquals(TRUE, FALSE)

notEqualsFalse = Forall(A, NotEquals(A, FALSE), conditions=[A])

trueEqFalseEval = Equals(Equals(TRUE, FALSE), FALSE)

falseEqTrueEval = Equals(Equals(FALSE, TRUE), FALSE)

trueConclusion = Forall(A, Implies(A, TRUE))

inBoolEquiv = Forall(A, Equals(inBool(A), Or(Equals(A, TRUE), Equals(A,
                                                                     FALSE))))

trueInBool = inBool(TRUE)

falseInBool = inBool(FALSE)
예제 #13
0
from proveit import Etcetera
from proveit.logic import Forall, InSet, Equals, NotEquals
from proveit.number import Integers, Naturals, NaturalsPos, Reals, RealsPos, Complexes
from proveit.number import Exp, sqrt, Add, Mult, Sub, Neg, frac, Abs, GreaterThan, GreaterThanEquals, LessThan, LessThanEquals
from proveit.common import a, b, c, d, n, x, y, z, xEtc, xMulti
from proveit.number.common import zero, one, two
from proveit import beginTheorems, endTheorems

beginTheorems(locals())

expNatClosure = Forall((a, b), InSet(Exp(a, b), NaturalsPos), domain=Naturals, conditions=[NotEquals(a, zero)])
expNatClosure

expRealClosure = Forall([a, b], InSet(Exp(a, b), Reals), domain=Reals,
                       conditions=[GreaterThanEquals(a, zero), GreaterThan(b, zero)])
expRealClosure

expRealPosClosure = Forall([a, b], InSet(Exp(a, b), RealsPos), domain=Reals,
                       conditions=[GreaterThan(a, zero)])
expRealPosClosure

expComplexClosure = Forall([a, b], InSet(Exp(a, b), Complexes), domain=Complexes, 
                    conditions=[NotEquals(a, zero)])
expComplexClosure

sqrtRealClosure = Forall([a], InSet(sqrt(a), Reals), domain=Reals,
                         conditions=[GreaterThanEquals(a, zero)])
sqrtRealClosure

sqrtRealPosClosure = Forall([a], InSet(sqrt(a), RealsPos), domain=RealsPos)
sqrtRealPosClosure
예제 #14
0
 def conclude(self, **defaults_config):
     from proveit.numbers import Rational, zero
     if (InSet(self.element, Rational).proven() and
             NotEquals(self.element, zero).proven()):
         return self.conclude_as_last_resort()
     return NumberMembership.conclude(self)
예제 #15
0
    def deduce_equal_or_not(self, other_tuple, **defaults_config):
        '''
        Prove and return that this ExprTuple is either equal or
        not equal to other_tuple or raises an UnsatisfiedPrerequisites
        or NotImplementedError if we cannot readily prove either of
        these.
        '''
        from proveit import (ExprRange, safe_dummy_var,
                             UnsatisfiedPrerequisites)
        from proveit.logic import (
                And, Or, Equals, NotEquals, deduce_equal_or_not)
        if self == other_tuple:
            return Equals(self, other_tuple).conclude_via_reflexivity
        if not isinstance(other_tuple, ExprTuple):
            raise TypeError("Expecting 'other_tuple' to be an ExprTuple "
                            "not a %s"%other_tuple.__class__)
        _i = self.num_elements()
        _j = other_tuple.num_elements()
        size_relation = deduce_equal_or_not(_i, _j)
        if isinstance(size_relation.expr, NotEquals):
            # Not equal because the lengths are different.
            return self.not_equal(other_tuple)
        
        def raise_non_corresponding():
            raise NotImplementedError(
                    "ExprTuple.deduce_equal_or_not is only "
                    "implemented for the case when ExprRanges "
                    "match up: %s vs %s"%self, other_tuple)
            
        if self.num_entries() == other_tuple.num_entries():
            if self.num_entries()==1 and self.contains_range():
                if not other_tuple.contains_range():
                    # One ExprTuple has a range but the other doesn't.
                    # That case isn't handled.
                    raise_non_corresponding()
                lhs_range = self.entries[0]
                rhs_range = other_tuple.entries[0]
                start_index = lhs_range.start_index
                end_index = lhs_range.end_index
                if ((start_index != rhs_range.start_index) or
                        (end_index != rhs_range.end_index)):
                    # Indices must match for a proper correspondence.
                    raise_non_corresponding()
                if lhs_range.parameter != rhs_range.parameter:
                    # Use a safe common parameter.
                    param = safe_dummy_var(lhs_range.body, rhs_range.body)
                    lhs_range_body = lhs_range.body.basic_replaced(
                            {lhs_range.parameter: param})
                    rhs_range_body = rhs_range.body.basic_replaced(
                            {rhs_range.parameter: param})
                else:
                    param = lhs_range.parameter
                    lhs_range_body = lhs_range.body
                    rhs_range_body = rhs_range.body
                inner_assumptions = defaults.assumptions + (
                        lhs_range.parameter_condition(),)
                try:
                    body_relation = deduce_equal_or_not(
                            lhs_range_body, rhs_range_body,
                            assumptions=inner_assumptions)
                    if isinstance(body_relation, Equals):
                        # Every element is equal, so the ExprTuples 
                        # are equal.
                        return self.deduce_equality(
                                Equals(self, other_tuple))
                    else:
                        # Every element is not equal, so the ExprTuples 
                        # are not equal.
                        # This will enable "any" from "all".
                        And(ExprRange(
                                param, NotEquals(lhs_range_body,
                                                 rhs_range_body),
                                start_index, end_index)).prove()
                        return self.not_equal(other_tuple)
                except (NotImplementedError, UnsatisfiedPrerequisites):
                    pass
                if And(ExprRange(param, Equals(lhs_range_body, 
                                               rhs_range_body),
                                 start_index, end_index)).proven():
                    # Every element is equal, so the ExprTuples 
                    # are equal.
                    return self.deduce_equality(
                            Equals(self, other_tuple))
                elif Or(ExprRange(param, NotEquals(lhs_range_body,
                                                   rhs_range_body),
                        start_index, end_index)).proven():
                    # Some element pair is not equal, so the ExprTuples 
                    # are not equal.
                    return self.not_equal(other_tuple)
                raise UnsatisfiedPrerequisites(
                        "Could not determine whether %s = %s"
                        %(self, other_tuple))
            
            # Loop through each entry pair in correspondence and
            # see if we can readily prove whether or not they are
            # all equal.
            for idx, (_x, _y) in enumerate(
                    zip(self.entries, other_tuple.entries)):
                if isinstance(_x, ExprRange) != isinstance(_y, ExprRange):
                    raise_non_corresponding()
                if _x == _y:
                    # The expressions are the same, so we know they
                    # are equal.
                    continue
                if isinstance(_x, ExprRange):
                    # Wrap ExprRanges in ExprTuples and compare as
                    # single entry tuples.
                    _x = ExprTuple(_x)
                    _y = ExprTuple(_y)
                    _k = _x.num_elements()
                    _l = _y.num_elements()
                    size_relation = deduce_equal_or_not(_k, _l)
                    if isinstance(size_relation.expr, NotEquals):
                        # Not implemented when the ExprRanges don't
                        # correspond in size.
                        raise_non_corresponding()
                    relation = deduce_equal_or_not(_x, _y)
                else:
                    # Compare singular entries.
                    relation = deduce_equal_or_not(_x, _y)
                if isinstance(relation.expr, NotEquals):
                    # Aha! They are not equal.
                    return self.not_equal(other_tuple)
            # They are equal!
            return self.deduce_equality(Equals(self, other_tuple))

        raise NotImplementedError(
                    "ExprTuple.deduce_equal_or_not is not implemented "
                    "for ExprTuples that have a different number of "
                    "elements.")
예제 #16
0
negComplexClosure

negatedPositiveIsNegative = Forall(a,
                                   LessThan(Neg(a), zero),
                                   domain=Reals,
                                   conditions=[GreaterThan(a, zero)])
negatedPositiveIsNegative

negatedNegativeIsPositive = Forall(a,
                                   GreaterThan(Neg(a), zero),
                                   domain=Reals,
                                   conditions=[LessThan(a, zero)])
negatedNegativeIsPositive

negNotEqZero = Forall(a,
                      NotEquals(Neg(a), zero),
                      domain=Complexes,
                      conditions=[NotEquals(a, zero)])
negNotEqZero

distributeNegThroughSum = Forall([xEtc],
                                 Equals(Neg(Add(xEtc)),
                                        Add(Etcetera(Neg(xMulti)))),
                                 domain=Complexes)
distributeNegThroughSum

distributeNegThroughSumRev = Forall([xEtc],
                                    Equals(Add(Etcetera(Neg(xMulti))),
                                           Neg(Add(xEtc))),
                                    domain=Complexes)
distributeNegThroughSumRev
예제 #17
0
fiveInNaturals = InSet(five,Naturals)
fiveInNaturals

sixInNaturals = InSet(six,Naturals)
sixInNaturals

sevenInNaturals = InSet(seven,Naturals)
sevenInNaturals

eightInNaturals = InSet(eight,Naturals)
eightInNaturals

nineInNaturals = InSet(nine,Naturals)
nineInNaturals

oneNotZero = NotEquals(one, zero)
oneNotZero

twoNotZero = NotEquals(two, zero)
twoNotZero

threeNotZero = NotEquals(three, zero)
threeNotZero

fourNotZero = NotEquals(four, zero)
fourNotZero

fiveNotZero = NotEquals(five, zero)
fiveNotZero

sixNotZero = NotEquals(six, zero)
예제 #18
0
inRealsNeg_inReals = Forall(a, InSet(a,Reals), domain = RealsNeg)
inRealsNeg_inReals

inRealsPos_inComplexes = Forall(a, InSet(a,Complexes), domain = RealsPos)
inRealsPos_inComplexes

inRealsNeg_inComplexes = Forall(a, InSet(a,Complexes), domain = RealsNeg)
inRealsNeg_inComplexes

inRealsPos_iff_positive = Forall(a, Iff(InSet(a, RealsPos), GreaterThan(a, zero)), domain=Reals)
inRealsPos_iff_positive

inRealsNeg_iff_negative = Forall(a, Iff(InSet(a, RealsNeg), LessThan(a, zero)), domain=Reals)
inRealsNeg_iff_negative

positive_implies_notZero = Forall(a, NotEquals(a, zero), domain=Reals, conditions=[GreaterThan(a, zero)])
positive_implies_notZero

negative_implies_notZero = Forall(a, NotEquals(a, zero), domain=Reals, conditions=[LessThan(a, zero)])
negative_implies_notZero

allInIntervalOO_InReals = Forall((a, b), Forall(x, InSet(x, Reals), domain=IntervalOO(a, b)), domain=Reals)
allInIntervalOO_InReals 

allInIntervalCO_InReals = Forall((a, b), Forall(x, InSet(x, Reals), domain=IntervalCO(a, b)), domain=Reals)
allInIntervalCO_InReals 

allInIntervalOC_InReals = Forall((a, b), Forall(x, InSet(x, Reals), domain=IntervalOC(a, b)), domain=Reals)
allInIntervalOC_InReals 

allInIntervalCC_InReals = Forall((a, b), Forall(x, InSet(x, Reals), domain=IntervalCC(a, b)), domain=Reals)
예제 #19
0
def deduce_number_set(expr, **defaults_config):
    '''
    Prove that 'expr' is an Expression that represents a number
    in a standard number set that is as restrictive as we can
    readily know.
    '''
    from proveit.logic import And, InSet, Equals, NotEquals
    from proveit.numbers import Less, LessEq, zero

    # Find the first (most restrictive) number set that
    # contains 'expr' or something equal to it.

    for number_set in sorted_number_sets:
        membership = None
        for eq_expr in Equals.yield_known_equal_expressions(expr):
            if isinstance(eq_expr, ExprRange):
                membership = And(
                    ExprRange(eq_expr.parameter,
                              InSet(eq_expr.body, number_set),
                              eq_expr.true_start_index,
                              eq_expr.true_end_index,
                              styles=eq_expr.get_styles()))
            else:
                membership = InSet(eq_expr, number_set)
            if membership.proven():
                break  # found a known number set membership
            else:
                membership = None
        if membership is not None:
            membership = InSet(expr, number_set).prove()
            break

    if hasattr(expr, 'deduce_number_set'):
        # Use 'deduce_number_set' method.
        try:
            deduced_membership = expr.deduce_number_set()
        except (UnsatisfiedPrerequisites, ProofFailure):
            deduced_membership = None
        if deduced_membership is not None:
            assert isinstance(deduced_membership, Judgment)
            if not isinstance(deduced_membership.expr, InSet):
                raise TypeError("'deduce_number_set' expected to prove an "
                                "InSet type expression")
            if deduced_membership.expr.element != expr:
                raise TypeError("'deduce_number_set' was expected to prove "
                                "that %s is in some number set" % expr)
            # See if this deduced number set is more restrictive than
            # what we had surmised already.
            deduced_number_set = deduced_membership.domain
            if membership is None:
                membership = deduced_membership
                number_set = deduced_number_set
            elif (deduced_number_set != number_set
                  and number_set.includes(deduced_number_set)):
                number_set = deduced_number_set
                membership = deduced_membership

    if membership is None:
        from proveit import defaults
        raise UnsatisfiedPrerequisites(
            "Unable to prove any number membership for %s" % expr)

    # Already proven to be in some number set,
    # Let's see if we can restrict it further.
    if Less(zero, expr).proven():  # positive
        number_set = pos_number_set.get(number_set, None)
    elif Less(expr, zero).proven():  # negative
        number_set = neg_number_set.get(number_set, None)
    elif LessEq(zero, expr).proven():  # non-negative
        number_set = nonneg_number_set.get(number_set, None)
    elif LessEq(expr, zero).proven():  # non-positive
        number_set = nonpos_number_set.get(number_set, None)
    elif NotEquals(expr, zero).proven():
        number_set = nonzero_number_set.get(number_set, None)
    if number_set is None:
        # Just use what we have already proven.
        return membership.prove()
    return InSet(expr, number_set).prove()
예제 #20
0
mod_abs_real_closure

# transferred by wdc 3/11/2020
abs_complex_closure = Forall([a], InSet(Abs(a), Real), domain=Complex)
abs_complex_closure

# transferred by wdc 3/11/2020
abs_nonzero_closure = Forall(
    [a],
    InSet(
        Abs(a),
        RealPos),
    domain=Complex,
    conditions=[
        NotEquals(
            a,
            zero)])
abs_nonzero_closure

# transferred by wdc 3/11/2020
mod_in_interval_c_o = Forall((a, b), InSet(
    Mod(a, b), IntervalCO(zero, b)), domain=Real)
mod_in_interval_c_o

# transferred by wdc 3/11/2020
abs_is_non_neg = Forall(a, GreaterThanEquals(Abs(a), zero), domain=Complex)
abs_is_non_neg

# transferred by wdc 3/11/2020
abs_not_eq_zero = Forall(
    [a],
예제 #21
0
from proveit.logic import Forall, Exists, NotExists, Boolean, TRUE, FALSE, in_bool, Not, And, Or, Implies, Iff, Equals, NotEquals
from proveit.common import A, B, C, P, Q, R, S, x, y, PofA, Qetc, Retc, x_etc, y_etc, z_etc, Px_etc, Py_etc, Pxy_etc, etc_Qx_etc, etc_Qy_etc, etc_Ry_etc
from proveit.logic.common import PofTrue, PofFalse
from proveit import begin_theorems, end_theorems

begin_theorems(locals())

true_eq_true = Equals(TRUE, TRUE)

true_eq_true_eval = Equals(Equals(TRUE, TRUE), TRUE)

false_eq_false = Equals(FALSE, FALSE)

false_eq_false_eval = Equals(Equals(FALSE, FALSE), TRUE)

true_not_false = NotEquals(TRUE, FALSE)

not_equals_false = Forall(A, NotEquals(A, FALSE), conditions=[A])

true_eq_false_eval = Equals(Equals(TRUE, FALSE), FALSE)

false_eq_true_eval = Equals(Equals(FALSE, TRUE), FALSE)

true_conclusion = Forall(A, Implies(A, TRUE))

in_bool_equiv = Forall(
    A, Equals(in_bool(A), Or(Equals(A, TRUE), Equals(A, FALSE))))

true_is_bool = in_bool(TRUE)

false_is_bool = in_bool(FALSE)
예제 #22
0
from proveit.logic import Forall, InSet, NotEquals
from proveit.number import Complexes
from proveit.common import a
from proveit.number.common import zero, i, ComplexesSansZero
from proveit import beginTheorems, endTheorems

beginTheorems(locals())

iInComplexes = InSet(i, Complexes)
iInComplexes

iNotZero = NotEquals(i, zero)
iNotZero

inComplexesSansZero = Forall(a,
                             InSet(a, ComplexesSansZero),
                             domain=Complexes,
                             conditions=[NotEquals(a, zero)])
inComplexesSansZero

endTheorems(locals(), __package__)
예제 #23
0
from proveit import Etcetera
from proveit.logic import Forall, InSet, Equals, NotEquals
from proveit.numbers import Integer, Natural, NaturalPos, Real, RealPos, Complex
from proveit.numbers import Exp, sqrt, Add, Mult, Sub, Neg, frac, Abs, GreaterThan, GreaterThanEquals, LessThan, LessThanEquals
from proveit.common import a, b, c, d, n, x, y, z, x_etc, x_multi
from proveit.numbers.common import zero, one, two
from proveit import begin_theorems, end_theorems

begin_theorems(locals())

exp_nat_closure = Forall((a, b),
                         InSet(Exp(a, b), NaturalPos),
                         domain=Natural,
                         conditions=[NotEquals(a, zero)])
exp_nat_closure

exp_real_closure = Forall(
    [a, b],
    InSet(Exp(a, b), Real),
    domain=Real,
    conditions=[GreaterThanEquals(a, zero),
                GreaterThan(b, zero)])
exp_real_closure

exp_real_pos_closure = Forall([a, b],
                              InSet(Exp(a, b), RealPos),
                              domain=Real,
                              conditions=[GreaterThan(a, zero)])
exp_real_pos_closure

exp_complex_closure = Forall([a, b],
예제 #24
0
    def shallow_simplification(self,
                               *,
                               must_evaluate=False,
                               **defaults_config):
        '''
        Returns a proven simplification equation for this Divide
        expression assuming the operands have been simplified.

        Specifically, cancels common factors and eliminates ones.
        '''
        from proveit.logic import is_irreducible_value
        from proveit.numbers import one, Neg
        expr = self
        # for convenience updating our equation
        eq = TransRelUpdater(expr)

        # perform cancelations where possible
        expr = eq.update(expr.cancelations(preserve_all=True))
        if not isinstance(expr, Div):
            # complete cancelation.
            return eq.relation

        if self.is_irreducible_value():
            # already irreducible
            return Equals(self, self).conclude_via_reflexivity()

        if must_evaluate and not all(
                is_irreducible_value(operand) for operand in self.operands):
            for operand in self.operands:
                if not is_irreducible_value(operand):
                    # The simplification of the operands may not have
                    # worked hard enough.  Let's work harder if we
                    # must evaluate.
                    operand.evaluation()
            return self.evaluation()

        if expr.denominator == one:
            # eliminate division by one
            expr = eq.update(expr.divide_by_one_elimination(preserve_all=True))

        if (isinstance(expr, Div)
                and Div._simplification_directives_.factor_negation
                and isinstance(expr.numerator, Neg)):
            # we have something like (-a)/b but want -(a/b)
            expr = eq.update(expr.neg_extraction())
            # return eq.relation  # no more division simplifications.

        if (Div._simplification_directives_.reduce_zero_numerator
                and isinstance(expr, Div)):
            if ((expr.numerator == zero
                 or Equals(expr.numerator, zero).proven())
                    and NotEquals(expr.denominator, zero).proven()):
                # we have something like 0/x so reduce to 0
                expr = eq.update(expr.zero_numerator_reduction())

        # finally, check if we have something like (x/(y/z))
        # but! remember to check here if we still even have a Div expr
        # b/c some of the work above might have changed it to
        # something else!
        if (isinstance(expr, Div) and isinstance(expr.denominator, Div)
                and NotEquals(expr.denominator.numerator, zero).proven()
                and NotEquals(expr.denominator.denominator, zero).prove()):
            expr = eq.update(expr.div_in_denominator_reduction())

        return eq.relation
예제 #25
0
                       domain=Integers)
modInInterval

modRealClosure = Forall((a, b), InSet(Mod(a, b), Reals), domain=Reals)
modRealClosure

modAbsRealClosure = Forall((a, b), InSet(ModAbs(a, b), Reals), domain=Reals)
modAbsRealClosure

absComplexClosure = Forall([a], InSet(Abs(a), Reals), domain=Complexes)
absComplexClosure

absNonzeroClosure = Forall([a],
                           InSet(Abs(a), RealsPos),
                           domain=Complexes,
                           conditions=[NotEquals(a, zero)])
absNonzeroClosure

modInIntervalCO = Forall((a, b),
                         InSet(Mod(a, b), IntervalCO(zero, b)),
                         domain=Reals)
modInIntervalCO

absIsNonNeg = Forall(a, GreaterThanEquals(Abs(a), zero), domain=Complexes)
absIsNonNeg

absNotEqZero = Forall([a],
                      NotEquals(Abs(a), zero),
                      domain=Complexes,
                      conditions=[NotEquals(a, zero)])
absNotEqZero
예제 #26
0
mult_real_closure = Forall([x_etc], InSet(Mult(x_etc), Real), domain=Real)
mult_real_closure

mult_real_pos_closure = Forall([x_etc],
                               InSet(Mult(x_etc), RealPos),
                               domain=RealPos)
mult_real_pos_closure

mult_complex_closure = Forall([x_etc],
                              InSet(Mult(x_etc), Complex),
                              domain=Complex)
mult_complex_closure

mult_not_eq_zero = Forall([x_etc],
                          NotEquals(Mult(x_etc), zero),
                          domain=ComplexSansZero)
mult_not_eq_zero

mult_one = Forall(x, Equals(Mult(one, x), x), domain=Complex)
mult_one

mult_zero = Forall(x, Equals(Mult(zero, x), zero), domain=Complex)
mult_zero

mult_comm = Forall([v_etc, w_etc, x_etc, y_etc, z_etc],
                   Equals(Mult(v_etc, w_etc, x_etc, y_etc, z_etc),
                          Mult(v_etc, y_etc, x_etc, w_etc, z_etc)),
                   domain=Complex)
mult_comm
예제 #27
0
five_in_natural = InSet(five, Natural)
five_in_natural

six_in_natural = InSet(six, Natural)
six_in_natural

seven_in_natural = InSet(seven, Natural)
seven_in_natural

eight_in_natural = InSet(eight, Natural)
eight_in_natural

nine_in_natural = InSet(nine, Natural)
nine_in_natural

one_not_zero = NotEquals(one, zero)
one_not_zero

two_not_zero = NotEquals(two, zero)
two_not_zero

three_not_zero = NotEquals(three, zero)
three_not_zero

four_not_zero = NotEquals(four, zero)
four_not_zero

five_not_zero = NotEquals(five, zero)
five_not_zero

six_not_zero = NotEquals(six, zero)
예제 #28
0
multRealClosure = Forall([xEtc], InSet(Mult(xEtc), Reals), domain=Reals)
multRealClosure

multRealPosClosure = Forall([xEtc],
                            InSet(Mult(xEtc), RealsPos),
                            domain=RealsPos)
multRealPosClosure

multComplexClosure = Forall([xEtc],
                            InSet(Mult(xEtc), Complexes),
                            domain=Complexes)
multComplexClosure

multNotEqZero = Forall([xEtc],
                       NotEquals(Mult(xEtc), zero),
                       domain=ComplexesSansZero)
multNotEqZero

multOne = Forall(x, Equals(Mult(one, x), x), domain=Complexes)
multOne

multZero = Forall(x, Equals(Mult(zero, x), zero), domain=Complexes)
multZero

multComm = Forall([vEtc, wEtc, xEtc, yEtc, zEtc],
                  Equals(Mult(vEtc, wEtc, xEtc, yEtc, zEtc),
                         Mult(vEtc, yEtc, xEtc, wEtc, zEtc)),
                  domain=Complexes)
multComm
예제 #29
0
 def conclude(self, **defaults_config):
     if (InSet(self.element, Integer).proven()
             and NotEquals(self.element, zero).proven()):
         return self.conclude_as_last_resort()
     return NumberMembership.conclude(self)
예제 #30
0
    def conclude(self, **defaults_config):
        '''
        Attempt to conclude the divisibility claim in various ways:
        (1) simple reflexivity (x|x);
        (2) simple x|0 for x ≠ 0;
        (3) simple x|xy or x|yx scenario
        (4) x^n | y^n if x|y is known or assumed
        (5) x|y if (x^n)|(y^n) is known or assumed
        (6) via transitivity.
        '''
        from proveit.numbers import Exp

        #-- -------------------------------------------------------- --#
        #-- Case (1): x|x with x != 0 known or assumed               --#
        #-- -------------------------------------------------------- --#
        from proveit.logic import InSet, NotEquals
        from proveit.numbers import zero, Complex
        err_str = "In Divides.conclude() we tried:\n"
        try:
            deduce_number_set(self.lhs)
        except UnsatisfiedPrerequisites:
            pass
        if self.lhs == self.rhs:
            if (NotEquals(self.lhs, zero).proven()
                    and InSet(self.lhs, Complex).proven()):
                # Trivial x|x with complex x ≠ 0
                return self.conclude_via_reflexivity()
            else:
                err_str = err_str + (
                    "Case: lhs = rhs. "
                    "Although lhs = rhs = {0}, either {0} is not known to "
                    "be non-zero or {0} is not known to be in the complex "
                    "numbers (or both). Try proving one or both of those "
                    "claims first.\n".format(self.lhs))
                # raise ProofFailure(self, assumptions, err_str)

        #-- -------------------------------------------------------- --#
        #-- Case (2): x|0 with x != 0 known or assumed               --#
        #-- -------------------------------------------------------- --#
        if self.rhs == zero:
            if (NotEquals(self.lhs, zero).proven()
                    and InSet(self.lhs, Complex).proven()):
                # We have 0/x with complex x ≠ 0
                return self.conclude_via_zero_factor()
            else:
                err_str = err_str + (
                    "Case: rhs = 0. "
                    "Although rhs = 0, either the lhs {0} is not known to "
                    "be non-zero or {0} is not known to be in the complex "
                    "numbers (or both). Try proving one or both of those "
                    "claims first.\n".format(self.lhs))

        #-- -------------------------------------------------------- --#
        #-- Case (3): very simple version of x|xy or x|yx            --#
        #-- -------------------------------------------------------- --#
        # return self.conclude_via_factor(assumptions)
        try:
            return self.conclude_via_factor()
        except Exception as e:
            err_str = err_str + (
                "Case: x|xy. This possible case returned the following "
                "error message: {0} \n".format(e))
            pass

        #-- -------------------------------------------------------- --#
        #-- Case (4): x^n|y^n if x|y                                 --#
        #-- -------------------------------------------------------- --#
        if (isinstance(self.lhs, Exp) and isinstance(self.rhs, Exp)
                and Equals(self.lhs.exponent, self.rhs.exponent)
                and Divides(self.lhs.base, self.rhs.base).proven()):
            try:
                deduce_number_set(self.lhs.base)
                deduce_number_set(self.rhs.base)
                deduce_number_set(self.lhs.exponent)
            except UnsatisfiedPrerequisites:
                pass

            if (InSet(self.lhs.base, Integer).proven()
                    and InSet(self.rhs.base, Integer).proven()
                    and InSet(self.lhs.exponent, NaturalPos).proven()):
                return (Divides(self.lhs.base,
                                self.rhs.base).introduce_common_exponent(
                                    self.lhs.exponent))

            else:
                err_str = err_str + (
                    "Case: (x^n) | (y^n). One or more of the conditions "
                    "(such as domain requirements or x|y) were not "
                    "already proven. Check the conditions for the "
                    "common_exponent_introduction theorem in the "
                    "number/divisibility package.\n")

        else:
            err_str = err_str + (
                "Case: (x^n) | (y^n). Does not appear applicable.\n")
        """
        # This case should be handled on the "side-effect" end.

        #-- -------------------------------------------------------- --#
        #-- Case (5): x|y if x^n|y^n (for some small pos nat n)      --#
        #-- -------------------------------------------------------- --#
        possible_exps = range(2,10)
        for e in possible_exps:
            # print("exp = {}".format(e))
            if (Divides(Exp(self.lhs, num(e)), Exp(self.rhs, num(e))).
                proven(assumptions)):
                # print("    Divides found for exp = {}".format(test_exp))
                return (Divides(Exp(self.lhs, test_exp),
                                Exp(self.rhs, test_exp)).
                        eliminate_common_exponent(assumptions=assumptions))

        err_str = err_str + (
                "Case: x|y where we already have (x^n)|(y^n). "
                "Does not appear applicable.\n")
        """

        #-- -------------------------------------------------------- --#
        #-- Case (6): x|z with x|y and y|z known or assumed          --#
        #-- -------------------------------------------------------- --#
        # Seek out the appropriate x|y and y|z and use transitivity
        # to get x|z, utilizing the conclude_via_transitivity() method
        # available for instances of TransitiveRelation
        try:
            return self.conclude_via_transitivity()
        except Exception as e:
            err_str = err_str + (
                "Case: transitivity search. In attempting to use "
                "conclude_via_transitivity(), obtained the following "
                "error message: {0}.".format(e))
            pass

        raise ProofFailure(self, defaults.assumptions, err_str)