def apply_transitivity(self, other, assumptions=USE_DEFAULTS): ''' Apply a transitivity rule to derive from this x<=y expression and something of the form y<z, y<=z, z>y, z>=y, or y=z to obtain x<z or x<=z as appropriate. In the special case of x<=y and y<=x (or x>=y), derive x=z. ''' from . import (transitivity_less_eq_less, transitivity_less_less_eq, transitivity_less_eq_less_eq, symmetric_less_eq) from .less import Less other = as_expression(other) if isinstance(other, Equals): return NumberOrderingRelation.apply_transitivity( self, other, assumptions) # handles this special case if other.lower == self.upper and other.upper == self.lower: # x <= y and y <= x implies that x=y return symmetric_less_eq.instantiate({ x: self.lower, y: self.upper }, assumptions=assumptions) elif other.lower == self.upper: if isinstance(other, Less): new_rel = transitivity_less_eq_less.instantiate( { x: self.lower, y: self.upper, z: other.upper }, assumptions=assumptions) elif isinstance(other, LessEq): new_rel = transitivity_less_eq_less_eq.instantiate( { x: self.lower, y: self.upper, z: other.upper }, assumptions=assumptions) elif other.upper == self.lower: if isinstance(other, Less): new_rel = transitivity_less_less_eq.instantiate( { x: other.lower, y: other.upper, z: self.upper }, assumptions=assumptions) elif isinstance(other, LessEq): new_rel = transitivity_less_eq_less_eq.instantiate( { x: other.lower, y: other.upper, z: self.upper }, assumptions=assumptions) else: raise ValueError("Cannot perform transitivity with %s and %s!" % (self, other)) return new_rel.with_mimicked_style(self)
def apply_transitivity(self, other, **defaults_config): ''' From A set_equiv B (self) and B set_equiv C (other) derive and return A set_equiv C. If "other" is not a SetEquiv, reverse roles and call 'apply_transitivity' from the "other" side. This method initially based on the apply_transitivity method from Equals class. ''' from . import set_equiv_transitivity other = as_expression(other) if not isinstance(other, SetEquiv): # If the other relation is not "SetEquiv", # call from the "other" side. return other.apply_transitivity(self) other_set_equiv = other # We can assume that B set_equiv A will be a Judgment if # A set_equiv B is a Judgment because it is derived as a # side-effect. if self.rhs == other_set_equiv.lhs: return set_equiv_transitivity.instantiate( { A: self.lhs, B: self.rhs, C: other_set_equiv.rhs }, preserve_all=True) elif self.rhs == other_set_equiv.rhs: return set_equiv_transitivity.instantiate( { A: self.lhs, B: self.rhs, C: other_set_equiv.lhs }, preserve_all=True) elif self.lhs == other_set_equiv.lhs: return set_equiv_transitivity.instantiate( { A: self.rhs, B: self.lhs, C: other_set_equiv.rhs }, preserve_all=True) elif self.lhs == other_set_equiv.rhs: return set_equiv_transitivity.instantiate( { A: self.rhs, B: self.lhs, C: other_set_equiv.lhs }, preserve_all=True) else: raise TransitivityException( self, defaults.assumptions, 'Transitivity cannot be applied unless there is ' 'something in common in the set equivalences: ' '%s vs %s' % (str(self), str(other)))
def apply_transitivity(self, other, assumptions=USE_DEFAULTS): ''' From x = y (self) and y = z (other) derive and return x = z. Also works more generally as long as there is a common side to the equations. If "other" is not an equality, reverse roles and call 'apply_transitivity' from the "other" side. ''' from . import equals_transitivity other = as_expression(other) if not isinstance(other, Equals): # If the other relation is not "Equals", call from the "other" # side. return other.apply_transitivity(self, assumptions) other_equality = other # We can assume that y=x will be a Judgment if x=y is a Judgment # because it is derived as a side-effect. if self.rhs == other_equality.lhs: return equals_transitivity.instantiate( { x: self.lhs, y: self.rhs, z: other_equality.rhs }, assumptions=assumptions) elif self.rhs == other_equality.rhs: return equals_transitivity.instantiate( { x: self.lhs, y: self.rhs, z: other_equality.lhs }, assumptions=assumptions) elif self.lhs == other_equality.lhs: return equals_transitivity.instantiate( { x: self.rhs, y: self.lhs, z: other_equality.rhs }, assumptions=assumptions) elif self.lhs == other_equality.rhs: return equals_transitivity.instantiate( { x: self.rhs, y: self.lhs, z: other_equality.lhs }, assumptions=assumptions) else: raise TransitivityException( self, assumptions, 'Transitivity cannot be applied unless there is something in common in the equalities: %s vs %s' % (str(self), str(other)))
def apply_transitivity(self, other, **defaults_config): ''' Apply a transitivity rule to derive from this x<y expression and something of the form y<z, y<=z, z>y, z>=y, or y=z to obtain x<z. ''' from . import transitivity_less_less from . import transitivity_less_less_eq from . import transitivity_less_eq_less from .less_eq import LessEq other = as_expression(other) if isinstance(other, Equals): return NumberOrderingRelation.apply_transitivity( self, other) # handles this special case elif other.lower == self.upper: if isinstance(other, Less): new_rel = transitivity_less_less.instantiate( { x: self.lower, y: self.upper, z: other.upper }, preserve_all=True) elif isinstance(other, LessEq): new_rel = transitivity_less_less_eq.instantiate( { x: self.lower, y: self.upper, z: other.upper }, preserve_all=True) elif other.upper == self.lower: if isinstance(other, Less): new_rel = transitivity_less_less.instantiate( { x: other.lower, y: self.lower, z: self.upper }, preserve_all=True) elif isinstance(other, LessEq): new_rel = transitivity_less_eq_less.instantiate( { x: other.lower, y: self.lower, z: self.upper }, preserve_all=True) else: raise ValueError("Cannot perform transitivity with %s and %s!" % (self, other)) return new_rel.with_mimicked_style(self)
def apply_transitivity(self, other, **defaults_config): ''' Apply a transitivity rule to derive from this x<y expression and something of the form y<z, y<=z, z>y, z>=y, or y=z to obtain x<z. ''' from proveit.logic import Equals from . import equiv_transitivity other = as_expression(other) if isinstance(other, Equals): return TransitiveRelation.apply_transitivity( self, other) # handles this special case elif self.rhs == other.lhs: return equiv_transitivity.instantiate( { A: self.lhs, B: self.rhs, C: other.rhs }, preserve_all=True) elif self.rhs == other.rhs: return equiv_transitivity.instantiate( { A: self.lhs, B: self.rhs, C: other.lhs }, preserve_all=True) elif self.lhs == other.lhs: return equiv_transitivity.instantiate( { A: self.rhs, B: self.lhs, C: other.rhs }, preserve_all=True) elif self.lhs == other.rhs: return equiv_transitivity.instantiate( { A: self.rhs, B: self.lhs, C: other.lhs }, preserve_all=True) else: raise TransitivityException( None, defaults.assumptions, 'Transitivity cannot be applied unless there is something ' 'in common in the equalities: %s vs %s' % (str(self), str(other)))
def apply_transitivity(self, other, assumptions=USE_DEFAULTS): ''' From x|y (self) and y|z (other) derive and return x|z. Will also check for y|z (self) and x|y (other) to return x|z. ''' from . import divides_transitivity _x, _y, _z = divides_transitivity.instance_params other = as_expression(other) if not isinstance(other, Divides): raise ValueError( "Unsupported transitivity operand: Divides.apply_transitivity() " "method requires another Divides expression for transitivity " "to be applied. Instead, received the following input: {0}.". format(other)) if self.rhs == other.lhs: return divides_transitivity.instantiate( { _x: self.lhs, _y: self.rhs, _z: other.rhs }, assumptions=assumptions) if self.lhs == other.rhs: return divides_transitivity.instantiate( { _x: other.lhs, _y: other.rhs, _z: self.rhs }, assumptions=assumptions) else: raise TransitivityException( self, assumptions, 'Transitivity cannot be applied unless the lhs of one of ' 'Divides expressions is equal to the rhs of the other ' 'Divides expression. Instead we have: {0} vs {1}'.format( self, other))
def apply_transitivity(self, other, assumptions=USE_DEFAULTS): ''' Apply a transitivity rule to derive from this A subseteq B expression and something of the form B subseteq C, B subset C, or B=C to obtain A subset B or A subseteq B as appropriate. ''' from proveit.logic import Equals, SetEquiv, ProperSubset from . import (transitivity_subset_eq_subset, transitivity_subset_subset_eq, transitivity_subset_eq_subset_eq) other = as_expression(other) if isinstance(other, Equals) or isinstance(other, SetEquiv): return InclusionRelation.apply_transitivity( self, other, assumptions=assumptions) if other.subset == self.superset: if isinstance(other, ProperSubset): new_rel = transitivity_subset_eq_subset.instantiate( {A: self.subset, B: self.superset, C: other.superset}, assumptions=assumptions) elif isinstance(other, SubsetEq): new_rel = transitivity_subset_eq_subset_eq.instantiate( {A: self.subset, B: self.superset, C: other.superset}, assumptions=assumptions) elif other.superset == self.subset: if isinstance(other, ProperSubset): new_rel = transitivity_subset_subset_eq.instantiate( {A: other.subset, B: other.superset, C: self.superset}, assumptions=assumptions) elif isinstance(other, SubsetEq): new_rel = transitivity_subset_eq_subset_eq.instantiate( {A: other.subset, B: other.superset, C: self.superset}, assumptions=assumptions) else: raise ValueError( "Cannot perform transitivity with {0} and {1}!". format(self, other)) return new_rel.with_mimicked_style(self)