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

Added support for assert through SymbolicCompare #2057

Merged
merged 3 commits into from
Jun 30, 2023

Conversation

anutosh491
Copy link
Collaborator

@anutosh491 anutosh491 commented Jun 29, 2023

The Pr adds support for the following

  1. Freeing the basic variables declared throughout the C generated code . For eg
(lf) anutosh491@spbhat68:~/lpython/lpython$ cat examples/expr2.py 
from sympy import Symbol, pi
from lpython import S

def main0():
    x: S = Symbol('x')
    y: S = Symbol('y')
    print(pi + S(100))

main0()

// Implementations
void main0()
{
    basic x;
    basic_new_stack(x);
    basic y;
    basic_new_stack(y);
    symbol_set(x, "x");
    symbol_set(y, "y");
    basic queue2;
    basic_new_stack(queue2);
    basic queue3;
    basic_new_stack(queue3);
    basic_const_pi(queue3);
    basic queue4;
    basic_new_stack(queue4);
    integer_set_si(queue4, 100);
    basic_add(queue2, queue3, queue4);
    printf("%s\n", basic_str(queue2));
    basic_free_stack(queue4);
    basic_free_stack(queue3);
    basic_free_stack(queue2);
    basic_free_stack(y);
    basic_free_stack(x);
}
  1. Support equal to and not equal to operators through assert
from sympy import Symbol, pi
from lpython import S

def test_operator_chaining():
    w: S = S(2)
    x: S = Symbol('x')
    y: S = Symbol('y')
    z: S = Symbol('z')

    a: S = x * w
    b: S = a + pi
    c: S = b / z
    d: S = c ** w

    assert(a == S(2)*x)
    assert(b == pi + S(2)*x)
    assert(c == (pi + S(2)*x)/z)
    assert(d == (pi + S(2)*x)**S(2)/z**S(2))

All test files have been updated to use assert

@anutosh491
Copy link
Collaborator Author

anutosh491 commented Jun 29, 2023

@certik
There are essentially two things I would like to point out here

  1. Firstly for comparison operators ( ==, != etc) , we can have two procedures I think
    i) We could have define something like SymbolicCompare( just like StringCompare, ListCompare etc) whenever we are comparing two symbolic expressions. Here would have to resolve stuff through visit_SymbolicCompare
    ii) I think we can also end up introducing SymbolicEqualTo , SymbolicNotEqualTo as intrinsic function nodes (just like SymbolicAdd, SymbolicMul) . Here we would have to resolve stuff through visit_IntrinsicFunction through the switch case where we can implement logic for SymbolicEqualTo etc

I've chosen the first one as of now . I don't know of particular advantages to the second approach and the first approach was doable easily.

  1. Any approach we choose there still remains a concern . So the file for symengine's C wrapper (https://github.com/symengine/symengine/blob/2b575b9be9bb499d866dc3e411e6368ca0d1bb42/symengine/cwrapper.h#L256) essentially has function only to deal with == and !=

Once I implemented SymbolicCompare, I thought I might as well handle other comparison operators too like (>, < , >= etc) but then I realized that there are no functions to handle these . I hope I've not overlooked anything , you could check once .
So we have basic_eq and basic_neq for == and != but no functions for others.
So we can do the following as of now

>>> x = Symbol('x')
>>> y = Symbol('y')
>>> x == y
False
>>> x != y
True

But not

>>> x > y
x > y
>>> x <= y
x <= y

Well it does serve our purpose as of now which is using assert instead of print while framing tests but we might want to consider this at some point !

@certik
Copy link
Contributor

certik commented Jun 29, 2023

I think the new node SymbolicCompare is fine. We can later add SymbolicBinOp as well (right now we added it inside the IntrinsicFunction).

Can you please separate this PR into two PRs, one for freeing variables, the other one for adding support for assert/compare?

Keep the print statements in the test, they test that printing works. And the assert tests that the result what we print is correct.

Otherwise it looks good!

Yes, only support != and == for now. The other operators are meant to create an equation, not really a comparison that returns true or false. In fact, even != and == can be used to construct an equation, but I would keep the SymPy usage, where == and != return true or false, and is used to compare expressions. We'll use other mechanisms to construct an equation.

@anutosh491
Copy link
Collaborator Author

anutosh491 commented Jun 29, 2023

Can you please separate this PR into two PRs, one for freeing variables, the other one for adding support for assert/compare?

Well most of the changes here are to support the assert statement . The code for freeing variables is actually quite minimal if you see.

  1. Defining a set to store released variables
  2. Adding queue[queue_front] to the set whenever we move queue_front by 1
  3. Finally a for loop to get elements out of the set , and add it to the main function through basic_free_stack(var)
    So it's around 7-8 lines overall , might not need a new PR.

Keep the print statements in the test, they test that printing works. And the assert tests that the result what we print is correct.

Yes, this should be done ! I'll do it in the following commit

@anutosh491 anutosh491 requested a review from certik June 29, 2023 16:56
@certik
Copy link
Contributor

certik commented Jun 30, 2023

It's hard to review multiple independent changes. Please separate the PRs, that way we can ensure that each change is clean and we can merge it.

@anutosh491
Copy link
Collaborator Author

Sure I'll do that right now !

@anutosh491 anutosh491 changed the title Added support for assert and freeing basic variables Added support for assert through SymbolicCompare Jun 30, 2023
@anutosh491
Copy link
Collaborator Author

anutosh491 commented Jun 30, 2023

I've removed the changes related to freeing of variables , hope that makes it easier for you to review . Nothing changes, the tests should still pass as everything is same except we are not freeing the stack space at the end . I'll raise a pr for that as soon as this goes in.

Copy link
Contributor

@certik certik left a comment

Choose a reason for hiding this comment

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

I think this looks great!

@certik certik enabled auto-merge (squash) June 30, 2023 04:21
@certik certik merged commit c210323 into lcompilers:main Jun 30, 2023
8 checks passed
@certik
Copy link
Contributor

certik commented Jun 30, 2023

@anutosh491 go ahead and submit a PR for the freeing of variables.

@anutosh491
Copy link
Collaborator Author

I'll do it right away !Give me 5 minutes.

@anutosh491 anutosh491 deleted the GSoC_PR4 branch June 30, 2023 04:51
@anutosh491 anutosh491 mentioned this pull request Jul 3, 2023
9 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants