示例#1
0
 def deduce_in_number_set(self, number_set, **defaults_config):
     from proveit.numbers import Natural, NaturalPos
     from proveit.logic import InSet
     if number_set == Natural:
         return self.deduce_in_natural()
     elif number_set == NaturalPos:
         return self.deduce_in_natural_pos()
     else:
         try:
             # Do this to avoid infinite recursion -- if
             # we already know this numeral is in NaturalPos
             # we should know how to prove that it is in any
             # number set that contains the natural numbers.
             if self.as_int() > 0:
                 InSet(self, NaturalPos).prove(automation=False)
             else:
                 InSet(self, Natural).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.
             self.deduce_in_natural()
             if self.as_int() > 0:
                 self.deduce_in_natural_pos()
         return InSet(self, number_set).conclude()
示例#2
0
 def shallow_simplification(self, *, must_evaluate=False,
                            **defaults_config):
     '''
     Returns a proven simplification equation for this Mod
     expression assuming the operands have been simplified.
     
     Specifically, performs reductions of the form
     (x mod L) = x where applicable and
     [(a mod L + b) mod L] = [(a + b) mod L].
     '''
     from . import (int_mod_elimination, real_mod_elimination,
                    redundant_mod_elimination, 
                    redundant_mod_elimination_in_sum)
     from proveit.numbers import (
         NaturalPos, RealPos, Interval, IntervalCO, subtract, zero, one)
     deduce_number_set(self.dividend)
     divisor_ns = deduce_number_set(self.divisor).domain
     if (NaturalPos.includes(divisor_ns) and 
             InSet(self.dividend, 
                   Interval(zero, 
                            subtract(self.divisor, one))).proven()):
         # (x mod L) = x if L in N+ and x in {0 .. L-1}
         return int_mod_elimination.instantiate(
             {x:self.dividend, L:self.divisor})
     if (RealPos.includes(divisor_ns) and 
             InSet(self.dividend, 
                   IntervalCO(zero, self.divisor)).proven()):
         # (x mod L) = x if L in R+ and x in [0, L)
         return real_mod_elimination.instantiate(
             {x:self.dividend, L:self.divisor})
     return Mod._redundant_mod_elimination(
             self, redundant_mod_elimination, 
             redundant_mod_elimination_in_sum)
示例#3
0
 def derive_element_in_restricted_number_set_if_known(
         self, **defaults_config):
     '''
     From (element in IntervalXX(x, y)), where either 
     x ≥ 0 or y ≤ 0 is known or provable without automation, 
     derive that the element is in RealPos, RealNeg, RealNonPos, or
     RealNonNeg as appropriate.  If neither x ≥ 0 nor y ≤ 0 is 
     known or provable without automation, raise an
     UnsatisfiedPrerequisites exception.
     '''
     from proveit.numbers import RealNonNeg, RealNonPos
     _a = self.domain.lower_bound
     _b = self.domain.upper_bound
     if (InSet(_a, RealNonNeg).proven() or 
             InSet(_b, RealNonPos).proven()):
         return self.derive_element_in_restricted_number_set()
     # Without employing further automation, can we prove the
     # lower bound is non-negative or the upper bound is
     # non-positive?
     try:
         _a.deduce_in_number_set(RealNonNeg, automation=False)
     except Exception:
         pass
     try:
         _b.deduce_in_number_set(RealNonPos, automation=False)
     except Exception:
         pass
     if (InSet(_a, RealNonNeg).proven() or 
             InSet(_b, RealNonPos).proven()):
         return self.derive_element_in_restricted_number_set()
     raise UnsatisfiedPrerequisites(
             "Must know that the lower bound is non-negative or the "
             "upper bound is non-positive to perform "
             "derive_element_in_restricted_number_set_if_known")
