Пример #1
0
def node_to_mql(e, node, visited_nodes):
    mql_query = {}
    num_relations = 0
    visited_nodes.add(node)
    for relation, dest in e.iter_edges(node):
        if not dest in visited_nodes:
            relation = format_mql_uri(relation)
            if isnode(dest):
                dest_mql = node_to_mql(e, dest, visited_nodes)
                if type(dest_mql) == dict:
                    dest_mql = [dest_mql]
                mql_query[relation] = dest_mql
            else:
                mql_query[relation] = adapt_mql(dest)
            num_relations += 1
    for relation, dest in iter_incoming_edges(e, node, visited_nodes):
        if not dest in visited_nodes:
            relation = '!' + format_mql_uri(relation)
            if isnode(dest):
                dest_mql = node_to_mql(e, dest, visited_nodes)
                if type(dest_mql) == dict:
                    dest_mql = [dest_mql]
                mql_query[relation] = dest_mql
            else:
                mql_query[relation] = adapt_mql(dest)
            num_relations += 1
    if num_relations == 0:
        return None
    return mql_query
Пример #2
0
def node_to_mql(e, node, visited_nodes):
    mql_query = {}
    num_relations = 0
    visited_nodes.add(node)
    for relation, dest in e.iter_edges(node):
        if not dest in visited_nodes:
            relation = format_mql_uri(relation)
            if isnode(dest):
                dest_mql = node_to_mql(e, dest, visited_nodes)
                if type(dest_mql) == dict:
                    dest_mql = [dest_mql]
                mql_query[relation] = dest_mql
            else:
                mql_query[relation] = adapt_mql(dest)
            num_relations += 1
    for relation, dest in iter_incoming_edges(e, node, visited_nodes):
        if not dest in visited_nodes:
            relation = '!' + format_mql_uri(relation)
            if isnode(dest):
                dest_mql = node_to_mql(e, dest, visited_nodes)
                if type(dest_mql) == dict:
                    dest_mql = [dest_mql]
                mql_query[relation] = dest_mql
            else:
                mql_query[relation] = adapt_mql(dest)
            num_relations += 1
    if num_relations == 0:
        return None
    return mql_query
Пример #3
0
def generate_mql(e):
    """
    Generates a MQL query for the `Expression` `e`.
    """
    start = choose_start_node(e)
    graph = to_bidirected_graph(e)
    generated = {}
    for node in post_order_depth_first(graph, start):
        d = {}
        for relation, other in graph[node]:
            if isnode(other):
                try:
                    other = generated[other]
                except KeyError:
                    continue  # other is not in post_order_depth_first order
            d[relation] = other
        generated[node] = [d]

    mql_query = json.dumps(generated[start],
                           sort_keys=True,
                           indent=2,
                           separators=(',', ': '))
    mql_query = _tidy(mql_query)
    target = paths_from_root(graph, start)[e.get_head()]
    return target, mql_query
Пример #4
0
def to_bidirected_graph(e):
    """
    Rewrite the graph such that there are reversed edges for every forward
    edge.
    If an edge goes into a data, it should not be reversed.
    """
    graph = {node: [] for node in e.iter_nodes()}
    for node in e.iter_nodes():
        for relation, other in e.iter_edges(node):
            relation = safely_to_unicode(relation)
            if isnode(other):
                graph[other].append((u"!" + relation, node))
            else:
                other = safely_to_unicode(other)
            graph[node].append((relation, other))
    assert all(isnode(x) for x in graph) and len(e) == len(graph)
    return graph
Пример #5
0
def to_bidirected_graph(e):
    """
    Rewrite the graph such that there are reversed edges for every forward
    edge.
    If an edge goes into a data, it should not be reversed.
    """
    graph = {node: [] for node in e.iter_nodes()}
    for node in e.iter_nodes():
        for relation, other in e.iter_edges(node):
            relation = safely_to_unicode(relation)
            if isnode(other):
                graph[other].append((u"!" + relation, node))
            else:
                other = safely_to_unicode(other)
            graph[node].append((relation, other))
    assert all(isnode(x) for x in graph) and len(e) == len(graph)
    return graph
Пример #6
0
def adapt(x):
    if isnode(x):
        x = "?x{}".format(x)
        return x
    if isinstance(x, str):
        assert_valid_encoding(x)
        if x.startswith("\"") or ":" in x:
            return x
        return '"{}"'.format(x)
    return str(x)
Пример #7
0
def adapt(x):
    if isnode(x):
        x = u"?x{}".format(x)
        return x
    if isinstance(x, basestring):
        assert_valid_encoding(x)
        if x.startswith(u"\"") or ":" in x:
            return x
        return u'"{}"'.format(x)
    return unicode(x)
Пример #8
0
def adapt(x):
    if isnode(x):
        x = u"?x{}".format(x)
        return x
    if isinstance(x, basestring):
        assert_valid_encoding(x)
        if x.startswith(u"\"") or ":" in x:
            return x
        return u'"{}"'.format(x)
    return unicode(x)
Пример #9
0
def adapt(x):
    if isnode(x):
        x = u"x{}".format(x)
        return x
    if isinstance(x, basestring):
        assert_valid_encoding(x)
        x = escape(x)
        if x.startswith(u'"'):
            return x
        return u'"{}"'.format(x)
    return unicode(x)
Пример #10
0
 def test_acyclic(self):
     head = self.e.get_head()
     q = [head]
     seen = set()
     while q:
         current = q.pop()
         self.assertNotIn(current, seen)
         seen.add(current)
         for relation, child in self.e.iter_edges(current):
             if isnode(child):
                 q.append(child)
Пример #11
0
 def test_acyclic(self):
     head = self.e.get_head()
     q = [head]
     seen = set()
     while q:
         current = q.pop()
         self.assertNotIn(current, seen)
         seen.add(current)
         for relation, child in self.e.iter_edges(current):
             if isnode(child):
                 q.append(child)
Пример #12
0
def make_canonical_expression(e):
    i = 0
    q = [e.get_head()]
    seen = set()
    while i != len(q):
        node = q[i]
        i += 1
        assert node not in seen, "Nouuu, expression is cyclic!"
        for relation, child in e.iter_edges(node):
            if isnode(child):
                q.append(child)
    q.reverse()
    canon = {}
    for node in q:
        childs = []
        for label, child in e.iter_edges(node):
            if isnode(child):
                child = canon[child]
            childs.append((label, child))
        childs.sort()
        canon[node] = tuple(childs)
    return canon[e.get_head()]
Пример #13
0
def make_canonical_expression(e):
    i = 0
    q = [e.get_head()]
    seen = set()
    while i != len(q):
        node = q[i]
        i += 1
        assert node not in seen, "Nouuu, expression is cyclic!"
        for relation, child in e.iter_edges(node):
            if isnode(child):
                q.append(child)
    q.reverse()
    canon = {}
    for node in q:
        childs = []
        for label, child in e.iter_edges(node):
            if isnode(child):
                child = canon[child]
            childs.append((label, child))
        childs.sort()
        canon[node] = tuple(childs)
    return canon[e.get_head()]
Пример #14
0
def paths_from_root(graph, start):
    """
    Generates paths from `start` to every other node in `graph` and puts it in
    the returned dictionary `paths`.
    ie.: `paths_from_node(graph, start)[node]` is a list of the edge names used
    to get to `node` form `start`.
    """
    paths = {start: []}
    q = [start]
    seen = set()
    while q:
        node = q.pop()
        seen.add(node)
        for relation, child in graph[node]:
            if isnode(child) and child not in seen:
                q.append(child)
                paths[child] = paths[node] + [relation]
    return paths
Пример #15
0
def paths_from_root(graph, start):
    """
    Generates paths from `start` to every other node in `graph` and puts it in
    the returned dictionary `paths`.
    ie.: `paths_from_node(graph, start)[node]` is a list of the edge names used
    to get to `node` form `start`.
    """
    paths = {start: []}
    q = [start]
    seen = set()
    while q:
        node = q.pop()
        seen.add(node)
        for relation, child in graph[node]:
            if isnode(child) and child not in seen:
                q.append(child)
                paths[child] = paths[node] + [relation]
    return paths
Пример #16
0
def post_order_depth_first(graph, start):
    """
    Iterate over the nodes of the graph (is a tree) in a way such that every
    node is preceded by it's childs.
    `graph` is a dict that represents the `Expression` graph. It's a tree too
    beacuse Expressions are trees.
    `start` is the node to use as the root of the tree.
    """
    q = [start]
    seen = set()
    i = 0
    while i != len(graph):
        node = q[i]
        seen.add(node)
        i += 1
        for _, other in graph[node]:
            if isnode(other) and other not in seen:
                q.append(other)
    assert len(q) == len(graph)
    q.reverse()
    return q
Пример #17
0
def post_order_depth_first(graph, start):
    """
    Iterate over the nodes of the graph (is a tree) in a way such that every
    node is preceded by it's childs.
    `graph` is a dict that represents the `Expression` graph. It's a tree too
    beacuse Expressions are trees.
    `start` is the node to use as the root of the tree.
    """
    q = [start]
    seen = set()
    i = 0
    while i != len(graph):
        node = q[i]
        seen.add(node)
        i += 1
        for _, other in graph[node]:
            if isnode(other) and other not in seen:
                q.append(other)
    assert len(q) == len(graph)
    q.reverse()
    return q
Пример #18
0
def generate_mql(e):
    """
    Generates a MQL query for the `Expression` `e`.
    """
    start = choose_start_node(e)
    graph = to_bidirected_graph(e)
    generated = {}
    for node in post_order_depth_first(graph, start):
        d = {}
        for relation, other in graph[node]:
            if isnode(other):
                try:
                    other = generated[other]
                except KeyError:
                    continue  # other is not in post_order_depth_first order
            d[relation] = other
        generated[node] = [d]

    mql_query = json.dumps(generated[start], sort_keys=True,
                            indent=2, separators=(',', ': '))
    mql_query = _tidy(mql_query)
    target = paths_from_root(graph, start)[e.get_head()]
    return target, mql_query