Exemplo n.º 1
0
class KamiGraph:
    """Graph container data structure.

    Attributes
    ----------
    graph : nx.(Di)Graph
        Graph
    meta_typing : dict
        Typing of the graph by the meta-model
    reference_typing : dict
        Typing of the graph by the reference graph
    """

    def __init__(self, graph=None, meta_typing=None,
                 reference_typing=None):
        """Initialize graph container."""
        if graph:
            self.graph = NXGraph.copy(graph)
        else:
            self.graph = NXGraph()

        if meta_typing:
            self.meta_typing = copy.deepcopy(meta_typing)
        else:
            self.meta_typing = dict()
        if reference_typing:
            self.reference_typing = copy.deepcopy(reference_typing)
        else:
            self.reference_typing = dict()
        return

    def add_node(self, node_id, attrs=None, meta_typing=None,
                 reference_typing=None):
        """Add node + typings to a nugget."""
        self.graph.add_node(node_id, attrs)
        if meta_typing:
            self.meta_typing[node_id] = meta_typing
        if reference_typing:
            self.reference_typing[node_id] = reference_typing
        return

    def add_node_attrs(self, node_id, attrs):
        self.graph.add_node_attrs(node_id, attrs)

    def add_edge(self, s, t, attrs=None):
        """Add edge between the nodes of a nugget."""
        self.graph.add_edge(s, t, attrs)
        return

    def remove_node(self, node_id):
        self.graph.remove_node(node_id)
        del self.meta_typing[node_id]
        if node_id in self.reference_typing:
            del self.reference_typing[node_id]

    def remove_node_attrs(self, node_id, attrs):
        self.graph.remove_node_attrs(node_id, attrs)

    def remove_edge(self, s, t):
        self.graph.remove_edge(s, t)

    def nodes(self):
        """Return a list of nodes of the nugget graph."""
        return self.graph.nodes()

    def edges(self):
        """Return a list of edges of the nugget graph."""
        return self.graph.edges()
