Пример #1
0
 def apply_transitivity(self, other, assumptions=USE_DEFAULTS):
     '''
     apply_transitivity(Subset(A,B), SetEquiv(B,C)) 
     returns Subset(A,C)
     '''
     from proveit.logic import Equals, SetEquiv, SubsetEq
     if isinstance(other, Equals):
         return TransitiveRelation.apply_transitivity(
             self, other, assumptions)
     if isinstance(other, SetEquiv):
         # From set equivalence, derive the appropriate subset_eq
         # so we can use normal subset transitivity.
         if other.lhs == self.superset or other.rhs == self.subset:
             # EITHER (A subset B) and (B set_equiv C)
             # OR (A subset B) and (C set_equiv A)
             other_as_subset_eq = SubsetEq(*other.operands.entries)
         elif other.rhs == self.superset or other.lhs == self.subset:
             # EITHER (A subset B) and (C set_equiv B)
             # OR (A subset B) and (A set_equiv C)
             other_as_subset_eq = SubsetEq(
                 *reversed(other.operands.entries))
         else:
             raise ValueError("Unable to apply transitivity between %s "
                              "and %s." % (self, other))
         return self.apply_transitivity(other_as_subset_eq, assumptions)
Пример #2
0
 def conclude(self, assumptions):
     '''
     Attempt to conclude that the element is in the domain.
     First, see if it is contained in a subset of the domain.  
     If that fails and the domain has a 'membershipObject' method,
     try calling 'conclude' on the object it generates.
     '''
     from proveit.logic import SubsetEq
     from proveit import ProofFailure
     # try to conclude some x in S
     if self.element in InSet.knownMemberships:
         for knownMembership in InSet.knownMemberships[self.element]:
             if knownMembership.isSufficient(assumptions):
                 try:
                     # x in R is a known truth; if we can proof R subseteq S, we are done.
                     subsetRelation = SubsetEq(
                         knownMembership.domain,
                         self.domain).prove(assumptions)
                     # S is a superset of R, so now we can prove x in S.
                     return subsetRelation.deriveSupsersetMembership(
                         self.element, assumptions=assumptions)
                 except ProofFailure:
                     pass  # no luck, keep trying
     # could not prove it through a subset relationship, now try to use a MembershipObject
     if hasattr(self, 'membershipObject'):
         return self.membershipObject.conclude(assumptions)
Пример #3
0
    def includes(self, other_set):
        '''
        Return True if this NumberSet includes the 'other_set' set.
        '''
        from proveit.numbers.number_operation import (
            sorted_number_sets, standard_number_sets, deduce_number_set)
        if other_set == self: return True
        if SubsetEq(other_set, self).proven():
            return True

        if other_set not in standard_number_sets:    
            # For example, 'other_set' could be an integer Interval
            # or real IntervalCC, IntervalOC, ...), so let's see if
            # we can prove that an arbitrary variable in the other_set
            # is also in self.
            _x = safe_dummy_var(self, other_set)
            assumptions = defaults.assumptions + (InSet(_x, other_set),)
            deduce_number_set(_x, assumptions=assumptions)
            if InSet(_x, self).proven(assumptions=assumptions):
                SubsetEq(other_set, self).conclude_as_folded()
                return True

        # Try one level of indirection via SubsetEq.
        for number_set in sorted_number_sets:
            if number_set in (other_set, self):
                continue
            if (SubsetEq(other_set, number_set).proven() and
                    SubsetEq(number_set, self).proven()):
                return True

        return False # Not known to include the 'other'
