コード例 #1
0
ファイル: calculus.py プロジェクト: ptjb/Mathics
    def apply(self, eqs, vars, evaluation):
        'Solve[eqs_, vars_]'

        vars_original = vars
        head_name = vars.get_head_name()
        if head_name == 'System`List':
            vars = vars.leaves
        else:
            vars = [vars]
        for var in vars:
            if ((var.is_atom() and not var.is_symbol()) or  # noqa
                    head_name in ('System`Plus', 'System`Times',
                                  'System`Power') or 'System`Constant'
                    in var.get_attributes(evaluation.definitions)):

                evaluation.message('Solve', 'ivar', vars_original)
                return
        eqs_original = eqs
        if eqs.get_head_name() in ('System`List', 'System`And'):
            eqs = eqs.leaves
        else:
            eqs = [eqs]
        sympy_eqs = []
        sympy_denoms = []
        for eq in eqs:
            if eq == SymbolTrue:
                pass
            elif eq == SymbolFalse:
                return Expression('List')
            elif not eq.has_form('Equal', 2):
                return evaluation.message('Solve', 'eqf', eqs_original)
            else:
                left, right = eq.leaves
                left = left.to_sympy()
                right = right.to_sympy()
                if left is None or right is None:
                    return
                eq = left - right
                eq = sympy.together(eq)
                eq = sympy.cancel(eq)
                sympy_eqs.append(eq)
                numer, denom = eq.as_numer_denom()
                sympy_denoms.append(denom)

        vars_sympy = [var.to_sympy() for var in vars]
        if None in vars_sympy:
            return

        # delete unused variables to avoid SymPy's
        # PolynomialError: Not a zero-dimensional system
        # in e.g. Solve[x^2==1&&z^2==-1,{x,y,z}]
        all_vars = vars[:]
        all_vars_sympy = vars_sympy[:]
        vars = []
        vars_sympy = []
        for var, var_sympy in zip(all_vars, all_vars_sympy):
            pattern = Pattern.create(var)
            if not eqs_original.is_free(pattern, evaluation):
                vars.append(var)
                vars_sympy.append(var_sympy)

        def transform_dict(sols):
            if not sols:
                yield sols
            for var, sol in sols.items():
                rest = sols.copy()
                del rest[var]
                rest = transform_dict(rest)
                if not isinstance(sol, (tuple, list)):
                    sol = [sol]
                if not sol:
                    for r in rest:
                        yield r
                else:
                    for r in rest:
                        for item in sol:
                            new_sols = r.copy()
                            new_sols[var] = item
                            yield new_sols
                break

        def transform_solution(sol):
            if not isinstance(sol, dict):
                if not isinstance(sol, (list, tuple)):
                    sol = [sol]
                sol = dict(list(zip(vars_sympy, sol)))
            return transform_dict(sol)

        if not sympy_eqs:
            sympy_eqs = True
        elif len(sympy_eqs) == 1:
            sympy_eqs = sympy_eqs[0]

        try:
            if isinstance(sympy_eqs, bool):
                result = sympy_eqs
            else:
                result = sympy.solve(sympy_eqs, vars_sympy)
            if not isinstance(result, list):
                result = [result]
            if (isinstance(result, list) and len(result) == 1
                    and result[0] is True):
                return Expression('List', Expression('List'))
            if result == [None]:
                return Expression('List')
            results = []
            for sol in result:
                results.extend(transform_solution(sol))
            result = results
            if any(sol and any(var not in sol for var in all_vars_sympy)
                   for sol in result):
                evaluation.message('Solve', 'svars')

            # Filter out results for which denominator is 0
            # (SymPy should actually do that itself, but it doesn't!)
            result = [
                sol for sol in result if all(
                    sympy.simplify(denom.subs(sol)) != 0
                    for denom in sympy_denoms)
            ]

            return Expression(
                'List',
                *(Expression(
                    'List',
                    *(Expression('Rule', var, from_sympy(sol[var_sympy]))
                      for var, var_sympy in zip(vars, vars_sympy)
                      if var_sympy in sol)) for sol in result))
        except sympy.PolynomialError:
            # raised for e.g. Solve[x^2==1&&z^2==-1,{x,y,z}] when not deleting
            # unused variables beforehand
            pass
        except NotImplementedError:
            pass
        except TypeError as exc:
            if str(exc).startswith("expected Symbol, Function or Derivative"):
                evaluation.message('Solve', 'ivar', vars_original)
コード例 #2
0
    def apply(self, expr, moff, mon, evaluation):
        'Quiet[expr_, moff_, mon_]'

        def get_msg_list(expr):
            if expr.has_form('MessageName', 2):
                expr = Expression('List', expr)
            if expr.get_name() == 'System`All':
                all = True
                messages = []
            elif expr.get_name() == 'System`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

        old_quiet_all, old_quiet_messages = \
            evaluation.quiet_all, evaluation.quiet_messages.copy()
        try:
            quiet_expr = Expression('Quiet', expr, moff, mon)
            try:
                off_all, off_messages = get_msg_list(moff)
            except ValueError:
                evaluation.message('Quiet', 'anmlist', 2, quiet_expr)
                return
            try:
                on_all, on_messages = get_msg_list(mon)
            except ValueError:
                evaluation.message('Quiet', 'anmlist', 2, quiet_expr)
                return
            if off_all and on_all:
                evaluation.message('Quiet', 'allall', quiet_expr)
                return
            evaluation.quiet_all = off_all
            conflict = []
            for off in off_messages:
                if off in on_messages:
                    conflict.append(off)
                    break
            if conflict:
                evaluation.message(
                    'Quiet', 'conflict', quiet_expr,
                    Expression(
                        'List',
                        *(Expression('MessageName', Symbol(symbol),
                                     String(tag))
                          for symbol, tag in conflict)))
                return
            for off in off_messages:
                evaluation.quiet_messages.add(off)
            for on in on_messages:
                evaluation.quiet_messages.discard(on)
            if on_all:
                evaluation.quiet_messages = set()

            return expr.evaluate(evaluation)
        finally:
            evaluation.quiet_all, evaluation.quiet_messages =\
                old_quiet_all, old_quiet_messages
コード例 #3
0
ファイル: calculus.py プロジェクト: ptjb/Mathics
    def apply_wrong(self, expr, x, other, evaluation):
        'D[expr_, {x_, other___}]'

        arg = Expression('List', x, *other.get_sequence())
        evaluation.message('D', 'dvar', arg)
        return Expression('D', expr, arg)
コード例 #4
0
 def callback(level):
     return Expression(f, level)
コード例 #5
0
    def apply(self, expr, evaluation):
        'Dimensions[expr_]'

        return Expression('List', *[
            Integer(dim) for dim in get_dimensions(expr)])
コード例 #6
0
                    exc_result = Symbol('$Aborted')
                if exc_result is not None:
                    self.recursion_depth = 0
                    result = self.format_output(exc_result)

                self.results.append(Result(self.out, result, line_no))
                self.out = []
            finally:
                self.stop()

            history_length = self.get_config_value('$HistoryLength', 100)
            if history_length is None or history_length > 100:
                history_length = 100
            line = line_no - history_length
            while line > 0:
                unset_in = self.definitions.unset('In', Expression('In', line))
                unset_out = self.definitions.unset('Out',
                                                   Expression('Out', line))
                if not (unset_in or unset_out):
                    break
                line -= 1

        if last_parse_error is not None:
            self.recursion_depth = 0
            self.stopped = False
            self.message('General', 'syntax', unicode(last_parse_error))
            self.results.append(Result(self.out, None, None))

    def get_stored_result(self, result):
        from mathics.core.expression import Symbol
コード例 #7
0
ファイル: datentime.py プロジェクト: ForeverRecompin/Mathics
 def evaluate(self, evaluation):
     return Expression('List', String(self.value))
コード例 #8
0
 def lhs(expr):
     return Expression('Format', expr, Symbol(format))
コード例 #9
0
 def rhs(expr):
     if expr.has_form('Infix', None):
         expr = Expression(
             Expression('HoldForm', expr.head),
             *expr.leaves)
     return Expression('InputForm', expr)
コード例 #10
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
        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
