From ac05d45ea39d7c06d61ab780a63bb8d6bf798d01 Mon Sep 17 00:00:00 2001 From: Stanislav Date: Fri, 16 Oct 2026 02:27:23 +0400 Subject: [PATCH 1/2] Negative, Positive, NonNegative, NonPositive: decide for Infinity and -Infinity These tests only had a rule for NumericQ arguments, and Infinity is not NumericQ, so Negative[Infinity] stayed unevaluated (WMA: False). Add the values for DirectedInfinity[1] and DirectedInfinity[-1]. Co-Authored-By: Claude Opus 5.5 --- .../testing_expressions/numerical_properties.py | 10 ++++++++++ test/builtin/test_testing_expressions.py | 17 +++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/mathics/builtin/testing_expressions/numerical_properties.py b/mathics/builtin/testing_expressions/numerical_properties.py index 6b6612ee5c..55b5a41682 100644 --- a/mathics/builtin/testing_expressions/numerical_properties.py +++ b/mathics/builtin/testing_expressions/numerical_properties.py @@ -258,12 +258,16 @@ class Negative(Builtin): = False >> Negative[a + b] = Negative[a + b] + >> {Negative[Infinity], Negative[-Infinity]} + = {False, True} """ attributes = A_LISTABLE | A_PROTECTED rules = { "Negative[x_?NumericQ]": "If[x < 0, True, False, False]", + "Negative[DirectedInfinity[1]]": "False", + "Negative[DirectedInfinity[-1]]": "True", } summary_text = "test whether an expression is a negative number" @@ -285,6 +289,8 @@ class NonNegative(Builtin): rules = { "NonNegative[x_?NumericQ]": "If[x >= 0, True, False, False]", + "NonNegative[DirectedInfinity[1]]": "True", + "NonNegative[DirectedInfinity[-1]]": "False", } summary_text = "test whether an expression is a non-negative number" @@ -306,6 +312,8 @@ class NonPositive(Builtin): rules = { "NonPositive[x_?NumericQ]": "If[x <= 0, True, False, False]", + "NonPositive[DirectedInfinity[1]]": "False", + "NonPositive[DirectedInfinity[-1]]": "True", } summary_text = "test whether an expression is a non-positive number" @@ -513,6 +521,8 @@ class Positive(Builtin): rules = { "Positive[x_?NumericQ]": "If[x > 0, True, False, False]", + "Positive[DirectedInfinity[1]]": "True", + "Positive[DirectedInfinity[-1]]": "False", } summary_text = "test whether an expression is a positive number" diff --git a/test/builtin/test_testing_expressions.py b/test/builtin/test_testing_expressions.py index 4dd16437f6..eb1c633c61 100644 --- a/test/builtin/test_testing_expressions.py +++ b/test/builtin/test_testing_expressions.py @@ -134,6 +134,23 @@ def test_equality_inequality(str_expr, msgs, str_expected, fail_msg): ("Positive[Sin[{11, 14}]]", None, "{False, True}", None), ("PrimeQ[1]", None, "False", None), ("PrimeQ[2 ^ 255 - 1]", None, "False", None), + # Real infinities + ("{Negative[Infinity], Negative[-Infinity]}", None, "{False, True}", None), + ("{Positive[Infinity], Positive[-Infinity]}", None, "{True, False}", None), + ( + "{NonNegative[Infinity], NonNegative[-Infinity]}", + None, + "{True, False}", + None, + ), + ( + "{NonPositive[Infinity], NonPositive[-Infinity]}", + None, + "{False, True}", + None, + ), + ("Negative[2 {Infinity, 3} - {3, 0}]", None, "{False, False}", None), + ("Negative[ComplexInfinity]", None, "Negative[ComplexInfinity]", None), ], ) def test_numerical_properties(str_expr, msgs, str_expected, fail_msg): From 7bc28810bf5786ac187ba21a8411578efbe55d54 Mon Sep 17 00:00:00 2001 From: Stanislav Date: Fri, 16 Oct 2026 17:32:16 +0400 Subject: [PATCH 2/2] Sign tests of DirectedInfinity[x]: the sign test of the direction x As suggested in review: Positive[DirectedInfinity[x_?NumericQ]] is Positive[x], and likewise for Negative, NonNegative, NonPositive. This covers Infinity and -Infinity, any numeric real direction, and complex directions, which give False as in WMA. ComplexInfinity and symbolic directions stay unevaluated. Co-Authored-By: Claude Opus 5.5 --- .../numerical_properties.py | 12 ++++------- test/builtin/test_testing_expressions.py | 21 +++++++++++++++++++ 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/mathics/builtin/testing_expressions/numerical_properties.py b/mathics/builtin/testing_expressions/numerical_properties.py index 55b5a41682..02300159af 100644 --- a/mathics/builtin/testing_expressions/numerical_properties.py +++ b/mathics/builtin/testing_expressions/numerical_properties.py @@ -266,8 +266,7 @@ class Negative(Builtin): rules = { "Negative[x_?NumericQ]": "If[x < 0, True, False, False]", - "Negative[DirectedInfinity[1]]": "False", - "Negative[DirectedInfinity[-1]]": "True", + "Negative[DirectedInfinity[x_?NumericQ]]": "Negative[x]", } summary_text = "test whether an expression is a negative number" @@ -289,8 +288,7 @@ class NonNegative(Builtin): rules = { "NonNegative[x_?NumericQ]": "If[x >= 0, True, False, False]", - "NonNegative[DirectedInfinity[1]]": "True", - "NonNegative[DirectedInfinity[-1]]": "False", + "NonNegative[DirectedInfinity[x_?NumericQ]]": "NonNegative[x]", } summary_text = "test whether an expression is a non-negative number" @@ -312,8 +310,7 @@ class NonPositive(Builtin): rules = { "NonPositive[x_?NumericQ]": "If[x <= 0, True, False, False]", - "NonPositive[DirectedInfinity[1]]": "False", - "NonPositive[DirectedInfinity[-1]]": "True", + "NonPositive[DirectedInfinity[x_?NumericQ]]": "NonPositive[x]", } summary_text = "test whether an expression is a non-positive number" @@ -521,8 +518,7 @@ class Positive(Builtin): rules = { "Positive[x_?NumericQ]": "If[x > 0, True, False, False]", - "Positive[DirectedInfinity[1]]": "True", - "Positive[DirectedInfinity[-1]]": "False", + "Positive[DirectedInfinity[x_?NumericQ]]": "Positive[x]", } summary_text = "test whether an expression is a positive number" diff --git a/test/builtin/test_testing_expressions.py b/test/builtin/test_testing_expressions.py index eb1c633c61..1ec8ccdd47 100644 --- a/test/builtin/test_testing_expressions.py +++ b/test/builtin/test_testing_expressions.py @@ -151,6 +151,27 @@ def test_equality_inequality(str_expr, msgs, str_expected, fail_msg): ), ("Negative[2 {Infinity, 3} - {3, 0}]", None, "{False, False}", None), ("Negative[ComplexInfinity]", None, "Negative[ComplexInfinity]", None), + # Other directions: the sign test of the direction, as in WMA + ( + "{Positive[DirectedInfinity[1.]], Negative[DirectedInfinity[-1/2]]," + " NonNegative[DirectedInfinity[Pi]], NonPositive[DirectedInfinity[-Sqrt[2]]]}", + None, + "{True, True, True, True}", + None, + ), + ( + "{Positive[DirectedInfinity[I]], Negative[DirectedInfinity[1 + I]]," + " NonNegative[DirectedInfinity[-I]], NonPositive[DirectedInfinity[I]]}", + None, + "{False, False, False, False}", + None, + ), + ( + "Head[Positive[DirectedInfinity[x]]]", + None, + "Positive", + "A symbolic direction is left undecided", + ), ], ) def test_numerical_properties(str_expr, msgs, str_expected, fail_msg):