/// <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); } }
/// <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); }
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); }
/// <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); }
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);