示例#1
0
文件: bcnf.py 项目: hhc97/playground
def project_dependencies(rel: Relation) -> None:
    """
    Update the fds in the relation by projecting them.
    """
    new_fds = []
    supers = []
    for single in rel.relation:
        closure = rel.closure({single})
        fd = FD(f'{single}->{"".join(closure)}')
        if closure == rel.relation:
            supers.append(fd)
        if not closure.issubset({single}):
            new_fds.append(fd)
    for s in powerset(rel.relation):
        redundant = False
        subset = set(s)
        for fd in supers:
            if subset.issuperset(fd.determinants):
                redundant = True
                break
        if redundant or subset == rel.relation or not subset:
            continue
        closure = rel.closure(subset)
        fd = FD(f'{"".join(subset)}->{"".join(closure)}')
        if closure == rel.relation:
            supers.append(fd)
        if not closure.issubset(subset) and fd not in new_fds:
            new_fds.append(fd)
    rel.fds = new_fds
示例#2
0
文件: bcnf.py 项目: hhc97/playground
def bcnf(rel: Relation) -> list:
    """
    Applies the BCNF algorithm to a relation and returns a list of relations.
    """
    for fd in rel.fds:
        if fd.determinants.issubset(rel.relation):
            closure = rel.closure(fd.determinants)
            if closure != rel.relation and closure != fd.determinants:
                print(f'Chosen FD: {fd}')
                left, right = _split(rel, fd)
                left = bcnf(left)
                right = bcnf(right)
                return left + right
    project_dependencies(rel)
    return [rel]
示例#3
0
文件: bcnf.py 项目: hhc97/playground
def _split(rel: Relation, fd: FD) -> tuple:
    """
    Splits a relation on a FD according to BCNF.
    """
    r1 = rel.closure(fd.determinants)
    r2 = rel.relation - (r1 - fd.determinants)

    new_r1 = Relation()
    new_r1.relation = r1
    new_r1.fds = rel.get_fds_copy()

    new_r2 = Relation()
    new_r2.relation = r2
    new_r2.fds = rel.get_fds_copy()

    return new_r1, new_r2