示例#4
0
    def deduce_linear_bound(self, **defaults_config):
        '''
        Bound the Sin function evaluation by a line.
        '''
        from . import (sine_linear_bound, sine_linear_bound_pos,
                       sine_linear_bound_nonneg, sine_linear_bound_neg,
                       sine_linear_bound_nonpos)

        deduce_number_set(self.angle)

        if isinstance(self.angle, Abs):
            bound = sine_linear_bound.instantiate({theta: self.angle.operand})
        elif InSet(self.angle, RealPos).proven():
            bound = sine_linear_bound_pos.instantiate({theta: self.angle})
        elif InSet(self.angle, RealNeg).proven():
            bound = sine_linear_bound_neg.instantiate({theta: self.angle})
        elif InSet(self.angle, RealNonNeg).proven():
            bound = sine_linear_bound_nonneg.instantiate({theta: self.angle})
        elif InSet(self.angle, RealNonPos).proven():
            bound = sine_linear_bound_nonpos.instantiate({theta: self.angle})
        else:
            _theta = Abs(self.angle)
            bound = sine_linear_bound.instantiate({theta: _theta})
        if bound.rhs == self:
            return bound.with_direction_reversed()
        return bound
示例#5
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'
示例#6
0
 def deduceInNumberSet(self, number_set, assumptions=USE_DEFAULTS):
     from proveit.number import Naturals, NaturalsPos
     from proveit.logic import InSet
     if number_set == Naturals:
         return self.deduceInNaturals()
     elif number_set == NaturalsPos:
         return self.deduceInNaturalsPos()
     else:
         try:
             # Do this to avoid infinite recursion -- if
             # we already know this numeral is in NaturalsPos
             # we should know how to prove that it is in any
             # number set that contains the naturals.
             if self.n > 0:
                 InSet(self, NaturalsPos).prove(automation=False)
             else:
                 InSet(self, Naturals).prove(automation=False)
         except:
             # Try to prove that it is in the given number
             # set after proving that the numeral is in
             # Naturals and NaturalsPos.
             self.deduceInNaturals()
             if self.n > 0:
                 self.deduceInNaturalsPos()
         return InSet(self, number_set).conclude(assumptions)
示例#7
0
 def explicitConditions(self):
     '''
     Return the conditions that are to be shown explicitly in the formatting
     (after the "such that" symbol "|") at this level according to the style.
     By default, this includes all of the 'joined' conditions except 
     implicit 'domain' conditions.
     '''
     from proveit.logic import InSet
     if hasattr(self, 'domains'):
         assert len(self.conditions) > len(
             self.domains), 'expecting a condition for each domain'
         for condition, domain in zip(self.conditions, self.domains):
             assert condition == InSet(self.instanceVar, domain)
         return self.conditions[len(self.domains):]  # skip the domains
     else:
         explicit_domains = self.explicitDomains()
         conditions = []
         for expr in self.joinedNestings():
             if len(explicit_domains) == 0:
                 conditions.extend(expr.conditions)
             else:
                 assert expr.conditions[0] == InSet(expr.instanceVar,
                                                    expr.domain)
                 conditions.extend(expr.conditions[1:])
         return conditions
示例#8
0
 def deduce_in_number_set(self, number_set, assumptions=USE_DEFAULTS):
     from proveit.numbers import Natural, NaturalPos, Digits
     from proveit.logic import InSet
     if number_set == Natural:
         return self.deduce_in_natural(assumptions)
     elif number_set == NaturalPos:
         return self.deduce_in_natural_pos(assumptions)
     elif number_set == Digits:
         return self.deduce_in_digits(assumptions)
     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)
         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.
             self.deduce_in_natural()
             if self.n > 0:
                 self.deduce_in_natural_pos()
         return InSet(self, number_set).conclude(assumptions)
