Example #1
0
    def format_plus(self, items, evaluation):
        'Plus[items__]'

        def negate(item):
            if item.has_form('Times', 1, None):
                if isinstance(item.leaves[0],
                              (Integer, Rational, Real, Complex)):
                    neg = Number.from_mp(-item.leaves[0].to_sympy())
                    if neg.same(Integer(1)):
                        if len(item.leaves) == 1:
                            return neg
                        else:
                            return Expression('Times', *item.leaves[1:])
                    else:
                        return Expression('Times', neg, *item.leaves[1:])
                else:
                    return Expression('Times', -1, *item.leaves)
            elif isinstance(item, (Integer, Rational, Real, Complex)):
                return Number.from_mp(-item.to_sympy())
            else:
                return Expression('Times', -1, item)

        def is_negative(value):
            if isinstance(value,
                          (Integer, Rational, Real)) and value.to_sympy() < 0:
                return True
            if isinstance(value, Complex):
                real, imag = value.to_sympy().as_real_imag()
                if real <= 0 and imag <= 0:
                    return True
            return False

        items = items.get_sequence()
        values = [Expression('HoldForm', item) for item in items[:1]]
        ops = []
        for item in items[1:]:
            if (item.has_form('Times', 1, None)
                    and is_negative(item.leaves[0])) or is_negative(item):
                item = negate(item)
                op = "-"
            else:
                op = "+"
            values.append(Expression('HoldForm', item))
            ops.append(String(op))
        return Expression('Infix', Expression('List', *values),
                          Expression('List', *ops), 310, Symbol('Left'))
Example #2
0
    def apply(self, items, evaluation):
        'Inequality[items___]'

        items = items.numerify(evaluation).get_sequence()
        count = len(items)
        if count == 1:
            return Symbol('True')
        elif count % 2 == 0:
            evaluation.message('Inequality', 'ineq', count)
        elif count == 3:
            name = items[1].get_name()
            if name in operators.keys():
                return Expression(name, items[0], items[2])
        else:
            groups = [Expression('Inequality', *items[index - 1:index + 2])
                      for index in range(1, count - 1, 2)]
            return Expression('And', *groups)
Example #3
0
    def apply(self, expr, ls, evaluation, options={}):
        'Level[expr_, ls_, OptionsPattern[Level]]'

        try:
            start, stop = python_levelspec(ls)
        except InvalidLevelspecError:
            evaluation.message('Level', 'level', ls)
            return
        result = []

        def callback(level):
            result.append(level)
            return level

        heads = self.get_option(options, 'Heads', evaluation) == Symbol('True')
        walk_levels(expr, start, stop, heads=heads, callback=callback)
        return Expression('List', *result)
Example #4
0
    def apply_symbol(self, vars, attributes, evaluation):
        'Unique[vars_, attributes___]'

        from mathics.core.parser import is_symbol_name
        from mathics.builtin.attributes import get_symbol_list

        attributes = attributes.get_sequence()
        if len(attributes) > 1:
            return evaluation.message('Unique', 'argrx', Integer(len(attributes) + 1))

        # Check valid symbol variables
        symbols = vars.leaves if vars.has_form('List', None) else [vars]
        for symbol in symbols:
            if not isinstance(symbol, Symbol):
                text = symbol.get_string_value()
                if text is None or not is_symbol_name(text):
                    return evaluation.message('Unique', 'usym', symbol)

        # Check valid attributes
        attrs = []
        if len(attributes) > 0:
            attrs = get_symbol_list(attributes[0], lambda item: evaluation.message('Unique', 'attnf', item))
            if attrs is None:
                return None

        # Generate list new symbols
        list = []
        for symbol in symbols:
            if isinstance(symbol, Symbol):
                list.append(Module(Expression('List', symbol), symbol).evaluate(evaluation))
            else:
                new_name = '%s%d' % (symbol.get_string_value(), self.seq_number)
                self.seq_number += 1
                # Next symbol in case of new name is defined before
                while evaluation.definitions.get_definition(new_name, True) is not None:
                    new_name = '%s%d' % (symbol.get_string_value(), self.seq_number)
                    self.seq_number += 1
                list.append(Symbol(new_name))
        for symbol in list:
            for att in attrs:
                evaluation.definitions.set_attribute(symbol.get_name(), att)

        if vars.has_form('List', None):
            return Expression('List', *list)
        else:
            return list[0]
