Esempio n. 1
0
class Power(BinaryOperator, SympyFunction):
    """
    <dl>
    <dt>'Power[$a$, $b$]'</dt>
    <dt>'$a$ ^ $b$'</dt>
        <dd>represents $a$ raised to the power of $b$.
    </dl>

    >> 4 ^ (1/2)
     = 2
    >> 4 ^ (1/3)
     = 2 ^ (2 / 3)
    >> 3^123
     = 48519278097689642681155855396759336072749841943521979872827

    >> (y ^ 2) ^ (1/2)
     = Sqrt[y ^ 2]
    >> (y ^ 2) ^ 3
     = y ^ 6

    >> Plot[Evaluate[Table[x^y, {y, 1, 5}]], {x, -1.5, 1.5}, AspectRatio -> 1]
     = -Graphics-

    Use a decimal point to force numeric evaluation:
    >> 4.0 ^ (1/3)
     = 1.58740105196819947

    'Power' has default value 1 for its second argument:
    >> DefaultValues[Power]
     = {HoldPattern[Default[Power, 2]] :> 1}
    >> a /. x_ ^ n_. :> {x, n}
     = {a, 1}

    'Power' can be used with complex numbers:
    >> (1.5 + 1.0 I) ^ 3.5
     = -3.68294005782191823 + 6.9513926640285049 I
    >> (1.5 + 1.0 I) ^ (3.5 + 1.5 I)
     = -3.19181629045628082 + 0.645658509416156807 I

    #> 1/0
     : Infinite expression (division by zero) encountered.
     = ComplexInfinity
    #> Sqrt[-3+2. I]
     = 0.550250522700337511 + 1.81735402102397062 I
    #> Sqrt[-3+2 I]
     = Sqrt[-3 + 2 I]
    #> (3/2+1/2I)^2
     = 2 + 3 I / 2
    #> I ^ I
     = I ^ I

    #> 2 ^ 2.0
     = 4.

    #> Pi ^ 4.
     = 97.4090910340024372
    """

    operator = '^'
    precedence = 590
    attributes = ('Listable', 'NumericFunction', 'OneIdentity')
    grouping = 'Right'

    default_formats = False

    sympy_name = 'Pow'

    messages = {
        'infy': "Infinite expression (division by zero) encountered.",
    }

    defaults = {
        2: '1',
    }

    formats = {
        Expression('Power', Expression('Pattern', Symbol('x'),
                   Expression('Blank')), Rational(1, 2)): 'HoldForm[Sqrt[x]]',
        (('InputForm', 'OutputForm'), 'x_ ^ y_'): (
            'Infix[{HoldForm[x], HoldForm[y]}, "^", 590, Right]'),
        ('', 'x_ ^ y_'): (
            'PrecedenceForm[Superscript[OuterPrecedenceForm[HoldForm[x], 590],'
            '  HoldForm[y]], 590]'),

        ('', 'x_ ^ y_?Negative'): (
            'HoldForm[Divide[1, #]]&[If[y==-1, HoldForm[x], HoldForm[x]^-y]]'),
    }

    rules = {
    }

    def apply(self, items, evaluation):
        'Power[items__]'

        items_sequence = items.get_sequence()

        if len(items_sequence) == 2:
            x, y = items_sequence
        else:
            return Expression('Power', *items_sequence)

        if y.get_int_value() == 1:
            return x
        elif x.get_int_value() == 1:
            return x
        elif y.get_int_value() == 0:
            if x.get_int_value() == 0:
                evaluation.message('Power', 'indet', Expression('Power', x, y))
                return Symbol('Indeterminate')
            else:
                return Integer(1)

        elif x.has_form('Power', 2) and isinstance(y, Integer):
            return Expression('Power', x.leaves[0],
                              Expression('Times', x.leaves[1], y))
        elif x.has_form('Times', None) and isinstance(y, Integer):
            return Expression('Times', *[
                Expression('Power', leaf, y) for leaf in x.leaves])

        elif (isinstance(x, Number) and isinstance(y, Number) and
              not (x.is_inexact() or y.is_inexact())):

            sym_x, sym_y = x.to_sympy(), y.to_sympy()

            try:
                if sympy.re(sym_y) >= 0:
                    result = sym_x ** sym_y
                else:
                    if sym_x == 0:
                        evaluation.message('Power', 'infy')
                        return Symbol('ComplexInfinity')
                    result = sympy.Integer(1) / (sym_x ** (-sym_y))
                if isinstance(result, sympy.Pow):
                    result = result.simplify()
                    args = [from_sympy(expr) for expr in result.as_base_exp()]
                    result = Expression('Power', *args)
                    result = result.evaluate_leaves(evaluation)
                    return result

                return from_sympy(result)
            except ValueError:
                return Expression('Power', x, y)
            except ZeroDivisionError:
                evaluation.message('Power', 'infy')
                return Symbol('ComplexInfinity')

        elif (isinstance(x, Number) and isinstance(y, Number) and
              (x.is_inexact() or y.is_inexact())):
            try:
                prec = min_prec(x, y)
                with mpmath.workprec(prec):
                    mp_x = sympy2mpmath(x.to_sympy(), prec)
                    mp_y = sympy2mpmath(y.to_sympy(), prec)
                    result = mp_x ** mp_y
                    if isinstance(result, mpmath.mpf):
                        return Real(str(result), prec)
                    elif isinstance(result, mpmath.mpc):
                        return Complex(str(result.real),
                                       str(result.imag), prec)
            except ZeroDivisionError:
                evaluation.message('Power', 'infy')
                return Symbol('ComplexInfinity')
        else:
            numerified_items = items.numerify(evaluation)
            return Expression('Power', *numerified_items.get_sequence())
Esempio n. 2
0
def options_to_rules(options):
    items = sorted(options.iteritems())
    return [Expression('Rule', Symbol(name), value) for name, value in items]
Esempio n. 3
0
    def apply(self, expr, form, evaluation):
        'MatchQ[expr_, form_]'

        if match(expr, form, evaluation):
            return Symbol("True")
        return Symbol("False")
Esempio n. 4
0
    def apply_empty(self, evaluation):
        'SeedRandom[]'

        with RandomEnv(evaluation) as rand:
            rand.seed()
        return Symbol('Null')
Esempio n. 5
0
 def apply(self, expr, evaluation):
     'ValueQ[expr_]'
     evaluated_expr = expr.evaluate(evaluation)
     if expr.same(evaluated_expr):
         return Symbol('False')
     return Symbol('True')
Esempio n. 6
0
 def apply_novar(self, s, evaluation):
     "MinimalPolynomial[s_]"
     x = Symbol("#1")
     return self.apply(s, x, evaluation)
Esempio n. 7
0
 def get_functions(self, prefix="apply", is_pymodule=False):
     functions = list(super(Predefined, self).get_functions(prefix))
     if prefix == "apply" and hasattr(self, "evaluate"):
         functions.append((Symbol(self.get_name()), self.evaluate))
     return functions
