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 handling chaining of Symbolic operators and printing without assignment . #2051

Merged
merged 5 commits into from
Jun 28, 2023

Conversation

anutosh491
Copy link
Collaborator

@anutosh491 anutosh491 commented Jun 27, 2023

This Pr starts small . For eg

(lf) anutosh491@spbhat68:~/lpython/lpython$ cat examples/expr2.py 
from sympy import pi
def main0():
    print(pi + pi)

main0()

(lf) anutosh491@spbhat68:~/lpython/lpython$ lpython --show-c examples/expr2.py 

// Implementations
void main0()
{
    basic queue0;
    basic_new_stack(queue0);
    basic queue1;
    basic_new_stack(queue1);
    basic_const_pi(queue1);
    basic queue2;
    basic_new_stack(queue2);
    basic_const_pi(queue2);
    basic_add(queue0, queue1, queue2);
    printf("%s\n", basic_str(queue0));
}

(lf) anutosh491@spbhat68:~/lpython/lpython$ lpython --backend=c --enable-symengine examples/expr2.py 
2*pi

But once we have a queue/stack data structure (I've chosen a queue as it is more intuitive at places) in place to generate temporary variables , we can essentially do much more as shown in the comment below.

@anutosh491 anutosh491 marked this pull request as draft June 27, 2023 17:02
@anutosh491
Copy link
Collaborator Author

(lf) anutosh491@spbhat68:~/lpython/lpython$ cat examples/expr2.py 
from sympy import Symbol, pi
def main0():
    x: S = Symbol('x')
    y: S = Symbol('y')
    z: S = (x - S(20)) * (pi + y + S(40))
    x = z
    y = x
    z = y + pi
    print(z)

main0()

(lf) anutosh491@spbhat68:~/lpython/lpython$ lpython --show-c examples/expr2.py 

// Implementations
void main0()
{
    basic x;
    basic_new_stack(x);
    basic y;
    basic_new_stack(y);
    basic z;
    basic_new_stack(z);
    symbol_set(x, "x");
    symbol_set(y, "y");
    basic queue0;
    basic_new_stack(queue0);
    basic queue1;
    basic_new_stack(queue1);
    integer_set_si(queue1, 20);
    basic_sub(queue0, x, queue1);
    basic queue2;
    basic_new_stack(queue2);
    basic queue3;
    basic_new_stack(queue3);
    basic queue4;
    basic_new_stack(queue4);
    basic_const_pi(queue4);
    basic_add(queue3, queue4, y);
    basic queue5;
    basic_new_stack(queue5);
    integer_set_si(queue5, 40);
    basic_add(queue2, queue3, queue5);
    basic_mul(z, queue0, queue2);
    basic_assign(x, z);
    basic_assign(y, x);
    basic queue6;
    basic_new_stack(queue6);
    basic_const_pi(queue6);
    basic_add(z, y, queue6);
    printf("%s\n", basic_str(z));
}

(lf) anutosh491@spbhat68:~/lpython/lpython$ lpython --backend=c --enable-symengine examples/expr2.py 
(-20 + x)*(40 + y + pi) + pi

@anutosh491
Copy link
Collaborator Author

@certik I shall do some more refactoring and explain you the code (mostly the approach) tomorrow in our weekly meeting . I did good amount of testing with random examples and everything works , if you have something particular to test let me know .

@anutosh491
Copy link
Collaborator Author

I've added a test . It might look a bit random but I guess that's the only way we can check all edge cases for operator chaining along with brackets placed randomly . Though I've compared all tests with SymPy and everything looks good

(lf) anutosh491@spbhat68:~/lpython/lpython$ cat examples/expr2.py 
from sympy import Symbol, pi, S
#from lpython import S

def test_chained_operations():
    x: S = Symbol('x')
    y: S = Symbol('y')
    z: S = Symbol('z')
    a: S = Symbol('a')
    b: S = Symbol('b')
    
    # Chained Operations
    w: S = (x + y) * ((a - b) / (pi + z))
    result: S = (w ** S(2) - pi) + S(3)
    
    # Print Statements
    print("Result 1:", result)
    
    # Additional Operations
    c: S = Symbol('c')
    d: S = Symbol('d')
    e: S = Symbol('e')
    f: S = Symbol('f')
    
    # Chained Operations with Additional Variables
    x = (c * d + e) / f
    y = (x - S(10)) * (pi + S(5))
    z = y ** (S(2) / (f + d))
    result = (z + e) * (a - b)
    
    # Print Statements
    print("Result 2:", result)
    print("x:", x)
    print("y:", y)
    print("z:", z)
    
test_chained_operations()
  1. Results through sympy
(lf) anutosh491@spbhat68:~/lpython/lpython$ python examples/expr2.py 
Result 1: (a - b)**2*(x + y)**2/(z + pi)**2 - pi + 3
Result 2: (a - b)*(e + ((-10 + (c*d + e)/f)*(pi + 5))**(2/(d + f)))
x: (c*d + e)/f
y: (-10 + (c*d + e)/f)*(pi + 5)
z: ((-10 + (c*d + e)/f)*(pi + 5))**(2/(d + f))
  1. Results through LPython
(lf) anutosh491@spbhat68:~/lpython/lpython$ lpython --backend=c --enable-symengine examples/expr2.py 
Result 1: 3 + (a - b)**2*(x + y)**2/(z + pi)**2 - pi
Result 2: (a - b)*(e + ((5 + pi)*(-10 + (e + c*d)/f))**(2/(d + f)))
x: (e + c*d)/f
y: (5 + pi)*(-10 + (e + c*d)/f)
z: ((5 + pi)*(-10 + (e + c*d)/f))**(2/(d + f))

@anutosh491
Copy link
Collaborator Author

anutosh491 commented Jun 28, 2023

Actually we might see that there are some differences between how stuff is being printed
Result 1: (a - b)**2*(x + y)**2/(z + pi)**2 - pi + 3 from sympy
vs
Result 1: 3 + (a - b)**2*(x + y)**2/(z + pi)**2 - pi from Lpython

I am not sure why this would happen, maybe some internal differences between how sympy and symengine's C wrapper have been framed . Because the C code generated is absolutely spot on . For eg I'll paste the last few lines for C code for result: S = (w ** S(2) - pi) + S(3)) from Lpython.

    basic queue22;
    basic_new_stack(queue22);
    integer_set_si(queue22, 3);
    basic_add(result, queue17, queue22);
    printf("%s\n", basic_str(result));

As you see S(3) is being added right associatively which is also being shown through basic_add(result, queue17, queue22). But when we link lsymengine and get a result out of it , the 3 is shifted at the front
3 + (a - b)**2*(x + y)**2/(z + pi)**2 - pi

I don't think this might be concerning unless and untill the expressions are same mathematically , though I thought of pointing it out if ever we end up thinking why something like this might be happening .

@anutosh491 anutosh491 marked this pull request as ready for review June 28, 2023 12:11
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 works.

@certik certik merged commit dc3510b into lcompilers:main Jun 28, 2023
8 checks passed
@anutosh491 anutosh491 deleted the GSoC_PR3 branch June 28, 2023 16:59
@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

3 participants