Beispiel #1
0
	def _congruence_graph(self):
		"""Form a graph whose vertex set is the QNF basis. The edges store the information which makes two vertices congruent."""
		from networkx.classes.digraph import DiGraph
		basis = self.quasinormal_basis
		min_exp = basis.minimal_expansion_for(self)
		terminal, initial = self.semi_infinite_end_points()
		endpts = sorted(terminal + initial)
		G = DiGraph()
		orbit_generators = set(min_exp)
		orbit_generators.update(endpts)
		
		#1. Add an edge for every direct congruence relationship.
		for gen in orbit_generators:
			type, images, _ = self.orbit_type(gen, basis)
			for power, img in images.items():
				images[power] = basis.test_above(img)
			
			congruent_pairs = permutations(images.items(), 2)
			for (pow1, (head1, tail1)), (pow2, (head2, tail2)) in congruent_pairs:
				if head1 == head2:
					continue
				data = dict(start_tail = tail1, power = pow2 - pow1, end_tail = tail2)
				G.add_edge(head1, head2, data)
				assert self.repeated_image(head1.extend(tail1), pow2 - pow1) == head2.extend(tail2)
		return G
Beispiel #2
0
 def remove_low_frequency_label(
         community_label_list_for_nodes: multivalued_dict) -> DiGraph:
     from sklearn.ensemble import IsolationForest
     digraph_of_node_labels_and_frequencies = DiGraph()
     for graph_of_node, label_list_of_nodes in community_label_list_for_nodes.items(
     ):
         digraph_of_node_labels_and_frequencies.add_node(graph_of_node)
         label_set = set(label_list_of_nodes)
         dict_of_frequency_of_label = dict(
             sorted([(label_list_of_nodes.count(label_item), label_item)
                     for label_item in label_set],
                    key=lambda frequency_and_label: frequency_and_label[0],
                    reverse=True))
         dict_of_sn_and_frequency = dict([
             (sequence_number, frequency_of_label)
             for sequence_number, frequency_of_label in enumerate(
                 dict_of_frequency_of_label.keys(), 1)
         ])
         list_of_mapping_points = []
         for sequence_number, frequency_of_label in dict_of_sn_and_frequency.items(
         ):
             list_of_mapping_points.extend([[sequence_number]] *
                                           frequency_of_label)
         clf = IsolationForest(n_estimators=120, contamination='auto')
         clf.fit(list_of_mapping_points)
         for sequence_number, frequency_of_label in dict_of_sn_and_frequency.items(
         ):
             if clf.predict([[sequence_number]])[0] == 1:
                 label_item = dict_of_frequency_of_label.__getitem__(
                     frequency_of_label)
                 digraph_of_node_labels_and_frequencies.add_edge(
                     graph_of_node, label_item, weight=frequency_of_label)
     return digraph_of_node_labels_and_frequencies
Beispiel #3
0
class MockSimpleGraphDB\
(
    Generic[MockVertexData],
    PartiallyStatefulDirectedGraphInterface[SimpleGraphKey, MockVertexData]
):
    '''
    Type for mocking a simple database.
    '''

    data: DiGraph

    def __init__(self) -> None:
        self.data = DiGraph()

    def write_stateful_vertex_(self, label: SimpleGraphKey,
                               data: MockVertexData, *args: Any,
                               **kwargs: Any) -> None:
        self.data.add_node(node_for_adding=label,
                           memento=data)  # type: ignore unkonwn

    def write_stateless_directed_edge_(self, source: SimpleGraphKey,
                                       destination: SimpleGraphKey, *args: Any,
                                       **kwargs: Any) -> None:
        self.data.add_edge(
            u_of_edge=source,
            v_of_edge=destination)  # type: ignore unkonwn member
Beispiel #4
0
class buchi_graph(object):
    """ construct buchi automaton graph
    Parameter:
        formula: LTL formula specifying task
    """
    def __init__(self, formula):
        self.formula = formula

    def formulaParser(self):
        """replace letter with symbol
        """
        indicator = 'FG'

        if [True for i in indicator if i in self.formula]:
            self.formula.replace('F', '<>').replace('G', '[]')

    def execLtl2ba(self):
        """ given formula, exectute the ltl2ba
        Parameter:
            buchi_str: output string of program ltl2ba  (utf-8 format)
        """

        dirname = os.path.dirname(__file__)
        self.buchi_str = subprocess.check_output(dirname + "/./ltl2ba -f \"" +
                                                 self.formula + "\"",
                                                 shell=True).decode("utf-8")

    def buchiGraph(self):
        """parse the output of ltl2ba
        Parameter:
            buchi_graph: Graph of buchi automaton
        """
        # find all states
        state_re = re.compile(r'\n(\w+):\n\t')
        state_group = re.findall(state_re, self.buchi_str)

        # find initial and accepting states
        init = [s for s in state_group if 'init' in s]
        accep = [s for s in state_group if 'accept' in s]
        """
        Format:
            buchi_graph.node = NodeView(('T0_init', 'T1_S1', 'accept_S1'))
            buchi_graph.edges = OutEdgeView([('T0_init', 'T0_init'), ('T0_init', 'T1_S1'),....])
            buchi_graph.succ = AdjacencyView({'T0_init': {'T0_init': {'label': '1'}, 'T1_S1': {'label': 'r3'}}})
        """
        self.buchi_graph = DiGraph(type='buchi', init=init, accept=accep)
        for state in state_group:
            # for each state, find transition relation
            # add node
            self.buchi_graph.add_node(state)
            state_if_fi = re.findall(state + r':\n\tif(.*?)fi', self.buchi_str,
                                     re.DOTALL)
            if state_if_fi:
                relation_group = re.findall(r':: \((.*?)\) -> goto (\w+)\n\t',
                                            state_if_fi[0])
                for (label, state_dest) in relation_group:
                    # add edge
                    self.buchi_graph.add_edge(state, state_dest, label=label)

        return self.buchi_graph
Beispiel #5
0
def build_crm(roadmap_dir='./build_roadmap/roadmap_2D.p',
              wsn_rate_dir='./wsn_routing/rate_map.p',
              ws_img_dir='./build_roadmap/ws_img.p'):
    '''
    build combined roadmap, crm
    via load roadmap and merge in wsn_rate info
    '''
    roadmap_edges = pickle.load(open(roadmap_dir, 'rb'))
    wsn_rate, wifis_loc, sink_loc = pickle.load(open(wsn_rate_dir, 'rb'))
    img = pickle.load(open(ws_img_dir, 'rb'))
    crm = DiGraph(name='combined_model',
                  ws_img=img,
                  wifis=wifis_loc,
                  sink=sink_loc)
    for e in roadmap_edges:
        (f_node, t_node) = e
        near_f_node = min(wsn_rate.keys(), key=lambda p: dist_2D(p, f_node))
        f_node_rate = wsn_rate[near_f_node]
        crm.add_node(f_node, rate=f_node_rate)
        near_t_node = min(wsn_rate.keys(), key=lambda p: dist_2D(p, t_node))
        t_node_rate = wsn_rate[near_t_node]
        crm.add_node(t_node, rate=t_node_rate)
        # interpolation
        dist_e = dist_2D(f_node, t_node)
        f_t_rate = intp_rate(f_node_rate, t_node_rate)
        crm.add_edge(f_node, t_node, rate=f_t_rate, dist=dist_e)
        t_f_rate = intp_rate(t_node_rate, f_node_rate)
        crm.add_edge(t_node, f_node, rate=t_f_rate, dist=dist_e)
    print '---crm constructed from %s and %s, %d nodes, %d edges---' % (
        roadmap_dir, wsn_rate_dir, len(crm.nodes()), len(crm.edges()))
    return crm
Beispiel #6
0
 def _digraph(self, index):
     g = DiGraph()
     g.add_node(index[self])
     for _, (fun, _) in self.calls:
         g.add_node(index[fun])
         g.add_edge(index[fun], index[self])
         g = networkx.compose(g, fun._digraph(index))
     return g
Beispiel #7
0
def load_graph(file_or_path:FileOrPath, ext:str=None) -> DiGraph:
  graph = DiGraph()
  for adj in load_jsonl(text_file_for(file_or_path)):
    src = adj[0]
    graph.add_node(src)
    for dst in adj[1:]:
      graph.add_edge(src, dst)
  return graph
Beispiel #8
0
def hoftask(init, buchi_graph, regions):
    h_task = DiGraph(type='subtask')
    try:
        label = to_dnf(
            buchi_graph.edges[(buchi_graph.graph['init'][0],
                               buchi_graph.graph['init'][0])]['label'], True)
    except KeyError:
        # no self loop
        label = to_dnf('0')
    init_node = State((init, buchi_graph.graph['init'][0]), label)
    h_task.add_node(init_node)
    open_set = list()
    open_set.append(init_node)
    explore_set = list()

    while open_set:
        curr = open_set.pop(0)

        # assume co-safe
        # if curr.q in buchi_graph.graph['accept']:
        #     continue
        # print(curr)
        for q_b in buchi_graph.succ[curr.q]:

            try:
                label = to_dnf(buchi_graph.edges[(q_b, q_b)]['label'], True)
            except KeyError:
                # no self loop
                label = to_dnf('0')
            if q_b != curr.q:  # and q_b not in buchi_graph.graph['accept']:
                # region corresponding to the label/word
                edge_label = (buchi_graph.edges[(curr.q, q_b)]['label'])
                if edge_label == '(1)':
                    x_set = [curr.x]
                else:
                    x_set = target(to_dnf(edge_label), regions)
                if x_set:
                    for x in x_set:
                        cand = State((x, q_b), label)
                        # print(cand)
                        if cand not in open_set and cand not in explore_set:
                            open_set.append(cand)
                            # check the match with each subtask in h_task
                            if not match(h_task, curr, cand):
                                # print(cand)
                                h_task.add_node(cand)
                                h_task.add_edge(curr, cand)
                                # continue
                            # roots for accepting states
                            # if q_b in buchi_graph.graph['accept']:
                            #     h_task.add_edge(curr, cand)

        explore_set.append(curr)
    # for x in h_task.nodes:
    #     print(x)
    return h_task
Beispiel #9
0
def _transition_graph():
    expected_graph = DiGraph()
    expected_graph.add_node('85',
                            coords=(-3.8347478, -38.592189),
                            datetime=['2017-09-02 22:00:27'],
                            freq_source=1,
                            freq_target=0)
    expected_graph.add_node('673',
                            coords=(-3.8235834, -38.590389),
                            datetime=['2017-09-02 22:01:36'],
                            freq_source=0,
                            freq_target=0)
    expected_graph.add_node('394',
                            coords=(-3.813889, -38.5904445),
                            datetime=['2017-09-02 22:03:08'],
                            freq_source=0,
                            freq_target=0)
    expected_graph.add_node('263',
                            coords=(-3.9067654, -38.5907723),
                            datetime=['2017-09-02 22:03:46'],
                            freq_source=0,
                            freq_target=0)
    expected_graph.add_node('224',
                            coords=(-3.8857223, -38.5928892),
                            datetime=['2017-09-02 22:07:19'],
                            freq_source=0,
                            freq_target=0)
    expected_graph.add_node('623',
                            coords=(-3.8828723, -38.5929789),
                            datetime=['2017-09-02 22:07:40'],
                            freq_source=0,
                            freq_target=1)
    expected_graph.add_edge('85',
                            '673',
                            weight=1,
                            mean_times='0 days 00:01:09')
    expected_graph.add_edge('673',
                            '394',
                            weight=1,
                            mean_times='0 days 00:01:32')
    expected_graph.add_edge('394',
                            '263',
                            weight=1,
                            mean_times='0 days 00:00:38')
    expected_graph.add_edge('263',
                            '224',
                            weight=1,
                            mean_times='0 days 00:03:33')
    expected_graph.add_edge('224',
                            '623',
                            weight=1,
                            mean_times='0 days 00:00:21')

    return expected_graph
