Exemple #1
0
    def __init__(self, indices, summand, domain, conditions=tuple()):
        r'''
        Sum summand over indices over domains.
        Arguments serve analogous roles to Forall arguments (found in basiclogic/booleans):
        indices: instance vars
        summand: instanceExpressions
        domains: conditions (except no longer optional)
        '''
        OperationOverInstances.__init__(self,
                                        Sum._operator_,
                                        indices,
                                        summand,
                                        domain=domain,
                                        conditions=conditions)
        if len(self.instanceVars) != 1:
            raise ValueError('Only one index allowed per integral!')

        self.indices = self.instanceVars
        self.summand = self.instanceExpr
        self.index = self.instanceVars[0]
        if isinstance(self.domain, RealInterval):
            raise ValueError(
                'Sum cannot sum over non-discrete set (e.g. Interval)')
        elif self.domain == Reals:
            raise ValueError('Sum cannot sum over Reals.')
        elif self.domain == Integers:
            self.domain = Interval(Neg(infinity), infinity)
        elif self.domain == Naturals:
            self.domain = Interval(zero, infinity)
Exemple #2
0
 def __init__(self,
              instanceVarOrVars,
              instanceElement,
              domain=None,
              domains=None,
              conditions=tuple()):
     '''
     Create an expression representing the set of all instanceElement for instanceVar(s) such that the conditions are satisfied:
     {instanceElement | conditions}_{instanceVar(s) \in S}
     '''
     # nestMultiIvars=False will ensure it does NOT treat multiple instance variables as
     # nested SetOfAll operations -- that would not make sense.
     # (unlike forall, exists, summation, and product where it does make sense).
     OperationOverInstances.__init__(self,
                                     SetOfAll._operator_,
                                     instanceVarOrVars,
                                     instanceElement,
                                     domain=domain,
                                     conditions=conditions,
                                     nestMultiIvars=False)
     self.instanceElement = self.instanceExpr
     if hasattr(self, 'instanceVar'):
         if not hasattr(self, 'domain'):
             raise ValueError("SetOfAll requires a domain")
     elif hasattr(self, 'instanceVars'):
         if not hasattr(self, 'domains') or None in self.domains:
             raise ValueError("SetOfAll requires a domain(s)")
     else:
         assert False, "Expecting either 'instanceVar' or 'instanceVars' to be set"
Exemple #3
0
 def __init__(self, instanceVar, instanceElement, domain, conditions=tuple()):
     '''
     Create an expression representing the set of all instanceElement for instanceVars such that the conditions are satisfied:
     {instanceElement | conditions}_{instanceVar \in S}
     '''
     OperationOverInstances.__init__(self, SetOfAll._operator_, instanceVar, instanceElement, domain=domain, conditions=conditions)
     self.instanceElement = self.instanceExpr