Example #5
0
 def apply(self, start, test, incr, body, evaluation):
     'For[start_, test_, incr_, body_]'
     while test.evaluate(evaluation).is_true():
         evaluation.check_stopped()
         try:
             try:
                 body.evaluate(evaluation)
             except ContinueInterrupt:
                 pass
             try:
                 incr.evaluate(evaluation)
             except ContinueInterrupt:
                 # Critical, most likely leads to an infinite loop
                 pass
         except BreakInterrupt:
             break
     return Symbol('Null')
Example #6
0
 def testInstances(self):
     # duplicate instantiations of same content (like Integer 5) to test for potential instantiation randomness.
     _test_group(
         list(
             map(
                 lambda f: (f(), f()),
                 (
                     lambda: Integer(5),
                     lambda: Rational(5, 2),
                     lambda: MachineReal(5.12345678),
                     lambda: Complex(Integer(5), Integer(2)),
                     lambda: String("xy"),
                     lambda: Symbol("xy"),
                 ),
             )
         )
     )
Example #7
0
 def apply(self, f, expr, test, m, evaluation):
     'NestWhile[f_, expr_, test_, Pattern[m,_Integer|All]]'
     
     results = [expr]
     while True:
         if m.get_name() == 'All':
             test_leaves = results
         else:
             test_leaves = results[-m.value:]
         test_expr = Expression(test, *test_leaves)
         test_result = test_expr.evaluate(evaluation)
         if test_result == Symbol('True'):
             next = Expression(f, results[-1])
             results.append(next.evaluate(evaluation))
         else:
             break
     return results[-1]
Example #8
0
def quiet_evaluate(expr, vars, evaluation, expect_list=False):
    """ Evaluates expr with given dynamic scoping values
    without producing arithmetic error messages. """
    expr = Expression('N', expr)
    quiet_expr = Expression('Quiet', expr, Expression('List',
        Expression('MessageName', Symbol('Power'), String('infy'))))
    value = dynamic_scoping(quiet_expr.evaluate, vars, evaluation)
    if expect_list:
        if value.has_form('List', None):
            value = [chop(item).get_real_value() for item in value.leaves]
            if any(item is None for item in value):
                return None
            return value
        else:
            return None
    else:
        return chop(value).get_real_value()
Example #9
0
    def apply(self, expr, args, evaluation):
        'Manipulate[expr_, args__]'
        if (not _jupyter) or (not Kernel.initialized()) or (Kernel.instance() is None):
            return evaluation.message('Manipulate', 'jupyter')

        instantiator = _WidgetInstantiator()  # knows about the arguments and their widgets

        for arg in args.get_sequence():
            try:
                if not instantiator.add(arg, evaluation):  # not a valid argument pattern?
                    return
            except IllegalWidgetArguments as e:
                return evaluation.message('Manipulate', 'widgetargs', strip_context(str(e.var)))
            except JupyterWidgetError as e:
                return evaluation.message('Manipulate', 'widgetmake', e.err)

        clear_output_callback = evaluation.output.clear
        display_data_callback = evaluation.output.display  # for pushing updates

        try:
            clear_output_callback(wait=True)
        except NotImplementedError:
            return evaluation.message('Manipulate', 'imathics')

        def callback(**kwargs):
            clear_output_callback(wait=True)

            line_no = evaluation.definitions.get_line_no()

            vars = [Expression('Set', Symbol(name), value) for name, value in kwargs.items()]
            evaluatable = Expression('ReleaseHold', Expression('Module', Expression('List', *vars), expr))

            result = evaluation.evaluate(evaluatable, timeout=settings.TIMEOUT)
            if result:
                display_data_callback(data=result.result, metadata={})

            evaluation.definitions.set_line_no(line_no)  # do not increment line_no for manipulate computations

        widgets = instantiator.get_widgets()
        if len(widgets) > 0:
            box = _interactive(instantiator.build_callback(callback), widgets)  # create the widget
            formatter = IPythonDisplayFormatter()
            if not formatter(box):  # make the widget appear on the Jupyter notebook
                return evaluation.message('Manipulate', 'widgetdisp')

        return Symbol('Null')  # the interactive output is pushed via kernel.display_data_callback (see above)
