예제 #1
0
파일: eol.py 프로젝트: skirpichev/Mathics
    def apply(self, items, pattern, ls, evaluation, options):
        "Cases[items_, pattern_, ls_:{1}, OptionsPattern[]]"
        if items.is_atom():
            return Expression(SymbolList)

        from mathics.builtin.patterns import Matcher

        if ls.has_form("Rule", 2):
            if ls.leaves[0].get_name() == "System`Heads":
                heads = ls.leaves[1].is_true()
                ls = Expression("List", 1)
            else:
                return evaluation.message("Position", "level", ls)
        else:
            heads = self.get_option(options, "Heads", evaluation).is_true()

        try:
            start, stop = python_levelspec(ls)
        except InvalidLevelspecError:
            return evaluation.message("Position", "level", ls)

        results = []

        if pattern.has_form("Rule", 2) or pattern.has_form("RuleDelayed", 2):

            match = Matcher(pattern.leaves[0]).match
            rule = Rule(pattern.leaves[0], pattern.leaves[1])

            def callback(level):
                if match(level, evaluation):
                    result = rule.apply(level, evaluation)
                    result = result.evaluate(evaluation)
                    results.append(result)
                return level

        else:
            match = Matcher(pattern).match

            def callback(level):
                if match(level, evaluation):
                    results.append(level)
                return level

        walk_levels(items, start, stop, heads=heads, callback=callback)

        return Expression(SymbolList, *results)
예제 #2
0
파일: logic.py 프로젝트: mathics/Mathics
    def apply(self, expr, test, level, evaluation):
        "%(name)s[expr_, test_, level_]"

        try:
            start, stop = python_levelspec(level)
        except InvalidLevelspecError:
            evaluation.message("Level", "level", level)
            return

        def callback(node):
            self._short_circuit(Expression(test, node).evaluate(evaluation).is_true())
            return node

        try:
            walk_levels(expr, start, stop, callback=callback)
        except _ShortCircuit as e:
            return e.result

        return self._no_short_circuit()
예제 #3
0
파일: logic.py 프로젝트: srossd/Mathics
    def apply(self, expr, test, level, evaluation):
        "%(name)s[expr_, test_, level_]"

        try:
            start, stop = python_levelspec(level)
        except InvalidLevelspecError:
            evaluation.message("Level", "level", level)
            return

        def callback(node):
            self._short_circuit(Expression(test, node).evaluate(evaluation).is_true())
            return node

        try:
            walk_levels(expr, start, stop, callback=callback)
        except _ShortCircuit as e:
            return e.result

        return self._no_short_circuit()
예제 #4
0
 def apply_level(self, f, expr, ls, evaluation, options={}):
     'Map[f_, expr_, ls_?LevelQ:{1}, OptionsPattern[Map]]'
     
     try:
         start, stop = python_levelspec(ls)
     except InvalidLevelspecError:
         evaluation.message('Map', 'level', ls)
         return
     
     def callback(level):
         return Expression(f, level)
     
     heads = self.get_option(options, 'Heads', evaluation).is_true()
     result, depth = walk_levels(expr, start, stop, heads=heads, callback=callback)
     
     return result
예제 #5
0
 def apply_level(self, f, expr, ls, evaluation, options={}):
     'MapIndexed[f_, expr_, ls_?LevelQ:{1}, OptionsPattern[MapIndexed]]'
     
     try:
         start, stop = python_levelspec(ls)
     except InvalidLevelspecError:
         evaluation.message('MapIndexed', 'level', ls)
         return
     
     def callback(level, pos):
         return Expression(f, level, Expression('List', *(Integer(p) for p in pos)))
     
     heads = self.get_option(options, 'Heads', evaluation).is_true()
     result, depth = walk_levels(expr, start, stop, heads=heads, callback=callback, include_pos=True)
     
     return result
예제 #6
0
 def apply_level(self, f, expr, ls, evaluation, options={}):
     'Map[f_, expr_, ls_?LevelQ:{1}, OptionsPattern[Map]]'
     
     try:
         start, stop = python_levelspec(ls)
     except InvalidLevelspecError:
         evaluation.message('Map', 'level', ls)
         return
     
     def callback(level):
         return Expression(f, level)
     
     heads = self.get_option(options, 'Heads', evaluation).is_true()
     result, depth = walk_levels(expr, start, stop, heads=heads, callback=callback)
     
     return result