Beispiel #10
0
class SimpleGraphDB\
(
    Generic[SimpleVertexLabel, VertexData], 
    PartiallyStatefulDirectedGraphInterface[SimpleVertexLabel, VertexData],
    StatefulVertexGraphLoaderInterface[SimpleVertexLabel, VertexData]
):
    '''
    Class that can write stateful vertices and stateless directed edges into a graph-like structure.
    '''

    __graph: DiGraph

    '''
    Property and dunder methods
    '''

    def __init__(self, *args: Any, **kwargs: Any) -> None:
        '''
        Sets up a `networkx.DiGraph` structure for writing stateful vertices and stateless direWcted edges.
        '''
        self.__graph = DiGraph()

        return None

    @property
    def _graph(self) -> DiGraph: return self.__graph

    '''
    ABC extensions.
    '''

    def write_stateful_vertex_(self, label: SimpleVertexLabel, data: VertexData, *args: Any, **kwargs: Any) -> None:
        '''
        Writes a vertex with this `label` associated with this `data` into a `networkx.DiGraph` object.
        '''
        self.__graph.add_node(node_for_adding = label, data = data)

        return None

    def write_stateless_directed_edge_(self, source: SimpleVertexLabel, destination: SimpleVertexLabel, *args: Any, **kwargs: Any) -> None:
        '''
        Writes an unlabelled edge between a vertex with this `source` label and one with this `destination` label into a `networkx.DiGraph` object.
        '''
        self.__graph.add_edge(u_of_edge = source, v_of_edge = destination)

        return None

    def load_stateful_vertex(self, label: SimpleVertexLabel, *args: Any, **kwargs: Any) -> VertexData:
        '''
        Loads the `VertexData` associated with this `label` from a `networkx.DiGraph` object.
        '''
        return self.__graph.nodes[label].get('data')
Beispiel #11
0
 def add_edge(self, u, v=None):  
     if v is None: (u,v)=u  # no v given, assume u is an edge tuple
     if self.has_edge(u,v): return # no parallel edges
     elif u in self and v in self:
         raise NetworkXError, "adding edge %s-%s not allowed in tree"%(u,v)
     elif u in self or v in self:
         DiGraph.add_edge(self,u,v) # u->v
         return
     elif len(self.adj)==0: # first leaf
         DiGraph.add_edge(self,u,v) # u->v           
         return
     else:
         raise NetworkXError("adding edge %s-%s not allowed in tree"%(u,v))
Beispiel #12
0
def buchi_from_ltl(formula,Type):
    promela_string = run_ltl2ba(formula)
    symbols = find_symbols(formula)
    edges = parse_ltl(promela_string)
    (states, initials, accepts) = find_states(edges)
    buchi = DiGraph(type=Type, initial=initials, accept=accepts, symbols=symbols)
    for state in states:
        buchi.add_node(state)
    for (ef,et) in edges.keys():
        guard_formula = edges[(ef,et)]
        guard_expr = parse_guard(guard_formula)
        buchi.add_edge(ef, et, guard=guard_expr, guard_formula=guard_formula)
    return buchi
Beispiel #13
0
    def load_from_graphml(path):
        """
        :type path: str
        :rtype: networkx.classes.graph.Graph
        """
        #: :type : networkx.classes.graph.Graph
        g1 = nx.read_graphml(path)
        #: :type graph: networkx.classes.digraph.DiGraph
        g2 = DiGraph()

        typetest = re.compile(r"([a-zA-z]+)(\d*)")

        max_qualifiers = dict(crossing=0, poi=0, plcs=0)
        node_mapping = dict()

        for node, data in g1.nodes_iter(data=True):

            m = typetest.match(data["label"])
            if m is None:
                raise(SALMAException("Wrong label format for node {}!".format(node)))

            loctype = m.group(1)
            if loctype in ["c"]:
                loctype = "crossing"
            elif loctype in ["p"]:
                loctype = "poi"
            elif loctype in ["pl"]:
                loctype = "plcs"
            if loctype not in ["poi", "plcs", "crossing"]:
                raise(SALMAException("Wrong loctype for node {}: {}".format(node, loctype)))
            qualifier = m.group(2)
            if len(qualifier) == 0:
                qualifier = max_qualifiers[loctype] + 1
                nid = data["label"] + str(qualifier)
            else:
                nid = data["label"]
            max_qualifiers[loctype] = max(max_qualifiers[loctype], qualifier)

            pos = (round(float(data["x"])), round(float(data["y"])))

            g2.add_node(nid, pos=pos, scaled_pos=pos, loctype=loctype)
            node_mapping[node] = nid

        for u, v in g1.edges_iter():
            n1 = node_mapping[u]
            n2 = node_mapping[v]
            g2.add_edge(n1, n2)
            g2.add_edge(n2, n1)

        MapGenerator.__add_roadlengths(g2)
        return g2
Beispiel #14
0
class BoardGraph(object):
    def walk(self, board, size_limit=maxint):
        pending_nodes = []
        self.graph = DiGraph()
        self.start = board.display(cropped=True)
        self.graph.add_node(self.start)
        pending_nodes.append(self.start)
        self.min_domino_count = len(board.dominoes)
        while pending_nodes:
            if len(self.graph) >= size_limit:
                raise GraphLimitExceeded(size_limit)
            state = pending_nodes.pop()
            board = Board.create(state, border=1)
            dominoes = set(board.dominoes)
            self.min_domino_count = min(self.min_domino_count, len(dominoes))
            for domino in dominoes:
                dx, dy = domino.direction
                self.try_move(state, domino, dx, dy, pending_nodes)
                self.try_move(state, domino, -dx, -dy, pending_nodes)
        self.last = state
        return set(self.graph.nodes())

    def try_move(self, old_state, domino, dx, dy, pending_states):
        try:
            new_state = self.move(domino, dx, dy)
            move = domino.describe_move(dx, dy)
            if not self.graph.has_node(new_state):
                # new node
                self.graph.add_node(new_state)
                pending_states.append(new_state)
            self.graph.add_edge(old_state, new_state, move=move)
        except BoardError:
            pass

    def move(self, domino, dx, dy):
        """ Move a domino and calculate the new board state.

        Afterward, put the board back in its original state.
        @return: the new board state
        @raise BoardError: if the move is illegal
        """
        domino.move(dx, dy)
        try:
            board = domino.head.board
            if not board.isConnected():
                raise BoardError('Board is not connected.')
            if board.hasLoner():
                raise BoardError('Board has a lonely domino.')
            return board.display(cropped=True)
        finally:
            domino.move(-dx, -dy)
Beispiel #15
0
 def add_edge(self, u, v=None):
     if v is None: (u, v) = u  # no v given, assume u is an edge tuple
     if self.has_edge(u, v): return  # no parallel edges
     elif u in self and v in self:
         raise NetworkXError, "adding edge %s-%s not allowed in tree" % (u,
                                                                         v)
     elif u in self or v in self:
         DiGraph.add_edge(self, u, v)  # u->v
         return
     elif len(self.adj) == 0:  # first leaf
         DiGraph.add_edge(self, u, v)  # u->v
         return
     else:
         raise NetworkXError("adding edge %s-%s not allowed in tree" %
                             (u, v))
Beispiel #16
0
 def construct_arg_crm(self):
     arg_crm = DiGraph()
     for wp_f in self.crm.nodes_iter():
         for d_f in iter(self.data_set):
             s_f = (wp_f, d_f)
             arg_crm.add_node(s_f)
             for wp_t in self.crm.neighbors(wp_f):
                 d_evolve = d_f - self.crm.edge[wp_f][wp_t][
                     'rate'] * self.sample_time - 2 * self.quant_size
                 d_t = [d for d in self.data_set if d >= d_evolve][0]
                 s_t = (wp_t, d_t)
                 arg_crm.add_edge(s_f, s_t, weight=1.0)
     print '---static argumented crm constructed: %d nodes, %d edges----' % (
         len(arg_crm.nodes()), len(arg_crm.edges()))
     self.arg_crm = arg_crm
Beispiel #17
0
def _get_projected_digraph(bg, matching, top_nodes):
    """
    """
    digraph = DiGraph()
    digraph.add_nodes_from(top_nodes)
    for n in top_nodes:
        # Add in-edges
        if n in matching:
            for t in bg[matching[n]]:
                if t != n:
                    digraph.add_edge(t, n)
        # Add out-edges
        for b in bg[n]:
            if b in matching and matching[b] != n:
                digraph.add_edge(n, matching[b])
    return digraph
def buchi_from_ltl(formula, Type1):
    promela_string = "never { /* G(goods->Xdepot)&&G(depot->Xgoods)&&(G(!b)&&G(!door||open)) */    accept_init :    /* init */    if	:: (!goods && !depot && !b && !door) || (!goods && !depot && !b && open) -> goto accept_init	:: (!goods && !b && !door) || (!goods && !b && open) -> goto accept_S2	:: (!depot && !b && !door) || (!depot && !b && open) -> goto accept_S3	:: (!b && !door) || (!b && open) -> goto accept_S4	fi;accept_S2 :    /* 1 */	if	:: (goods && !depot && !b && !door) || (goods && !depot && !b && open) -> goto accept_S3	:: (goods && !b && !door) || (goods && !b && open) -> goto accept_S4	fi;accept_S3 :    /* 2 */	if	:: (!goods && depot && !b && !door) || (!goods && depot && !b && open) -> goto accept_S2	:: (depot && !b && !door) || (depot && !b && open) -> goto accept_S4	fi;accept_S4 :    /* 3 */	if	:: (goods && depot && !b && !door) || (goods && depot && !b && open) -> goto accept_S4	fi;}"
    #promela_string = run_ltl2ba(formula)
    symbols = find_symbols(formula)
    edges = parse_ltl(promela_string)
    (states, initials, accepts) = find_states(edges)
    buchi = DiGraph(type=Type,
                    initial=initials,
                    accept=accepts,
                    symbols=symbols)
    for state in states:
        buchi.add_node(state)
    for (ef, et) in edges.keys():
        guard_formula = edges[(ef, et)]
        guard_expr = parse_guard(guard_formula)
        buchi.add_edge(ef, et, guard=guard_expr, guard_formula=guard_formula)
    return buchi
Beispiel #19
0
def DuoBA_from_ltls(hard_spec, soft_spec):
    hard_buchi = buchi_from_ltl(hard_spec, 'hard_buchi')
    soft_buchi = buchi_from_ltl(soft_spec, 'soft_buchi')
    hard_symbols = hard_buchi.graph['symbols']
    soft_symbols = soft_buchi.graph['symbols']
    symbols = set(hard_symbols).union(set(soft_symbols))
    DuoBA = DiGraph(type='safe_buchi',
                    hard=hard_buchi,
                    soft=soft_buchi,
                    symols=symbols)
    initial = set()
    accept = set()
    for (h_node, s_node, l) in cartesian_product(hard_buchi.nodes(),
                                                 soft_buchi.nodes(), [1, 2]):
        DuoNode = (h_node, s_node, l)
        DuoBA.add_node(DuoNode, hard=h_node, soft=s_node, level=l)
        if (h_node in hard_buchi.graph['initial']
                and s_node in soft_buchi.graph['initial'] and l == 1):
            initial.add(DuoNode)
        if (h_node in hard_buchi.graph['accept'] and l == 1):
            accept.add(DuoNode)
    DuoBA.graph['accept'] = accept
    DuoBA.graph['initial'] = initial
    for f_duonode in DuoBA.nodes_iter():
        for t_duonode in DuoBA.nodes_iter():
            f_h_node, f_s_node, f_level = check_duo_attr(DuoBA, f_duonode)
            t_h_node, t_s_node, t_level = check_duo_attr(DuoBA, t_duonode)
            if (t_h_node not in DuoBA.graph['hard'].neighbors(f_h_node) or
                    t_s_node not in DuoBA.graph['soft'].neighbors(f_s_node)):
                continue
                # relaxed because no common input alphabets are enabled
            hardguard = DuoBA.graph['hard'].edge[f_h_node][t_h_node]['guard']
            softguard = DuoBA.graph['soft'].edge[f_s_node][t_s_node]['guard']
            if ((f_h_node not in DuoBA.graph['hard'].graph['accept']
                 and f_level == 1 and t_level == 1)
                    or (f_h_node in DuoBA.graph['hard'].graph['accept']
                        and f_level == 1 and t_level == 2)
                    or (f_s_node not in DuoBA.graph['soft'].graph['accept']
                        and f_level == 2 and t_level == 2)
                    or (f_s_node in DuoBA.graph['soft'].graph['accept']
                        and f_level == 2 and t_level == 1)):
                DuoBA.add_edge(f_duonode,
                               t_duonode,
                               hardguard=hardguard,
                               softguard=softguard)
    return DuoBA
Beispiel #20
0
def hoftask_no_simplified(init, buchi_graph, regions):
    try:
        label = to_dnf(
            buchi_graph.edges[(buchi_graph.graph['init'][0],
                               buchi_graph.graph['init'][0])]['label'], True)
    except KeyError:
        # no self loop
        label = to_dnf('0')
    init_node = State((init, buchi_graph.graph['init'][0]), label)
    h_task = DiGraph(type='subtask', init=init_node)
    h_task.add_node(init_node)
    open_set = list()
    open_set.append(init_node)
    explore_set = list()

    while open_set:
        curr = open_set.pop(0)
        for q_b in buchi_graph.succ[curr.q]:
            try:
                label = to_dnf(buchi_graph.edges[(q_b, q_b)]['label'], True)
            except KeyError:
                # no self loop
                label = to_dnf('0')
            if q_b != curr.q:
                # region corresponding to the label/word
                edge_label = (buchi_graph.edges[(curr.q, q_b)]['label'])
                if edge_label == '(1)':
                    x_set = [curr.x]
                elif '~' in edge_label and to_dnf(edge_label).nargs == {
                        1
                }:  # ~l3_1
                    x_set = [curr.x]  # !!!!!!!
                else:
                    x_set = target(to_dnf(edge_label), regions)
                if x_set:
                    for x in x_set:
                        cand = State((x, q_b), label)
                        #  whether cand is already in the h_task
                        # cand = find_node(cand, h_task)
                        h_task.add_edge(curr, cand)
                        if cand not in open_set and cand not in explore_set:
                            open_set.append(cand)

        explore_set.append(curr)
    return h_task
def build_txs_graph(datadir: str) -> DiGraph:
    """
    read all block and transaction files in the given datadir and construct
    a full transaction graph.
    
    Each node represents a transaction. the node's id is the txid and it has
    the following attributes:
        - "tx" - the full tx json, as returned by bitcoind
        - "fee" - the tx fee
        - "height" - the block height in which the tx was included
    
    Each edge has the following attributes:
        - "value" the value in BTC of the output represented by this edge
        
    """
    blocks = load_blocks(datadir)
    txs = load_txs(datadir)

    txid_to_fee = {txid: find_tx_fee(txid, txs) for txid in txs.keys()}
    txid_to_height = {
        txid: block["height"]
        for block in blocks.values() for txid in block["tx"]
    }

    graph = DiGraph()

    # add all transactions
    for txid in txs.keys():
        graph.add_node(txid,
                       tx=txs[txid],
                       fee=txid_to_fee[txid],
                       height=txid_to_height[txid])

    # add edges between transactions
    for dest_txid, dest_tx in txs.items():
        for entry in dest_tx["vin"]:
            if "coinbase" in entry:
                continue  # coinbase transaction. no src
            src_txid = entry["txid"]
            index = entry["vout"]
            value = txs[src_txid]["vout"][index]["value"]
            graph.add_edge(src_txid, dest_txid, value=value)

    return graph
Beispiel #22
0
def find_SCCs(mdp, Sneg):
    #----simply find strongly connected components----
    print 'Remaining states size', len(Sneg)
    SCC  = set()
    simple_digraph = DiGraph()
    A = dict()
    for s in mdp.nodes():
        A[s] = mdp.node[s]['act'].copy()
    for s_f in Sneg:
        if s_f not in simple_digraph:
            simple_digraph.add_node(s_f)
        for s_t in mdp.successors_iter(s_f):
            if s_t in Sneg:
                simple_digraph.add_edge(s_f,s_t)
    print "SubGraph of one Sf: %s states and %s edges" %(str(len(simple_digraph.nodes())), str(len(simple_digraph.edges())))
    sccs = strongly_connected_component_subgraphs(simple_digraph)
    for scc in sccs:
        SCC.add(frozenset(scc.nodes()))    
    return SCC, A
Beispiel #23
0
def build_graph(num_grid, t):
    env = DiGraph(name='Environment')

    open_set = set()
    explore_set = set()
    r = round(1 / num_grid, 10)
    open_set.add((round(r / 2, 10), round(r / 2, 10)))
    while open_set:
        point = open_set.pop()
        env.add_node(point)
        fea_point = direction(point, r, t)
        for p in fea_point:
            env.add_edge(point, p)
            env.add_edge(p, point)
            if point not in explore_set:
                open_set.add(p)
        explore_set.add(point)

    return env
Beispiel #24
0
    def __init__(self,data=None,**kwds):
        DiGraph.__init__(self,**kwds)
        if data is not None:

            try: # build a rooted tree
                D=DiGraph()
                for (child,parent) in data.par.iteritems():
                    D.add_edge(parent,child)
            except AttributeError: 
                D=DiGraph(data)
            except: # else nothing we can do
                raise NetworkXError, "Data %s is not a rooted tree:"%data
                    
            if D.order()==D.size()+1:
                self.pred=D.pred.copy()
                self.succ=D.succ.copy()
                self.adj=self.succ
                del D
            else: # not a tree
                raise NetworkXError, "Data %s is not a rooted tree:"%data
Beispiel #25
0
    def __init__(self, data=None, **kwds):
        DiGraph.__init__(self, **kwds)
        if data is not None:

            try:  # build a rooted tree
                D = DiGraph()
                for (child, parent) in data.par.iteritems():
                    D.add_edge(parent, child)
            except AttributeError:
                D = DiGraph(data)
            except:  # else nothing we can do
                raise NetworkXError, "Data %s is not a rooted tree:" % data

            if D.order() == D.size() + 1:
                self.pred = D.pred.copy()
                self.succ = D.succ.copy()
                self.adj = self.succ
                del D
            else:  # not a tree
                raise NetworkXError, "Data %s is not a rooted tree:" % data
Beispiel #26
0
def DuoBA_from_ltls(hard_spec, soft_spec):
    hard_buchi = buchi_from_ltl(hard_spec, 'hard_buchi')
    soft_buchi = buchi_from_ltl(soft_spec, 'soft_buchi')
    hard_symbols = hard_buchi.graph['symbols']
    soft_symbols = soft_buchi.graph['symbols']
    symbols = set(hard_symbols).union(set(soft_symbols))
    DuoBA = DiGraph(type='safe_buchi', hard=hard_buchi, soft=soft_buchi, symols=symbols)
    initial = set()
    accept = set()
    for (h_node, s_node, l) in cartesian_product(hard_buchi.nodes(), soft_buchi.nodes(), [1, 2]):
        DuoNode = (h_node, s_node, l)
        DuoBA.add_node(DuoNode,hard=h_node, soft=s_node, level=l)
        if (h_node in hard_buchi.graph['initial'] and 
            s_node in soft_buchi.graph['initial'] and l == 1):
            initial.add(DuoNode)
        if (h_node in hard_buchi.graph['accept'] and l == 1):
            accept.add(DuoNode)
    DuoBA.graph['accept'] = accept
    DuoBA.graph['initial'] = initial
    for f_duonode in DuoBA.nodes():
        for t_duonode in DuoBA.nodes():
            f_h_node, f_s_node, f_level = check_duo_attr(DuoBA, f_duonode)
            t_h_node, t_s_node, t_level = check_duo_attr(DuoBA, t_duonode)
            if (t_h_node not in DuoBA.graph['hard'].neighbors(f_h_node) or 
                t_s_node not in DuoBA.graph['soft'].neighbors(f_s_node)):
                continue
                # relaxed because no common input alphabets are enabled
            hardguard = DuoBA.graph['hard'].edges[f_h_node,t_h_node]['guard']
            softguard = DuoBA.graph['soft'].edges[f_s_node,t_s_node]['guard']
            if ((f_h_node not in DuoBA.graph['hard'].graph['accept'] and 
                f_level == 1 and t_level == 1) or 
                (f_h_node in DuoBA.graph['hard'].graph['accept'] and 
                f_level == 1 and t_level == 2) or 
                (f_s_node not in DuoBA.graph['soft'].graph['accept'] and 
                f_level == 2 and t_level == 2) or 
                (f_s_node in DuoBA.graph['soft'].graph['accept'] and 
                f_level == 2 and t_level == 1)):
                DuoBA.add_edge(f_duonode, t_duonode, hardguard=hardguard, softguard=softguard)
    return DuoBA
def buchi_from_ltl(formula, Type):
    promela_string = run_ltl2ba(formula)
    symbols = find_symbols(formula)
    # print "Output from symbols"
    # print symbols
    edges = parse_ltl(promela_string)
    (states, initials, accepts) = find_states(edges)
    # print "Output from find_states"
    # print states
    # print initials
    # print accepts
    buchi = DiGraph(type=Type,
                    initial=initials,
                    accept=accepts,
                    symbols=symbols)
    for state in states:
        buchi.add_node(state)
    for (ef, et) in edges.keys():
        guard_formula = edges[(ef, et)]
        guard_expr = parse_guard(guard_formula)
        buchi.add_edge(ef, et, guard=guard_expr, guard_formula=guard_formula)
    # write_dot(buchi, "./result.dot")
    return buchi
Beispiel #28
0
    def setUp(self):
        graph = DiGraph()
        graph.add_cycle([1, 2, 3, 4])
        graph.add_cycle([5, 6, 7, 8])
        graph.add_node(0)
        graph.add_edge(9, 10)
        self.graph_1 = graph

        graph = DiGraph()
        graph.add_cycle([1, 2, 3, 4])
        graph.add_cycle([5, 6, 7, 8])
        graph.add_node(0)
        graph.add_edge(9, 10)
        graph.add_edge(3, 9)
        graph.add_edge(10, 7)
        self.graph_2 = graph
Beispiel #29
0
    def _build_ast(cls, rpn_expression):
        """build an AST from an Excel formula

        :param rpn_expression: a string formula or the result of parse_to_rpn()
        :return: AST which can be used to generate code
        """

        # use a directed graph to store the syntax tree
        tree = DiGraph()

        # production stack
        stack = []

        for node in rpn_expression:
            # The graph does not maintain the order of adding nodes/edges, so
            # add an attribute 'pos' so we can always sort to the correct order

            node.ast = tree
            if isinstance(node, OperatorNode):
                if node.token.type == node.token.OP_IN:
                    try:
                        arg2 = stack.pop()
                        arg1 = stack.pop()
                    except IndexError:
                        raise FormulaParserError(
                            "'{}' operator missing operand".format(
                                node.token.value))
                    tree.add_node(arg1, pos=0)
                    tree.add_node(arg2, pos=1)
                    tree.add_edge(arg1, node)
                    tree.add_edge(arg2, node)
                else:
                    try:
                        arg1 = stack.pop()
                    except IndexError:
                        raise FormulaParserError(
                            "'{}' operator missing operand".format(
                                node.token.value))
                    tree.add_node(arg1, pos=1)
                    tree.add_edge(arg1, node)

            elif isinstance(node, FunctionNode):
                if node.num_args:
                    args = stack[-node.num_args:]
                    del stack[-node.num_args:]
                    for i, a in enumerate(args):
                        tree.add_node(a, pos=i)
                        tree.add_edge(a, node)
            else:
                tree.add_node(node, pos=0)

            stack.append(node)

        assert 1 == len(stack)
        return stack[0]
Beispiel #30
0
    def _build_ast(cls, rpn_expression):
        """build an AST from an Excel formula

        :param rpn_expression: a string formula or the result of parse_to_rpn()
        :return: AST which can be used to generate code
        """

        # use a directed graph to store the syntax tree
        tree = DiGraph()

        # production stack
        stack = []

        for node in rpn_expression:
            # The graph does not maintain the order of adding nodes/edges, so
            # add an attribute 'pos' so we can always sort to the correct order

            node.ast = tree
            if isinstance(node, OperatorNode):
                if node.token.type == node.token.OP_IN:
                    try:
                        arg2 = stack.pop()
                        arg1 = stack.pop()
                    except IndexError:
                        raise FormulaParserError(
                            "'{}' operator missing operand".format(
                                node.token.value))
                    tree.add_node(arg1, pos=0)
                    tree.add_node(arg2, pos=1)
                    tree.add_edge(arg1, node)
                    tree.add_edge(arg2, node)
                else:
                    try:
                        arg1 = stack.pop()
                    except IndexError:
                        raise FormulaParserError(
                            "'{}' operator missing operand".format(
                                node.token.value))
                    tree.add_node(arg1, pos=1)
                    tree.add_edge(arg1, node)

            elif isinstance(node, FunctionNode):
                if node.num_args:
                    args = stack[-node.num_args:]
                    del stack[-node.num_args:]
                    for i, a in enumerate(args):
                        tree.add_node(a, pos=i)
                        tree.add_edge(a, node)
            else:
                tree.add_node(node, pos=0)

            stack.append(node)

        assert 1 == len(stack)
        return stack[0]
Beispiel #31
0
def build_ast(expression, debug = False):
    """build an AST from an Excel formula expression in reverse polish notation"""
    #use a directed graph to store the tree
    G = DiGraph()
    stack = []


    for n in expression:
        # Since the graph does not maintain the order of adding nodes/edges
        # add an extra attribute 'pos' so we can always sort to the correct order
        if isinstance(n,OperatorNode):
            if n.ttype == "operator-infix":
                arg2 = stack.pop()
                arg1 = stack.pop()
                # Hack to write the name of sheet in 2argument address
                if(n.tvalue == ':'):
                    if '!' in arg1.tvalue and arg2.ttype == 'operand' and '!' not in arg2.tvalue:
                        arg2.tvalue = arg1.tvalue.split('!')[0] + '!' + arg2.tvalue
                    
                G.add_node(arg1,{'pos':1})
                G.add_node(arg2,{'pos':2})
                G.add_edge(arg1, n)
                G.add_edge(arg2, n)
            else:
                arg1 = stack.pop()
                G.add_node(arg1,{'pos':1})
                G.add_edge(arg1, n)
                
        elif isinstance(n,FunctionNode):
            args = []
            for _ in range(n.num_args):
                try:
                    args.append(stack.pop())
                except:
                    raise Exception()
            #try:
                # args = [stack.pop() for _ in range(n.num_args)]
            #except:
            #        print 'STACK', stack, type(n)
            #        raise Exception('prut')
            args.reverse()
            for i,a in enumerate(args):
                G.add_node(a,{'pos':i})
                G.add_edge(a,n)

        else:
            G.add_node(n,{'pos':0})

        stack.append(n)

    return G,stack.pop()
Beispiel #32
0
def build_ast(expression, debug=False):
    """build an AST from an Excel formula expression in reverse polish notation"""
    #use a directed graph to store the tree
    G = DiGraph()
    stack = []

    for n in expression:
        # Since the graph does not maintain the order of adding nodes/edges
        # add an extra attribute 'pos' so we can always sort to the correct order
        if isinstance(n, OperatorNode):
            if n.ttype == "operator-infix":
                arg2 = stack.pop()
                arg1 = stack.pop()
                # Hack to write the name of sheet in 2argument address
                if (n.tvalue == ':'):
                    if '!' in arg1.tvalue and arg2.ttype == 'operand' and '!' not in arg2.tvalue:
                        arg2.tvalue = arg1.tvalue.split(
                            '!')[0] + '!' + arg2.tvalue

                G.add_node(arg1, {'pos': 1})
                G.add_node(arg2, {'pos': 2})
                G.add_edge(arg1, n)
                G.add_edge(arg2, n)
            else:
                arg1 = stack.pop()
                G.add_node(arg1, {'pos': 1})
                G.add_edge(arg1, n)

        elif isinstance(n, FunctionNode):
            args = []
            for _ in range(n.num_args):
                try:
                    args.append(stack.pop())
                except:
                    raise Exception()
            #try:
            # args = [stack.pop() for _ in range(n.num_args)]
            #except:
            #        print 'STACK', stack, type(n)
            #        raise Exception('prut')
            args.reverse()
            for i, a in enumerate(args):
                G.add_node(a, {'pos': i})
                G.add_edge(a, n)

        else:
            G.add_node(n, {'pos': 0})

        stack.append(n)

    return G, stack.pop()
Beispiel #33
0
def build_ast(expression):

    """build an AST from an Excel formula expression in reverse polish notation"""
    
    #use a directed graph to store the tree
    G = DiGraph()
    
    stack = []
    
    for n in expression:
        # Since the graph does not maintain the order of adding nodes/edges
        # add an extra attribute 'pos' so we can always sort to the correct order
        if isinstance(n,OperatorNode):
            if n.ttype == "operator-infix":
                arg2 = stack.pop()
                arg1 = stack.pop()
                G.add_node(arg1,{'pos':1})
                G.add_node(arg2,{'pos':2})
                G.add_edge(arg1, n)
                G.add_edge(arg2, n)
            else:
                arg1 = stack.pop()
                G.add_node(arg1,{'pos':1})
                G.add_edge(arg1, n)
                
        elif isinstance(n,FunctionNode):
            args = [stack.pop() for _ in range(n.num_args)]
            args.reverse()
            for i,a in enumerate(args):
                G.add_node(a,{'pos':i})
                G.add_edge(a,n)
            #for i in range(n.num_args):
            #    G.add_edge(stack.pop(),n)
        else:
            G.add_node(n,{'pos':0})

        stack.append(n)
        
    return G,stack.pop()
Beispiel #34
0
def build_ast(expression):
    """build an AST from an Excel formula expression in reverse polish notation"""

    #use a directed graph to store the tree
    G = DiGraph()

    stack = []

    for n in expression:
        # Since the graph does not maintain the order of adding nodes/edges
        # add an extra attribute 'pos' so we can always sort to the correct order
        if isinstance(n, OperatorNode):
            if n.ttype == "operator-infix":
                arg2 = stack.pop()
                arg1 = stack.pop()
                G.add_node(arg1, {'pos': 1})
                G.add_node(arg2, {'pos': 2})
                G.add_edge(arg1, n)
                G.add_edge(arg2, n)
            else:
                arg1 = stack.pop()
                G.add_node(arg1, {'pos': 1})
                G.add_edge(arg1, n)

        elif isinstance(n, FunctionNode):
            args = [stack.pop() for _ in range(n.num_args)]
            args.reverse()
            for i, a in enumerate(args):
                G.add_node(a, {'pos': i})
                G.add_edge(a, n)
            #for i in range(n.num_args):
            #    G.add_edge(stack.pop(),n)
        else:
            G.add_node(n, {'pos': 0})

        stack.append(n)

    return G, stack.pop()
Beispiel #35
0
def dp_dag_general(G, r, U,
                   cost_func,
                   node_reward_key='r',
                   debug=False):
    """
    cost_func(node, D table, graph, [(cost at child , child)])

    It should return cost as integer type(fixed point is used when appropriate)
    """
    ns = G.nodes()
    if debug:
        print("total #nodes {}".format(len(ns)))
    
    A, D, BP = {}, {}, {}
    for n in ns:
        A[n] = {}  # maximum sum of node u at a cost i
        A[n][0] = G.node[n][node_reward_key]

        D[n] = {}  # set of nodes included corresponding to A[u][i]
        D[n][0] = {n}

        BP[n] = defaultdict(list)  # backpointer corresponding to A[u][i]

    for n_i, n in enumerate(
            topological_sort(G, reverse=True)):  # leaves come first

        if debug:
            print("#nodes processed {}".format(n_i))

        children = G.neighbors(n)
        if debug:
                print('{}\'s children={}'.format(n, children))
        reward = G.node[n][node_reward_key]
        if len(children) == 1:
            child = children[0]
            if debug:
                print('child={}'.format(child))
            for i in A[child]:
                c = cost_func(n, D, G,
                              [(i, child)])
                assert isinstance(c, int)
                if c <= U:
                    A[n][c] = A[child][i] + reward
                    D[n][c] = D[child][i] | {n}
                    BP[n][c] = [(child, i)]
        elif len(children) > 1:
            assert len(children) == 2
            lchild, rchild = children

            for i in A[lchild]:
                c = cost_func(n, D, G,
                              [(i, lchild)])
                assert isinstance(c, int)
                if debug:
                    print('n={}, D={}, cost_child_tuples={}'.format(
                        n, D, [(i, lchild)])
                    )
                    print('c={}'.format(c))
                if c <= U:
                    if A[n].get(c) is None or A[lchild][i] + reward > A[n][c]:
                        A[n][c] = A[lchild][i] + reward
                        D[n][c] = D[lchild][i] | {n}
                        BP[n][c] = [(lchild, i)]

            for i in A[rchild]:
                c = cost_func(n, D, G,
                              [(i, rchild)])
                assert isinstance(c, int)
                if c <= U:
                    if A[n].get(c) is None or A[rchild][i] + reward > A[n][c]:
                        A[n][c] = A[rchild][i] + reward
                        D[n][c] = D[rchild][i] | {n}
                        BP[n][c] = [(rchild, i)]
            
            for i in A[lchild]:
                for j in A[rchild]:
                    c = cost_func(n, D, G,
                                  [(i, lchild), (j, rchild)])
                    assert isinstance(c, int)
                    lset, rset = D[lchild][i], D[rchild][j]
                    if c <= U:
                        if (A[n].get(c) is None or
                            A[lchild][i] + A[rchild][j] + reward > A[n][c]) and \
                           len(lset & rset) == 0:
                            A[n][c] = A[lchild][i] + A[rchild][j] + reward
                            D[n][c] = D[lchild][i] | D[rchild][j] | {n}
                            BP[n][c] = [(lchild, i), (rchild, j)]

            if n == r:  # no need to continue once we processed root
                break
                
    best_cost = max(xrange(U + 1),
                    key=lambda i: A[r][i] if i in A[r] else float('-inf'))
    tree = DiGraph()
    tree.add_node(r)
    stack = []
    if debug and len(stack) == 0:
        print('stack empty')
        print(A)
    for n, cost in BP[r][best_cost]:
        stack.append((r, n, cost))
    while len(stack) > 0:
        if debug:
            print('stack size: {}'.format(len(stack)))
            print('stack: {}'.format(stack))
        
        parent, child, cost = stack.pop(0)
        tree.add_edge(parent, child)

        # copy the attributes
        tree[parent][child] = G[parent][child]
        tree.node[parent] = G.node[parent]
        tree.node[child] = G.node[child]

        for grandchild, cost2 in BP[child][cost]:
            if debug:
                print(grandchild, cost2)
            stack.append((child, grandchild, cost2))

    return tree
Beispiel #36
0
def lst_dag(G, r, U,
            node_reward_key='r',
            edge_cost_key='c',
            edge_weight_decimal_point=None,
            fixed_point_func=round,
            debug=False):
    """
    Param:
    -------------
    binary_dag: a DAG in networkx format. Each node can have at most 2 child
    r: root node in dag
    U: the maximum threshold of edge weight sum

    Return:
    maximum-sum subtree rooted at r whose sum of edge weights <= A
    ------------
    """
    # round edge weight to fixed decimal point if necessary

    if edge_weight_decimal_point is not None:
        G = G.copy()
        G, U = round_edge_weights_by_multiplying(
            G,
            U,
            edge_weight_decimal_point,
            edge_cost_key=edge_cost_key,
            fixed_point_func=fixed_point_func
        )

    if debug:
        print('U => {}'.format(U))

    ns = G.nodes()
    if debug:
        print("total #nodes {}".format(len(ns)))
    
    A, D, BP = {}, {}, {}
    for n in ns:
        A[n] = {}  # maximum sum of node u at a cost i
        A[n][0] = G.node[n][node_reward_key]

        D[n] = {}  # set of nodes included corresponding to A[u][i]
        D[n][0] = {n}

        BP[n] = defaultdict(list)  # backpointer corresponding to A[u][i]

    for n_i, n in enumerate(
            topological_sort(G, reverse=True)):  # leaves come first

        if debug:
            print("#nodes processed {}".format(n_i))
        
        children = G.neighbors(n)
        reward = G.node[n][node_reward_key]
        if len(children) == 1:
            child = children[0]
            w = G[n][child][edge_cost_key]
            for i in xrange(U, w - 1, -1):
                if (i-w) in A[child]:
                    A[n][i] = A[child][i-w] + reward
                    D[n][i] = D[child][i-w] | {n}
                    BP[n][i] = [(child, i-w)]
        elif len(children) > 1:
            lchild, rchild = children
            lw = G[n][lchild][edge_cost_key]
            rw = G[n][rchild][edge_cost_key]

            for i in A[lchild]:
                c = lw + i
                if debug:
                    print('n={}, D={}, cost_child_tuples={}'.format(
                        n, D, [(i, lchild)])
                    )
                    print('c={}'.format(c))
                if c <= U:
                    if A[n].get(c) is None or A[lchild][i] + reward > A[n][c]:
                        A[n][c] = A[lchild][i] + reward
                        D[n][c] = D[lchild][i] | {n}
                        BP[n][c] = [(lchild, i)]

            for i in A[rchild]:
                c = rw + i
                if c <= U:
                    if A[n].get(c) is None or A[rchild][i] + reward > A[n][c]:
                        A[n][c] = A[rchild][i] + reward
                        D[n][c] = D[rchild][i] | {n}
                        BP[n][c] = [(rchild, i)]
            
            for i in A[lchild]:
                for j in A[rchild]:
                    c = lw + rw + i + j
                    if c <= U:
                        if (A[n].get(c) is None or
                            A[lchild][i] + A[rchild][j] + reward > A[n][c]) and \
                           len(D[lchild][i] & D[rchild][j]) == 0:
                            A[n][c] = A[lchild][i] + A[rchild][j] + reward
                            D[n][c] = D[lchild][i] | D[rchild][j] | {n}
                            BP[n][c] = [(lchild, i), (rchild, j)]
            
            # if n == r:  # no need to continue once we processed root
            #     break
                
    if debug:
        print('A[r]', A[r])

    best_cost = max(xrange(U + 1),
                    key=lambda i: A[r][i] if i in A[r] else float('-inf'))
    if debug:
        print("best_cost", best_cost)

    tree = DiGraph()
    tree.add_node(r)
    stack = []
    for n, cost in BP[r][best_cost]:
        stack.append((r, n, cost))
    while len(stack) > 0:
        # if debug:
        #     print('stack size: {}'.format(len(stack)))
        #     print('stack: {}'.format(stack))
        
        parent, child, cost = stack.pop(0)
        tree.add_edge(parent, child)

        # copy the attributes
        tree[parent][child] = G[parent][child]
        tree.node[parent] = G.node[parent]
        tree.node[child] = G.node[child]

        for grandchild, cost2 in BP[child][cost]:
            # if debug:
            #     print(grandchild, cost2)
            stack.append((child, grandchild, cost2))

    return tree
Beispiel #37
0
        net, _i, _f = run_heuristic(log, label,
                                    'dest_class_func',
                                    parameters=heuristic_b_params)

        print(f'Creating graph for petri net...')
        graph = DiGraph()
        all_nodes = set()

        for place in net.places:
            graph.add_node(str(place), label=str(place))
            all_nodes.add(str(place))
        for transition in net.transitions:
            graph.add_node(str(transition), label=str(transition))
            all_nodes.add(str(transition))
        for arc in net.arcs:
            graph.add_edge(str(arc.source), str(arc.target))

        sp_nodes = set([label for label in nodes_in_shortest_path(graph)
                       if heuristic_filter(label)])

        filtered_nodes = set([label for label in all_nodes
                             if heuristic_filter(label)])

        # print("Filtered Nodes")
        # print(filtered_nodes)
        # print()
        # print("Shortest Path Nodes")
        # print(sp_nodes)
        # print()
        print()
Beispiel #38
0
class tree(object):
    """ construction of prefix and suffix tree
    """
    def __init__(self, ts, buchi_graph, init, step_size, base=1e3):
        """
        :param ts: transition system
        :param buchi_graph:  Buchi graph
        :param init: product initial state
        """
        self.robot = 1
        self.goals = []
        self.ts = ts
        self.buchi_graph = buchi_graph
        self.init = init
        self.step_size = step_size
        self.dim = len(self.ts['workspace'])
        uni_v = np.power(np.pi, self.robot * self.dim /
                         2) / math.gamma(self.robot * self.dim / 2 + 1)
        self.gamma = np.ceil(
            4 * np.power(1 / uni_v, 1. /
                         (self.dim * self.robot)))  # unit workspace
        self.tree = DiGraph(type='PBA', init=init)
        label = self.label(init[0])
        if label != '':
            label = label + '_' + str(1)
        # accepting state before current node
        acc = set()
        if 'accept' in init[1]:
            acc.add(init)
        self.tree.add_node(init, cost=0, label=label, acc=acc)
        self.search_goal(init, label, acc)

        # already used skilles
        self.used = set()
        self.base = base

    def sample(self):
        """
        sample point from the workspace
        :return: sampled point, tuple
        """
        x_rand = []
        for i in range(self.dim):
            x_rand.append(uniform(0, self.ts['workspace'][i]))

        return tuple(x_rand)

    def nearest(self, x_rand):
        """
        find the nearest class of vertices in the tree
        :param: x_rand randomly sampled point form: single point ()
        :return: nearest class of vertices form: single point ()
        """
        min_dis = math.inf
        q_nearest = []
        for vertex in self.tree.nodes:
            x_vertex = vertex[0]
            dis = np.linalg.norm(np.subtract(x_rand, x_vertex))
            if dis < min_dis:
                q_nearest = list()
                q_nearest.append(vertex)
                min_dis = dis
            elif dis == min_dis:
                q_nearest.append(vertex)
        return q_nearest

    def steer(self, x_rand, x_nearest):
        """
        steer
        :param: x_rand randomly sampled point form: single point ()
        :param: x_nearest nearest point in the tree form: single point ()
        :return: new point single point ()
        """
        if np.linalg.norm(np.subtract(x_rand, x_nearest)) <= self.step_size:
            return x_rand
        else:
            return tuple(
                np.asarray(x_nearest) + self.step_size *
                (np.subtract(x_rand, x_nearest)) /
                np.linalg.norm(np.subtract(x_rand, x_nearest)))

    def acpt_check(self, q_min, q_new):
        """
        check the accepting state in the patg leading to q_new
        :param q_min:
        :param q_new:
        :return:
        """
        changed = False
        acc = set(self.tree.nodes[q_min]['acc'])  # copy
        if 'accept' in q_new[1]:
            acc.add(q_new)
            # print(acc)
            changed = True
        return acc, changed

    def search_goal(self, q_new, label_new, acc):
        """
        whether q_new can connect to point before acc
        :param q_new:
        :param label_new:
        :param acc:
        :return:
        """
        for ac in acc:
            # connect to path leading to accepting state, including accepting state
            path = self.findpath([ac])[0][1]
            for point in path:
                if list(self.obs_check([q_new], point[0], self.tree.nodes[point]['label']).values())[0] \
                        and self.checkTranB(q_new[1], label_new, point[1]):
                    self.goals.append(
                        (q_new, point,
                         ac))  # endpoint, middle point, accepting point

    def extend(self, q_new, near_v, label, obs_check, succ_list):
        """
        :param: q_new: new state form: tuple (mulp, buchi)
        :param: near_v: near state form: tuple (mulp, buchi)
        :param: obs_check: check obstacle free  form: dict { (mulp, mulp): True }
        :param: succ: list of successor of the root
        :return: extending the tree
        """
        added = 0
        cost = np.inf
        q_min = ()
        for near_vertex in near_v:
            if near_vertex in succ_list:  # do not extend if there is a corresponding root
                continue
            if q_new != near_vertex and obs_check[(q_new[0], near_vertex[0])] \
                    and self.checkTranB(near_vertex[1], self.tree.nodes[near_vertex]['label'], q_new[1]):
                c = self.tree.nodes[near_vertex]['cost'] + \
                    np.linalg.norm(np.subtract(q_new[0], near_vertex[0]))
                if c < cost:
                    added = 1
                    q_min = near_vertex
                    cost = c
        if added == 1:
            self.tree.add_node(q_new, cost=cost, label=label)
            self.tree.nodes[q_new]['acc'] = set(
                self.acpt_check(q_min, q_new)[0])
            self.tree.add_edge(q_min, q_new)
            # self.search_goal(q_new, label, self.tree.nodes[q_new]['acc'])
        return added

    def rewire(self, q_new, near_v, obs_check):
        """
        :param: q_new: new state form: tuple (mul, buchi)
        :param: near_v: near state form: tuple (mul, buchi)
        :param: obs_check: check obstacle free form: dict { (mulp, mulp): True }
        :return: rewiring the tree
        """
        for near_vertex in near_v:
            if obs_check[(q_new[0], near_vertex[0])] \
                    and self.checkTranB(q_new[1], self.tree.nodes[q_new]['label'], near_vertex[1]):
                c = self.tree.nodes[q_new]['cost'] \
                    + np.linalg.norm(np.subtract(q_new[0], near_vertex[0]))
                delta_c = self.tree.nodes[near_vertex]['cost'] - c
                # update the cost of node in the subtree rooted at near_vertex
                if delta_c > 0:
                    # self.tree.nodes[near_vertex]['cost'] = c
                    self.tree.remove_edge(
                        list(self.tree.pred[near_vertex].keys())[0],
                        near_vertex)
                    self.tree.add_edge(q_new, near_vertex)
                    edges = dfs_labeled_edges(self.tree, source=near_vertex)
                    acc, changed = self.acpt_check(q_new, near_vertex)
                    self.tree.nodes[near_vertex]['acc'] = set(acc)
                    for u, v, d in edges:
                        if d == 'forward':
                            self.tree.nodes[v][
                                'cost'] = self.tree.nodes[v]['cost'] - delta_c
                            if changed:
                                self.tree.nodes[v]['acc'] = set(
                                    self.acpt_check(u, v)[0])  # copy
        # better to research the goal but abandon the implementation

    def near(self, x_new):
        """
        find the states in the near ball
        :param x_new: new point form: single point
        :return: p_near: near state, form: tuple (mulp, buchi)
        """
        p_near = []
        r = min(
            self.gamma * np.power(
                np.log(self.tree.number_of_nodes() + 1) /
                self.tree.number_of_nodes(), 1. / (self.dim * self.robot)),
            self.step_size)
        # r = self.step_size
        for vertex in self.tree.nodes:
            if np.linalg.norm(np.subtract(x_new, vertex[0])) <= r:
                p_near.append(vertex)
        return p_near

    def obs_check(self, q_near, x_new, label):
        """
        check whether obstacle free along the line from x_near to x_new
        :param q_near: states in the near ball, tuple (mulp, buchi)
        :param x_new: new state form: multiple point
        :param label: label of x_new
        :param stage: regular stage or final stage, deciding whether it's goal state
        :return: dict (x_near, x_new): true (obs_free)
        """

        obs_check_dict = {}
        checked = set()

        for x in q_near:
            if x[0] in checked:
                continue
            checked.add(x[0])
            obs_check_dict[(x_new, x[0])] = True

            # the line connecting two points crosses an obstacle
            for (obs, boundary) in iter(self.ts['obs'].items()):
                if LineString([Point(x[0]),
                               Point(x_new)]).intersects(boundary):
                    obs_check_dict[(x_new, x[0])] = False
                    break

            for (region, boundary) in iter(self.ts['region'].items()):
                if LineString([Point(x[0]), Point(x_new)]).intersects(boundary) \
                        and region + '_' + str(1) != label \
                        and region + '_' + str(1) != self.tree.nodes[x]['label']:
                    # if stage == 'reg' or (stage == 'final' and region in self.no):
                    obs_check_dict[(x_new, x[0])] = False
                    break

        return obs_check_dict

    def label(self, x):
        """
        generating the label of position state
        :param x: position
        :return: label
        """

        point = Point(x)
        # whether x lies within obstacle
        for (obs, boundary) in iter(self.ts['obs'].items()):
            if point.within(boundary):
                return obs

        # whether x lies within regions
        for (region, boundary) in iter(self.ts['region'].items()):
            if point.within(boundary):
                return region
        # x lies within unlabeled region
        return ''

    def checkTranB(self, b_state, x_label, q_b_new):
        """ decide valid transition, whether b_state --L(x)---> q_b_new
             Algorithm2 in Chapter 2 Motion and Task Planning
             :param b_state: buchi state
             :param x_label: label of x
             :param q_b_new buchi state
             :return True satisfied
        """
        b_state_succ = self.buchi_graph.succ[b_state]
        # q_b_new is not the successor of b_state
        if q_b_new not in b_state_succ:
            return False

        truth = self.buchi_graph.edges[(b_state, q_b_new)]['truth']
        if self.t_satisfy_b_truth(x_label, truth):
            return True

        return False

    def t_satisfy_b_truth(self, x_label, truth):
        """
        check whether transition enabled under current label
        :param x_label: current label
        :param truth: truth value making transition enabled
        :return: true or false
        """
        if truth == '1':
            return True

        true_label = [
            truelabel for truelabel in truth.keys() if truth[truelabel]
        ]
        for label in true_label:
            if label not in x_label:
                return False

        false_label = [
            falselabel for falselabel in truth.keys() if not truth[falselabel]
        ]
        for label in false_label:
            if label in x_label:
                return False

        return True

    def findpath(self, goals):
        """
        find the path backwards
        :param goals: goal state
        :return: dict path : cost
        """
        paths = OrderedDict()
        for i in range(len(goals)):
            goal = goals[i]
            path = [goal]
            s = goal
            while s != self.init:
                s = list(self.tree.pred[s].keys())[0]
                if s == path[0]:
                    print("loop")
                path.insert(0, s)

            paths[i] = [self.tree.nodes[goal]['cost'], path]
        return paths
Beispiel #39
0
class BoardGraph(object):
    def __init__(self, board_class=Board):
        self.graph = self.start = self.last = self.closest = None
        self.min_domino_count = None
        self.board_class = board_class

    def walk(self, board, size_limit=maxsize):
        pending_nodes = []
        self.graph = DiGraph()
        self.start = board.display(cropped=True)
        self.graph.add_node(self.start)
        pending_nodes.append(self.start)
        self.last = self.start
        while pending_nodes:
            if len(self.graph) >= size_limit:
                raise GraphLimitExceeded(size_limit)
            state = pending_nodes.pop()
            board = self.board_class.create(state, border=1)
            for move, new_state in self.generate_moves(board):
                if not self.graph.has_node(new_state):
                    # new node
                    self.graph.add_node(new_state)
                    pending_nodes.append(new_state)
                self.graph.add_edge(state, new_state, move=move)
        return set(self.graph.nodes())

    def generate_moves(self, board):
        """ Generate all moves from the board's current state.

        :param Board board: the current state
        :return: a generator of (state, move_description) tuples
        """
        dominoes = set(board.dominoes)
        domino_count = len(dominoes)
        if self.min_domino_count is None or domino_count < self.min_domino_count:
            self.min_domino_count = domino_count
            self.last = board.display(cropped=True)
        for domino in dominoes:
            dx, dy = domino.direction
            yield from self.try_move(domino, dx, dy)
            yield from self.try_move(domino, -dx, -dy)

    def try_move(self, domino, dx, dy):
        try:
            new_state = self.move(domino, dx, dy)
            move = domino.describe_move(dx, dy)
            yield move, new_state
        except BadPositionError:
            pass

    def move(self, domino, dx, dy):
        """ Move a domino and calculate the new board state.

        Afterward, put the board back in its original state.
        @return: the new board state
        @raise BadPositionError: if the move is illegal
        """
        domino.move(dx, dy)
        try:
            board = domino.head.board
            if not board.isConnected():
                raise BadPositionError('Board is not connected.')
            if board.hasLoner():
                raise BadPositionError('Board has a lonely domino.')
            return board.display(cropped=True)
        finally:
            domino.move(-dx, -dy)

    def get_solution(self, return_partial=False):
        """ Find a solution from the graph of moves.

        @param return_partial: If True, a partial solution will be returned if no
        solution exists.
        @return: a list of strings describing each move. Each string is two
        digits describing the domino that moved plus a letter to show the
        direction.
        """
        solution = []
        goal = self.closest if return_partial else self.last or ''
        solution_nodes = shortest_path(self.graph, self.start, goal)
        for i in range(len(solution_nodes) - 1):
            source, target = solution_nodes[i:i + 2]
            solution.append(self.graph[source][target]['move'])
        return solution

    def get_choice_counts(self):
        solution_nodes = shortest_path(self.graph, self.start, self.last)
        return [len(self.graph[node]) for node in solution_nodes[:-1]]

    def get_average_choices(self):
        choices = self.get_choice_counts()
        return sum(choices) / float(len(choices)) if choices else maxsize

    def get_max_choices(self):
        choices = self.get_choice_counts()
        return max(choices) if choices else maxsize
Beispiel #40
0
class StadynaMcgAnalysis:
    def __init__(self):
        self.androGuardObjects = []
        
        self.nodes = {}
        self.nodes_id = {}
        self.entry_nodes = []
        self.G = DiGraph()
        
#         self.internal_methods = []
        #self.GI = DiGraph()
        
        
    def analyseFile(self, vmx, apk):
        vm = vmx.get_vm()
        self.androGuardObjects.append((apk, vm, vmx))

#         self.internal_methods.extend(vm.get_methods())
        
        #creating real internal nodes
        internal_called_methods = vmx.get_tainted_packages().stadyna_get_internal_called_methods()
        for method in internal_called_methods:
            class_name, method_name, descriptor = method
            
            nodeType = None
            if method_name == "<clinit>":
                nodeType = NODE_STATIC_INIT
            elif method_name == "<init>":
                nodeType = NODE_CONSTRUCTOR
            else:
                nodeType = NODE_METHOD
            n = self._get_node(nodeType, (class_name, method_name, descriptor))
            n.set_attribute(ATTR_CLASS_NAME, class_name)
            n.set_attribute(ATTR_METHOD_NAME, method_name)
            n.set_attribute(ATTR_DESCRIPTOR, descriptor)
            self.G.add_node(n.id)
            
        
        
        
        #creating real edges (nodes are already there)
        #currently we are working only with internal packages.
        for j in vmx.get_tainted_packages().get_internal_packages():
            src_class_name, src_method_name, src_descriptor = j.get_src(vm.get_class_manager())
            dst_class_name, dst_method_name, dst_descriptor = j.get_dst(vm.get_class_manager())
             
            n1 = self._get_existed_node((src_class_name, src_method_name, src_descriptor))
#             n1.set_attribute(ATTR_CLASS_NAME, src_class_name)
#             n1.set_attribute(ATTR_METHOD_NAME, src_method_name)
#             n1.set_attribute(ATTR_DESCRIPTOR, src_descriptor)
             
            n2 = self._get_existed_node((dst_class_name, dst_method_name, dst_descriptor))
