/// <summary>
        /// Tests if two implicants have the same set of items
        /// and difference is only in one item sign.
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <param name="commonImplicant">Common intersection of implicants only if returns true.</param>
        /// <param name="signDifferenceIndex">Single item index difference only if returns true.</param>
        /// <returns></returns>
        public static bool TestDifferenceInOneSign(
            Implicant a,
            Implicant b,
            out Implicant commonImplicant,
            out int signDifferenceIndex)
        {
            commonImplicant     = null;
            signDifferenceIndex = -1;

            if (a.Count != b.Count)
            {
                return(false);
            }

            var        common = new List <InputSign>();
            List <int> signDifferenceIndexes = new List <int>();

            for (int i = 0; i < a.Count; i++)
            {
                InputSign aItem = a.Items[i];
                InputSign bItem = b.Items[i];
                if (aItem.Index != bItem.Index)
                {
                    return(false);
                }

                if (aItem.IsInversed == bItem.IsInversed)
                {
                    common.Add(aItem);
                }
                else
                {
                    signDifferenceIndexes.Add(aItem.Index);
                }
            }

            if (signDifferenceIndexes.Count == 0)
            {
                return(false);
            }
            else if (signDifferenceIndexes.Count == 1)
            {
                commonImplicant     = new Implicant(common);
                signDifferenceIndex = signDifferenceIndexes[0];
                return(true);
            }
            else
            {
                return(false);
            }
        }
예제 #2
0
        /// <summary>
        /// Petrick's method (https://en.wikipedia.org/wiki/Petrick%27s_method) is too complicated for lab work programming.
        /// Thats why lets implement primitive method based on teacher's explanation.
        /// </summary>
        private static List <Implicant> GetMinimalDisjunctionNormalForm(List <Implicant> constituents, List <Implicant> implicants)
        {
            var coreImplicants = new HashSet <Implicant>();

            foreach (Implicant implicant in implicants)
            {
                foreach (Implicant constituent in constituents)
                {
                    List <Implicant> implicantsInConstituent = implicants.Where(i => i.IsSubsetOf(constituent)).ToList();

                    if (implicantsInConstituent.Count == 1 && implicantsInConstituent.Contains(implicant))
                    {
                        coreImplicants.Add(implicant);
                        continue;
                    }
                }
            }
            List <Implicant> noncoreImplicants = implicants.Except(coreImplicants).ToList();

            List <Implicant> notCoveredConstituents = constituents
                                                      .Where(c => !coreImplicants.Any(coreImplicant => coreImplicant.IsSubsetOf(c))).ToList();

            List <Implicant> resultImplicants = coreImplicants.ToList();

            while (notCoveredConstituents.Count > 0)
            {
                noncoreImplicants = noncoreImplicants
                                    .OrderBy(i => notCoveredConstituents.Where(c => i.IsSubsetOf(c)).Count()).ToList();
                Implicant noncoreTopRatedImplicant = noncoreImplicants[noncoreImplicants.Count - 1];
                noncoreImplicants.RemoveAt(noncoreImplicants.Count - 1);

                bool covers = false;
                for (int i = notCoveredConstituents.Count - 1; i >= 0; i--)
                {
                    if (noncoreTopRatedImplicant.IsSubsetOf(notCoveredConstituents[i]))
                    {
                        notCoveredConstituents.RemoveAt(i);
                        covers = true;
                    }
                }
                if (covers)
                {
                    resultImplicants.Add(noncoreTopRatedImplicant);
                }
            }

            return(resultImplicants);
        }
예제 #3
0
        private static bool EvaluateImplicant(uint input, Implicant implicant)
        {
            foreach (InputSign inputSign in implicant)
            {
                bool bit = BitTools.GetBit(input, bitIndex: inputSign.Index);
                if (inputSign.IsInversed)
                {
                    bit = !bit;
                }
                if (!bit)
                {
                    return(false);
                }
            }

            return(true);
        }
예제 #4
0
        /// <param name="implicants">Implicants ordered from short to long.</param>
        private static List <Implicant> AbsorpImplicantsToShortDisjunctionNormalForm(List <Implicant> implicants)
        {
            List <Implicant> resultList = implicants.ToList();

            for (int absorperIndex = 0; absorperIndex < resultList.Count - 1; absorperIndex++)
            {
                Implicant absorper = resultList[absorperIndex];
                for (int absorpedIndex = resultList.Count - 1; absorpedIndex > absorperIndex; absorpedIndex--)
                {
                    Implicant absorped = resultList[absorpedIndex];
                    if (absorper.IsSubsetOf(absorped))
                    {
                        resultList.RemoveAt(absorpedIndex);
                    }
                }
            }

            return(resultList);
        }
예제 #5
0
        private static IReadOnlyList <IReadOnlyList <Implicant> > GetImplicantsGroupedByDifferencePosition(
            IEnumerable <Tuple <Implicant, Implicant> > constituentPairs)
        {
            var implicantsGroupped = new SortedDictionary <int, List <Implicant> >();

            foreach (Tuple <Implicant, Implicant> item in constituentPairs)
            {
                Implicant commonImplicant;
                int       signDifferenceIndex;
                if (Implicant.TestDifferenceInOneSign(item.Item1, item.Item2, out commonImplicant, out signDifferenceIndex))
                {
                    List <Implicant> group;
                    if (!implicantsGroupped.TryGetValue(signDifferenceIndex, out group))
                    {
                        group = new List <Implicant>();
                        implicantsGroupped[signDifferenceIndex] = group;
                    }
                    group.Add(commonImplicant);
                }
            }
            return(implicantsGroupped.Values.ToList());
        }
 internal bool IsSubsetOf(Implicant other)
 {
     return(this.indexSet.IsSubsetOf(other.indexSet));
 }
 public bool Equals(Implicant other) => this.indexSet.SetEquals(other.indexSet);