def test_disjuncts(): A, B, C = symbols('ABC') assert disjuncts(A | B | C) == [A, B, C] assert disjuncts((A | B) & C) == [(A | B) & C] assert disjuncts(A) == [A] assert disjuncts(True) == [True] assert disjuncts(False) == [False]
def test_disjuncts(): A, B, C = map(Boolean, symbols("A,B,C")) assert disjuncts(A | B | C) == set([A, B, C]) assert disjuncts((A | B) & C) == set([(A | B) & C]) assert disjuncts(A) == set([A]) assert disjuncts(True) == set([True]) assert disjuncts(False) == set([False])
def test_disjuncts(): A, B, C = map(Boolean, symbols('A,B,C')) assert disjuncts(A | B | C) == set([A, B, C]) assert disjuncts((A | B) & C) == set([(A | B) & C]) assert disjuncts(A) == set([A]) assert disjuncts(True) == set([True]) assert disjuncts(False) == set([False])
def test_disjuncts(): A, B, C = map(Boolean, symbols('ABC')) assert set(disjuncts(A | B | C)) == set([A, B, C]) assert disjuncts((A | B) & C) == [(A | B) & C] assert disjuncts(A) == [A] assert disjuncts(True) == [True] assert disjuncts(False) == [False]
def find_pure_symbol(symbols, unknown_clauses): """Find a symbol and its value if it appears only as a positive literal (or only as a negative) in clauses. >>> from sympy import symbols >>> A, B, C = symbols('ABC') >>> find_pure_symbol([A, B, C], [A|~B,~B|~C,C|A]) (A, True) """ for sym in symbols: found_pos, found_neg = False, False for c in unknown_clauses: if not found_pos and sym in disjuncts(c): found_pos = True if not found_neg and Not(sym) in disjuncts(c): found_neg = True if found_pos != found_neg: return sym, found_pos return None, None
def process_conds(cond): """ Turn ``cond`` into a strip (a, b), and auxiliary conditions. """ a = -oo b = oo aux = True conds = conjuncts(to_cnf(cond)) t = Dummy('t', real=True) for c in conds: a_ = oo b_ = -oo aux_ = [] for d in disjuncts(c): d_ = d.replace(re, lambda x: x.as_real_imag()[0]).subs(re(s), t) if not d.is_Relational or (d.rel_op != '<' and d.rel_op != '<=') \ or d_.has(s) or not d_.has(t): aux_ += [d] continue soln = _solve_inequality(d_, t) if not soln.is_Relational or \ (soln.rel_op != '<' and soln.rel_op != '<='): aux_ += [d] continue if soln.lhs == t: b_ = Max(soln.rhs, b_) else: a_ = Min(soln.lhs, a_) if a_ != oo and a_ != b: a = Max(a_, a) elif b_ != -oo and b_ != a: b = Min(b_, b) else: aux = And(aux, Or(*aux_)) return a, b, aux
def get_gene_association_list(ga): gene_association = ga.replace('and', '&').replace('or', '|').replace('OR', '|') if not gene_association: return "" try: res = to_cnf(gene_association, False) gene_association = [[str(it) for it in disjuncts(cjs)] for cjs in conjuncts(res)] result = '''<table class="p_table" border="0" width="100%%"> <tr class="centre"><th colspan="%d" class="centre">Gene association</th></tr> <tr>''' % (2 * len(gene_association) - 1) first = True for genes in gene_association: if first: first = False else: result += '<td class="centre"><i>and</i></td>' result += '<td><table border="0">' if len(genes) > 1: result += "<tr><td class='centre'><i>(or)</i></td></tr>" for gene in genes: result += "<tr><td class='main'><a href=\'http://www.ncbi.nlm.nih.gov/gene/?term=%s[sym]\' target=\'_blank\'>%s</a></td></tr>" % ( gene, gene) result += '</table></td>' result += '</tr></table>' return result except: return ""
def _laplace_transform(f, t, s, simplify=True): """ The backend function for laplace transforms. """ from sympy import (re, Max, exp, pi, Abs, Min, periodic_argument as arg, cos, Wild, symbols) F = integrate(exp(-s * t) * f, (t, 0, oo)) if not F.has(Integral): return _simplify(F, simplify), -oo, True if not F.is_Piecewise: raise IntegralTransformError('Laplace', f, 'could not compute integral') F, cond = F.args[0] if F.has(Integral): raise IntegralTransformError('Laplace', f, 'integral in unexpected form') a = -oo aux = True conds = conjuncts(to_cnf(cond)) u = Dummy('u', real=True) p, q, w1, w2, w3 = symbols('p q w1 w2 w3', cls=Wild, exclude=[s]) for c in conds: a_ = oo aux_ = [] for d in disjuncts(c): m = d.match(abs(arg((s + w3)**p * q, w1)) < w2) if m: if m[q] > 0 and m[w2] / m[p] == pi / 2: d = re(s + m[w3]) > 0 m = d.match(0 < cos(abs(arg(s, q))) * abs(s) - p) if m: d = re(s) > m[p] d_ = d.replace(re, lambda x: x.expand().as_real_imag()[0]).subs( re(s), t) if not d.is_Relational or (d.rel_op != '<' and d.rel_op != '<=') \ or d_.has(s) or not d_.has(t): aux_ += [d] continue soln = _solve_inequality(d_, t) if not soln.is_Relational or \ (soln.rel_op != '<' and soln.rel_op != '<='): aux_ += [d] continue if soln.lhs == t: raise IntegralTransformError('Laplace', f, 'convergence not in half-plane?') else: a_ = Min(soln.lhs, a_) if a_ != oo: a = Max(a_, a) else: aux = And(aux, Or(*aux_)) return _simplify(F, simplify), a, aux
def find_pure_symbol(symbols, unknown_clauses): """ Find a symbol and its value if it appears only as a positive literal (or only as a negative) in clauses. >>> from sympy import symbols >>> from sympy.abc import A, B, D >>> from sympy.logic.algorithms.dpll import find_pure_symbol >>> find_pure_symbol([A, B, D], [A|~B,~B|~D,D|A]) (A, True) """ for sym in symbols: found_pos, found_neg = False, False for c in unknown_clauses: if not found_pos and sym in disjuncts(c): found_pos = True if not found_neg and Not(sym) in disjuncts(c): found_neg = True if found_pos != found_neg: return sym, found_pos return None, None
def _mellin_transform(f, x, s_, integrator=_default_integrator, simplify=True): """ Backend function to compute mellin transforms. """ from sympy import re, Max, Min # We use a fresh dummy, because assumptions on s might drop conditions on # convergence of the integral. s = _dummy('s', 'mellin-transform', f) F = integrator(x**(s - 1) * f, x) if not F.has(Integral): return _simplify(F.subs(s, s_), simplify), (-oo, oo), True if not F.is_Piecewise: raise IntegralTransformError('Mellin', f, 'could not compute integral') F, cond = F.args[0] if F.has(Integral): raise IntegralTransformError('Mellin', f, 'integral in unexpected form') a = -oo b = oo aux = True conds = conjuncts(to_cnf(cond)) t = Dummy('t', real=True) for c in conds: a_ = oo b_ = -oo aux_ = [] for d in disjuncts(c): d_ = d.replace(re, lambda x: x.as_real_imag()[0]).subs(re(s), t) if not d.is_Relational or (d.rel_op != '<' and d.rel_op != '<=') \ or d_.has(s) or not d_.has(t): aux_ += [d] continue soln = _solve_inequality(d_, t) if not soln.is_Relational or \ (soln.rel_op != '<' and soln.rel_op != '<='): aux_ += [d] continue if soln.lhs == t: b_ = Max(soln.rhs, b_) else: a_ = Min(soln.lhs, a_) if a_ != oo and a_ != b: a = Max(a_, a) elif b_ != -oo and b_ != a: b = Min(b_, b) else: aux = And(aux, Or(*aux_)) if aux is False: raise IntegralTransformError('Mellin', f, 'no convergence found') return _simplify(F.subs(s, s_), simplify), (a, b), aux
def process_conds(conds): """ Turn ``conds`` into a strip and auxiliary conditions. """ a = -oo aux = True conds = conjuncts(to_cnf(conds)) u = Dummy('u', real=True) p, q, w1, w2, w3, w4, w5 = symbols('p q w1 w2 w3 w4 w5', cls=Wild, exclude=[s]) for c in conds: a_ = oo aux_ = [] for d in disjuncts(c): m = d.match(abs(arg((s + w3)**p * q, w1)) < w2) if not m: m = d.match(abs(arg((s + w3)**p * q, w1)) <= w2) if not m: m = d.match(abs(arg((polar_lift(s + w3))**p * q, w1)) < w2) if not m: m = d.match( abs(arg((polar_lift(s + w3))**p * q, w1)) <= w2) if m: if m[q] > 0 and m[w2] / m[p] == pi / 2: d = re(s + m[w3]) > 0 m = d.match( 0 < cos(abs(arg(s**w1 * w5, q)) * w2) * abs(s**w3)**w4 - p) if not m: m = d.match( 0 < cos(abs(arg(polar_lift(s)**w1 * w5, q)) * w2) * abs(s**w3)**w4 - p) if m and all(m[wild] > 0 for wild in [w1, w2, w3, w4, w5]): d = re(s) > m[p] d_ = d.replace(re, lambda x: x.expand().as_real_imag()[0]).subs( re(s), t) if not d.is_Relational or (d.rel_op != '<' and d.rel_op != '<=') \ or d_.has(s) or not d_.has(t): aux_ += [d] continue soln = _solve_inequality(d_, t) if not soln.is_Relational or \ (soln.rel_op != '<' and soln.rel_op != '<='): aux_ += [d] continue if soln.lhs == t: raise IntegralTransformError( 'Laplace', f, 'convergence not in half-plane?') else: a_ = Min(soln.lhs, a_) if a_ != oo: a = Max(a_, a) else: aux = And(aux, Or(*aux_)) return a, aux
def _mellin_transform(f, x, s_, integrator=_default_integrator, simplify=True): """ Backend function to compute mellin transforms. """ from sympy import re, Max, Min # We use a fresh dummy, because assumptions on s might drop conditions on # convergence of the integral. s = _dummy('s', 'mellin-transform', f) F = integrator(x**(s-1) * f, x) if not F.has(Integral): return _simplify(F.subs(s, s_), simplify), (-oo, oo), True if not F.is_Piecewise: raise IntegralTransformError('Mellin', f, 'could not compute integral') F, cond = F.args[0] if F.has(Integral): raise IntegralTransformError('Mellin', f, 'integral in unexpected form') a = -oo b = oo aux = True conds = conjuncts(to_cnf(cond)) t = Dummy('t', real=True) for c in conds: a_ = oo b_ = -oo aux_ = [] for d in disjuncts(c): d_ = d.replace(re, lambda x: x.as_real_imag()[0]).subs(re(s), t) if not d.is_Relational or (d.rel_op != '<' and d.rel_op != '<=') \ or d_.has(s) or not d_.has(t): aux_ += [d] continue soln = _solve_inequality(d_, t) if not soln.is_Relational or \ (soln.rel_op != '<' and soln.rel_op != '<='): aux_ += [d] continue if soln.lhs == t: b_ = Max(soln.rhs, b_) else: a_ = Min(soln.lhs, a_) if a_ != oo and a_ != b: a = Max(a_, a) elif b_ != -oo and b_ != a: b = Min(b_, b) else: aux = And(aux, Or(*aux_)) if aux is False: raise IntegralTransformError('Mellin', f, 'no convergence found') return _simplify(F.subs(s, s_), simplify), (a, b), aux
def _laplace_transform(f, t, s, simplify=True): """ The backend function for laplace transforms. """ from sympy import (re, Max, exp, pi, Abs, Min, periodic_argument as arg, cos, Wild, symbols) F = integrate(exp(-s*t) * f, (t, 0, oo)) if not F.has(Integral): return _simplify(F, simplify), -oo, True if not F.is_Piecewise: raise IntegralTransformError('Laplace', f, 'could not compute integral') F, cond = F.args[0] if F.has(Integral): raise IntegralTransformError('Laplace', f, 'integral in unexpected form') a = -oo aux = True conds = conjuncts(to_cnf(cond)) u = Dummy('u', real=True) p, q, w1, w2, w3 = symbols('p q w1 w2 w3', cls=Wild, exclude=[s]) for c in conds: a_ = oo aux_ = [] for d in disjuncts(c): m = d.match(abs(arg((s + w3)**p*q, w1)) < w2) if m: if m[q] > 0 and m[w2]/m[p] == pi/2: d = re(s + m[w3]) > 0 m = d.match(0 < cos(abs(arg(s, q)))*abs(s) - p) if m: d = re(s) > m[p] d_ = d.replace(re, lambda x: x.expand().as_real_imag()[0]).subs(re(s), t) if not d.is_Relational or (d.rel_op != '<' and d.rel_op != '<=') \ or d_.has(s) or not d_.has(t): aux_ += [d] continue soln = _solve_inequality(d_, t) if not soln.is_Relational or \ (soln.rel_op != '<' and soln.rel_op != '<='): aux_ += [d] continue if soln.lhs == t: raise IntegralTransformError('Laplace', f, 'convergence not in half-plane?') else: a_ = Min(soln.lhs, a_) if a_ != oo: a = Max(a_, a) else: aux = And(aux, Or(*aux_)) return _simplify(F, simplify), a, aux
def process_conds(conds): """ Turn ``conds`` into a strip and auxiliary conditions. """ a = -oo aux = True conds = conjuncts(to_cnf(conds)) u = Dummy('u', real=True) p, q, w1, w2, w3, w4, w5 = symbols('p q w1 w2 w3 w4 w5', cls=Wild, exclude=[s]) for c in conds: a_ = oo aux_ = [] for d in disjuncts(c): m = d.match(abs(arg((s + w3)**p*q, w1)) < w2) if not m: m = d.match(abs(arg((s + w3)**p*q, w1)) <= w2) if not m: m = d.match(abs(arg((polar_lift(s + w3))**p*q, w1)) < w2) if not m: m = d.match(abs(arg((polar_lift(s + w3))**p*q, w1)) <= w2) if m: if m[q] > 0 and m[w2]/m[p] == pi/2: d = re(s + m[w3]) > 0 m = d.match(0 < cos(abs(arg(s**w1*w5, q))*w2)*abs(s**w3)**w4 - p) if not m: m = d.match(0 < cos(abs(arg(polar_lift(s)**w1*w5, q))*w2)*abs(s**w3)**w4 - p) if m and all(m[wild] > 0 for wild in [w1, w2, w3, w4, w5]): d = re(s) > m[p] d_ = d.replace(re, lambda x: x.expand().as_real_imag()[0]).subs(re(s), t) if not d.is_Relational or \ d.rel_op not in ('>', '>=', '<', '<=') \ or d_.has(s) or not d_.has(t): aux_ += [d] continue soln = _solve_inequality(d_, t) if not soln.is_Relational or \ soln.rel_op not in ('>', '>=', '<', '<='): aux_ += [d] continue if soln.lts == t: raise IntegralTransformError('Laplace', f, 'convergence not in half-plane?') else: a_ = Min(soln.lts, a_) if a_ != oo: a = Max(a_, a) else: aux = And(aux, Or(*aux_)) return a, aux
def find_unit_clause(clauses, model): """A unit clause has only 1 variable that is not bound in the model. >>> from sympy import symbols >>> A, B, C = symbols('ABC') >>> find_unit_clause([A | B | C, B | ~C, A | ~B], {A:True}) (B, False) """ for clause in clauses: num_not_in_model = 0 for literal in disjuncts(clause): sym = literal_symbol(literal) if sym not in model: num_not_in_model += 1 P, value = sym, not (isinstance(literal, Not)) if num_not_in_model == 1: return P, value return None, None
def find_unit_clause(clauses, model): """ A unit clause has only 1 variable that is not bound in the model. >>> from sympy.abc import A, B, D >>> from sympy.logic.algorithms.dpll import find_unit_clause >>> find_unit_clause([A | B | D, B | ~D, A | ~B], {A:True}) (B, False) """ for clause in clauses: num_not_in_model = 0 for literal in disjuncts(clause): sym = literal_symbol(literal) if sym not in model: num_not_in_model += 1 P, value = sym, not isinstance(literal, Not) if num_not_in_model == 1: return P, value return None, None
def find_unit_clause(clauses, model): """ A unit clause has only 1 variable that is not bound in the model. >>> from sympy import symbols >>> from sympy.abc import A, B, D >>> from sympy.logic.algorithms.dpll import find_unit_clause >>> find_unit_clause([A | B | D, B | ~D, A | ~B], {A:True}) (B, False) """ for clause in clauses: num_not_in_model = 0 for literal in disjuncts(clause): sym = literal_symbol(literal) if sym not in model: num_not_in_model += 1 P, value = sym, not (literal.func is Not) if num_not_in_model == 1: return P, value return None, None
def ask(expr, key, assumptions=True): """ Method for inferring properties about objects. **Syntax** * ask(expression, key) * ask(expression, key, assumptions) where expression is any SymPy expression **Examples** >>> from sympy import ask, Q, Assume, pi >>> from sympy.abc import x, y >>> ask(pi, Q.rational) False >>> ask(x*y, Q.even, Assume(x, Q.even) & Assume(y, Q.integer)) True >>> ask(x*y, Q.prime, Assume(x, Q.integer) & Assume(y, Q.integer)) False **Remarks** Relations in assumptions are not implemented (yet), so the following will not give a meaningful result. >> ask(x, positive=True, Assume(x>0)) It is however a work in progress and should be available before the official release """ expr = sympify(expr) assumptions = And(assumptions, And(*global_assumptions)) # direct resolution method, no logic resolutors = [] for handler in handlers_dict[key]: resolutors.append( get_class(handler) ) res, _res = None, None mro = inspect.getmro(type(expr)) for handler in resolutors: for subclass in mro: if hasattr(handler, subclass.__name__): res = getattr(handler, subclass.__name__)(expr, assumptions) if _res is None: _res = res elif res is None: # since first resolutor was conclusive, we keep that value res = _res else: # only check consistency if both resolutors have concluded if _res != res: raise ValueError, 'incompatible resolutors' break if res is not None: return res if assumptions is True: return # use logic inference if not expr.is_Atom: return clauses = copy.deepcopy(known_facts_compiled) assumptions = conjuncts(to_cnf(assumptions)) # add assumptions to the knowledge base for assump in assumptions: conj = eliminate_assume(assump, symbol=expr) if conj: out = [] for sym in conjuncts(to_cnf(conj)): lit, pos = literal_symbol(sym), type(sym) is not Not if pos: out.extend([known_facts_keys.index(str(l))+1 for l in disjuncts(lit)]) else: out.extend([-(known_facts_keys.index(str(l))+1) for l in disjuncts(lit)]) clauses.append(out) n = len(known_facts_keys) clauses.append([known_facts_keys.index(key)+1]) if not dpll_int_repr(clauses, range(1, n+1), {}): return False clauses[-1][0] = -clauses[-1][0] if not dpll_int_repr(clauses, range(1, n+1), {}): # if the negation is satisfiable, it is entailed return True del clauses
def _laplace_transform(f, t, s_, simplify=True): """ The backend function for laplace transforms. """ from sympy import (re, Max, exp, pi, Abs, Min, periodic_argument as arg, cos, Wild, symbols, polar_lift) s = Dummy('s') F = integrate(exp(-s * t) * f, (t, 0, oo)) if not F.has(Integral): return _simplify(F.subs(s, s_), simplify), -oo, True if not F.is_Piecewise: raise IntegralTransformError('Laplace', f, 'could not compute integral') F, cond = F.args[0] if F.has(Integral): raise IntegralTransformError('Laplace', f, 'integral in unexpected form') def process_conds(conds): """ Turn ``conds`` into a strip and auxiliary conditions. """ a = -oo aux = True conds = conjuncts(to_cnf(conds)) u = Dummy('u', real=True) p, q, w1, w2, w3, w4, w5 = symbols('p q w1 w2 w3 w4 w5', cls=Wild, exclude=[s]) for c in conds: a_ = oo aux_ = [] for d in disjuncts(c): m = d.match(abs(arg((s + w3)**p * q, w1)) < w2) if not m: m = d.match(abs(arg((s + w3)**p * q, w1)) <= w2) if not m: m = d.match(abs(arg((polar_lift(s + w3))**p * q, w1)) < w2) if not m: m = d.match( abs(arg((polar_lift(s + w3))**p * q, w1)) <= w2) if m: if m[q] > 0 and m[w2] / m[p] == pi / 2: d = re(s + m[w3]) > 0 m = d.match( 0 < cos(abs(arg(s**w1 * w5, q)) * w2) * abs(s**w3)**w4 - p) if not m: m = d.match( 0 < cos(abs(arg(polar_lift(s)**w1 * w5, q)) * w2) * abs(s**w3)**w4 - p) if m and all(m[wild] > 0 for wild in [w1, w2, w3, w4, w5]): d = re(s) > m[p] d_ = d.replace(re, lambda x: x.expand().as_real_imag()[0]).subs( re(s), t) if not d.is_Relational or (d.rel_op != '<' and d.rel_op != '<=') \ or d_.has(s) or not d_.has(t): aux_ += [d] continue soln = _solve_inequality(d_, t) if not soln.is_Relational or \ (soln.rel_op != '<' and soln.rel_op != '<='): aux_ += [d] continue if soln.lhs == t: raise IntegralTransformError( 'Laplace', f, 'convergence not in half-plane?') else: a_ = Min(soln.lhs, a_) if a_ != oo: a = Max(a_, a) else: aux = And(aux, Or(*aux_)) return a, aux conds = [process_conds(c) for c in disjuncts(cond)] conds = filter(lambda x: x[1] is not False and x[0] != -oo, conds) def cnt(expr): if isinstance(expr, bool): return 0 return expr.count_ops() conds.sort(key=lambda x: (-x[0], cnt(x[1]))) if not conds: raise IntegralTransformError('Laplace', f, 'no convergence found') a, aux = conds[0] def sbs(expr): if isinstance(expr, bool): return expr return expr.subs(s, s_) if simplify: F = _simplifyconds(F, s, a) aux = _simplifyconds(aux, s, a) return _simplify(F.subs(s, s_), simplify), sbs(a), sbs(aux)
def test_disjuncts(): assert disjuncts(A | B | C) == {A, B, C} assert disjuncts((A | B) & C) == {(A | B) & C} assert disjuncts(A) == {A} assert disjuncts(True) == {True} assert disjuncts(False) == {False}
def ask(expr, key, assumptions=True): """ Method for inferring properties about objects. **Syntax** * ask(expression, key) * ask(expression, key, assumptions) where expression is any SymPy expression **Examples** >>> from sympy import ask, Q, Assume, pi >>> from sympy.abc import x, y >>> ask(pi, Q.rational) False >>> ask(x*y, Q.even, Assume(x, Q.even) & Assume(y, Q.integer)) True >>> ask(x*y, Q.prime, Assume(x, Q.integer) & Assume(y, Q.integer)) False **Remarks** Relations in assumptions are not implemented (yet), so the following will not give a meaningful result. >> ask(x, positive=True, Assume(x>0)) It is however a work in progress and should be available before the official release """ expr = sympify(expr) if type(key) is not Predicate: key = getattr(Q, str(key)) assumptions = And(assumptions, And(*global_assumptions)) # direct resolution method, no logic res = eval_predicate(key, expr, assumptions) if res is not None: return res # use logic inference if assumptions is True: return if not expr.is_Atom: return clauses = copy.deepcopy(known_facts_compiled) assumptions = conjuncts(to_cnf(assumptions)) # add assumptions to the knowledge base for assump in assumptions: conj = eliminate_assume(assump, symbol=expr) if conj: for clause in conjuncts(to_cnf(conj)): out = set() for atom in disjuncts(clause): lit, pos = literal_symbol(atom), type(atom) is not Not if pos: out.add(known_facts_keys.index(lit)+1) else: out.add(-(known_facts_keys.index(lit)+1)) clauses.append(out) n = len(known_facts_keys) clauses.append(set([known_facts_keys.index(key)+1])) if not dpll_int_repr(clauses, set(range(1, n+1)), {}): return False clauses[-1] = set([-(known_facts_keys.index(key)+1)]) if not dpll_int_repr(clauses, set(range(1, n+1)), {}): # if the negation is satisfiable, it is entailed return True del clauses
def _laplace_transform(f, t, s_, simplify=True): """ The backend function for laplace transforms. """ from sympy import (re, Max, exp, pi, Abs, Min, periodic_argument as arg, cos, Wild, symbols, polar_lift) s = Dummy('s') F = integrate(exp(-s*t) * f, (t, 0, oo)) if not F.has(Integral): return _simplify(F.subs(s, s_), simplify), -oo, True if not F.is_Piecewise: raise IntegralTransformError('Laplace', f, 'could not compute integral') F, cond = F.args[0] if F.has(Integral): raise IntegralTransformError('Laplace', f, 'integral in unexpected form') def process_conds(conds): """ Turn ``conds`` into a strip and auxiliary conditions. """ a = -oo aux = True conds = conjuncts(to_cnf(conds)) u = Dummy('u', real=True) p, q, w1, w2, w3, w4, w5 = symbols('p q w1 w2 w3 w4 w5', cls=Wild, exclude=[s]) for c in conds: a_ = oo aux_ = [] for d in disjuncts(c): m = d.match(abs(arg((s + w3)**p*q, w1)) < w2) if not m: m = d.match(abs(arg((s + w3)**p*q, w1)) <= w2) if not m: m = d.match(abs(arg((polar_lift(s + w3))**p*q, w1)) < w2) if not m: m = d.match(abs(arg((polar_lift(s + w3))**p*q, w1)) <= w2) if m: if m[q] > 0 and m[w2]/m[p] == pi/2: d = re(s + m[w3]) > 0 m = d.match(0 < cos(abs(arg(s**w1*w5, q))*w2)*abs(s**w3)**w4 - p) if not m: m = d.match(0 < cos(abs(arg(polar_lift(s)**w1*w5, q))*w2)*abs(s**w3)**w4 - p) if m and all(m[wild] > 0 for wild in [w1, w2, w3, w4, w5]): d = re(s) > m[p] d_ = d.replace(re, lambda x: x.expand().as_real_imag()[0]).subs(re(s), t) if not d.is_Relational or (d.rel_op != '<' and d.rel_op != '<=') \ or d_.has(s) or not d_.has(t): aux_ += [d] continue soln = _solve_inequality(d_, t) if not soln.is_Relational or \ (soln.rel_op != '<' and soln.rel_op != '<='): aux_ += [d] continue if soln.lhs == t: raise IntegralTransformError('Laplace', f, 'convergence not in half-plane?') else: a_ = Min(soln.lhs, a_) if a_ != oo: a = Max(a_, a) else: aux = And(aux, Or(*aux_)) return a, aux conds = [process_conds(c) for c in disjuncts(cond)] conds = filter(lambda x: x[1] is not False and x[0] != -oo, conds) def cnt(expr): if isinstance(expr, bool): return 0 return expr.count_ops() conds.sort(key=lambda x: (-x[0], cnt(x[1]))) if not conds: raise IntegralTransformError('Laplace', f, 'no convergence found') a, aux = conds[0] def sbs(expr): if isinstance(expr, bool): return expr return expr.subs(s, s_) if simplify: F = _simplifyconds(F, s, a) aux = _simplifyconds(aux, s, a) return _simplify(F.subs(s, s_), simplify), sbs(a), sbs(aux)
def test_disjuncts(): A, B, C = symbols('ABC') assert disjuncts(A | B | C) == [A, B, C]
def test_disjuncts(): assert disjuncts(A | B | C) == set([A, B, C]) assert disjuncts((A | B) & C) == set([(A | B) & C]) assert disjuncts(A) == set([A]) assert disjuncts(True) == set([True]) assert disjuncts(False) == set([False])
def _mellin_transform(f, x, s_, integrator=_default_integrator, simplify=True): """ Backend function to compute mellin transforms. """ from sympy import re, Max, Min, count_ops # We use a fresh dummy, because assumptions on s might drop conditions on # convergence of the integral. s = _dummy('s', 'mellin-transform', f) F = integrator(x**(s-1) * f, x) if not F.has(Integral): return _simplify(F.subs(s, s_), simplify), (-oo, oo), True if not F.is_Piecewise: raise IntegralTransformError('Mellin', f, 'could not compute integral') F, cond = F.args[0] if F.has(Integral): raise IntegralTransformError('Mellin', f, 'integral in unexpected form') def process_conds(cond): """ Turn ``cond`` into a strip (a, b), and auxiliary conditions. """ a = -oo b = oo aux = True conds = conjuncts(to_cnf(cond)) t = Dummy('t', real=True) for c in conds: a_ = oo b_ = -oo aux_ = [] for d in disjuncts(c): d_ = d.replace(re, lambda x: x.as_real_imag()[0]).subs(re(s), t) if not d.is_Relational or \ d.rel_op not in ('>', '>=', '<', '<=') \ or d_.has(s) or not d_.has(t): aux_ += [d] continue soln = _solve_inequality(d_, t) if not soln.is_Relational or \ soln.rel_op not in ('>', '>=', '<', '<='): aux_ += [d] continue if soln.lts == t: b_ = Max(soln.gts, b_) else: a_ = Min(soln.lts, a_) if a_ != oo and a_ != b: a = Max(a_, a) elif b_ != -oo and b_ != a: b = Min(b_, b) else: aux = And(aux, Or(*aux_)) return a, b, aux conds = [process_conds(c) for c in disjuncts(cond)] conds = filter(lambda x: x[2] is not False, conds) conds.sort(key=lambda x: (x[0]-x[1], count_ops(x[2]))) if not conds: raise IntegralTransformError('Mellin', f, 'no convergence found') a, b, aux = conds[0] return _simplify(F.subs(s, s_), simplify), (a, b), aux
def ask(expr, key, assumptions=True): """ Method for inferring properties about objects. **Syntax** * ask(expression, key) * ask(expression, key, assumptions) where expression is any SymPy expression **Examples** >>> from sympy import ask, Q, Assume, pi >>> from sympy.abc import x, y >>> ask(pi, Q.rational) False >>> ask(x*y, Q.even, Assume(x, Q.even) & Assume(y, Q.integer)) True >>> ask(x*y, Q.prime, Assume(x, Q.integer) & Assume(y, Q.integer)) False **Remarks** Relations in assumptions are not implemented (yet), so the following will not give a meaningful result. >> ask(x, positive=True, Assume(x>0)) It is however a work in progress and should be available before the official release """ expr = sympify(expr) assumptions = And(assumptions, And(*global_assumptions)) # direct resolution method, no logic resolutors = [] for handler in handlers_dict[key]: resolutors.append(get_class(handler)) res, _res = None, None mro = inspect.getmro(type(expr)) for handler in resolutors: for subclass in mro: if hasattr(handler, subclass.__name__): res = getattr(handler, subclass.__name__)(expr, assumptions) if _res is None: _res = res elif res is None: # since first resolutor was conclusive, we keep that value res = _res else: # only check consistency if both resolutors have concluded if _res != res: raise ValueError('incompatible resolutors') break if res is not None: return res if assumptions is True: return # use logic inference if not expr.is_Atom: return clauses = copy.deepcopy(known_facts_compiled) assumptions = conjuncts(to_cnf(assumptions)) # add assumptions to the knowledge base for assump in assumptions: conj = eliminate_assume(assump, symbol=expr) if conj: out = set() for sym in conjuncts(to_cnf(conj)): lit, pos = literal_symbol(sym), type(sym) is not Not if pos: out.update([ known_facts_keys.index(str(l)) + 1 for l in disjuncts(lit) ]) else: out.update([ -(known_facts_keys.index(str(l)) + 1) for l in disjuncts(lit) ]) clauses.append(out) n = len(known_facts_keys) clauses.append(set([known_facts_keys.index(key) + 1])) if not dpll_int_repr(clauses, set(range(1, n + 1)), {}): return False clauses[-1] = set([-(known_facts_keys.index(key) + 1)]) if not dpll_int_repr(clauses, set(range(1, n + 1)), {}): # if the negation is satisfiable, it is entailed return True del clauses