Esempio n. 8
0
 def apply_novar(self, s, evaluation):
     'MinimalPolynomial[s_]'
     x = Symbol('#1')
     return self.apply(s, x, evaluation)
Esempio n. 9
0
    def apply(self, vars, expr, evaluation):
        "Compile[vars_, expr_]"
        from mathics.builtin.compile import (
            _compile,
            int_type,
            real_type,
            bool_type,
            CompileArg,
            CompileError,
        )

        # _Complex not implemented
        permitted_types = {
            Expression("Blank", Symbol("Integer")): int_type,
            Expression("Blank", Symbol("Real")): real_type,
            Symbol("True"): bool_type,
            Symbol("False"): bool_type,
        }

        if not vars.has_form("List", None):
            return evaluation.message("Compile", "invars")
        args = []
        names = []
        for var in vars.get_leaves():
            if isinstance(var, Symbol):
                symb = var
                name = symb.get_name()
                typ = real_type
            elif var.has_form("List", 2):
                symb, typ = var.get_leaves()
                if isinstance(symb, Symbol) and typ in permitted_types:
                    name = symb.get_name()
                    typ = permitted_types[typ]
                else:
                    return evaluation.message("Compile", "invar", var)
            else:
                return evaluation.message("Compile", "invar", var)

            # check for duplicate names
            if name in names:
                return evaluation.message("Compile", "fdup", symb, vars)
            else:
                names.append(name)
            args.append(CompileArg(name, typ))

        try:
            cfunc = _compile(expr, args)
        except CompileError:
            cfunc = None

        if cfunc is None:
            try:

                def _pythonized_mathics_expr(*x):
                    inner_evaluation = Evaluation(definitions=evaluation.definitions)
                    vars = dict(list(zip(names, x[: len(names)])))
                    pyexpr = expr.replace_vars(vars)
                    pyexpr = Expression("N", pyexpr).evaluate(inner_evaluation)
                    res = pyexpr.to_python(n_evaluation=inner_evaluation)
                    return res

                # TODO: check if we can use numba to compile this...
                cfunc = _pythonized_mathics_expr
            except Exception:
                cfunc = None

        if cfunc is None:
            evaluation.message("Compile", "comperr", expr)
            args = Expression("List", *names)
            return Expression("Function", args, expr)

        code = CompiledCode(cfunc, args)
        arg_names = Expression("List", *(Symbol(arg.name) for arg in args))
        return Expression("CompiledFunction", arg_names, expr, code)
Esempio n. 10
0
 def from_sympy(self, sympy_name, leaves):
     return Expression('Power', Symbol('E'), leaves[0])
Esempio n. 11
0
    def set_ownvalue(self, name, value):
        from .expression import Symbol
        from .rules import Rule

        name = self.lookup_name(name)
        self.add_rule(name, Rule(Symbol(name), value))
Esempio n. 12
0
 def to_sympy(self, expr):
     if expr == Symbol('System`Degree'):
         return sympy.pi / 180
Esempio n. 13
0
def from_sympy(expr):
    from mathics.builtin import sympy_to_mathics
    from mathics.core.expression import (Symbol, Integer, Rational, Real,
                                         Complex, String, Expression)

    from sympy.core import numbers, function, symbol

    if isinstance(expr, (tuple, list)):
        return Expression('List', *[from_sympy(item) for item in expr])
    if isinstance(expr, int):
        return Integer(expr)
    if isinstance(expr, float):
        return Real(expr)
    if isinstance(expr, complex):
        return Complex(expr.real, expr.imag)
    if isinstance(expr, str):
        return String(expr)
    if expr is None:
        return Symbol('Null')
    if isinstance(expr, sympy.Matrix):
        return Expression(
            'List', *[
                Expression('List', *[from_sympy(item) for item in row])
                for row in expr.tolist()
            ])
    if expr.is_Atom:
        name = None
        if expr.is_Symbol:
            name = unicode(expr)
            if isinstance(expr, symbol.Dummy):
                name = name + ('__Dummy_%d' % expr.dummy_index)
                return Symbol(name, sympy_dummy=expr)
            if ((
                    not name.startswith(sympy_symbol_prefix) or  # noqa
                    name.startswith(sympy_slot_prefix))
                    and name.startswith('C')):
                return Expression('C', int(name[1:]))
            if name.startswith(sympy_symbol_prefix):
                name = name[len(sympy_symbol_prefix):]
            if name.startswith(sympy_slot_prefix):
                index = name[len(sympy_slot_prefix):]
                return Expression('Slot', int(index))
        elif expr.is_NumberSymbol:
            name = unicode(expr)
        if name is not None:
            builtin = sympy_to_mathics.get(name)
            if builtin is not None:
                name = builtin.get_name()
            return Symbol(name)
        elif isinstance(expr, (numbers.Infinity, numbers.ComplexInfinity)):
            return Symbol(expr.__class__.__name__)
        elif isinstance(expr, numbers.NegativeInfinity):
            return Expression('Times', Integer(-1), Symbol('Infinity'))
        elif isinstance(expr, numbers.ImaginaryUnit):
            return Complex(0, 1)
        elif isinstance(expr, numbers.Integer):
            return Integer(expr.p)
        elif isinstance(expr, numbers.Rational):
            if expr.q == 0:
                if expr.p > 0:
                    return Symbol('Infinity')
                elif expr.p < 0:
                    return Expression('Times', Integer(-1), Symbol('Infinity'))
                else:
                    assert expr.p == 0
                    return Symbol('Indeterminate')
            return Rational(expr.p, expr.q)
        elif isinstance(expr, numbers.Float):
            return Real(expr)
        elif isinstance(expr, numbers.NaN):
            return Symbol('Indeterminate')
        elif isinstance(expr, function.FunctionClass):
            return Symbol(unicode(expr))
    elif expr.is_number and all([x.is_Number for x in expr.as_real_imag()]):
        # Hack to convert 3 * I to Complex[0, 3]
        return Complex(*[from_sympy(arg) for arg in expr.as_real_imag()])
    elif expr.is_Add:
        return Expression('Plus',
                          *sorted([from_sympy(arg) for arg in expr.args]))
    elif expr.is_Mul:
        return Expression('Times',
                          *sorted([from_sympy(arg) for arg in expr.args]))
    elif expr.is_Pow:
        return Expression('Power', *[from_sympy(arg) for arg in expr.args])
    elif expr.is_Equality:
        return Expression('Equal', *[from_sympy(arg) for arg in expr.args])

    elif isinstance(expr, SympyExpression):
        # print "SympyExpression: %s" % expr
        return expr.expr

    elif isinstance(expr, sympy.RootSum):
        return Expression('RootSum', from_sympy(expr.poly),
                          from_sympy(expr.fun))
    elif isinstance(expr, sympy.PurePoly):
        coeffs = expr.coeffs()
        monoms = expr.monoms()
        result = []
        for coeff, monom in zip(coeffs, monoms):
            factors = []
            if coeff != 1:
                factors.append(from_sympy(coeff))
            for index, exp in enumerate(monom):
                if exp != 0:
                    slot = Expression('Slot', index + 1)
                    if exp == 1:
                        factors.append(slot)
                    else:
                        factors.append(
                            Expression('Power', slot, from_sympy(exp)))
            if factors:
                result.append(Expression('Times', *factors))
            else:
                result.append(Integer(1))
        return Expression('Function', Expression('Plus', *result))
    elif isinstance(expr, sympy.Lambda):
        vars = [
            sympy.Symbol('%s%d' % (sympy_slot_prefix, index + 1))
            for index in range(len(expr.variables))
        ]
        return Expression('Function', from_sympy(expr(*vars)))

    elif expr.is_Function or isinstance(
            expr,
        (sympy.Integral, sympy.Derivative, sympy.Sum, sympy.Product)):
        if isinstance(expr, sympy.Integral):
            name = 'Integral'
        elif isinstance(expr, sympy.Derivative):
            name = 'Derivative'
        else:
            name = expr.func.__name__
            if name.startswith(sympy_symbol_prefix):
                name = name[len(sympy_symbol_prefix):]
        args = [from_sympy(arg) for arg in expr.args]
        builtin = sympy_to_mathics.get(name)
        if builtin is not None:
            name = builtin.get_name()
            args = builtin.from_sympy(args)
        return Expression(Symbol(name), *args)

    elif isinstance(expr, sympy.Tuple):
        return Expression('List', *[from_sympy(arg) for arg in expr.args])

    # elif isinstance(expr, sympy.Sum):
    #    return Expression('Sum', )

    elif isinstance(expr, sympy.LessThan):
        return Expression('LessEqual', [from_sympy(arg) for arg in expr.args])
    elif isinstance(expr, sympy.StrictLessThan):
        return Expression('Less', [from_sympy(arg) for arg in expr.args])
    elif isinstance(expr, sympy.GreaterThan):
        return Expression('GreaterEqual',
                          [from_sympy(arg) for arg in expr.args])
    elif isinstance(expr, sympy.StrictGreaterThan):
        return Expression('Greater', [from_sympy(arg) for arg in expr.args])
    elif isinstance(expr, sympy.Unequality):
        return Expression('Unequal', [from_sympy(arg) for arg in expr.args])
    elif isinstance(expr, sympy.Equality):
        return Expression('Equal', [from_sympy(arg) for arg in expr.args])
    else:
        raise ValueError("Unknown SymPy expression: %s" % expr)
