Example #1
0
def gen_m_graph(q: ConjunctiveQuery) -> nx.DiGraph:
    """
    Computes the M-graph of a given ConjunctiveQuery q.
    :param q:   A ConjunctiveQuery
    :return:    Generated M-Graph
    """
    atoms = q.get_atoms()
    g = nx.DiGraph()
    for atom1 in atoms:
        g.add_node(atom1)
        closure = transitive_closure(set(atom1.variables()),
                                     q.get_consistent_fd())
        for atom2 in [atom for atom in atoms if atom != atom1]:
            if set(q.get_key_vars(atom2)).issubset(closure):
                g.add_edge(atom1, atom2)
    return g
Example #2
0
def find_bad_internal_fd(
        q: ConjunctiveQuery) -> FrozenSet[FunctionalDependency]:
    """
    Given a non saturated ConjunctiveQuery, returns the FunctionalDependencies culprit of it's non saturation.
    :param q:       A ConjunctiveQuery.
    :return:        A FrozenSet containing the FunctionalDependencies culprit of the non saturation of q.
    """
    res = frozenset()
    possible_starts = []
    possible_ends = []
    for fd in q.get_all_fd().set:
        if fd.left not in possible_starts:
            possible_starts.append(fd.left)
        if fd.right not in possible_ends:
            possible_ends.append(fd.right)
    for left in possible_starts:
        for right in possible_ends:
            test_fd = FunctionalDependency(left, right)
            if fd_is_internal(test_fd, q):
                if right not in transitive_closure(set(left),
                                                   q.get_consistent_fd()):
                    res = res.union(frozenset([test_fd]))
    return res