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)
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)
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
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))
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)
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.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 from proveit import ProofFailure from proveit.logic import SimplificationError # See if the membership is already known. if self.element in InSet.known_memberships: for known_membership in InSet.known_memberships[self.element]: if known_membership.is_sufficient(assumptions): # x in R is a judgment; if we know that R subseteq S, # or R = S we are done. eq_rel = Equals(known_membership.domain, self.domain) if eq_rel.proven(assumptions): return eq_rel.sub_right_side_into( known_membership.inner_expr().domain) sub_rel = SubsetEq(known_membership.domain, self.domain) if sub_rel.proven(assumptions): # S is a superset of R, so now we can prove x in S. return sub_rel.derive_superset_membership( 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.inner_expr().element return elem_simplification.sub_left_side_into( inner_expr, assumptions) else: # 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(assumptions) raise ProofFailure( self, assumptions, "Unable to conclude automatically; " "the domain, %s, has no 'membership_object' " "method with a strategy for proving " "membership." % self.domain)