Esempio n. 14
0
    def apply(self, items, evaluation):
        'Power[items__]'

        items_sequence = items.get_sequence()

        if len(items_sequence) == 2:
            x, y = items_sequence
        else:
            return Expression('Power', *items_sequence)

        if y.get_int_value() == 1:
            return x
        elif x.get_int_value() == 1:
            return x
        elif y.get_int_value() == 0:
            if x.get_int_value() == 0:
                evaluation.message('Power', 'indet', Expression('Power', x, y))
                return Symbol('Indeterminate')
            else:
                return Integer(1)

        elif x.has_form('Power', 2) and isinstance(y, Integer):
            return Expression('Power', x.leaves[0],
                              Expression('Times', x.leaves[1], y))
        elif x.has_form('Times', None) and isinstance(y, Integer):
            return Expression('Times', *[
                Expression('Power', leaf, y) for leaf in x.leaves])

        elif (isinstance(x, Number) and isinstance(y, Number) and
              not (x.is_inexact() or y.is_inexact())):

            sym_x, sym_y = x.to_sympy(), y.to_sympy()

            try:
                if sympy.re(sym_y) >= 0:
                    result = sym_x ** sym_y
                else:
                    if sym_x == 0:
                        evaluation.message('Power', 'infy')
                        return Symbol('ComplexInfinity')
                    result = sympy.Integer(1) / (sym_x ** (-sym_y))
                if isinstance(result, sympy.Pow):
                    result = result.simplify()
                    args = [from_sympy(expr) for expr in result.as_base_exp()]
                    result = Expression('Power', *args)
                    result = result.evaluate_leaves(evaluation)
                    return result

                return from_sympy(result)
            except ValueError:
                return Expression('Power', x, y)
            except ZeroDivisionError:
                evaluation.message('Power', 'infy')
                return Symbol('ComplexInfinity')

        elif (isinstance(x, Number) and isinstance(y, Number) and
              (x.is_inexact() or y.is_inexact())):
            try:
                prec = min_prec(x, y)
                with mpmath.workprec(prec):
                    mp_x = sympy2mpmath(x.to_sympy(), prec)
                    mp_y = sympy2mpmath(y.to_sympy(), prec)
                    result = mp_x ** mp_y
                    if isinstance(result, mpmath.mpf):
                        return Real(str(result), prec)
                    elif isinstance(result, mpmath.mpc):
                        return Complex(str(result.real),
                                       str(result.imag), prec)
            except ZeroDivisionError:
                evaluation.message('Power', 'infy')
                return Symbol('ComplexInfinity')
        else:
            numerified_items = items.numerify(evaluation)
            return Expression('Power', *numerified_items.get_sequence())
Esempio n. 15
0
 def lhs(expr):
     return Expression('Format', expr, Symbol(format))
