Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions mathics/builtin/list/associations.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
from mathics.eval.lists import list_boxes


class Association(Builtin):
class Association_(Builtin):

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the next PR there will be a mathics.core.atoms.association.Association class. I thought I had stashed away the changes, but this one bleeds through.

"""
<url>
:WMA link:
Expand Down Expand Up @@ -57,10 +57,11 @@ class Association(Builtin):
= {1, 3}
"""

error_idx = 0

attributes = A_HOLD_ALL_COMPLETE | A_PROTECTED

error_idx = 0

name = "Association"
summary_text = "make an association between keys and values"

def eval_makeboxes(self, rules, f, evaluation: Evaluation):
Expand Down
29 changes: 25 additions & 4 deletions mathics/builtin/patterns/rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ def eval_list(
return result

def eval(
self, rules: Expression, evaluation: Evaluation
self, rules: BaseElement, evaluation: Evaluation
) -> OptionalType[BaseElement]:
"""Dispatch[rules_]"""
if not isinstance(rules, Expression):
Expand Down Expand Up @@ -489,6 +489,8 @@ def eval_list(
return result


# rocky: I don't know why, but this class seems to need a lot of
# things that handled differently from normal practice.
class Rule_(InfixOperator):
"""

Expand All @@ -510,20 +512,39 @@ class Rule_(InfixOperator):
"""

attributes = A_SEQUENCE_HOLD | A_PROTECTED

# For some mysterious reason, the below does not work and
# we have to do argument checking as code in eval().
# eval_error = Builtin.generic_argument_error
# expected_args = 2

grouping = "Right"
name = "Rule"
needs_verbatim = True

# FIXME: if we remove this we have problems.
# We should be able to get this from JSON.
# FIXME: We should be able to get the operator from the JSON operator tables.
# However, if we remove the operator class variable assignment, is we have problems.
# Run test/format/test_format.py::test_makeboxes_text for details.
operator = "->"

summary_text = "a replacement rule"

def eval_rule(self, elems, evaluation):
def eval(self, elems, evaluation: Evaluation):
"""Rule[elems___]"""

num_parms = len(elems.get_sequence())
if num_parms != 2:
evaluation.message("Rule", "argrx", "Rule", Integer(num_parms), Integer2)

# "Rule" is a somewhat generic term in WMA and thus Mathics3.
Comment thread
mmatera marked this conversation as resolved.
# Rule semantics and its implementation change depending on the context that the Rule appears in.
# Inside a Set, RuleDelayed, or ReplaceAll expression, the left-hand side of a Rule is a pattern.
# But inside an Association or an Option, it is a key-value pair, with no pattern matching applied
# to the left-hand side.
# As a result, at this point we don't know which context Rule[] might appear, so we have to return
# "None" which keeps the Expression the same. Returning "elems" which you might think would be the
# same thing, is not correct, since the Head symbol "Rule" can get replaced with "Sequence" symbol
# coming into this code.
return None


Expand Down
1 change: 1 addition & 0 deletions mathics/core/pattern.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ def create(
Otherwise, if ``expr`` is an ``Atom``, create and return ``AtomPattern`` for ``expr``.
Otherwise, create and return and ``ExpressionPattern`` for ``expr``.
"""

name = expr.get_head_name()
pattern_object = pattern_objects.get(name)
if pattern_object is not None:
Expand Down
22 changes: 18 additions & 4 deletions mathics/core/rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@
arguments, and then apply a Python "evaluation" function to a Mathics3 Expression.
These kinds of rules are handled by objects in the `FunctionApplyRule` class.

This module contains the classes for these two types of rules.
Finally, Rules are used as KeyValue pairs in an Association or an Options list.
Here, no pattern matching is applied to the left-hand side.

This module contains the classes for the first two non-KeyValue types of rules.

In a `FunctionApplyRule` rule, the match status of a rule depends on the evaluation return.

Expand Down Expand Up @@ -236,13 +239,24 @@ def element_order(self) -> tuple:
# True used to be self.system. Can we remove True?
return tuple((True, self.pattern.element_order))

# The below routines might be needed in the future, if BaseRule becomes
# more BaseElement-like. Right now that's not the situation, probably
# due to the nature of the generality of Rule which causes
# special casing lots of places in the Expression code.

# def get_head_name(self, short=False) -> str:
# return "Rule" if short else "System`Rule"

# def get_lookup_name(self) -> str:
# return "System`Rule"

def get_replace_value(self) -> BaseElement:
raise ValueError

@property
def lhs(self) -> BasePattern:
def lhs(self) -> BasePattern | Expression:
"""
Lefthand side of a rule. Also known as its "pattern".
Left-hand side of a rule. Also known, in this context, as its "pattern".
"""
return self.pattern

Expand Down Expand Up @@ -351,7 +365,7 @@ def get_replace_value(self) -> BaseElement:
"""return the replace value"""
return self.replace

# This will probably be needed when we use with builtin Rule_
# # This might be needed in the future.
# @property
# def is_literal(self):
# """
Expand Down
Loading