Пример #4
0
    def conclude(self, assumptions):
        '''
        Attempt to conclude that the element is in the domain.
        First, see if it is not contained in a superset of the domain.
        Next, check if the element has a known simplification; if so,
        try to derive non-membership via this simplification.
        If there isn't a known simplification, next try to call
        the 'self.domain.nonmembership_object.conclude(..)' method to prove
        the non-membership.  If that fails, try simplifying the element
        again, this time using automation to push the simplification through
        if possible.
        As a last resort, try 'conclude_as_folded'.
        '''
        from proveit.logic import SubsetEq, InSet
        from proveit import ProofFailure
        from proveit.logic import SimplificationError

        # See if the membership is already known.
        if self.element in NotInSet.known_nonmemberships:
            for known_nonmembership in NotInSet.known_nonmemberships[
                    self.element]:
                if known_nonmembership.is_sufficient(assumptions):
                    # x not in R is known to be true; if we know that
                    # S subset_eq R, we are done.
                    rel = SubsetEq(self.domain, known_nonmembership.domain)
                    if rel.proven(assumptions):
                        # S is a subset of R, so now we can prove
                        # x not in S.
                        return rel.derive_subset_nonmembership(
                            self.element, assumptions)
        # No known membership works.  Let's see if there is a known
        # simplification of the element before trying anything else.
        try:
            elem_simplification = self.element.simplification(assumptions,
                                                              automation=True)
            if elem_simplification.lhs == elem_simplification.rhs:
                elem_simplification = None  # reflection doesn't count
        except SimplificationError:
            elem_simplification = None

        # If the element simplification succeeded, prove the membership
        # via the simplified form of the element.
        if elem_simplification is not None:
            simple_elem = elem_simplification.rhs
            simple_nonmembership = NotInSet(simple_elem,
                                            self.domain).prove(assumptions)
            inner_expr = simple_nonmembership.inner_expr().element
            return elem_simplification.sub_left_side_into(
                inner_expr, assumptions)
        else:
            # If it has a 'nonmembership_object', try to conclude
            # nonmembership using that.
            if hasattr(self, 'nonmembership_object'):
                return self.nonmembership_object.conclude(assumptions)
            else:
                # Otherwise, attempt to conclude via Not(x in S)
                return self.conclude_as_folded(assumptions=assumptions)
Пример #5
0
    def conclude(self, **defaults_config):
        '''
        Attempt to conclude that the the NotInSet object is true ---
        i.e. that the element is not in the domain.
        First, see if it is not contained in a superset of the domain.
        Next, check if the element has a known simplification; if so,
        try to derive non-membership via this simplification.
        If there isn't a known simplification, next try to call
        the 'self.domain.nonmembership_object.conclude(..)' method to
        prove the non-membership.  If that fails, try simplifying the
        element again, this time using automation to push the
        simplification through if possible.
        As a last resort, try 'conclude_as_folded'.
        '''
        from proveit import ProofFailure
        from proveit.logic import SubsetEq, evaluation_or_simplification

        if self.negated().disproven():
            return self.conclude_as_folded()

        # See if the element, or something known to be equal to
        # the element, is known to be a nonmember of the domain or a
        # superset of the domain.
        if self.element in NotInClass.known_nonmemberships:
            for known_nonmembership in \
                    NotInClass.known_nonmemberships[self.element]:
                if known_nonmembership.is_applicable():
                    # x not in R is known to be true; if we know that
                    # S subset_eq R, we are done.
                    rel = SubsetEq(self.domain, known_nonmembership.domain)
                    if rel.proven():
                        # S is a subset of R, so now we can prove
                        # x not in S.
                        return rel.derive_subset_nonmembership(self.element)

        # Try the standard Relation strategies -- evaluate or
        # simplify both sides.
        try:
            return Relation.conclude(self)
        except ProofFailure:
            # Both sides are already irreducible or simplified
            # or we were unable to simplify either side.
            pass

        # If it has a 'nonmembership_object', try to conclude
        # nonmembership using that.
        if hasattr(self, 'nonmembership_object'):
            return self.nonmembership_object.conclude()
        else:
            # Otherwise, attempt to conclude via Not(x in S)
            return self.conclude_as_folded()