コード例 #11
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')
コード例 #12
0
    def match(
        self,
        yield_func,
        expression,
        vars,
        evaluation,
        head=None,
        leaf_index=None,
        leaf_count=None,
        fully=True,
        wrap_oneid=True,
    ):
        evaluation.check_stopped()

        attributes = self.head.get_attributes(evaluation.definitions)
        if "System`Flat" not in attributes:
            fully = True
        if not expression.is_atom():
            # don't do this here, as self.get_pre_choices changes the
            # ordering of the leaves!
            # if self.leaves:
            #    next_leaf = self.leaves[0]
            #    next_leaves = self.leaves[1:]

            def yield_choice(pre_vars):
                next_leaf = self.leaves[0]
                next_leaves = self.leaves[1:]

                # "leading_blanks" below handles expressions with leading Blanks H[x_, y_, ...]
                # much more efficiently by not calling get_match_candidates_count() on leaves
                # that have already been matched with one of the leading Blanks. this approach
                # is only valid for Expressions that are not Orderless (as with Orderless, the
                # concept of leading items does not exist).
                #
                # simple performance test case:
                #
                # f[x_, {a__, b_}] = 0;
                # f[x_, y_] := y + Total[x];
                # First[Timing[f[Range[5000], 1]]]"
                #
                # without "leading_blanks", Range[5000] will be tested against {a__, b_} in a
                # call to get_match_candidates_count(), which is slow.

                unmatched_leaves = expression.leaves
                leading_blanks = "System`Orderless" not in attributes

                for leaf in self.leaves:
                    match_count = leaf.get_match_count()

                    if leading_blanks:
                        if tuple(match_count) == (
                                1,
                                1,
                        ):  # Blank? (i.e. length exactly 1?)
                            if not unmatched_leaves:
                                raise StopGenerator_ExpressionPattern_match()
                            if not leaf.does_match(unmatched_leaves[0],
                                                   evaluation, pre_vars):
                                raise StopGenerator_ExpressionPattern_match()
                            unmatched_leaves = unmatched_leaves[1:]
                        else:
                            leading_blanks = False

                    if not leading_blanks:
                        candidates = leaf.get_match_candidates_count(
                            unmatched_leaves,
                            expression,
                            attributes,
                            evaluation,
                            pre_vars,
                        )
                        if candidates < match_count[0]:
                            raise StopGenerator_ExpressionPattern_match()

                # for new_vars, rest in self.match_leaf(    # nopep8
                #    self.leaves[0], self.leaves[1:], ([], expression.leaves),
                #    pre_vars, expression, attributes, evaluation, first=True,
                #    fully=fully, leaf_count=len(self.leaves),
                #    wrap_oneid=expression.get_head_name() != 'System`MakeBoxes'):
                # def yield_leaf(new_vars, rest):
                #    yield_func(new_vars, rest)
                self.match_leaf(
                    yield_func,
                    next_leaf,
                    next_leaves,
                    ([], expression.leaves),
                    pre_vars,
                    expression,
                    attributes,
                    evaluation,
                    first=True,
                    fully=fully,
                    leaf_count=len(self.leaves),
                    wrap_oneid=expression.get_head_name() !=
                    "System`MakeBoxes",
                )

            # for head_vars, _ in self.head.match(expression.get_head(), vars,
            # evaluation):
            def yield_head(head_vars, _):
                if self.leaves:
                    # pre_choices = self.get_pre_choices(
                    #    expression, attributes, head_vars)
                    # for pre_vars in pre_choices:

                    self.get_pre_choices(yield_choice, expression, attributes,
                                         head_vars)
                else:
                    if not expression.leaves:
                        yield_func(head_vars, None)
                    else:
                        return

            try:
                self.head.match(yield_head, expression.get_head(), vars,
                                evaluation)
            except StopGenerator_ExpressionPattern_match:
                return
        if (wrap_oneid and "System`OneIdentity" in attributes
                and expression.get_head() != self.head  # nopep8
                and expression != self.head):
            # and 'OneIdentity' not in
            # (expression.get_attributes(evaluation.definitions) |
            # expression.get_head().get_attributes(evaluation.definitions)):
            new_expression = Expression(self.head, expression)
            for leaf in self.leaves:
                leaf.match_count = leaf.get_match_count()
                leaf.candidates = [expression]
                # leaf.get_match_candidates(
                #    new_expression.leaves, new_expression, attributes,
                #    evaluation, vars)
                if len(leaf.candidates) < leaf.match_count[0]:
                    return
            # for new_vars, rest in self.match_leaf(
            #    self.leaves[0], self.leaves[1:],
            #    ([], [expression]), vars, new_expression, attributes,
            #    evaluation, first=True, fully=fully,
            #    leaf_count=len(self.leaves), wrap_oneid=True):
            # def yield_leaf(new_vars, rest):
            #    yield_func(new_vars, rest)
            self.match_leaf(
                yield_func,
                self.leaves[0],
                self.leaves[1:],
                ([], [expression]),
                vars,
                new_expression,
                attributes,
                evaluation,
                first=True,
                fully=fully,
                leaf_count=len(self.leaves),
                wrap_oneid=True,
            )
