def test_unify(): expr = Basic(S(1), S(2), S(3)) a, b, c = map(Symbol, 'abc') pattern = Basic(a, b, c) assert list(unify(expr, pattern, {}, (a, b, c))) == [{a: 1, b: 2, c: 3}] assert list(unify(expr, pattern, variables=(a, b, c))) == \ [{a: 1, b: 2, c: 3}]
def test_bottom_up_once(): bottom_rl = bottom_up_once(rl) assert bottom_rl(Basic(S(1), S(2), Basic(S(3.0), S(4.0)))) == Basic(S(1), S(2), Basic2(S(3.0), S(4.0)))
def test_subs(): from sympy.core.symbol import symbols a,b,c,d,e,f = symbols('a,b,c,d,e,f') mapping = {a: d, d: a, Basic(e): Basic(f)} expr = Basic(a, Basic(b, c), Basic(d, Basic(e))) result = Basic(d, Basic(b, c), Basic(a, Basic(f))) assert subs(mapping)(expr) == result
def test_atomic(): g, h = map(Function, 'gh') x = symbols('x') assert _atomic(g(x + h(x))) == {g(x + h(x))} assert _atomic(g(x + h(x)), recursive=True) == {h(x), x, g(x + h(x))} assert _atomic(1) == set() assert _atomic(Basic(1, 2)) == {Basic(1, 2)}
def test_gcd_terms(): f = 2*(x + 1)*(x + 4)/(5*x**2 + 5) + (2*x + 2)*(x + 5)/(x**2 + 1)/5 + \ (2*x + 2)*(x + 6)/(5*x**2 + 5) assert _gcd_terms(f) == ((Rational(6, 5)) * ((1 + x) / (1 + x**2)), 5 + x, 1) assert _gcd_terms(Add.make_args(f)) == \ ((Rational(6, 5))*((1 + x)/(1 + x**2)), 5 + x, 1) newf = (Rational(6, 5)) * ((1 + x) * (5 + x) / (1 + x**2)) assert gcd_terms(f) == newf args = Add.make_args(f) # non-Basic sequences of terms treated as terms of Add assert gcd_terms(list(args)) == newf assert gcd_terms(tuple(args)) == newf assert gcd_terms(set(args)) == newf # but a Basic sequence is treated as a container assert gcd_terms(Tuple(*args)) != newf assert gcd_terms(Basic(Tuple(S(1), 3*y + 3*x*y), Tuple(S(1), S(3)))) == \ Basic((S(1), 3*y*(x + 1)), (S(1), S(3))) # but we shouldn't change keys of a dictionary or some may be lost assert gcd_terms(Dict((x*(1 + y), S(2)), (x + x*y, y + x*y))) == \ Dict({x*(y + 1): S(2), x + x*y: y*(1 + x)}) assert gcd_terms((2 * x + 2)**3 + (2 * x + 2)**2) == 4 * (x + 1)**2 * (2 * x + 3) assert gcd_terms(0) == 0 assert gcd_terms(1) == 1 assert gcd_terms(x) == x assert gcd_terms(2 + 2 * x) == Mul(2, 1 + x, evaluate=False) arg = x * (2 * x + 4 * y) garg = 2 * x * (x + 2 * y) assert gcd_terms(arg) == garg assert gcd_terms(sin(arg)) == sin(garg) # issue 6139-like alpha, alpha1, alpha2, alpha3 = symbols('alpha:4') a = alpha**2 - alpha * x**2 + alpha + x**3 - x * (alpha + 1) rep = (alpha, (1 + sqrt(5)) / 2 + alpha1 * x + alpha2 * x**2 + alpha3 * x**3) s = (a / (x - alpha)).subs(*rep).series(x, 0, 1) assert simplify(collect(s, x)) == -sqrt(5) / 2 - Rational(3, 2) + O(x) # issue 5917 assert _gcd_terms([S.Zero, S.Zero]) == (0, 0, 1) assert _gcd_terms([2 * x + 4]) == (2, x + 2, 1) eq = x / (x + 1 / x) assert gcd_terms(eq, fraction=False) == eq eq = x / 2 / y + 1 / x / y assert gcd_terms(eq, fraction=True, clear=True) == \ (x**2 + 2)/(2*x*y) assert gcd_terms(eq, fraction=True, clear=False) == \ (x**2/2 + 1)/(x*y) assert gcd_terms(eq, fraction=False, clear=True) == \ (x + 2/x)/(2*y) assert gcd_terms(eq, fraction=False, clear=False) == \ (x/2 + 1/x)/y
def test_FiniteSet_complex(): from sympy.sets.sets import FiniteSet a, b, c, x, y, z = symbols('a,b,c,x,y,z') expr = FiniteSet(Basic(S(1), x), y, Basic(x, z)) pattern = FiniteSet(a, Basic(x, b)) variables = a, b expected = tuple([{b: 1, a: FiniteSet(y, Basic(x, z))}, {b: z, a: FiniteSet(y, Basic(S(1), x))}]) assert iterdicteq(unify(expr, pattern, variables=variables), expected)
def test_issue_6079(): # since x + 2.0 == x + 2 we can't do a simple equality test assert _aresame((x + 2.0).subs(2, 3), x + 2.0) assert _aresame((x + 2.0).subs(2.0, 3), x + 3) assert not _aresame(x + 2, x + 2.0) assert not _aresame(Basic(cos(x), S(1)), Basic(cos(x), S(1.))) assert _aresame(cos, cos) assert not _aresame(1, S.One) assert not _aresame(x, symbols('x', positive=True))
def test_xreplace(): assert b21.xreplace({b2: b1}) == Basic(b1, b1) assert b21.xreplace({b2: b21}) == Basic(b21, b1) assert b3.xreplace({b2: b1}) == b2 assert Basic(b1, b2).xreplace({b1: b2, b2: b1}) == Basic(b2, b1) assert Atom(b1).xreplace({b1: b2}) == Atom(b1) assert Atom(b1).xreplace({Atom(b1): b2}) == b2 raises(TypeError, 'b1.xreplace()') raises(TypeError, 'b1.xreplace([b1,b2])')
def test_purestr(): assert purestr(Symbol('x')) == "Symbol('x')" assert purestr(Basic(S(1), S(2))) == "Basic(Integer(1), Integer(2))" assert purestr(Float(2)) == "Float('2.0', precision=53)" assert purestr(Symbol('x'), with_args=True) == ("Symbol('x')", ()) assert purestr(Basic(S(1), S(2)), with_args=True) == \ ('Basic(Integer(1), Integer(2))', ('Integer(1)', 'Integer(2)')) assert purestr(Float(2), with_args=True) == \ ("Float('2.0', precision=53)", ())
def test_simple(): rl = rewriterule(Basic(p, S(1)), Basic(p, S(2)), variables=(p,)) assert list(rl(Basic(S(3), S(1)))) == [Basic(S(3), S(2))] p1 = p**2 p2 = p**3 rl = rewriterule(p1, p2, variables=(p,)) expr = x**2 assert list(rl(expr)) == [x**3]
def test_matches_basic(): instances = [Basic(b1, b1, b2), Basic(b1, b2, b1), Basic(b2, b1, b1), Basic(b1, b2), Basic(b2, b1), b2, b1] for i, b_i in enumerate(instances): for j, b_j in enumerate(instances): if i == j: assert b_i.matches(b_j) == {} else: assert b_i.matches(b_j) is None assert b1.match(b1) == {}
def test_subs(): assert b21.subs(b2, b1) == Basic(b1, b1) assert b21.subs(b2, b21) == Basic(b21, b1) assert b3.subs(b2, b1) == b2 assert b21.subs([(b2, b1), (b1, b2)]) == Basic(b2, b2) assert b21.subs({b1: b2, b2: b1}) == Basic(b2, b2) raises(ValueError, "b21.subs('bad arg')") raises(ValueError, "b21.subs(b1, b2, b3)")
def test_equality(): instances = [b1, b2, b3, b21, Basic(b1, b1, b1), Basic] for i, b_i in enumerate(instances): for j, b_j in enumerate(instances): assert (b_i == b_j) == (i == j) assert (b_i != b_j) == (i != j) assert Basic() != [] assert not (Basic() == []) assert Basic() != 0 assert not (Basic() == 0)
def _test_stop_on_non_basics(trav): def add_one_if_can(expr): try: return expr + 1 except TypeError: return expr expr = Basic(S(1), Str('a'), Basic(S(2), Str('b'))) expected = Basic(S(2), Str('a'), Basic(S(3), Str('b'))) rl = trav(add_one_if_can) assert rl(expr) == expected
def test_xreplace(): assert b21.xreplace({b2: b1}) == Basic(b1, b1) assert b21.xreplace({b2: b21}) == Basic(b21, b1) assert b3.xreplace({b2: b1}) == b2 assert Basic(b1, b2).xreplace({b1: b2, b2: b1}) == Basic(b2, b1) assert Atom(b1).xreplace({b1: b2}) == Atom(b1) assert Atom(b1).xreplace({Atom(b1): b2}) == b2 raises(TypeError, lambda: b1.xreplace()) raises(TypeError, lambda: b1.xreplace([b1, b2])) for f in (exp, Function('f')): assert f.xreplace({}) == f assert f.xreplace({}, hack2=True) == f assert f.xreplace({f: b1}) == b1 assert f.xreplace({f: b1}, hack2=True) == b1
def test_Singleton(): global instantiated instantiated = 0 class MySingleton(with_metaclass(Singleton, Basic)): def __new__(cls): global instantiated instantiated += 1 return Basic.__new__(cls) assert instantiated == 0 MySingleton() # force instantiation assert instantiated == 1 assert MySingleton() is not Basic() assert MySingleton() is MySingleton() assert S.MySingleton is MySingleton() assert instantiated == 1 class MySingleton_sub(MySingleton): pass assert instantiated == 1 MySingleton_sub() assert instantiated == 2 assert MySingleton_sub() is not MySingleton() assert MySingleton_sub() is MySingleton_sub()
def test_core_basic(): for c in (Atom, Atom(), Basic, Basic(), # XXX: dynamically created types are not picklable # BasicMeta, BasicMeta("test", (), {}), SingletonRegistry, S): check(c)
def test_deconstruct(): expr = Basic(S(1), S(2), S(3)) expected = Compound(Basic, (1, 2, 3)) assert deconstruct(expr) == expected assert deconstruct(1) == 1 assert deconstruct(x) == x assert deconstruct(x, variables=(x, )) == Variable(x) assert deconstruct(Add(1, x, evaluate=False)) == Compound(Add, (1, x)) assert deconstruct(Add(1, x, evaluate=False), variables=(x,)) == \ Compound(Add, (1, Variable(x)))
def test_styleof(): styles = [(Basic, { 'color': 'blue', 'shape': 'ellipse' }), (Expr, { 'color': 'black' })] assert styleof(Basic(S(1)), styles) == { 'color': 'blue', 'shape': 'ellipse' } assert styleof(x + 1, styles) == {'color': 'black', 'shape': 'ellipse'}
def test_split5(): expr = Basic(S(2), Basic(S(5), S(3)), S(8)) expected = { Basic(S(0), Basic(S(0), S(0)), S(10)), Basic(S(0), Basic(S(10), S(0)), S(10)) } brl = canon(branch5) assert set(brl(expr)) == expected
def test_Singleton(): class MySingleton(Basic, metaclass=Singleton): pass MySingleton() # force instantiation assert MySingleton() is not Basic() assert MySingleton() is MySingleton() assert S.MySingleton is MySingleton() class MySingleton_sub(MySingleton): pass MySingleton_sub() assert MySingleton_sub() is not MySingleton() assert MySingleton_sub() is MySingleton_sub()
def test_top_down_harder_function(): def split5(x): if x == 5: yield x - 1 yield x + 1 expr = Basic(Basic(S(5), S(6)), S(1)) expected = {Basic(Basic(S(4), S(6)), S(1)), Basic(Basic(S(6), S(6)), S(1))} brl = top_down(split5) assert set(brl(expr)) == expected
def test_sall(): expr = Basic(S(1), S(2)) expected = Basic(S(2), S(3)) brl = sall(inc) assert list(brl(expr)) == [expected] expr = Basic(S(1), S(2), Basic(S(3), S(4))) expected = Basic(S(2), S(3), Basic(S(3), S(4))) brl = sall(do_one(inc, identity)) assert list(brl(expr)) == [expected]
def test_subs(): assert b21.subs(b2, b1) == Basic(b1, b1) assert b21.subs(b2, b21) == Basic(b21, b1) assert b3.subs(b2, b1) == b2 assert b21.subs([(b2, b1), (b1, b2)]) == Basic(b2, b2) assert b21.subs({b1: b2, b2: b1}) == Basic(b2, b2) if sys.version_info >= (3, 4): assert b21.subs(collections.ChainMap({b1: b2}, {b2: b1})) == Basic(b2, b2) assert b21.subs(collections.OrderedDict([(b2, b1), (b1, b2)])) == Basic(b2, b2) raises(ValueError, lambda: b21.subs('bad arg')) raises(ValueError, lambda: b21.subs(b1, b2, b3))
def test_preorder_traversal(): expr = Basic(b21, b3) assert list( preorder_traversal(expr)) == [expr, b21, b2, b1, b1, b3, b2, b1] assert list(preorder_traversal( ('abc', ('d', 'ef')))) == [('abc', ('d', 'ef')), 'abc', ('d', 'ef'), 'd', 'ef'] result = [] pt = preorder_traversal(expr) for i in pt: result.append(i) if i == b2: pt.skip() assert result == [expr, b21, b2, b1, b3, b2] w, x, y, z = symbols('w:z') expr = z + w * (x + y) assert list(preorder_traversal([expr], key=default_sort_key)) == \ [[w*(x + y) + z], w*(x + y) + z, z, w*(x + y), w, x + y, x, y]
def test_equality(): instances = [b1, b2, b3, b21, Basic(b1, b1, b1), Basic] for i, b_i in enumerate(instances): for j, b_j in enumerate(instances): assert (b_i == b_j) == (i == j) assert (b_i != b_j) == (i != j) assert Basic() != [] assert not (Basic() == []) assert Basic() != 0 assert not (Basic() == 0) class Foo(object): """ Class that is unaware of Basic, and relies on both classes returning the NotImplemented singleton for equivalence to evaluate to False. """ b = Basic() foo = Foo() assert b != foo assert foo != b assert not b == foo assert not foo == b class Bar(object): """ Class that considers itself equal to any instance of Basic, and relies on Basic returning the NotImplemented singleton in order to achieve a symmetric equivalence relation. """ def __eq__(self, other): if isinstance(other, Basic): return True return NotImplemented def __ne__(self, other): return not self == other bar = Bar() assert b == bar assert bar == b assert not b != bar assert not bar != b
def test_Singleton(): global instanciated instanciated = 0 class MySingleton(Basic): __metaclass__ = Singleton def __new__(cls): global instanciated instanciated += 1 return Basic.__new__(cls) assert instanciated == 1 assert MySingleton() is not Basic() assert MySingleton() is MySingleton() assert S.MySingleton is MySingleton() assert instanciated == 1 class MySingleton_sub(MySingleton): pass assert instanciated == 2 assert MySingleton_sub() is not MySingleton() assert MySingleton_sub() is MySingleton_sub()
def test_preorder_traversal(): expr = Basic(b21, b3) assert list( preorder_traversal(expr)) == [expr, b21, b2, b1, b1, b3, b2, b1] assert list(preorder_traversal(("abc", ("d", "ef")))) == [ ("abc", ("d", "ef")), "abc", ("d", "ef"), "d", "ef", ] result = [] pt = preorder_traversal(expr) for i in pt: result.append(i) if i == b2: pt.skip() assert result == [expr, b21, b2, b1, b3, b2] w, x, y, z = symbols("w:z") expr = z + w * (x + y) assert list(preorder_traversal([expr], keys=default_sort_key)) == [ [w * (x + y) + z], w * (x + y) + z, z, w * (x + y), w, x + y, x, y, ] assert list(preorder_traversal((x + y) * z, keys=True)) == [ z * (x + y), z, x + y, x, y, ]
def _eval_expand_mul(self, **hints): from sympy import fraction, expand_mul # Handle things like 1/(x*(x + 1)), which are automatically converted # to 1/x*1/(x + 1) expr = self n, d = fraction(expr) if d.is_Mul: expr = n/d._eval_expand_mul(**hints) if not expr.is_Mul: return expand_mul(expr, deep=False) plain, sums, rewrite = [], [], False for factor in expr.args: if factor.is_Add: sums.append(factor) rewrite = True else: if factor.is_commutative: plain.append(factor) else: sums.append(Basic(factor)) # Wrapper if not rewrite: return expr else: plain = Mul(*plain) if sums: terms = Mul._expandsums(sums) args = [] for term in terms: t = Mul(plain, term) if t.is_Mul and any(a.is_Add for a in t.args): t = t._eval_expand_mul() args.append(t) return Add(*args) else: return plain
def test_subs(): assert b21.subs(b2, b1) == Basic(b1, b1) assert b21.subs(b2, b21) == Basic(b21, b1) assert b3.subs(b2, b1) == b2 assert b21.subs([(b2, b1), (b1, b2)]) == Basic(b2, b2) assert b21.subs({b1: b2, b2: b1}) == Basic(b2, b2) if sys.version_info >= (3, 4): assert b21.subs(collections.ChainMap({b1: b2}, {b2: b1})) == Basic(b2, b2) assert b21.subs(collections.OrderedDict([(b2, b1), (b1, b2)])) == Basic(b2, b2) raises(ValueError, lambda: b21.subs('bad arg')) raises(ValueError, lambda: b21.subs(b1, b2, b3)) # dict(b1=foo) creates a string 'b1' but leaves foo unchanged; subs # will convert the first to a symbol but will raise an error if foo # cannot be sympified; sympification is strict if foo is not string raises(ValueError, lambda: b21.subs(b1='bad arg'))