public static Set <Set <I> > compute(Set <I> set) { switch (set) { case ExplicitSet <I> explicitSet: { var subsets = new ExplicitSet <Set <I> >(); subsets.Elements.Add(Set <I> .EmptySet); foreach (var elem in explicitSet.Elements) { var combos = subsets.Elements.ToHashSet(); foreach (var copy in combos.Select(s => ((ExplicitSet <I>)s).Elements.ToHashSet())) { copy.Add(elem); subsets.Elements.Add(new ExplicitSet <I>(copy)); } } return(subsets); } case DerivedSet <I> derivedSet: return(new DerivedSet <Set <I> >(s => s.IsSubset(set), derivedSet.GetCardinality().powerset(), "x \\subseteq" + set.ToLaTeX())); default: return(null); } }
/// <summary> /// Recursively collects all of the elements in the cartesian product /// </summary> /// <param name="sets">The groups to compute the cartesian product of</param> /// <returns>A bag of all of the elements in the cartesian product</returns> private static ConcurrentBag <Value.Tuple <I> > collectElements(ExplicitSet <I>[] sets) { var elements = new ConcurrentBag <Value.Tuple <I> >(); // If there is only one set, convert the identifiers to singleton arrays of elements // containing their identifiers if (sets.Length == 1) { Parallel.ForEach(sets[0].Elements, el => elements.Add(new Value.Tuple <I>(new[] { el })) ); } else { // Recursively collect all of the elements in the cartesian product of all sets except the first var otherSets = new ExplicitSet <I> [sets.Length - 1]; Array.Copy(sets, 1, otherSets, 0, sets.Length - 1); var otherGroupElems = collectElements(otherSets); // Find all tuples containing this element as the first entry combined with all other tuples obtained // recursively Parallel.ForEach(sets[0].Elements, elem => Parallel.ForEach(otherGroupElems, el => { var tup = new I[sets.Length]; tup[0] = elem; Parallel.For(1, sets.Length, i => { tup[i] = el[i - 1]; }); var comb = new Value.Tuple <I>(tup); elements.Add(comb); }) ); } return(elements); }