コード例 #13
0
    def apply_makeboxes(self, x, y, f, evaluation):
        'MakeBoxes[Subscript[x_, y__], f:StandardForm|TraditionalForm]'

        y = y.get_sequence()
        return Expression('SubscriptBox', Expression('MakeBoxes', x, f),
                          *list_boxes(y, f))
コード例 #14
0
 def transform_item(item):
     if depth > 2:
         return Expression(self.get_name(), item, new_depth)
     else:
         return item
コード例 #15
0
 def evaluate(self, evaluation) -> Expression:
     return Expression("List", *(String(arg) for arg in sys.argv))
コード例 #16
0
ファイル: optimization.py プロジェクト: wxchen4277/Mathics
    def apply_constraints(self, f, vars, evaluation):
        'Minimize[f_?ListQ, vars_?ListQ]'
        head_name = vars.get_head_name()
        vars_or = vars
        vars = vars.leaves
        for var in vars:
            if ((var.is_atom() and not var.is_symbol()) or  # noqa
                    head_name in ('System`Plus', 'System`Times',
                                  'System`Power') or 'System`Constant'
                    in var.get_attributes(evaluation.definitions)):

                evaluation.message('Minimize', 'ivar', vars_or)
                return

        vars_sympy = [var.to_sympy() for var in vars]
        constraints = [function for function in f.leaves]
        objective_function = constraints[0].to_sympy()

        constraints = constraints[1:]

        g_functions = []
        h_functions = []

        g_variables = []
        h_variables = []

        for constraint in constraints:
            left, right = constraint.leaves
            head_name = constraint.get_head_name()

            left = left.to_sympy()
            right = right.to_sympy()

            if head_name == 'System`LessEqual' or head_name == 'System`Less':
                eq = left - right
                eq = sympy.together(eq)
                eq = sympy.cancel(eq)

                g_functions.append(eq)
                g_variables.append(
                    sympy.Symbol('kkt_g' + str(len(g_variables))))

            elif head_name == 'System`GreaterEqual' or head_name == 'System`Greater':
                eq = -1 * (left - right)
                eq = sympy.together(eq)
                eq = sympy.cancel(eq)

                g_functions.append(eq)
                g_variables.append(
                    sympy.Symbol('kkt_g' + str(len(g_variables))))

            elif head_name == 'System`Equal':
                eq = left - right
                eq = sympy.together(eq)
                eq = sympy.cancel(eq)

                h_functions.append(eq)
                h_variables.append(
                    sympy.Symbol('kkt_h' + str(len(h_variables))))

        equations = []

        for variable in vars_sympy:
            equation = sympy.diff(objective_function, variable)

            for i in range(len(g_variables)):
                g_variable = g_variables[i]
                g_function = g_functions[i]

                equation = equation + g_variable * sympy.diff(
                    g_function, variable)

            for i in range(len(h_variables)):
                h_variable = h_variables[i]
                h_function = h_functions[i]

                equation = equation + h_variable * sympy.diff(
                    h_function, variable)

            equations.append(equation)

        for i in range(len(g_variables)):
            g_variable = g_variables[i]
            g_function = g_functions[i]

            equations.append(g_variable * g_function)

        for i in range(len(h_variables)):
            h_variable = h_variables[i]
            h_function = h_functions[i]

            equations.append(h_variable * h_function)

        all_variables = vars_sympy + g_variables + h_variables

        candidates_tmp = sympy.solve(equations, all_variables, dict=True)
        candidates = []

        for candidate in candidates_tmp:
            if len(candidate) != len(vars_sympy):
                for variable in candidate:
                    for i in range(len(candidate), len(vars_sympy)):
                        candidate[variable] = candidate[variable].subs(
                            {vars_sympy[i]: 1})
                for i in range(len(candidate), len(vars_sympy)):
                    candidate[vars_sympy[i]] = 1

            candidates.append(candidate)

        kkt_candidates = []

        for candidate in candidates:
            kkt_ok = True

            sum_constraints = 0

            for i in range(len(g_variables)):
                g_variable = g_variables[i]
                g_function = g_functions[i]

                if candidate[g_variable] < 0:
                    kkt_ok = False

                if candidate[g_variable] * g_function.subs(candidate) != 0:
                    kkt_ok = False

                sum_constraints = sum_constraints + candidate[g_variable]

            for i in range(len(h_variables)):
                h_variable = h_variables[i]
                h_function = h_functions[i]

                sum_constraints = sum_constraints + abs(candidate[h_variable])

            if sum_constraints <= 0:
                kkt_ok = False

            if not kkt_ok:
                continue

            kkt_candidates.append(candidate)

        hessian = sympy.Matrix([[sympy.diff(deriv, x) for x in all_variables]
                                for deriv in equations])

        for i in range(0, len(all_variables) - len(vars_sympy)):
            hessian.col_del(len(all_variables) - i - 1)
            hessian.row_del(len(all_variables) - i - 1)

        minimum_list = []

        for candidate in kkt_candidates:
            eigenvals = hessian.subs(candidate).eigenvals()

            positives_eigenvalues = 0
            negatives_eigenvalues = 0

            for val in eigenvals:
                val = complex(sympy.N(val, chop=True))

                if val.imag == 0:
                    val = val.real
                    if val < 0:
                        negatives_eigenvalues += 1
                    elif val > 0:
                        positives_eigenvalues += 1

            if positives_eigenvalues + negatives_eigenvalues != len(eigenvals):
                continue

            if positives_eigenvalues == len(eigenvals):
                for g_variable in g_variables:
                    del candidate[g_variable]
                for h_variable in h_variables:
                    del candidate[h_variable]

                minimum_list.append(candidate)

        return Expression(
            'List',
            *(Expression(
                'List',
                from_sympy(objective_function.subs(minimum).simplify()), [
                    Expression('Rule', from_sympy(list(minimum.keys())[i]),
                               from_sympy(list(minimum.values())[i]))
                    for i in range(len(vars_sympy))
                ]) for minimum in minimum_list))
