From bcddb885d234de8a2c12ab1b879d75b3b5ee540e Mon Sep 17 00:00:00 2001 From: Juan Mauricio Matera Date: Wed, 7 Oct 2026 08:54:36 -0300 Subject: [PATCH 1/3] 1. Add a rule for ``Element[elem_,Algebraic]`` since sympy does not handle this set. 2. wrong call to method ``Import.self.eval_element_list`` in importexport 3. `SameQ.eval_list` must be `SameQ.eval` to overwrite the parent class. 4. Literal `ExpressionPattern`s should be ordered by the Expression element_order. 5. Orderless expressions mark themselves as `isliteral` when they are. --- mathics/builtin/arithmetic.py | 9 +++++++++ mathics/builtin/import_export/importexport.py | 4 +++- .../builtin/testing_expressions/equality_inequality.py | 4 ++-- mathics/core/keycomparable.py | 2 ++ mathics/core/pattern/base.py | 3 +++ mathics/core/pattern/orderless.py | 4 ++++ 6 files changed, 23 insertions(+), 3 deletions(-) diff --git a/mathics/builtin/arithmetic.py b/mathics/builtin/arithmetic.py index 3107a67c0c..2071f44d56 100644 --- a/mathics/builtin/arithmetic.py +++ b/mathics/builtin/arithmetic.py @@ -539,6 +539,12 @@ def eval_wrong_domain( evaluation.message("Element", "bset", domain) return None + def eval_algebraic(self, elem: baseElement, evaluation: Evaluation): + """Element[elem_, Algebraics]""" + if elem.to_sympy().is_algebraic: + return SymbolTrue + return SymbolFalse + def eval_Element_alternatives( self, elems: BaseElement, domain: BaseElement, evaluation: Evaluation ) -> Expression | None | Symbol: @@ -574,6 +580,9 @@ def to_sympy(self, expr, **kwargs): sympy_domain = sympy.Rationals case domain if domain is SymbolReals: sympy_domain = sympy.Reals + # Not implemented in sympy... + # case domain if domain is SymbolAlgebraics: + # sympy_domain = sympy.S.Algebraics case _: raise RuntimeError("Unknown domain {domain}") return sympy.Contains(arg.to_sympy(), sympy_domain) diff --git a/mathics/builtin/import_export/importexport.py b/mathics/builtin/import_export/importexport.py index 8acac13adb..3425fdb440 100644 --- a/mathics/builtin/import_export/importexport.py +++ b/mathics/builtin/import_export/importexport.py @@ -463,7 +463,9 @@ def import_setup(self, source, evaluation) -> tuple: def eval(self, source, evaluation, options={}): "Import[source_, OptionsPattern[]]" - return self.eval_element_list(source, ListExpression(), evaluation, options) + return self.eval_with_element_list( + source, ListExpression(), evaluation, options + ) def eval_elements_query(self, source, evaluation, options={}): """Import[source_String, "Elements", OptionsPattern[]]""" diff --git a/mathics/builtin/testing_expressions/equality_inequality.py b/mathics/builtin/testing_expressions/equality_inequality.py index 9dcf496b35..ced4dbdc91 100644 --- a/mathics/builtin/testing_expressions/equality_inequality.py +++ b/mathics/builtin/testing_expressions/equality_inequality.py @@ -836,7 +836,7 @@ class SameQ(_ComparisonOperator): summary_text = "literal symbolic identity" - def eval_list(self, elements, evaluation: Evaluation): + def eval(self, elements, evaluation: Evaluation): "%(name)s[elements___]" elements_sequence = elements.get_sequence() if len(elements_sequence) <= 1: @@ -972,7 +972,7 @@ class UnsameQ(_ComparisonOperator): summary_text = "not literal symbolic identity" - def eval_list(self, elements, evaluation: Evaluation): + def eval(self, elements, evaluation: Evaluation): "%(name)s[elements___]" elements_sequence = elements.get_sequence() if len(elements_sequence) <= 1: diff --git a/mathics/core/keycomparable.py b/mathics/core/keycomparable.py index b505178a34..a0aa41509e 100644 --- a/mathics/core/keycomparable.py +++ b/mathics/core/keycomparable.py @@ -248,6 +248,8 @@ def __ne__(self, other) -> bool: # The numeric magic code for an expression BASIC_EXPRESSION_PATTERN_SORT_KEY = MAGIC_ATOM_SORT_KEY + PATTERN_SORT_KEY_IS_EXPRESSION +# TODO: Mark that it is an expression but literal. +BASIC_LITERAL_EXPRESSION_PATTERN_SORT_KEY = MAGIC_ATOM_SORT_KEY # Blanks BLANK_WITH_PATTERN_PATTERN_SORT_KEY = ( diff --git a/mathics/core/pattern/base.py b/mathics/core/pattern/base.py index a34df447d6..16b6f96c41 100644 --- a/mathics/core/pattern/base.py +++ b/mathics/core/pattern/base.py @@ -28,6 +28,7 @@ from mathics.core.keycomparable import ( BASIC_ATOM_PATTERN_SORT_KEY, BASIC_EXPRESSION_PATTERN_SORT_KEY, + BASIC_LITERAL_EXPRESSION_PATTERN_SORT_KEY, END_OF_LIST_PATTERN_SORT_KEY, ) from mathics.core.symbols import Atom, Symbol @@ -478,6 +479,8 @@ def __init__( ] def _build_pattern_sort_key(self) -> tuple: + if self.isliteral: + return (BASIC_LITERAL_EXPRESSION_PATTERN_SORT_KEY, self.expr.element_order) return ( BASIC_EXPRESSION_PATTERN_SORT_KEY, self.head.pattern_precedence, diff --git a/mathics/core/pattern/orderless.py b/mathics/core/pattern/orderless.py index ef7d478229..d09aeb4111 100644 --- a/mathics/core/pattern/orderless.py +++ b/mathics/core/pattern/orderless.py @@ -324,6 +324,10 @@ def __init__( super().__init__(expression, attributes, evaluation) self.attributes = attributes self.sort() + if not (A_ONE_IDENTITY + A_FLAT) & attributes: + self.isliteral = self.head.isliteral and all( + element.isliteral for element in self.elements + ) def _yield_sequence_wrappings(self, items: Tuple, yield_func: Callable): """Orderless case: one Sequence[...] wrapping per permutation.""" From d8ba4d85cb069d898f2f21c604de9c4d9b28c4a0 Mon Sep 17 00:00:00 2001 From: Juan Mauricio Matera Date: Wed, 7 Oct 2026 09:08:44 -0300 Subject: [PATCH 2/3] adjust test --- mathics/builtin/assignments/types.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mathics/builtin/assignments/types.py b/mathics/builtin/assignments/types.py index 14ed82be85..f9ef414c90 100644 --- a/mathics/builtin/assignments/types.py +++ b/mathics/builtin/assignments/types.py @@ -153,11 +153,11 @@ class SubValues(Builtin): >> f[1][x_] := x >> f[2][x_] := x ^ 2 >> SubValues[f] - = {HoldPattern[f[2][x_]] ⧴ x ^ 2, HoldPattern[f[1][x_]] ⧴ x} + = {HoldPattern[f[1][x_]] ⧴ x, HoldPattern[f[2][x_]] ⧴ x ^ 2} >> Definition[f] - = f[2][x_] = x^2 + = f[1][x_] = x . - . f[1][x_] = x + . f[2][x_] = x^2 """ attributes = A_HOLD_ALL | A_PROTECTED From 44617fcd137f1d8e12bd34a3bc5c20fdc2f5b9dd Mon Sep 17 00:00:00 2001 From: Juan Mauricio Matera Date: Wed, 7 Oct 2026 09:15:35 -0300 Subject: [PATCH 3/3] fix typo. Import SymbolRoot in mathics.builtin.numbers.calculus --- mathics/builtin/arithmetic.py | 2 +- mathics/builtin/numbers/calculus.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/mathics/builtin/arithmetic.py b/mathics/builtin/arithmetic.py index 2071f44d56..efde223d82 100644 --- a/mathics/builtin/arithmetic.py +++ b/mathics/builtin/arithmetic.py @@ -539,7 +539,7 @@ def eval_wrong_domain( evaluation.message("Element", "bset", domain) return None - def eval_algebraic(self, elem: baseElement, evaluation: Evaluation): + def eval_algebraic(self, elem: BaseElement, evaluation: Evaluation): """Element[elem_, Algebraics]""" if elem.to_sympy().is_algebraic: return SymbolTrue diff --git a/mathics/builtin/numbers/calculus.py b/mathics/builtin/numbers/calculus.py index 477faf33e9..20fab40840 100644 --- a/mathics/builtin/numbers/calculus.py +++ b/mathics/builtin/numbers/calculus.py @@ -76,6 +76,7 @@ SymbolList, SymbolLog, SymbolNIntegrate, + SymbolRoot, SymbolRule, SymbolSequence, SymbolSeries,