Example #10
0
def read_list_from_types(read_types):
    """Return a Mathics List from a list of read_type names or a single read_type"""

    # Trun read_types into a list if it isn't already one.
    if read_types.has_form("List", None):
        read_types = read_types._leaves
    else:
        read_types = (read_types, )

    # TODO: look for a better implementation handling "Hold[Expression]".
    #
    read_types = (Symbol("HoldExpression") if
                  (typ.get_head_name() == "System`Hold"
                   and typ.leaves[0].get_name() == "System`Expression") else
                  typ for typ in read_types)

    return Expression("List", *read_types)
Example #11
0
 def map_at_one(i, leaves):
     if 1 <= i <= m:
         j = i - 1
     elif -m <= i <= -1:
         j = m + i
     else:
         raise PartRangeError
     replace_leaf = new_leaves[j]
     if hasattr(replace_leaf, "head") and replace_leaf.head == Symbol("System`Rule"):
         new_leaves[j] = Expression(
             "System`Rule",
             replace_leaf.leaves[0],
             Expression(f, replace_leaf.leaves[1]),
         )
     else:
         new_leaves[j] = Expression(f, replace_leaf)
     return new_leaves
Example #12
0
    def apply(self, l, k, f, evaluation):
        "CombinatoricaOld`BinarySearch[l_List, k_, f_] /; Length[l] > 0"

        leaves = l.leaves

        lower_index = 1
        upper_index = len(leaves)

        if (
            lower_index > upper_index
        ):  # empty list l? Length[l] > 0 condition should guard us, but check anyway
            return Symbol("$Aborted")

        # "transform" is a handy wrapper for applying "f" or nothing
        if f.get_name() == "System`Identity":

            def transform(x):
                return x

        else:

            def transform(x):
                return Expression(f, x).evaluate(evaluation)

        # loop invariants (true at any time in the following loop):
        # (1) lower_index <= upper_index
        # (2) k > leaves[i] for all i < lower_index
        # (3) k < leaves[i] for all i > upper_index
        while True:
            pivot_index = (lower_index + upper_index) >> 1  # i.e. a + (b - a) // 2
            # as lower_index <= upper_index, lower_index <= pivot_index <= upper_index
            pivot = transform(leaves[pivot_index - 1])  # 1-based to 0-based

            # we assume a trichotomous relation: k < pivot, or k = pivot, or k > pivot
            if k < pivot:
                if pivot_index == lower_index:  # see invariant (2), to see that
                    # k < leaves[pivot_index] and k > leaves[pivot_index - 1]
                    return Rational((pivot_index - 1) + pivot_index, 2)
                upper_index = pivot_index - 1
            elif k == pivot:
                return Integer(pivot_index)
            else:  # k > pivot
                if pivot_index == upper_index:  # see invariant (3), to see that
                    # k > leaves[pivot_index] and k < leaves[pivot_index + 1]
                    return Rational(pivot_index + (pivot_index + 1), 2)
                lower_index = pivot_index + 1
Example #13
0
def get_default_value(name, evaluation, k=None, n=None):
    pos = []
    if k is not None:
        pos.append(k)
    if n is not None:
        pos.append(n)
    for pos_len in reversed(range(len(pos) + 1)):
        # Try patterns from specific to general
        defaultexpr = Expression('Default', Symbol(name),
                                 *[Integer(index) for index in pos[:pos_len]])
        result = evaluation.definitions.get_value(name, 'System`DefaultValues',
                                                  defaultexpr, evaluation)
        if result is not None:
            if result.same(defaultexpr):
                result = result.evaluate(evaluation)
            return result
    return None