コード例 #17
0
    def apply_full(self, xmin, ymin, zmin, xmax, ymax, zmax, evaluation):
        'Cuboid[{xmin_, ymin_, zmin_}, {xmax_, ymax_, zmax_}]'

        try:
            xmin, ymin, zmin = [
                value.to_number(n_evaluation=evaluation)
                for value in (xmin, ymin, zmin)
            ]
            xmax, ymax, zmax = [
                value.to_number(n_evaluation=evaluation)
                for value in (xmax, ymax, zmax)
            ]
        except NumberError:
            # TODO
            return

        if (xmax <= xmin) or (ymax <= ymin) or (zmax <= zmin):
            # TODO
            return

        polygons = [
            # X
            Expression('List', Expression('List', xmin, ymin, zmin),
                       Expression('List', xmin, ymax, zmin),
                       Expression('List', xmin, ymax, zmax)),
            Expression('List', Expression('List', xmin, ymin, zmin),
                       Expression('List', xmin, ymin, zmax),
                       Expression('List', xmin, ymax, zmax)),
            Expression('List', Expression('List', xmax, ymin, zmin),
                       Expression('List', xmax, ymax, zmin),
                       Expression('List', xmax, ymax, zmax)),
            Expression('List', Expression('List', xmax, ymin, zmin),
                       Expression('List', xmax, ymin, zmax),
                       Expression('List', xmax, ymax, zmax)),
            # Y
            Expression('List', Expression('List', xmin, ymin, zmin),
                       Expression('List', xmax, ymin, zmin),
                       Expression('List', xmax, ymin, zmax)),
            Expression('List', Expression('List', xmin, ymin, zmin),
                       Expression('List', xmin, ymin, zmax),
                       Expression('List', xmax, ymin, zmax)),
            Expression('List', Expression('List', xmin, ymax, zmin),
                       Expression('List', xmax, ymax, zmin),
                       Expression('List', xmax, ymax, zmax)),
            Expression('List', Expression('List', xmin, ymax, zmin),
                       Expression('List', xmin, ymax, zmax),
                       Expression('List', xmax, ymax, zmax)),
            # Z
            Expression('List', Expression('List', xmin, ymin, zmin),
                       Expression('List', xmin, ymax, zmin),
                       Expression('List', xmax, ymax, zmin)),
            Expression('List', Expression('List', xmin, ymin, zmin),
                       Expression('List', xmax, ymin, zmin),
                       Expression('List', xmax, ymax, zmin)),
            Expression('List', Expression('List', xmin, ymin, zmax),
                       Expression('List', xmin, ymax, zmax),
                       Expression('List', xmax, ymax, zmax)),
            Expression('List', Expression('List', xmin, ymin, zmax),
                       Expression('List', xmax, ymin, zmax),
                       Expression('List', xmax, ymax, zmax)),
        ]

        return Expression('Polygon', Expression('List', *polygons))