Exemplo n.º 2
0
    def __init__(self):
        """Initialize hierarchies."""
        self.nx_hierarchy = NXHierarchy()
        try:
            self.neo4j_hierarchy = Neo4jHierarchy(uri="bolt://localhost:7687",
                                                  user="******",
                                                  password="******")
            self.neo4j_hierarchy._clear()
        except:
            warnings.warn("Neo4j is down, skipping Neo4j-related tests")
            self.neo4j_hierarchy = None

        g0 = NXGraph()
        g0.add_node("circle", {"a": {1, 2, 3}})
        g0.add_node("square", {"a": {1, 2, 3, 5}})
        g0.add_node("triangle", {"new_attrs": {1}})
        g0.add_edges_from([
            ("circle", "circle"),  # , {"b": {1, 2, 3, 4}}),
            ("circle", "square"),
            ("square", "circle", {
                "new_attrs": {2}
            }),
            ("square", "triangle", {
                "new_attrs": {3, 4}
            })
        ])
        self.nx_hierarchy.add_graph("g0", g0, {"name": "Shapes"})
        if self.neo4j_hierarchy:
            self.neo4j_hierarchy.add_graph("g0", g0, {"name": "Shapes"})

        g00 = NXGraph()
        g00.add_node('black', {"a": {1, 2, 3}, "new_attrs": {1}})
        g00.add_node('white', {"a": {1, 2, 3, 5}})
        g00.add_edges_from([('white', 'white', {
            "new_attrs": 2
        }), ('white', 'black', {
            "new_attrs": {4, 3}
        }), ('black', 'black'), ('black', 'white')])
        self.nx_hierarchy.add_graph("g00", g00, {"name": "Colors"})
        if self.neo4j_hierarchy:
            self.neo4j_hierarchy.add_graph("g00", g00, {"name": "Colors"})

        g1 = NXGraph()
        g1.add_nodes_from([("black_circle", {
            "a": {1, 2, 3}
        }), "white_circle", "black_square", ("white_square", {
            "a": {1, 2}
        }), "black_triangle", "white_triangle"])

        g1.add_edges_from([
            ("black_circle", "black_circle"),  # {"b": {1, 2, 3, 4}}),
            ("black_circle", "white_circle"),
            ("black_circle", "black_square"),
            ("white_circle", "black_circle"),
            ("white_circle", "white_square"),
            ("black_square", "black_circle"),
            ("black_square", "black_triangle"),
            ("black_square", "white_triangle"),
            ("white_square", "white_circle"),
            ("white_square", "black_triangle"),
            ("white_square", "white_triangle")
        ])

        self.nx_hierarchy.add_graph("g1", g1)
        if self.neo4j_hierarchy:
            self.neo4j_hierarchy.add_graph("g1", g1)
        self.nx_hierarchy.add_typing(
            "g1", "g0", {
                "black_circle": "circle",
                "white_circle": "circle",
                "black_square": "square",
                "white_square": "square",
                "black_triangle": "triangle",
                "white_triangle": "triangle"
            })
        if self.neo4j_hierarchy:
            self.neo4j_hierarchy.add_typing(
                "g1", "g0", {
                    "black_circle": "circle",
                    "white_circle": "circle",
                    "black_square": "square",
                    "white_square": "square",
                    "black_triangle": "triangle",
                    "white_triangle": "triangle"
                })

        self.nx_hierarchy.add_typing(
            "g1", "g00", {
                "black_square": "black",
                "black_circle": "black",
                "black_triangle": "black",
                "white_square": "white",
                "white_circle": "white",
                "white_triangle": "white"
            })
        if self.neo4j_hierarchy:
            self.neo4j_hierarchy.add_typing(
                "g1", "g00", {
                    "black_square": "black",
                    "black_circle": "black",
                    "black_triangle": "black",
                    "white_square": "white",
                    "white_circle": "white",
                    "white_triangle": "white"
                })

        g2 = NXGraph()
        g2.add_nodes_from([
            (1, {
                "a": {1, 2}
            }),
            2,
            3,
            4,
            (5, {
                "a": {1}
            }),
            6,
            7,
        ])

        g2.add_edges_from([
            (1, 2),  # {"b": {1, 2, 3}}),
            (2, 3),
            (3, 6),
            (3, 7),
            (4, 2),
            (4, 5),
            (5, 7)
        ])
        self.nx_hierarchy.add_graph("g2", g2)
        if self.neo4j_hierarchy:
            self.neo4j_hierarchy.add_graph("g2", g2)
        self.nx_hierarchy.add_typing(
            "g2", "g1", {
                1: "black_circle",
                2: "black_circle",
                3: "black_square",
                4: "white_circle",
                5: "white_square",
                6: "white_triangle",
                7: "black_triangle"
            })
        if self.neo4j_hierarchy:
            self.neo4j_hierarchy.add_typing(
                "g2", "g1", {
                    1: "black_circle",
                    2: "black_circle",
                    3: "black_square",
                    4: "white_circle",
                    5: "white_square",
                    6: "white_triangle",
                    7: "black_triangle"
                })

        g3 = NXGraph()
        g3.add_nodes_from([
            (1),  # {"a": {1, 2}}),
            2,
            3,
            5,
            (4),  # {"a": {1}}),
            6,
            7,
        ])

        g3.add_edges_from([
            (1, 1),  # , {"b": {1, 2, 3}}),
            (1, 2),
            (1, 3),
            (1, 5),
            (2, 1),
            (3, 4),
            (4, 7),
            (4, 6),
            (5, 6),
            (5, 7)
        ])
        self.nx_hierarchy.add_graph("g3", g3)
        if self.neo4j_hierarchy:
            self.neo4j_hierarchy.add_graph("g3", g3)
        self.nx_hierarchy.add_typing(
            "g3", "g1", {
                1: "black_circle",
                2: "white_circle",
                3: "white_circle",
                5: "black_square",
                4: "white_square",
                6: "white_triangle",
                7: "black_triangle"
            })
        if self.neo4j_hierarchy:
            self.neo4j_hierarchy.add_typing(
                "g3", "g1", {
                    1: "black_circle",
                    2: "white_circle",
                    3: "white_circle",
                    5: "black_square",
                    4: "white_square",
                    6: "white_triangle",
                    7: "black_triangle"
                })

        g4 = NXGraph()
        g4.add_nodes_from([1, 2, 3])
        g4.add_edges_from([(1, 2), (2, 3)])

        self.nx_hierarchy.add_graph("g4", g4)
        self.nx_hierarchy.add_typing("g4", "g2", {1: 2, 2: 3, 3: 6})
        self.nx_hierarchy.add_typing("g4", "g3", {1: 1, 2: 5, 3: 6})
        if self.neo4j_hierarchy:
            self.neo4j_hierarchy.add_graph("g4", g4)
            self.neo4j_hierarchy.add_typing("g4", "g2", {1: 2, 2: 3, 3: 6})
            self.neo4j_hierarchy.add_typing("g4", "g3", {1: 1, 2: 5, 3: 6})

        g5 = NXGraph()
        g5.add_nodes_from([
            ("black_circle"),  # {"a": {255}}),
            ("black_square"),  # {"a": {256}}),
            ("white_triangle"),  # {"a": {257}}),
            ("star")  # , {"a": {258}})
        ])
        g5.add_edges_from([
            ("black_circle", "black_square"),
            ("black_square", "white_triangle"),  # , {"b": {11}}),
            ("star", "black_square"),
            ("star", "white_triangle")
        ])

        self.nx_hierarchy.add_graph("g5", g5)
        if self.neo4j_hierarchy:
            self.neo4j_hierarchy.add_graph("g5", g5)
