예제 #1
0
파일: core.py 프로젝트: weakit/calc9000
def thread(func, *args, **kwargs):
    """
    Internal threading function
    keyword args are not threaded
    """

    length = None

    for arg in args:
        if isinstance(arg, iterables):
            if length is not None:
                if length != len(arg):
                    raise FunctionException(
                        "General::thread",
                        "Cannot Thread over Lists of Unequal Length.",
                    )
            else:
                length = len(arg)

    if length is None:
        return func(*args, **kwargs)

    chained = list(args)

    for i in range(len(chained)):
        if not isinstance(chained[i], iterables):
            chained[i] = (chained[i],) * length

    return List.create(thread(func, *z, **kwargs) for z in zip(*chained))
예제 #2
0
파일: core.py 프로젝트: weakit/calc9000
def evaluate_no_lazy(expr):
    """
    Evaluate an expression with current definitions.
    Does not evaluate any LazyFunctions in given expression.
    """

    # if is iterable, apply for each element
    if isinstance(expr, iterables) and not isinstance(expr, s.Matrix):
        return List.create(evaluate_no_lazy(x) for x in expr)

    # if expr does not have ability to perform substitutions, return
    if not hasattr(expr, "xreplace"):
        return expr

    def extend(ex):
        # if ex is a number, return
        if hasattr(ex, "is_Number") and ex.is_Number:
            return ex

        # if ex is a symbol, return definitions if present
        if isinstance(ex, s.Symbol):
            st = ex.name
            if st in r.refs.OwnValues:
                return r.refs.OwnValues[st]
            elif st in r.refs.Constants.Dict:
                return r.refs.Constants.Dict[st]

        # if ex does not have any arguments, return
        if not hasattr(ex, "args") or not isinstance(ex.args, iterables):
            return ex

        # ex is supposed to be a function at this point (since args are present)
        f_name = type(ex).__name__

        # do not make substitutions if function is explicit
        # since explicit functions require unevaluated args
        if Functions.is_explicit(f_name):
            return ex

        # evaluate args
        rep = {x: extend(x) for x in ex.args}
        ex = ex.xreplace(rep)

        # built-ins are automatically re-evaluated
        # when replacements are made by sympy

        # apply definitions if function has any
        if Functions.is_not_builtin(f_name):
            ex = Functions.apply_definitions(ex)

        return ex

    # evaluate inside-out
    return extend(expr)
예제 #3
0
파일: core.py 프로젝트: weakit/calc9000
    def evaluate(expr):
        """
        Evaluate an expression with current definitions.
        Evaluates all LazyFunctions in given expression.
        """

        # see evaluate_no_lazy for explanation

        if isinstance(expr, iterables) and not isinstance(expr, s.Matrix):
            return List.create(LazyFunction.evaluate(x) for x in expr)

        if not hasattr(expr, "subs"):
            return expr

        def extend(ex):
            if hasattr(ex, "is_Number") and ex.is_Number:
                return ex

            if isinstance(ex, s.Symbol):
                st = ex.name
                if st in r.refs.OwnValues:
                    return r.refs.OwnValues[st]
                elif st in r.refs.Constants.Dict:
                    return r.refs.Constants.Dict[st]

            if not hasattr(ex, "args") or not isinstance(ex.args, iterables):
                return ex

            f_name = type(ex).__name__

            if Functions.is_explicit(f_name):
                # if explicit lazy function, call with args un-evaluated
                if isinstance(ex, LazyFunction):
                    return ex.land()
                return ex

            rep = {x: extend(x) for x in ex.args}
            ex = ex.xreplace(rep)

            if Functions.is_not_builtin(f_name):
                ex = Functions.apply_definitions(ex)

            # if lazy function, call actual function
            if isinstance(ex, LazyFunction):
                return ex.land()

            return ex

        return extend(expr)
예제 #4
0
파일: core.py 프로젝트: weakit/calc9000
 def exec(cls, n):
     if isinstance(n, iterables):
         return List.create(Unset(x) for x in n)
     if isinstance(n, s.Symbol) and str(n) in r.refs.OwnValues:
         del r.refs.OwnValues[str(n)]
     return NoOutput(None)
예제 #5
0
파일: core.py 프로젝트: weakit/calc9000
def do_set(x, n):
    """Handles assignment"""
    refs = r.refs

    if isinstance(x, s.Symbol):
        if not is_assignable(x.name):
            raise FunctionException(
                "Set::setx",
                f"Symbol {x} is protected and cannot be assigned to.",
            )

        if isinstance(x, Tag):
            set_tag_value(x, n)
            return n

        if isinstance(n, s.Expr):
            if x in n.atoms():
                return None  # TODO: raise

        refs.OwnValues[x.name] = n

        return n

    if isinstance(x, s.Function):
        name = type(x).__name__

        # handle part assignment
        if name == "Part":
            return set_part(x, n)

        if not is_assignable(name):
            raise FunctionException("Set::set", f"Symbol {x} cannot be Assigned to.")

        # create dict of patterns if not present
        if name not in refs.DownValues:
            refs.DownValues[name] = {ArgsPattern(*x.args): n}

        # else add pattern to existing dict
        else:
            pat = ArgsPattern(*x.args)

            # remove duplicate if present
            remove_duplicate_pattern(refs.DownValues[name], pat)

            # update in place
            refs.DownValues[name].update({pat: n})

            # sort dict when done
            # sorting is done during assignment to keep function calls fast
            refs.DownValues[name] = OrderedDict(
                sorted(
                    refs.DownValues[name].items(),
                    key=lambda z: z[0].importance,
                    reverse=True,
                )
            )

        return n

    if isinstance(x, iterables):
        if isinstance(n, iterables) and len(x) == len(n):
            return List.create(Set(a, b) for a, b in zip(x, n))
        else:
            raise FunctionException("Set::shape")

    return None