Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make count_ops() work with logic operations by creating a binary tree. #7303

Merged
merged 26 commits into from Apr 12, 2014
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
cefd428
Make count_ops() work with logic operations by creating a binary tree…
sahilshekhawat Mar 19, 2014
5389065
Added tests of the logic functions for count_ops() function.
sahilshekhawat Mar 19, 2014
7000d9e
Fixed a test case of Xor(x,y) = 2*AND + OR
sahilshekhawat Mar 19, 2014
3c5ba38
Fixed the test case for Nand(x,y).count_ops(visual=True) = OR and Nor…
sahilshekhawat Mar 19, 2014
07168de
Removed the obsolete test case which was addressing the bug.
sahilshekhawat Mar 19, 2014
25a9686
Included the case of logic function in the "else" case.
sahilshekhawat Mar 19, 2014
d5abbd7
removed the XXX comment to report bug.
sahilshekhawat Mar 19, 2014
366f864
Removed the case for logic functions because it was contradicting wit…
sahilshekhawat Mar 19, 2014
00604b1
Final commit, added the logic function to be counted in count_ops()
sahilshekhawat Mar 19, 2014
d374ed5
remove the else condition and added the is.Boolean condition to gener…
sahilshekhawat Mar 22, 2014
d277512
Removed redundant tests count_ops(Basic()) = S.zero
sahilshekhawat Mar 22, 2014
dc6cf28
Removed trailing whitespaces, will always check them first.
sahilshekhawat Mar 22, 2014
ee126ac
Added the cases to handle the exception of True and False, who were b…
sahilshekhawat Mar 23, 2014
b49c02c
Fixed the bug.
sahilshekhawat Mar 23, 2014
2f7d1de
Merge branch 'master' of https://github.com/sympy/sympy
sahilshekhawat Mar 23, 2014
e1c8ea4
Fix the bug due to which `Basic()` was counted as an operation and us…
sahilshekhawat Mar 28, 2014
7adde66
Added more tests which also include some complex ones.
sahilshekhawat Mar 28, 2014
cc74cd8
removed extra spaces
sahilshekhawat Mar 28, 2014
80fd37a
removed ``true`` and ``false`` and used ``not a.args is ()`` instead …
sahilshekhawat Mar 29, 2014
912c0fd
Replace "is" with "==" to check the conditions.
sahilshekhawat Mar 29, 2014
9549f0b
replaced 'is' with '=='
sahilshekhawat Apr 4, 2014
37ba49b
Added tests to include cases of logic functions given less arguments …
sahilshekhawat Apr 5, 2014
4fbde7b
removed Basic and Tuple check
sahilshekhawat Apr 10, 2014
9771a86
Added more test related to Basic()
sahilshekhawat Apr 10, 2014
5d3950d
Added logical test for TUPLE and removed duplicate tests
sahilshekhawat Apr 11, 2014
189c659
removed some tests which were showing bugs in logical functions.
sahilshekhawat Apr 11, 2014
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
13 changes: 12 additions & 1 deletion sympy/core/function.py
Expand Up @@ -2326,7 +2326,18 @@ def count_ops(expr, visual=False):
else: # it's Basic not isinstance(expr, Expr):
if not isinstance(expr, Basic):
raise TypeError("Invalid type of expr")
ops = [count_ops(a, visual=visual) for a in expr.args]
else:
ops = []
args = [expr]
while args:
a = args.pop()
if a.args:
o = C.Symbol(a.func.__name__.upper())
if a.is_Boolean:
ops.append(o*(len(a.args)-1))
else:
ops.append(o)
args.extend(a.args)

if not ops:
if visual:
Expand Down
50 changes: 44 additions & 6 deletions sympy/core/tests/test_count_ops.py
@@ -1,8 +1,9 @@
from sympy import symbols, sin, exp, cos, Derivative, Integral, Basic, \
count_ops, S, And, I, pi, Eq
count_ops, S, And, I, pi, Eq, Or, Not, Xor ,Nand ,Nor, Implies,Equivalent, ITE
from sympy.core.containers import Tuple

x, y, z = symbols('x,y,z')

a, b, c = symbols('a,b,c')

def test_count_ops_non_visual():
def count(val):
Expand All @@ -14,12 +15,23 @@ def count(val):
assert count(x + y*x + 2*y) == 4
assert count({x + y: x}) == 1
assert count({x + y: S(2) + x}) is not S.One

assert count(Or(x,y)) == 1
assert count(And(x,y)) == 1
assert count(Not(x)) == 0
assert count(Nor(x,y)) == 1
assert count(Nand(x,y)) == 1
assert count(Xor(x,y)) == 3
assert count(Implies(x,y)) == 1
assert count(Equivalent(x,y)) == 1
assert count(ITE(x,y,z)) == 3
assert count(ITE(True,x,y)) == 0

def test_count_ops_visual():
ADD, MUL, POW, SIN, COS, EXP, AND, D, G = symbols(
'Add Mul Pow sin cos exp And Derivative Integral'.upper())
DIV, SUB, NEG = symbols('DIV SUB NEG')
OR, AND, IMPLIES, EQUIVALENT, BASIC, TUPLE = symbols(
'Or And Implies Equivalent Basic Tuple'.upper())

def count(val):
return count_ops(val, visual=True)
Expand Down Expand Up @@ -78,7 +90,33 @@ def count(val):
assert count([x + 1, sin(x)*y, None]) == SIN + ADD + MUL
assert count([]) is S.Zero

# XXX: These are a bit surprising, only Expr-compatible ops are counted.
assert count(And(x, y, z)) == 0
assert count(Basic(x, x + y)) == ADD
assert count(Basic()) == 0
assert count(Basic(Basic(),Basic(x,x+y))) == ADD + 2*BASIC
assert count(Basic(x, x + y)) == ADD + BASIC
assert count(Or(x,y)) == OR
assert count(And(x,y)) == AND
assert count(And(x**y,z)) == AND + POW
assert count(Or(x,Or(y,And(z,a)))) == AND + 2*OR
assert count(Nor(x,y)) == AND
assert count(Nand(x,y)) == OR
assert count(Xor(x,y)) == 2*AND + OR
assert count(Implies(x,y)) == IMPLIES
assert count(Equivalent(x,y)) == EQUIVALENT
assert count(ITE(x,y,z)) == 2*AND + OR
assert count([Or(x,y), And(x,y), Basic(x+y)]) == ADD + AND + BASIC + OR

assert count(Basic(Tuple(x))) == BASIC + TUPLE
#It checks that TUPLE is counted as an operation.

assert count(Eq(x + y, S(2))) == ADD

# The test given below checks the results which comes when logical
# functions are given less number of arguments than required and
# don't raises an exception. They don't make much sense.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would just remove these tests. They are all either things that don't make sense or operations that return a different object than what is started with. I think these tests are just confusing, especially if any of these things are changed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

okay! i am commiting after removing these.

assert count(And((x,y+z))) == ADD
assert count(Equivalent(x)) == 0 # Equivalent(x) == 0
assert count(And(x)) == 0 # And(x) == 0
assert count(Nand(And(x,y))) == OR # Nand(x) == Not(x)
assert count(Xor(And(x,y))) == AND # Xor(x) == x
# Any logic function don't check if the argument is an empty tuple
assert count(And(x,())) == AND