Example #1
0
 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
Example #2
0
    def apply(self, z, evaluation):
        '%(name)s[z__]'

        args = z.get_sequence()

        if len(args) != self.nargs:
            return

        # if no arguments are inexact attempt to use sympy
        if all(not x.is_inexact() for x in args):
            result = Expression(self.get_name(), *args).to_sympy()
            result = self.prepare_mathics(result)
            result = from_sympy(result)
            # evaluate leaves to convert e.g. Plus[2, I] -> Complex[2, 1]
            result = result.evaluate_leaves(evaluation)
        else:
            prec = min_prec(*args)
            with mpmath.workprec(prec):
                mpmath_args = [sympy2mpmath(x.to_sympy()) for x in args]
                if None in mpmath_args:
                    return
                try:
                    result = self.eval(*mpmath_args)
                    result = from_sympy(mpmath2sympy(result, prec))
                except ValueError, exc:
                    text = str(exc)
                    if text == 'gamma function pole':
                        return Symbol('ComplexInfinity')
                    else:
                        raise
                except ZeroDivisionError:
                    return
                except SpecialValueError, exc:
                    return Symbol(exc.name)
Example #3
0
    def importer(self, filename, evaluation):

        path = filename.to_python()
        if not (isinstance(path, basestring) and path[0] == path[-1] == '"'):
            evaluation.message('Import', 'chtype', filename)
            return Symbol('$Failed')
        path = path.strip('"')

        if path.startswith("ExampleData"):
            path = ROOT_DIR + 'data/' + path

        if not os.path.exists(path):
            evaluation.message('Import', 'nffil')
            return None

        filetype = Expression('FileFormat', path).evaluate(evaluation=evaluation)

        assert isinstance(filetype, String)
        filetype = filetype.to_python().strip('"')
        assert filetype in IMPORTFORMATS

        result = {}
        if filetype == 'Text':
            with open(path, 'r') as f:
                plaintext = f.read()
                textlines = filter(lambda x: x != '', plaintext.split('\n'))
                textwords = filter(lambda x: x != '', plaintext.split())
                result['Plaintext'] = plaintext
                result['Lines'] = textlines
                result['Words'] = textwords
                result['String'] = plaintext
                result['Data'] = textlines

        return result
Example #4
0
    def apply(self, expr, evaluation):
        'Variables[expr_]'

        variables = set()

        def find_vars(e):
            if e.to_sympy().is_constant():
                return
            elif e.is_symbol():
                variables.add(e)
            elif (e.has_form('Plus', None) or
                  e.has_form('Times', None)):
                for l in e.leaves:
                    find_vars(l)
            elif e.has_form('Power', 2):
                (a, b) = e.leaves  # a^b
                if not(a.to_sympy().is_constant()) and b.to_sympy().is_rational:
                    find_vars(a)
            elif not(e.is_atom()):
                variables.add(e)

        exprs = expr.leaves if expr.has_form('List', None) else [expr]
        for e in exprs:
            find_vars(from_sympy(e.to_sympy().expand()))

        variables = Expression('List', *variables)
        variables.sort()        # MMA doesn't do this
        return variables
Example #5
0
 def apply(self, items, evaluation):
     'Times[items___]'
     
     items = items.numerify(evaluation).get_sequence()
     number = mpz(1)
     leaves = []
     for item in items:
         if isinstance(item, Number):
             if get_type(item.value) == 'z' and item.value == 0:
                 return Integer('0')
             number = mul(number, item.value)
         elif leaves and item == leaves[-1]:
             leaves[-1] = Expression('Power', leaves[-1], Integer(2))
         elif leaves and item.has_form('Power', 2) and leaves[-1].has_form('Power', 2) and item.leaves[0].same(leaves[-1].leaves[0]):
             leaves[-1].leaves[1] = Expression('Plus', item.leaves[1], leaves[-1].leaves[1])
         elif leaves and item.has_form('Power', 2) and item.leaves[0].same(leaves[-1]):
             leaves[-1] = Expression('Power', leaves[-1], Expression('Plus', item.leaves[1], Integer(1)))
         elif leaves and leaves[-1].has_form('Power', 2) and leaves[-1].leaves[0].same(item):
             leaves[-1] = Expression('Power', item, Expression('Plus', Integer(1), leaves[-1].leaves[1]))
         else:
             leaves.append(item)
     if get_type(number) == 'z':
         if number == 1:
             number = None
         elif number == -1 and leaves and leaves[0].has_form('Plus', None):
             leaves[0].leaves = [Expression('Times', Integer(-1), leaf) for leaf in leaves[0].leaves]
             number = None
     if number is not None:
         leaves.insert(0, Number.from_mp(number))
     if not leaves:
         return Integer(1)
     elif len(leaves) == 1:
         return leaves[0]
     else:
         return Expression('Times', *leaves)
Example #6
0
 def apply(self, items, evaluation):
     '%(name)s[items__]'
     
     items_sequence = items.get_sequence()
     all_numeric = all(item.is_numeric() and item.get_precision() is None for item in items_sequence)
     if all_numeric and any(not isinstance(item, Number) for item in items_sequence):
         # All expressions are numeric but exact and they are not all numbers,
         # so apply N and compare them.
         items = items_sequence
         n_items = []
         for item in items:
             if not isinstance(item, Number):
                 # TODO: use $MaxExtraPrecision insterad of hard-coded 50
                 n_expr = Expression('N', item, Real(50)) 
                 item = n_expr.evaluate(evaluation)
             n_items.append(item)
         items = n_items
     else:
         items = items.numerify(evaluation).get_sequence()
     wanted = operators[self.get_name()]
     prev = None
     for item in items:
         if item.get_real_value() is None and not item.has_form('DirectedInfinity', None):
             return
         if prev is not None and do_cmp(prev, item) not in wanted:
             return Symbol('False')
         prev = item
     return Symbol('True')
Example #7
0
    def apply(self, f, args, h, evaluation):
        'Thread[f_[args___], h_]'

        args = args.get_sequence()
        expr = Expression(f, *args)
        threaded, result = expr.thread(evaluation, head=h)
        return result
