# Source code for sympy.assumptions.refine

from __future__ import print_function, division

from sympy.core import S, Add, Expr, Basic, Mul

[docs]def refine(expr, assumptions=True): """ Simplify an expression using assumptions. Gives the form of expr that would be obtained if symbols in it were replaced by explicit numerical expressions satisfying the assumptions. Examples ======== >>> from sympy import refine, sqrt, Q >>> from sympy.abc import x >>> refine(sqrt(x**2), Q.real(x)) Abs(x) >>> refine(sqrt(x**2), Q.positive(x)) x """ if not isinstance(expr, Basic): return expr if not expr.is_Atom: args = [refine(arg, assumptions) for arg in expr.args] # TODO: this will probably not work with Integral or Polynomial expr = expr.func(*args) if hasattr(expr, '_eval_refine'): ref_expr = expr._eval_refine(assumptions) if ref_expr is not None: return ref_expr name = expr.__class__.__name__ handler = handlers_dict.get(name, None) if handler is None: return expr new_expr = handler(expr, assumptions) if (new_expr is None) or (expr == new_expr): return expr if not isinstance(new_expr, Expr): return new_expr return refine(new_expr, assumptions)
[docs]def refine_abs(expr, assumptions): """ Handler for the absolute value. Examples ======== >>> from sympy import Symbol, Q, refine, Abs >>> from sympy.assumptions.refine import refine_abs >>> from sympy.abc import x >>> refine_abs(Abs(x), Q.real(x)) >>> refine_abs(Abs(x), Q.positive(x)) x >>> refine_abs(Abs(x), Q.negative(x)) -x """ from sympy.core.logic import fuzzy_not from sympy import Abs arg = expr.args[0] if ask(Q.real(arg), assumptions) and \ fuzzy_not(ask(Q.negative(arg), assumptions)): # if it's nonnegative return arg if ask(Q.negative(arg), assumptions): return -arg # arg is Mul if isinstance(arg, Mul): r = [refine(abs(a), assumptions) for a in arg.args] non_abs = [] in_abs = [] for i in r: if isinstance(i, Abs): in_abs.append(i.args[0]) else: non_abs.append(i) return Mul(*non_abs) * Abs(Mul(*in_abs))