From 845c23be2bc0740b65678bb7565d0f4c4c895279 Mon Sep 17 00:00:00 2001 From: anutosh491 Date: Thu, 29 Jun 2023 16:15:54 +0530 Subject: [PATCH 1/3] Added support for assert and freeing basic variables --- integration_tests/symbolics_01.py | 3 +- integration_tests/symbolics_02.py | 12 +++--- integration_tests/symbolics_03.py | 7 +++- integration_tests/symbolics_04.py | 11 +++--- src/libasr/ASR.asdl | 1 + src/libasr/codegen/asr_to_c.cpp | 8 +++- src/libasr/codegen/asr_to_c_cpp.h | 43 +++++++++++++++++++++ src/lpython/semantics/python_ast_to_asr.cpp | 2 + 8 files changed, 70 insertions(+), 17 deletions(-) diff --git a/integration_tests/symbolics_01.py b/integration_tests/symbolics_01.py index 9c1a0e9096..04e1c2e18e 100644 --- a/integration_tests/symbolics_01.py +++ b/integration_tests/symbolics_01.py @@ -6,6 +6,7 @@ def main0(): y: S = Symbol('y') x = pi z: S = x + y - print(z) + assert(z == pi + y) + assert(z != S(2)*pi + y) main0() \ No newline at end of file diff --git a/integration_tests/symbolics_02.py b/integration_tests/symbolics_02.py index 2bc24e8511..549e9e9d5a 100644 --- a/integration_tests/symbolics_02.py +++ b/integration_tests/symbolics_02.py @@ -7,28 +7,28 @@ def test_symbolic_operations(): # Addition z: S = x + y - print(z) # Expected: x + y + assert(z == x + y) # Subtraction w: S = x - y - print(w) # Expected: x - y + assert(w == x - y) # Multiplication u: S = x * y - print(u) # Expected: x*y + assert(u == x * y) # Division v: S = x / y - print(v) # Expected: x/y + assert(v == x / y) # Power p: S = x ** y - print(p) # Expected: x**y + assert(p == x ** y) # Casting a: S = S(100) b: S = S(-100) c: S = a + b - print(c) # Expected: 0 + assert(c == S(0)) test_symbolic_operations() diff --git a/integration_tests/symbolics_03.py b/integration_tests/symbolics_03.py index 12295fd0e7..8dc91a9720 100644 --- a/integration_tests/symbolics_03.py +++ b/integration_tests/symbolics_03.py @@ -6,13 +6,16 @@ def test_operator_chaining(): x: S = Symbol('x') y: S = Symbol('y') z: S = Symbol('z') - Pi: S = Symbol('pi') a: S = x * w - b: S = a + Pi + 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)) print(a) # Expected: 2*x print(b) # Expected: pi + 2*x print(c) # Expected: (pi + 2*x)/z diff --git a/integration_tests/symbolics_04.py b/integration_tests/symbolics_04.py index 32cb8df66c..c6d0a5d551 100644 --- a/integration_tests/symbolics_04.py +++ b/integration_tests/symbolics_04.py @@ -13,6 +13,7 @@ def test_chained_operations(): result: S = (w ** S(2) - pi) + S(3) # Print Statements + assert(result == S(3) + (a -b)**S(2)*(x + y)**S(2)/(z + pi)**S(2) - pi) print(result) # Expected: 3 + (a - b)**2*(x + y)**2/(z + pi)**2 - pi @@ -29,13 +30,11 @@ def test_chained_operations(): result = (z + e) * (a - b) # Print Statements + assert(result == (a - b)*(e + ((S(5) + pi)*(S(-10) + (e + c*d)/f))**(S(2)/(d + f)))) print(result) # Expected: (a - b)*(e + ((5 + pi)*(-10 + (e + c*d)/f))**(2/(d + f))) - print(x) - # Expected: (e + c*d)/f - print(y) - # Expected: (5 + pi)*(-10 + (e + c*d)/f) - print(z) - # Expected: ((5 + pi)*(-10 + (e + c*d)/f))**(2/(d + f)) + assert(x == (e + c*d)/f) + assert(y == (S(5) + pi)*(S(-10) + (e + c*d)/f)) + assert(z == ((S(5) + pi)*(S(-10) + (e + c*d)/f))**(S(2)/(d + f))) test_chained_operations() \ No newline at end of file diff --git a/src/libasr/ASR.asdl b/src/libasr/ASR.asdl index 6d92af736d..e4d54f237c 100644 --- a/src/libasr/ASR.asdl +++ b/src/libasr/ASR.asdl @@ -290,6 +290,7 @@ expr | StringChr(expr arg, ttype type, expr? value) | CPtrCompare(expr left, cmpop op, expr right, ttype type, expr? value) + | SymbolicCompare(expr left, cmpop op, expr right, ttype type, expr? value) | DictConstant(expr* keys, expr* values, ttype type) | DictLen(expr arg, ttype type, expr? value) diff --git a/src/libasr/codegen/asr_to_c.cpp b/src/libasr/codegen/asr_to_c.cpp index 1f649059b6..45fa2534cc 100644 --- a/src/libasr/codegen/asr_to_c.cpp +++ b/src/libasr/codegen/asr_to_c.cpp @@ -1064,15 +1064,19 @@ R"( // Initialise Numpy std::string indent(indentation_level*indentation_spaces, ' '); std::string out = indent; bracket_open++; + visit_expr(*x.m_test); + if (ASR::is_a(*x.m_test)){ + out = symengine_src; + symengine_src = ""; + out += indent; + } if (x.m_msg) { out += "ASSERT_MSG("; - visit_expr(*x.m_test); out += src + ", "; visit_expr(*x.m_msg); out += src + ");\n"; } else { out += "ASSERT("; - visit_expr(*x.m_test); out += src + ");\n"; } bracket_open--; diff --git a/src/libasr/codegen/asr_to_c_cpp.h b/src/libasr/codegen/asr_to_c_cpp.h index e9610667f4..253137f964 100644 --- a/src/libasr/codegen/asr_to_c_cpp.h +++ b/src/libasr/codegen/asr_to_c_cpp.h @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -88,6 +89,7 @@ class SymEngineQueue { std::vector queue; int queue_front = -1; std::string& symengine_src; + std::unordered_set variables_to_free; SymEngineQueue(std::string& symengine_src) : symengine_src(symengine_src) {} @@ -97,14 +99,17 @@ class SymEngineQueue { if(queue_front == -1 || queue_front >= static_cast(queue.size())) { var = "queue" + std::to_string(queue.size()); queue.push_back(var); + if(queue_front == -1) queue_front++; symengine_src = indent + "basic " + var + ";\n"; symengine_src += indent + "basic_new_stack(" + var + ");\n"; } + variables_to_free.insert(queue[queue_front]); return queue[queue_front++]; } void pop() { LCOMPILERS_ASSERT(queue_front != -1 && queue_front < static_cast(queue.size())); + variables_to_free.insert(queue[queue_front]); queue_front++; } }; @@ -781,6 +786,10 @@ R"(#include + ";\n"; } + for (const auto& var : symengine_queue.variables_to_free) { + current_body += indent + "basic_free_stack(" + var + ");\n"; + } + symengine_queue.variables_to_free.clear(); if (decl.size() > 0 || current_body.size() > 0) { sub += "{\n" + decl + current_body + "}\n"; } else { @@ -1952,6 +1961,40 @@ PyMODINIT_FUNC PyInit_lpython_module_)" + fn_name + R"((void) { handle_Compare(x); } + void visit_SymbolicCompare(const ASR::SymbolicCompare_t &x) { + CHECK_FAST_C_CPP(compiler_options, x) + self().visit_expr(*x.m_left); + std::string left_src = symengine_src; + if(ASR::is_a(*x.m_left)){ + symengine_queue.pop(); + } + std::string left = std::move(src); + + self().visit_expr(*x.m_right); + std::string right_src = symengine_src; + if(ASR::is_a(*x.m_right)){ + symengine_queue.pop(); + } + std::string right = std::move(src); + std::string op_str = ASRUtils::cmpop_to_str(x.m_op); + switch (x.m_op) { + case (ASR::cmpopType::Eq) : { + src = "basic_eq(" + left + ", " + right + ") " + op_str + " 1"; + break; + } + case (ASR::cmpopType::NotEq) : { + src = "basic_neq(" + left + ", " + right + ") " + op_str + " 0"; + break; + } + default : { + throw LCompilersException("Symbolic comparison operator: '" + + op_str + + "' is not implemented"); + } + } + symengine_src = left_src + right_src; + } + template void handle_Compare(const T &x) { CHECK_FAST_C_CPP(compiler_options, x) diff --git a/src/lpython/semantics/python_ast_to_asr.cpp b/src/lpython/semantics/python_ast_to_asr.cpp index 5952ffcd2f..0d7b3d52e9 100644 --- a/src/lpython/semantics/python_ast_to_asr.cpp +++ b/src/lpython/semantics/python_ast_to_asr.cpp @@ -6227,6 +6227,8 @@ class BodyVisitor : public CommonVisitor { x.base.base.loc); } tmp = ASR::make_CPtrCompare_t(al, x.base.base.loc, left, asr_op, right, type, value); + } else if (ASR::is_a(*dest_type)) { + tmp = ASR::make_SymbolicCompare_t(al, x.base.base.loc, left, asr_op, right, type, value); } else { throw SemanticError("Compare not supported for type: " + ASRUtils::type_to_str_python(dest_type), x.base.base.loc); From d39ecb68beec467fecc09954b502aec584abebc9 Mon Sep 17 00:00:00 2001 From: anutosh491 Date: Thu, 29 Jun 2023 20:00:56 +0530 Subject: [PATCH 2/3] Added print statements --- integration_tests/symbolics_01.py | 1 + integration_tests/symbolics_02.py | 12 +++++++++--- integration_tests/symbolics_04.py | 5 +++-- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/integration_tests/symbolics_01.py b/integration_tests/symbolics_01.py index 04e1c2e18e..525cf6ab4c 100644 --- a/integration_tests/symbolics_01.py +++ b/integration_tests/symbolics_01.py @@ -6,6 +6,7 @@ def main0(): y: S = Symbol('y') x = pi z: S = x + y + print(z) assert(z == pi + y) assert(z != S(2)*pi + y) diff --git a/integration_tests/symbolics_02.py b/integration_tests/symbolics_02.py index 549e9e9d5a..f22a432606 100644 --- a/integration_tests/symbolics_02.py +++ b/integration_tests/symbolics_02.py @@ -8,27 +8,33 @@ def test_symbolic_operations(): # Addition z: S = x + y assert(z == x + y) + print(z) # Subtraction w: S = x - y assert(w == x - y) + print(w) # Multiplication u: S = x * y assert(u == x * y) - + print(u) + # Division v: S = x / y assert(v == x / y) - + print(v) + # Power p: S = x ** y assert(p == x ** y) - + print(p) + # Casting a: S = S(100) b: S = S(-100) c: S = a + b assert(c == S(0)) + print(c) test_symbolic_operations() diff --git a/integration_tests/symbolics_04.py b/integration_tests/symbolics_04.py index c6d0a5d551..63d30bf3f6 100644 --- a/integration_tests/symbolics_04.py +++ b/integration_tests/symbolics_04.py @@ -15,7 +15,6 @@ def test_chained_operations(): # Print Statements assert(result == S(3) + (a -b)**S(2)*(x + y)**S(2)/(z + pi)**S(2) - pi) print(result) - # Expected: 3 + (a - b)**2*(x + y)**2/(z + pi)**2 - pi # Additional Variables c: S = Symbol('c') @@ -32,9 +31,11 @@ def test_chained_operations(): # Print Statements assert(result == (a - b)*(e + ((S(5) + pi)*(S(-10) + (e + c*d)/f))**(S(2)/(d + f)))) print(result) - # Expected: (a - b)*(e + ((5 + pi)*(-10 + (e + c*d)/f))**(2/(d + f))) assert(x == (e + c*d)/f) + print(x) assert(y == (S(5) + pi)*(S(-10) + (e + c*d)/f)) + print(y) assert(z == ((S(5) + pi)*(S(-10) + (e + c*d)/f))**(S(2)/(d + f))) + print(z) test_chained_operations() \ No newline at end of file From 22a31de7ca028d209d70749556c60ce2f346bd02 Mon Sep 17 00:00:00 2001 From: anutosh491 Date: Fri, 30 Jun 2023 09:24:42 +0530 Subject: [PATCH 3/3] Removed changes related to freeing variables --- src/libasr/codegen/asr_to_c_cpp.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/libasr/codegen/asr_to_c_cpp.h b/src/libasr/codegen/asr_to_c_cpp.h index 253137f964..50268a9148 100644 --- a/src/libasr/codegen/asr_to_c_cpp.h +++ b/src/libasr/codegen/asr_to_c_cpp.h @@ -89,7 +89,6 @@ class SymEngineQueue { std::vector queue; int queue_front = -1; std::string& symengine_src; - std::unordered_set variables_to_free; SymEngineQueue(std::string& symengine_src) : symengine_src(symengine_src) {} @@ -103,13 +102,11 @@ class SymEngineQueue { symengine_src = indent + "basic " + var + ";\n"; symengine_src += indent + "basic_new_stack(" + var + ");\n"; } - variables_to_free.insert(queue[queue_front]); return queue[queue_front++]; } void pop() { LCOMPILERS_ASSERT(queue_front != -1 && queue_front < static_cast(queue.size())); - variables_to_free.insert(queue[queue_front]); queue_front++; } }; @@ -786,10 +783,6 @@ R"(#include + ";\n"; } - for (const auto& var : symengine_queue.variables_to_free) { - current_body += indent + "basic_free_stack(" + var + ");\n"; - } - symengine_queue.variables_to_free.clear(); if (decl.size() > 0 || current_body.size() > 0) { sub += "{\n" + decl + current_body + "}\n"; } else {