예제 #7
0
 def apply_level(self, f, expr, ls, evaluation, options={}):
     'MapIndexed[f_, expr_, ls_?LevelQ:{1}, OptionsPattern[MapIndexed]]'
     
     try:
         start, stop = python_levelspec(ls)
     except InvalidLevelspecError:
         evaluation.message('MapIndexed', 'level', ls)
         return
     
     def callback(level, pos):
         return Expression(f, level, Expression('List', *(Integer(p) for p in pos)))
     
     heads = self.get_option(options, 'Heads', evaluation).is_true()
     result, depth = walk_levels(expr, start, stop, heads=heads, callback=callback, include_pos=True)
     
     return result
예제 #8
0
파일: structure.py 프로젝트: kgtaek/Mathics
    def apply_level(self, f, expr, ls, evaluation, options={}):
        """MapIndexed[f_, expr_, Optional[Pattern[ls, _?LevelQ], {1}],
                OptionsPattern[MapIndexed]]"""

        try:
            start, stop = python_levelspec(ls)
        except InvalidLevelspecError:
            evaluation.message("MapIndexed", "level", ls)
            return

        def callback(level, pos):
            return Expression(f, level, Expression("List", *[Integer(p) for p in pos]))

        heads = self.get_option(options, "Heads", evaluation).is_true()
        result, depth = walk_levels(expr, start, stop, heads=heads, callback=callback, include_pos=True)

        return result
예제 #9
0
파일: structure.py 프로젝트: kgtaek/Mathics
    def apply_level(self, f, expr, ls, evaluation, options={}):
        """Map[f_, expr_, Optional[Pattern[ls, _?LevelQ], {1}],
                OptionsPattern[Map]]"""

        try:
            start, stop = python_levelspec(ls)
        except InvalidLevelspecError:
            evaluation.message("Map", "level", ls)
            return

        def callback(level):
            return Expression(f, level)

        heads = self.get_option(options, "Heads", evaluation).is_true()
        result, depth = walk_levels(expr, start, stop, heads=heads, callback=callback)

        return result
예제 #10
0
파일: structure.py 프로젝트: srossd/Mathics
    def apply_level(self, f, expr, ls, evaluation, options={}):
        """Map[f_, expr_, Optional[Pattern[ls, _?LevelQ], {1}],
        OptionsPattern[Map]]"""

        try:
            start, stop = python_levelspec(ls)
        except InvalidLevelspecError:
            evaluation.message("Map", "level", ls)
            return

        def callback(level):
            return Expression(f, level)

        heads = self.get_option(options, "Heads", evaluation).is_true()
        result, depth = walk_levels(expr, start, stop, heads=heads, callback=callback)

        return result
예제 #11
0
 def apply(self, f, expr, ls, evaluation, options={}):
     'Apply[f_, expr_, ls_?LevelQ:{0}, OptionsPattern[Apply]]'
     
     try:
         start, stop = python_levelspec(ls)
     except InvalidLevelspecError:
         evaluation.message('Apply', 'level', ls)
         return
     
     def callback(level):
         if level.is_atom():
             return level
         else:
             return Expression(f, *level.leaves)
     
     heads = self.get_option(options, 'Heads', evaluation).is_true()
     result, depth = walk_levels(expr, start, stop, heads=heads, callback=callback)
     
     return result
예제 #12
0
 def apply(self, f, expr, ls, evaluation, options={}):
     'Apply[f_, expr_, ls_?LevelQ:{0}, OptionsPattern[Apply]]'
     
     try:
         start, stop = python_levelspec(ls)
     except InvalidLevelspecError:
         evaluation.message('Apply', 'level', ls)
         return
     
     def callback(level):
         if level.is_atom():
             return level
         else:
             return Expression(f, *level.leaves)
     
     heads = self.get_option(options, 'Heads', evaluation).is_true()
     result, depth = walk_levels(expr, start, stop, heads=heads, callback=callback)
     
     return result
예제 #13
0
    def apply_level(self, f, expr, ls, evaluation, options={}):
        '''Scan[f_, expr_, Optional[Pattern[ls, _?LevelQ], {1}],
                OptionsPattern[Map]]'''

        try:
            start, stop = python_levelspec(ls)
        except InvalidLevelspecError:
            evaluation.message('Map', 'level', ls)
            return

        def callback(level):
            Expression(f, level).evaluate(evaluation)
            return level

        heads = self.get_option(options, 'Heads', evaluation).is_true()
        result, depth = walk_levels(
            expr, start, stop, heads=heads, callback=callback)

        return Symbol('Null')
예제 #14
0
    def apply_level(self, f, expr, ls, evaluation, options={}):
        '''Scan[f_, expr_, Optional[Pattern[ls, _?LevelQ], {1}],
                OptionsPattern[Map]]'''

        try:
            start, stop = python_levelspec(ls)
        except InvalidLevelspecError:
            evaluation.message('Map', 'level', ls)
            return

        def callback(level):
            Expression(f, level).evaluate(evaluation)
            return level

        heads = self.get_option(options, 'Heads', evaluation).is_true()
        result, depth = walk_levels(
            expr, start, stop, heads=heads, callback=callback)

        return Symbol('Null')
예제 #15
0
파일: structure.py 프로젝트: srossd/Mathics
    def apply_level(self, f, expr, ls, evaluation, options={}):
        """MapIndexed[f_, expr_, Optional[Pattern[ls, _?LevelQ], {1}],
        OptionsPattern[MapIndexed]]"""

        try:
            start, stop = python_levelspec(ls)
        except InvalidLevelspecError:
            evaluation.message("MapIndexed", "level", ls)
            return

        def callback(level, pos):
            return Expression(f, level, Expression("List", *[Integer(p) for p in pos]))

        heads = self.get_option(options, "Heads", evaluation).is_true()
        result, depth = walk_levels(
            expr, start, stop, heads=heads, callback=callback, include_pos=True
        )

        return result
예제 #16
0
파일: structure.py 프로젝트: kgtaek/Mathics
    def apply(self, f, expr, ls, evaluation, options={}):
        """Apply[f_, expr_, Optional[Pattern[ls, _?LevelQ], {0}],
                OptionsPattern[Apply]]"""

        try:
            start, stop = python_levelspec(ls)
        except InvalidLevelspecError:
            evaluation.message("Apply", "level", ls)
            return

        def callback(level):
            if level.is_atom():
                return level
            else:
                return Expression(f, *level.leaves)

        heads = self.get_option(options, "Heads", evaluation).is_true()
        result, depth = walk_levels(expr, start, stop, heads=heads, callback=callback)

        return result
예제 #17
0
파일: structure.py 프로젝트: srossd/Mathics
    def apply(self, f, expr, ls, evaluation, options={}):
        """Apply[f_, expr_, Optional[Pattern[ls, _?LevelQ], {0}],
        OptionsPattern[Apply]]"""

        try:
            start, stop = python_levelspec(ls)
        except InvalidLevelspecError:
            evaluation.message("Apply", "level", ls)
            return

        def callback(level):
            if level.is_atom():
                return level
            else:
                return Expression(f, *level.leaves)

        heads = self.get_option(options, "Heads", evaluation).is_true()
        result, depth = walk_levels(expr, start, stop, heads=heads, callback=callback)

        return result
예제 #18
0
    def apply_list(self, expr, n, h, evaluation):
        "Flatten[expr_, n_List, h_]"

        # prepare levels
        # find max depth which matches `h`
        expr, max_depth = walk_levels(expr)
        max_depth = {
            "max_depth": max_depth
        }  # hack to modify max_depth from callback

        def callback(expr, pos):
            if len(pos) < max_depth["max_depth"] and (expr.is_atom()
                                                      or expr.head != h):
                max_depth["max_depth"] = len(pos)
            return expr

        expr, depth = walk_levels(expr,
                                  callback=callback,
                                  include_pos=True,
                                  start=0)
        max_depth = max_depth["max_depth"]

        levels = n.to_python()

        # mappings
        if isinstance(levels, list) and all(
                isinstance(level, int) for level in levels):
            levels = [levels]

        # verify levels is list of lists of positive ints
        if not (isinstance(levels, list) and len(levels) > 0):
            evaluation.message("Flatten", "flpi", n)
            return
        seen_levels = []
        for level in levels:
            if not (isinstance(level, list) and len(level) > 0):
                evaluation.message("Flatten", "flpi", n)
                return
            for l in level:
                if not (isinstance(l, int) and l > 0):
                    evaluation.message("Flatten", "flpi", n)
                    return
                if l in seen_levels:
                    # level repeated
                    evaluation.message("Flatten", "flrep", l)
                    return
                seen_levels.append(l)

        # complete the level spec e.g. {{2}} -> {{2}, {1}, {3}}
        for l in range(1, max_depth + 1):
            if l not in seen_levels:
                levels.append([l])

        # verify specified levels are smaller max depth
        for level in levels:
            for l in level:
                if l > max_depth:
                    evaluation.message("Flatten", "fldep", l, n, max_depth,
                                       expr)
                    return

        # assign new indices to each leaf
        new_indices = {}

        def callback(expr, pos):
            if len(pos) == max_depth:
                new_depth = tuple(
                    tuple(pos[i - 1] for i in level) for level in levels)
                new_indices[new_depth] = expr
            return expr

        expr, depth = walk_levels(expr, callback=callback, include_pos=True)

        # build new tree inserting nodes as needed
        result = Expression(h)
        leaves = sorted(new_indices.items())

        def insert_leaf(expr, leaves):
            # gather leaves into groups with the same leading index
            # e.g. [((0, 0), a), ((0, 1), b), ((1, 0), c), ((1, 1), d)]
            # -> [[(0, a), (1, b)], [(0, c), (1, d)]]
            leading_index = None
            grouped_leaves = []
            for index, leaf in leaves:
                if index[0] == leading_index:
                    grouped_leaves[-1].append((index[1:], leaf))
                else:
                    leading_index = index[0]
                    grouped_leaves.append([(index[1:], leaf)])
            # for each group of leaves we either insert them into the current level
            # or make a new level and recurse
            for group in grouped_leaves:
                if len(group[0][0]) == 0:  # bottom level leaf
                    assert len(group) == 1
                    expr.leaves.append(group[0][1])
                else:
                    expr.leaves.append(Expression(h))
                    insert_leaf(expr.leaves[-1], group)

        insert_leaf(result, leaves)
        return result