Example #14
0
    def apply_1(self, rules, evaluation):
        """SparseArray[rules_List]"""
        if not (rules.has_form("List", None) and len(rules.leaves) > 0):
            if rules == Symbol("Automatic"):
                return
            print(rules.has_form("List", (1,)))
            evaluation.message("SparseArray", "list", rules)
            return

        if not rules.leaves[0].is_atom() and rules.leaves[0].get_head_name() in (
            "System`Rule",
            "System`DelayedRule",
        ):
            dims = self.find_dimensions(rules.leaves, evaluation)
            if dims is None:
                return
            return self.apply_3(rules, dims, Integer0, evaluation)
        return self.list_to_sparse(rules, evaluation)
Example #15
0
    def apply(self, number, evaluation, options={}):
        "Factorial2[number_?NumberQ, OptionsPattern[%(name)s]]"

        try:
            import scipy.special as sp
            from numpy import pi

            # From https://stackoverflow.com/a/36779406/546218
            def fact2_generic(x):
                n = (x + 1.0) / 2.0
                return 2.0**n * sp.gamma(n + 0.5) / (pi**(0.5))

        except ImportError:
            fact2_generic = None

        pref_expr = self.get_option(options, "Method", evaluation)
        is_automatic = False
        if pref_expr == Symbol("System`Automatic"):
            is_automatic = True
            preference = "mpmath"
        else:
            preference = pref_expr.get_string_value()

        if preference in ("mpmath", "Automatic"):
            number_arg = number.to_mpmath()
            convert_from_fn = from_mpmath
            fact2_fn = getattr(mpmath, self.mpmath_name)
        elif preference == "sympy":
            number_arg = number.to_sympy()
            convert_from_fn = from_sympy
            fact2_fn = getattr(sympy, self.sympy_name)
        else:
            return evaluation.message("Factorial2", "unknownp", preference)

        try:
            result = fact2_fn(number_arg)
        except:  # noqa
            number_arg = number.to_python()
            # Maybe an even negative number? Try generic routine
            if is_automatic and fact2_generic:
                return from_python(fact2_generic(number_arg))
            return evaluation.message("Factorial2", "ndf", preference,
                                      str(sys.exc_info()[1]))
        return convert_from_fn(result)
Example #16
0
    def atom_to_boxes(self, f, evaluation):
        try:
            if self.color_space == 'Grayscale':
                pixels = self.pixels
            else:
                pixels = self.color_convert('RGB').pixels

            if pixels.dtype == numpy.bool:
                pixels = skimage.img_as_ubyte(pixels)

            shape = pixels.shape

            width = shape[1]
            height = shape[0]
            scaled_width = width
            scaled_height = height

            # if the image is very small, scale it up using nearest neighbour.
            min_size = 128
            if width < min_size and height < min_size:
                scale = min_size / max(width, height)
                scaled_width = int(scale * width)
                scaled_height = int(scale * height)
                pixels = skimage.transform.resize(
                    pixels, (scaled_height, scaled_width), order=0)

            with warnings.catch_warnings():
                warnings.simplefilter("ignore")

                stream = BytesIO()
                skimage.io.imsave(stream, pixels, 'pil', format_str='png')
                stream.seek(0)
                contents = stream.read()
                stream.close()

            encoded = base64.b64encode(contents)
            if not six.PY2:
                encoded = encoded.decode('utf8')
            encoded = 'data:image/png;base64,' + encoded

            return Expression('ImageBox', String(encoded),
                              Integer(scaled_width), Integer(scaled_height))
        except:
            return Symbol("$Failed")
