diff --git a/integration_tests/symbolics_02.py b/integration_tests/symbolics_02.py index 713aecbacb..c3f4df98c2 100644 --- a/integration_tests/symbolics_02.py +++ b/integration_tests/symbolics_02.py @@ -98,5 +98,9 @@ def test_symbolic_operations(): print(b4) assert(b4 == False) + # is_integer check + assert(pi1.is_integer == False) + assert(a.is_integer == True) + assert(c.is_integer == True) test_symbolic_operations() diff --git a/src/libasr/pass/intrinsic_function_registry.h b/src/libasr/pass/intrinsic_function_registry.h index 550785af36..99f9e129c2 100644 --- a/src/libasr/pass/intrinsic_function_registry.h +++ b/src/libasr/pass/intrinsic_function_registry.h @@ -160,6 +160,7 @@ inline std::string get_intrinsic_name(int x) { INTRINSIC_NAME_CASE(SymbolicLogQ) INTRINSIC_NAME_CASE(SymbolicSinQ) INTRINSIC_NAME_CASE(SymbolicGetArgument) + INTRINSIC_NAME_CASE(SymbolicIsInteger) default : { throw LCompilersException("pickle: intrinsic_id not implemented"); } @@ -457,6 +458,8 @@ namespace IntrinsicElementalFunctionRegistry { {nullptr, &SymbolicSinQ::verify_args}}, {static_cast(IntrinsicElementalFunctions::SymbolicGetArgument), {nullptr, &SymbolicGetArgument::verify_args}}, + {static_cast(IntrinsicElementalFunctions::SymbolicIsInteger), + {nullptr, &SymbolicIsInteger::verify_args}}, }; static const std::map& intrinsic_function_id_to_name = { @@ -742,6 +745,8 @@ namespace IntrinsicElementalFunctionRegistry { "SymbolicSinQ"}, {static_cast(IntrinsicElementalFunctions::SymbolicGetArgument), "SymbolicGetArgument"}, + {static_cast(IntrinsicElementalFunctions::SymbolicIsInteger), + "SymbolicIsInteger"}, }; @@ -891,6 +896,7 @@ namespace IntrinsicElementalFunctionRegistry { {"LogQ", {&SymbolicLogQ::create_SymbolicLogQ, &SymbolicLogQ::eval_SymbolicLogQ}}, {"SinQ", {&SymbolicSinQ::create_SymbolicSinQ, &SymbolicSinQ::eval_SymbolicSinQ}}, {"GetArgument", {&SymbolicGetArgument::create_SymbolicGetArgument, &SymbolicGetArgument::eval_SymbolicGetArgument}}, + {"is_integer", {&SymbolicIsInteger::create_SymbolicIsInteger, &SymbolicIsInteger::eval_SymbolicIsInteger}}, }; static inline bool is_intrinsic_function(const std::string& name) { diff --git a/src/libasr/pass/intrinsic_functions.h b/src/libasr/pass/intrinsic_functions.h index cd407fec2a..879f5bf134 100644 --- a/src/libasr/pass/intrinsic_functions.h +++ b/src/libasr/pass/intrinsic_functions.h @@ -161,6 +161,7 @@ enum class IntrinsicElementalFunctions : int64_t { SymbolicLogQ, SymbolicSinQ, SymbolicGetArgument, + SymbolicIsInteger, // ... }; @@ -5853,6 +5854,7 @@ create_symbolic_query_macro(SymbolicMulQ) create_symbolic_query_macro(SymbolicPowQ) create_symbolic_query_macro(SymbolicLogQ) create_symbolic_query_macro(SymbolicSinQ) +create_symbolic_query_macro(SymbolicIsInteger) #define create_symbolic_unary_macro(X) \ namespace X { \ diff --git a/src/libasr/pass/replace_symbolic.cpp b/src/libasr/pass/replace_symbolic.cpp index 2c86c9a29e..3218cd3ede 100644 --- a/src/libasr/pass/replace_symbolic.cpp +++ b/src/libasr/pass/replace_symbolic.cpp @@ -279,6 +279,7 @@ class ReplaceSymbolicVisitor : public PassUtils::PassVisitor &args, diag::Diagnostics &diag) { + Vec args_with_list; + args_with_list.reserve(al, args.size() + 1); + args_with_list.push_back(al, s); + for(size_t i = 0; i < args.size(); i++) { + args_with_list.push_back(al, args[i]); + } + ASRUtils::create_intrinsic_function create_function = + ASRUtils::IntrinsicElementalFunctionRegistry::get_create_function("is_integer"); + return create_function(al, loc, args_with_list, diag); + } + }; // AttributeHandler } // namespace LCompilers::LPython diff --git a/src/runtime/lpython/lpython.py b/src/runtime/lpython/lpython.py index 9f23b02e9b..d48be834dd 100644 --- a/src/runtime/lpython/lpython.py +++ b/src/runtime/lpython/lpython.py @@ -15,6 +15,11 @@ # data-types +def get_sympy_S(x): + from sympy import S + return S(x) + + type_to_convert_func = { "i1": bool, "i8": int, @@ -34,7 +39,7 @@ "Callable": lambda x: x, "Allocatable": lambda x: x, "Pointer": lambda x: x, - "S": lambda x: x, + "S": get_sympy_S, } class Type: