コード例 #1
0
 def draw(self, weights=True, name='g'):
     G = GGraph(name)
     G.add_nodes(self.V)
     if weights:
         G.add_weights(self._D)
     G.add_edges(unfold(self.A), 'black')
     G.add_edges(unfold(self.E), 'red')
     G.render()
コード例 #2
0
    def get_makespan(self):
        import networkx as nx
        G = nx.DiGraph()
        edg = tuple(set(unfold(self.A)) | set(unfold(self.E)))
        edg_weighted = [(x[0], x[1], -self.getD(x[0])) for x in edg]
        G.add_weighted_edges_from(edg_weighted)

        s = nx.johnson(G, weight='weight')[-1][self.N - 2]
        return sum([self.getD(x) for x in s])
コード例 #3
0
ファイル: Query.py プロジェクト: YuvalLot/pyLocal
    def search(self, depth):
        """
        Search. Uses generators (yield statements) to generate solutions for this query.
        Given type "r" looks for predicates
        Given type "~" looks to see that a predicate doesn't have a solution
        Given type "&" looks for both gates of query, uses the first to 'feed' the second
        Given type "\\" looks for left side once only, and then right size
        Given type "|" yields from first gate, and from second gate
        Given type "$" yields from first gate, if none yielded, yields from second gate
        Given type "pi", represents Package{param}(variables), searched packages
        Given type "%", unfolds (if possible) and searches normally ('r')
        Given type "c" conditional.

        :param depth: a Counter object, maximum recursion depth
        :return: a generator object that can generate solutions for this query, dict[str, str]
        """

        if depth.count < 0:
            return

        if self.interpreter.console_trace_on:
            print(
                f"Searching for {self.__str__()}, with accumulated depth of {depth}, type {self.type}"
            )

        if self.interpreter.trace_on:
            self.interpreter.message(f"Searching for {self.__str__()}")
            yield "Print"

        # regular query
        if self.type == 'r':

            if not self.gateA:
                return

            if outString(self.gateA, ":"):
                data_name, _, second_part = self.gateA.partition(":")
                action, _, query_pat = second_part.partition("(")
                query_pat = query_pat[:-1]
                data_struct: AbstractDataStructure = self.interpreter.datasets.get(
                    data_name, None) or self.interpreter.datahashes.get(
                        data_name, None)
                if data_struct:
                    if action == "Insert":
                        yield from data_struct.insert(query_pat)
                    elif action == "Remove":
                        yield from data_struct.remove(query_pat)
                    elif action == "Lookup":
                        yield from data_struct.lookup(query_pat)
                    elif action == "Clear":
                        if query_pat == "":
                            yield from data_struct.clear()

                elif match_type(data_name) == "title":
                    t_name, _, t_pattern = data_name.partition("(")
                    start = ""
                    if f"{t_name}.metacall" in self.interpreter.predicates and action != "metacall":
                        start = f"{t_name}.metacall(" + data_name + "," + action + ",[" + query_pat + "])&"
                    class_prefix = f"{t_name}.{action}"
                    if class_prefix in self.interpreter.predicates:
                        class_string = start + f"{class_prefix}(" + data_name + (
                            query_pat and "," + query_pat) + ")"
                        print(class_string)
                        class_action = Query.create(self.interpreter,
                                                    class_string)
                        if class_action:
                            yield from class_action.search(depth)
                    else:
                        if f"{t_name}.call" in self.interpreter.predicates:
                            class_string = start + f"{t_name}.call(" + data_name + "," + action + ",[" + query_pat + "])"
                            yield from Query.create(self.interpreter,
                                                    class_string).search(depth)

                elif f"{data_name}.new" in self.interpreter.predicates:
                    for construct_dict in Query.create(
                            self.interpreter,
                            f"{data_name}.new(?construct)").search(depth):
                        construct = construct_dict.get("?construct", None)
                        if construct:
                            m = MatchDictionary.match(self.interpreter, action,
                                                      construct)
                            if m:
                                yield m[1]

                return

            query_name, _, query_pat = self.gateA.partition("(")
            query_pat = query_pat[:-1]

            for mac in self.interpreter.macros:
                if mac in query_pat:
                    flag = True
                    break
            else:
                flag = False

            if flag:
                query_pat = self.interpreter.macroSimplified(query_pat, depth)
                if query_pat is None:
                    return

            if query_name == "True":
                yield {}
                return

            if "{" in query_name:
                self.type = "pi"
                yield from self.search(depth)
                return

            # if predicate is variable
            if query_name[0] == "?":
                if query_pat == "":
                    return
                for predicate in self.interpreter.predicates.values():
                    sol_with_predicate = {query_name: predicate.name}
                    Q = Query.create(
                        self.interpreter,
                        smart_replace(self.__str__(), sol_with_predicate))
                    depth.sub(1)
                    for sol in Q.search(depth):
                        if type(sol) == str:
                            yield sol
                            continue
                        complete_sol = smartUpdate(sol_with_predicate, sol)
                        yield complete_sol
                return

            if query_name in self.interpreter.pythons:
                try:
                    yield from self.interpreter.pythons[query_name](query_pat)
                except Exception as e:
                    self.interpreter.raiseError(f"Python Error: {e}")
                return

            if query_name == "Time":
                parts = splitWithoutParen(query_pat)
                if len(parts) != 1:
                    return
                m = MatchDictionary.match(
                    self.interpreter, parts[0],
                    str((time.time() - Query.start).__round__(2)))
                if m:
                    yield m[1]
                return

            if query_name == "ClockInit":
                if query_pat != "":
                    return
                Query.start = time.time()
                yield {}
                return

            found = [False]
            for solution in BuiltIns.builtin(self.interpreter, query_name,
                                             query_pat, depth, found):
                yield solution
            if found[0]:
                return

            if query_name in self.interpreter.domains:
                domain = self.interpreter.domains[query_name]
                # print(f"Found the domain {domain.name}")
                for sol in domain.search(depth, query_pat):
                    # print(f"Found a solution {sol}")
                    m = MatchDictionary.match(
                        self.interpreter, query_pat,
                        smart_replace(domain.raw_vars, sol))
                    if m:
                        yield m[1]
                return

            query_name, _, query_pat = self.gateA.partition("(")
            query_pat = query_pat[:-1]

            predicate_match = self.interpreter.predicates.get(query_name, None)

            if predicate_match:
                for search, backward, forwards in predicate_match.match(
                        query_pat):
                    if search == 1:
                        yield backward
                    else:
                        next_q = Query.create(self.interpreter, search)
                        depth.sub(1)
                        for solution in next_q.search(depth):

                            if solution == "Request":
                                yield "Request"
                                continue
                            if solution == "Print":
                                yield "Print"
                                continue

                            solution_as_dict = {}
                            for key in backward.keys():

                                if backward[key] in solution.keys():
                                    solution_as_dict[key] = solution[
                                        backward[key]]
                                else:
                                    solution_as_dict[key] = processHead(
                                        smart_replace(backward[key], solution))

                            yield solution_as_dict

        # filter clause
        elif self.type == "~":

            if not self.gateA:
                return

            for sol in self.gateA.search(depth):
                if sol != "Print" and sol != "Request":
                    return

            yield {}

        # cut clause
        elif self.type == "\\":

            if not self.gateA or not self.gateB:
                return

            try:
                gen = self.gateA.search(depth)
                p_solution = next(gen)
                while p_solution in ["Print", "Request"]:
                    yield p_solution
                    p_solution = next(gen)

                updated_gate_B = self.gateB.add_new_info(p_solution)

                for solution in updated_gate_B.search(depth):

                    if solution == "Request":
                        yield "Request"
                        continue

                    if solution == "Print":
                        yield "Print"
                        continue

                    q_solution = p_solution.copy()
                    q_solution = smartUpdate(q_solution, solution)
                    yield q_solution

            except StopIteration:
                pass
            finally:
                return

        # and clause
        elif self.type == "&":

            if not self.gateA or not self.gateB:
                return

            for p_solution in self.gateA.search(depth):

                if p_solution == "Request":
                    yield "Request"
                    continue
                if p_solution == "Print":
                    yield "Print"
                    continue

                updated_gate_B = self.gateB.add_new_info(p_solution)

                for solution in updated_gate_B.search(depth):
                    if solution == "Request":
                        yield "Request"
                        continue
                    if solution == "Print":
                        yield "Print"
                        continue

                    q_solution = p_solution.copy()
                    q_solution = smartUpdate(q_solution, solution)
                    yield q_solution

        # or clause
        elif self.type == '|':

            if not self.gateA or not self.gateB:
                return

            yield from self.gateA.search(depth)
            yield from self.gateB.search(depth)

        # Lazy Or
        elif self.type == "$":
            if not self.gateA or not self.gateB:
                return

            first_solutions = self.gateA.search(depth)
            found_in_first = False
            for sol in first_solutions:
                if sol != "Print" or sol != "Request":
                    found_in_first = True
                yield sol

            if not found_in_first:
                yield from self.gateB.search(depth)

        # Package with input
        elif self.type == 'pi':

            if not self.gateA:
                return

            X = find_package_end(self.gateA)
            if not X:
                return

            p_pred, q_inp = X
            q_inp = q_inp[1:-1]
            p_name, _, p_inp = p_pred.partition("{")
            p_inp = p_inp[:-1]

            if p_name not in self.interpreter.packages:
                return

            flag_p = False
            flag_q = False

            for macro in self.interpreter.macros:
                if macro in p_inp:
                    flag_p = True
                if macro in q_inp:
                    flag_q = True
                if flag_p and flag_q:
                    break

            if flag_p:
                p_inp = self.interpreter.macroSimplified(p_inp, depth)
            if flag_q:
                q_inp = self.interpreter.macroSimplified(q_inp, depth)

            package_match = self.interpreter.packages[p_name]

            for search, backward in package_match.match(p_inp, q_inp):
                if search == 1:
                    yield backward
                    continue

                new_query = Query.create(self.interpreter, search)

                depth.sub(1)

                for solution in new_query.search(depth):
                    solution_as_dict = {}
                    for key in backward:
                        solution_as_dict[key] = smart_replace(
                            backward[key], solution)
                    yield solution_as_dict

        # Folding
        elif self.type == '%':

            if not self.gateA:
                return

            if outString(self.gateA, "){"):
                X = find_package_end(self.gateA)
                if not X:
                    return

                p_pred, q_inp = X
                q_inp = q_inp[1:-1]
                p_name, _, p_inp = p_pred.partition("{")
                p_inp = p_inp[:-1]

                if outString(p_inp, "%"):
                    p_inp = unfold(p_inp)
                if outString(q_inp, "%"):
                    q_inp = unfold(q_inp)

                if not p_inp or not q_inp:
                    return

                new_query = Query.create(self.interpreter,
                                         f"{p_name}{{{p_inp}}}({q_inp})")
                yield from new_query.search(depth)

            try:
                query_name, _, query_pat = self.gateA.partition("(")
                query_pat = query_pat[:-1]
            except ValueError:
                return

            query_pat = unfold(query_pat)
            if query_pat == False or query_pat is None:
                return
            new_query = Query.create(self.interpreter,
                                     f"{query_name}({query_pat})")
            print(new_query)
            if new_query:
                yield from new_query.search(depth)
            return

        # Conditional Statements
        elif self.type == 'c':
            for key, value in self.cond:
                if not key or not value:
                    continue
                try:
                    search = key.search(depth)
                    p_solution = next(search)
                    while p_solution in ["Print", "Request"]:
                        yield p_solution
                        p_solution = next(search)
                    for sol in value.add_new_info(p_solution).search(depth):
                        if sol in ["Print", "Request"]:
                            yield sol
                            continue
                        yield smartUpdate(p_solution, sol)
                    return
                except StopIteration:
                    continue

        # Dereference
        elif self.type == "!":

            if not self.gateA:
                return

            if outString(self.gateA, "){"):
                X = find_package_end(self.gateA)
                if not X:
                    return

                p_pred, q_inp = X
                q_inp = q_inp[1:-1]
                p_name, _, p_inp = p_pred.partition("{")
                p_inp = p_inp[:-1]

                if outString(p_inp, "%"):
                    p_inp = deref(self.interpreter, p_inp)
                if outString(q_inp, "%"):
                    q_inp = deref(self.interpreter, q_inp)

                if not p_inp or not q_inp:
                    return

                new_query = Query.create(self.interpreter,
                                         f"{p_name}{{{p_inp}}}({q_inp})")
                yield from new_query.search(depth)

            try:
                query_name, _, query_pat = self.gateA.partition("(")
                query_pat = query_pat[:-1]
            except ValueError:
                return

            query_pat = deref(self.interpreter, query_pat)
            if not query_pat:
                return
            new_query = Query.create(self.interpreter,
                                     f"{query_name}({query_pat})")
            if new_query:
                yield from new_query.search(depth)
            return

        # Setting Reference
        elif self.type == ':=':
            if self.gateA not in self.interpreter.references:
                self.interpreter.raiseError(
                    f"Error: Trying to change the value of non-existent reference, '{self.gateA}'"
                )
                return
            elif independent(self.gateB):
                self.interpreter.raiseError(
                    f"Error: trying to change the value of a reference to a value containing variables, '{self.gateB}'"
                )
                return
            self.gateB = deref(self.interpreter, self.gateB)
            if not self.gateB:
                return
            self.gateB = processHead(self.gateB)
            if not self.gateB:
                return
            self.interpreter.references[self.gateA] = self.gateB
            yield {}

        else:
            self.interpreter.raiseError(f"Error: Illegal Query")
コード例 #4
0
 def is_feasible(self):
     import networkx as nx
     G = nx.DiGraph()
     edg = tuple(set(unfold(self.A)) | set(unfold(self.E)))
     G.add_edges_from(edg)
     return nx.is_directed_acyclic_graph(G)