Exemple #4
0
 def __init__(self,
              indexOrIndices,
              summand,
              domain=None,
              domains=None,
              conditions=tuple(),
              _lambda_map=None):
     r'''
     Sum summand over indices over domains.
     Arguments serve analogous roles to Forall arguments (found in basiclogic/booleans):
     indices: instance vars
     summand: instanceExpressions
     domains: conditions (except no longer optional)
     '''
     # nestMultiIvars=True will cause it to treat multiple instance variables as nested Sum operations internally
     # and only join them together as a style consequence.
     OperationOverInstances.__init__(self,
                                     Sum._operator_,
                                     indexOrIndices,
                                     summand,
                                     domain=domain,
                                     domains=domains,
                                     conditions=conditions,
                                     nestMultiIvars=True,
                                     _lambda_map=_lambda_map)
     if hasattr(self, 'instanceVar'):
         self.index = self.instanceVar
     if hasattr(self, 'instanceVars'):
         self.indices = self.instanceVars
     self.summand = self.instanceExpr
     """
 def __init__(self,
              instance_param_or_params,
              instance_element,
              domain=None,
              *,
              domains=None,
              condition=None,
              conditions=None,
              _lambda_map=None):
     '''
     Create an expression representing the set of all
     instance_element for instance parameter(s) such that the conditions
     are satisfied:
     {instance_element | conditions}_{instance_param_or_params \in S}
     '''
     OperationOverInstances.__init__(self,
                                     SetOfAll._operator_,
                                     instance_param_or_params,
                                     instance_element,
                                     domain=domain,
                                     domains=domains,
                                     condition=condition,
                                     conditions=conditions,
                                     _lambda_map=_lambda_map)
     self.instance_element = self.instance_expr
     if hasattr(self, 'instance_param'):
         if not hasattr(self, 'domain'):
             raise ValueError("SetOfAll requires a domain")
     elif hasattr(self, 'instance_params'):
         if not hasattr(self, 'domains') or None in self.domains:
             raise ValueError("SetOfAll requires domains")
     else:
         assert False, (
             "Expecting either 'instance_param' or 'instance_params' "
             "to be set")
Exemple #6
0
 def __init__(self,
              instanceParamOrParams,
              instanceExpr,
              *,
              domain=None,
              domains=None,
              condition=None,
              conditions=None,
              _lambda_map=None):
     '''
     Create a exists (there exists) expression:
     exists_{instanceParamOrParams | conditions} instanceExpr
     This expresses that there exists a value of the instance parameters(s)
     for which the optional condition(s) is/are satisfied and the 
     instanceExpr is true.  The instance parameters(s) and condition(s) may 
     be singular or plural (iterable).
     '''
     OperationOverInstances.__init__(self,
                                     NotExists._operator_,
                                     instanceParamOrParams,
                                     instanceExpr,
                                     domain=domain,
                                     domains=domains,
                                     condition=condition,
                                     conditions=conditions,
                                     _lambda_map=_lambda_map)
Exemple #7
0
 def __init__(self,
              instanceParamOrParams,
              instanceExpr,
              *,
              domain=None,
              domains=None,
              condition=None,
              conditions=None,
              _lambda_map=None):
     '''
     Create a Forall expression:
     forall_{instanceParamOrParams | conditions} instanceExpr.
     This expresses that the instanceExpr is true for all values of the
     instance parameter(s) given that the optional condition(s) is/are
     satisfied.  The instance parameter(s) and condition(s)
     may be singular or plural (iterable).
     '''
     OperationOverInstances.__init__(self,
                                     Forall._operator_,
                                     instanceParamOrParams,
                                     instanceExpr,
                                     domain=domain,
                                     domains=domains,
                                     condition=condition,
                                     conditions=conditions,
                                     _lambda_map=_lambda_map)
Exemple #8
0
 def __init__(self,
              indexOrIndices,
              summand,
              *,
              domain=None,
              domains=None,
              condition=None,
              conditions=None,
              _lambda_map=None):
     r'''
     Sum summand over indices over domains.
     Arguments serve analogous roles to Forall arguments (found in basiclogic/booleans):
     indices: instance vars
     summand: instanceExpressions
     domains: conditions (except no longer optional)
     '''
     OperationOverInstances.__init__(self,
                                     Sum._operator_,
                                     indexOrIndices,
                                     summand,
                                     domain=domain,
                                     domains=domains,
                                     condition=condition,
                                     conditions=conditions,
                                     _lambda_map=_lambda_map)
     if hasattr(self, 'instanceVar'):
         self.index = self.instanceVar
     if hasattr(self, 'instanceVars'):
         self.indices = self.instanceVars
     self.summand = self.instanceExpr
     """
Exemple #9
0
 def __init__(self,
              instanceVarOrVars,
              instanceExpr,
              domain=None,
              domains=None,
              conditions=tuple(),
              _lambda_map=None):
     '''
     Create a exists (there exists) expression:
     exists_{instanceVars | conditions} instanceExpr
     This expresses that there exists a value of the instanceVar(s) for 
     which the optional condition(s) is/are satisfied and the instanceExpr
     is true.  The instanceVar(s) and condition(s) may be 
     singular or plural (iterable).
     '''
     # nestMultiIvars=True will cause it to treat multiple instance
     # variables as nested NotExists operations internally
     # and only join them together as a style consequence.
     OperationOverInstances.__init__(self,
                                     NotExists._operator_,
                                     instanceVarOrVars,
                                     instanceExpr,
                                     domain,
                                     domains,
                                     conditions,
                                     nestMultiIvars=True,
                                     _lambda_map=_lambda_map)