Exemplo n.º 3
0
    def __init__(self):
        D = NXGraph()

        D.add_node('square')
        D.add_node('circle')
        D.add_node('dark_square')
        D.add_node('dark_circle')
        D.add_edge('square', 'circle')
        D.add_edge('circle', 'dark_circle')
        D.add_edge('circle', 'dark_square')
        D.add_edge('circle', 'circle')

        self.D = D

        A = NXGraph()

        A.add_node(2)
        A.add_node(3)
        A.add_edge(2, 3)

        self.A = A

        B = NXGraph()

        B.add_node(1)
        B.add_node(2)
        B.add_node(3)
        B.add_edge(1, 2)
        B.add_edge(2, 3)

        self.B = B

        C = NXGraph()

        C.add_node(2)
        C.add_node(3)
        C.add_node('dark_square')

        C.add_edge(2, 3)
        C.add_edge(2, 'dark_square')
        C.add_edge(2, 2)

        self.C = C

        self.homAB = {
            2: 2,
            3: 3
        }
        self.homAC = {
            2: 2,
            3: 3
        }
        self.homBD = {
            1: 'square',
            2: 'circle',
            3: 'dark_circle'
        }

        self.homCD = {
            2: 'circle',
            3: 'dark_circle',
            'dark_square': 'dark_square'
        }
Exemplo n.º 4
0
    def test_graph_rollback(self):
        g = VersionedGraph(self.initial_graph)

        # Branch 'test'
        g.branch("test")

        pattern = NXGraph()
        pattern.add_node("square")
        rule = Rule.from_transform(pattern)
        # _, rhs_clone =
        rule.inject_clone_node("square")
        g.rewrite(
            rule, {"square": "square"},
            "Clone square")

        # Switch to master
        g.switch_branch("master")

        print("\n\n\nasserting...............")
        for s, t in g._revision_graph.edges():
            print(g._revision_graph.nodes[s]["message"])
            print(g._revision_graph.nodes[t]["message"])
            d = g._revision_graph.adj[s][t]["delta"]
            assert(
                set(d["rule"].rhs.nodes()) ==
                set(d["rhs_instance"].keys())
            )

        # Add edge and triangle
        pattern = NXGraph()
        pattern.add_nodes_from(["circle"])
        rule = Rule.from_transform(pattern)
        # _, rhs_clone =
        rule.inject_add_edge("circle", "circle")
        rule.inject_add_node("triangle")
        rule.inject_add_edge("triangle", "circle")
        rhs_instance, _ = g.rewrite(
            rule, {"circle": "circle"},
            "Add edge to circle and triangle")
        triangle = rhs_instance["triangle"]

        # Clone circle
        pattern = NXGraph()
        pattern.add_node("circle")
        rule = Rule.from_transform(pattern)
        _, rhs_clone = rule.inject_clone_node("circle")

        rhs_instance, rollback_commit = g.rewrite(
            rule, {"circle": "circle"},
            "Clone circle")

        rhs_circle_clones = list({
            rule.p_rhs[p] for p in rule.cloned_nodes()["circle"]
        })

        # Remove original circle
        pattern = NXGraph()
        pattern.add_node("circle")
        rule = Rule.from_transform(pattern)
        rule.inject_remove_node("circle")

        rhs_instance, _ = g.rewrite(
            rule,
            {"circle": rhs_instance[rhs_circle_clones[0]]},
            message="Remove circle")

        # Merge circle clone and triangle
        pattern = NXGraph()
        pattern.add_nodes_from(["circle", "triangle"])
        rule = Rule.from_transform(pattern)
        rule.inject_merge_nodes(["circle", "triangle"])

        rhs_instance, _ = g.rewrite(
            rule,
            {
                "circle": rhs_instance[rhs_clone],
                "triangle": triangle
            },
            message="Merge circle and triangle")
        g.print_history()
        g.rollback(rollback_commit)

        g.merge_with("test")