Example #8
0
    def format_output(self, expr, format=None):
        if format is None:
            format = self.format

        if isinstance(format, dict):
            return dict((k, self.format_output(expr, f)) for k, f in format.items())

        from mathics.core.expression import Expression, BoxError

        if format == 'text':
            result = expr.format(self, 'System`OutputForm')
        elif format == 'xml':
            result = Expression(
                'StandardForm', expr).format(self, 'System`MathMLForm')
        elif format == 'tex':
            result = Expression('StandardForm', expr).format(
                self, 'System`TeXForm')
        else:
            raise ValueError

        try:
            boxes = result.boxes_to_text(evaluation=self)
        except BoxError:
            self.message('General', 'notboxes',
                         Expression('FullForm', result).evaluate(self))
            boxes = None
        return boxes
Example #9
0
        def yield_match(vars, rest):
            if rest is None:
                rest = ([], [])
            if 0 < len(rest[0]) + len(rest[1]) == len(expression.get_leaves()):
                # continue
                return
            options = {}
            for name, value in list(vars.items()):
                if name.startswith('_option_'):
                    options[name[len('_option_'):]] = value
                    del vars[name]
            new_expression = self.do_replace(expression, vars, options, evaluation)
            if new_expression is None:
                new_expression = expression
            if rest[0] or rest[1]:
                result = Expression(expression.get_head(), *(
                    rest[0] + [new_expression] + rest[1]))
            else:
                result = new_expression

            # Flatten out sequences (important for Rule itself!)
            result = result.flatten_pattern_sequence()
            if return_list:
                result_list.append(result)
                # count += 1
                if max_list is not None and len(result_list) >= max_list:
                    # return result_list
                    raise StopGenerator_BaseRule(result_list)
            else:
                raise StopGenerator_BaseRule(result)
Example #10
0
 def get_msg_list(expr):
     if expr.has_form('MessageName', 2):
         expr = Expression('List', expr)
     if expr.get_name() == 'All':
         all = True
         messages = []
     elif expr.get_name() == 'None':
         all = False
         messages = []
     elif expr.has_form('List', None):
         all = False
         messages = []
         for item in expr.leaves:
             if item.has_form('MessageName', 2):
                 symbol = item.leaves[0].get_name()
                 tag = item.leaves[1].get_string_value()
                 if symbol and tag:
                     messages.append((symbol, tag))
                 else:
                     raise ValueError
             else:
                 raise ValueError
     else:
         raise ValueError
     return all, messages
Example #11
0
    def apply(self, expr, evaluation):
        'Variables[expr_]'

        variables = find_all_vars(expr)
        
        variables = Expression('List', *variables)
        variables.sort()        # MMA doesn't do this
        return variables
Example #12
0
    def apply(self, items, evaluation):
        'Times[items___]'

        #TODO: Clean this up and optimise it        

        items = items.numerify(evaluation).get_sequence()
        number = (sympy.Integer(1), sympy.Integer(0))
        leaves = []

        prec = min_prec(*items)
        is_real = all([not isinstance(i, Complex) for i in items])

        for item in items:
            if isinstance(item, Number):
                if isinstance(item, Complex):
                    sym_real, sym_imag = item.real.to_sympy(), item.imag.to_sympy()
                else:
                    sym_real, sym_imag = item.to_sympy(), sympy.Integer(0)

                if prec is not None:
                    sym_real = sym_real.n(dps(prec))
                    sym_imag = sym_imag.n(dps(prec))

                if sym_real.is_zero and sym_imag.is_zero and prec is None:
                    return Integer('0')
                number = (number[0]*sym_real - number[1]*sym_imag, number[0]*sym_imag + number[1]*sym_real)
            elif leaves and item == leaves[-1]:
                leaves[-1] = Expression('Power', leaves[-1], Integer(2))
            elif leaves and item.has_form('Power', 2) and leaves[-1].has_form('Power', 2) and item.leaves[0].same(leaves[-1].leaves[0]):
                leaves[-1].leaves[1] = Expression('Plus', item.leaves[1], leaves[-1].leaves[1])
            elif leaves and item.has_form('Power', 2) and item.leaves[0].same(leaves[-1]):
                leaves[-1] = Expression('Power', leaves[-1], Expression('Plus', item.leaves[1], Integer(1)))
            elif leaves and leaves[-1].has_form('Power', 2) and leaves[-1].leaves[0].same(item):
                leaves[-1] = Expression('Power', item, Expression('Plus', Integer(1), leaves[-1].leaves[1]))
            else:
                leaves.append(item)
        if number == (1, 0):
            number = None
        elif number == (-1, 0) and leaves and leaves[0].has_form('Plus', None):
            leaves[0].leaves = [Expression('Times', Integer(-1), leaf) for leaf in leaves[0].leaves]
            number = None

        if number is not None:
            if number[1].is_zero and is_real:
                leaves.insert(0, Number.from_mp(number[0], prec))
            elif number[1].is_zero and number[1].is_Integer and prec is None:
                leaves.insert(0, Number.from_mp(number[0], prec))
            else:
                leaves.insert(0, Complex(from_sympy(number[0]), from_sympy(number[1]), prec))

        if not leaves:
            return Integer(1)
        elif len(leaves) == 1:
            return leaves[0]
        else:
            return Expression('Times', *leaves)
Example #13
0
 def compare(e1, e2):
     result = Expression(p, e1, e2).evaluate(evaluation)
     if result.is_true():
         result = Expression(p, e2, e1).evaluate(evaluation)
         if result.is_true():
             return 0
         else:
             return -1
     else:
         return 1
Example #14
0
    def apply_elements(self, filename, expr, elems, evaluation, options={}):
        "Export[filename_, expr_, elems_List?(AllTrue[#, NotOptionQ]&), OptionsPattern[]]"

        # Check filename
        if not self._check_filename(filename, evaluation):
            return Symbol('$Failed')

        # Process elems {comp* format?, elem1*}
        leaves = elems.get_leaves()

        format_spec, elems_spec = [], []
        found_form = False
        for leaf in leaves[::-1]:
            leaf_str = leaf.get_string_value()

            if not found_form and leaf_str in EXPORTERS:
                found_form = True

            if found_form:
                format_spec.append(leaf_str)
            else:
                elems_spec.append(leaf)

        # Infer format if not present
        if not found_form:
            assert format_spec == []
            format_spec = self._infer_form(filename, evaluation)
            if format_spec is None:
                evaluation.message('Export', 'infer', filename)
                return Symbol('$Failed')
            format_spec = [format_spec]
        else:
            assert format_spec != []

        # First item in format_spec is the explicit format.
        # The other elements (if present) are compression formats

        if elems_spec != []:        # FIXME: support elems
            evaluation.message(
                'Export', 'noelem', elems, String(format_spec[0]))
            return Symbol('$Failed')

        # Load the exporter
        exporter_symbol, exporter_options = EXPORTERS[format_spec[0]]

        stream_options, custom_options = _importer_exporter_options(
            exporter_options.get("System`Options"), options, evaluation)

        exporter_function = Expression(
            exporter_symbol, filename, expr, *list(chain(stream_options, custom_options)))

        if exporter_function.evaluate(evaluation) == Symbol('Null'):
            return filename
        return Symbol('$Failed')