示例#9
0
    def derive_element_in_restricted_number_set(self, **defaults_config):
        '''
        From (member in Interval(x, y)), where x ≥ 0 or y ≤ 0,
        deduce that the element is in Natural, NaturalPos, IntegerNeg,
        or IntegerNonPos as appropriate.
        '''
        _a = self.domain.lower_bound
        _b = self.domain.upper_bound
        _n = self.element

        # We wish to deduce a fact based upon the following
        # membership fact:
        self.expr.prove()

        if (not InSet(_a, Natural).proven()
                and not InSet(_b, IntegerNonPos).proven()):
            # If we don't know that a ≥ 0 or b ≤ 0, we can't prove
            # the element is in either restricted number set
            # (NaturalPos or IntegerNeg).  So, try to sort a, b, 0
            # to work this out.
            LessEq.sort([_a, _b, zero])

        if InSet(_a, Natural).proven():
            try:
                _a.deduce_in_number_set(NaturalPos, automation=False)
            except Exception:
                pass
            if InSet(_a, NaturalPos).proven():
                # member in N^{>0}
                lower_bounding = self.derive_element_lower_bound()
                a_bounding = greater(_a, zero)
                lower_bounding.apply_transitivity(a_bounding)
                return InSet(_n, NaturalPos).prove()
            else:
                # member in N
                lower_bounding = self.derive_element_lower_bound()
                a_bounding = greater_eq(_a, zero)
                lower_bounding.apply_transitivity(a_bounding)
                return InSet(_n, Natural).prove()
        if InSet(_b, IntegerNonPos).proven():
            try:
                _b.deduce_in_number_set(IntegerNeg, automation=False)
            except Exception:
                pass
            if InSet(_b, IntegerNeg).proven():
                # member in Z^{<0}
                upper_bounding = self.derive_element_upper_bound()
                b_bounding = Less(_b, zero)
                upper_bounding.apply_transitivity(b_bounding)
                return InSet(_n, IntegerNeg).prove()
            else:
                # member in Z^{≤0}
                upper_bounding = self.derive_element_upper_bound()
                b_bounding = LessEq(_b, zero)
                upper_bounding.apply_transitivity(b_bounding)
                return InSet(_n, IntegerNonPos).prove()
示例#10
0
 def deduce_in_number_set(self, number_set, **defaults_config):
     interval_membership = self.deduce_in_interval()
     if isinstance(number_set, Interval):
         if number_set == interval_membership.domain:
             return interval_membership
         return number_set.deduce_elem_in_set(self)
     if InSet(self, number_set).proven():
         # proven as a side-effect
         return InSet(self, number_set).prove()
     raise NotImplementedError("Proving %s in %s has not been implemented" %
                               (self, number_set))
示例#11
0
def deduce_as_mon_dec_func(fxn, *, domain=None, **defaults_config):
    '''
    Prove that the Lambda-map specified by fxn is contained in the
    set of monotonically-decreasing functions defined over the domain.
    For example, we might have fxn = Lambda(x, 1/x^2) and
    domain = RealPos, in which case we try to prove that
    Lambda(x, 1/x^2) is in the set of MonDecFuncs(RealPos).
    '''
    membership = None

    if domain is not None and InSet(fxn, MonDecFuncs(domain)).proven():
        # fxn already known to be a monotonically-decreasing function.
        return InSet(fxn, MonDecFuncs(domain)).prove()
    
    if hasattr(fxn, 'deduce_as_mon_dec_func'):
        # If there is a 'deduce_as_mon_dec_func' class method for the
        # fxn, try that.
        membership = fxn.deduce_as_mon_dec_func()

    # in the original VecSpaces.deduce_as_vec_space(), the following
    # checked for proper class membership before returning the
    # the membership; instead we are dealing with a set membership
    # and temporarily achieve this check manually further below
    # if membership is not None:
    #     InClass.check_proven_class_membership(
    #             membership, expr, VecSpaces)
    #     if field is not None and membership.domain.field != field:
    #         raise ValueError("'deduce_as_vec_space' proved membership in "
    #                          "vector spaces over %s, not over the requested "
    #                          "%s field"%(membership.domain.field, field))

    # def check_proven_class_membership(membership, element, class_of_class):
    #     if (not isinstance(membership, Judgment)
    #             or not isinstance(membership.expr, InClass)
    #             or membership.element != element
    #             or not isinstance(membership.domain, class_of_class)):
    #         raise ValueError(
    #                 "Failed to meet expectation: %s is supposed to be a "
    #                 "proven Judgment that %s is a member of a class "
    #                 "represented by an Expression of type %s"
    #                 %(membership, element, class_of_class)) 
    
    if membership is not None:
        if (not isinstance(membership, Judgment)
            or not isinstance(membership.expr, InSet)
            or membership.element != fxn
            or not isinstance(membership.domain, MonDecFuncs)):
            raise ValueError(
                    "Failed ... with message to be completed!")
        return membership

    raise NotImplementedError(
            "'deduce_as_mon_dec_func' is not implemented for this case")
