Coverage RemoveRedundant(Coverage groups) { // A group is redundant if it covers "ones" already covered by other // essential groups var redundant = new Coverage(); var essential = new Coverage(groups.Where(g => g.IsEssential.Value)); foreach (var g in groups) { if (g.IsEssential.Value) { continue; } var remaining_terms = new Group(g); foreach (var e in essential) { remaining_terms.ExceptWith(e); } if (remaining_terms.Count == 0) { redundant.Add(g); } } return(new Coverage(groups.Except(redundant))); }
public HashSet <Coverage> Minimize() { var groups = new Coverage(); // Generate initial groups (of cardinality 1) foreach (var one in on_set_binary) { groups.Add(new Group() { one }); } // onsider the don't cares as 'ones', but don't consider them essential foreach (var dc in dc_set_binary) { groups.Add(new Group() { dc }); } Coverage previous_groups = null; // Continue merging and optimizing until it's possible while (previous_groups == null || !groups.Equals(previous_groups)) { previous_groups = groups; // Save the state before merging and optimizing // Merge groups of cardinality 'n' to create groups of double cardinality groups = MergeGroups(groups); // Clean up groups that are strict subsets of other groups groups = RemoveSubsets(groups); } // Detect essential groups groups = MarkEssential(groups); // Remove completely redundant groups, that is, groups that cover 'ones' (of the function) already covered by other ESSENTIAL groups groups = RemoveRedundant(groups); return(GetCoverages(groups)); }
Coverage RemoveSubsets(Coverage groups) { var not_subsets = new Coverage(); foreach (var candidate_subset in groups) { if (!groups.Any(candidate_superset => candidate_subset.IsProperSubsetOf(candidate_superset))) { not_subsets.Add(candidate_subset); } } return(not_subsets); }
Coverage MergeGroups(Coverage groups) { var merged = new Coverage(); foreach (var g1 in groups) { foreach (var g2 in groups) { // Two groups can only merge if they are adjacent and disjoint if (g1.Intersect(g2).Count() == 0 && AreGroupsAdjacent(g1, g2)) { var new_group = new Group(g1.Union(g2)); merged.Add(new_group); } } } return(new Coverage(groups.Union(merged))); }