def _lambdaExpr(lambdaMap, defaultGlobalReplSubExpr): from proveit._core_.expression.inner_expr import InnerExpr if isinstance(lambdaMap, InnerExpr): expr = lambdaMap.replMap() else: expr = lambdaMap if not isinstance(expr, Lambda): # as a default, do a global replacement return Lambda.globalRepl(expr, defaultGlobalReplSubExpr) return expr
def reduceOperands(innerExpr, inPlace=True, mustEvaluate=False, assumptions=USE_DEFAULTS): ''' Attempt to return an InnerExpr object that is provably equivalent to the given innerExpr but with simplified operands at the inner-expression level. If inPlace is True, the top-level expression must be a KnownTruth and the simplified KnownTruth is derived instead of an equivalence relation. If mustEvaluate is True, the simplified operands must be irreducible values (see isIrreducibleValue). ''' # Any of the operands that can be simplified must be replaced with their evaluation from proveit import InnerExpr assert isinstance( innerExpr, InnerExpr), "Expecting 'innerExpr' to be of type 'InnerExpr'" inner = innerExpr.exprHierarchy[-1] while True: allReduced = True for operand in inner.operands: if not mustEvaluate or not isIrreducibleValue(operand): # the operand is not an irreducible value so it must be evaluated operandEval = operand.evaluation( assumptions=assumptions ) if mustEvaluate else operand.simplification( assumptions=assumptions) if mustEvaluate and not isIrreducibleValue(operandEval.rhs): raise EvaluationError( 'Evaluations expected to be irreducible values') if operandEval.lhs != operandEval.rhs: # compose map to replace all instances of the operand within the inner expression lambdaMap = innerExpr.replMap().compose( Lambda.globalRepl(inner, operand)) # substitute in the evaluated value if inPlace: innerExpr = InnerExpr( operandEval.subRightSideInto(lambdaMap), innerExpr.innerExprPath) else: innerExpr = InnerExpr( operandEval.substitution(lambdaMap).rhs, innerExpr.innerExprPath) allReduced = False break # start over (there may have been multiple substitutions) if allReduced: return innerExpr inner = innerExpr.exprHierarchy[-1]
def _lambdaExpr(lambda_map, expr_being_replaced, assumptions=USE_DEFAULTS): from proveit import ExprRange, InnerExpr if isinstance(lambda_map, InnerExpr): lambda_map = lambda_map.repl_lambda() if not isinstance(lambda_map, Lambda): # as a default, do a global replacement lambda_map = Lambda.globalRepl(lambda_map, expr_being_replaced) if len(lambda_map.parameters) != 1: raise ValueError("When substituting, expecting a single " "'lambda_map' parameter entry which may " "be a single parameter or a range; got " "%s as 'lambda_map'" % lambda_map) if isinstance(lambda_map.parameters[0], ExprRange): from proveit.number import one if lambda_map.parameters[0].start_index != one: raise ValueError("When substituting a range, expecting " "the 'lambda_map' parameter range to " "have a starting index of 1; got " "%s as 'lambda_map'" % lambda_map) return lambda_map
def test(): substitution.specialize({fx:Not(x), x:a, y:b}, assumptions=[Equals(a, b)]) expr = Equals(a, Add(b, Frac(c, d), Exp(c, d))) gRepl = Lambda.globalRepl(expr, d) d_eq_y = Equals(d, y) d_eq_y.substitution(gRepl, assumptions=[d_eq_y]) d_eq_y.substitution(expr, assumptions=[d_eq_y]) d_eq_y.substitution(expr, assumptions=[d_eq_y]).proof() innerExpr = expr.innerExpr() innerExpr = innerExpr.rhs innerExpr = innerExpr.operands[1] innerExpr = innerExpr.denominator d_eq_y.substitution(innerExpr, assumptions=[d_eq_y]) d_eq_y.substitution(expr.innerExpr().rhs.operands[2].exponent, assumptions=[d_eq_y]) d_eq_y.subRightSideInto(gRepl, assumptions=[d_eq_y,expr]) d_eq_y.subRightSideInto(expr, assumptions=[d_eq_y,expr]) y_eq_d = Equals(y, d) y_eq_d.subLeftSideInto(gRepl, assumptions=[y_eq_d,expr]) y_eq_d.subLeftSideInto(expr, assumptions=[y_eq_d,expr]) y_eq_d.subLeftSideInto(expr, assumptions=[y_eq_d,expr]).proof()
def reduceOperands(innerExpr, inPlace=True, mustEvaluate=False, assumptions=USE_DEFAULTS): ''' Attempt to return an InnerExpr object that is provably equivalent to the given innerExpr but with simplified operands at the inner-expression level. If inPlace is True, the top-level expression must be a KnownTruth and the simplified KnownTruth is derived instead of an equivalence relation. If mustEvaluate is True, the simplified operands must be irreducible values (see isIrreducibleValue). ''' # Any of the operands that can be simplified must be replaced with # their simplification. from proveit import InnerExpr, ExprRange assert isinstance(innerExpr, InnerExpr), \ "Expecting 'innerExpr' to be of type 'InnerExpr'" inner = innerExpr.exprHierarchy[-1] substitutions = [] while True: allReduced = True for operand in inner.operands: if (not isIrreducibleValue(operand) and not isinstance(operand, ExprRange)): # The operand isn't already irreducible, so try to # simplify it. if mustEvaluate: operandEval = operand.evaluation(assumptions=assumptions) else: operandEval = operand.simplification( assumptions=assumptions) if mustEvaluate and not isIrreducibleValue(operandEval.rhs): msg = 'Evaluations expected to be irreducible values' raise EvaluationError(msg, assumptions) if operandEval.lhs != operandEval.rhs: # Compose map to replace all instances of the # operand within the inner expression. global_repl = Lambda.globalRepl(inner, operand) lambdaMap = innerExpr.repl_lambda().compose(global_repl) # substitute in the evaluated value if inPlace: subbed = operandEval.subRightSideInto(lambdaMap) innerExpr = InnerExpr(subbed, innerExpr.innerExprPath) else: sub = operandEval.substitution(lambdaMap) innerExpr = InnerExpr(sub.rhs, innerExpr.innerExprPath) substitutions.append(sub) allReduced = False # Start over since there may have been multiple # substitutions: break if allReduced: break # done! inner = innerExpr.exprHierarchy[-1] if not inPlace and len(substitutions) > 1: # When there have been multiple substitutions, apply # transtivity over the chain of substitutions to equate the # end-points. Equals.applyTransitivities(substitutions, assumptions) return innerExpr