def __init__(self, implicationExpr, assumptions=None): from proveit.logic import Implies assumptions = defaults.checkedAssumptions(assumptions) prev_default_assumptions = defaults.assumptions defaults.assumptions = assumptions # these assumptions will be used for deriving any side-effects try: # obtain the implication and antecedent KnownTruths assert isinstance(implicationExpr, Implies) and len(implicationExpr.operands)==2, 'The implication of a modus ponens proof must refer to an Implies expression with two operands' try: # Must prove the implication under the given assumptions. # (if WILDCARD_ASSUMPTIONS is included, it will be proven by assumption if there isn't an existing proof otherwise) implicationTruth = implicationExpr.prove(assumptions) _appendExtraAssumptions(assumptions, implicationTruth) except: raise ModusPonensFailure(implicationExpr.operands[1], assumptions, 'Implication, %s, is not proven'%str(implicationExpr)) try: # Must prove the antecedent under the given assumptions. # (if WILDCARD_ASSUMPTIONS is included, it will be proven by assumption if there isn't an existing proof otherwise) antecedentTruth = implicationExpr.operands[0].prove(assumptions) _appendExtraAssumptions(assumptions, antecedentTruth) except: raise ModusPonensFailure(implicationExpr.operands[1], assumptions, 'Antecedent of %s is not proven'%str(implicationExpr)) # remove any unnecessary assumptions (but keep the order that was provided) assumptionsSet = implicationTruth.assumptionsSet | antecedentTruth.assumptionsSet assumptions = [assumption for assumption in assumptions if assumption in assumptionsSet] # we have what we need; set up the ModusPonens Proof consequentTruth = KnownTruth(implicationExpr.operands[1], assumptions, self) _checkImplication(implicationTruth.expr, antecedentTruth.expr, consequentTruth.expr) self.implicationTruth = implicationTruth self.antecedentTruth = antecedentTruth Proof.__init__(self, consequentTruth, [self.implicationTruth, self.antecedentTruth]) finally: # restore the original default assumptions defaults.assumptions = prev_default_assumptions
def __init__(self, expr, context, name): if not isinstance(context, Context): raise ValueError("An axiom 'context' must be a Context object") if not isinstance(name, str): raise ValueError("An axiom 'name' must be a string") self.context = context self.name = name Proof.__init__(self, KnownTruth(expr, expr.getRequirements(), self), [])
def __init__(self, instanceTruth, newForallVarLists, newConditions=tuple()): ''' A Generalization step wraps a KnownTruth (instanceTruth) in one or more Forall operations. The number of Forall operations introduced is the number of lists in newForallVarLists. The conditions are introduced in the order they are given at the outermost level that is n applicable. For example, if newForallVarLists is [[x, y], z] and the new conditions are f(x, y) and g(y, z) and h(z), this will prove a statement of the form: forall_{x, y in Integers | f(x, y)} forall_{z | g(y, z), h(z)} ... ''' from proveit import KnownTruth, Variable from proveit.logic import Forall if not isinstance(instanceTruth, KnownTruth): raise GeneralizationFailure(None, [], 'May only generalize a KnownTruth instance') # the assumptions required for the generalization are the assumptions of # the original KnownTruth minus the all of the new conditions (including those # implied by the new domain). assumptions = set(instanceTruth.assumptions) prev_default_assumptions = defaults.assumptions defaults.assumptions = assumptions # these assumptions will be used for deriving any side-effects try: remainingConditions = list(newConditions) expr = instanceTruth.expr introducedForallVars = set() for k, newForallVars in enumerate(reversed(newForallVarLists)): for forallVar in newForallVars: if not isinstance(forallVar, Variable): raise ValueError('Forall variables of a generalization must be Variable objects') introducedForallVars |= set(newForallVars) newConditions = [] if k == len(newForallVarLists)-1: # the final introduced Forall operation must use all of the remaining conditions newConditions = remainingConditions else: # use all applicable conditions in the supplied order conditionApplicability = [not remainingCondition.freeVars().isdisjoint(newForallVars) for remainingCondition in remainingConditions] newConditions = [remainingCondition for applicable, remainingCondition in zip(conditionApplicability, remainingConditions) if applicable] remainingConditions = [remainingCondition for applicable, remainingCondition in zip(conditionApplicability, remainingConditions) if not applicable] # new conditions can eliminate corresponding assumptions assumptions -= set(newConditions) # create the new generalized expression generalizedExpr = Forall(instanceVarOrVars=newForallVars, instanceExpr=expr, conditions=newConditions) # make sure this is a proper generalization that doesn't break the logic: Generalization._checkGeneralization(generalizedExpr, expr) expr = generalizedExpr for assumption in assumptions: if not assumption.freeVars().isdisjoint(introducedForallVars): raise GeneralizationFailure(generalizedExpr, assumptions, 'Cannot generalize using assumptions that involve any of the new forall variables (except as assumptions are eliminated via conditions or domains)') generalizedTruth = KnownTruth(generalizedExpr, assumptions, self) self.instanceTruth = instanceTruth self.newForallVars = newForallVars self.newConditions = newConditions Proof.__init__(self, generalizedTruth, [self.instanceTruth]) finally: # restore the original default assumptions defaults.assumptions = prev_default_assumptions
def __init__(self, consequentTruth, antecedentExpr): from proveit.logic import Implies assumptions = [assumption for assumption in consequentTruth.assumptions if assumption != antecedentExpr] prev_default_assumptions = defaults.assumptions defaults.assumptions = assumptions # these assumptions will be used for deriving any side-effects try: implicationExpr = Implies(antecedentExpr, consequentTruth.expr) implicationTruth = KnownTruth(implicationExpr, assumptions, self) self.consequentTruth = consequentTruth Proof.__init__(self, implicationTruth, [self.consequentTruth]) finally: # restore the original default assumptions defaults.assumptions = prev_default_assumptions
def __init__(self, expr, context, name): if not isinstance(context, Context): raise ValueError("A theorem 'package' must be a Context object") if not isinstance(name, str): raise ValueError("A theorem 'name' must be a string") self.context = context self.name = name # keep track of proofs that may be used to prove the theorem # before 'beginProof' is called so we will have the proof handy. self._possibleProofs = [] # Note that _setUsability will be called within Proof.__init__ Proof.__init__(self, KnownTruth(expr, frozenset(), self), []) Theorem.allTheorems.append(self)
def __init__(self, expr, assumptions=None): assumptions = defaults.checkedAssumptions(assumptions) if expr not in assumptions: # an Assumption proof must assume itself; that's what it does. assumptions = assumptions + (expr,) prev_default_assumptions = defaults.assumptions defaults.assumptions = assumptions # these assumptions will be used for deriving any side-effects try: Proof.__init__(self, KnownTruth(expr, {expr}, self), []) finally: # restore the original default assumptions defaults.assumptions = prev_default_assumptions Assumption.allAssumptions[(expr, assumptions)] = self
def __init__(self, generalTruth, numForallEliminations, specializeMap=None, relabelMap=None, assumptions=USE_DEFAULTS): ''' Create the Specialization proof step that specializes the given general expression using the substitution map (subMap) under the given assumptions. Eliminates the number of nested Forall operations as indicated, substituting their instance variables according to subMap. The default for any unspecified instance variable is to specialize it to itself, or, in the case of a bundled variable (Etcetera-wrapped MultiVariables), the default is to specialize it to an empty list. Substitution of variables that are not instance variables of the Forall operations being eliminated are to be relabeled. Relabeling is limited to substituting a Variable to another Variable or substituting a bundled variable to another bundled variable or list of variables (bundled or not). ''' assumptions = list(defaults.checkedAssumptions(assumptions)) prev_default_assumptions = defaults.assumptions defaults.assumptions = assumptions # these assumptions will be used for deriving any side-effects try: if relabelMap is None: relabelMap = dict() if specializeMap is None: specializeMap = dict() Failure = SpecializationFailure if numForallEliminations>0 else RelabelingFailure if not isinstance(generalTruth, KnownTruth): raise Failure(None, [], 'May only specialize/relabel a KnownTruth') if generalTruth.proof() is None: raise UnusableProof(KnownTruth.theoremBeingProven, generalTruth) if not generalTruth.assumptionsSet.issubset(assumptions): if '*' in assumptions: # if WILDCARD_ASSUMPTIONS is included, add any extra assumptions that are needed _appendExtraAssumptions(assumptions, generalTruth) else: raise Failure(None, [], 'Assumptions do not include the assumptions required by generalTruth') generalExpr = generalTruth.expr # perform the appropriate substitution/relabeling specializedExpr, requirements, mappedVarLists, mappings = Specialization._specialized_expr(generalExpr, numForallEliminations, specializeMap, relabelMap, assumptions) # obtain the KnownTruths for the substituted conditions requirementTruths = [] requirementTruthSet = set() # avoid repeats of requirements for requirementExpr in requirements: try: # each substituted condition must be proven under the assumptions # (if WILDCARD_ASSUMPTIONS is included, it will be proven by assumption if there isn't an existing proof otherwise) requirementTruth = requirementExpr.prove(assumptions) if requirementTruth not in requirementTruthSet: requirementTruths.append(requirementTruth) requirementTruthSet.add(requirementTruth) _appendExtraAssumptions(assumptions, requirementTruth) except: raise Failure(specializedExpr, assumptions, 'Unmet specialization requirement: ' + str(requirementExpr)) # remove any unnecessary assumptions (but keep the order that was provided) assumptionsSet = generalTruth.assumptionsSet for requirementTruth in requirementTruths: assumptionsSet |= requirementTruth.assumptionsSet assumptions = [assumption for assumption in assumptions if assumption in assumptionsSet] # we have what we need; set up the Specialization Proof self.generalTruth = generalTruth self.requirementTruths = requirementTruths self.mappedVarLists = mappedVarLists self.mappings = mappings specializedTruth = KnownTruth(specializedExpr, assumptions, self) Proof.__init__(self, specializedTruth, [generalTruth] + requirementTruths) finally: # restore the original default assumptions defaults.assumptions = prev_default_assumptions