コード例 #18
0
ファイル: optimization.py プロジェクト: wxchen4277/Mathics
    def apply_multiplevariable(self, f, vars, evaluation):
        'Minimize[f_?NotListQ, vars_?ListQ]'

        head_name = vars.get_head_name()
        vars_or = vars
        vars = vars.leaves
        for var in vars:
            if ((var.is_atom() and not var.is_symbol()) or  # noqa
                    head_name in ('System`Plus', 'System`Times',
                                  'System`Power') or 'System`Constant'
                    in var.get_attributes(evaluation.definitions)):

                evaluation.message('Minimize', 'ivar', vars_or)
                return

        vars_sympy = [var.to_sympy() for var in vars]
        sympy_f = f.to_sympy()

        jacobian = [sympy.diff(sympy_f, x) for x in vars_sympy]
        hessian = sympy.Matrix([[sympy.diff(deriv, x) for x in vars_sympy]
                                for deriv in jacobian])

        candidates_tmp = sympy.solve(jacobian, vars_sympy, dict=True)
        candidates = []

        for candidate in candidates_tmp:
            if len(candidate) != len(vars_sympy):
                for variable in candidate:
                    for i in range(len(candidate), len(vars_sympy)):
                        candidate[variable] = candidate[variable].subs(
                            {vars_sympy[i]: 1})

                for i in range(len(candidate), len(vars_sympy)):
                    candidate[vars_sympy[i]] = 1

            candidates.append(candidate)

        minimum_list = []

        for candidate in candidates:
            eigenvals = hessian.subs(candidate).eigenvals()

            positives_eigenvalues = 0
            negatives_eigenvalues = 0

            for val in eigenvals:
                if val.is_real:
                    if val < 0:
                        negatives_eigenvalues += 1
                    elif val >= 0:
                        positives_eigenvalues += 1

            if positives_eigenvalues + negatives_eigenvalues != len(eigenvals):
                continue

            if positives_eigenvalues == len(eigenvals):
                minimum_list.append(candidate)

        return Expression(
            'List',
            *(Expression('List', from_sympy(
                sympy_f.subs(minimum).simplify()), [
                    Expression('Rule', from_sympy(list(minimum.keys())[i]),
                               from_sympy(list(minimum.values())[i]))
                    for i in range(len(vars_sympy))
                ]) for minimum in minimum_list))