Example #17
0
    def apply(self, mlist, test, evaluation):
        'Split[mlist_, test_]'

        expr = Expression('Split', mlist, test)

        if mlist.is_atom():
            evaluation.message('Select', 'normal', 1, expr)
            return

        result = [[mlist.leaves[0]]]
        for leaf in mlist.leaves[1:]:
            applytest = Expression(test, result[-1][-1], leaf)
            if applytest.evaluate(evaluation) == Symbol('True'):
                result[-1].append(leaf)
            else:
                result.append([leaf])

        return Expression(mlist.head,
                          *[Expression('List', *l) for l in result])
Example #18
0
    def apply_inexact(self, z, evaluation):
        '%(name)s[z_Real|z_Complex?InexactNumberQ]'

        prec = z.get_precision()
        with mpmath.workprec(prec):
            z = sympy2mpmath(z.to_sympy())
            if z is None:
                return
            try:
                result = self.eval(z)
                result = mpmath2sympy(result, prec)
            except ValueError, exc:
                text = str(exc)
                if text == 'gamma function pole':
                    return Symbol('ComplexInfinity')
                else:
                    raise
            except ZeroDivisionError:
                return
Example #19
0
        def evaluate():
            if history_length > 0:
                self.definitions.add_rule(
                    'In', Rule(Expression('In', line_no), query))
            result = query.evaluate(self)
            if history_length > 0:
                if self.predetermined_out is not None:
                    out_result = self.predetermined_out
                    self.predetermined_out = None
                else:
                    out_result = result

                stored_result = self.get_stored_result(out_result)
                self.definitions.add_rule(
                    'Out', Rule(Expression('Out', line_no), stored_result))
            if result != Symbol('Null'):
                return self.format_output(result, self.format)
            else:
                return None
Example #20
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')
Example #21
0
        def check(level, expr):
            if not expr.has_form('List', None):
                test_expr = Expression(test, expr)
                if test_expr.evaluate(evaluation) != Symbol('True'):
                    return False
                level_dim = None
            else:
                level_dim = len(expr.leaves)

            if len(dims) > level:
                if dims[level] != level_dim:
                    return False
            else:
                dims.append(level_dim)
            if level_dim is not None:
                for leaf in expr.leaves:
                    if not check(level + 1, leaf):
                        return False
            return True
Example #22
0
    def apply(self, symbols, attributes, evaluation):
        'ClearAttributes[symbols_, attributes_]'

        symbols = get_symbol_list(
            symbols,
            lambda item: evaluation.message('ClearAttributes', 'sym', item, 1))
        if symbols is None:
            return
        values = get_symbol_list(
            attributes,
            lambda item: evaluation.message('ClearAttributes', 'sym', item, 2))
        if values is None:
            return
        for symbol in symbols:
            if 'Locked' in evaluation.definitions.get_attributes(symbol):
                evaluation.message('ClearAttributes', 'locked', symbol)
            else:
                for value in values:
                    evaluation.definitions.clear_attribute(symbol, value)
        return Symbol('Null')
Example #23
0
 def apply(self, a, b, evaluation, options):
     '%(name)s[a_, b_, OptionsPattern[%(name)s]]'
     if isinstance(a, String) and isinstance(b, String):
         py_a = a.get_string_value()
         py_b = b.get_string_value()
         if options['System`IgnoreCase'] == Symbol('True'):
             if hasattr(str, 'casefold'):
                 def normalize(c):
                     return unicodedata.normalize("NFKD", c.casefold())
                 py_a = [normalize(c) for c in py_a]
                 py_b = [normalize(c) for c in py_b]
             else:  # python2, PyPy
                 py_a = py_a.lower()
                 py_b = py_b.lower()
         return Integer(self._distance(
             py_a, py_b, lambda u, v: u == v))
     elif a.get_head_name() == 'System`List' and b.get_head_name() == 'System`List':
         return Integer(self._distance(
             a.leaves, b.leaves, lambda u, v: u.same(v)))
     else:
         return Expression('EditDistance', a, b)
    def apply(self, c, G, h, evaluation):
        "LinearProgramming[c_, G_, h_]"

        (c, G, h), subs = to_sage((c, G, h), evaluation)
        n = len(c)
        c = vector(c)
        G = matrix([[-item for item in row]
                    for row in G] + [unit_vector(k, n, -1) for k in range(n)])
        h = vector([-item for item in h] + [0] * n)
        result = linear_program(c, G, h)
        status = result['status']
        if status == 'dual infeasible':
            evaluation.message('LinearProgramming', 'lpsub')
            return Expression('List', *([Symbol('Indeterminate')] * n))
        elif status == 'primal infeasible':
            return evaluation.message('LinearProgramming', 'lpsnf')
        #print result
        x = result['x']
        x = [round(value, 6)
             for value in x]  # round result to 6 digits after comma
        return from_sage(x, subs)