Пример #6
0
 def deduce_in_vec_space(self, vec_space=None, *, field, **defaults_config):
     from . import invFT_is_unitary
     if field != Complex:
         raise NotImplementedError(
             "NumKet.deduce_in_vec_space only implemented for a "
             "complex field, not %s." % field)
     _SUdomain = invFT_is_unitary.instantiate({n: self.nqubits}).domain
     vspace = _SUdomain.including_vec_space(field=Complex)
     if vec_space is not None and vec_space != vspace:
         raise NotImplementedError(
             "InverseFourierTransofrm.deduce_in_vec_space only "
             "implemented to deduce membership in %s, not %s" %
             (vspace, vec_space))
     sub_rel = SubsetEq(_SUdomain, vspace)
     return sub_rel.derive_superset_membership(self)
Пример #7
0
 def deduce_in_vec_space(self, vec_space=None, *, field,
                         **defaults_config):
     '''
     Deduce that the tensor product of vectors is in a vector space
     which is the tensor product of corresponding vectors spaces.
     '''
     from . import tensor_prod_is_in_tensor_prod_space
     _a = self.operands
     _i = _a.num_elements()
     _K = VecSpaces.get_field(field)
     vec_spaces = VecSpaces.known_vec_spaces(self.operands, field=_K)
     membership = tensor_prod_is_in_tensor_prod_space.instantiate(
             {K: _K, i: _i, V: vec_spaces, a: _a})      
     if vec_space is not None and membership.domain != vec_space:
         sub_rel = SubsetEq(membership.domain, vec_space)
         return sub_rel.derive_superset_membership(self)
     return membership
Пример #8
0
 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)