#             n2.set_attribute(ATTR_CLASS_NAME, dst_class_name)
#             n2.set_attribute(ATTR_METHOD_NAME, dst_method_name)
#             n2.set_attribute(ATTR_DESCRIPTOR, dst_descriptor)
            self.G.add_edge(n1.id, n2.id)
        
        
        
        #adding fake class nodes    
        for method in internal_called_methods:
            src_class_name, src_method_name, src_descriptor = method
            if src_method_name == "<init>" or src_method_name == "<clinit>":
                n1 = self._get_existed_node((src_class_name, src_method_name, src_descriptor))
                n2 = self._get_node(NODE_FAKE_CLASS, src_class_name, None, False)
                n2.set_attribute(ATTR_CLASS_NAME, src_class_name)
                if src_method_name == "<clinit>":
                    self.G.add_edge(n1.id, n2.id)
                elif src_method_name == "<init>":
                    self.G.add_edge(n2.id, n1.id)
                
        
        #real (external) reflection invoke nodes    
        reflection_invoke_paths = analysis.seccon_get_invoke_method_paths(vmx)
        for j in reflection_invoke_paths:
            src_class_name, src_method_name, src_descriptor = j.get_src( vm.get_class_manager() )
            dst_class_name, dst_method_name, dst_descriptor = j.get_dst( vm.get_class_manager() )
            
            n1 = self._get_existed_node((src_class_name, src_method_name, src_descriptor))
            if n1 == None:
                logger.warning("Cannot find the node [%s], where reflection invoke is called!" % (src_class_name, src_method_name, src_descriptor))
                continue
            
            key = "%s %s %s %s %s %s %s" % (src_class_name, src_method_name, src_descriptor, dst_class_name, dst_method_name, dst_descriptor, POSTFIX_REFL_INVOKE)
            n2 = self._get_node(NODE_REFL_INVOKE, key, LABEL_REFL_INVOKE, True)
            n2.set_attribute(ATTR_CLASS_NAME, src_class_name)
            n2.set_attribute(ATTR_METHOD_NAME, src_method_name)
            n2.set_attribute(ATTR_DESCRIPTOR, src_descriptor)
            
            self.G.add_edge( n1.id, n2.id )
            
        
        #real (external) reflection new instance nodes   
        reflection_newInstance_paths = analysis.seccon_get_newInstance_method_paths(vmx)
        for j in reflection_newInstance_paths:
            src_class_name, src_method_name, src_descriptor = j.get_src( vm.get_class_manager() )
            dst_class_name, dst_method_name, dst_descriptor = j.get_dst( vm.get_class_manager() )
            
            n1 = self._get_existed_node((src_class_name, src_method_name, src_descriptor))
            if n1 == None:
                logger.warning("Cannot find the node [%s], where reflection new instance is called!" % (src_class_name, src_method_name, src_descriptor))
                continue
            
            key = "%s %s %s %s %s %s %s" % (src_class_name, src_method_name, src_descriptor, dst_class_name, dst_method_name, dst_descriptor, POSTFIX_REFL_NEWINSTANCE)
            n2 = self._get_node(NODE_REFL_NEWINSTANCE, key, LABEL_REFL_NEWINSTANCE, True)
            n2.set_attribute(ATTR_CLASS_NAME, src_class_name)
            n2.set_attribute(ATTR_METHOD_NAME, src_method_name)
            n2.set_attribute(ATTR_DESCRIPTOR, src_descriptor)
            
            self.G.add_edge( n1.id, n2.id )
        
        
        #adding fake entry points
        if apk != None:
            for i in apk.get_activities() :
                j = bytecode.FormatClassToJava(i)
                n1 = self._get_existed_node((j, "onCreate", "(Landroid/os/Bundle;)V"))
                if n1 != None: 
                    key = "%s %s %s %s" % (j, "onCreate", "(Landroid/os/Bundle;)V", POSTFIX_ACTIVITY)
                    n2 = self._get_node(NODE_FAKE_ACTIVITY, key, LABEL_ACTIVITY, False)
                    self.G.add_edge( n2.id, n1.id )
                    self.entry_nodes.append( n1.id )
                    
            for i in apk.get_services() :
                j = bytecode.FormatClassToJava(i)
                n1 = self._get_existed_node( (j, "onCreate", "()V") )
                if n1 != None : 
                    key = "%s %s %s %s" % (j, "onCreate", "()V", POSTFIX_SERVICE)
                    n2 = self._get_node(NODE_FAKE_SERVICE, key, LABEL_SERVICE, False)
                    self.G.add_edge( n2.id, n1.id )
                    self.entry_nodes.append( n1.id )
            
            for i in apk.get_receivers() :
                j = bytecode.FormatClassToJava(i)
                n1 = self._get_existed_node( (j, "onReceive", "(Landroid/content/Context;Landroid/content/Intent;)V") )
                if n1 != None : 
                    key = "%s %s %s %s" % (j, "onReceive", "(Landroid/content/Context;Landroid/content/Intent;)V", POSTFIX_RECEIVER)
                    n2 = self._get_node(NODE_FAKE_SERVICE, key, LABEL_RECEIVER, False)
                    self.G.add_edge( n2.id, n1.id )
                    self.entry_nodes.append( n1.id )

        
        #fake permissions
        list_permissions = vmx.stadyna_get_permissions([])
        for x in list_permissions:
            for j in list_permissions[x]:
                if isinstance(j, PathVar):
                    continue

                src_class_name, src_method_name, src_descriptor = j.get_src( vm.get_class_manager() )
                dst_class_name, dst_method_name, dst_descriptor = j.get_dst( vm.get_class_manager() )
                
                n1 = self._get_existed_node((src_class_name, src_method_name, src_descriptor))
                if n1 == None:
                    logger.warning("Cannot find node [%s %s %s] for permission [%s]!" % (src_class_name, src_method_name, src_descriptor, x))
                    continue
                
                #SOURCE, DEST, POSTFIX, PERMISSION_NAME
                key = "%s %s %s %s %s %s %s %s" %  (src_class_name, src_method_name, src_descriptor, dst_class_name, dst_method_name, dst_descriptor, POSTFIX_PERM, x)
                n2 = self._get_node(NODE_FAKE_PERMISSION, key, x, False)
                n2.set_attribute(ATTR_CLASS_NAME, dst_class_name)
                n2.set_attribute(ATTR_METHOD_NAME, dst_method_name)
                n2.set_attribute(ATTR_DESCRIPTOR, dst_descriptor)
                n2.set_attribute(ATTR_PERM_NAME, x)
                n2.set_attribute(ATTR_PERM_LEVEL, MANIFEST_PERMISSIONS[ x ][0])
                
                self.G.add_edge(n1.id, n2.id)
                                

        #fake DexClassLoader nodes
        dyn_code_loading = analysis.seccon_get_dyncode_loading_paths(vmx)
        for j in dyn_code_loading:
            src_class_name, src_method_name, src_descriptor = j.get_src( vm.get_class_manager() )
            dst_class_name, dst_method_name, dst_descriptor = j.get_dst( vm.get_class_manager() )
            
            n1 = self._get_existed_node((src_class_name, src_method_name, src_descriptor))
            if n1 == None:
                logger.warning("Cannot find dexload node [%s]!" % (src_class_name, src_method_name, src_descriptor))
                continue
            
            key = "%s %s %s %s %s %s %s" % (src_class_name, src_method_name, src_descriptor, dst_class_name, dst_method_name, dst_descriptor, POSTFIX_DEXLOAD)
            n2 = self._get_node(NODE_FAKE_DEXLOAD, key, LABEL_DEXLOAD, False)
            n2.set_attribute(ATTR_CLASS_NAME, src_class_name)
            n2.set_attribute(ATTR_METHOD_NAME, src_method_name)
            n2.set_attribute(ATTR_DESCRIPTOR, src_descriptor)
            
            self.G.add_edge( n1.id, n2.id )
        
        
        
        # Specific Java/Android library
        for c in vm.get_classes():
            #if c.get_superclassname() == "Landroid/app/Service;" :
            #    n1 = self._get_node( c.get_name(), "<init>", "()V" )
            #    n2 = self._get_node( c.get_name(), "onCreate", "()V" )

            #    self.G.add_edge( n1.id, n2.id )
            if c.get_superclassname() == "Ljava/lang/Thread;" or c.get_superclassname() == "Ljava/util/TimerTask;" :
                for i in vm.get_method("run") :
                    if i.get_class_name() == c.get_name() :
                        n1 = self._get_node(NODE_METHOD, (i.get_class_name(), i.get_name(), i.get_descriptor()))
                        n2 = self._get_node(NODE_METHOD, (i.get_class_name(), "start", i.get_descriptor())) 
                       
                        # link from start to run
                        self.G.add_edge( n2.id, n1.id )
                        #n2.add_edge( n1, {} )

                        # link from init to start
                        for init in vm.get_method("<init>") :
                            if init.get_class_name() == c.get_name():
                                #TODO: Leaving _get_existed_node to check if all the nodes are included
                                #It is possible that internal_packages does not contain this node. Leaving _get_existed_node to check this
                                n3 = self._get_node(NODE_CONSTRUCTOR, (init.get_class_name(), "<init>", init.get_descriptor()))
                                self.G.add_edge( n3.id, n2.id )
                                #n3.add_edge( n2, {} )
        
                        
                        
    def addInvokePath(self, src, through, dst):
        src_class_name, src_method_name, src_descriptor = src
        dst_class_name, dst_method_name, dst_descriptor = dst
        through_class_name, through_method_name, through_descriptor = through
        key = "%s %s %s %s %s %s %s" % (src_class_name, src_method_name, src_descriptor, through_class_name, through_method_name, through_descriptor, POSTFIX_REFL_INVOKE)
        n1 = self._get_existed_node(key)
        if n1 == None:
            logger.warning("Something wrong has happened! Could not find invoke Node in Graph with key [%s]" % str(key))
            return
        
        n2 = self._get_node(NODE_METHOD, (dst_class_name, dst_method_name, dst_descriptor))
        n2.set_attribute(ATTR_CLASS_NAME, dst_class_name)
        n2.set_attribute(ATTR_METHOD_NAME, dst_method_name)
        n2.set_attribute(ATTR_DESCRIPTOR, dst_descriptor)
        
        self.G.add_edge(n1.id, n2.id)
        
        #check if called method calls protected feature
        data = "%s-%s-%s" % (dst_class_name, dst_method_name, dst_descriptor)
        if data in DVM_PERMISSIONS_BY_API_CALLS:
            logger.info("BINGOOOOOOO! The protected method is called through reflection!")
            perm = DVM_PERMISSIONS_BY_API_CALLS[ data ]
            key1 = "%s %s %s %s %s %s %s %s" %  (through_class_name, through_method_name, through_descriptor, dst_class_name, dst_method_name, dst_descriptor, POSTFIX_PERM, perm)
            n3 = self._get_node(NODE_FAKE_PERMISSION, key1, perm, False)
            n3.set_attribute(ATTR_CLASS_NAME, dst_class_name)
            n3.set_attribute(ATTR_METHOD_NAME, dst_method_name)
            n3.set_attribute(ATTR_DESCRIPTOR, dst_descriptor)
            n3.set_attribute(ATTR_PERM_NAME, perm)
            n3.set_attribute(ATTR_PERM_LEVEL, MANIFEST_PERMISSIONS[ perm ][0])
            self.G.add_edge(n2.id, n3.id)
            

        
            
    def addNewInstancePath(self, src, through, dst):
        src_class_name, src_method_name, src_descriptor = src
        dst_class_name, dst_method_name, dst_descriptor = dst
        through_class_name, through_method_name, through_descriptor = through
        key = "%s %s %s %s %s %s %s" % (src_class_name, src_method_name, src_descriptor, through_class_name, through_method_name, through_descriptor, POSTFIX_REFL_NEWINSTANCE)
        n1 = self._get_existed_node(key)
        if n1 == None:
            logger.error("Something wrong has happened! Could not find Node in Graph with key [%s]" % str(key))
            return
        
        n2 = self._get_node(NODE_CONSTRUCTOR, (dst_class_name, dst_method_name, dst_descriptor))
        n2.set_attribute(ATTR_CLASS_NAME, dst_class_name)
        n2.set_attribute(ATTR_METHOD_NAME, dst_method_name)
        n2.set_attribute(ATTR_DESCRIPTOR, dst_descriptor) 
        
        self.G.add_edge(n1.id, n2.id)
        
        #we also need to add link to the class node
        #TODO: Think in the future what to do with this
        n_class = self._get_node(NODE_FAKE_CLASS, dst_class_name, None, False)
        n_class.set_attribute(ATTR_CLASS_NAME, dst_class_name)
        self.G.add_edge(n_class.id, n2.id)
        
        #checking if we need to add additional permission nodes
        data = "%s-%s-%s" % (dst_class_name, dst_method_name, dst_descriptor)
        if data in DVM_PERMISSIONS_BY_API_CALLS:
            logger.info("BINGOOOOOOO! The protected method is called through reflection!")
            perm = DVM_PERMISSIONS_BY_API_CALLS[ data ]
            key1 = "%s %s %s %s %s %s %s %s" %  (through_class_name, through_method_name, through_descriptor, dst_class_name, dst_method_name, dst_descriptor, POSTFIX_PERM, perm)
            n3 = self._get_node(NODE_FAKE_PERMISSION, key1, perm, False)
            n3.set_attribute(ATTR_CLASS_NAME, dst_class_name)
            n3.set_attribute(ATTR_METHOD_NAME, dst_method_name)
            n3.set_attribute(ATTR_DESCRIPTOR, dst_descriptor)
            n3.set_attribute(ATTR_PERM_NAME, perm)
            n3.set_attribute(ATTR_PERM_LEVEL, MANIFEST_PERMISSIONS[ perm ][0])
            self.G.add_edge(n2.id, n3.id)
        
            
    def addDexloadPath(self, src, through, filename):
        src_class_name, src_method_name, src_descriptor = src
        through_class_name, through_method_name, through_descriptor = through
        key = "%s %s %s %s %s %s %s" % (src_class_name, src_method_name, src_descriptor,  through_class_name, through_method_name, through_descriptor, POSTFIX_DEXLOAD)
        n1 = self._get_existed_node(key)
        if n1 == None:
            logger.error("Something wrong has happened! Could not find Node in Graph with key [%s]" % str(key))
            return
        
        n2 = self._get_node(NODE_FAKE_DEXLOAD_FILE, filename, filename, False)
        n2.set_attribute(ATTR_DEXLOAD_FILENAME, filename)
        
        self.G.add_edge(n1.id, n2.id)
        
    

    def _get_node(self, nType, key, label=None, real=True):
        node_key = None
        if isinstance(key, basestring):
            node_key = key
        elif isinstance(key, tuple):
            node_key = "%s %s %s" % key
        else:
            logger.error("Unknown instance type of key!!!")
        
        if node_key not in self.nodes.keys():
            new_node = NodeS(len(self.nodes), nType, node_key, label, real)
            self.nodes[node_key] = new_node
            self.nodes_id[new_node.id] = new_node
        
        return self.nodes[node_key]
    
    
    def _get_existed_node(self, key):
        node_key = None
        if isinstance(key, basestring):
            node_key = key
        elif isinstance(key, tuple):
            node_key = "%s %s %s" % key
        else:
            logger.error("Unknown instance type of key!!!")
        
        try:
            return self.nodes[node_key]
        except KeyError:
            logger.error("Could not find existed node [%s]!" % node_key)
            return None

    def export_to_gexf(self) :
        buff = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
        buff += "<gexf xmlns=\"http://www.gephi.org/gexf\" xmlns:viz=\"http://www.gephi.org/gexf/viz\">\n"
        buff += "<graph type=\"static\">\n"

        buff += "<attributes class=\"node\" type=\"static\">\n"
        buff += "<attribute title=\"%s\" id=\"%d\" type=\"string\"/>\n" % (ATTR_TYPE,              ID_ATTRIBUTES[ ATTR_TYPE ])
        buff += "<attribute title=\"%s\" id=\"%d\" type=\"string\"/>\n" % (ATTR_CLASS_NAME,        ID_ATTRIBUTES[ ATTR_CLASS_NAME ])
        buff += "<attribute title=\"%s\" id=\"%d\" type=\"string\"/>\n" % (ATTR_METHOD_NAME,       ID_ATTRIBUTES[ ATTR_METHOD_NAME ])
        buff += "<attribute title=\"%s\" id=\"%d\" type=\"string\"/>\n" % (ATTR_DESCRIPTOR,        ID_ATTRIBUTES[ ATTR_DESCRIPTOR ])
        buff += "<attribute title=\"%s\" id=\"%d\" type=\"string\"/>\n" % (ATTR_REAL,              ID_ATTRIBUTES[ ATTR_REAL ])
        buff += "<attribute title=\"%s\" id=\"%d\" type=\"string\"/>\n" % (ATTR_PERM_NAME,         ID_ATTRIBUTES[ ATTR_PERM_NAME ])
        buff += "<attribute title=\"%s\" id=\"%d\" type=\"string\"/>\n" % (ATTR_PERM_LEVEL,        ID_ATTRIBUTES[ ATTR_PERM_LEVEL ])
        buff += "<attribute title=\"%s\" id=\"%d\" type=\"string\"/>\n" % (ATTR_DEXLOAD_FILENAME,  ID_ATTRIBUTES[ ATTR_DEXLOAD_FILENAME ])
        buff += "</attributes>\n"