Example #15
0
 def post_parse(self, expression):
     leaves = [leaf.post_parse() for leaf in expression.leaves]
     expression = Expression(expression.head.post_parse(), *leaves)
     if expression.has_form('Optional', 2) and expression.leaves[0].get_name():
         sub = expression.leaves[1]
         if sub.has_form(('Pattern', 'Optional'), 2):
             return Expression('Optional', Expression('Pattern', expression.leaves[0], sub.leaves[0]), sub.leaves[1])
         else:
             return Expression('Pattern', *[leaf.post_parse() for leaf in expression.leaves])
     else:
         return expression
Example #16
0
 def apply(self, list, expr, evaluation):
     'Select[list_, expr_]'
     
     if list.is_atom():
         evaluation.message('Select', 'normal')
         return
     new_leaves = []
     for leaf in list.leaves:
         test = Expression(expr, leaf)
         if test.evaluate(evaluation) == Symbol('True'):
             new_leaves.append(leaf)
     return Expression(list.head, *new_leaves)
Example #17
0
def _norm_calc(head, u, v, evaluation):
    expr = Expression(head, u, v)
    old_quiet_all = evaluation.quiet_all
    try:
        evaluation.quiet_all = True
        expr_eval = expr.evaluate(evaluation)
    finally:
        evaluation.quiet_all = old_quiet_all
    if expr_eval.same(expr):
        evaluation.message('Norm', 'nvm')
        return None
    else:
        return expr_eval
Example #18
0
 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
Example #19
0
    def apply(self, filename, expr, elems, evaluation):
        "Export[filename_, expr_, elems_List]"

        # Check filename
        if not self._check_filename(filename, evaluation):
            return Symbol('$Failed')

        ## Process elems {comp* format?, elem1*}
        leaves = elems.get_leaves()

        format_spec, elems_spec = [], []
        found_form = False
        for leaf in leaves[::-1]:
            leaf_str = leaf.get_string_value()

            if not found_form and leaf_str in EXPORTERS:
                found_form = True

            if found_form:
                format_spec.append(leaf_str)
            else:
                elems_spec.append(leaf)

        # Infer format if not present
        if not found_form:
            assert format_spec == []
            format_spec = self._infer_form(filename, evaluation)
            if format_spec is None:
                evaluation.message('Export', 'infer', filename)
                return Symbol('$Failed')
            format_spec = [format_spec]
        else:
            assert format_spec != []

        # First item in format_spec is the explicit format.
        # The other elements (if present) are compression formats

        if elems_spec != []:        # FIXME: support elems
            evaluation.message(
                'Export', 'noelem', elems, String(format_spec[0]))
            return Symbol('$Failed')

        # Load the exporter
        exporter_symbol = EXPORTERS[format_spec[0]]

        exporter_function = Expression(exporter_symbol, filename, expr)

        if exporter_function.evaluate(evaluation) == Symbol('Null'):
            return filename
        return Symbol('$Failed')
Example #20
0
 def add(self, expression, evaluation):
     expr = Expression('System`Private`ManipulateParameter', expression).evaluate(evaluation)
     if expr.get_head_name() != 'System`List':  # if everything was parsed ok, we get a List
         return False
     # convert the rules given us by ManipulateParameter[] into a dict. note: duplicate keys
     # will be overwritten, the latest one wins.
     kwargs = {'evaluation': evaluation}
     for rule in expr.leaves:
         if rule.get_head_name() != 'System`Rule' or len(rule.leaves) != 2:
             return False
         kwargs[strip_context(rule.leaves[0].to_python()).lower()] = rule.leaves[1]
     widget = kwargs['type'].get_string_value()
     del kwargs['type']
     getattr(self, '_add_%s_widget' % widget.lower())(**kwargs)  # create the widget
     return True
Example #21
0
 def yield_match(vars_2, rest):                
     items = expression.get_sequence()
     for item in items:                              
         quick_test = self.quick_pattern_test(item, self.test_name)
         if quick_test is not None:
             if not quick_test:
                 break
                 #raise StopGenerator
         else:                        
             test_expr = Expression(self.test, item)
             test_value = test_expr.evaluate(evaluation)
             if not test_value.is_true():
                 break
                 #raise StopGenerator
     else:
         yield_func(vars_2, None)
Example #22
0
 def get_wrappings(self, yield_func, items, max_count, expression, attributes, include_flattened=True):
     if len(items) == 1:
         yield_func(items[0])
     else:
         if max_count is None or len(items) <= max_count:
             if 'Orderless' in attributes:
                 for perm in permutations(items):
                     sequence = Expression('Sequence', *perm)
                     sequence.pattern_sequence = True
                     yield_func(sequence)
             else:
                 sequence = Expression('Sequence', *items)
                 sequence.pattern_sequence = True
                 yield_func(sequence)
         if 'Flat' in attributes and include_flattened:
             yield_func(Expression(expression.get_head(), *items))
Example #23
0
 def format_output(self, expr):
     from mathics.core.expression import Expression, String, BoxError
     
     if self.format == 'text':
         result = expr.format(self, 'OutputForm')
     elif self.format == 'xml':
         result = Expression('StandardForm', expr).format(self, 'MathMLForm')
     elif self.format == 'tex':
         result = Expression('StandardForm', expr).format(self, 'TeXForm')
     else:
         raise ValueError
     try:
         boxes = result.boxes_to_text(evaluation=self)
     except BoxError:
         self.message('General', 'notboxes', String('%s' % result))
         boxes = None
     return boxes
Example #24
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.is_true():
                next = Expression(f, results[-1])
                results.append(next.evaluate(evaluation))
            else:
                break
        return results[-1]
