A set of attributes.
Closure
Suppose is an attribute set and is a set of functional dependencies.
Closure of under a set of functional dependencies , is the set of all attributes functionally determined by using the dependencies in . Denoted as ,
Algorithm
can be computed by:
- Start with .
- For each dependency in :
If , then add to . - Repeat until no new attributes can be added.
If includes all attributes of , then is a superkey of .
Can be used to test if a given functional dependency holds.
def attribute_closure(attributes, fds):
"""
Compute the closure of a set of attributes with respect to a set of functional dependencies.
:param attributes: set of attribute strings, e.g. {'A', 'B'}
:param fds: list of tuples (lhs, rhs), where lhs and rhs are sets of attributes
e.g. [({'A'}, {'B'}), ({'B'}, {'C'})]
:return: set of attributes in the closure
"""
closure = set(attributes)
changed = True
while changed:
changed = False
for lhs, rhs in fds:
if lhs.issubset(closure) and not rhs.issubset(closure):
closure.update(rhs)
changed = True
return closure