def conclude_via_some(self, subset_disjunction, assumptions=USE_DEFAULTS): ''' From some true (or assumed true) disjunctive subset of the operands, conclude that this 'or' expression is true. This is similar to the conclude_via_example method above. For example, we might have a disjunction such as: example_disj = A V B V C V D, where we know (or assume) that B V D is true. We could call example_disj.conclude_via_some(B V D, assumptions=[B V D]), which will return {B V D} |– A V B V C V D ''' # Check that the subset_disjunction is an instance of OR if not isinstance(subset_disjunction, Or): raise TypeError(('subset_disjunction arg should be ' 'a disjunction (Or)')) # Check that each of the operands in subset_disjunction occur as # operands in self (otherwise throw a ValueError). self_operands = self.operands subset_operands = subset_disjunction.operands unexpected_operands = list(set(subset_operands) - set(self_operands)) if len(unexpected_operands) != 0: raise ValueError('the disjunctive subset (subset_disjunction) you ' 'provided contains unexpected items: {}'.format( unexpected_operands)) # collect the operands not present in the proffered subset # (in using set() we are (temporarily) assuming no repeated operands) # and let's assume we get a non-empty set complementary_operands = list( set(self_operands) - set(subset_operands)) if len(complementary_operands) == 1: complementary_disjunction = complementary_operands[0] else: complementary_disjunction = Or(*complementary_operands) # the following produces a permutated, associated version of the # original disjunction binary_disjunction = (Or( subset_disjunction, complementary_disjunction).conclude_via_left(assumptions)) # remove the extra parentheses (not yet un-permuting) permuted_disjunction = (binary_disjunction.disassociate( 0, assumptions).disassociate(-1, assumptions)) return self.conclude_via_permutation(permuted_disjunction, assumptions)
def negationSideEffects(self, knownTruth): ''' Side-effect derivations to attempt automatically for Not(A and B and .. and .. Z). ''' from proveit.logic import Not, Or yield self.deriveInBool # (A and B and ... and Z) in Booleans # implemented by JML on 7/2/19 # If all of the operands are negated call the disjunction form of DeMorgan's if all(isinstance(operand, Not) for operand in self.operands): demorganOr = Or(*[operand.operand for operand in self.operands]) yield demorganOr.concludeViaDemorgans
def negation_side_effects(self, judgment): ''' Side-effect derivations to attempt automatically for Not(A and B and .. and .. Z). ''' from proveit.logic import Not, Or yield self.derive_in_bool # (A and B and ... and Z) in Boolean # implemented by JML on 7/2/19 # If all of the operands are negated call the disjunction form of # DeMorgan's if all(isinstance(operand, Not) for operand in self.operands): demorgan_or = Or(*[operand.operand for operand in self.operands]) yield demorgan_or.conclude_via_demorgans
from proveit.logic import Forall, Or, Equals, Implies from proveit.number import Reals from proveit.number import Less, LessEq, Greater, GreaterEq from proveit.common import x, y, z from proveit import beginAxioms, endAxioms beginAxioms(locals()) lessThanEqualsDef = Forall([x, y], Or(Less(x, y), Equals(x, y)), domain=Reals, conditions=LessEq(x, y)) lessThanEqualsDef greaterThanEqualsDef = Forall([x, y], Or(Greater(x, y), Equals(x, y)), domain=Reals, conditions=GreaterEq(x, y)) greaterThanEqualsDef reverseGreaterThanEquals = Forall((x, y), Implies(GreaterEq(x, y), LessEq(y, x))) reverseGreaterThanEquals reverseLessThanEquals = Forall((x, y), Implies(LessEq(x, y), GreaterEq(y, x))) reverseLessThanEquals reverseGreaterThan = Forall((x, y), Implies(Greater(x, y), Less(y, x))) reverseGreaterThan reverseLessThan = Forall((x, y), Implies(Less(x, y), Greater(y, x)))
InSet(LessThanEquals(a, b), Booleans), domain=Reals) lessThanEqualsInBools 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
InSet(LessEq(a, b), Booleans), domain=Reals) lessThanEqualsInBools greaterThanInBools = Forall([a, b], InSet(Greater(a, b), Booleans), domain=Reals) greaterThanInBools greaterThanEqualsInBools = Forall([a, b], InSet(GreaterEq(a, b), Booleans), domain=Reals) greaterThanEqualsInBools notEqualsIsLessThanOrGreaterThan = Forall((a, x), Or(Less(x, a), Greater(x, a)), domain=Reals, conditions=[NotEquals(x, a)]) notEqualsIsLessThanOrGreaterThan shiftLessThanToLessThanEquals = Forall((a, b), LessEq(a, b), domain=Integers, conditions=[Less(Sub(a, one), b)]) shiftLessThanToLessThanEquals lessThanEqualsAddRight = Forall([a, b, c], LessEq(Add(a, c), Add(b, c)), domain=Reals, conditions=[LessEq(a, b)]) lessThanEqualsAddRight
from proveit.logic import Forall, Or, Equals, Implies from proveit.number import Reals from proveit.number import LessThan, LessThanEquals, GreaterThan, GreaterThanEquals from proveit.common import x, y, z from proveit import beginAxioms, endAxioms beginAxioms(locals()) lessThanEqualsDef = Forall([x, y], Or(LessThan(x, y), Equals(x, y)), domain=Reals, conditions=LessThanEquals(x, y)) lessThanEqualsDef greaterThanEqualsDef = Forall([x, y], Or(GreaterThan(x, y), Equals(x, y)), domain=Reals, conditions=GreaterThanEquals(x, y)) greaterThanEqualsDef reverseGreaterThanEquals = Forall((x, y), Implies(GreaterThanEquals(x, y), LessThanEquals(y, x))) reverseGreaterThanEquals reverseLessThanEquals = Forall((x, y), Implies(LessThanEquals(x, y), GreaterThanEquals(y, x))) reverseLessThanEquals reverseGreaterThan = Forall((x, y), Implies(GreaterThan(x, y), LessThan(y, x)))
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) unfold_forall_over_bool = Forall( P, Implies(Forall(A, PofA, domain=Boolean), And(PofTrue, PofFalse))) in_bool_if_true = Forall(A, in_bool(A), conditions=[A]) in_bool_if_false = Forall(A, in_bool(A), conditions=[Not(A)]) # This weak form requires B to be a Boolean by_cases_weak = Forall((A, B), B,
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) unfoldForallOverBool = Forall( P, Implies(Forall(A, PofA, domain=Booleans), And(PofTrue, PofFalse))) inBoolIfTrue = Forall(A, inBool(A), conditions=[A]) inBoolIfFalse = Forall(A, inBool(A), conditions=[Not(A)]) # This weak form requires B to be a Boolean byCasesWeak = Forall((A, B), B,
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.")
conditions = LessThan(a,b)) relaxLessThan lessThanInBools = Forall([a, b], InSet(LessThan(a, b), Booleans), domain=Reals) lessThanInBools lessThanEqualsInBools = Forall([a, b], InSet(LessThanEquals(a, b), Booleans), domain=Reals) lessThanEqualsInBools 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], LessThanEquals(Add(c, a), Add(c, b)), domain=Reals, conditions=[LessThanEquals(a, b)]) lessThanEqualsAddLeft lessThanEqualsSubtract = Forall([a, b, c], LessThanEquals(Sub(a, c), Sub(b, c)), domain=Reals, conditions=[LessThanEquals(a, b)]) lessThanEqualsSubtract lessThanAddRight = Forall([a, b, c], LessThan(Add(a, c), Add(b, c)), domain=Reals, conditions=[LessThan(a, b)])