#         buff += "<attributes class=\"node\" type=\"static\">\n" 
#         buff += "<attribute id=\"%d\" title=\"type\" type=\"string\" default=\"normal\"/>\n" % ID_ATTRIBUTES[ "type"]
#         buff += "<attribute id=\"%d\" title=\"class_name\" type=\"string\"/>\n" % ID_ATTRIBUTES[ "class_name"]
#         buff += "<attribute id=\"%d\" title=\"method_name\" type=\"string\"/>\n" % ID_ATTRIBUTES[ "method_name"]
#         buff += "<attribute id=\"%d\" title=\"descriptor\" type=\"string\"/>\n" % ID_ATTRIBUTES[ "descriptor"]
# 
# 
#         buff += "<attribute id=\"%d\" title=\"permissions\" type=\"integer\" default=\"0\"/>\n" % ID_ATTRIBUTES[ "permissions"]
#         buff += "<attribute id=\"%d\" title=\"permissions_level\" type=\"string\" default=\"normal\"/>\n" % ID_ATTRIBUTES[ "permissions_level"]
#         
#         buff += "<attribute id=\"%d\" title=\"dynamic_code\" type=\"boolean\" default=\"false\"/>\n" % ID_ATTRIBUTES[ "dynamic_code"]
#         
#         buff += "</attributes>\n"   

        buff += "<nodes>\n"
        for node in self.G.nodes() :
            buff += "<node id=\"%d\" label=\"%s\">\n" % (node, escape(self.nodes_id[ node ].label))
            buff += self.nodes_id[ node ].get_attributes_gexf()
            buff += "</node>\n"
        buff += "</nodes>\n"


        buff += "<edges>\n"
        nb = 0
        for edge in self.G.edges() :
            buff += "<edge id=\"%d\" source=\"%d\" target=\"%d\"/>\n" % (nb, edge[0], edge[1])
            nb += 1
        buff += "</edges>\n"


        buff += "</graph>\n"
        buff += "</gexf>\n"

        return buff
  
    
    def get_current_real_node_count(self):
        count = 0
        for node in self.nodes_id.keys():
            if self.nodes_id[node].get_attribute(ATTR_REAL) == "True":
                count += 1
        return count

    def get_current_node_count(self):
        return len(self.G.nodes())
    
    def get_current_edge_count(self):
        return len(self.G.edges())
    
    def get_current_permission_level_node_count(self, permission_level):
        count = 0
        for node in self.nodes_id.keys():
            if self.nodes_id[node].get_attribute(ATTR_PERM_LEVEL) == permission_level:
                count += 1
        return count
    
    def get_current_protected_node_count(self):
        count = 0
        for node in self.nodes_id.keys():
            if self.nodes_id[node].get_attribute(ATTR_PERM_LEVEL) != None:
                count += 1
        return count
Beispiel #41
0
def find_MECs(mdp, Sneg):
    #----implementation of Alg.47 P866 of Baier08----
    print 'Remaining states size', len(Sneg)
    U = mdp.graph['U']
    A = dict()
    for s in Sneg:
        A[s] = mdp.node[s]['act'].copy()
        if not A[s]:
            print "Isolated state"
    MEC = set()
    MECnew = set()
    MECnew.add(frozenset(Sneg))
    #----
    k = 0
    while MEC != MECnew:
        print "<============iteration %s============>" %k
        k +=1
        MEC = MECnew
        MECnew = set()
        print "MEC size: %s" %len(MEC)
        print "MECnew size: %s" %len(MECnew)
        for T in MEC:
            R = set()
            T_temp = set(T)
            simple_digraph = DiGraph()
            for s_f in T_temp:
                if s_f not in simple_digraph:
                    simple_digraph.add_node(s_f)
                for s_t in mdp.successors_iter(s_f):
                    if s_t in T_temp:
                        simple_digraph.add_edge(s_f,s_t)
            print "SubGraph of one MEC: %s states and %s edges" %(str(len(simple_digraph.nodes())), str(len(simple_digraph.edges())))
            Sccs = strongly_connected_component_subgraphs(simple_digraph)
            i = 0
            for Scc in Sccs:
                i += 1
                if (len(Scc.edges())>=1):
                    for s in Scc.nodes():
                        U_to_remove = set() 
                        for u in A[s]:
                            for t in mdp.successors_iter(s):
                                if ((u  in mdp.edge[s][t]['prop'].keys()) and (t not in Scc.nodes())):
                                    U_to_remove.add(u)
                        A[s].difference_update(U_to_remove)
                        if not A[s]:                            
                            R.add(s)
            while R:
                s = R.pop()
                T_temp.remove(s)
                for f in mdp.predecessors(s):
                    if f in T_temp:
                        A[f].difference_update(set(mdp.edge[f][s]['prop'].keys()))
                        if not A[f]:
                            R.add(f)
            New_Sccs = strongly_connected_component_subgraphs(simple_digraph)
            j = 0
            for Scc in New_Sccs:
                j += 1
                if (len(Scc.edges()) >= 1):
                    common = set(Scc.nodes()).intersection(T_temp)
                    if common:
                        MECnew.add(frozenset(common))
    #---------------
    print 'Final MEC and MECnew size:', len(MEC)
    return MEC, A
Beispiel #42
0
class Program:
    def __init__(self, rules):
        self.rules = rules
        self.predicate_names = None
        self.predicate_deps_graph = None
        assert (self.is_stratified())

    def get_rules(self):
        return self.rules

    def get_derivation_rules(self):
        return [rule for rule in self.rules if not rule.is_type_rule]

    def get_type_rules(self):
        return [rule for rule in self.rules if rule.is_type_rule]

    def get_predicate_names(self):
        if self.predicate_names != None:
            return self.predicate_names

        self.predicate_names = set()
        for rule in self.get_derivation_rules():
            self.predicate_names.add(rule.head.name)
            for literal in rule.get_literals():
                self.predicate_names.add(literal.atom.name)
        return self.predicate_names

    def get_nonrecursive_idb_predicate_names(self):
        return self.extend_nonrecursive_idb_predicate_names(set())

    def get_recursive_idb_predicate_names(self):
        return self.get_idb_predicate_names(
        ) - self.get_nonrecursive_idb_predicate_names()

    def extend_nonrecursive_idb_predicate_names(self, cur_nonrecursive):
        extended_nonrecursive = set()
        for predicate_name in self.get_idb_predicate_names():
            if predicate_name in cur_nonrecursive:
                extended_nonrecursive.add(predicate_name)
                continue

            recursive = False
            for rule in self.get_rules_for_predicate(predicate_name):
                for literal in rule.get_literals():
                    literal_predicate_name = literal.atom.name
                    if literal_predicate_name not in self.get_edb_predicate_names(
                    ) and literal_predicate_name not in cur_nonrecursive:
                        recursive = True
            if not recursive:
                extended_nonrecursive.add(predicate_name)
        if cur_nonrecursive == extended_nonrecursive:
            return extended_nonrecursive
        else:
            return self.extend_nonrecursive_idb_predicate_names(
                extended_nonrecursive)

    def get_idb_predicate_names(self):
        idbs = set()
        for rule in self.get_derivation_rules():
            idbs.add(rule.head.name)
        return idbs

    def get_edb_predicate_names(self):
        return self.get_predicate_names() - self.get_idb_predicate_names()

    def predicate_depends_on(self, predicate_name1, predicate_name2):
        return has_path(self.get_predicate_deps_graph(), predicate_name2,
                        predicate_name1)

    def get_rules_for_predicate(self, predicate_name):
        rules = set()
        for rule in self.get_derivation_rules():
            if rule.head.name == predicate_name:
                rules.add(rule)
        return rules

    def get_predicate_deps_graph(self):
        if self.predicate_deps_graph != None:
            return self.predicate_deps_graph

        self.predicate_deps_graph = DiGraph()
        # add a node for each Predicate
        self.predicate_deps_graph.add_nodes_from(self.get_predicate_names())
        for predicate_name in self.get_predicate_names():
            for rule in self.get_rules_for_predicate(predicate_name):
                for literal in rule.get_literals():
                    self.predicate_deps_graph.add_edge(literal.atom.name,
                                                       predicate_name)
        return self.predicate_deps_graph

    def is_stratified(self):
        positivePredicateDeps = {}
        negativePredicateDeps = {}
        for predicate_name in self.get_predicate_names():
            positivePredicateDeps[predicate_name] = set()
            negativePredicateDeps[predicate_name] = set()
            for rule in self.get_rules_for_predicate(predicate_name):
                for literal in rule.get_literals():
                    if literal.negated:
                        negativePredicateDeps[predicate_name].add(
                            literal.atom.name)
                    else:
                        positivePredicateDeps[predicate_name].add(
                            literal.atom.name)
        for scc in strongly_connected_components(
                self.get_predicate_deps_graph()):
            for predicate_name in scc:
                if negativePredicateDeps[predicate_name].intersection(
                        set(scc)):
                    return False
        return True

    def is_recursive_predicate(self, predicate_name):
        for cyclic_predicates in simple_cycles(
                self.get_predicate_deps_graph()):
            if predicate_name in cyclic_predicates:
                return True
        return False