From dcd534c475a6bbbcab76b1d9f75c5b62f8926241 Mon Sep 17 00:00:00 2001 From: Juan Mauricio Matera Date: Fri, 29 Nov 2024 22:44:22 -0300 Subject: [PATCH 1/2] Precedences for Del, DifferentialD and CapitalDifferentialD (#100) * Fixes #94 * Run precedence tests using mathics-core * change precedence for DifferentialD and CapitalDifferentialD to the WMA values --- Makefile | 1 + mathics_scanner/data/named-characters.yml | 1 - mathics_scanner/data/operators.yml | 4 +- test/mathics_helper.py | 168 ++++++ test/test_mathics_precedence.py | 606 ++++++++++++++++++++++ 5 files changed, 777 insertions(+), 3 deletions(-) create mode 100644 test/mathics_helper.py create mode 100644 test/test_mathics_precedence.py diff --git a/Makefile b/Makefile index 77d9f98..52a074c 100644 --- a/Makefile +++ b/Makefile @@ -79,6 +79,7 @@ inputrc-unicode: #: Run Mathics core checks check-mathics:: MATHICS_CHARACTER_ENCODING="ASCII" $(PYTHON) -m mathics.docpipeline $o + pytest test/test_mathics_precedence.py #: Remove ChangeLog rmChangeLog: diff --git a/mathics_scanner/data/named-characters.yml b/mathics_scanner/data/named-characters.yml index f58e21e..7c574f1 100644 --- a/mathics_scanner/data/named-characters.yml +++ b/mathics_scanner/data/named-characters.yml @@ -6920,7 +6920,6 @@ Nor: has-unicode-inverse: false is-letter-like: false operator-name: Nor - # No precedences since this gets transformed to Not[Or[expr]] unicode-equivalent: "\u22BD" unicode-equivalent-name: NOR unicode-reference: https://www.compart.com/en/unicode/U+22BD diff --git a/mathics_scanner/data/operators.yml b/mathics_scanner/data/operators.yml index de6fa78..7d8a844 100644 --- a/mathics_scanner/data/operators.yml +++ b/mathics_scanner/data/operators.yml @@ -490,7 +490,7 @@ Cap: CapitalDifferentialD: Precedence-Function: 550 - precedence: 560 + precedence: 550 WolframLanguageData: WolframLanguageData-corrected: 23 UnicodeCharacters.tr: 630 @@ -1119,7 +1119,7 @@ DifferenceDelta: DifferentialD: Precedence-Function: 550 - precedence: 560 + precedence: 550 WolframLanguageData: WolframLanguageData-corrected: 23 UnicodeCharacters.tr: 630 diff --git a/test/mathics_helper.py b/test/mathics_helper.py new file mode 100644 index 0000000..b428f88 --- /dev/null +++ b/test/mathics_helper.py @@ -0,0 +1,168 @@ +# -*- coding: utf-8 -*- +import os.path as osp +import time +from typing import Optional + +from mathics.core.load_builtin import import_and_load_builtins +from mathics.session import MathicsSession + +import_and_load_builtins() + +# Set up a Mathics session with definitions. +# For consistency set the character encoding ASCII which is +# the lowest common denominator available on all systems. +session = MathicsSession(character_encoding="ASCII") + +# Set up a data path that can be used in testing +data_dir = osp.normpath(osp.join(osp.dirname(__file__), "data")) + + +def reset_session(add_builtin=True, catch_interrupt=False): + """ + reset the session cleaning all the definitions. + """ + global session + session.reset() + session.evaluate("SetDirectory[$TemporaryDirectory];") + + +def evaluate_value(str_expr: str): + return session.evaluate(str_expr).value + + +def evaluate(str_expr: str): + return session.evaluate(str_expr) + + +def check_evaluation( + str_expr: Optional[str], + str_expected: Optional[str] = None, + failure_message: str = "", + hold_expected: bool = False, + to_string_expr: bool = True, + to_string_expected: bool = True, + to_python_expected: bool = False, + expected_messages: Optional[tuple] = None, +): + """ + Helper function to test Mathics expression against + its results. + + Compares the expressions represented by ``str_expr`` and ``str_expected`` by + evaluating the first, and optionally, the second. If omitted, `str_expected` + is assumed to be `"Null"`. + + str_expr: The expression to be tested. If its value is ``None``, the session is + reset. + At the beginning of each set of pytests, it is important to call + ``check_evaluation(None)`` to avoid that definitions introduced by + other tests affect the results. + + str_expected: The expected result. The value ``None`` is equivalent to ``"Null"``. + + failure_message: message shown in case of failure. Use "" for no failure message. + + hold_expected: If ``False`` (default value) the ``str_expected`` is evaluated. + Otherwise, the expression is considered literally. + + to_string_expr: If ``True`` (default value) the result of the evaluation is + converted into a Python string. Otherwise, the expression is kept + as an Expression object. + If this argument is set to ``None``, the session is reset. + + to_string_expected: If ``True`` (default value) the expected expression is + evaluated and then converted to a Python string. result of the + evaluation is converted into a Python string. + If ``False``, the expected expression is kept as an Expression + object. + + to_python_expected: If ``True``, and ``to_string_expected`` is ``False``, the result + of evaluating ``str_expr``is compared against the result of the + evaluation of ``str_expected``, converted into a + Python object. + + expected_messages: If a tuple of strings are passed into + this parameter, messages and prints raised during + the evaluation of ``str_expr`` are compared with the elements of + the list. If ``None``, this comparison + is omitted. + """ + if str_expr is None: + reset_session() + return + if str_expected is None: + str_expected = "Null" + + if to_string_expr: + str_expr = f"ToString[{str_expr}]" + result = evaluate_value(str_expr) + else: + result = evaluate(str_expr) + + outs = [out.text for out in session.evaluation.out] + + if to_string_expected: + if hold_expected: + expected = str_expected + else: + str_expected = f"ToString[{str_expected}]" + expected = evaluate_value(str_expected) + else: + if hold_expected: + if to_python_expected: + expected = str_expected + else: + expected = evaluate(f"HoldForm[{str_expected}]").elements[0] + else: + expected = evaluate(str_expected) + if to_python_expected: + expected = expected.to_python(string_quotes=False) + + print(time.asctime()) + if failure_message: + print((result, expected)) + assert result == expected, failure_message + else: + print((result, expected)) + assert result == expected + + if expected_messages is not None: + msgs = list(expected_messages) + expected_len = len(msgs) + got_len = len(outs) + assert ( + expected_len == got_len + ), f"expected {expected_len}; got {got_len}. Messages: {outs}" + for out, msg in zip(outs, msgs): + if out != msg: + print(f"out:<<{out}>>") + print(" and ") + print(f"expected=<<{msg}>>") + assert False, " do not match." + + +def check_evaluation_as_in_cli( + str_expr: Optional[str] = None, + str_expected: Optional[str] = None, + failure_message: str = "", + expected_messages: Optional[tuple] = None, +): + """ + Use this method when special Symbols like Return, %, %%, + $IterationLimit, $RecursionLimit, etc. are used in the tests. + """ + if str_expr is None: + reset_session() + return + + res = session.evaluate_as_in_cli(str_expr) + if expected_messages is None: + assert len(res.out) == 0 + else: + assert len(res.out) == len(expected_messages) + for li1, li2 in zip(res.out, expected_messages): + assert li1.text == li2 + + if failure_message: + assert res.result == str_expected, failure_message + assert res.result == str_expected diff --git a/test/test_mathics_precedence.py b/test/test_mathics_precedence.py new file mode 100644 index 0000000..fd038c9 --- /dev/null +++ b/test/test_mathics_precedence.py @@ -0,0 +1,606 @@ +""" +Test precedences +""" + +try: + from test.mathics_helper import check_evaluation, evaluate, session + + MATHICS_NOT_INSTALLED = False +except ModuleNotFoundError: + MATHICS_NOT_INSTALLED = True + +import pytest + +WMA_PRECEDENCES = { + "CompoundExpression": 10.0, + "Put": 30.0, + "PutAppend": 30.0, + "Set": 40.0, + "SetDelayed": 40.0, + "UpSet": 40.0, + "UpSetDelayed": 40.0, + "Because": 50.0, + "Therefore": 50.0, + "Postfix": 70.0, + "Colon": 80.0, + "Function": 90.0, + "AddTo": 100.0, + "DivideBy": 100.0, + "SubtractFrom": 100.0, + "TimesBy": 100.0, + "ReplaceAll": 110.0, + "ReplaceRepeated": 110.0, + "RuleDelayed": 120.0, + "Rule": 120.0, + "Condition": 130.0, + "StringExpression": 135.0, + "Optional": 140.0, + "Alternatives": 160.0, + "Repeated": 170.0, + "RepeatedNull": 170.0, + "SuchThat": 180.0, + "DoubleLeftTee": 190.0, + "DoubleRightTee": 190.0, + "DownTee": 190.0, + "LeftTee": 190.0, + "Perpendicular": 190.0, + "RightTee": 190.0, + "UpTee": 190.0, + "Implies": 200.0, + "Equivalent": 205.0, + "And": 215.0, + "Nand": 215.0, + "Nor": 215.0, + "Or": 215.0, + "Xor": 215.0, + "Not": 230.0, + "RoundImplies": 240.0, + "NotReverseElement": 250.0, + "NotSquareSubsetEqual": 250.0, + "NotSquareSupersetEqual": 250.0, + "NotSubset": 250.0, + "NotSubsetEqual": 250.0, + "NotSuperset": 250.0, + "NotSupersetEqual": 250.0, + "ReverseElement": 250.0, + "SquareSubset": 250.0, + "SquareSubsetEqual": 250.0, + "SquareSuperset": 250.0, + "SquareSupersetEqual": 250.0, + "Subset": 250.0, + "SubsetEqual": 250.0, + "Superset": 250.0, + "SupersetEqual": 250.0, + "DoubleLeftArrow": 270.0, + "DoubleLeftRightArrow": 270.0, + "DoubleRightArrow": 270.0, + "DownLeftRightVector": 270.0, + "DownLeftTeeVector": 270.0, + "DownLeftVector": 270.0, + "DownLeftVectorBar": 270.0, + "DownRightTeeVector": 270.0, + "DownRightVector": 270.0, + "DownRightVectorBar": 270.0, + "LeftArrow": 270.0, + "LeftArrowBar": 270.0, + "LeftArrowRightArrow": 270.0, + "LeftRightArrow": 270.0, + "LeftRightVector": 270.0, + "LeftTeeArrow": 270.0, + "LeftTeeVector": 270.0, + "LeftVector": 270.0, + "LeftVectorBar": 270.0, + "LowerLeftArrow": 270.0, + "LowerRightArrow": 270.0, + "RightArrow": 270.0, + "RightArrowBar": 270.0, + "RightArrowLeftArrow": 270.0, + "RightTeeArrow": 270.0, + "RightTeeVector": 270.0, + "RightVector": 270.0, + "RightVectorBar": 270.0, + "ShortLeftArrow": 270.0, + "ShortRightArrow": 270.0, + "UpperLeftArrow": 270.0, + "UpperRightArrow": 270.0, + "DoubleVerticalBar": 280.0, + "NotDoubleVerticalBar": 280.0, + "VerticalBar": 280.0, + "Equal": 290.0, + "Greater": 290.0, + "GreaterEqual": 290.0, + "Less": 290.0, + "LessEqual": 290.0, + "SameQ": 290.0, + "Unequal": 290.0, + "UnsameQ": 290.0, + "Congruent": 290.0, + "CupCap": 290.0, + "DotEqual": 290.0, + "EqualTilde": 290.0, + "Equilibrium": 290.0, + "GreaterEqualLess": 290.0, + "GreaterFullEqual": 290.0, + "GreaterGreater": 290.0, + "GreaterLess": 290.0, + "GreaterTilde": 290.0, + "HumpDownHump": 290.0, + "HumpEqual": 290.0, + "LeftTriangle": 290.0, + "LeftTriangleBar": 290.0, + "LeftTriangleEqual": 290.0, + "LessEqualGreater": 290.0, + "LessFullEqual": 290.0, + "LessGreater": 290.0, + "LessLess": 290.0, + "LessTilde": 290.0, + "NestedGreaterGreater": 290.0, + "NestedLessLess": 290.0, + "NotCongruent": 290.0, + "NotCupCap": 290.0, + "NotGreater": 290.0, + "NotGreaterEqual": 290.0, + "NotGreaterFullEqual": 290.0, + "NotGreaterLess": 290.0, + "NotGreaterTilde": 290.0, + "NotLeftTriangle": 290.0, + "NotLeftTriangleEqual": 290.0, + "NotLess": 290.0, + "NotLessEqual": 290.0, + "NotLessFullEqual": 290.0, + "NotLessGreater": 290.0, + "NotLessTilde": 290.0, + "NotPrecedes": 290.0, + "NotPrecedesSlantEqual": 290.0, + "NotPrecedesTilde": 290.0, + "NotRightTriangle": 290.0, + "NotRightTriangleEqual": 290.0, + "NotSucceeds": 290.0, + "NotSucceedsSlantEqual": 290.0, + "NotSucceedsTilde": 290.0, + "NotTilde": 290.0, + "NotTildeEqual": 290.0, + "NotTildeFullEqual": 290.0, + "NotTildeTilde": 290.0, + "Precedes": 290.0, + "PrecedesEqual": 290.0, + "PrecedesSlantEqual": 290.0, + "PrecedesTilde": 290.0, + "Proportion": 290.0, + "Proportional": 290.0, + "ReverseEquilibrium": 290.0, + "RightTriangle": 290.0, + "RightTriangleBar": 290.0, + "RightTriangleEqual": 290.0, + "Succeeds": 290.0, + "SucceedsEqual": 290.0, + "SucceedsSlantEqual": 290.0, + "SucceedsTilde": 290.0, + "Tilde": 290.0, + "TildeEqual": 290.0, + "TildeFullEqual": 290.0, + "TildeTilde": 290.0, + "DirectedEdge": 295.0, + "UndirectedEdge": 295.0, + "SquareUnion": 300.0, + "UnionPlus": 300.0, + "Span": 305.0, + "SquareIntersection": 305.0, + "MinusPlus": 310.0, + "PlusMinus": 310.0, + "Plus": 310.0, + "Subtract": 310.0, + "CircleMinus": 330.0, + "CirclePlus": 330.0, + "Cup": 340.0, + "Cap": 350.0, + "Coproduct": 360.0, + "VerticalTilde": 370.0, + "Star": 390.0, + "Times": 400.0, + "CenterDot": 410.0, + "CircleTimes": 420.0, + "Vee": 430.0, + "Wedge": 440.0, + "Diamond": 450.0, + "Backslash": 460.0, + "Divide": 470.0, + "Minus": 480.0, + "Dot": 490.0, + "CircleDot": 520.0, + "SmallCircle": 530.0, + "Square": 540.0, + "CapitalDifferentialD": 550.0, + "Del": 550.0, + "DifferentialD": 550.0, + "DoubleDownArrow": 580.0, + "DoubleLongLeftArrow": 580.0, + "DoubleLongLeftRightArrow": 580.0, + "DoubleLongRightArrow": 580.0, + "DoubleUpArrow": 580.0, + "DoubleUpDownArrow": 580.0, + "DownArrow": 580.0, + "DownArrowBar": 580.0, + "DownArrowUpArrow": 580.0, + "DownTeeArrow": 580.0, + "LeftDownTeeVector": 580.0, + "LeftDownVector": 580.0, + "LeftDownVectorBar": 580.0, + "LeftUpDownVector": 580.0, + "LeftUpTeeVector": 580.0, + "LeftUpVector": 580.0, + "LeftUpVectorBar": 580.0, + "LongLeftArrow": 580.0, + "LongLeftRightArrow": 580.0, + "LongRightArrow": 580.0, + "ReverseUpEquilibrium": 580.0, + "RightDownTeeVector": 580.0, + "RightDownVector": 580.0, + "RightDownVectorBar": 580.0, + "RightUpDownVector": 580.0, + "RightUpTeeVector": 580.0, + "RightUpVector": 580.0, + "RightUpVectorBar": 580.0, + "ShortDownArrow": 580.0, + "ShortUpArrow": 580.0, + "UpArrow": 580.0, + "UpArrowBar": 580.0, + "UpArrowDownArrow": 580.0, + "UpDownArrow": 580.0, + "UpEquilibrium": 580.0, + "UpTeeArrow": 580.0, + "Power": 590.0, + "StringJoin": 600.0, + "Factorial": 610.0, + "Factorial2": 610.0, + "Apply": 620.0, + "Map": 620.0, + "Prefix": 640.0, + "Decrement": 660.0, + "Increment": 660.0, + "PreDecrement": 660.0, + "PreIncrement": 660.0, + "Unset": 670.0, + "Information": 670.0, + "GreaterSlantEqual": 670.0, + "LessSlantEqual": 670.0, + "Derivative": 670.0, + "MapApply": 670.0, + "PatternTest": 680.0, + "Get": 720.0, + "MessageName": 750.0, +} + +SORTED_SYMBOLS_BY_PRECEDENCE = [ + "CompoundExpression", + "Put", + "PutAppend", + "Set", + "SetDelayed", + "UpSet", + "UpSetDelayed", + "Because", + "Therefore", + "Postfix", + "Colon", + "Function", + "AddTo", + "DivideBy", + "SubtractFrom", + "TimesBy", + "ReplaceAll", + "ReplaceRepeated", + "RuleDelayed", + "Rule", + "Condition", + "StringExpression", + "Optional", + "Alternatives", + "Repeated", + "RepeatedNull", + "SuchThat", + "DoubleLeftTee", + "DoubleRightTee", + "DownTee", + "LeftTee", + "Perpendicular", # 190 + "RightTee", # 190 + # In WMA, `RoundImplies` has a + # larger precedence value (240) than Not (230), + # but behaves as it has a precedence + # between RightTee and UpTee, both with + # a precedence value of 190. + # + # This behavior is not the one in Mathics. For example, + # the input + # a\[RoundImplies]b\[UpTee]c//FullForm + # Is parsed in WMA as + # RoundImplies[a,UpTee[b,c]], + # But in Mathics as + # UpTee[RoundImplies[a, b], c] + # "RoundImplies", # WMA->240, Mathics->200, Must be ~193 + "UpTee", # 190 Must be ~197 + "Implies", # 200 + "Equivalent", + "Nor", + "Or", + "Xor", + "And", + "Nand", + "Not", + "NotReverseElement", + "NotSquareSubsetEqual", + "NotSquareSupersetEqual", + "NotSubset", + "NotSubsetEqual", + "NotSuperset", + "NotSupersetEqual", + "ReverseElement", + "SquareSubset", + "SquareSubsetEqual", + "SquareSuperset", + "SquareSupersetEqual", + "Subset", + "SubsetEqual", + "Superset", + "SupersetEqual", + "DoubleLeftArrow", + "DoubleLeftRightArrow", + "DoubleRightArrow", + "DownLeftRightVector", + "DownLeftTeeVector", + "DownLeftVector", + "DownLeftVectorBar", + "DownRightTeeVector", + "DownRightVector", + "DownRightVectorBar", + "LeftArrow", + "LeftArrowBar", + "LeftArrowRightArrow", + "LeftRightArrow", + "LeftRightVector", + "LeftTeeArrow", + "LeftTeeVector", + "LeftVector", + "LeftVectorBar", + "LowerLeftArrow", + "LowerRightArrow", + "RightArrow", + "RightArrowBar", + "RightArrowLeftArrow", + "RightTeeArrow", + "RightTeeVector", + "RightVector", + "RightVectorBar", + "ShortLeftArrow", + "ShortRightArrow", + "UpperLeftArrow", + "UpperRightArrow", + "DoubleVerticalBar", + "NotDoubleVerticalBar", + "VerticalBar", + "Equal", + "Greater", + "GreaterEqual", + "Less", + "LessEqual", + "GreaterSlantEqual", + "LessSlantEqual", + "SameQ", + "Unequal", + "UnsameQ", + "Congruent", + "CupCap", + "DotEqual", + "EqualTilde", + "Equilibrium", + "GreaterEqualLess", + "GreaterFullEqual", + "GreaterGreater", + "GreaterLess", + "GreaterTilde", + "HumpDownHump", + "HumpEqual", + "LeftTriangle", + "LeftTriangleBar", + "LeftTriangleEqual", + "LessEqualGreater", + "LessFullEqual", + "LessGreater", + "LessLess", + "LessTilde", + "NestedGreaterGreater", + "NestedLessLess", + "NotCongruent", + "NotCupCap", + "NotGreater", + "NotGreaterEqual", + "NotGreaterFullEqual", + "NotGreaterLess", + "NotGreaterTilde", + "NotLeftTriangle", + "NotLeftTriangleEqual", + "NotLess", + "NotLessEqual", + "NotLessFullEqual", + "NotLessGreater", + "NotLessTilde", + "NotPrecedes", + "NotPrecedesSlantEqual", + "NotPrecedesTilde", + "NotRightTriangle", + "NotRightTriangleEqual", + "NotSucceeds", + "NotSucceedsSlantEqual", + "NotSucceedsTilde", + "NotTilde", + "NotTildeEqual", + "NotTildeFullEqual", + "NotTildeTilde", + "Precedes", + "PrecedesEqual", + "PrecedesSlantEqual", + "PrecedesTilde", + "Proportion", + "Proportional", + "ReverseEquilibrium", + "RightTriangle", + "RightTriangleBar", + "RightTriangleEqual", + "Succeeds", + "SucceedsEqual", + "SucceedsSlantEqual", + "SucceedsTilde", + "Tilde", + "TildeEqual", + "TildeFullEqual", + "TildeTilde", + # In Mathics, the precedence of these operators is quite low. + # "DirectedEdge", # Mathics 128 , WMA 295 + # "UndirectedEdge", # Mathics 120, WMA 295 + "SquareUnion", + "UnionPlus", + "Span", + "SquareIntersection", + "MinusPlus", + "PlusMinus", + "Plus", + "Subtract", # 310 + # "Integrate", # In Mathics, this has the default precedence. In WMA, 325 + "CircleMinus", # 330 + "CirclePlus", + "Cup", + "Cap", + "Coproduct", + "VerticalTilde", + "Star", + "Times", + "CenterDot", + "CircleTimes", + "Vee", + "Wedge", + "Diamond", + "Backslash", + "Divide", + "Minus", + "Dot", + "CircleDot", + "SmallCircle", + "Square", # 540 + "Del", # In WMA, has the same precedence as DifferentialD and CapitalDifferentialD + "CapitalDifferentialD", # Mathics 560, WMA 550 + "DifferentialD", # Mathics 560, WMA, 550 + "DoubleDownArrow", # 580 + "DoubleLongLeftArrow", + "DoubleLongLeftRightArrow", + "DoubleLongRightArrow", + "DoubleUpArrow", + "DoubleUpDownArrow", + "DownArrow", + "DownArrowBar", + "DownArrowUpArrow", + "DownTeeArrow", + "LeftDownTeeVector", + "LeftDownVector", + "LeftDownVectorBar", + "LeftUpDownVector", + "LeftUpTeeVector", + "LeftUpVector", + "LeftUpVectorBar", + "LongLeftArrow", + "LongLeftRightArrow", + "LongRightArrow", + "ReverseUpEquilibrium", + "RightDownTeeVector", + "RightDownVector", + "RightDownVectorBar", + "RightUpDownVector", + "RightUpTeeVector", + "RightUpVector", + "RightUpVectorBar", + "ShortDownArrow", + "ShortUpArrow", + "UpArrow", + "UpArrowBar", + "UpArrowDownArrow", + "UpDownArrow", + "UpEquilibrium", + "UpTeeArrow", + "Power", + "StringJoin", + "Factorial", + "Factorial2", + "Apply", + "Map", + "MapApply", # In WMA, the default precedence (670) is reported + "Prefix", + "Decrement", + "Increment", + "PreDecrement", + "PreIncrement", + "Unset", + "Derivative", + "PatternTest", + "Get", + "MessageName", + "Information", +] + + +@pytest.mark.skipif(MATHICS_NOT_INSTALLED, reason="Requires Mathics-core installed") +@pytest.mark.parametrize( + ( + "symbol", + "prec", + ), + list(WMA_PRECEDENCES.items()), +) +@pytest.mark.xfail +def test_precedence_values(symbol, prec): + """ + + TrueRelPrecedence[op1_, op2_] := + Module[{formatted = + ToString[ + HoldForm[ope2[ope1[a, b], c]] /. {ope1 -> op1, ope2 -> op2}, + InputForm]}, + Not[Or[StringPart[formatted, 1] == "(", + StringPart[formatted, -1] == ")"]]] + + Transpose[{a, ALLOPS}] // TableForm""" + + mathics_prec = session.evaluate(f"Precedence[{symbol}]").value + print("Check", f"Precedence[{symbol}]=={prec}") + check_evaluation( + f"Precedence[{symbol}]=={prec}", + "True", + to_string_expr=True, + to_string_expected=True, + hold_expected=True, + failure_message=f"Precendece of {symbol} in mathics {mathics_prec} != WMA value {prec}", + expected_messages=None, + ) + + +@pytest.mark.skipif(MATHICS_NOT_INSTALLED, reason="Requires Mathics-core installed") +def test_precedence_order(): + """ + Test the precedence order. + This is a slighly flexible test, which does not + requires the numerical coincidence of the Precedence values + with WMA, but just to preserve the order. + """ + precedence_values = [ + session.evaluate(f"Precedence[{symbol}]").value + for symbol in SORTED_SYMBOLS_BY_PRECEDENCE + ] + fails = [] + for i in range(len(precedence_values) - 1): + if precedence_values[i] > precedence_values[i + 1]: + fails.append( + f"Precedence[{SORTED_SYMBOLS_BY_PRECEDENCE[i]}]={precedence_values[i]}>" + f"{precedence_values[i+1]}=Precedence[{SORTED_SYMBOLS_BY_PRECEDENCE[i+1]}]" + ) + for fail in fails: + print(fail) + assert len(fails) == 0 From b51e4db3ed18a3d571126944cfb7339892fd22b4 Mon Sep 17 00:00:00 2001 From: "R. Bernstein" Date: Sat, 30 Nov 2024 04:28:55 -0500 Subject: [PATCH 2/2] Go back to testing using Mathics core master (#102) --- .github/workflows/mathics.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/mathics.yml b/.github/workflows/mathics.yml index d709091..f6fefd0 100644 --- a/.github/workflows/mathics.yml +++ b/.github/workflows/mathics.yml @@ -31,9 +31,7 @@ jobs: - name: Test Mathics3 run: | # Until next Mathics3/mathics-core release is out... - # git clone https://github.com/Mathics3/mathics-core.git - # Until next operator-info-from-JSON is merges - git clone -b operator-info-from-JSON https://github.com/Mathics3/mathics-core.git + git clone https://github.com/Mathics3/mathics-core.git cd mathics-core/ make PIP_INSTALL_OPTS='[full]' # pip install Mathics3[full]