Esempio n. 16
0
class DensityPlot(Builtin):
    """
    <dl>
    <dt>'DensityPlot[$f$, {$x$, $xmin$, $xmax$}, {$y$, $ymin$, $ymax$}]'
        <dd>plots a density plot of $f$ with $x$ ranging from $xmin$ to $xmax$ and $y$ ranging from $ymin$ to $ymax$.
    </dl>
    
    >> DensityPlot[x ^ 2 + 1 / y, {x, -1, 1}, {y, 1, 4}]
     = -Graphics-
    """

    from graphics import Graphics

    attributes = ('HoldAll', )

    options = Graphics.options.copy()
    options.update({
        'Axes': 'False',
        'AspectRatio': '1',
        'Frame': 'True',
        'ColorFunction': 'Automatic',
        'ColorFunctionScaling': 'True',
    })

    def apply(self, f, x, xstart, xstop, y, ystart, ystop, evaluation,
              options):
        'DensityPlot[f_, {x_Symbol, xstart_, xstop_}, {y_Symbol, ystart_, ystop_}, OptionsPattern[DensityPlot]]'

        x = x.get_name()
        y = y.get_name()

        color_function = self.get_option(options,
                                         'ColorFunction',
                                         evaluation,
                                         pop=True)
        color_function_scaling = self.get_option(options,
                                                 'ColorFunctionScaling',
                                                 evaluation,
                                                 pop=True)

        color_function_min = color_function_max = None
        if color_function.get_name() == 'Automatic':
            color_function = String('LakeColors')
        if color_function.get_string_value():
            func = Expression(
                'ColorData',
                color_function.get_string_value()).evaluate(evaluation)
            if func.has_form('ColorDataFunction', 4):
                color_function_min = func.leaves[2].leaves[0].get_real_value()
                color_function_max = func.leaves[2].leaves[1].get_real_value()
                color_function = Expression(
                    'Function',
                    Expression(func.leaves[3], Expression('Slot', 1)))
            else:
                evaluation.message('DensityPlot', 'color', func)
                return
        if color_function.has_form('ColorDataFunction', 4):
            color_function_min = color_function.leaves[2].leaves[
                0].get_real_value()
            color_function_max = color_function.leaves[2].leaves[
                1].get_real_value()

        color_function_scaling = color_function_scaling.is_true()

        try:
            xstart, xstop, ystart, ystop = [
                value.to_number(n_evaluation=evaluation)
                for value in (xstart, xstop, ystart, ystop)
            ]
        except NumberError, exc:
            expr = Expression('DensityPlot', f,
                              Expression('List', x, xstart, xstop),
                              Expression('List', y, ystart, ystop),
                              *options_to_rules(options))
            evaluation.message('DensityPlot', 'plln', exc.value, expr)
            return

        #print "Initialized"

        stored = {}

        def eval_f(x_value, y_value):
            value = stored.get((x_value, y_value), False)
            if value == False:
                value = dynamic_scoping(f.evaluate, {
                    x: Real(x_value),
                    y: Real(y_value)
                }, evaluation)
                value = chop(value).get_real_value()
                value = float(value)
                stored[(x_value, y_value)] = value
            return value

        v_borders = [None, None]

        triangles = []

        eps = 0.01

        def triangle(x1, y1, x2, y2, x3, y3, depth=None):
            if depth is None:
                x1, x2, x3 = [
                    xstart + value * (xstop - xstart) for value in (x1, x2, x3)
                ]
                y1, y2, y3 = [
                    ystart + value * (ystop - ystart) for value in (y1, y2, y3)
                ]
                depth = 0
            v1, v2, v3 = eval_f(x1, y1), eval_f(x2, y2), eval_f(x3, y3)
            for v in (v1, v2, v3):
                if v_borders[0] is None or v < v_borders[0]:
                    v_borders[0] = v
                if v_borders[1] is None or v > v_borders[1]:
                    v_borders[1] = v
            if v1 is None or v2 is None or v3 is None:
                return
            limit = (v_borders[1] - v_borders[0]) * eps
            if depth < 2:
                if abs(v1 - v2) > limit:
                    triangle(x1, y1, x3, y3, (x1 + x2) / 2, (y1 + y2) / 2,
                             depth + 1)
                    triangle(x2, y2, x3, y3, (x1 + x2) / 2, (y1 + y2) / 2,
                             depth + 1)
                    return
                if abs(v2 - v3) > limit:
                    triangle(x1, y1, x2, y2, (x2 + x3) / 2, (y2 + y3) / 2,
                             depth + 1)
                    triangle(x1, y1, x3, y3, (x2 + x3) / 2, (y2 + y3) / 2,
                             depth + 1)
                    return
                if abs(v1 - v3) > limit:
                    triangle(x2, y2, x1, y1, (x1 + x3) / 2, (y1 + y3) / 2,
                             depth + 1)
                    triangle(x2, y2, x3, y3, (x1 + x3) / 2, (y1 + y3) / 2,
                             depth + 1)
                    return
            triangles.append([(x1, y1, v1), (x2, y2, v2), (x3, y3, v3)])

        points = 7
        num = points * 1.0
        for xi in range(points):
            for yi in range(points):
                triangle(xi / num, yi / num, (xi + 1) / num, (yi + 1) / num,
                         (xi + 1) / num, yi / num)
                triangle(xi / num, yi / num, (xi + 1) / num, (yi + 1) / num,
                         xi / num, (yi + 1) / num)

        v_min = v_max = None

        #if color_function_scaling:
        for t in triangles:
            for tx, ty, v in t:
                if v_min is None or v < v_min:
                    v_min = v
                if v_max is None or v > v_max:
                    v_max = v
        v_range = v_max - v_min
        if v_range == 0:
            v_range = 1

        if color_function.has_form('ColorDataFunction', 4):
            color_func = color_function.leaves[3]
        else:
            color_func = color_function
        if color_function_scaling and color_function_min is not None and color_function_max is not None:
            color_function_range = color_function_max - color_function_min

        colors = {}

        def eval_color(x, y, v):
            #v_lookup = int(v * 100)
            #if color_function_scaling:
            v_scaled = (v - v_min) / v_range
            if color_function_scaling and color_function_min is not None and color_function_max is not None:
                v_color_scaled = color_function_min + v_scaled * color_function_range
            else:
                v_color_scaled = v
            v_lookup = int(
                v_scaled * 100 +
                0.5)  # calculate and store 100 different shades max.
            value = colors.get(v_lookup)
            if value is None:
                #print "Calc"
                #print "Scale"
                #print "Expression"
                #print "Calc color for %f" % v_scaled
                value = Expression(color_func, Real(v_color_scaled))
                #print "Evaluate %s" % value
                value = value.evaluate(evaluation)
                #value = Expression('RGBColor', Real(0.5), Real(0.5), Real(0.5))
                #print "Set"
                colors[v_lookup] = value
            return value

        #print "Points"
        points = []
        vertex_colors = []
        for p1, p2, p3 in triangles:
            #print "Triangle %s,%s,%s" % (p1, p2, p3)
            c1, c2, c3 = eval_color(*p1), eval_color(*p2), eval_color(*p3)
            #print "Append"
            points.append(
                Expression('List', Expression('List', *p1[:2]),
                           Expression('List', *p2[:2]),
                           Expression('List', *p3[:2])))
            vertex_colors.append(Expression('List', c1, c2, c3))

        #print "Polygon"
        polygon = Expression(
            'Polygon', Expression('List', *points),
            Expression('Rule', Symbol('VertexColors'),
                       Expression('List', *vertex_colors)))
        #print "Result"
        result = Expression('Graphics', polygon, *options_to_rules(options))
        #print "Return"
        return result
