예제 #1
0
 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)
예제 #2
0
 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)))
예제 #3
0
 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)))
예제 #4
0
 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)
예제 #5
0
 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)))
예제 #6
0
    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))
예제 #7
0
 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)