diff --git a/integration_tests/symbolics_02.py b/integration_tests/symbolics_02.py index c3f4df98c2..11c8e9fa89 100644 --- a/integration_tests/symbolics_02.py +++ b/integration_tests/symbolics_02.py @@ -103,4 +103,9 @@ def test_symbolic_operations(): assert(a.is_integer == True) assert(c.is_integer == True) + # is_positive check + assert(a.is_positive == True) + assert(b.is_positive == False) + assert(c.is_positive == False) + test_symbolic_operations() diff --git a/src/libasr/pass/intrinsic_function_registry.h b/src/libasr/pass/intrinsic_function_registry.h index 99f9e129c2..e81feeeabd 100644 --- a/src/libasr/pass/intrinsic_function_registry.h +++ b/src/libasr/pass/intrinsic_function_registry.h @@ -161,6 +161,7 @@ inline std::string get_intrinsic_name(int x) { INTRINSIC_NAME_CASE(SymbolicSinQ) INTRINSIC_NAME_CASE(SymbolicGetArgument) INTRINSIC_NAME_CASE(SymbolicIsInteger) + INTRINSIC_NAME_CASE(SymbolicIsPositive) default : { throw LCompilersException("pickle: intrinsic_id not implemented"); } @@ -460,6 +461,8 @@ namespace IntrinsicElementalFunctionRegistry { {nullptr, &SymbolicGetArgument::verify_args}}, {static_cast(IntrinsicElementalFunctions::SymbolicIsInteger), {nullptr, &SymbolicIsInteger::verify_args}}, + {static_cast(IntrinsicElementalFunctions::SymbolicIsPositive), + {nullptr, &SymbolicIsPositive::verify_args}}, }; static const std::map& intrinsic_function_id_to_name = { @@ -747,6 +750,8 @@ namespace IntrinsicElementalFunctionRegistry { "SymbolicGetArgument"}, {static_cast(IntrinsicElementalFunctions::SymbolicIsInteger), "SymbolicIsInteger"}, + {static_cast(IntrinsicElementalFunctions::SymbolicIsPositive), + "SymbolicIsPositive"}, }; @@ -897,6 +902,7 @@ namespace IntrinsicElementalFunctionRegistry { {"SinQ", {&SymbolicSinQ::create_SymbolicSinQ, &SymbolicSinQ::eval_SymbolicSinQ}}, {"GetArgument", {&SymbolicGetArgument::create_SymbolicGetArgument, &SymbolicGetArgument::eval_SymbolicGetArgument}}, {"is_integer", {&SymbolicIsInteger::create_SymbolicIsInteger, &SymbolicIsInteger::eval_SymbolicIsInteger}}, + {"is_positive", {&SymbolicIsPositive::create_SymbolicIsPositive, &SymbolicIsPositive::eval_SymbolicIsPositive}}, }; 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 efe6b96091..23b5be711d 100644 --- a/src/libasr/pass/intrinsic_functions.h +++ b/src/libasr/pass/intrinsic_functions.h @@ -162,6 +162,7 @@ enum class IntrinsicElementalFunctions : int64_t { SymbolicSinQ, SymbolicGetArgument, SymbolicIsInteger, + SymbolicIsPositive, // ... }; @@ -5859,6 +5860,7 @@ create_symbolic_query_macro(SymbolicPowQ) create_symbolic_query_macro(SymbolicLogQ) create_symbolic_query_macro(SymbolicSinQ) create_symbolic_query_macro(SymbolicIsInteger) +create_symbolic_query_macro(SymbolicIsPositive) #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 3218cd3ede..f71bf6b2c0 100644 --- a/src/libasr/pass/replace_symbolic.cpp +++ b/src/libasr/pass/replace_symbolic.cpp @@ -268,6 +268,15 @@ class ReplaceSymbolicVisitor : public PassUtils::PassVisitor(*expr)) { ASR::IntrinsicElementalFunction_t* intrinsic_func = ASR::down_cast(expr); @@ -280,6 +289,7 @@ class ReplaceSymbolicVisitor : public PassUtils::PassVisitorm_args[0], intrinsic_func->m_args[1]); } + case LCompilers::ASRUtils::IntrinsicElementalFunctions::SymbolicIsPositive: { + return basic_is_positive(loc, intrinsic_func->m_args[0]); + } // (sym_name, n) where n = 16, 15, ... as the right value of the // IntegerCompare node as it represents SYMENGINE_ADD through SYMENGINE_ENUM BASIC_ATTR(AddQ, 16) diff --git a/src/lpython/semantics/python_attribute_eval.h b/src/lpython/semantics/python_attribute_eval.h index ba47934f99..369b8486a5 100644 --- a/src/lpython/semantics/python_attribute_eval.h +++ b/src/lpython/semantics/python_attribute_eval.h @@ -48,7 +48,8 @@ struct AttributeHandler { {"diff", &eval_symbolic_diff}, {"expand", &eval_symbolic_expand}, {"has", &eval_symbolic_has_symbol}, - {"is_integer", &eval_symbolic_is_integer} + {"is_integer", &eval_symbolic_is_integer}, + {"is_positive", &eval_symbolic_is_positive} }; } @@ -576,6 +577,19 @@ struct AttributeHandler { return create_function(al, loc, args_with_list, diag); } + static ASR::asr_t* eval_symbolic_is_positive(ASR::expr_t *s, Allocator &al, const Location &loc, + Vec &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_positive"); + return create_function(al, loc, args_with_list, diag); + } + }; // AttributeHandler } // namespace LCompilers::LPython