Exemple #10
0
 def __init__(self,
              index,
              integrand,
              domain,
              *,
              condition=None,
              conditions=None):
     r'''
     Integrates integrand over indices over domain.
     Arguments serve analogous roles to Forall arguments (found in basiclogic/booleans):
     index: single instance var
     integrand: instanceExpressions
     domains: conditions (except no longer optional)
     '''
     OperationOverInstances.__init__(self,
                                     Integrate._operator_,
                                     index,
                                     integrand,
                                     domain=domain,
                                     condition=condition,
                                     conditions=conditions)
     if len(self.instanceVars) != 1:
         raise ValueError('Only one index allowed per integral!')
     elif isinstance(self.domain, Interval):
         raise ValueError('Can\'t integrate over DiscreteContiguousSet!')
     elif self.domain == Reals:
         self.domain = IntervalCC(Neg(infinity), infinity)
     self.index = self.instanceVars[0]
     self.integrand = self.instanceExpr
Exemple #11
0
    def __init__(self, instanceVarOrVars, instanceExpr, domain=None, domains=None, conditions = tuple()):
        '''
        Create a Forall expression:
        forall_{instanceVars | conditions} instanceExpr.
        This expresses that the instanceExpr is true for all values of the instanceVar(s)
        given that the optional condition(s) is/are satisfied.  The instanceVar(s) and condition(s)
        may be singular or plural (iterable).
        '''

        OperationOverInstances.__init__(self, Forall._operator_, instanceVarOrVars, instanceExpr, domain, domains, conditions)
Exemple #12
0
 def __init__(self, indices, summand, domain, conditions=tuple()):
     r'''
     Sum summand over indices over domains.
     Arguments serve analogous roles to Forall arguments (found in basiclogic/booleans):
     indices: instance vars
     summand: instanceExpressions
     domains: conditions (except no longer optional)
     '''
     OperationOverInstances.__init__(self,
                                     Prod._operator_,
                                     indices,
                                     summand,
                                     domain=domain,
                                     conditions=conditions)
Exemple #13
0
 def __init__(self, instanceVarOrVars, instanceExpr, domain=None, domains=None, 
              conditions = tuple(), _lambda_map=None):
     '''
     Create a Forall expression:
     forall_{instanceVars | conditions} instanceExpr.
     This expresses that the instanceExpr is true for all values of the instanceVar(s)
     given that the optional condition(s) is/are satisfied.  The instanceVar(s) and condition(s)
     may be singular or plural (iterable).
     '''
     # nestMultiIvars=True will cause it to treat multiple instance 
     # variables as nested Forall operations internally
     # and only join them together as a style consequence.
     OperationOverInstances.__init__(self, Forall._operator_, instanceVarOrVars, 
                                     instanceExpr, domain, domains, conditions, 
                                     nestMultiIvars=True, _lambda_map=_lambda_map)
Exemple #14
0
 def _formatted(self, format_type, **kwargs):
     from proveit.numbers import Interval
     # MUST BE UPDATED TO DEAL WITH 'joining' NESTED LEVELS
     fence = kwargs['fence'] if 'fence' in kwargs else False
     if isinstance(self.domain, Interval):
         lower = self.domain.lower_bound.formatted(format_type)
         upper = self.domain.upper_bound.formatted(format_type)
         formatted_inner = self.operator.formatted(
             format_type) + r'_{' + self.index.formatted(
                 format_type) + '=' + lower + r'}' + r'^{' + upper + r'} '
         explicit_ivars = list(self.explicit_instance_vars())
         has_explicit_ivars = (len(explicit_ivars) > 0)
         explicit_conds = list(self.explicit_conditions())
         has_explicit_conds = (len(explicit_conds) > 0)
         if has_explicit_conds:
             if has_explicit_ivars:
                 formatted_inner += " | "
             formatted_inner += ', '.join(
                 condition.formatted(format_type)
                 for condition in explicit_conds)
         formatted_inner += self.summand.formatted(format_type, fence=True)
         return maybe_fenced(format_type, formatted_inner, fence=fence)
     else:
         return OperationOverInstances._formatted(self,
                                                  format_type,
                                                  fence=fence)