示例#12
0
    def deduceInNumberSet(self, number_set, assumptions=USE_DEFAULTS):
        '''
        Given a number set number_set (such as Integers, Reals, etc),
        attempt to prove that the given expression is in that number
        set using the appropriate closure theorem.
        '''
        from proveit.number.absolute_value._theorems_ import (
            absComplexClosure, absNonzeroClosure, absComplexClosureNonNegReals)
        from proveit.number import Complexes, Reals, RealsNonNeg, RealsPos

        # among other things, make sure non-existent assumptions
        # manifest as empty tuple () rather than None
        assumptions = defaults.checkedAssumptions(assumptions)

        if number_set == Reals:
            return absComplexClosure.specialize({a: self.operand},
                                                assumptions=assumptions)

        if number_set == RealsPos:
            return absNonzeroClosure.specialize({a: self.operand},
                                                assumptions=assumptions)

        if number_set == RealsNonNeg:
            return absComplexClosureNonNegReals.specialize(
                {a: self.operand}, assumptions=assumptions)

        # To be thorough and a little more general, we check if the
        # specified number_set is already proven to *contain* one of
        # the number sets we have theorems for -- for example,
        #     Y=Complexes contain X=Reals, and
        #     Y=(-1, inf) contains X=RealsPos,
        # but we don't have specific thms for those supersets Y.
        # If so, use the appropiate thm to determine that self is in X,
        # then prove that self must also be in Y since Y contains X.
        if Subset(Reals, number_set).proven(assumptions=assumptions):
            absComplexClosure.specialize({a: self.operand},
                                         assumptions=assumptions)
            return InSet(self, number_set).prove(assumptions=assumptions)
        if Subset(RealsPos, number_set).proven(assumptions=assumptions):
            absNonzeroClosure.specialize({a: self.operand},
                                         assumptions=assumptions)
            return InSet(self, number_set).prove(assumptions=assumptions)
        if Subset(RealsNonNeg, number_set).proven(assumptions=assumptions):
            absComplexClosureNonNegReals.specialize({a: self.operand},
                                                    assumptions=assumptions)
            return InSet(self, number_set).prove(assumptions=assumptions)

        # otherwise, we just don't have the right thm to make it work
        msg = ("'Abs.deduceInNumberSet()' not implemented for "
               "the %s set" % str(number_set))
        raise ProofFailure(InSet(self, number_set), assumptions, msg)
示例#13
0
 def side_effects(self, judgment):
     '''
     Yield some possible side effects of real IntervalXX set
     nonmembership:
     (1) If element is real, deduce some possible bounds on it;
     (2) Deduce that the nonmembership claim is Boolean
     '''
     _a = self.domain.lower_bound
     _b = self.domain.upper_bound
     _x = self.element
     if ((InSet(_a, Real)).proven() and
        (InSet(_b, Real)).proven() and
        (InSet(_x, Real)).proven()):
         yield self.deduce_real_element_bounds
示例#14
0
 def deduce_in_vec_space(self, vec_space=None, *, field, **defaults_config):
     '''
     Prove that this Qmult is in a vector space (e.g., if it is
     a ket).
     '''
     from proveit.physics.quantum import QmultCodomain
     # In the process of proving that 'self' is in QmultCodomain,
     # it will prove it is a vector in a Hilbert space if
     # appropriate.
     QmultCodomain.membership_object(self).conclude()
     if vec_space is not None:
         return InSet(self, vec_space).prove()
     return InSet(self, VecSpaces.known_vec_space(self,
                                                  field=field)).prove()
示例#15
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)
示例#16
0
def deduce_in_number_set(expr, number_set, **defaults_config):
    '''
    Prove that 'expr' is an Expression that respresents a number
    in the given 'number_set'.
    '''
    from proveit.logic import InSet
    membership = InSet(expr, number_set)
    if membership.proven():
        # Already proven. We're done.
        return membership.prove()
    if hasattr(expr, 'deduce_in_number_set'):
        # Use 'deduce_in_number_set' method.
        return expr.deduce_in_number_set(number_set)
    # Try prove().
    return membership.prove()