コード例 #19
0
class Evaluation(object):
    def __init__(self,
                 input=None,
                 definitions=None,
                 timeout=None,
                 out_callback=None,
                 format='text',
                 catch_interrupt=True):
        from mathics.core.definitions import Definitions

        if definitions is None:
            definitions = Definitions()
        self.definitions = definitions
        self.recursion_depth = 0
        self.timeout = False
        self.stopped = False
        self.out = []
        self.out_callback = out_callback
        self.listeners = {}
        self.options = None

        self.quiet_all = False
        self.quiet_messages = set()

        self.format = format

        queries = []
        last_parse_error = None
        if input is not None:
            from mathics.core.parser import parse, TranslateError

            lines = input.splitlines()
            query = ''
            for line in lines:
                if line:
                    query += line
                    try:
                        expression = parse(query, self.definitions)
                        if expression is not None:
                            queries.append(expression)
                        query = ''
                        last_parse_error = None
                    except TranslateError, exc:
                        last_parse_error = exc
                else:
                    query += ' '

        self.results = []

        for query in queries:
            self.recursion_depth = 0
            self.timeout = False
            self.stopped = False

            from mathics.core.expression import Symbol, Expression, Integer
            from mathics.core.rules import Rule

            line_no = self.get_config_value('$Line', 0)
            line_no += 1
            self.definitions.set_ownvalue('$Line', Integer(line_no))

            history_length = self.get_config_value('$HistoryLength', 100)
            if history_length is None or history_length > 100:
                history_length = 100

            def evaluate():
                if history_length > 0:
                    self.definitions.add_rule(
                        'In', Rule(Expression('In', line_no), query))
                result = query.evaluate(self)
                if history_length > 0:
                    stored_result = self.get_stored_result(result)
                    self.definitions.add_rule(
                        'Out', Rule(Expression('Out', line_no), stored_result))
                if result != Symbol('Null'):
                    return self.format_output(result)
                else:
                    return None

            try:
                result = None
                exc_result = None
                try:
                    if timeout is None:
                        result = evaluate()
                    else:
                        with interruptingcow.timeout(timeout,
                                                     TimeoutInterrupt):
                            result = evaluate()
                except KeyboardInterrupt:
                    if catch_interrupt:
                        exc_result = Symbol('$Aborted')
                    else:
                        raise
                except ValueError, exc:
                    text = unicode(exc)
                    if (text == 'mpz.pow outrageous exponent' or  # noqa
                            text == 'mpq.pow outrageous exp num'):
                        self.message('General', 'ovfl')
                        exc_result = Expression('Overflow')
                    else:
                        raise
                except OverflowError:
                    self.message('General', 'ovfl')
                    exc_result = Expression('Overflow')
                except BreakInterrupt:
                    self.message('Break', 'nofdw')
                    exc_result = Expression('Hold', Expression('Break'))
                except ContinueInterrupt:
                    self.message('Continue', 'nofdw')
                    exc_result = Expression('Hold', Expression('Continue'))
                except TimeoutInterrupt:
                    self.stopped = False
                    self.timeout = True
                    self.message('General', 'timeout')
                    exc_result = Symbol('$Aborted')
                except AbortInterrupt:  # , error:
                    exc_result = Symbol('$Aborted')
                if exc_result is not None:
                    self.recursion_depth = 0
                    result = self.format_output(exc_result)

                self.results.append(Result(self.out, result, line_no))
                self.out = []
            finally:
コード例 #20
0
ファイル: diffeqns.py プロジェクト: yushuiqiang/Mathics
    def apply(self, eqn, y, x, evaluation):
        'DSolve[eqn_, y_, x_]'

        if eqn.has_form('List', eqn):
            # TODO: Try and solve BVPs using Solve or something analagous OR
            # add this functonality to sympy.
            evaluation.message('DSolve', 'symsys')
            return

        if eqn.get_head_name() != 'System`Equal':
            evaluation.message('DSolve', 'deqn', eqn)
            return

        # FIXME: This code is duplicated in calculus.py
        if ((x.is_atom() and not x.is_symbol()) or      # nopep8
            x.get_head_name() in ('System`Plus', 'System`Times',
                                  'System`Power') or
            'System`Constant' in x.get_attributes(evaluation.definitions)):
            evaluation.message('DSolve', 'dsvar')
            return

        # Fixes pathalogical DSolve[y''[x] == y[x], y, x]
        try:
            y.leaves
            function_form = None
            func = y
        except AttributeError:
            func = Expression(y, x)
            function_form = Expression('List', x)

        if func.is_atom():
            evaluation.message('DSolve', 'dsfun', y)
            return

        if len(func.leaves) != 1:
            evaluation.message('DSolve', 'symmua')
            return

        if x not in func.leaves:
            evaluation.message('DSolve', 'deqx')
            return

        left, right = eqn.leaves
        eqn = Expression('Plus', left, Expression(
            'Times', -1, right)).evaluate(evaluation)

        sym_eq = eqn.to_sympy(converted_functions=set([func.get_head_name()]))
        sym_x = sympy.symbols(str(sympy_symbol_prefix + x.name))
        sym_func = sympy.Function(str(
            sympy_symbol_prefix + func.get_head_name()))(sym_x)

        try:
            sym_result = sympy.dsolve(sym_eq, sym_func)
        except ValueError:
            evaluation.message('DSolve', 'symimp')
            return
        except NotImplementedError:
            evaluation.message('DSolve', 'symimp')
            return
        except TypeError:
            # Sympy bug #9446
            evaluation.message('DSolve', 'litarg', eqn)
            return
        except AttributeError:
            evaluation.message('DSolve', 'litarg', eqn)
            return
        except KeyError:
            evaluation.message('DSolve', 'litarg', eqn)
            return
        else:
            if not isinstance(sym_result, list):
                sym_result = [sym_result]

        if function_form is None:
            return Expression('List', *[
                Expression(
                    'List', Expression('Rule', *from_sympy(soln).leaves))
                for soln in sym_result])
        else:
            return Expression('List', *[
                Expression('List', Expression('Rule', y, Expression(
                    'Function', function_form, *from_sympy(soln).leaves[1:])))
                for soln in sym_result])