Example #25
0
    def apply_iter(self, expr, i, imin, imax, di, evaluation):
        '%(name)s[expr_, {i_Symbol, imin_, imax_, di_}]'
        
        if isinstance(self, SympyFunction) and di.get_int_value() == 1:
            whole_expr = Expression(self.get_name(), expr, Expression('List', i, imin, imax))
            sympy_expr = whole_expr.to_sympy()
            
            # apply Together to produce results similar to Mathematica
            result = sympy.together(sympy_expr)
            result = from_sympy(result)
            result = cancel(result)
            
            if not result.same(whole_expr):
                return result
        
        index = imin.evaluate(evaluation)
        imax = imax.evaluate(evaluation)
        di = di.evaluate(evaluation)

        result = []
        while True:
            cont = Expression('LessEqual', index, imax).evaluate(evaluation)
            if cont == Symbol('False'):
                break
            if cont != Symbol('True'):
                if self.throw_iterb:
                    evaluation.message(self.get_name(), 'iterb')
                return

            evaluation.check_stopped()
            try:
                item = dynamic_scoping(expr.evaluate, {i.name: index}, evaluation)
                result.append(item)
            except ContinueInterrupt:
                if self.allow_loopcontrol:
                    pass
                else:
                    raise
            except BreakInterrupt:
                if self.allow_loopcontrol:
                    break
                else:
                    raise
            index = Expression('Plus', index, di).evaluate(evaluation)
        return self.get_result(result)
Example #26
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 #27
0
    def apply(self, filename, evaluation):
        'FileFormat[filename_String]'

        findfile = Expression('FindFile', filename).evaluate(evaluation)
        if findfile == Symbol('$Failed'):
            evaluation.message(
                'FileFormat', 'nffil', Expression('FileFormat', filename))
            return findfile

        path = findfile.get_string_value()

        if not FileFormat.detector:
            loader = magic.MagicLoader()
            loader.load()
            FileFormat.detector = magic.MagicDetector(loader.mimetypes)

        mime = set(FileFormat.detector.match(path))

        # If match fails match on extension only
        if mime == set([]):
            mime, encoding = mimetypes.guess_type(path)
            if mime is None:
                mime = set([])
            else:
                mime = set([mime])

        result = []
        for key in mimetype_dict.keys():
            if key in mime:
                result.append(mimetype_dict[key])

        # the following fixes an extremely annoying behaviour on some (not all)
        # installations of Windows, where we end up classifying .csv files als XLS.
        if len(result) == 1 and result[0] == 'XLS' and path.lower().endswith('.csv'):
            return String('CSV')

        if len(result) == 0:
            result = 'Binary'
        elif len(result) == 1:
            result = result[0]
        else:
            return None

        return from_python(result)
Example #28
0
        def get_results(tmp_function):
            if function_channels == Expression('List', String('FileNames')):
                tmp = Expression(tmp_function, findfile).evaluate(evaluation)
            elif function_channels == Expression('List', String('Streams')):
                stream = Expression('OpenRead', findfile).evaluate(evaluation)
                if stream.get_head_name() != 'InputStream':
                    evaluation.message('Import', 'nffil')
                    return None
                tmp = Expression(tmp_function, stream).evaluate(evaluation)
                Expression('Close', stream).evaluate(evaluation)
            else:
                #TODO print appropriate error message
                raise NotImplementedError
            tmp = tmp.get_leaves()
            if not all(expr.has_form('Rule', None) for expr in tmp):
                return None

            # return {a.get_string_value() : b for (a,b) in map(lambda x: x.get_leaves(), tmp)}
            return dict((a.get_string_value(), b) for (a,b) in map(lambda x: x.get_leaves(), tmp))
Example #29
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 #30
0
 def apply_iter(self, expr, i, imin, imax, di, evaluation):
     '%(name)s[expr_, {i_Symbol, imin_, imax_, di_}]'
     
     if di.get_int_value() == 1 and isinstance(self, SageFunction):
         whole_expr = Expression(self.get_name(), expr, Expression('List', i, imin, imax))
         sympy_expr = whole_expr.to_sympy()
         
         # apply Together to produce results similar to Mathematica
         result = sympy.together(sympy_expr)
         result = from_sympy(result)
         result = cancel(result)
         
         if not result.same(whole_expr):
             return result
     
     index = imin.evaluate(evaluation).get_real_value()
     imax = imax.evaluate(evaluation).get_real_value()
     di = di.evaluate(evaluation).get_real_value()
     
     if index is None or imax is None or di is None:
         if self.throw_iterb:
             evaluation.message(self.get_name(), 'iterb')
         return
     
     result = []
     while index <= imax:
         evaluation.check_stopped()
         try:
             item = dynamic_scoping(expr.evaluate, {i.name: Number.from_mp(index)}, evaluation)
             result.append(item)
         except ContinueInterrupt:
             if self.allow_loopcontrol:
                 pass
             else:
                 raise
         except BreakInterrupt:
             if self.allow_loopcontrol:
                 break
             else:
                 raise
         index = add(index, di)
     return self.get_result(result)
Example #31
0
 def determine_filetype():
     return Expression(
         'FileFormat',
         findfile).evaluate(evaluation=evaluation).get_string_value()
Example #32
0
 def to_sympy(self, expr):
     if len(expr.leaves) == 1:
         return Expression('ArcSinh', Expression('Power', expr.leaves[0], Integer(-1))).to_sympy()
Example #33
0
 def p_slotseq(self, args):
     ' expr ::= slotseq '
     return Expression('SlotSequence', Integer(args[0].value))
Example #34
0
 def apply_element(self, expr, element, evaluation, options={}):
     'ExportString[expr_, element_String, OptionsPattern[]]'
     return self.apply_elements(expr, Expression('List', element),
                                evaluation, options)
Example #35
0
 def op_670_part(self, args):
     ' expr ::= expr position'
     return Expression('Part', args[0], *args[1].items)
Example #36
0
 def p_list(self, args):
     ' expr ::= { sequence } '
     return Expression('List', *args[1].items)
Example #37
0
 def op_305_2(self, args):
     ' expr ::= span_start ;; span_stop '
     return Expression('Span', args[0], args[2], Integer(1))
Example #38
0
 def _infer_form(self, filename, evaluation):
     ext = Expression('FileExtension', filename).evaluate(evaluation)
     ext = ext.get_string_value().lower()
     return self._extdict.get(ext)
