def deduce_equality(self, equality, **defaults_config): ''' Prove the given equality with self on the left-hand side. ''' from proveit.logic import Equals if not isinstance(equality, Equals): raise ValueError("The 'equality' should be an Equals expression") if equality.lhs != self: raise ValueError("The left side of 'equality' should be 'self'") if equality.proven(): return equality # Already proven. with defaults.temporary() as temp_defaults: # Auto-simplify everything except the left and right sides # of the equality. temp_defaults.preserved_exprs = {equality.lhs, equality.rhs} temp_defaults.auto_simplify = True # Try a special-case "typical equality". if isinstance(equality.rhs, Len): if (isinstance(equality.rhs.operands, ExprTuple) and isinstance(self.operands, ExprTuple)): if (equality.rhs.operands.num_entries() == 1 and isinstance(equality.rhs.operands[0], ExprRange)): try: eq = self.typical_eq() if eq.expr == equality: return eq except (NotImplementedError, ValueError): pass # Next try to compute each side, simplify each side, and # prove they are equal. lhs_computation = equality.lhs.computation() if isinstance(equality.rhs, Len): # Compute both lengths and see if we can prove that they # are equal. rhs_computation = equality.rhs.computation() eq = Equals(lhs_computation.rhs, rhs_computation.rhs) if eq.lhs == eq.rhs: # Trivial reflection eq = eq.conclude_via_reflexivity() else: eq = eq.conclude_via_transitivity() return Equals.apply_transitivities( [lhs_computation, eq, rhs_computation]) else: # Compute the lhs length and see if we can prove that it is # equal to the rhs. eq = Equals(lhs_computation.rhs, equality.rhs) if eq.lhs == eq.rhs: # Trivial reflection eq = eq.conclude_via_reflexivity() else: eq = eq.conclude_via_transitivity() return lhs_computation.apply_transitivity(eq)
def deduce_equality(self, equality, assumptions=USE_DEFAULTS, minimal_automation=False): from proveit.logic import Equals if not isinstance(equality, Equals): raise ValueError("The 'equality' should be an Equals expression") if equality.lhs != self: raise ValueError("The left side of 'equality' should be 'self'") # Try a special-case "typical equality". if isinstance(equality.rhs, Len): if (isinstance(equality.rhs.operand, ExprTuple) and isinstance(self.operand, ExprTuple)): if (equality.rhs.operand.num_entries() == 1 and isinstance(equality.rhs.operand[0], ExprRange)): try: eq = \ self.typical_eq(assumptions=assumptions) if eq.expr == equality: return eq except (NotImplementedError, ValueError): pass # Next try to compute each side, simplify each side, and # prove they are equal. lhs_computation = equality.lhs.computation(assumptions=assumptions) if isinstance(equality.rhs, Len): # Compute both lengths and see if we can prove that they # are equal. rhs_computation = equality.rhs.computation(assumptions=assumptions) eq = Equals(lhs_computation.rhs, rhs_computation.rhs) if eq.lhs == eq.rhs: # Trivial reflection -- automation is okay for that. eq = eq.prove() else: eq = eq.prove(assumptions, automation=not minimal_automation) return Equals.apply_transitivities( [lhs_computation, eq, rhs_computation], assumptions=assumptions) else: # Compute the lhs length and see if we can prove that it is # equal to the rhs. eq = Equals(lhs_computation.rhs, equality.rhs) if eq.lhs == eq.rhs: # Trivial reflection -- automation is okay for that. eq = eq.prove() else: eq = eq.prove(assumptions, automation=not minimal_automation) return lhs_computation.apply_transitivity(eq, assumptions=assumptions)