コード例 #21
0
 def callback(level):
     if level.is_atom():
         return level
     else:
         return Expression(f, *level.leaves)
コード例 #22
0
    def apply(self, eqns, a, n, evaluation):
        "RSolve[eqns_, a_, n_]"

        # TODO: Do this with rules?
        if not eqns.has_form("List", None):
            eqns = Expression("List", eqns)

        if len(eqns.leaves) == 0:
            return

        for eqn in eqns.leaves:
            if eqn.get_head_name() != "System`Equal":
                evaluation.message("RSolve", "deqn", eqn)
                return

        if (
            (n.is_atom() and not n.is_symbol())
            or n.get_head_name() in ("System`Plus", "System`Times", "System`Power")
            or "System`Constant" in n.get_attributes(evaluation.definitions)
        ):
            # TODO: Factor out this check for dsvar into a separate
            # function. DSolve uses this too.
            evaluation.message("RSolve", "dsvar")
            return

        try:
            a.leaves
            function_form = None
            func = a
        except AttributeError:
            func = Expression(a, n)
            function_form = Expression("List", n)

        if func.is_atom() or len(func.leaves) != 1:
            evaluation.message("RSolve", "dsfun", a)

        if n not in func.leaves:
            evaluation.message("DSolve", "deqx")

        # Seperate relations from conditions
        conditions = {}

        def is_relation(eqn):
            left, right = eqn.leaves
            for l, r in [(left, right), (right, left)]:
                if (
                    left.get_head_name() == func.get_head_name()
                    and len(left.leaves) == 1  # noqa
                    and isinstance(l.leaves[0].to_python(), int)
                    and r.is_numeric()
                ):

                    r_sympy = r.to_sympy()
                    if r_sympy is None:
                        raise ValueError
                    conditions[l.leaves[0].to_python()] = r_sympy
                    return False
            return True

        # evaluate is_relation on all leaves to store conditions
        try:
            relations = [leaf for leaf in eqns.leaves if is_relation(leaf)]
        except ValueError:
            return
        relation = relations[0]

        left, right = relation.leaves
        relation = Expression("Plus", left, Expression("Times", -1, right)).evaluate(
            evaluation
        )

        sym_eq = relation.to_sympy(converted_functions=set([func.get_head_name()]))
        if sym_eq is None:
            return
        sym_n = sympy.core.symbols(str(sympy_symbol_prefix + n.name))
        sym_func = sympy.Function(str(sympy_symbol_prefix + func.get_head_name()))(
            sym_n
        )

        sym_conds = {}
        for cond in conditions:
            sym_conds[
                sympy.Function(str(sympy_symbol_prefix + func.get_head_name()))(cond)
            ] = conditions[cond]

        try:
            # Sympy raises error when given empty conditions. Fixed in
            # upcomming sympy release.
            if sym_conds != {}:
                sym_result = sympy.rsolve(sym_eq, sym_func, sym_conds)
            else:
                sym_result = sympy.rsolve(sym_eq, sym_func)

            if not isinstance(sym_result, list):
                sym_result = [sym_result]
        except ValueError:
            return

        if function_form is None:
            return Expression(
                "List",
                *[
                    Expression("List", Expression("Rule", a, from_sympy(soln)))
                    for soln in sym_result
                ]
            )
        else:
            return Expression(
                "List",
                *[
                    Expression(
                        "List",
                        Expression(
                            "Rule",
                            a,
                            Expression("Function", function_form, from_sympy(soln)),
                        ),
                    )
                    for soln in sym_result
                ]
            )
コード例 #23
0
 def callback(level, pos):
     return Expression(f, level,
                       Expression('List', *(Integer(p) for p in pos)))
コード例 #24
0
ファイル: calculus.py プロジェクト: ptjb/Mathics
 def diff(evaluation):
     return Expression('D', f, x).evaluate(evaluation)
コード例 #25
0
 def summand(i):
     return Expression(f, get_part(list1, i_cur + [i]),
                       get_part(list2, [i] + j_cur))
コード例 #26
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]