示例#17
0
    def derive_quantification(self, instance_param=None, **defaults_config):
        '''
        From P(i) and ... and P(j), represented as a single ExprRange
        in a conjunction, prove 
        forall_{k in {i .. j}} P(k).
        If 'instance_param' is provided, use it as the 'k' parameter.
        Otherwise, use the parameter of the ExprRange.
        '''
        from proveit import ExprRange
        from proveit.logic import InSet
        from proveit.numbers import Interval
        from . import quantification_from_conjunction
        if (self.operands.num_entries() != 1
                or not isinstance(self.operands[0], ExprRange)):
            raise ValueError("'derive_quantification' may only be used "
                             "on a conjunction with a single ExprRange "
                             "operand entry.")
        expr_range = self.operands[0]
        _i = expr_range.true_start_index
        _j = expr_range.true_end_index
        _k = expr_range.parameter if instance_param is None else instance_param
        _P = expr_range.lambda_map
        proven_quantification = quantification_from_conjunction.instantiate(
            {
                i: _i,
                j: _j,
                k: _k,
                P: _P
            }, preserve_expr=self).derive_consequent()

        if defaults.automation:
            # While we are at it, as an "unofficial" side-effect,
            # let's instantatiate forall_{k in {i .. j}} P(k) to derive
            # {k in {i .. j}} |- P(k)
            # and induce side-effects for P(k).
            assumptions = defaults.assumptions + (InSet(_k, Interval(_i,
                                                                     _j)), )
            proven_quantification.instantiate(assumptions=assumptions)
            # We'll do it with the canonical variable as well for good
            # measure, if it is any different.
            canonical_version = proven_quantification.canonical_version()
            if canonical_version._style_id != proven_quantification._style_id:
                _k = canonical_version.instance_var
                assumptions = defaults.assumptions + (InSet(
                    _k, Interval(_i, _j)), )
                canonical_version.instantiate(assumptions=assumptions)

        return proven_quantification
示例#18
0
 def generalize(self, forallVars, domain=None, conditions=tuple()):
     r'''
     This makes a generalization of this expression, prepending Forall
     operations according to newForallVars and newConditions and/or newDomain
     that will bind 'arbitrary' free variables.  This overrides the expr
     version to absorb antecedent into conditions if they match.  For example,
     :math:`[A(x) \Rightarrow [B(x, y) \Rightarrow P(x, y)]]` generalized
     forall :math:`x, y` such that :math:`A(x), B(x, y)`
     becomes :math:`\forall_{x, y | A(x), B(x, y)} P(x, y)`,
     '''
     from proveit.logic import InSet
     hypothesizedConditions = set()
     conditionsSet = set(compositeExpression(conditions))
     if domain is not None:
         # add in the effective conditions from the domain
         for var in compositeExpression(forallVars):
             conditionsSet.add(InSet(var, domain))
     expr = self
     while isinstance(expr, Implies) and expr.antecedent in conditionsSet:
         hypothesizedConditions.add(expr.antecedent)
         expr = expr.consequent
     if len(hypothesizedConditions) == 0:
         # Just use the expr version
         return expr.generalize(self, forallVars, domain, conditions)
     return expr.generalize(expr, forallVars, domain, conditions)
示例#19
0
 def shallow_simplification(self, *, must_evaluate=False,
                            **defaults_config):
     '''
     Returns a proven simplification equation for this VecSum
     expression assuming the operands have been simplified.
     For the trivial case of summing over only one item (currently
     implemented just for a Interval where the endpoints are equal),
     derive and return this vector summation expression equated with
     the simplified form of the single term.
     Also reduce the VecSum to a number Sum if applicable.
     '''
     from proveit.numbers import Complex
     from . import vec_sum_single
     if (isinstance(self.domain,Interval) and
             self.domain.lower_bound == self.domain.upper_bound):
         # Reduce singular summation.
         if hasattr(self, 'index'):
             return vec_sum_single.instantiate(
                 {Function(v, self.index): self.summand,
                  a: self.domain.lower_bound})
     inner_assumptions = defaults.assumptions + self.conditions.entries
     if hasattr(self.summand, 'deduce_in_number_set'):
         # Maybe we can reduce the VecSum to a number Sum.
         self.summand.deduce_in_number_set(
                 Complex, assumptions=inner_assumptions)
     if InSet(self.summand, Complex).proven(assumptions=inner_assumptions):
         # If the operands are all complex numbers, this
         # VecAdd will reduce to number Add.
         return self.number_sum_reduction()
     return GroupSum.shallow_simplification(
             self, must_evaluate=must_evaluate)