Example #25
0
    def apply(self, symbols, evaluation):
        '%(name)s[symbols___]'

        for symbol in symbols.get_sequence():
            name = symbol.get_name()
            if not name:
                name = symbol.get_string_value()
            if not name:
                evaluation.message('Clear', 'ssym', symbol)
                continue
            attributes = evaluation.definitions.get_attributes(name)
            if 'Protected' in attributes:
                evaluation.message('Clear', 'wrsym', name)
                continue
            if not self.allow_locked and 'Locked' in attributes:
                evaluation.message('Clear', 'locked', name)
                continue
            definition = evaluation.definitions.get_user_definition(name)
            self.do_clear(definition)

        return Symbol('Null')
Example #26
0
    def apply(self, symbols, attributes, evaluation):
        "SetAttributes[symbols_, attributes_]"

        symbols = get_symbol_list(
            symbols,
            lambda item: evaluation.message("SetAttributes", "sym", item, 1))
        if symbols is None:
            return
        values = get_symbol_list(
            attributes,
            lambda item: evaluation.message("SetAttributes", "sym", item, 2))
        if values is None:
            return
        for symbol in symbols:
            if "System`Locked" in evaluation.definitions.get_attributes(
                    symbol):
                evaluation.message("SetAttributes", "locked", Symbol(symbol))
            else:
                for value in values:
                    evaluation.definitions.set_attribute(symbol, value)
        return SymbolNull
Example #27
0
    def apply_N(self, precision, evaluation, options={}):
        "N[Degree, precision_, OptionsPattern[%(name)s]]"
        try:
            if precision:
                d = get_precision(precision, evaluation)
            else:
                d = get_precision(Symbol("System`MachinePrecision"),
                                  evaluation)
        except PrecisionValueError:
            return

        # FIXME: There are all sorts of interactions between in the trig functions,
        # that are expected to work out right. Until we have convertion between
        # mpmath and sympy worked out so that values can be made the to the same
        # precision and compared. we have to not use mpmath right now.
        # return self.get_constant(precision, evaluation, preference="mpmath")

        if d is None:
            return MachineReal(math.pi / 180)
        else:
            return PrecisionReal((sympy.pi / 180).n(d))
Example #28
0
    def apply(self, f, expr, n, evaluation, options):
        "FixedPoint[f_, expr_, n_:DirectedInfinity[1], OptionsPattern[FixedPoint]]"
        if n == Expression("DirectedInfinity", 1):
            count = None
        else:
            count = n.get_int_value()
            if count is None or count < 0:
                evaluation.message("FixedPoint", "intnn")
                return

        if count is None:
            count = self.get_option(options, "MaxIterations", evaluation)
            if count.is_numeric():
                count = count.get_int_value()
            else:
                count = None

        result = expr
        index = 0
        sametest = self.get_option(options, "SameTest", evaluation)
        if sametest == Symbol("Automatic"):
            sametest = None

        while count is None or index < count:
            evaluation.check_stopped()
            new_result = Expression(f, result).evaluate(evaluation)
            if sametest:
                same = Expression(sametest, result,
                                  new_result).evaluate(evaluation)
                same = same.is_true()
                if same:
                    break
            else:
                if new_result == result:
                    result = new_result
                    break
            result = new_result
            index += 1

        return result