예제 #1
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)
예제 #2
0
    def generalize(self,
                   forallVarLists,
                   domainLists=None,
                   domain=None,
                   conditions=tuple()):
        '''
        Performs a generalization derivation step.  Returns the
        proven generalized KnownTruth.  Can introduce any number of
        nested Forall operations to wrap the original statement,
        corresponding to the number of given forallVarLists and domains.
        A single variable list or single variable and a single domain may 
        be provided to introduce a single Forall wrapper.
        '''
        from proveit._core_.proof import Generalization
        from proveit import Variable, compositeExpression
        from proveit.logic import InSet

        if isinstance(forallVarLists, Variable):
            forallVarLists = [[
                forallVarLists
            ]]  # a single Variable to convert into a list of variable lists
        else:
            if not hasattr(forallVarLists, '__len__'):
                raise ValueError(
                    "Must supply 'generalize' with a Variable, list of Variables, or list of Variable lists."
                )
            if len(forallVarLists) == 0:
                raise ValueError(
                    "Must provide at least one Variable to generalize over")
            if all(isinstance(x, Variable) for x in forallVarLists):
                # convert a list of Variable/MultiVariables to a list of lists
                forallVarLists = [forallVarLists]

        # Add domain conditions as appropriate
        if domain is not None and domainLists is not None:
            raise ValueError(
                "Either specify a 'domain' or a list of 'domainLists' but not both"
            )
        if domain is not None:
            domainLists = [[domain] * len(forallVarList)
                           for forallVarList in forallVarLists]
        if domainLists is not None:
            domainConditions = []
            for domainList, forallVarList in zip(domainLists, forallVarLists):
                domainList = compositeExpression(domainList)
                if len(domainList) == 1:
                    domainList = [domainList[0]] * len(forallVarList)
                domainConditions += [
                    InSet(instanceVar, domain)
                    for instanceVar, domain in zip(forallVarList, domainList)
                ]
            conditions = domainConditions + list(conditions)

        return self._checkedTruth(
            Generalization(self, forallVarLists, conditions))
예제 #3
0
 def has_matching_ranges(self, other_tuple):
     '''
     Return True iff the `other_tuple` matches this ExprTuple
     with respect to which entries are ExprRanges and, where they
     are, the start and end indices of the ExprRanges match.
     '''
     from proveit import ExprRange, compositeExpression
     if not isinstance(other_tuple, ExprTuple):
         other_tuple = compositeExpression(other_tuple)
     if len(self) != len(other_tuple):
         return False  # don't have the same number of entries
     for entry, other_entry in zip(self, other_tuple):
         if (isinstance(entry, ExprRange) != isinstance(
                 other_entry, ExprRange)):
             return False  # range vs singular mismatch
         if isinstance(entry, ExprRange):
             if entry.start_index != other_entry.start_index:
                 return False  # start indices don't match
             if entry.end_index != other_entry.end_index:
                 return False  # end indices don't match
     return True  # everything matches.