示例#20
0
 def deduceInNumberSet(self, numberSet, assumptions=USE_DEFAULTS):
     from ._theorems_ import summationNatsClosure, summationIntsClosure, summationRealsClosure, summationComplexesClosure
     P_op, P_op_sub = Operation(P, self.instanceVars), self.instanceExpr
     Q_op, Q_op_sub = Operation(Qmulti, self.instanceVars), self.conditions
     Operation(P, self.instanceVars)
     self.summand
     if numberSet == Naturals:
         thm = summationNatsClosure
     elif numberSet == Integers:
         thm = summationIntsClosure
     elif numberSet == Reals:
         thm = summationRealsClosure
     elif numberSet == Complexes:
         thm = summationComplexesClosure
     else:
         raise ProofFailure(
             InSet(self, numberSet), assumptions,
             "'deduceInNumberSet' not implemented for the %s set" %
             str(numberSet))
     return thm.specialize(
         {
             P_op: P_op_sub,
             S: self.domain,
             Q_op: Q_op_sub
         },
         relabelMap={
             xMulti: self.instanceVars
         },
         assumptions=assumptions).deriveConsequent(assumptions=assumptions)
示例#21
0
 def side_effects(self, judgment):
     '''
     Yield some possible side effects of Interval set nonmembership:
     (1) if element is an integer, deduce some possible bounds on it;
     '''
     if InSet(self.element, Integer).proven():
         yield self.deduce_int_element_bounds
示例#22
0
 def double_scaling_reduction(self, **defaults_config):
     from . import doubly_scaled_as_singly_scaled
     if not isinstance(self.scaled, ScalarMult):
         raise ValueError("'double_scaling_reduction' is only applicable "
                          "for a doubly nested ScalarMult")
     # Reduce doubly-nested ScalarMult
     _x = self.scaled.scaled
     # _V = VecSpaces.known_vec_space(_x)
     # the following is a little klunky, but trying to avoid the
     # use of a default field=Real if we're actually dealing with
     # complex scalars somewhere in the vector
     from proveit import free_vars
     if any([InSet(elem, Complex).proven() for elem in free_vars(self)]):
         _V = VecSpaces.known_vec_space(self, field=Complex)
     else:
         _V = VecSpaces.known_vec_space(self)
     _K = VecSpaces.known_field(_V)
     _alpha = self.scalar
     _beta = self.scaled.scalar
     return doubly_scaled_as_singly_scaled.instantiate({
         K: _K,
         V: _V,
         x: _x,
         alpha: _alpha,
         beta: _beta
     })
示例#23
0
def rounding_deduce_in_number_set(expr,
                                  number_set,
                                  rounding_real_closure_thm,
                                  rounding_real_pos_closure_thm,
                                  assumptions=USE_DEFAULTS):
    '''
    Given a number set number_set, attempt to prove that the given
    Ceil, Floor, or Round expression is in that number set using
    the appropriate closure theorem.
    '''
    from proveit import ProofFailure
    from proveit import x
    from proveit.logic import InSet
    from proveit.numbers import Integer, Natural

    # among other things, convert any assumptions=None
    # to assumptions=()
    assumptions = defaults.checked_assumptions(assumptions)

    if number_set == Integer:
        return rounding_real_closure_thm.instantiate({x: expr.operand},
                                                     assumptions=assumptions)

    if number_set == Natural:
        return rounding_real_pos_closure_thm.instantiate(
            {x: expr.operand}, assumptions=assumptions)

    msg = ("The rounding_methods.py function "
           "'rounding_deduce_in_number_set()' is not implemented for the "
           "%s set" % str(number_set))
    raise ProofFailure(InSet(expr, number_set), assumptions, msg)