Exemple #15
0
 def __init__(self,
              instanceVarOrVars,
              instanceExpr,
              domain=None,
              domains=None,
              conditions=tuple()):
     '''
     Create a exists (there exists) expression:
     exists_{instanceVars | condition} instanceExpr
     This expresses that there exists a value of the instanceVar(s) for which the optional condition(s)
     is/are satisfied and the instanceExpr is true.  The instanceVar(s) and condition(s) may be 
     singular or plural (iterable).
     '''
     OperationOverInstances.__init__(self, Exists._operator_,
                                     instanceVarOrVars, instanceExpr,
                                     domain, domains, conditions)
Exemple #16
0
    def shallow_simplification(self,
                               *,
                               must_evaluate=False,
                               **defaults_config):
        '''
        From this forall statement, evaluate it to TRUE or FALSE if
        possible by calling the domain's forall_evaluation method
        '''
        from proveit.logic import EvaluationError
        if must_evaluate and not self.has_domain():
            # Cannot automatically evaluate a forall statement with
            # no domain.
            raise EvaluationError(self)

        if hasattr(self, 'instance_param'):
            if hasattr(self.domain, 'forall_evaluation'):
                # Use the domain's forall_evaluation method
                return self.domain.forall_evaluation(self)
        '''
        # Let's not do this fancy stuff just yet.
        # Evaluate an unbundled version
        unbundle_eq = self.unbundle_equality()
        return unbundle_eq.rhs.evaluation()
        '''
        if must_evaluate:
            raise EvaluationError(self)

        return OperationOverInstances.shallow_simplification(self)
Exemple #17
0
 def __init__(self, indices, summand, domain, conditions=tuple()):
     r'''
     Sum summand over indices over domains.
     Arguments serve analogous roles to Forall arguments (found in basiclogic/booleans):
     indices: instance vars
     summand: instanceExpressions
     domains: conditions (except no longer optional)
     '''
     # nestMultiIvars=True will cause it to treat multiple instance variables as nested Prod operations internally
     # and only join them together as a style consequence.
     OperationOverInstances.__init__(self,
                                     Prod._operator_,
                                     indices,
                                     summand,
                                     domain=domain,
                                     conditions=conditions,
                                     nestMultiIvars=True)
Exemple #18
0
 def extractInitArgValue(argName, operators, operands):
     '''
     Given a name of one of the arguments of the __init__ method,
     return the corresponding value contained in the 'operands'
     composite expression (i.e., the operands of a constructed operation).
     '''
     if argName == 'indexOrIndices':
         argName = 'instanceVarOrVars'
     elif argName == 'summand':
         argName = 'instanceExpr'
     return OperationOverInstances.extractInitArgValue(
         argName, operators, operands)