Esempio n. 17
0
    def apply(self, expr, form, evaluation):
        "CoefficientList[expr_, form_]"
        vars = [form] if not form.has_form("List", None) else [
            v for v in form.leaves
        ]

        # check form is not a variable
        for v in vars:
            if not (isinstance(v, Symbol)) and not (isinstance(v, Expression)):
                return evaluation.message("CoefficientList", "ivar", v)

        # special cases for expr and form
        e_null = expr == Symbol("Null")
        f_null = form == Symbol("Null")
        if expr == Integer(0):
            return Expression("List")
        elif e_null and f_null:
            return Expression("List", Integer(0), Integer(0))
        elif e_null and not f_null:
            return Expression("List", Symbol("Null"))
        elif f_null:
            return Expression("List", expr)
        elif form.has_form("List", 0):
            return expr

        sympy_expr = expr.to_sympy()
        sympy_vars = [v.to_sympy() for v in vars]

        if not sympy_expr.is_polynomial(*[x for x in sympy_vars]):
            return evaluation.message("CoefficientList", "poly", expr)

        try:
            sympy_poly, sympy_opt = sympy.poly_from_expr(
                sympy_expr, sympy_vars)
            dimensions = [
                sympy_poly.degree(x) if x in sympy_poly.gens else 0
                for x in sympy_vars
            ]

            # single & multiple variables cases
            if not form.has_form("List", None):
                return Expression(
                    "List", *[
                        _coefficient(self.__class__.__name__, expr, form,
                                     Integer(n), evaluation)
                        for n in range(dimensions[0] + 1)
                    ])
            elif form.has_form("List", 1):
                form = form.leaves[0]
                return Expression(
                    "List", *[
                        _coefficient(self.__class__.__name__, expr, form,
                                     Integer(n), evaluation)
                        for n in range(dimensions[0] + 1)
                    ])
            else:

                def _nth(poly, dims, exponents):
                    if not dims:
                        return from_sympy(poly.coeff_monomial(exponents))

                    leaves = []
                    first_dim = dims[0]
                    for i in range(first_dim + 1):
                        exponents.append(i)
                        subs = _nth(poly, dims[1:], exponents)
                        leaves.append(subs)
                        exponents.pop()
                    result = Expression("List", *leaves)
                    return result

                return _nth(sympy_poly, dimensions, [])
        except sympy.PolificationFailed:
            return evaluation.message("CoefficientList", "poly", expr)
Esempio n. 18
0
def options_to_rules(options, filter=None):
    items = sorted(options.items())
    if filter:
        items = [(name, value) for name, value in items
                 if strip_context(name) in filter.keys()]
    return [Expression('Rule', Symbol(name), value) for name, value in items]
Esempio n. 19
0
 def p_symbol(self, args):
     'expr : symbol'
     args[0] = Symbol(args[1])
Esempio n. 20
0
    def construct_graphics(self, triangles, mesh_points, v_min, v_max, options, evaluation):
        mesh_option = self.get_option(options, 'Mesh', evaluation)
        mesh = mesh_option.to_python()

        color_function = self.get_option(options, 'ColorFunction', evaluation, pop=True)
        color_function_scaling = self.get_option(options, 'ColorFunctionScaling', evaluation, pop=True)

        color_function_min = color_function_max = None
        if color_function.get_name() == 'Automatic':
            color_function = String('LakeColors')
        if color_function.get_string_value():
            func = Expression('ColorData', color_function.get_string_value()).evaluate(evaluation)
            if func.has_form('ColorDataFunction', 4):
                color_function_min = func.leaves[2].leaves[0].get_real_value()
                color_function_max = func.leaves[2].leaves[1].get_real_value()
                color_function = Expression('Function', Expression(func.leaves[3], Expression('Slot', 1)))
            else:
                evaluation.message('DensityPlot', 'color', func)
                return
        if color_function.has_form('ColorDataFunction', 4):
            color_function_min = color_function.leaves[2].leaves[0].get_real_value()
            color_function_max = color_function.leaves[2].leaves[1].get_real_value()

        color_function_scaling = color_function_scaling.is_true()
        v_range = v_max - v_min

        if v_range == 0:
            v_range = 1

        if color_function.has_form('ColorDataFunction', 4):
            color_func = color_function.leaves[3]
        else:
            color_func = color_function
        if color_function_scaling and color_function_min is not None and color_function_max is not None:
            color_function_range = color_function_max - color_function_min

        colors = {}
        def eval_color(x, y, v):
            v_scaled = (v - v_min) / v_range
            if color_function_scaling and color_function_min is not None and color_function_max is not None:
                v_color_scaled = color_function_min + v_scaled * color_function_range
            else:
                v_color_scaled = v
            v_lookup = int(v_scaled * 100 + 0.5)     # calculate and store 100 different shades max.
            value = colors.get(v_lookup)
            if value is None:
                value = Expression(color_func, Real(v_color_scaled))
                value = value.evaluate(evaluation)
                colors[v_lookup] = value
            return value

        points = []
        vertex_colors = []
        graphics = []
        for p1, p2, p3 in triangles:
            c1, c2, c3 = eval_color(*p1), eval_color(*p2), eval_color(*p3)
            points.append(Expression('List', Expression('List', *p1[:2]), Expression('List', *p2[:2]),
                Expression('List', *p3[:2])))
            vertex_colors.append(Expression('List', c1, c2, c3))

        graphics.append(Expression('Polygon', Expression('List', *points),
            Expression('Rule', Symbol('VertexColors'), Expression('List', *vertex_colors))))

        if mesh == 'Full':
            for xi in range(len(mesh_points)):
                line = []
                for yi in range(len(mesh_points[xi])):
                    line.append(Expression('List', mesh_points[xi][yi][0], mesh_points[xi][yi][1]))
                graphics.append(Expression('Line', Expression('List', *line)))
        elif mesh == 'All':
            for p1, p2, p3 in triangles:
                line = [from_python(p1[:2]), from_python(p2[:2]), from_python(p3[:2])]
                graphics.append(Expression('Line', Expression('List', *line)))
        return graphics
