Пример #1
0
        public FunctionalDependency GetMinimalFD(FunctionalDependency fd)
        {
            var det = fd.Determinants;

            if (det.Count == 1)
            {
                return(fd);
            }
            var refClosure = GetClosure(det);

            foreach (var attr in det)
            {
                var testdets = det.GetExcepted(attr);
                if (refClosure.SetEquals(GetClosure(testdets)))
                {
                    return(GetMinimalFD(fd.Dependent.DependsOn(testdets)));
                }
            }
            return(fd.Dependent.DependsOn(det));
        }
Пример #2
0
        /// <summary>
        /// Step 2
        /// </summary>
        public static Tuple <bool, HashSet <HashSet <Attribute> > > IsAttributeSuperfluous(Relation reference, HashSet <Relation> relations, Relation target, Attribute attr)
        {
            var none = Tuple.Create <bool, HashSet <HashSet <Attribute> > >(false, null);

            if (!target.Attributes.Contains(attr))
            {
                throw new ArgumentException("target relation does not contain requested attribute");
            }
            if (!relations.Contains(target))
            {
                throw new ArgumentException("relation set does not contain target relation");
            }

            var Ki = new HashSet <HashSet <Attribute> >(target.FDs.Select(fd => fd.Determinants), HashSet <Attribute> .CreateSetComparer());

            if (Ki.Count == 1 && Ki.Single().SetEquals(target.Attributes))
            {
                return(none);
            }

            var Ki_prime = new HashSet <HashSet <Attribute> >(Ki.Where(x => !x.Contains(attr)), HashSet <Attribute> .CreateSetComparer());

            if (!Ki_prime.Any())
            {
                return(none);
            }

            var Gi = new HashSet <FunctionalDependency>();

            foreach (var K in Ki)
            {
                Gi.UnionWith(FunctionalDependency.Decompose(K, target.Attributes.GetExceptedMany(K)));
            }
            var Gi_R = new Relation(Relation.GetAttributeSet(Gi), Gi);

            var Gi_prime = new HashSet <FunctionalDependency>();

            foreach (var G in relations.Where(r => r != target))
            {
                Gi_prime.UnionWith(G.FDs);
            }
            var exceptAttr = target.FDs.Where(fd => !fd.Determinants.Contains(attr));
            var Ai_prime   = target.Attributes.GetExcepted(attr);

            foreach (var fd in exceptAttr)
            {
                var K = fd.Determinants;
                Gi_prime.UnionWith(FunctionalDependency.Decompose(K, Ai_prime.GetExceptedMany(K)));
            }
            var Gi_primeR = new Relation(Relation.GetAttributeSet(Gi_prime), Gi_prime);

            // check restorability
            foreach (var K in Ki_prime)
            {
                if (!Gi_primeR.GetClosure(K).Contains(attr))
                {
                    return(none);
                }
            }

            // B is restorable, check non-essentiality
            foreach (var K in Ki.Except(Ki_prime))
            {
                var M = Gi_primeR.GetClosure(K);
                if (target.Attributes.SetEquals(M))
                {
                    return(Tuple.Create(true, Ki_prime));
                }

                var M_test = new HashSet <Attribute>(M);
                M_test.IntersectWith(target.Attributes);
                M_test.Remove(attr);
                // M_test = (M intersect Ai) - B
                if (!reference.GetClosure(M_test).IsSupersetOf(target.Attributes))
                {
                    return(none);
                }

                // add key of Ri in M_test to Ki_prime
                // only consider attributes found in FDs, not "dangling" attributes
                var attrCover = new HashSet <Attribute>();
                foreach (var k in Ki_prime)
                {
                    attrCover.UnionWith(k);
                }
                attrCover.IntersectWith(M_test);
                //Ki_prime.Clear();
                Ki_prime.Add(target.MinimizeAttributeSet(attrCover));
            }

            return(Tuple.Create(true, Ki_prime));
        }