// return the set of attributes, // each attribute in the set is functionally determined by X Set ComputeXClosure(X, F) // X: a set of attributes, F: a set of FD { Set XC = X; // XC: a set of attributes // X -> XC (trivial because XC is X) bool reachClosure = false; while (!reachClosure) { reachClosure = true; for (each (Y -> Z) in set F) { if Y is subset of XC, and Z is not a subset of XC { // X -> XC (invariant) // XC -> Y (trivial because Y is a sebset of XC) // Y -> Z (it's given because it's in set F) XC = XC union Z; // X -> XC, XC -> Y, Y -> Z => X -> Z reachClosure = false; // just added some new attribute to XC } } } return XC; }