Пример #9
0
    def deduce_in_number_set(self, number_set, **defaults_config):
        '''
        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.numbers.modular import (
            mod_int_closure, mod_int_to_nat_closure, mod_real_closure)
        from proveit.numbers import (Integer, Natural, Real,
                                     Interval, RealInterval)

        if (isinstance(number_set, Interval) or 
                isinstance(number_set, RealInterval)):
            if isinstance(number_set, Interval):
                # To prove that it is in an integer interval through
                # standard means, we'll need to know that the dividend
                # and divisor are integers.
                InSet(self.dividend, Integer).prove()
                InSet(self.divisor, Integer).prove()
            in_mod_interval = self.deduce_in_interval()
            mod_interval = in_mod_interval.domain
            if mod_interval == number_set:
                return in_mod_interval
            # To prove by standard means, 'mod_interval' must be a
            # subset of 'number_set'.
            set_relation = SubsetEq(mod_interval, number_set).prove()
            return set_relation.derive_superset_membership(self)
            
        if number_set == Integer:
            return mod_int_closure.instantiate(
                {a: self.dividend, b: self.divisor})

        if number_set == Natural:
            return mod_int_to_nat_closure.instantiate(
                {a: self.dividend, b: self.divisor})

        if number_set == Real:
            return mod_real_closure.instantiate(
                {a: self.dividend, b: self.divisor})

        raise NotImplementedError(
            "'Mod.deduce_in_number_set()' not implemented for the %s set" 
            % str(number_set))
Пример #10
0
def including_vec_space(subset, *, field):
    '''
    Return a vector space over the given field which includes
    the 'subset'.  Handles the following CartExpr cases:
        C^n contains R^n and Q^n as well as C^n
        R^n contains Q^n as well as R^n
        Q^n only contains Q^n
    Otherwise, call the 'including_vec_space' class method on
    'subset' if there is one.  Raise a NotImplementedError if all else
    fails.
    '''
    from proveit.logic import SubsetEq, CartExp
    from proveit.numbers import Rational, Real, Complex
    vec_space = None
    if isinstance(subset, CartExp):
        if field is None or field==subset.base:
            vec_space = subset
        elif ((field == Complex and subset.base in (Rational, Real))
              or (field == Real and subset.base == Rational)):
            vec_space = CartExp(field, subset.exponent)
    if ((field==Complex and (subset in (Rational, Real))) or
            (field==Real and subset==Rational)):
        vec_space = field
    if vec_space is None and hasattr(subset, 'including_vec_space'):
        vec_space = subset.including_vec_space(field=field)
    if vec_space is None:
        raise NotImplementedError(
                "'including_vec_space' is not implemented "
                "to handle %s over field %s and %s has no "
                "'including_vec_space' method"
                %(subset, field, subset))
    # Make sure it is a vector space
    deduce_as_vec_space(vec_space)
    # Make sure the field is a match.
    if field is not None:
        if VecSpaces.known_field(vec_space) != field:
            raise ValueError(
                    "%s is NOT a vector space over %s as requested."
                    %(vec_space, field))
    if subset != vec_space:
        # Make sure this new domain contains the
        # old domain.
        SubsetEq(subset, vec_space).prove()
    return vec_space
Пример #11
0
 def deduce_in_prob_domain(self,
                           sample_space,
                           is_event=None,
                           **defaults_config):
     '''
     Prove that this Prob is between 0 and 1 given that its
     operand is in a sample space or a subset of the sample space.
     Set is_event to true/false to indicate that this is/isn't a 
     probability of an event.  If left as None, this is inferred.
     '''
     from . import prob_in_interval, event_prob_in_interval
     from proveit.logic import InSet, SubsetEq
     from proveit.logic.sets import (Set, Union, Intersect, Difference,
                                     SetOfAll, PowerSet, CartProd, CartExp)
     if is_event == False or InSet(self.operand, sample_space).proven():
         # This is a sample probability.
         return prob_in_interval.instantiate({
             Omega: sample_space,
             x: self.operand
         })
     if is_event == True or SubsetEq(self.operand, sample_space).proven():
         # This is an event probability.
         return event_prob_in_interval.instantiate({
             Omega: sample_space,
             X: self.operand
         })
     for set_expr in (Set, Union, Intersect, Difference, SetOfAll, PowerSet,
                      CartProd, CartExp):
         if isinstance(self.operand, set_expr):
             # Infer this is an event probability because the
             # operand is a set-type expression.
             return event_prob_in_interval.instantiate({
                 Omega: sample_space,
                 X: self.operand
             })
     # Assume this is a sample probability because there is
     # no indication to the contrary.
     return prob_in_interval.instantiate({
         Omega: sample_space,
         x: self.operand
     })
Пример #12
0
    def conclude(self, **defaults_config):
        '''
        Attempt to conclude that the element is in the domain.  First, 
        see if it is known to be contained in a known subset of the
        domain.  Next, check if the element has a known simplification; 
        if so, try to derive membership via this simplification.
        If there isn't a known simplification, next try to call
        the 'self.domain.membership_object.conclude(..)' method to prove
        the membership.  If that fails, try simplifying the element
        again, this time using automation to push the simplification 
        through if possible.
        '''
        from proveit.logic import Equals, SubsetEq, evaluation_or_simplification

        # See if the element, or something known to be equal to
        # the element, is known to be a member of the domain or a subset
        # of the domain.
        for elem_sub in Equals.yield_known_equal_expressions(self.element):
            same_membership = None  # membership in self.domain
            eq_membership = None  # membership in an equal domain
            subset_membership = None  # membership in a subset
            for known_membership in InClass.yield_known_memberships(elem_sub):
                eq_rel = Equals(known_membership.domain, self.domain)
                sub_rel = SubsetEq(known_membership.domain, self.domain)
                if known_membership.domain == self.domain:
                    same_membership = known_membership
                    break  # this is the best to use; we are done
                elif eq_rel.proven():
                    eq_membership = known_membership
                elif sub_rel.proven():
                    subset_membership = known_membership
            elem_sub_in_domain = None
            if same_membership is not None:
                elem_sub_in_domain = same_membership
            elif eq_membership is not None:
                # domains are equal -- just substitute to domain.
                eq_rel = Equals(eq_membership.domain, self.domain)
                elem_sub_in_domain = eq_rel.sub_right_side_into(
                    eq_membership.inner_expr().domain)
            elif subset_membership is not None:
                # S is a superset of R, so now we can prove x in S.
                sub_rel = SubsetEq(subset_membership.domain, self.domain)
                elem_sub_in_domain = sub_rel.derive_superset_membership(
                    elem_sub)
            if elem_sub_in_domain is not None:
                # We found what we are looking for.
                if elem_sub == self.element:
                    return elem_sub_in_domain  # done
                # Just need to sub in the element for _elem_sub.
                Equals(elem_sub, self.element).conclude_via_transitivity()
                return elem_sub_in_domain.inner_expr().element.substitute(
                    self.element)

        # Try the standard Relation strategies -- evaluate or
        # simplify both sides.
        try:
            return Relation.conclude(self)
        except ProofFailure:
            # Both sides are already irreducible or simplified
            # or we were unable to simplify either side.
            pass

        # Unable to simplify the element.  Try to conclude via
        # the 'membership_object' if there is one.
        if hasattr(self, 'membership_object'):
            return self.membership_object.conclude()

        raise ProofFailure(
            self, defaults.assumptions, "Unable to conclude automatically; "
            "the domain, %s, has no 'membership_object' "
            "method with a strategy for proving "
            "membership." % self.domain)
Пример #13
0
    def conclude(self, assumptions):
        '''
        Attempt to conclude that the element is in the domain.
        First, see if it is known to be contained in a known subset of the
        domain.  Next, check if the element has a known simplification; if so,
        try to derive membership via this simplification.
        If there isn't a known simplification, next try to call
        the 'self.domain.membershipObject.conclude(..)' method to prove
        the membership.  If that fails, try simplifying the element
        again, this time using automation to push the simplification through
        if possible.
        '''
        from proveit.logic import Equals, SubsetEq
        from proveit import ProofFailure
        from proveit.logic import SimplificationError

        # See if the membership is already known.
        if self.element in InSet.knownMemberships:
            for knownMembership in InSet.knownMemberships[self.element]:
                if knownMembership.isSufficient(assumptions):
                    # x in R is a known truth; if we know that R subseteq S,
                    # or R = S we are done.
                    eqRel = Equals(knownMembership.domain, self.domain)
                    if eqRel.proven(assumptions):
                        return eqRel.subRightSideInto(
                            knownMembership.innerExpr().domain)
                    subRel = SubsetEq(knownMembership.domain, self.domain)
                    if subRel.proven(assumptions):
                        # S is a superset of R, so now we can prove x in S.
                        return subRel.deriveSupersetMembership(
                            self.element, assumptions)

        # No known membership works.  Let's see if there is a known
        # simplification of the element before trying anything else.
        try:
            elem_simplification = self.element.simplification(assumptions,
                                                              automation=False)
            if elem_simplification.lhs == elem_simplification.rhs:
                elem_simplification = None  # reflection doesn't count
        except SimplificationError:
            elem_simplification = None

        if elem_simplification is None:
            # Let's try harder to simplify the element.
            try:
                elem_simplification = self.element.simplification(assumptions)
                if elem_simplification.lhs == elem_simplification.rhs:
                    elem_simplification = None  # reflection doesn't count
            except SimplificationError:
                pass

        # If the element simplification succeeded, prove the membership
        # via the simplified form of the element.
        if elem_simplification is not None:
            simple_elem = elem_simplification.rhs
            simple_membership = InSet(simple_elem,
                                      self.domain).prove(assumptions)
            inner_expr = simple_membership.innerExpr().element
            return elem_simplification.subLeftSideInto(inner_expr, assumptions)
        else:
            # Unable to simplify the element.  Try to conclude via
            # the 'membershipObject' if there is one.
            if hasattr(self, 'membershipObject'):
                return self.membershipObject.conclude(assumptions)

            raise ProofFailure(
                self, assumptions, "Unable to conclude automatically; "
                "the domain, %s, has no 'membershipObject' "
                "method with a strategy for proving "
                "membership." % self.domain)