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)
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)
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)
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()
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()
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)
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'.")
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()
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)
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],
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,
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)
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
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)
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.")
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
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)
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)
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()
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],
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)
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__)
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],
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
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
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
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)
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
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)
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)