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
5 changes: 4 additions & 1 deletion mathics/builtin/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -721,11 +721,14 @@ def boxes_to_tex(self, leaves, **options) -> str:
class PatternError(Exception):
def __init__(self, name, tag, *args):
super().__init__()
self.name = name
self.tag = tag
self.args = args


class PatternArgumentError(PatternError):
def __init__(self, name, count, expected):
super().__init__(None, None)
super().__init__(name, "argr", count, expected)


class PatternObject(InstanceableBuiltin, Pattern):
Expand Down
28 changes: 22 additions & 6 deletions mathics/builtin/patterns.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@
Integer,
Rational,
Real,
SymbolFalse,
SymbolList,
SymbolTrue,
)
from mathics.core.rules import Rule
from mathics.core.pattern import Pattern, StopGenerator
Expand Down Expand Up @@ -451,6 +453,9 @@ class PatternTest(BinaryOperator, PatternObject):
= True
>> MatchQ[-3, _Integer?(#>0&)]
= False
>> MatchQ[3, Pattern[3]]
: First element in pattern Pattern[3] is not a valid pattern name.
= False
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@mmatera Here is what I get when I try running this in mathics

MatchQ[3, Pattern[3]]
Traceback (most recent call last):
  File "/home/rocky/.pyenv/versions/3.7.10/bin/mathics", line 11, in <module>
    load_entry_point('Mathics3', 'console_scripts', 'mathics')()
  File "/src/external-vcs/github/mathics/Mathics/mathics/main.py", line 369, in main
    result = evaluation.evaluate(query, timeout=settings.TIMEOUT)
  File "/src/external-vcs/github/mathics/Mathics/mathics/core/evaluation.py", line 355, in evaluate
    result = run_with_timeout_and_stack(evaluate, timeout, self)
  File "/src/external-vcs/github/mathics/Mathics/mathics/core/evaluation.py", line 112, in run_with_timeout_and_stack
    return request()
  File "/src/external-vcs/github/mathics/Mathics/mathics/core/evaluation.py", line 326, in evaluate
    self.last_eval = query.evaluate(self)
  File "mathics/core/expression.py", line 1310, in mathics.core.expression.Expression.evaluate
    expr, reevaluate = expr.evaluate_next(evaluation)
  File "mathics/core/expression.py", line 1444, in mathics.core.expression.Expression.evaluate_next
    result = rule.apply(new, evaluation, fully=False)
  File "mathics/core/rules.py", line 67, in mathics.core.rules.BaseRule.apply
    self.pattern.match(yield_match, expression, {}, evaluation, fully=fully)
  File "mathics/core/pattern.py", line 291, in mathics.core.pattern.ExpressionPattern.match
    self.head.match(yield_head, expression.get_head(), vars, evaluation)
  File "mathics/core/pattern.py", line 159, in mathics.core.pattern.AtomPattern.match
    yield_func(vars, None)
  File "mathics/core/pattern.py", line 281, in mathics.core.pattern.ExpressionPattern.match.yield_head
    self.get_pre_choices(
  File "mathics/core/pattern.py", line 429, in mathics.core.pattern.ExpressionPattern.get_pre_choices
    yield_func(vars)
  File "mathics/core/pattern.py", line 258, in mathics.core.pattern.ExpressionPattern.match.yield_choice
    self.match_leaf(
  File "mathics/core/pattern.py", line 655, in mathics.core.pattern.ExpressionPattern.match_leaf
    self.get_wrappings(
  File "mathics/core/pattern.py", line 456, in mathics.core.pattern.ExpressionPattern.get_wrappings
    yield_func(items[0])
  File "mathics/core/pattern.py", line 643, in mathics.core.pattern.ExpressionPattern.match_leaf.yield_wrapping
    leaf.match(
  File "mathics/builtin/patterns.py", line 829, in mathics.builtin.patterns.Pattern_.match
    return self.pattern.get_match_count(vars)
  File "mathics/builtin/patterns.py", line 1027, in mathics.builtin.patterns.Blank.match
    #> StringReplace["hello world!", _ -> "x"]
  File "mathics/core/pattern.py", line 623, in mathics.core.pattern.ExpressionPattern.match_leaf.match_yield
    self.match_leaf(
  File "mathics/core/pattern.py", line 655, in mathics.core.pattern.ExpressionPattern.match_leaf
    self.get_wrappings(
  File "mathics/core/pattern.py", line 456, in mathics.core.pattern.ExpressionPattern.get_wrappings
    yield_func(items[0])
  File "mathics/core/pattern.py", line 643, in mathics.core.pattern.ExpressionPattern.match_leaf.yield_wrapping
    leaf.match(
  File "mathics/builtin/patterns.py", line 829, in mathics.builtin.patterns.Pattern_.match
    return self.pattern.get_match_count(vars)
  File "mathics/builtin/patterns.py", line 1027, in mathics.builtin.patterns.Blank.match
    #> StringReplace["hello world!", _ -> "x"]
  File "mathics/core/pattern.py", line 640, in mathics.core.pattern.ExpressionPattern.match_leaf.match_yield
    yield_func(new_vars, items_rest)
  File "mathics/core/pattern.py", line 616, in mathics.core.pattern.ExpressionPattern.match_leaf.leaf_yield
    yield_func(
  File "mathics/core/rules.py", line 42, in mathics.core.rules.BaseRule.apply.yield_match
    new_expression = self.do_replace(expression, vars, options, evaluation)
  File "mathics/core/rules.py", line 131, in mathics.core.rules.BuiltinRule.do_replace
    return self.function(evaluation=evaluation, **vars_noctx)
  File "mathics/builtin/patterns.py", line 670, in mathics.builtin.patterns.MatchQ.apply
    = False
  File "mathics/builtin/patterns.py", line 647, in mathics.builtin.patterns.match
    return True
  File "mathics/builtin/patterns.py", line 633, in mathics.builtin.patterns.Matcher.__init__
    pass
  File "mathics/core/pattern.py", line 24, in mathics.core.pattern.Pattern_create
    return pattern_object(expr)
  File "/src/external-vcs/github/mathics/Mathics/mathics/builtin/base.py", line 382, in __new__
    instance.init(*args, **kwargs)
  File "mathics/builtin/patterns.py", line 804, in mathics.builtin.patterns.Pattern_.init
    "MakeBoxes[Verbatim[Pattern][symbol_Symbol, blank_Blank|blank_BlankSequence|blank_BlankNullSequence], f:StandardForm|TraditionalForm|InputForm|OutputForm]": "MakeBoxes[symbol, f] <> MakeBoxes[blank, f]",
  File "/src/external-vcs/github/mathics/Mathics/mathics/builtin/base.py", line 746, in init
    self.error_args(len(expr.leaves), *self.arg_counts)
  File "/src/external-vcs/github/mathics/Mathics/mathics/builtin/base.py", line 755, in error_args
    raise PatternArgumentError(self.get_name(), count, *expected)
mathics.builtin.base.PatternArgumentError

When I run through test, I don't have a problem thought.

Do you know what's up here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I find this error in the current master branch. The patch in this PR catches the exception producing a message
Pattern::patvar: First element in pattern Pattern[3] is not a valid pattern name.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

BTW, #> StringReplace["hello world!", _ -> "x"] line in the trace seems to suggest that your branch is probably mixed with something else.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This weird, and I don't understand. I just tried again, looking for this kind of problem of mismatched versions, and I removed any cythonized files and I still get the same thing.

$ git checkout fb6231ae
Note: switching to 'fb6231ae'.
...
HEAD is now at fb6231ae adding argr message for PatternArgumentError
$ mathics

Mathics 2.1.1.dev0
on CPython 3.9.2 (default, Feb 27 2021, 22:36:52) 
using SymPy 1.7.1, mpmath 1.2.1, numpy 1.20.1, cython 0.29.23

Copyright (C) 2011-2021 The Mathics Team.
This program comes with ABSOLUTELY NO WARRANTY.
This is free software, and you are welcome to redistribute it
under certain conditions.
See the documentation for the full license.

Quit by evaluating Quit[] or by pressing CONTROL-D.

In[1]:= MatchQ[3, Pattern[3]]
Traceback (most recent call last):
  File "/home/rocky/.pyenv/versions/3.9.2/bin/mathics", line 33, in <module>
    sys.exit(load_entry_point('Mathics3', 'console_scripts', 'mathics')())
  File "/src/external-vcs/github/mathics/Mathics/mathics/main.py", line 369, in main
    result = evaluation.evaluate(query, timeout=settings.TIMEOUT)
  File "/src/external-vcs/github/mathics/Mathics/mathics/core/evaluation.py", line 355, in evaluate
    result = run_with_timeout_and_stack(evaluate, timeout, self)
  File "/src/external-vcs/github/mathics/Mathics/mathics/core/evaluation.py", line 112, in run_with_timeout_and_stack
    return request()
  File "/src/external-vcs/github/mathics/Mathics/mathics/core/evaluation.py", line 326, in evaluate
    self.last_eval = query.evaluate(self)
  File "/src/external-vcs/github/mathics/Mathics/mathics/core/expression.py", line 1310, in evaluate
    expr, reevaluate = expr.evaluate_next(evaluation)
  File "/src/external-vcs/github/mathics/Mathics/mathics/core/expression.py", line 1444, in evaluate_next
    result = rule.apply(new, evaluation, fully=False)
  File "/src/external-vcs/github/mathics/Mathics/mathics/core/rules.py", line 67, in apply
    self.pattern.match(yield_match, expression, {}, evaluation, fully=fully)
  File "/src/external-vcs/github/mathics/Mathics/mathics/core/pattern.py", line 291, in match
    self.head.match(yield_head, expression.get_head(), vars, evaluation)
  File "/src/external-vcs/github/mathics/Mathics/mathics/core/pattern.py", line 159, in match
    yield_func(vars, None)
  File "/src/external-vcs/github/mathics/Mathics/mathics/core/pattern.py", line 281, in yield_head
    self.get_pre_choices(
  File "/src/external-vcs/github/mathics/Mathics/mathics/core/pattern.py", line 429, in get_pre_choices
    yield_func(vars)
  File "/src/external-vcs/github/mathics/Mathics/mathics/core/pattern.py", line 258, in yield_choice
    self.match_leaf(
  File "/src/external-vcs/github/mathics/Mathics/mathics/core/pattern.py", line 655, in match_leaf
    self.get_wrappings(
  File "/src/external-vcs/github/mathics/Mathics/mathics/core/pattern.py", line 456, in get_wrappings
    yield_func(items[0])
  File "/src/external-vcs/github/mathics/Mathics/mathics/core/pattern.py", line 643, in yield_wrapping
    leaf.match(
  File "mathics/builtin/patterns.py", line 829, in mathics.builtin.patterns.Pattern_.match
    def get_match_count(self, vars={}):
  File "mathics/builtin/patterns.py", line 1027, in mathics.builtin.patterns.Blank.match
    
  File "/src/external-vcs/github/mathics/Mathics/mathics/core/pattern.py", line 623, in match_yield
    self.match_leaf(
  File "/src/external-vcs/github/mathics/Mathics/mathics/core/pattern.py", line 655, in match_leaf
    self.get_wrappings(
  File "/src/external-vcs/github/mathics/Mathics/mathics/core/pattern.py", line 456, in get_wrappings
    yield_func(items[0])
  File "/src/external-vcs/github/mathics/Mathics/mathics/core/pattern.py", line 643, in yield_wrapping
    leaf.match(
  File "mathics/builtin/patterns.py", line 829, in mathics.builtin.patterns.Pattern_.match
    def get_match_count(self, vars={}):
  File "mathics/builtin/patterns.py", line 1027, in mathics.builtin.patterns.Blank.match
    
  File "/src/external-vcs/github/mathics/Mathics/mathics/core/pattern.py", line 640, in match_yield
    yield_func(new_vars, items_rest)
  File "/src/external-vcs/github/mathics/Mathics/mathics/core/pattern.py", line 616, in leaf_yield
    yield_func(
  File "/src/external-vcs/github/mathics/Mathics/mathics/core/rules.py", line 42, in yield_match
    new_expression = self.do_replace(expression, vars, options, evaluation)
  File "/src/external-vcs/github/mathics/Mathics/mathics/core/rules.py", line 131, in do_replace
    return self.function(evaluation=evaluation, **vars_noctx)
  File "mathics/builtin/patterns.py", line 670, in mathics.builtin.patterns.MatchQ.apply
    = False
  File "mathics/builtin/patterns.py", line 647, in mathics.builtin.patterns.match
    return True
  File "mathics/builtin/patterns.py", line 633, in mathics.builtin.patterns.Matcher.__init__
    pass
  File "/src/external-vcs/github/mathics/Mathics/mathics/core/pattern.py", line 24, in Pattern_create
    return pattern_object(expr)
  File "/src/external-vcs/github/mathics/Mathics/mathics/builtin/base.py", line 382, in __new__
    instance.init(*args, **kwargs)
  File "mathics/builtin/patterns.py", line 804, in mathics.builtin.patterns.Pattern_.init
    rules = {
  File "/src/external-vcs/github/mathics/Mathics/mathics/builtin/base.py", line 743, in init
    self.error_args(len(expr.leaves), *self.arg_counts)
  File "/src/external-vcs/github/mathics/Mathics/mathics/builtin/base.py", line 752, in error_args
    raise PatternArgumentError(self.get_name(), count, *expected)
mathics.builtin.base.PatternArgumentError: (1, 2)
$ 

When you do the same thing you don't get a traceback to falls through to the top-level?

"""

operator = "?"
Expand Down Expand Up @@ -660,16 +665,23 @@ class MatchQ(Builtin):
= False
>> MatchQ[_Integer][123]
= True
>> MatchQ[3, Pattern[3]]
: First element in pattern Pattern[3] is not a valid pattern name.
= False
"""

rules = {"MatchQ[form_][expr_]": "MatchQ[expr, form]"}

def apply(self, expr, form, evaluation):
"MatchQ[expr_, form_]"

if match(expr, form, evaluation):
return Symbol("True")
return Symbol("False")
try:
if match(expr, form, evaluation):
return SymbolTrue
return SymbolFalse
except PatternError as e:
evaluation.message(e.name, e.tag, *(e.args))
return SymbolFalse


class Verbatim(PatternObject):
Expand Down Expand Up @@ -786,6 +798,7 @@ class Pattern_(PatternObject):
"nodef": (
"No default setting found for `1` in " "position `2` when length is `3`."
),
"argr": "Pattern called with 1 argument; 2 arguments are expected.",
}

rules = {
Expand All @@ -801,10 +814,13 @@ class Pattern_(PatternObject):
}

def init(self, expr):
super(Pattern_, self).init(expr)
self.varname = expr.leaves[0].get_name()
if self.varname is None:
if len(expr.leaves) != 2:
self.error("patvar", expr)
varname = expr.leaves[0].get_name()
if varname is None or varname == "":
self.error("patvar", expr)
super(Pattern_, self).init(expr)
self.varname = varname
self.pattern = Pattern.create(expr.leaves[1])

def __repr__(self):
Expand Down