def conclude(self, assumptions=USE_DEFAULTS): ''' Attempt to conclude that the element is in the exponentiated set. ''' from proveit.logic import InSet from proveit.logic.sets.membership import (exp_set_0, exp_set_1, exp_set_2, exp_set_3, exp_set_4, exp_set_5, exp_set_6, exp_set_7, exp_set_8, exp_set_9) from proveit.numbers import zero, is_literal_int, DIGITS element = self.element domain = self.domain elem_in_set = InSet(element, domain) if not isinstance(element, ExprTuple): raise ProofFailure( elem_in_set, assumptions, "Can only automatically deduce membership in exponentiated " "sets for an element that is a list") exponent_eval = domain.exponent.evaluation(assumptions=assumptions) exponent = exponent_eval.rhs base = domain.base #print(exponent, base, exponent.as_int(),element, domain, len(element)) if is_literal_int(exponent): if exponent == zero: return exp_set_0.instantiate({S: base}, assumptions=assumptions) if element.num_entries() != exponent.as_int(): raise ProofFailure( elem_in_set, assumptions, "Element not a member of the exponentiated set; " "incorrect list length") elif exponent in DIGITS: # thm = forall_S forall_{a, b... in S} (a, b, ...) in S^n thm = locals()['exp_set_%d' % exponent.as_int()] expr_map = {S: base} # S is the base # map a, b, ... to the elements of element. expr_map.update({ proveit.__getattr__(chr(ord('a') + k)): elem_k for k, elem_k in enumerate(element) }) elem_in_set = thm.instantiate(expr_map, assumptions=assumptions) else: raise ProofFailure( elem_in_set, assumptions, "Automatic deduction of membership in exponentiated sets " "is not supported beyond an exponent of 9") else: raise ProofFailure( elem_in_set, assumptions, "Automatic deduction of membership in exponentiated sets is " "only supported for an exponent that is a literal integer") if exponent_eval.lhs != exponent_eval.rhs: # after proving that the element is in the set taken to # the evaluation of the exponent, substitute back in the # original exponent. return exponent_eval.sub_left_side_into(elem_in_set, assumptions=assumptions) return elem_in_set
def notEqual(self, other): from _.theorems_ import falseNotTrue from ._common_ import TRUE, FALSE if other == TRUE: return falseNotTrue if other == FALSE: raise ProofFailure("Cannot prove FALSE != FALSE since that statement is false") raise ProofFailure("Inequality between FALSE and a non-boolean not defined")
def not_equal(self, other, **defaults_config): from _.theorems_ import false_not_true from . import TRUE, FALSE if other == TRUE: return false_not_true if other == FALSE: raise ProofFailure( "Cannot prove FALSE != FALSE since that statement is false") raise ProofFailure( "Inequality between FALSE and a non-boolean not defined")
def not_equal(self, other, **defaults_config): from . import true_not_false from . import TRUE, FALSE if other == FALSE: return true_not_false if other == TRUE: raise ProofFailure( "Cannot prove TRUE != TRUE since that statement is false") raise ProofFailure( "Inequality between TRUE and a non-boolean not defined")
def notEqual(self, other, assumptions=USE_DEFAULTS): from ._theorems_ import trueNotFalse from ._common_ import TRUE, FALSE if other == FALSE: return trueNotFalse if other == TRUE: raise ProofFailure( "Cannot prove TRUE != TRUE since that statement is false") raise ProofFailure( "Inequality between TRUE and a non-boolean not defined")
def conclude(self, assumptions): ''' If the domain has a 'foldForall' method, attempt to conclude this Forall statement via 'concludeAsFolded' or by proving the instance expression under proper assumptions and then generalizing. ''' # first try to prove via generalization without automation extra_assumptions = tuple(self.inclusiveConditions()) try: proven_inst_expr = self.explicitInstanceExpr().prove( assumptions=extra_assumptions + defaults.checkedAssumptions(assumptions), automation=False) return proven_inst_expr.generalize(self.explicitInstanceVars(), conditions=extra_assumptions) except: pass # next try 'foldAsForall' on the domain (if applicable) hasFoldAsForall = False if self.hasDomain() and hasattr(self.domain, 'foldAsForall'): # try foldAsForall first hasFoldAsForall = True try: return self.concludeAsFolded(assumptions) except: pass # lastly, try to prove via generalization with automation try: proven_inst_expr = self.explicitInstanceExpr().prove( assumptions=extra_assumptions + defaults.checkedAssumptions(assumptions)) instanceVarLists = [list(self.explicitInstanceVars())] conditions = list(self.inclusiveConditions()) # see if we can generalize multiple levels simultaneously for a shorter proof while isinstance(proven_inst_expr.proof(), Generalization): instanceVarLists.append( list(proven_inst_expr.explicitInstanceVars())) conditions += proven_inst_expr.conditions proven_inst_expr = proven_inst_expr.proof().requiredTruths[0] return proven_inst_expr.generalize(forallVarLists=instanceVarLists, conditions=conditions) except ProofFailure: if hasFoldAsForall: raise ProofFailure( self, assumptions, "Unable to conclude automatically; both the 'foldAsForall' method on the domain and automated generalization failed." ) else: raise ProofFailure( self, assumptions, "Unable to conclude automatically; the domain has no 'foldAsForall' method and automated generalization failed." )
def deduceInNumberSet(self, numberSet, assumptions=USE_DEFAULTS): from ._theorems_ import summationNatsClosure, summationIntsClosure, summationRealsClosure, summationComplexesClosure P_op, P_op_sub = Operation(P, self.instanceVars), self.instanceExpr Q_op, Q_op_sub = Operation(Qmulti, self.instanceVars), self.conditions Operation(P, self.instanceVars) self.summand if numberSet == Naturals: thm = summationNatsClosure elif numberSet == Integers: thm = summationIntsClosure elif numberSet == Reals: thm = summationRealsClosure elif numberSet == Complexes: thm = summationComplexesClosure else: raise ProofFailure( InSet(self, numberSet), assumptions, "'deduceInNumberSet' not implemented for the %s set" % str(numberSet)) return thm.specialize( { P_op: P_op_sub, S: self.domain, Q_op: Q_op_sub }, relabelMap={ xMulti: self.instanceVars }, assumptions=assumptions).deriveConsequent(assumptions=assumptions)
def rounding_deduce_in_number_set(expr, number_set, rounding_real_closure_thm, rounding_real_pos_closure_thm, assumptions=USE_DEFAULTS): ''' Given a number set number_set, attempt to prove that the given Ceil, Floor, or Round expression is in that number set using the appropriate closure theorem. ''' from proveit import ProofFailure from proveit import x from proveit.logic import InSet from proveit.numbers import Integer, Natural # among other things, convert any assumptions=None # to assumptions=() assumptions = defaults.checked_assumptions(assumptions) if number_set == Integer: return rounding_real_closure_thm.instantiate({x: expr.operand}, assumptions=assumptions) if number_set == Natural: return rounding_real_pos_closure_thm.instantiate( {x: expr.operand}, assumptions=assumptions) msg = ("The rounding_methods.py function " "'rounding_deduce_in_number_set()' is not implemented for the " "%s set" % str(number_set)) raise ProofFailure(InSet(expr, number_set), assumptions, msg)
def deduceInNumberSet(self, number_set, assumptions=USE_DEFAULTS): ''' Given a number set number_set (such as Integers, Reals, etc), attempt to prove that the given ModAbs expression is in that number set using the appropriate closure theorem. ''' from proveit._common_ import a, b from proveit.logic import InSet from proveit.number.modular._theorems_ import ( modAbsIntClosure, modAbsRealClosure) from proveit.number import Integers, Reals # among other things, make sure non-existent assumptions # manifest as empty tuple () rather than None assumptions = defaults.checkedAssumptions(assumptions) if number_set == Integers: return modAbsIntClosure.specialize( {a:self.value, b:self.divisor}, assumptions=assumptions) if number_set == Reals: return modAbsRealClosure.specialize( {a:self.value, b:self.divisor}, assumptions=assumptions) msg = ("'ModAbs.deduceInNumberSet()' not implemented for " "the %s set"%str(number_set)) raise ProofFailure(InSet(self, number_set), assumptions, msg)
def conclude(self, assumptions=USE_DEFAULTS): ''' Try to deduce that the given element is in the set of Booleans under the given assumptions. ''' from ._theorems_ import inBoolIfTrue, inBoolIfFalse element = self.element # if the element is already proven or disproven, use inBoolIfTrue or inBoolIfFalse try: element.prove(assumptions=assumptions, automation=False) return inBoolIfTrue.specialize({A: element}, assumptions=assumptions) except: pass try: element.disprove(assumptions=assumptions, automation=False) return inBoolIfFalse.specialize({A: element}, assumptions=assumptions) except: pass # Use 'deduceInBool' if the element has that method. if hasattr(element, 'deduceInBool'): return element.deduceInBool(assumptions=assumptions) raise ProofFailure( inBool(element), assumptions, str(element) + ' not proven to be equal to TRUE or FALSE.')
def conclude(self, assumptions=USE_DEFAULTS): ''' Try to deduce that the given element is in the Boolean set under the given assumptions. ''' from . import in_bool_if_true, in_bool_if_false element = self.element # if the element is already proven or disproven, use in_bool_if_true or # in_bool_if_false try: element.prove(assumptions=assumptions, automation=False) return in_bool_if_true.instantiate({A: element}, assumptions=assumptions) except ProofFailure: pass try: element.disprove(assumptions=assumptions, automation=False) return in_bool_if_false.instantiate({A: element}, assumptions=assumptions) except ProofFailure: pass # Use 'deduce_in_bool' if the element has that method. if hasattr(element, 'deduce_in_bool'): return element.deduce_in_bool(assumptions=assumptions) raise ProofFailure( in_bool(element), assumptions, str(element) + ' not proven to be equal to TRUE or FALSE.')
def rounding_deduceInNumberSet(expr, number_set, roundingRealClosureThm, roundingRealPosClosureThm, assumptions=USE_DEFAULTS): ''' Given a number set number_set, attempt to prove that the given Ceil, Floor, or Round expression is in that number set using the appropriate closure theorem. ''' from proveit import ProofFailure from proveit._common_ import x from proveit.logic import InSet from proveit.number import Integers, Naturals # among other things, convert any assumptions=None # to assumptions=() assumptions = defaults.checkedAssumptions(assumptions) if number_set == Integers: return roundingRealClosureThm.specialize( {x:expr.operand}, assumptions=assumptions) if number_set == Naturals: return roundingRealPosClosureThm.specialize( {x:expr.operand}, assumptions=assumptions) msg = ("The rounding_methods.py function " "'rounding_deduceInNumberSet()' is not implemented for the " "%s set"%str(number_set)) raise ProofFailure(InSet(expr, number_set), assumptions, msg)
def concludeViaImplication(consequent, assumptions): ''' Perform a breadth-first search of implications going in reverse from the consequent until reaching an antecedent that has been proven. ''' visited = set() consequent_map = dict() # map antecedents to consequents that arise durent the breadth-first search queue = [consequent] while len(queue) > 0: expr = queue.pop() if expr not in visited: visited.add(expr) if expr not in Implies.knownRightSides: continue # no known implications with the expr as the consequent; skip it for knownImplication in Implies.knownRightSides[expr]: # see if the knownImplication is applicable under the given set of assumptions if knownImplication.isSufficient(assumptions): local_antecedent, local_consequent = knownImplication.antecedent, knownImplication.consequent consequent_map[local_antecedent] = local_consequent try: knownImplication.antecedent.prove(assumptions, automation=False) # found a solution; use it by deriving "local" consequents until getting to the desired consequent while True: known_truth = Implies(local_antecedent, local_consequent).deriveConsequent(assumptions=assumptions) if known_truth.expr == consequent: return known_truth local_antecedent = known_truth.expr local_consequent = consequent_map[local_antecedent] except ProofFailure: queue.append(local_antecedent) raise ProofFailure(consequent, assumptions, 'Unable to conclude via implications')
def conclude_via_generalization(self, **defaults_config): ''' Conclude this universal quantification by proving the instance expression with assumptions that include the conditions of the quantification and then performing generalization step(s). This will delve into any number of nested universal quantifications if necessary. With automation turned on, we will attempt to prove the innermost instance expression, under appropriate assumptions, via automation if necessary. ''' automation = defaults.automation expr = self instance_param_lists = [] conditions = [] proven_inst_expr = None while isinstance(expr, Forall): new_params = expr.explicit_instance_params() instance_param_lists.append(list(new_params)) conditions += list(expr.conditions.entries) expr = expr.instance_expr with defaults.temporary() as temp_defaults: temp_defaults.assumptions = (defaults.assumptions + tuple(conditions)) if automation and not isinstance(expr, Forall): expr.prove() if expr.proven(): proven_inst_expr = expr.prove() break if proven_inst_expr is not None: return proven_inst_expr.generalize(instance_param_lists, conditions=conditions) raise ProofFailure( self, defaults.assumptions, "Unable to 'conclude_via_generalization' without automation.")
def deduce_in_number_set(self, number_set, assumptions=USE_DEFAULTS): from . import (summation_nat_closure, summation_int_closure, summation_real_closure, summation_complex_closure) _x = self.instance_param P_op, _P_op = Function(P, _x), self.instance_expr Q_op, _Q_op = Function(Q, _x), self.condition self.summand if number_set == Natural: thm = summation_nat_closure elif number_set == Integer: thm = summation_int_closure elif number_set == Real: thm = summation_real_closure elif number_set == Complex: thm = summation_complex_closure else: raise ProofFailure( InSet(self, number_set), assumptions, ("'deduce_in_number_set' not implemented for the %s set" % str(number_set))) impl = thm.instantiate({ x: _x, P_op: _P_op, Q_op: _Q_op }, assumptions=assumptions) return impl.derive_consequent(assumptions=assumptions)
def deduce_in_number_set(self, number_set, assumptions=USE_DEFAULTS): ''' Given a number set number_set (such as Integer, Real, etc), attempt to prove that the given Mod expression is in that number set using the appropriate closure theorem. ''' from proveit.logic import InSet from proveit.numbers.modular import ( mod_int_closure, mod_int_to_nat_closure, mod_real_closure) from proveit.numbers import Integer, Natural, Real # among other things, make sure non-existent assumptions # manifest as empty tuple () rather than None assumptions = defaults.checked_assumptions(assumptions) if number_set == Integer: return mod_int_closure.instantiate( {a: self.dividend, b: self.divisor}, assumptions=assumptions) if number_set == Natural: return mod_int_to_nat_closure.instantiate( {a: self.dividend, b: self.divisor}, assumptions=assumptions) if number_set == Real: return mod_real_closure.instantiate( {a: self.dividend, b: self.divisor}, assumptions=assumptions) msg = ("'Mod.deduce_in_number_set()' not implemented for " "the %s set" % str(number_set)) raise ProofFailure(InSet(self, number_set), assumptions, msg)
def notEqual(self, rhs, assumptions=USE_DEFAULTS): from ._theorems_ import multNotEqZero if rhs == zero: return multNotEqZero.specialize({xMulti: self.operands}, assumptions=assumptions) raise ProofFailure( Equals(self, zero), assumptions, "'notEqual' only implemented for a right side of zero")
def deduce_in_integer_nonpos(self, **defaults_config): from proveit.logic import InSet from proveit.numbers import IntegerNonPos if self.n != 0: raise ProofFailure(InSet(self, IntegerNonPos), defaults.assumptions, "%s is positive"%self) from proveit.numbers.number_sets.integers import zero_is_nonpos return zero_is_nonpos
def conclude(self, **defaults_config): ''' Try to deduce that the given element is in the number set under the given assumptions. ''' from proveit.numbers import deduce_number_set element = self.element ''' # Maybe let's not simplify first. If # See if we can simplify the element first. if hasattr(element, 'simplification'): simplification = element.simplification(assumptions=assumptions) element = simplification.rhs if element != self.element: # Prove membersip for the simplified element elem_in_set = InSet(element, self.number_set).prove(assumptions) # Substitute into the original. return simplification.sub_left_side_into(elem_in_set, assumptions) ''' try: deduce_number_set(element) except (ProofFailure, UnsatisfiedPrerequisites): pass membership = InSet(element, self.number_set) if membership.proven(): return membership.prove() # Try the 'deduce_in_number_set' method. if hasattr(element, 'deduce_in_number_set'): try: return element.deduce_in_number_set(self.number_set) except (NotImplementedError, UnsatisfiedPrerequisites) as e: if hasattr(self, 'conclude_as_last_resort'): return self.conclude_as_last_resort() raise ProofFailure(InSet(self.element, self.number_set), defaults.assumptions, str(e)) else: if hasattr(self, 'conclude_as_last_resort'): return self.conclude_as_last_resort() msg = str(element) + " has no 'deduce_in_number_set' method." raise ProofFailure(InSet(self.element, self.number_set), defaults.assumptions, msg)
def conclude(self, assumptions=USE_DEFAULTS): ''' Try to deduce that the given element is in the number set under the given assumptions. ''' if hasattr(self.element, 'deduceInNumberSet'): return self.element.deduceInNumberSet(self, assumptions=assumptions) raise ProofFailure( InSet(self.element, self.number_set), assumptions, str(self.element) + " has no 'deduceInNumberSet' method.")
def notEqual(self, rhs, assumptions=USE_DEFAULTS): # accessed from conclude() method in not_equals.py from ._theorems_ import absNotEqZero from proveit.number import zero if rhs == zero: return absNotEqZero.specialize({a: self.operand}, assumptions=assumptions) raise ProofFailure( Equals(self, zero), assumptions, "'notEqual' only implemented for a right side of zero")
def not_equal(self, rhs, assumptions=USE_DEFAULTS): # accessed from conclude() method in not_equals.py from . import abs_not_eq_zero from proveit.numbers import zero if rhs == zero: return abs_not_eq_zero.instantiate({a: self.operand}, assumptions=assumptions) raise ProofFailure( Equals(self, zero), assumptions, "'not_equal' only implemented for a right side of zero")
def deduceInNumberSet(self, numberSet, assumptions=USE_DEFAULTS): # edited by JML 7/20/19 from ._theorems_ import multIntClosure, multIntClosureBin, multNatClosure, multNatClosureBin, multNatPosClosure, multNatClosureBin, multRealClosure, multRealClosureBin, multRealPosClosure, multRealPosClosureBin, multComplexClosure, multComplexClosureBin from proveit.number import num if hasattr(self, 'number_set'): numberSet = numberSet.number_set bin = False if numberSet == Integers: if len(self.operands) == 2: thm = multIntClosureBin bin = True else: thm = multIntClosure elif numberSet == Naturals: if len(self.operands) == 2: thm = multNatsClosureBin bin = True else: thm = multNatsClosure elif numberSet == NaturalsPos: if len(self.operands) == 2: thm = multNatsPosClosureBin bin = True else: thm = multNatsPosClosure elif numberSet == Reals: if len(self.operands) == 2: thm = multRealClosureBin bin = True else: thm = multRealClosure elif numberSet == RealsPos: if len(self.operands) == 2: thm = multRealsPosClosureBin bin = True else: thm = multRealPosClosure elif numberSet == Complexes: if len(self.operands) == 2: thm = multComplexClosureBin bin = True else: thm = multComplexClosure else: msg = "'deduceInNumberSet' not implemented for the %s set"%str(numberSet) raise ProofFailure(InSet(self, numberSet), assumptions, msg) from proveit._common_ import AA # print("thm", thm) # print("self in deduce in number set", self) # print("self.operands", self.operands) if bin: return thm.specialize({a:self.operands[0], b:self.operands[1]}, assumptions=assumptions) return thm.specialize({m:num(len(self.operands)),AA:self.operands}, assumptions=assumptions)
def conclude(self, assumptions): ''' Try to automatically conclude this negation via evaluation reductions or double negation. ''' from proveit.logic import SimplificationError # as a last resort (concludeNegation on the operand should have been # tried first), conclude negation via evaluating the operand as false. try: self.operand.evaluation(assumptions=assumptions) except SimplificationError: raise ProofFailure(self, assumptions, "Unable to evaluate %s"%str(self.operand)) return self.concludeViaFalsifiedNegation(assumptions=assumptions)
def deduceInNumberSet(self, number_set, assumptions=USE_DEFAULTS): ''' Given a number set number_set (such as Integers, Reals, etc), attempt to prove that the given expression is in that number set using the appropriate closure theorem. ''' from proveit.number.absolute_value._theorems_ import ( absComplexClosure, absNonzeroClosure, absComplexClosureNonNegReals) from proveit.number import Complexes, Reals, RealsNonNeg, RealsPos # among other things, make sure non-existent assumptions # manifest as empty tuple () rather than None assumptions = defaults.checkedAssumptions(assumptions) if number_set == Reals: return absComplexClosure.specialize({a: self.operand}, assumptions=assumptions) if number_set == RealsPos: return absNonzeroClosure.specialize({a: self.operand}, assumptions=assumptions) if number_set == RealsNonNeg: return absComplexClosureNonNegReals.specialize( {a: self.operand}, assumptions=assumptions) # To be thorough and a little more general, we check if the # specified number_set is already proven to *contain* one of # the number sets we have theorems for -- for example, # Y=Complexes contain X=Reals, and # Y=(-1, inf) contains X=RealsPos, # but we don't have specific thms for those supersets Y. # If so, use the appropiate thm to determine that self is in X, # then prove that self must also be in Y since Y contains X. if Subset(Reals, number_set).proven(assumptions=assumptions): absComplexClosure.specialize({a: self.operand}, assumptions=assumptions) return InSet(self, number_set).prove(assumptions=assumptions) if Subset(RealsPos, number_set).proven(assumptions=assumptions): absNonzeroClosure.specialize({a: self.operand}, assumptions=assumptions) return InSet(self, number_set).prove(assumptions=assumptions) if Subset(RealsNonNeg, number_set).proven(assumptions=assumptions): absComplexClosureNonNegReals.specialize({a: self.operand}, assumptions=assumptions) return InSet(self, number_set).prove(assumptions=assumptions) # otherwise, we just don't have the right thm to make it work msg = ("'Abs.deduceInNumberSet()' not implemented for " "the %s set" % str(number_set)) raise ProofFailure(InSet(self, number_set), assumptions, msg)
def conclude(self, **defaults_config): ''' Try to automatically conclude this negation via evaluation reductions or double negation. ''' from proveit.logic import EvaluationError # as a last resort (conclude_negation on the operand should have been # tried first), conclude negation via evaluating the operand as false. try: self.operand.evaluation() except EvaluationError: raise ProofFailure(self, defaults.assumptions, "Unable to evaluate %s" % str(self.operand)) return self.conclude_via_falsified_negation()
def notEqual(self, rhs, assumptions=USE_DEFAULTS): from ._theorems_ import multNotEqZero from proveit.number import zero if rhs == zero: _n = self.operands.length(assumptions) _a = self.operands return multNotEqZero.specialize({ n: _n, a: _a }, assumptions=assumptions) raise ProofFailure( Equals(self, zero), assumptions, ("'notEqual' only implemented for a right side of zero"))
def concludeNegation(self, assumptions=USE_DEFAULTS): # Created by JML on 6/24/19 from ._theorems_ import (trueAndFalseNegated, falseAndTrueNegated, falseAndFalseNegated, nandIfNeither, nandIfLeftButNotRight, nandIfRightButNotLeft) from proveit.logic import Not not_self = Not(self) if not_self in {trueAndFalseNegated.expr, falseAndTrueNegated.expr, falseAndFalseNegated.expr}: # should be disproven via one of the imported theorems as a simple special case return not_self.prove() # Prove that the conjunction is true by proving that one of its operands is false and then negate it. # In the first attempt, don't use automation to prove any of the operands so that # we don't waste time trying to prove operands when we already know one to be false for useAutomationForOperand in [False, True]: disprovenOperandIndices = [] for _k, operand in enumerate(self.operands): try: operand.disprove(assumptions, automation=useAutomationForOperand) disprovenOperandIndices.append(_k) # possible way to prove it self.concludeViaExample(operand, assumptions=assumptions) except ProofFailure: pass if len(self.operands) == 2 and len(disprovenOperandIndices) > 0: # One or both of the two operands were known to be true (without automation). # Try a possibly simpler proof than concludeViaExample. try: if len(disprovenOperandIndices) == 2: return nandIfNeither.specialize({A: self.operands[0], B: self.operands[1]}, assumptions=assumptions) elif disprovenOperandIndices[0] == 0: return nandIfRightButNotLeft.specialize({A: self.operands[0], B: self.operands[1]}, assumptions=assumptions) else: return nandIfLeftButNotRight.specialize({A: self.operands[0], B: self.operands[1]}, assumptions=assumptions) except: pass if len(disprovenOperandIndices) > 0: # Not(self) should have been proven via # concludeViaExample above try: return not_self.prove(assumptions, automation=False) except: # If it wasn't proven via concludeViaExample, let's # call it again to raise the appropriate exception. operand = self.operands[disprovenOperandIndices[0]] return self.concludeViaExample(operand, assumptions=assumptions) raise ProofFailure(not_self, assumptions, "Unable to conclude the negated conjunction; " "we could not disprove any of the conjunction " "operands.")
def deduce_in_number_set(self, number_set, **defaults_config): from proveit.numbers import (Natural, NaturalPos, Digits, IntegerNonPos, RationalNonPos, RealNonPos) from proveit.logic import InSet, SubsetEq if number_set == Natural: return self.deduce_in_natural() elif number_set == NaturalPos: return self.deduce_in_natural_pos() elif number_set == IntegerNonPos: if self.n > 0: raise ProofFailure( InSet(self, number_set), defaults.assumptions, "%s is positive"%self) return InSet(self, number_set).conclude_as_last_resort() elif number_set == Digits: return self.deduce_in_digits() else: try: # Do this to avoid infinite recursion -- if # we already know this numeral is in the NaturalPos set # we should know how to prove that it is in any # number set that contains the natural numbers. if self.n > 0: InSet(self, NaturalPos).prove(automation=False) else: InSet(self, Natural).prove(automation=False) InSet(self, IntegerNonPos).prove(automation=False) except BaseException: # Try to prove that it is in the given number # set after proving that the numeral is in the # Natural set and the NaturalPos set. if self.n > 0: self.deduce_in_natural_pos() else: self.deduce_in_natural() self.deduce_in_integer_nonpos() if self.n > 0: sub_rel = SubsetEq(NaturalPos, number_set) else: if number_set in (RationalNonPos, RealNonPos): sub_rel = SubsetEq(IntegerNonPos, number_set) # Allow automation for this minor thing even # if automation has been disabled coming into this. sub_rel.prove(automation=True) else: sub_rel = SubsetEq(Natural, number_set) # Prove membership via inclusion: return sub_rel.derive_superset_membership(self)
def conclude(self, assumptions=USE_DEFAULTS): from proveit import ProofFailure from proveit.logic import Equals, SetOfAll, SetEquiv # Equal sets include each other. if Equals(*self.operands.entries).proven(assumptions): return self.conclude_via_equality(assumptions) # Equivalent sets include each other. if SetEquiv(*self.operands.entries).proven(assumptions): return self.conclude_via_equivalence(assumptions) # Check for special case of set comprehension # [{x | Q*(x)}_{x \in S}] \subseteq S if isinstance(self.subset, SetOfAll): from proveit.logic.sets.comprehension import ( comprehension_is_subset) set_of_all = self.subset if (len(set_of_all.all_instance_vars()) == 1 and set_of_all.instance_element == set_of_all.all_instance_vars()[0] and set_of_all.domain == self.superset): Q_op, Q_op_sub = ( Operation(Q, set_of_all.all_instance_vars()), set_of_all.conditions) concluded = comprehension_is_subset.instantiate( {S: set_of_all.domain, Q_op: Q_op_sub}, relabel_map={x: set_of_all.all_instance_vars()[0]}, assumptions=assumptions) return concluded.with_matching_style(self) _A, _B = self.operands.entries if hasattr(_B, 'deduce_subset_eq_relation'): try: return _B.deduce_subset_eq_relation(_A, assumptions) except NotImplementedError: pass try: # Attempt to conclude A subseteq B via # forall_{x in A} x in B. return self.conclude_as_folded( elem_instance_var=safe_dummy_var(self), assumptions=assumptions) except ProofFailure as e: raise ProofFailure(self, assumptions, "Failed to conclude as folded: %s.\n" "To try to prove %s via transitive " "relations, try 'conclude_via_transitivity'." %(str(self), str(e)))