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

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

merged 26 commits into from Apr 12, 2014

Conversation

sahilshekhawat
Copy link
Contributor

Bug was that Logic functions are not the instance of sympy.core.expr.Expr due to which logic operation were actually skipping to "else" case.

Fixes #7010

…. Bug was that Logic functions are not the instance of sympy.core.expr.Expr due to which logic operation were actually skipping to "else" case.

Fixes #7010
args = [expr]
while args:
a = args.pop()
o = C.Symbol(a.func.__name__.upper())
Copy link

Choose a reason for hiding this comment

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

I may not wonder if args.pop() will return whole the expr you import regardless how larger that is. Something like a = expr.args() would do the trick.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Its for the condition when two or more args of the expr are also logic functions( something like binary tree), in that case they will be appended to args and args.pop() will run the loop for each of them.
yes! you are right, initially it will return the whole expression regardless of how large it is.

@asmeurer
Copy link
Member

Please add tests.

@sahilshekhawat
Copy link
Contributor Author

I have done all the test locally on my system. but i don't know how to add tests here (Travis one's)

@debugger22
Copy link
Member

@sahilshekhawat There's a file called .travis.yml in the repository. It contains information related to the test files. You just add tests for the particular function you added in the corresponding test file and the github will take care of the rest.

@sahilshekhawat
Copy link
Contributor Author

But i have not added any functions i have just added some lines to an existing function.

@skirpichev
Copy link
Contributor

At least, you should add tests from the referenced issue.

@sahilshekhawat
Copy link
Contributor Author

I got it! Thanks

assert count(Implies(x,y)) == IMPLIES
assert count(Equivalent(x,y)) == EQUIVALENT
assert count(ITE(x,y,z)) == 2*AND + OR

# XXX: These are a bit surprising, only Expr-compatible ops are counted.
assert count(And(x, y, z)) == 0
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This test is causing an error should i remove it. because the bug is now fixed

Copy link
Member

Choose a reason for hiding this comment

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

Yes.

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, Thanks 👍

@asmeurer
Copy link
Member

I mean, your algorithm is general. It can work on anything, not just Boolean. So you should replace elif expr.is_Boolean with just else (and also get rid of the if aargs[i].is_Boolean line below).

@sahilshekhawat
Copy link
Contributor Author

My algorithm is same as that used above in the case of is_Add for example, and for else there is already an condition see ops = [count_ops(a, visual=visual) for a in expr.args]
which handles everything else.
and about removing if aargs[i].is_Boolean, then if one of the args is just a constant or symbol, how can we distinguish it from any function. can i use is_Function?

@asmeurer
Copy link
Member

But your algorithm actually counts all operations. I'd rather have that, even for Basic ops.

@sahilshekhawat
Copy link
Contributor Author

so to separate the symbols from the Basic ops should i use isinstance(aargs, Basic) or aargs.is_Function?

@sahilshekhawat
Copy link
Contributor Author

isinstance(aargs, Basic) will not work and i think is_Function is just a subset of Basic. and i did what you said but removing aargs.isBoolean, is giving wrong answers.
I have used if not aargs.is_Symbol: but it is failing the test because count_ops(Basic()) expects S.zero which was in the else conditions..i think that either the current solution is correct or we need to change test case. any advice?

@sahilshekhawat
Copy link
Contributor Author

@skirpichev can you please help me?

@sahilshekhawat
Copy link
Contributor Author

Sorry for the extra commit for trailing white spaces..i forgot to run ./bin/test quality before commiting. Will take care of that from the next time.

@skirpichev
Copy link
Contributor

@skirpichev can you please help me?

I'm slightly off this discussion. What help do you need?

@sahilshekhawat
Copy link
Contributor Author

Sorry for that mention, Aaron just cleared my doubt on gitter. I think it will work for any equation now, even those who are the instance of Basic()
Thanks

@@ -69,7 +79,6 @@ def count(val):

assert count(Derivative(x, x)) == D
assert count(Integral(x, x) + 2*x/(1 + x)) == G + DIV + MUL + 2*ADD
assert count(Basic()) is S.Zero
Copy link
Member

Choose a reason for hiding this comment

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

Don't remove the test. Replace it with the new value. And add some more tests for more complicated expressions like Basic(Basic(), Basic()) or Basic(x + y) and so on.

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 adding more complex tests for other logic functions and Basic() too

@sahilshekhawat
Copy link
Contributor Author

@asmeurer I have done just as you suggested. Please review it!

@sahilshekhawat
Copy link
Contributor Author

@asmeurer Thanks for the help..i have corrected it..i know it was a silly mistake but i am still learning ...please don't mind..

@sahilshekhawat
Copy link
Contributor Author

@asmeurer on my system the same code count_ops([x, sin(x), None, True, x + 2], visual=False) is running perfectly...but travis is showing an error. Can you please help me on what could be the possible cause.??

@sahilshekhawat
Copy link
Contributor Author

Thank you @asmeurer for pointing that mistake, now as it has passed all the tests, can we merge it now?

assert count(Implies(x,y)) == IMPLIES
assert count(Equivalent(x,y)) == EQUIVALENT
assert count(ITE(x,y,z)) == 2*AND + OR
assert count(And((((x,y+z))))) == ADD
Copy link
Member

Choose a reason for hiding this comment

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

This doesn't even use And

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is because the simpify(And((((x,y+z))))) == (x, y+z) and thats why it is returning ADD.
This is due to the fact that Add(x) == x when there is only one argument instead of two in the Add()

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is actually a special case thats why i have included it.

Copy link
Member

Choose a reason for hiding this comment

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

You can at least remove the redundant parentheses.

Copy link
Member

Choose a reason for hiding this comment

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

You should construct expressions that don't make sense, like And of a tuple.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ya, it doesn't make sense to include so many parenthesis. :)
Okay, i am writing them..Thanks

@sahilshekhawat
Copy link
Contributor Author

Is everything okay now?

@sahilshekhawat
Copy link
Contributor Author

@asmeurer please have a look, i have added the tests.

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(Basic(Basic(), Basic(x,x+y))) == ADD + 2*BASIC
Copy link
Member

Choose a reason for hiding this comment

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

You have this test twice.

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 removing this.


# 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.

@asmeurer
Copy link
Member

I have just that one comment. The rest looks good.

@sahilshekhawat
Copy link
Contributor Author

I have removed those tests...
Do we have to wait for Travis to finish the tests?

@asmeurer
Copy link
Member

Yes.

@sahilshekhawat
Copy link
Contributor Author

Thank you Aaron, for your help.

asmeurer added a commit that referenced this pull request Apr 12, 2014
Make count_ops() work with logic operations by creating a binary tree.

Fixes #7010
@asmeurer asmeurer merged commit f20add3 into sympy:master Apr 12, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

count_ops() returns 0 for logic expressions
6 participants