示例#24
0
 def deduce_in_number_set(self, number_set, assumptions=USE_DEFAULTS):
     from . import (summation_nat_closure, summation_int_closure,
                    summation_real_closure, summation_complex_closure)
     _x = self.instance_param
     P_op, _P_op = Function(P, _x), self.instance_expr
     Q_op, _Q_op = Function(Q, _x), self.condition
     self.summand
     if number_set == Natural:
         thm = summation_nat_closure
     elif number_set == Integer:
         thm = summation_int_closure
     elif number_set == Real:
         thm = summation_real_closure
     elif number_set == Complex:
         thm = summation_complex_closure
     else:
         raise ProofFailure(
             InSet(self, number_set), assumptions,
             ("'deduce_in_number_set' not implemented for the %s set" %
              str(number_set)))
     impl = thm.instantiate({
         x: _x,
         P_op: _P_op,
         Q_op: _Q_op
     },
                            assumptions=assumptions)
     return impl.derive_consequent(assumptions=assumptions)
示例#25
0
 def conclude(self, assumptions=USE_DEFAULTS):
     '''
     Attempt to conclude that the element is in the exponentiated set.
     '''
     from proveit.logic import InSet
     from proveit.logic.sets.membership import (exp_set_0, exp_set_1,
                                                exp_set_2, exp_set_3,
                                                exp_set_4, exp_set_5,
                                                exp_set_6, exp_set_7,
                                                exp_set_8, exp_set_9)
     from proveit.numbers import zero, is_literal_int, DIGITS
     element = self.element
     domain = self.domain
     elem_in_set = InSet(element, domain)
     if not isinstance(element, ExprTuple):
         raise ProofFailure(
             elem_in_set, assumptions,
             "Can only automatically deduce membership in exponentiated "
             "sets for an element that is a list")
     exponent_eval = domain.exponent.evaluation(assumptions=assumptions)
     exponent = exponent_eval.rhs
     base = domain.base
     #print(exponent, base, exponent.as_int(),element, domain, len(element))
     if is_literal_int(exponent):
         if exponent == zero:
             return exp_set_0.instantiate({S: base},
                                          assumptions=assumptions)
         if element.num_entries() != exponent.as_int():
             raise ProofFailure(
                 elem_in_set, assumptions,
                 "Element not a member of the exponentiated set; "
                 "incorrect list length")
         elif exponent in DIGITS:
             # thm = forall_S forall_{a, b... in S} (a, b, ...) in S^n
             thm = locals()['exp_set_%d' % exponent.as_int()]
             expr_map = {S: base}  # S is the base
             # map a, b, ... to the elements of element.
             expr_map.update({
                 proveit.__getattr__(chr(ord('a') + k)): elem_k
                 for k, elem_k in enumerate(element)
             })
             elem_in_set = thm.instantiate(expr_map,
                                           assumptions=assumptions)
         else:
             raise ProofFailure(
                 elem_in_set, assumptions,
                 "Automatic deduction of membership in exponentiated sets "
                 "is not supported beyond an exponent of 9")
     else:
         raise ProofFailure(
             elem_in_set, assumptions,
             "Automatic deduction of membership in exponentiated sets is "
             "only supported for an exponent that is a literal integer")
     if exponent_eval.lhs != exponent_eval.rhs:
         # after proving that the element is in the set taken to
         # the evaluation of the exponent, substitute back in the
         # original exponent.
         return exponent_eval.sub_left_side_into(elem_in_set,
                                                 assumptions=assumptions)
     return elem_in_set
