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)
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)