Exemple #19
0
    def __init__(self,
                 index_or_indices,
                 summand,
                 *,
                 domain=None,
                 domains=None,
                 condition=None,
                 conditions=None,
                 styles=None,
                 _lambda_map=None):
        r'''
        Sum summand over indices over domains.
        Arguments serve analogous roles to Forall arguments (found in
        basiclogic.booleanss):
        indices: instance vars
        summand: instance_expressions
        domains: conditions (except no longer optional)
        '''
        if (domains is not None):
            raise NotImplementedError("Sum class not yet implemented for "
                                      "multiple domains nor for multiple "
                                      "indices.")

        OperationOverInstances.__init__(self,
                                        Sum._operator_,
                                        index_or_indices,
                                        summand,
                                        domain=domain,
                                        domains=domains,
                                        condition=condition,
                                        conditions=conditions,
                                        styles=styles,
                                        _lambda_map=_lambda_map)
        if hasattr(self, 'instance_param'):
            self.index = self.instance_param
        if hasattr(self, 'instance_params'):
            self.indices = self.instance_params
        self.summand = self.instance_expr
        """
Exemple #20
0
 def _formatted(self, format_type, **kwargs):
     # MUST BE UPDATED TO DEAL WITH 'joining' NESTED LEVELS
     fence = kwargs['fence'] if 'fence' in kwargs else False
     explicit_conds = self.explicit_conditions()
     if isinstance(self.domain, Interval) and len(explicit_conds) == 0:
         formatted_operator = self.operator.formatted(format_type)
         formatted_index = self.index.formatted(format_type)
         formatted_lower = self.domain.lower_bound.formatted(format_type)
         formatted_upper = self.domain.upper_bound.formatted(format_type)
         formatted_summand = self.summand.formatted(format_type, fence=True)
         formatted_inner = "%s_{%s = %s}^{%s} %s" % (
             formatted_operator, formatted_index, formatted_lower,
             formatted_upper, formatted_summand)
         return maybe_fenced(format_type, formatted_inner, fence=fence)
     else:
         return OperationOverInstances._formatted(self,
                                                  format_type,
                                                  fence=fence)
Exemple #21
0
 def _formatted(self, formatType, **kwargs):
     # MUST BE UPDATED TO DEAL WITH 'joining' NESTED LEVELS
     fence = kwargs['fence'] if 'fence' in kwargs else False
     if isinstance(self.domain,Interval):
         lower = self.domain.lowerBound.formatted(formatType)
         upper = self.domain.upperBound.formatted(formatType)
         formattedInner = self.operator.formatted(formatType)+r'_{'+self.index.formatted(formatType)+'='+lower+r'}'+r'^{'+upper+r'} '
         explicitIvars = list(self.explicitInstanceVars())
         hasExplicitIvars = (len(explicitIvars) > 0)
         explicitConds = list(self.explicitConditions())
         hasExplicitConds = (len(explicitConds) > 0)
         if hasExplicitConds:
             if hasExplicitIvars: 
                 formattedInner += " | "
             formattedInner += ', '.join(condition.formatted(formatType) for condition in explicitConds) 
         formattedInner += self.summand.formatted(formatType, fence=fence) 
         return maybeFenced(formatType, formattedInner, fence=fence)
     else:
         return OperationOverInstances._formatted(self, formatType, fence)
Exemple #22
0
    def _formatted(self, format_type, **kwargs):
        # ACTUALLY, notice that the open-interval versions
        # probably lead to incorrect upper/lower bounds on the
        # formatted integrals. For example, an integral over the
        # open half-open interval (0, 1] would need to be formatted
        # or expressed as a limit as 'a' approaches 0 from the right
        # of the integral from 0 to 1.
        fence = kwargs['fence'] if 'fence' in kwargs else False
        if (isinstance(self.domain,IntervalCC) or
            isinstance(self.domain,IntervalCO) or
            isinstance(self.domain,IntervalOC) or
            isinstance(self.domain,IntervalOO)):

            lower = self.domain.lower_bound.formatted(format_type)
            upper = self.domain.upper_bound.formatted(format_type)
            formatted_inner = (
                    self.operator.formatted(format_type) +
                    r'_{' + lower + r'}' + r'^{' + upper + r'} ')
            explicit_ivars = list(self.explicit_instance_vars())
            has_explicit_ivars = (len(explicit_ivars) > 0)
            explicit_conds = list(self.explicit_conditions())
            has_explicit_conds = (len(explicit_conds) > 0)
            if has_explicit_conds:
                if has_explicit_ivars:
                    formatted_inner += " | "
                formatted_inner += ', '.join(condition.formatted(format_type)
                                             for condition in explicit_conds)
            formatted_inner += (
                    self.integrand.formatted(format_type, fence=fence) +
                    r'\,d' + self.index.formatted(format_type))

            # old/previous
            # return (self.operator.formatted(format_type) +
            #         r'_{' + lower + r'}' + r'^{' + upper + r'}' +
            #         self.integrand.formatted(format_type, fence=fence) +
            #         'd' + self.index.formatted(format_type))
            
            return maybe_fenced(format_type, formatted_inner, fence=fence)
        else:
            return OperationOverInstances._formatted(self, format_type,
                                                     fence=fence)
Exemple #23
0
 def extractInitArgValue(argName, operators, operands):
     '''
     Given a name of one of the arguments of the __init__ method,
     return the corresponding value contained in the 'operands'
     composite expression (i.e., the operands of a constructed operation).
     '''
     from proveit.logic import InSet
     if argName=='instanceElement':
         return operands.body # instance mapping
     elif argName=='instanceVar':
         return operands.parameter
     elif argName=='domain':
         # the first condition must be the domain condition
         domainCondition = operands.conditions[0]
         assert isinstance(domainCondition, InSet), "Expecting the first condition of a SetOfAll object to be the domain condition of type InSet"
         assert domainCondition.element==operands.parameter, "Expecting the first condition of a SetOfAll object to be the domain condition with the proper element"
         return domainCondition.domain
     elif argName=='conditions':
         return ExprList(*operands.conditions[1:]) # all except the domain condition
     else:
         return OperationOverInstances.extractInitArgValue(argName, operators, operands)
Exemple #24
0
 def _formatted(self, formatType, **kwargs):
     fence = kwargs['fence'] if 'fence' in kwargs else False
     if isinstance(self.domain, Interval):
         lower = self.domain.lowerBound.formatted(formatType)
         upper = self.domain.upperBound.formatted(formatType)
         formattedInner = self.operator.formatted(
             formatType) + r'_{' + self.index.formatted(
                 formatType) + '=' + lower + r'}' + r'^{' + upper + r'} '
         implicitIvars = self.implicitInstanceVars(formatType)
         hasExplicitIvars = (len(implicitIvars) < len(self.instanceVars))
         implicitConditions = self.implicitConditions(formatType)
         hasExplicitConditions = self.hasCondition() and (
             len(implicitConditions) < len(self.conditions))
         if hasExplicitConditions:
             if hasExplicitIvars:
                 formattedInner += " | "
             formattedInner += ', '.join(
                 condition.formatted(formatType)
                 for condition in self.conditions
                 if condition not in implicitConditions)
         formattedInner += self.summand.formatted(formatType, fence=fence)
         return maybeFenced(formatType, formattedInner, fence=fence)
     else:
         return OperationOverInstances._formatted(self, formatType, fence)
Exemple #25
0
    def substitute_instances(self, universality, **defaults_config):
        '''
        Derive from this Exists operation, Exists_{..x.. in S | ..Q(..x..)..} P(..x..),
        one that substitutes instance expressions given some
        universality = forall_{..x.. in S | P(..x..), ..Q(..x..)..} R(..x..).
                                            or forall_{..x.. in S | ..Q(..x..)..} P(..x..) = R(..x..).
        Either is allowed in the theory of the existential quantifier.
        Derive and return the following type of existential operation assuming universality:
        Exists_{..x.. in S | ..Q(..x..)..} R(..x..)
        Works also when there is no domain S and/or no conditions ..Q...
        '''
        raise NotImplementedError("Need to test/update")
        from . import existential_implication, no_domain_existential_implication
        from proveit import Etcetera
        from proveit.logic import Forall
        from proveit._generic_ import InstanceSubstitutionException
        if isinstance(universality, Judgment):
            universality = universality.expr
        if not isinstance(universality, Forall):
            raise InstanceSubstitutionException(
                "'universality' must be a forall expression", self,
                universality)

        if self.instance_expr in universality.conditions:
            # map from the forall instance variables to self's instance
            # variables
            i_var_substitutions = {
                forall_ivar: self_ivar
                for forall_ivar, self_ivar in zip(universality.instance_vars,
                                                  self.instance_vars)
            }
            first_condition = universality.conditions[0].substituted(
                i_var_substitutions)
            if first_condition != self.instance_expr:
                raise InstanceSubstitutionException(
                    "The first condition of the 'universality' must match the instance expression of the Exists operation having instances substituted",
                    self, universality)
            if (universality.instance_vars.num_entries() !=
                    self.instance_vars.num_entries()):
                raise InstanceSubstitutionException(
                    "'universality' must have the same number of variables as the Exists operation having instances substituted",
                    self, universality)
            if universality.domain != self.domain:
                raise InstanceSubstitutionException(
                    "'universality' must have the same domain as the Exists having instances substituted",
                    self, universality)
            if ExpressionList(universality.conditions[1:]).substituted(
                    i_var_substitutions) != self.conditions:
                raise InstanceSubstitutionException(
                    "'universality' must have the same conditions as the Exists operation having instances substituted, in addition to the Exists instance expression",
                    self, universality)
            _x = universality.instance_vars,
            _y = self.instance_params
            _P = Lambda(_y, self.instance_expr)
            _Q = Lambda(_y, self.condition)
            _R = Lambda(
                _y,
                universality.instance_expr.substituted(i_var_substitutions))
            _impl = existential_implication.instantiate({
                P: _P,
                Q: _Q,
                R: _R,
                S: self.domain,
                x: _x,
                y: _y,
                z: _y
            })
            return _impl.derive_consequent().derive_consequent()
        # Default to the OperationOverInstances version which works with
        # universally quantified equalities.
        return OperationOverInstances.substitute(self, universality)
Exemple #26
0
    def __init__(self, index_or_indices, integrand, *, domain=None,
                 domains=None, condition=None, conditions=None,
                 styles=None, _lambda_map=None):
        r'''
        Represents a definite integral of the integrand over the
        index_or_indices over the domain, with arguments serving
        roles analogous to those for Forall arguments (found in
        logic.booleans.quantification.universality) and Sum arguments
        (found in numbers.summation):
        index_or_indices: a single instance var such as x
        integrand       : instance expression
        domain          : conditions
        Despite the generality preserved for the arguments, such
        Integrate objects are currently defined only for a single
        index and over a single continuous interval domain defined
        by a numerical set (such as Real, RealPos, etc.) or real
        interval (using IntervalCC, IntervalCO, IntervalOC, or
        IntervalOO objects).
        '''

        # original
        # OperationOverInstances.__init__(
        #     self, Integrate._operator_, index, integrand,
        #     domain=domain, condition=condition, conditions=conditions,
        #     styles=styles)
        # new 20220111

        # If domain expressed as a special number set,
        # re-express domain as a continuous interval before
        # feeding as argument to OperationOverInstances.__init__().
        # if domain == Real:
        #     domain = IntervalOO(Neg(infinity), infinity)
        # elif domain == RealPos:
        #     domain = IntervalOO(zero, infinity)
        # elif domain == RealNonNeg:
        #     domain = IntervalCO(zero, infinity)
        # elif domain == RealNeg:
        #     domain = IntervalOO(Neg(infinity), zero)
        # elif domain == RealNonPos:
        #     domain = IntervalOC(Neg(infinity), zero)

        OperationOverInstances.__init__(
            self, Integrate._operator_, index_or_indices, integrand,
            domain=domain, domains=domains, condition=condition,
            conditions=conditions, styles=styles, _lambda_map=_lambda_map)
        # original
        # if len(self.instance_vars) != 1:
        #     raise ValueError('Only one index allowed per integral!')
        # elif isinstance(self.domain, Interval):
        #     raise ValueError('Can\'t integrate over DiscreteContiguousSet!')
        # elif self.domain == Real:
        #     self.domain = IntervalCC(Neg(infinity), infinity)
        # self.index = self.instance_vars[0]
        # self.integrand = self.instance_expr
        # new
        if hasattr(self, 'instance_param'):
            self.index = self.instance_param
        if hasattr(self, 'instance_params'):
            self.indices = self.instance_params
            if len(self.instance_params.entries) != 1:
                raise ValueError('Only one index allowed per integral!')
        if isinstance(self.domain, Interval):
            # elaborate this error message later
            raise ValueError('Can\'t integrate over DiscreteContiguousSet!')
        self.integrand = self.instance_expr
Exemple #27
0
    def substituteInstances(self, universality, assumptions=USE_DEFAULTS):
        '''
        Derive from this Exists operation, Exists_{..x.. in S | ..Q(..x..)..} P(..x..),
        one that substitutes instance expressions given some 
        universality = forall_{..x.. in S | P(..x..), ..Q(..x..)..} R(..x..).
                                            or forall_{..x.. in S | ..Q(..x..)..} P(..x..) = R(..x..).
        Either is allowed in the context of the existential quantifier.
        Derive and return the following type of existential operation assuming universality:
        Exists_{..x.. in S | ..Q(..x..)..} R(..x..)
        Works also when there is no domain S and/or no conditions ..Q...
        '''
        raise NotImplementedError("Need to update")
        from ._theorems_ import existentialImplication, noDomainExistentialImplication
        from proveit import Etcetera
        from proveit.logic import Forall
        from proveit._generic_ import InstanceSubstitutionException
        from proveit._common_ import n, Qmulti, xMulti, yMulti, zMulti, S
        if isinstance(universality, KnownTruth):
            universality = universality.expr
        if not isinstance(universality, Forall):
            raise InstanceSubstitutionException(
                "'universality' must be a forall expression", self,
                universality)

        if self.instanceExpr in universality.conditions:
            # map from the forall instance variables to self's instance variables
            iVarSubstitutions = {
                forallIvar: selfIvar
                for forallIvar, selfIvar in zip(universality.instanceVars,
                                                self.instanceVars)
            }
            firstCondition = universality.conditions[0].substituted(
                iVarSubstitutions)
            if firstCondition != self.instanceExpr:
                raise InstanceSubstitutionException(
                    "The first condition of the 'universality' must match the instance expression of the Exists operation having instances substituted",
                    self, universality)
            if len(universality.instanceVars) != len(self.instanceVars):
                raise InstanceSubstitutionException(
                    "'universality' must have the same number of variables as the Exists operation having instances substituted",
                    self, universality)
            if universality.domain != self.domain:
                raise InstanceSubstitutionException(
                    "'universality' must have the same domain as the Exists having instances substituted",
                    self, universality)
            if ExpressionList(universality.conditions[1:]).substituted(
                    iVarSubstitutions) != self.conditions:
                raise InstanceSubstitutionException(
                    "'universality' must have the same conditions as the Exists operation having instances substituted, in addition to the Exists instance expression",
                    self, universality)
            P_op, P_op_sub = Operation(P, self.instanceVars), self.instanceExpr
            Q_op, Q_op_sub = Operation(Qmulti,
                                       self.instanceVars), self.conditions
            R_op, R_op_sub = Operation(
                R, self.instanceVars), universality.instanceExpr.substituted(
                    iVarSubstitutions)
            if self.hasDomain():
                return existentialImplication.specialize({S:self.domain, P_op:P_op_sub, Q_op:Q_op_sub, R_op:R_op_sub}, \
                                                        relabelMap={xMulti:universality.instanceVars, yMulti:self.instanceVars, zMulti:self.instanceVars}, assumptions=assumptions).deriveConsequent(assumptions).deriveConsequent(assumptions)
            else:
                return noDomainExistentialImplication.specialize(
                    {
                        P_op: P_op_sub,
                        Q_op: Q_op_sub,
                        R_op: R_op_sub
                    },
                    relabelMap={
                        xMulti: universality.instanceVars,
                        yMulti: self.instanceVars,
                        zMulti: self.instanceVars
                    },
                    assumptions=assumptions).deriveConsequent(
                        assumptions).deriveConsequent(assumptions)
        # Default to the OperationOverInstances version which works with universally quantified equivalences.
        return OperationOverInstances.substitute(self,
                                                 universality,
                                                 assumptions=assumptions)