Esempio n. 21
0
    def contribute(self, definitions, is_pymodule=False):
        from mathics.core.parser import parse_builtin_rule

        if is_pymodule:
            name = "PyMathics`" + self.get_name(short=True)
        else:
            name = self.get_name()

        options = {}
        option_syntax = "Warn"
        for option, value in self.options.items():
            if option == "$OptionSyntax":
                option_syntax = value
                continue
            option = ensure_context(option)
            options[option] = parse_builtin_rule(value)
            if option.startswith("System`"):
                # Create a definition for the option's symbol.
                # Otherwise it'll be created in Global` when it's
                # used, so it won't work.
                if option not in definitions.builtin:
                    definitions.builtin[option] = Definition(name=name,
                                                             attributes=set())

        # Check if the given options are actually supported by the Builtin.
        # If not, we might issue an optx error and abort. Using '$OptionSyntax'
        # in your Builtin's 'options', you can specify the exact behaviour
        # using one of the following values:

        # - 'Strict': warn and fail with unsupported options
        # - 'Warn': warn about unsupported options, but continue
        # - 'Ignore': allow unsupported options, do not warn

        if option_syntax in ("Strict", "Warn", "System`Strict", "System`Warn"):

            def check_options(options_to_check, evaluation):
                name = self.get_name()
                for key, value in options_to_check.items():
                    short_key = strip_context(key)
                    if not has_option(options, short_key, evaluation):
                        evaluation.message(
                            name,
                            "optx",
                            Expression("Rule", short_key, value),
                            strip_context(name),
                        )
                        if option_syntax in ("Strict", "System`Strict"):
                            return False
                return True

        elif option_syntax in ("Ignore", "System`Ignore"):
            check_options = None
        else:
            raise ValueError("illegal option mode %s; check $OptionSyntax." %
                             option_syntax)

        rules = []
        definition_class = (PyMathicsDefinitions()
                            if is_pymodule else SystemDefinitions())

        for pattern, function in self.get_functions(is_pymodule=is_pymodule):
            rules.append(
                BuiltinRule(name,
                            pattern,
                            function,
                            check_options,
                            system=not is_pymodule))
        for pattern, replace in self.rules.items():
            if not isinstance(pattern, BaseExpression):
                pattern = pattern % {"name": name}
                pattern = parse_builtin_rule(pattern, definition_class)
            replace = replace % {"name": name}
            # FIXME: Should system=True be system=not is_pymodule ?
            rules.append(
                Rule(pattern, parse_builtin_rule(replace), system=True))

        box_rules = []
        if name != "System`MakeBoxes":
            new_rules = []
            for rule in rules:
                if rule.pattern.get_head_name() == "System`MakeBoxes":
                    box_rules.append(rule)
                else:
                    new_rules.append(rule)
            rules = new_rules

        def extract_forms(name, pattern):
            # Handle a tuple of (forms, pattern) as well as a pattern
            # on the left-hand side of a format rule. 'forms' can be
            # an empty string (=> the rule applies to all forms), or a
            # form name (like 'System`TraditionalForm'), or a sequence
            # of form names.
            def contextify_form_name(f):
                # Handle adding 'System`' to a form name, unless it's
                # '' (meaning the rule applies to all forms).
                return "" if f == "" else ensure_context(f)

            if isinstance(pattern, tuple):
                forms, pattern = pattern
                if isinstance(forms, str):
                    forms = [contextify_form_name(forms)]
                else:
                    forms = [contextify_form_name(f) for f in forms]
            else:
                forms = [""]
            return forms, pattern

        formatvalues = {"": []}
        for pattern, function in self.get_functions("format_"):
            forms, pattern = extract_forms(name, pattern)
            for form in forms:
                if form not in formatvalues:
                    formatvalues[form] = []
                formatvalues[form].append(
                    BuiltinRule(name, pattern, function, None, system=True))
        for pattern, replace in self.formats.items():
            forms, pattern = extract_forms(name, pattern)
            for form in forms:
                if form not in formatvalues:
                    formatvalues[form] = []
                if not isinstance(pattern, BaseExpression):
                    pattern = pattern % {"name": name}
                    pattern = parse_builtin_rule(pattern)
                replace = replace % {"name": name}
                formatvalues[form].append(
                    Rule(pattern, parse_builtin_rule(replace), system=True))
        for form, formatrules in formatvalues.items():
            formatrules.sort()

        messages = [
            Rule(
                Expression("MessageName", Symbol(name), String(msg)),
                String(value),
                system=True,
            ) for msg, value in self.messages.items()
        ]

        messages.append(
            Rule(
                Expression("MessageName", Symbol(name), String("optx")),
                String("`1` is not a supported option for `2`[]."),
                system=True,
            ))

        if name == "System`MakeBoxes":
            attributes = []
        else:
            attributes = ["System`Protected"]
        attributes += list(ensure_context(a) for a in self.attributes)
        options = {}
        for option, value in self.options.items():
            option = ensure_context(option)
            options[option] = parse_builtin_rule(value)
            if option.startswith("System`"):
                # Create a definition for the option's symbol.
                # Otherwise it'll be created in Global` when it's
                # used, so it won't work.
                if option not in definitions.builtin:
                    definitions.builtin[option] = Definition(name=name,
                                                             attributes=set())
        defaults = []
        for spec, value in self.defaults.items():
            value = parse_builtin_rule(value)
            pattern = None
            if spec is None:
                pattern = Expression("Default", Symbol(name))
            elif isinstance(spec, int):
                pattern = Expression("Default", Symbol(name), Integer(spec))
            if pattern is not None:
                defaults.append(Rule(pattern, value, system=True))
        definition = Definition(
            name=name,
            rules=rules,
            formatvalues=formatvalues,
            messages=messages,
            attributes=attributes,
            options=options,
            defaultvalues=defaults,
        )
        if is_pymodule:
            definitions.pymathics[name] = definition
        else:
            definitions.builtin[name] = definition

        makeboxes_def = definitions.builtin["System`MakeBoxes"]
        for rule in box_rules:
            makeboxes_def.add_rule(rule)
Esempio n. 22
0
 def get_result(self, items):
     return Symbol('Null')
Esempio n. 23
0
    def apply_words(self, words, evaluation, options):
        'WordCloud[words_List, OptionsPattern[%(name)s]]'
        ignore_case = self.get_option(options, 'IgnoreCase',
                                      evaluation) == Symbol('True')

        freq = dict()
        for word in words.leaves:
            if not isinstance(word, String):
                return
            py_word = word.get_string_value()
            if ignore_case:
                key = py_word.lower()
            else:
                key = py_word
            record = freq.get(key, None)
            if record is None:
                freq[key] = [py_word, 1]
            else:
                record[1] += 1

        max_items = self.get_option(options, 'MaxItems', evaluation)
        if isinstance(max_items, Integer):
            py_max_items = max_items.get_int_value()
        else:
            py_max_items = 200

        image_size = self.get_option(options, 'ImageSize', evaluation)
        if image_size == Symbol('Automatic'):
            py_image_size = (800, 600)
        elif image_size.get_head_name() == 'System`List' and len(
                image_size.leaves) == 2:
            py_image_size = []
            for leaf in image_size.leaves:
                if not isinstance(leaf, Integer):
                    return
                py_image_size.append(leaf.get_int_value())
        elif isinstance(image_size, Integer):
            size = image_size.get_int_value()
            py_image_size = (size, size)
        else:
            return

        # inspired by http://minimaxir.com/2016/05/wordclouds/
        import random
        import os

        def color_func(word,
                       font_size,
                       position,
                       orientation,
                       random_state=None,
                       **kwargs):
            return self.default_colors[random.randint(0, 7)]

        font_base_path = os.path.dirname(
            os.path.abspath(__file__)) + '/../fonts/'

        font_path = os.path.realpath(font_base_path + 'AmaticSC-Bold.ttf')
        if not os.path.exists(font_path):
            font_path = None

        from wordcloud import WordCloud
        wc = WordCloud(width=py_image_size[0],
                       height=py_image_size[1],
                       font_path=font_path,
                       max_font_size=300,
                       mode='RGB',
                       background_color='white',
                       max_words=py_max_items,
                       color_func=color_func,
                       random_state=42,
                       stopwords=set())
        wc.generate_from_frequencies(freq.values())

        image = wc.to_image()
        return Image(numpy.array(image), 'RGB')
Esempio n. 24
0
    def apply(self, evaluation):
        'Quit[]'

        evaluation.definitions.set_user_definitions({})
        return Symbol('Null')