Example #39
0
        def get_results(tmp_function, findfile):
            if function_channels == Expression('List', String('FileNames')):
                joined_options = list(chain(stream_options, custom_options))
                tmpfile = False
                if findfile is None:
                    tmpfile = True
                    stream = Expression('OpenWrite').evaluate(evaluation)
                    findfile = stream.leaves[0]
                    if not data is None:
                        Expression('WriteString', data).evaluate(evaluation)
                    else:
                        Expression('WriteString',
                                   String("")).evaluate(evaluation)
                    Expression('Close', stream).evaluate(evaluation)
                    stream = None
                tmp = Expression(tmp_function, findfile,
                                 *joined_options).evaluate(evaluation)
                if tmpfile:
                    Expression("DeleteFile", findfile).evaluate(evaluation)
            elif function_channels == Expression('List', String('Streams')):
                if findfile is None:
                    stream = Expression('StringToStream',
                                        data).evaluate(evaluation)
                else:
                    stream = Expression('OpenRead', findfile,
                                        *stream_options).evaluate(evaluation)
                if stream.get_head_name() != 'System`InputStream':
                    evaluation.message('Import', 'nffil')
                    evaluation.predetermined_out = current_predetermined_out
                    return None
                tmp = Expression(tmp_function, stream,
                                 *custom_options).evaluate(evaluation)
                Expression('Close', stream).evaluate(evaluation)
            else:
                # TODO message
                evaluation.predetermined_out = current_predetermined_out
                return Symbol('$Failed')
            tmp = tmp.get_leaves()
            if not all(expr.has_form('Rule', None) for expr in tmp):
                evaluation.predetermined_out = current_predetermined_out
                return None

            # return {a.get_string_value() : b for (a,b) in map(lambda x:
            # x.get_leaves(), tmp)}
            evaluation.predetermined_out = current_predetermined_out
            return dict((a.get_string_value(), b)
                        for (a, b) in [x.get_leaves() for x in tmp])
Example #40
0
class OptionsPattern(PatternObject):
    """
    <dl>
    <dt>'OptionsPattern[$f$]'
        <dd>is a pattern that stands for a sequence of options given
        to a function, with default values taken from 'Options[$f$]'.
        The options can be of the form '$opt$->$value$' or
        '$opt$:>$value$', and might be in arbitrarily nested lists.
    <dt>'OptionsPattern[{$opt1$->$value1$, ...}]'
        <dd>takes explicit default values from the given list. The
        list may also contain symbols $f$, for which 'Options[$f$]' is
        taken into account; it may be arbitrarily nested.
        'OptionsPattern[{}]' does not use any default values.
    </dl>

    The option values can be accessed using 'OptionValue'.

    >> f[x_, OptionsPattern[{n->2}]] := x ^ OptionValue[n]
    >> f[x]
     = x ^ 2
    >> f[x, n->3]
     = x ^ 3

    Delayed rules as options:
    >> e = f[x, n:>a]
     = x ^ a
    >> a = 5;
    >> e
     = x ^ 5

    Options might be given in nested lists:
    >> f[x, {{{n->4}}}]
     = x ^ 4

    #> {opt -> b} /. OptionsPattern[{}] -> t
     = t

    #> Clear[f]
    #> Options[f] = {Power -> 2};
    #> f[x_, OptionsPattern[f]] := x ^ OptionValue[Power]
    #> f[10]
     = 100
    #> f[10, Power -> 3]
     = 1000
    #> Clear[f]

    #> Options[f] = {Power -> 2};
    #> f[x_, OptionsPattern[]] := x ^ OptionValue[Power]
    #> f[10]
     = 100
    #> f[10, Power -> 3]
     = 1000
    #> Clear[f]
    """

    arg_counts = [0, 1]

    def init(self, expr):
        super(OptionsPattern, self).init(expr)
        try:
            self.defaults = expr.leaves[0]
        except IndexError:
            # OptionsPattern[] takes default options of the nearest enclosing
            # function. Set to not None in self.match
            self.defaults = None

    def match(self, yield_func, expression, vars, evaluation, **kwargs):
        if self.defaults is None:
            self.defaults = kwargs.get("head")
            if self.defaults is None:
                # we end up here with OptionsPattern that do not have any
                # default options defined, e.g. with this code:
                # f[x:OptionsPattern[]] := x; f["Test" -> 1]
                # set self.defaults to an empty List, so we don't crash.
                self.defaults = Expression(SymbolList)
        values = self.defaults.get_option_values(evaluation,
                                                 allow_symbols=True,
                                                 stop_on_error=False)
        sequence = expression.get_sequence()
        for options in sequence:
            option_values = options.get_option_values(evaluation)
            if option_values is None:
                return
            values.update(option_values)
        new_vars = vars.copy()
        for name, value in values.items():
            new_vars["_option_" + name] = value
        yield_func(new_vars, None)

    def get_match_count(self, vars={}):
        return (0, None)

    def get_match_candidates(self,
                             leaves,
                             expression,
                             attributes,
                             evaluation,
                             vars={}):
        def _match(leaf):
            return leaf.has_form(
                ("Rule", "RuleDelayed"), 2) or leaf.has_form("List", None)

        return [leaf for leaf in leaves if _match(leaf)]
Example #41
0
    def apply_element(self, data, element, evaluation, options={}):
        'ImportString[data_, element_String, OptionsPattern[]]'

        return self.apply_elements(data, Expression('List', element),
                                   evaluation, options)
Example #42
0
 def rhs(expr):
     if expr.has_form('Infix', None):
         expr = Expression(Expression(
             'HoldForm', expr.head), *expr.leaves)
     return Expression('InputForm', expr)
Example #43
0
 def get_result(self, items):
     return Expression('Times', *items)
Example #44
0
 def from_sympy(self, sympy_name, args):
     # Hack to get around weird sympy.Piecewise 'otherwise' behaviour
     if str(args[-1].leaves[1]).startswith('System`_True__Dummy_'):
         args[-1].leaves[1] = Symbol('True')
     return Expression(self.get_name(), args)
Example #45
0
 def apply_element(self, filename, element, evaluation, options={}):
     'Import[filename_, element_String, OptionsPattern[]]'
     return self.apply_elements(filename, Expression('List', element),
                                evaluation, options)
Example #46
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')
Example #47
0
 def p_slot(self, args):
     ' expr ::= slot '
     return Expression('Slot', Integer(args[0].value))
