Skip to content

Commit 9794c37

Browse files
authored
Merge pull request #1350 from mathics/Cases-Heads-option
More Cases Heads option handling
2 parents 1145dd1 + dd57b1e commit 9794c37

2 files changed

Lines changed: 32 additions & 13 deletions

File tree

CHANGES.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ Enhancements
2727

2828
* a function `evaluate_predicate` allows for a basic predicate evaluation using `$Assumptions`.
2929
* ``Attributes`` accepts a string parameter.
30+
* ``Cases`` accepts Heads option. Issue #1302.
3031
* ``ColorNegate`` for colors is supported.
3132
* ``D`` and ``Derivative`` improvements.
3233
* ``FileNames`` returns a sorted list (#1250).

mathics/builtin/lists.py

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
MessageException,
2626
NegativeIntegerException,
2727
CountableInteger,
28+
2829
)
2930
from mathics.core.expression import (
3031
Expression,
@@ -50,7 +51,7 @@
5051
from mathics.core.expression import min_prec, machine_precision
5152
from mathics.core.expression import structure
5253
from mathics.core.evaluation import BreakInterrupt, ContinueInterrupt, ReturnInterrupt
53-
from mathics.core.rules import Pattern
54+
from mathics.core.rules import Pattern, Rule
5455
from mathics.core.convert import from_sympy
5556
from mathics.builtin.numbers.algebra import cancel
5657
from mathics.algorithm.introselect import introselect
@@ -1970,17 +1971,29 @@ def apply_pattern(self, items, sel, pattern, evaluation):
19701971
class Cases(Builtin):
19711972
"""
19721973
<dl>
1973-
<dt>'Cases[$list$, $pattern$]'
1974-
<dd>returns the elements of $list$ that match $pattern$.
1975-
<dt>'Cases[$list$, $pattern$, $ls$]'
1976-
<dd>returns the elements matching at levelspec $ls$.
1974+
<dt>'Cases[$list$, $pattern$]'
1975+
<dd>returns the elements of $list$ that match $pattern$.
1976+
1977+
<dt>'Cases[$list$, $pattern$, $ls$]'
1978+
<dd>returns the elements matching at levelspec $ls$.
1979+
1980+
<dt>'Cases[$list$, $pattern$, Head->$bool$]'
1981+
<dd>Match including the head of the expression in the search.
19771982
</dl>
19781983
19791984
>> Cases[{a, 1, 2.5, "string"}, _Integer|_Real]
19801985
= {1, 2.5}
19811986
>> Cases[_Complex][{1, 2I, 3, 4-I, 5}]
19821987
= {2 I, 4 - I}
19831988
1989+
Find symbols among the elements of an expression:
1990+
>> Cases[{b, 6, \[Pi]}, _Symbol]
1991+
= {b, Pi}
1992+
1993+
Also include the head of the expression in the previous search:
1994+
>> Cases[{b, 6, \[Pi]}, _Symbol, Heads -> True]
1995+
= {List, b, Pi}
1996+
19841997
#> Cases[1, 2]
19851998
= {}
19861999
@@ -2008,24 +2021,33 @@ class Cases(Builtin):
20082021
"Cases[pattern_][list_]": "Cases[list, pattern]",
20092022
}
20102023

2011-
options = {"Heads": "False",}
2024+
options = {
2025+
"Heads": "False",
2026+
}
20122027

20132028
def apply(self, items, pattern, ls, evaluation, options):
20142029
"Cases[items_, pattern_, ls_:{1}, OptionsPattern[]]"
20152030
if items.is_atom():
20162031
return Expression(SymbolList)
20172032

2033+
from mathics.builtin.patterns import Matcher
2034+
if ls.has_form("Rule", 2):
2035+
if ls.leaves[0].get_name() == "System`Heads":
2036+
heads = ls.leaves[1].is_true()
2037+
ls = Expression("List", 1)
2038+
else:
2039+
return evaluation.message("Position", "level", ls)
2040+
else:
2041+
heads = self.get_option(options, "Heads", evaluation).is_true()
2042+
20182043
try:
20192044
start, stop = python_levelspec(ls)
20202045
except InvalidLevelspecError:
20212046
return evaluation.message("Position", "level", ls)
20222047

20232048
results = []
20242049

2025-
from mathics.builtin.patterns import Matcher
2026-
20272050
if pattern.has_form("Rule", 2) or pattern.has_form("RuleDelayed", 2):
2028-
from mathics.core.rules import Rule
20292051

20302052
match = Matcher(pattern.leaves[0]).match
20312053
rule = Rule(pattern.leaves[0], pattern.leaves[1])
@@ -2045,10 +2067,6 @@ def callback(level):
20452067
results.append(level)
20462068
return level
20472069

2048-
# TODO
2049-
heads = self.get_option(options, 'Heads', evaluation).is_true()
2050-
# heads = False
2051-
20522070
walk_levels(items, start, stop, heads=heads, callback=callback)
20532071

20542072
return Expression(SymbolList, *results)

0 commit comments

Comments
 (0)