示例#26
0
    def deduce_in_number_set(self, number_set, assumptions=USE_DEFAULTS):
        '''
        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.logic import InSet
        from proveit.numbers.modular import (
            mod_int_closure, mod_int_to_nat_closure, mod_real_closure)
        from proveit.numbers import Integer, Natural, Real

        # among other things, make sure non-existent assumptions
        # manifest as empty tuple () rather than None
        assumptions = defaults.checked_assumptions(assumptions)

        if number_set == Integer:
            return mod_int_closure.instantiate(
                {a: self.dividend, b: self.divisor}, assumptions=assumptions)

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

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

        msg = ("'Mod.deduce_in_number_set()' not implemented for "
               "the %s set" % str(number_set))
        raise ProofFailure(InSet(self, number_set), assumptions, msg)
示例#27
0
 def conclude(self, **defaults_config):
     '''
     Conclude something of the form 
     a < b.
     '''
     from proveit.logic import InSet
     from proveit.numbers import Add, zero, RealPos, deduce_number_set
     from . import positive_if_real_pos
     if self.upper == zero:
         # Special case with upper bound of zero.
         from . import negative_if_real_neg
         concluded = negative_if_real_neg.instantiate({a: self.lower})
         return concluded
     if self.lower == zero:
         # Special case with lower bound of zero.
         deduce_number_set(self.upper)
         if InSet(self.upper, RealPos).proven():
             positive_if_real_pos.instantiate({a: self.upper})
     if ((isinstance(self.lower, Add)
          and self.upper in self.lower.terms.entries)
             or (isinstance(self.upper, Add)
                 and self.lower in self.upper.terms.entries)):
         try:
             # Conclude an sum is bounded by one of its terms.
             return self.conclude_as_bounded_by_term()
         except UnsatisfiedPrerequisites:
             # If prerequisites weren't satisfied to do this,
             # we can still try something else.
             pass
     return NumberOrderingRelation.conclude(self)
示例#28
0
    def deduceInNumberSet(self, number_set, assumptions=USE_DEFAULTS):
        '''
        Given a number set number_set (such as Integers, Reals, etc),
        attempt to prove that the given ModAbs expression is in that
        number set using the appropriate closure theorem.
        '''
        from proveit._common_ import a, b
        from proveit.logic import InSet
        from proveit.number.modular._theorems_ import (
                modAbsIntClosure, modAbsRealClosure)
        from proveit.number import Integers, Reals

        # among other things, make sure non-existent assumptions
        # manifest as empty tuple () rather than None
        assumptions = defaults.checkedAssumptions(assumptions)

        if number_set == Integers:
            return modAbsIntClosure.specialize(
                    {a:self.value, b:self.divisor}, assumptions=assumptions)

        if number_set == Reals:
            return modAbsRealClosure.specialize(
                    {a:self.value, b:self.divisor}, assumptions=assumptions)

        msg = ("'ModAbs.deduceInNumberSet()' not implemented for "
               "the %s set"%str(number_set))
        raise ProofFailure(InSet(self, number_set), assumptions, msg)
示例#29
0
def rounding_deduceInNumberSet(expr, number_set, roundingRealClosureThm,
                               roundingRealPosClosureThm,
                               assumptions=USE_DEFAULTS):
        '''
        Given a number set number_set, attempt to prove that the given
        Ceil, Floor, or Round expression is in that number set using
        the appropriate closure theorem.
        '''
        from proveit import ProofFailure
        from proveit._common_ import x
        from proveit.logic import InSet
        from proveit.number import Integers, Naturals

        # among other things, convert any assumptions=None
        # to assumptions=()
        assumptions = defaults.checkedAssumptions(assumptions)

        if number_set == Integers:
            return roundingRealClosureThm.specialize(
                        {x:expr.operand}, assumptions=assumptions)

        if number_set == Naturals:
            return roundingRealPosClosureThm.specialize(
                        {x:expr.operand}, assumptions=assumptions)

        msg = ("The rounding_methods.py function "
               "'rounding_deduceInNumberSet()' is not implemented for the "
               "%s set"%str(number_set))
        raise ProofFailure(InSet(expr, number_set), assumptions, msg)
示例#30
0
 def generalize(self, forall_vars, domain=None, conditions=tuple(), **defaults_config):
     r'''
     This makes a generalization of this expression, prepending Forall
     operations according to new_forall_vars and new_conditions and/or new_domain
     that will bind 'arbitrary' free variables.  This overrides the expr
     version to absorb antecedent into conditions if they match.  For example,
     [A(x) => [B(x, y) => P(x, y)]] generalized
     forall x, y such that A(x), B(x, y)
     becomes forall_{x, y | A(x), B(x, y)} P(x, y).
     '''
     from proveit.logic import InSet
     hypothesized_conditions = set()
     conditions_set = set(composite_expression(conditions))
     if domain is not None:
         # add in the effective conditions from the domain
         for var in composite_expression(forall_vars):
             conditions_set.add(InSet(var, domain))
     expr = self
     while isinstance(expr, Implies) and expr.antecedent in conditions_set:
         hypothesized_conditions.add(expr.antecedent)
         expr = expr.consequent
     if len(hypothesized_conditions) == 0:
         # Just use the expr version
         return expr.generalize(self, forall_vars, domain, conditions)
     return expr.generalize(expr, forall_vars, domain, conditions)