Example #48
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 > MAX_RECURSION_DEPTH):  # nopep8

                evaluation.message('$RecursionLimit', 'limset', rhs)
                return False
            try:
                set_python_recursion_limit(rhs_int_value)
            except OverflowError:
                # TODO: Message
                return False
            ignore_protection = True
        if lhs_name == 'System`$IterationLimit':
            if (not rhs_int_value or rhs_int_value < 20) and not rhs.get_name() == 'System`Infinity':
                evaluation.message('$IterationLimit', 'limset', rhs)
                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
        elif lhs_name == 'System`$MinPrecision':
            # $MinPrecision = Infinity is not allowed
            if rhs_int_value is not None and rhs_int_value >= 0:
                ignore_protection = True
                max_prec = evaluation.definitions.get_config_value('$MaxPrecision')
                if max_prec is not None and max_prec < rhs_int_value:
                    evaluation.message('$MinPrecision', 'preccon', Symbol('$MinPrecision'))
                    return True
            else:
                evaluation.message(lhs_name, 'precset', lhs, rhs)
                return False
        elif lhs_name == 'System`$MaxPrecision':
            if rhs.has_form('DirectedInfinity', 1) and rhs.leaves[0].get_int_value() == 1:
                ignore_protection = True
            elif rhs_int_value is not None and rhs_int_value > 0:
                ignore_protection = True
                min_prec = evaluation.definitions.get_config_value('$MinPrecision')
                if min_prec is not None and rhs_int_value < min_prec:
                    evaluation.message('$MaxPrecision', 'preccon', Symbol('$MaxPrecision'))
                    ignore_protection = True
                    return True
            else:
                evaluation.message(lhs_name, 'precset', lhs, 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
Example #49
0
 def evaluate(self, evaluation):
     return Expression('List', *sorted(EXPORTERS.keys()))
Example #50
0
    def assign_elementary(self, lhs, rhs, evaluation, tags=None, upset=False):
        name = lhs.get_head_name()

        if name in ('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', name, tag)
                return False

            if name != 'Attributes' and 'Protected' in evaluation.definitions.get_attributes(
                    tag):
                evaluation.message(name, 'wrsym', tag)
                return False
            if name == '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 == 'Attributes':
                attributes = get_symbol_list(
                    rhs, lambda item: evaluation.message(name, 'sym', item, 1))
                if attributes is None:
                    return False
                if 'Locked' in evaluation.definitions.get_attributes(tag):
                    evaluation.message(name, 'locked', 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 == '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 == 'MessageName':
            if len(lhs.leaves) != 2:
                evaluation.message_args('MessageName', len(lhs.leaves), 2)
                return False
            focus = lhs.leaves[0]
            message = True
        elif name == '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 == '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 = (
                    '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', name)
                    return False

        ignore_protection = False
        rhs_int_value = rhs.get_int_value()
        lhs_name = lhs.get_name()
        if lhs_name == '$RecursionLimit':
            #if (not rhs_int_value or rhs_int_value < 20) and not rhs.get_name() == 'Infinity':
            if not rhs_int_value or rhs_int_value < 20 or rhs_int_value > settings.MAX_RECURSION_DEPTH:
                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 == '$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 ('$Line', '$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 == '$RandomState':
            # TODO: allow setting of legal random states!
            # (but consider pickle's insecurity!)
            evaluation.message('$RandomState', 'rndst', rhs)
            return False

        rhs_name = rhs.get_head_name()
        if rhs_name == '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 'Protected' in evaluation.definitions.get_attributes(
                    tag):
                if lhs.get_name() == tag:
                    evaluation.message(self.get_name(), 'wrsym', tag)
                else:
                    evaluation.message(self.get_name(), 'write', 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
Example #51
0
    def apply_elements(self, expr, elems, evaluation, options={}):
        "ExportString[expr_, elems_List?(AllTrue[#, NotOptionQ]&), OptionsPattern[]]"
        # Process elems {comp* format?, elem1*}
        leaves = elems.get_leaves()

        format_spec, elems_spec = [], []
        found_form = False
        for leaf in leaves[::-1]:
            leaf_str = leaf.get_string_value()

            if not found_form and leaf_str in EXPORTERS:
                found_form = True

            if found_form:
                format_spec.append(leaf_str)
            else:
                elems_spec.append(leaf)

        # Just to be sure that the following evaluations do not change the value of this property
        current_predetermined_out = evaluation.predetermined_out

        # Infer format if not present
        if format_spec is None:
            evaluation.message('ExportString', 'infer', filename)
            evaluation.predetermined_out = current_predetermined_out
            return Symbol('$Failed')

        # First item in format_spec is the explicit format.
        # The other elements (if present) are compression formats

        if elems_spec != []:  # FIXME: support elems
            if format_spec != []:
                evaluation.message('ExportString', 'noelem', elems,
                                   String(format_spec[0]))
            else:
                evaluation.message('ExportString', 'noelem', elems,
                                   String("Unknown"))
            evaluation.predetermined_out = current_predetermined_out
            return Symbol('$Failed')

        # Load the exporter
        exporter_symbol, exporter_options = EXPORTERS[format_spec[0]]
        function_channels = exporter_options.get("System`FunctionChannels")

        stream_options, custom_options = _importer_exporter_options(
            exporter_options.get("System`Options"), options, "System Options",
            evaluation)

        if function_channels is None:
            evaluation.message('ExportString', 'emptyfch')
            evaluation.predetermined_out = current_predetermined_out
            return Symbol('$Failed')
        elif function_channels == Expression('List', String('FileNames')):
            # Generates a temporary file
            import tempfile
            tmpfile = tempfile.NamedTemporaryFile(dir=tempfile.gettempdir())
            filename = String(tmpfile.name)
            tmpfile.close()
            exporter_function = Expression(
                exporter_symbol, filename, expr,
                *list(chain(stream_options, custom_options)))
            if exporter_function.evaluate(evaluation) != Symbol('Null'):
                evaluation.predetermined_out = current_predetermined_out
                return Symbol('$Failed')
            else:
                try:
                    tmpstream = open(filename.value, 'rb')
                    res = tmpstream.read().decode('utf-8')
                    tmpstream.close()
                except Exception as e:
                    print("something went wrong")
                    print(e)
                    evaluation.predetermined_out = current_predetermined_out
                    return Symbol('$Failed')
                res = String(str(res))
        elif function_channels == Expression('List', String('Streams')):
            from io import StringIO
            from mathics.builtin.files import STREAMS, NSTREAMS
            pystream = StringIO()
            n = next(NSTREAMS)
            STREAMS.append(pystream)
            stream = Expression('OutputStream', String('String'), Integer(n))
            exporter_function = Expression(
                exporter_symbol, stream, expr,
                *list(chain(stream_options, custom_options)))
            res = exporter_function.evaluate(evaluation)
            if res == Symbol('Null'):
                res = String(str(pystream.getvalue()))
            else:
                res = Symbol("$Failed")
            Expression('Close', stream).evaluate(evaluation)
        else:
            evaluation.message('ExportString', 'emptyfch')
            evaluation.predetermined_out = current_predetermined_out
            return Symbol('$Failed')

        evaluation.predetermined_out = current_predetermined_out
        return res
Example #52
0
    def _import(findfile,
                determine_filetype,
                elements,
                evaluation,
                options,
                data=None):
        current_predetermined_out = evaluation.predetermined_out
        # Check elements
        if elements.has_form('List', None):
            elements = elements.get_leaves()
        else:
            elements = [elements]

        for el in elements:
            if not isinstance(el, String):

                evaluation.message('Import', 'noelem', el)
                evaluation.predetermined_out = current_predetermined_out
                return Symbol('$Failed')

        elements = [el.get_string_value() for el in elements]

        # Determine file type
        for el in elements:
            if el in IMPORTERS.keys():
                filetype = el
                elements.remove(el)
                break
        else:
            filetype = determine_filetype()

        if filetype not in IMPORTERS.keys():
            evaluation.message('Import', 'fmtnosup', filetype)
            evaluation.predetermined_out = current_predetermined_out
            return Symbol('$Failed')

        # Load the importer
        (conditionals, default_function, posts,
         importer_options) = IMPORTERS[filetype]

        stream_options, custom_options = _importer_exporter_options(
            importer_options.get("System`Options"), options, "System`Import",
            evaluation)

        function_channels = importer_options.get("System`FunctionChannels")

        if function_channels is None:
            # TODO message
            if data is None:
                evaluation.message('Import', 'emptyfch')
            else:
                evaluation.message('ImportString', 'emptyfch')
            evaluation.predetermined_out = current_predetermined_out
            return Symbol('$Failed')

        default_element = importer_options.get("System`DefaultElement")
        if default_element is None:
            # TODO message
            evaluation.predetermined_out = current_predetermined_out
            return Symbol('$Failed')

        def get_results(tmp_function, findfile):
            if function_channels == Expression('List', String('FileNames')):
                joined_options = list(chain(stream_options, custom_options))
                tmpfile = False
                if findfile is None:
                    tmpfile = True
                    stream = Expression('OpenWrite').evaluate(evaluation)
                    findfile = stream.leaves[0]
                    if not data is None:
                        Expression('WriteString', data).evaluate(evaluation)
                    else:
                        Expression('WriteString',
                                   String("")).evaluate(evaluation)
                    Expression('Close', stream).evaluate(evaluation)
                    stream = None
                tmp = Expression(tmp_function, findfile,
                                 *joined_options).evaluate(evaluation)
                if tmpfile:
                    Expression("DeleteFile", findfile).evaluate(evaluation)
            elif function_channels == Expression('List', String('Streams')):
                if findfile is None:
                    stream = Expression('StringToStream',
                                        data).evaluate(evaluation)
                else:
                    stream = Expression('OpenRead', findfile,
                                        *stream_options).evaluate(evaluation)
                if stream.get_head_name() != 'System`InputStream':
                    evaluation.message('Import', 'nffil')
                    evaluation.predetermined_out = current_predetermined_out
                    return None
                tmp = Expression(tmp_function, stream,
                                 *custom_options).evaluate(evaluation)
                Expression('Close', stream).evaluate(evaluation)
            else:
                # TODO message
                evaluation.predetermined_out = current_predetermined_out
                return Symbol('$Failed')
            tmp = tmp.get_leaves()
            if not all(expr.has_form('Rule', None) for expr in tmp):
                evaluation.predetermined_out = current_predetermined_out
                return None

            # return {a.get_string_value() : b for (a,b) in map(lambda x:
            # x.get_leaves(), tmp)}
            evaluation.predetermined_out = current_predetermined_out
            return dict((a.get_string_value(), b)
                        for (a, b) in [x.get_leaves() for x in tmp])

        # Perform the import
        defaults = None

        if not elements:
            defaults = get_results(default_function, findfile)
            if defaults is None:
                evaluation.predetermined_out = current_predetermined_out
                return Symbol('$Failed')
            if default_element == Symbol("Automatic"):
                evaluation.predetermined_out = current_predetermined_out
                return Expression(
                    'List',
                    *(Expression('Rule', String(key), defaults[key])
                      for key in defaults.keys()))
            else:
                result = defaults.get(default_element.get_string_value())
                if result is None:
                    evaluation.message('Import', 'noelem', default_element,
                                       from_python(filetype))
                    evaluation.predetermined_out = current_predetermined_out
                    return Symbol('$Failed')
                evaluation.predetermined_out = current_predetermined_out
                return result
        else:
            assert len(elements) == 1
            el = elements[0]
            if el == "Elements":
                defaults = get_results(default_function, findfile)
                if defaults is None:
                    evaluation.predetermined_out = current_predetermined_out
                    return Symbol('$Failed')
                # Use set() to remove duplicates
                evaluation.predetermined_out = current_predetermined_out
                return from_python(
                    sorted(
                        set(
                            list(conditionals.keys()) + list(defaults.keys()) +
                            list(posts.keys()))))
            else:
                if el in conditionals.keys():
                    result = get_results(conditionals[el], findfile)
                    if result is None:
                        evaluation.predetermined_out = current_predetermined_out
                        return Symbol('$Failed')
                    if len(list(result.keys())) == 1 and list(
                            result.keys())[0] == el:
                        evaluation.predetermined_out = current_predetermined_out
                        return list(result.values())[0]
                elif el in posts.keys():
                    # TODO: allow use of conditionals
                    result = get_results(posts[el])
                    if result is None:
                        evaluation.predetermined_out = current_predetermined_out
                        return Symbol('$Failed')
                else:
                    if defaults is None:
                        defaults = get_results(default_function, findfile)
                        if defaults is None:
                            evaluation.predetermined_out = current_predetermined_out
                            return Symbol('$Failed')
                    if el in defaults.keys():
                        evaluation.predetermined_out = current_predetermined_out
                        return defaults[el]
                    else:
                        evaluation.message('Import', 'noelem', from_python(el),
                                           from_python(filetype))
                        evaluation.predetermined_out = current_predetermined_otu
                        return Symbol('$Failed')
Example #53
0
 def op_305_1(self, args):
     ' expr ::= span_start ;; span_stop ;; span_step '
     return Expression('Span', args[0], args[2], args[4])
Example #54
0
 def p_out(self, args):
     ' expr ::= out '
     return Expression('Out', Integer(args[0].value))
Example #55
0
 def lhs(expr):
     return Expression('Format', expr, Symbol(format))
Example #56
0
 def op_670_call(self, args):
     ' expr ::= expr args'
     expr = Expression(args[0], *args[1].items)
     expr.parenthesized = True  # to handle e.g. Power[a,b]^c correctly
     return expr
Example #57
0
    def apply(self, items, evaluation):
        'Plus[items___]'

        items = items.numerify(evaluation).get_sequence()
        leaves = []
        last_item = last_count = None

        prec = min_prec(*items)
        is_machine_precision = any(item.is_machine_precision()
                                   for item in items)
        numbers = []

        def append_last():
            if last_item is not None:
                if last_count == 1:
                    leaves.append(last_item)
                else:
                    if last_item.has_form('Times', None):
                        last_item.leaves.insert(0, from_sympy(last_count))
                        leaves.append(last_item)
                    else:
                        leaves.append(
                            Expression('Times', from_sympy(last_count),
                                       last_item))

        for item in items:
            if isinstance(item, Number):
                numbers.append(item)
            else:
                count = rest = None
                if item.has_form('Times', None):
                    for leaf in item.leaves:
                        if isinstance(leaf, Number):
                            count = leaf.to_sympy()
                            rest = item.leaves[:]
                            rest.remove(leaf)
                            if len(rest) == 1:
                                rest = rest[0]
                            else:
                                rest.sort()
                                rest = Expression('Times', *rest)
                            break
                if count is None:
                    count = sympy.Integer(1)
                    rest = item
                if last_item is not None and last_item == rest:
                    last_count = last_count + count
                else:
                    append_last()
                    last_item = rest
                    last_count = count
        append_last()

        if numbers:
            if prec is not None:
                if is_machine_precision:
                    numbers = [item.to_mpmath() for item in numbers]
                    number = mpmath.fsum(numbers)
                    number = Number.from_mpmath(number)
                else:
                    with mpmath.workprec(prec):
                        numbers = [item.to_mpmath() for item in numbers]
                        number = mpmath.fsum(numbers)
                        number = Number.from_mpmath(number, dps(prec))
            else:
                number = from_sympy(sum(item.to_sympy() for item in numbers))
        else:
            number = Integer(0)

        if not number.same(Integer(0)):
            leaves.insert(0, number)

        if not leaves:
            return Integer(0)
        elif len(leaves) == 1:
            return leaves[0]
        else:
            leaves.sort()
            return Expression('Plus', *leaves)
Example #58
0
    def apply_elements(self, filename, expr, elems, evaluation, options={}):
        "Export[filename_, expr_, elems_List?(AllTrue[#, NotOptionQ]&), OptionsPattern[]]"

        # Check filename
        if not self._check_filename(filename, evaluation):
            return Symbol('$Failed')

        # Process elems {comp* format?, elem1*}
        leaves = elems.get_leaves()

        format_spec, elems_spec = [], []
        found_form = False
        for leaf in leaves[::-1]:
            leaf_str = leaf.get_string_value()

            if not found_form and leaf_str in EXPORTERS:
                found_form = True

            if found_form:
                format_spec.append(leaf_str)
            else:
                elems_spec.append(leaf)

        # Just to be sure that the following calls do not change the state of this property
        current_predetermined_out = evaluation.predetermined_out
        # Infer format if not present
        if not found_form:
            assert format_spec == []
            format_spec = self._infer_form(filename, evaluation)
            if format_spec is None:
                evaluation.message('Export', 'infer', filename)
                evaluation.predetermined_out = current_predetermined_out
                return Symbol('$Failed')
            format_spec = [format_spec]
        else:
            assert format_spec != []

        # First item in format_spec is the explicit format.
        # The other elements (if present) are compression formats

        if elems_spec != []:  # FIXME: support elems
            evaluation.message('Export', 'noelem', elems,
                               String(format_spec[0]))
            evaluation.predetermined_out = current_predetermined_out
            return Symbol('$Failed')

        # Load the exporter
        exporter_symbol, exporter_options = EXPORTERS[format_spec[0]]
        function_channels = exporter_options.get("System`FunctionChannels")

        stream_options, custom_options = _importer_exporter_options(
            exporter_options.get("System`Options"), options, 'System`Export',
            evaluation)

        if function_channels is None:
            evaluation.message('Export', 'emptyfch')
            evaluation.predetermined_out = current_predetermined_out
            return Symbol('$Failed')
        elif function_channels == Expression('List', String('FileNames')):
            exporter_function = Expression(
                exporter_symbol, filename, expr,
                *list(chain(stream_options, custom_options)))
            res = exporter_function.evaluate(evaluation)
        elif function_channels == Expression('List', String('Streams')):
            stream = Expression('OpenWrite', filename,
                                *stream_options).evaluate(evaluation)
            if stream.get_head_name() != 'System`OutputStream':
                evaluation.message('Export', 'nffil')
                evaluation.predetermined_out = current_predetermined_out
                return Symbol("$Failed")
            exporter_function = Expression(
                exporter_symbol, stream, expr,
                *list(chain(stream_options, custom_options)))
            res = exporter_function.evaluate(evaluation)
            Expression('Close', stream).evaluate(evaluation)
        if res == Symbol('Null'):
            evaluation.predetermined_out = current_predetermined_out
            return filename
        evaluation.predetermined_out = current_predetermined_out
        return Symbol('$Failed')
Example #59
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))
Example #60
0
    def op_010(self, args):
        ' expr ::= expr ; '

        return Expression('CompoundExpression', args[0], Symbol('Null'))