Esempio n. 25
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)
Esempio n. 26
0
    def assign_elementary(self, lhs, rhs, evaluation, tags=None, upset=False):
        name = lhs.get_head_name()

        if name in system_symbols('OwnValues', 'DownValues', 'SubValues',
                                  'UpValues', 'NValues', 'Options',
                                  'DefaultValues', 'Attributes', 'Messages'):
            if len(lhs.leaves) != 1:
                evaluation.message_args(name, len(lhs.leaves), 1)
                return False
            tag = lhs.leaves[0].get_name()
            if not tag:
                evaluation.message(name, 'sym', lhs.leaves[0], 1)
                return False
            if tags is not None and tags != [tag]:
                evaluation.message(name, 'tag', Symbol(name), Symbol(tag))
                return False

            if (name != 'System`Attributes' and 'System`Protected'  # noqa
                    in evaluation.definitions.get_attributes(tag)):
                evaluation.message(name, 'wrsym', Symbol(tag))
                return False
            if name == 'System`Options':
                option_values = rhs.get_option_values(evaluation)
                if option_values is None:
                    evaluation.message(name, 'options', rhs)
                    return False
                evaluation.definitions.set_options(tag, option_values)
            elif name == 'System`Attributes':
                attributes = get_symbol_list(
                    rhs, lambda item: evaluation.message(name, 'sym', item, 1))
                if attributes is None:
                    return False
                if 'System`Locked' in evaluation.definitions.get_attributes(
                        tag):
                    evaluation.message(name, 'locked', Symbol(tag))
                    return False
                evaluation.definitions.set_attributes(tag, attributes)
            else:
                rules = rhs.get_rules_list()
                if rules is None:
                    evaluation.message(name, 'vrule', lhs, rhs)
                    return False
                evaluation.definitions.set_values(tag, name, rules)
            return True

        form = ''
        nprec = None
        default = False
        message = False

        allow_custom_tag = False

        focus = lhs

        if name == 'System`N':
            if len(lhs.leaves) not in (1, 2):
                evaluation.message_args('N', len(lhs.leaves), 1, 2)
                return False
            if len(lhs.leaves) == 1:
                nprec = Symbol('MachinePrecision')
            else:
                nprec = lhs.leaves[1]
            focus = lhs.leaves[0]
            lhs = Expression('N', focus, nprec)
        elif name == 'System`MessageName':
            if len(lhs.leaves) != 2:
                evaluation.message_args('MessageName', len(lhs.leaves), 2)
                return False
            focus = lhs.leaves[0]
            message = True
        elif name == 'System`Default':
            if len(lhs.leaves) not in (1, 2, 3):
                evaluation.message_args('Default', len(lhs.leaves), 1, 2, 3)
                return False
            focus = lhs.leaves[0]
            default = True
        elif name == 'System`Format':
            if len(lhs.leaves) not in (1, 2):
                evaluation.message_args('Format', len(lhs.leaves), 1, 2)
                return False
            if len(lhs.leaves) == 2:
                form = lhs.leaves[1].get_name()
                if not form:
                    evaluation.message('Format', 'fttp', lhs.leaves[1])
                    return False
            else:
                form = system_symbols('StandardForm', 'TraditionalForm',
                                      'OutputForm', 'TeXForm', 'MathMLForm')
            lhs = focus = lhs.leaves[0]
        else:
            allow_custom_tag = True

        focus = focus.evaluate_leaves(evaluation)

        if tags is None and not upset:
            name = focus.get_lookup_name()
            if not name:
                evaluation.message(self.get_name(), 'setraw', focus)
                return False
            tags = [name]
        elif upset:
            if allow_custom_tag:
                tags = []
                if focus.is_atom():
                    evaluation.message(self.get_name(), 'normal')
                    return False
                for leaf in focus.leaves:
                    name = leaf.get_lookup_name()
                    tags.append(name)
            else:
                tags = [focus.get_lookup_name()]
        else:
            allowed_names = [focus.get_lookup_name()]
            if allow_custom_tag:
                for leaf in focus.get_leaves():
                    allowed_names.append(leaf.get_lookup_name())
            for name in tags:
                if name not in allowed_names:
                    evaluation.message(self.get_name(), 'tagnfd', Symbol(name))
                    return False

        ignore_protection = False
        rhs_int_value = rhs.get_int_value()
        lhs_name = lhs.get_name()
        if lhs_name == 'System`$RecursionLimit':
            # if (not rhs_int_value or rhs_int_value < 20) and not
            # rhs.get_name() == 'System`Infinity':
            if (not rhs_int_value or rhs_int_value < 20
                    or rhs_int_value > settings.MAX_RECURSION_DEPTH):  # nopep8

                evaluation.message('$RecursionLimit', 'limset', rhs)
                return False
            try:
                set_recursionlimit(rhs_int_value)
            except OverflowError:
                # TODO: Message
                return False
            ignore_protection = True
        elif lhs_name == 'System`$ModuleNumber':
            if not rhs_int_value or rhs_int_value <= 0:
                evaluation.message('$ModuleNumber', 'set', rhs)
                return False
            ignore_protection = True
        elif lhs_name in ('System`$Line', 'System`$HistoryLength'):
            if rhs_int_value is None or rhs_int_value < 0:
                evaluation.message(lhs_name, 'intnn', rhs)
                return False
            ignore_protection = True
        elif lhs_name == 'System`$RandomState':
            # TODO: allow setting of legal random states!
            # (but consider pickle's insecurity!)
            evaluation.message('$RandomState', 'rndst', rhs)
            return False
        elif lhs_name == 'System`$Context':
            new_context = rhs.get_string_value()
            if new_context is None or not valid_context_name(
                    new_context, allow_initial_backquote=True):
                evaluation.message(lhs_name, 'cxset', rhs)
                return False

            # With $Context in Mathematica you can do some strange
            # things: e.g. with $Context set to Global`, something
            # like:
            #    $Context = "`test`"; newsym
            # is accepted and creates Global`test`newsym.
            # Implement this behaviour by interpreting
            #    $Context = "`test`"
            # as
            #    $Context = $Context <> "test`"
            #
            if new_context.startswith('`'):
                new_context = (evaluation.definitions.get_current_context() +
                               new_context.lstrip('`'))

            evaluation.definitions.set_current_context(new_context)
            ignore_protection = True
            return True
        elif lhs_name == 'System`$ContextPath':
            context_path = [s.get_string_value() for s in rhs.get_leaves()]
            if rhs.has_form('List', None) and all(
                    valid_context_name(s) for s in context_path):
                evaluation.definitions.set_context_path(context_path)
                ignore_protection = True
                return True
            else:
                evaluation.message(lhs_name, 'cxlist', rhs)
                return False

        rhs_name = rhs.get_head_name()
        if rhs_name == 'System`Condition':
            if len(rhs.leaves) != 2:
                evaluation.message_args('Condition', len(rhs.leaves), 2)
                return False
            else:
                lhs = Expression('Condition', lhs, rhs.leaves[1])
                rhs = rhs.leaves[0]

        rule = Rule(lhs, rhs)
        count = 0
        defs = evaluation.definitions
        for tag in tags:
            if (not ignore_protection and 'System`Protected'  # noqa
                    in evaluation.definitions.get_attributes(tag)):
                if lhs.get_name() == tag:
                    evaluation.message(self.get_name(), 'wrsym', Symbol(tag))
                else:
                    evaluation.message(self.get_name(), 'write', Symbol(tag),
                                       lhs)
                continue
            count += 1
            if form:
                defs.add_format(tag, rule, form)
            elif nprec:
                defs.add_nvalue(tag, rule)
            elif default:
                defs.add_default(tag, rule)
            elif message:
                defs.add_message(tag, rule)
            else:
                if upset:
                    defs.add_rule(tag, rule, position='up')
                else:
                    defs.add_rule(tag, rule)
        if count == 0:
            return False

        return True