Exemplo n.º 5
0
class TestGraphClasses:
    """Main test class."""
    def __init__(self):
        """Initialize test object."""
        self.nx_graph = NXGraph()
        try:
            self.neo4j_graph = Neo4jGraph(uri="bolt://localhost:7687",
                                          user="******",
                                          password="******")
            self.neo4j_graph._clear()
        except:
            warnings.warn("Neo4j is down, skipping Neo4j-related tests")
            self.neo4j_graph = None

        node_list = [("b", {
            "name": "Bob",
            "age": 20
        }), ("a", {
            "name": "Alice",
            "age": 35
        }), ("d", {
            "name": "dummy"
        })]

        edge_list = [("a", "b", {
            "type": "friends",
            "since": 1999
        }), ("d", "a"), ("b", "d")]

        self.nx_graph.add_nodes_from(node_list)
        self.nx_graph.add_edges_from(edge_list)

        if self.neo4j_graph:
            self.neo4j_graph.add_nodes_from(node_list)
            self.neo4j_graph.add_edges_from(edge_list)

        node = "c"
        attrs = {"name": "Claire", "age": 66}
        self.nx_graph.add_node(node, attrs)
        if self.neo4j_graph:
            self.neo4j_graph.add_node(node, attrs)
        edge_attrs = {"type": "parent"}
        self.nx_graph.add_edge("c", "b", edge_attrs)
        if self.neo4j_graph:
            self.neo4j_graph.add_edge("c", "b", edge_attrs)

        self.nx_graph.remove_edge("d", "a")
        if self.neo4j_graph:
            self.neo4j_graph.remove_edge("d", "a")
        self.nx_graph.remove_node("d")
        if self.neo4j_graph:
            self.neo4j_graph.remove_node("d")

        self.nx_graph.update_node_attrs("a", {"name": "Alison"})
        if self.neo4j_graph:
            self.neo4j_graph.update_node_attrs("a", {"name": "Alison"})
        self.nx_graph.update_edge_attrs("a", "b", {"type": "enemies"})
        if self.neo4j_graph:
            self.neo4j_graph.update_edge_attrs("a", "b", {"type": "enemies"})

        self.nx_graph.set_node_attrs("a", {"age": 19}, update=False)
        if self.neo4j_graph:
            self.neo4j_graph.set_node_attrs("a", {"age": 19}, update=False)
        self.nx_graph.set_edge_attrs("a", "b", {"since": 1945}, update=False)
        if self.neo4j_graph:
            self.neo4j_graph.set_edge_attrs("a",
                                            "b", {"since": 1945},
                                            update=False)

        self.nx_graph.add_node_attrs("a", {"gender": {"M", "F"}})
        if self.neo4j_graph:
            self.neo4j_graph.add_node_attrs("a", {"gender": {"M", "F"}})
        self.nx_graph.add_edge_attrs("a", "b", {"probability": 0.5})
        if self.neo4j_graph:
            self.neo4j_graph.add_edge_attrs("a", "b", {"probability": 0.5})

        self.nx_graph.remove_node_attrs("a", {"gender": "F"})
        if self.neo4j_graph:
            self.neo4j_graph.remove_node_attrs("a", {"gender": "F"})
        self.nx_graph.remove_edge_attrs("a", "b", {"probability": 0.5})
        if self.neo4j_graph:
            self.neo4j_graph.remove_edge_attrs("a", "b", {"probability": 0.5})

        clone_id = self.nx_graph.clone_node("b", "b_clone")
        if self.neo4j_graph:
            self.neo4j_graph.clone_node("b", "b_clone")

        # Test relabeling
        self.nx_graph.relabel_node("b", "baba")
        if self.neo4j_graph:
            self.neo4j_graph.relabel_node("b", "baba")
        self.nx_graph.relabel_node("baba", "b")
        if self.neo4j_graph:
            self.neo4j_graph.relabel_node("baba", "b")
        self.nx_graph.relabel_nodes({
            clone_id: "lala",
            "b": "b1",
            "a": "a1",
            "c": "c1"
        })
        if self.neo4j_graph:
            self.neo4j_graph.relabel_nodes({
                clone_id: "lala",
                "b": "b1",
                "a": "a1",
                "c": "c1"
            })
        self.nx_graph.relabel_nodes({
            "b1": "b",
            "a1": "a",
            "c1": "c",
            "lala": clone_id
        })
        if self.neo4j_graph:
            self.neo4j_graph.relabel_nodes({
                "b1": "b",
                "a1": "a",
                "c1": "c",
                "lala": clone_id
            })

        self.nx_graph.merge_nodes(["b", "c"])
        if self.neo4j_graph:
            self.neo4j_graph.merge_nodes(["b", "c"])

        self.nx_graph.copy_node("a", "a_copy")
        if self.neo4j_graph:
            self.neo4j_graph.copy_node("a", "a_copy")

        # Test find matching
        pattern = NXGraph()
        pattern.add_nodes_from(["x", ("y", {"name": "Claire"}), "z"])
        pattern.add_edges_from([("x", "y"), ("y", "y"), ("y", "z")])
        instances1 = self.nx_graph.find_matching(pattern)
        if self.neo4j_graph:
            instances2 = self.neo4j_graph.find_matching(pattern)
            assert (instances1 == instances2)

        rule = Rule.from_transform(pattern)
        p_n, r_n = rule.inject_clone_node("y")
        rule.inject_remove_edge(p_n, "y")
        rule.inject_remove_edge("y", "y")
        rule.inject_add_node("w", {"name": "Frank"})
        rule.inject_add_edge("w", r_n, {"type": "parent"})
        rhs_g1 = self.nx_graph.rewrite(rule, instances1[0])
        if self.neo4j_graph:
            rhs_g2 = self.neo4j_graph.rewrite(rule, instances1[0])

        self.nx_graph.relabel_node(rhs_g1[r_n], "b")
        if self.neo4j_graph:
            self.neo4j_graph.relabel_node(rhs_g2[r_n], "b")
        self.nx_graph.relabel_node(rhs_g1["y"], "c")
        if self.neo4j_graph:
            self.neo4j_graph.relabel_node(rhs_g2["y"], "c")
            # Test the two obtained graphs are the same
            assert (self.nx_graph == self.neo4j_graph)
            assert (set(self.nx_graph.predecessors("b")) == set(
                self.neo4j_graph.predecessors("b")))
            assert (set(self.nx_graph.successors("a")) == set(
                self.neo4j_graph.successors("a")))
            assert (
                self.nx_graph.get_node("c") == self.neo4j_graph.get_node("c"))
            assert (self.nx_graph.get_edge("c",
                                           "b") == self.neo4j_graph.get_edge(
                                               "c", "b"))

    def test_getters(self):
        """Test various getters."""
        if self.neo4j_graph:
            assert (set(self.nx_graph.nodes()) == set(
                self.neo4j_graph.nodes()))
            assert (set(self.nx_graph.edges()) == set(
                self.neo4j_graph.edges()))
            self.neo4j_graph.nodes(data=True)
            self.neo4j_graph.edges(data=True)
            assert (
                self.nx_graph.get_node("a") == self.neo4j_graph.get_node("a"))
            assert (self.nx_graph.get_edge("a",
                                           "b") == self.neo4j_graph.get_edge(
                                               "a", "b"))
            assert (set(self.nx_graph.in_edges("b")) == set(
                self.neo4j_graph.in_edges("b")))
            assert (set(self.nx_graph.out_edges("a")) == set(
                self.neo4j_graph.out_edges("a")))

    def test_load_export(self):
        self.nx_graph.export("nxgraph.json")
        if self.neo4j_graph:
            self.neo4j_graph.export("neo4jgraph.json")

        g1 = NXGraph.load("nxgraph.json")
        if self.neo4j_graph:
            p = Neo4jGraph(driver=self.neo4j_graph._driver,
                           node_label="new_node",
                           edge_label="new_edge")
            p._clear()
            g2 = Neo4jGraph.load(driver=self.neo4j_graph._driver,
                                 filename="neo4jgraph.json",
                                 node_label="new_node",
                                 edge_label="new_edge")
            assert (g1 == g2)