예제 #19
0
 def apply(self, expr, evaluation):
     "Depth[expr_]"
     expr, depth = walk_levels(expr)
     return Integer(depth + 1)
예제 #20
0
파일: structure.py 프로젝트: Darkoe/Mathics
 def apply(self, expr, evaluation):
     'Depth[expr_]'
     expr, depth = walk_levels(expr)
     return Integer(depth + 1)
예제 #21
0
파일: structure.py 프로젝트: Darkoe/Mathics
    def apply_list(self, expr, n, h, evaluation):
        'Flatten[expr_, n_List, h_]'

        # prepare levels
        # find max depth which matches `h`
        expr, max_depth = walk_levels(expr)
        max_depth = {'max_depth': max_depth}    # hack to modify max_depth from callback

        def callback(expr, pos):
            if len(pos) < max_depth['max_depth'] and (expr.is_atom() or expr.head != h):
                max_depth['max_depth'] = len(pos)
            return expr
        expr, depth = walk_levels(expr, callback=callback, include_pos=True, start=0)
        max_depth = max_depth['max_depth']

        levels = n.to_python()

        # mappings
        if isinstance(levels, list) and all(isinstance(level, int) for level in levels):
            levels = [levels]

        # verify levels is list of lists of positive ints
        if not (isinstance(levels, list) and len(levels) > 0):
            evaluation.message('Flatten', 'flpi', n)
            return
        seen_levels = []
        for level in levels:
            if not (isinstance(level, list) and len(level) > 0):
                evaluation.message('Flatten', 'flpi', n)
                return
            for l in level:
                if not (isinstance(l, int) and l > 0):
                    evaluation.message('Flatten', 'flpi', n)
                    return
                if l in seen_levels:
                    # level repeated
                    evaluation.message('Flatten', 'flrep', l)
                    return
                seen_levels.append(l)

        # complete the level spec e.g. {{2}} -> {{2}, {1}, {3}}
        for l in range(1, max_depth + 1):
            if l not in seen_levels:
                levels.append([l])

        # verify specified levels are smaller max depth
        for level in levels:
            for l in level:
                if l > max_depth:
                    evaluation.message('Flatten', 'fldep', l, n, max_depth, expr)
                    return

        # assign new indices to each leaf
        new_indices = {}

        def callback(expr, pos):
            if len(pos) == max_depth:
                new_depth = tuple(tuple(pos[i - 1] for i in level) for level in levels)
                new_indices[new_depth] = expr
            return expr
        expr, depth = walk_levels(expr, callback=callback, include_pos=True)

        # build new tree inserting nodes as needed
        result = Expression(h)
        leaves = sorted(six.iteritems(new_indices))

        def insert_leaf(expr, leaves):
            # gather leaves into groups with the same leading index
            # e.g. [((0, 0), a), ((0, 1), b), ((1, 0), c), ((1, 1), d)]
            # -> [[(0, a), (1, b)], [(0, c), (1, d)]]
            leading_index = None
            grouped_leaves = []
            for index, leaf in leaves:
                if index[0] == leading_index:
                    grouped_leaves[-1].append((index[1:], leaf))
                else:
                    leading_index = index[0]
                    grouped_leaves.append([(index[1:], leaf)])
            # for each group of leaves we either insert them into the current level
            # or make a new level and recurse
            for group in grouped_leaves:
                if len(group[0][0]) == 0:   # bottom level leaf
                    assert len(group) == 1
                    expr.leaves.append(group[0][1])
                else:
                    expr.leaves.append(Expression(h))
                    insert_leaf(expr.leaves[-1], group)
        insert_leaf(result, leaves)
        return result