Esempio n. 27
0
 def yield_func(vars, rest):
     raise StopGenerator_MatchQ(Symbol("True"))
Esempio n. 28
0
    def format_definition(self, symbol, evaluation, grid=True):
        'StandardForm,TraditionalForm,OutputForm: Definition[symbol_]'

        lines = []

        def print_rule(rule, up=False, lhs=lambda l: l, rhs=lambda r: r):
            evaluation.check_stopped()
            if isinstance(rule, Rule):
                r = rhs(
                    rule.replace.replace_vars({
                        'System`Definition':
                        Expression('HoldForm', Symbol('Definition'))
                    }))
                lines.append(
                    Expression(
                        'HoldForm',
                        Expression(up and 'UpSet' or 'Set',
                                   lhs(rule.pattern.expr), r)))

        name = symbol.get_name()
        if not name:
            evaluation.message('Definition', 'sym', symbol, 1)
            return
        attributes = evaluation.definitions.get_attributes(name)
        definition = evaluation.definitions.get_user_definition(name,
                                                                create=False)
        all = evaluation.definitions.get_definition(name)
        if attributes:
            attributes = list(attributes)
            attributes.sort()
            lines.append(
                Expression(
                    'HoldForm',
                    Expression(
                        'Set', Expression('Attributes', symbol),
                        Expression(
                            'List',
                            *(Symbol(attribute)
                              for attribute in attributes)))))

        if definition is not None and 'System`ReadProtected' not in attributes:
            for rule in definition.ownvalues:
                print_rule(rule)
            for rule in definition.downvalues:
                print_rule(rule)
            for rule in definition.subvalues:
                print_rule(rule)
            for rule in definition.upvalues:
                print_rule(rule, up=True)
            for rule in definition.nvalues:
                print_rule(rule)
            formats = sorted(definition.formatvalues.items())
            for format, rules in formats:
                for rule in rules:

                    def lhs(expr):
                        return Expression('Format', expr, Symbol(format))

                    def rhs(expr):
                        if expr.has_form('Infix', None):
                            expr = Expression(
                                Expression('HoldForm', expr.head),
                                *expr.leaves)
                        return Expression('InputForm', expr)

                    print_rule(rule, lhs=lhs, rhs=rhs)
        for rule in all.defaultvalues:
            print_rule(rule)
        if all.options:
            options = sorted(all.options.items())
            lines.append(
                Expression(
                    'HoldForm',
                    Expression(
                        'Set', Expression('Options', symbol),
                        Expression(
                            'List',
                            *(Expression('Rule', Symbol(name), value)
                              for name, value in options)))))
        if grid:
            if lines:
                return Expression(
                    'Grid',
                    Expression('List',
                               *(Expression('List', line) for line in lines)),
                    Expression('Rule', Symbol('ColumnAlignments'),
                               Symbol('Left')))
            else:
                return Symbol('Null')
        else:
            for line in lines:
                evaluation.print_out(Expression('InputForm', line))
            return Symbol('Null')
Esempio n. 29
0
    def apply_2(self, n, b, evaluation, nr_elements=None, pos=None):
        "RealDigits[n_?NumericQ, b_Integer]"

        expr = Expression("RealDigits", n)
        rational_no = (
            True if isinstance(n, Rational) else False
        )  # it is used for checking whether the input n is a rational or not
        py_b = b.get_int_value()
        if isinstance(n, (Expression, Symbol, Rational)):
            pos_len = abs(pos) + 1 if pos is not None and pos < 0 else 1
            if nr_elements is not None:
                n = Expression(
                    "N", n,
                    int(mpmath.log(py_b**(nr_elements + pos_len), 10)) +
                    1).evaluate(evaluation)
            else:
                if rational_no:
                    n = Expression("N", n).evaluate(evaluation)
                else:
                    return evaluation.message("RealDigits", "ndig", expr)
        py_n = abs(n.value)

        if not py_b > 1:
            return evaluation.message("RealDigits", "rbase", py_b)

        if isinstance(py_n, complex):
            return evaluation.message("RealDigits", "realx", expr)

        if isinstance(n, Integer):
            display_len = (int(mpmath.floor(mpmath.log(py_n, py_b)))
                           if py_n != 0 and py_n != 1 else 1)
        else:
            display_len = int(
                Expression(
                    "N",
                    Expression(
                        "Round",
                        Expression(
                            "Divide",
                            Expression("Precision", py_n),
                            Expression("Log", 10, py_b),
                        ),
                    ),
                ).evaluate(evaluation).to_python())

        exp = int(mpmath.ceil(mpmath.log(
            py_n, py_b))) if py_n != 0 and py_n != 1 else 1

        if py_n == 0 and nr_elements is not None:
            exp = 0

        digits = []
        if not py_b == 10:
            digits = convert_float_base(py_n, py_b, display_len - exp)
            # truncate all the leading 0's
            i = 0
            while digits and digits[i] == 0:
                i += 1
            digits = digits[i:]

            if not isinstance(n, Integer):
                if len(digits) > display_len:
                    digits = digits[:display_len - 1]
        else:
            # drop any leading zeroes
            for x in str(py_n):
                if x != "." and (digits or x != "0"):
                    digits.append(x)

        if pos is not None:
            temp = exp
            exp = pos + 1
            move = temp - 1 - pos
            if move <= 0:
                digits = [0] * abs(move) + digits
            else:
                digits = digits[abs(move):]
                display_len = display_len - move

        list_str = Expression("List")

        for x in digits:
            if x == "e" or x == "E":
                break
            # Convert to Mathics' list format
            list_str.leaves.append(from_python(int(x)))

        if not rational_no:
            while len(list_str.leaves) < display_len:
                list_str.leaves.append(from_python(0))

        if nr_elements is not None:
            # display_len == nr_elements
            if len(list_str.leaves) >= nr_elements:
                # Truncate, preserving the digits on the right
                list_str = list_str.leaves[:nr_elements]
            else:
                if isinstance(n, Integer):
                    while len(list_str.leaves) < nr_elements:
                        list_str.leaves.append(from_python(0))
                else:
                    # Adding Indeterminate if the length is greater than the precision
                    while len(list_str.leaves) < nr_elements:
                        list_str.leaves.append(
                            from_python(Symbol("Indeterminate")))

        return Expression("List", list_str, exp)
Esempio n. 30
0
def create_infix(items, operator, prec, grouping):
    if len(items) == 1:
        return items[0]
    else:
        return Expression('Infix', Expression('List', *items),
                          String(operator), prec, Symbol(grouping))