private Simplify ( Pivots.Pivot>.Dictionary |
||
pivotVsPivotValues | Pivots.Pivot>.Dictionary | |
return |
internal PivotsExpression Simplify(Dictionary<string, Pivots.Pivot> pivotVsPivotValues) { if (invariant) return this; if (matching_combinations.Count == 0) return False; int possible_combinations = 1; foreach (string pivot in relevant_pivots) { possible_combinations *= pivotVsPivotValues[pivot].Choices.Keys.Count; } if (matching_combinations.Count == possible_combinations) return True; foreach (string pivot in relevant_pivots) { var values = pivotVsPivotValues[pivot].Choices.Keys; if (matching_combinations.Count % values.Count != 0) continue; int reduced_combinations = matching_combinations.Count / values.Count; ComparableHashSet<ComparableHashSet<string>> new_combinations = new ComparableHashSet<ComparableHashSet<string>>(); foreach (var combination in matching_combinations) { ComparableHashSet<string> reduced_combination = new ComparableHashSet<string>(combination); reduced_combination.ExceptWith(values); new_combinations.Add(reduced_combination); if (new_combinations.Count > reduced_combinations) break; } if (new_combinations.Count == reduced_combinations) { PivotsExpression result = new PivotsExpression(); result.relevant_pivots = new HashSet<string>(relevant_pivots); result.relevant_pivots.Remove(pivot); result.matching_combinations = new_combinations; return result.Simplify(pivotVsPivotValues); } } return this; }
internal override PivotsExpression ToPivotsExpression(Dictionary<string, Pivots.Pivot> pivotVsPivotValues, GetChoiceDelegate get_choice_fn) { PivotsExpression left, right; left = left_child.ToPivotsExpression(pivotVsPivotValues, get_choice_fn); if (left.invariant) { if (left.invariant_result) return left; else return right_child.ToPivotsExpression(pivotVsPivotValues, get_choice_fn); } right = right_child.ToPivotsExpression(pivotVsPivotValues, get_choice_fn); if (right.invariant) { if (right.invariant_result) return right; else return left; } HashSet<string> pivots; ComparableHashSet<ComparableHashSet<string>> result; pivots = new HashSet<string>(left.relevant_pivots); pivots.UnionWith(right.relevant_pivots); result = GetExpandedChoices(left, pivots, pivotVsPivotValues); result.UnionWith(GetExpandedChoices(right, pivots, pivotVsPivotValues)); PivotsExpression res = new PivotsExpression(); res.relevant_pivots = pivots; res.matching_combinations = result; return res.Simplify(pivotVsPivotValues); }
internal override PivotsExpression ToPivotsExpression(Dictionary<string, Pivots.Pivot> pivotVsPivotValues, GetChoiceDelegate get_choice_fn) { PivotsExpression left, right; left = left_child.ToPivotsExpression(pivotVsPivotValues, get_choice_fn); if (left.invariant) { if (left.invariant_result) return right_child.ToPivotsExpression(pivotVsPivotValues, get_choice_fn); else return left; } right = right_child.ToPivotsExpression(pivotVsPivotValues, get_choice_fn); if (right.invariant) { if (right.invariant_result) return left; else return right; } HashSet<string> shared_pivots = new HashSet<string>(left.relevant_pivots); shared_pivots.IntersectWith(right.relevant_pivots); if (shared_pivots.Count == left.relevant_pivots.Count) { // All pivots are shared, just intersect the sets. PivotsExpression result = new PivotsExpression(); result.relevant_pivots = left.relevant_pivots; result.matching_combinations = new ComparableHashSet<ComparableHashSet<string>>(left.matching_combinations); result.matching_combinations.IntersectWith(right.matching_combinations); return result.Simplify(pivotVsPivotValues); } if (shared_pivots.Count == 0) { // No shared pivots, so do a cross product PivotsExpression result = new PivotsExpression(); result.relevant_pivots = new HashSet<string>(left.relevant_pivots); result.relevant_pivots.UnionWith(right.relevant_pivots); result.matching_combinations = new ComparableHashSet<ComparableHashSet<string>>(); foreach (var left_combination in left.matching_combinations) { foreach (var right_combination in right.matching_combinations) { ComparableHashSet<string> new_combination = new ComparableHashSet<string>(left_combination); new_combination.UnionWith(right_combination); result.matching_combinations.Add(new_combination); } } // It shouldn't be necessary to simplify in this case, as any independent pivots should have been removed already return result; } HashSet<string> shared_pivot_values = new HashSet<string>(); foreach (string pivot in shared_pivots) { shared_pivot_values.UnionWith(pivotVsPivotValues[pivot].Choices.Keys); } // Sort by relevant pivot count if (left.relevant_pivots.Count > right.relevant_pivots.Count) { var tmp = left; left = right; right = tmp; } if (right.relevant_pivots.IsSupersetOf(left.relevant_pivots)) { // Filter the combintions in right by what's in left. PivotsExpression result = new PivotsExpression(); result.relevant_pivots = right.relevant_pivots; result.matching_combinations = new ComparableHashSet<ComparableHashSet<string>>(); foreach (var right_combination in right.matching_combinations) { ComparableHashSet<string> reduced_combination = new ComparableHashSet<string>(right_combination); reduced_combination.IntersectWith(shared_pivot_values); if (left.matching_combinations.Contains(reduced_combination)) result.matching_combinations.Add(right_combination); } return result.Simplify(pivotVsPivotValues); } else { Dictionary<ComparableHashSet<string>, List<ComparableHashSet<string>>> shared_values_to_left_values = new Dictionary<ComparableHashSet<string>, List<ComparableHashSet<string>>>(); foreach (var left_combination in left.matching_combinations) { ComparableHashSet<string> shared_values = new ComparableHashSet<string>(); foreach (var value in left_combination) { if (shared_pivot_values.Contains(value)) shared_values.Add(value); } List<ComparableHashSet<string>> combination_list; if (!shared_values_to_left_values.TryGetValue(shared_values, out combination_list)) combination_list = shared_values_to_left_values[shared_values] = new List<ComparableHashSet<string>>(); combination_list.Add(left_combination); } PivotsExpression result = new PivotsExpression(); result.relevant_pivots = new HashSet<string>(left.relevant_pivots); result.relevant_pivots.UnionWith(right.relevant_pivots); result.matching_combinations = new ComparableHashSet<ComparableHashSet<string>>(); foreach (var right_combination in right.matching_combinations) { ComparableHashSet<string> shared_values = new ComparableHashSet<string>(); foreach (var value in right_combination) { if (shared_pivot_values.Contains(value)) shared_values.Add(value); } List<ComparableHashSet<string>> left_combinations; if (shared_values_to_left_values.TryGetValue(shared_values, out left_combinations)) { foreach (var left_combination in left_combinations) { ComparableHashSet<string> new_combination = new ComparableHashSet<string>(right_combination); new_combination.UnionWith(left_combination); result.matching_combinations.Add(new_combination); } } } return result.Simplify(pivotVsPivotValues); } }
internal override PivotsExpression ToPivotsExpression(Dictionary <string, Pivots.Pivot> pivotVsPivotValues, GetChoiceDelegate get_choice_fn) { PivotsExpression left, right; left = left_child.ToPivotsExpression(pivotVsPivotValues, get_choice_fn); if (left.invariant) { if (left.invariant_result) { return(right_child.ToPivotsExpression(pivotVsPivotValues, get_choice_fn)); } else { return(left); } } right = right_child.ToPivotsExpression(pivotVsPivotValues, get_choice_fn); if (right.invariant) { if (right.invariant_result) { return(left); } else { return(right); } } HashSet <string> shared_pivots = new HashSet <string>(left.relevant_pivots); shared_pivots.IntersectWith(right.relevant_pivots); if (shared_pivots.Count == left.relevant_pivots.Count) { // All pivots are shared, just intersect the sets. PivotsExpression result = new PivotsExpression(); result.relevant_pivots = left.relevant_pivots; result.matching_combinations = new ComparableHashSet <ComparableHashSet <string> >(left.matching_combinations); result.matching_combinations.IntersectWith(right.matching_combinations); return(result.Simplify(pivotVsPivotValues)); } if (shared_pivots.Count == 0) { // No shared pivots, so do a cross product PivotsExpression result = new PivotsExpression(); result.relevant_pivots = new HashSet <string>(left.relevant_pivots); result.relevant_pivots.UnionWith(right.relevant_pivots); result.matching_combinations = new ComparableHashSet <ComparableHashSet <string> >(); foreach (var left_combination in left.matching_combinations) { foreach (var right_combination in right.matching_combinations) { ComparableHashSet <string> new_combination = new ComparableHashSet <string>(left_combination); new_combination.UnionWith(right_combination); result.matching_combinations.Add(new_combination); } } // It shouldn't be necessary to simplify in this case, as any independent pivots should have been removed already return(result); } HashSet <string> shared_pivot_values = new HashSet <string>(); foreach (string pivot in shared_pivots) { shared_pivot_values.UnionWith(pivotVsPivotValues[pivot].Choices.Keys); } // Sort by relevant pivot count if (left.relevant_pivots.Count > right.relevant_pivots.Count) { var tmp = left; left = right; right = tmp; } if (right.relevant_pivots.IsSupersetOf(left.relevant_pivots)) { // Filter the combintions in right by what's in left. PivotsExpression result = new PivotsExpression(); result.relevant_pivots = right.relevant_pivots; result.matching_combinations = new ComparableHashSet <ComparableHashSet <string> >(); foreach (var right_combination in right.matching_combinations) { ComparableHashSet <string> reduced_combination = new ComparableHashSet <string>(right_combination); reduced_combination.IntersectWith(shared_pivot_values); if (left.matching_combinations.Contains(reduced_combination)) { result.matching_combinations.Add(right_combination); } } return(result.Simplify(pivotVsPivotValues)); } else { Dictionary <ComparableHashSet <string>, List <ComparableHashSet <string> > > shared_values_to_left_values = new Dictionary <ComparableHashSet <string>, List <ComparableHashSet <string> > >(); foreach (var left_combination in left.matching_combinations) { ComparableHashSet <string> shared_values = new ComparableHashSet <string>(); foreach (var value in left_combination) { if (shared_pivot_values.Contains(value)) { shared_values.Add(value); } } List <ComparableHashSet <string> > combination_list; if (!shared_values_to_left_values.TryGetValue(shared_values, out combination_list)) { combination_list = shared_values_to_left_values[shared_values] = new List <ComparableHashSet <string> >(); } combination_list.Add(left_combination); } PivotsExpression result = new PivotsExpression(); result.relevant_pivots = new HashSet <string>(left.relevant_pivots); result.relevant_pivots.UnionWith(right.relevant_pivots); result.matching_combinations = new ComparableHashSet <ComparableHashSet <string> >(); foreach (var right_combination in right.matching_combinations) { ComparableHashSet <string> shared_values = new ComparableHashSet <string>(); foreach (var value in right_combination) { if (shared_pivot_values.Contains(value)) { shared_values.Add(value); } } List <ComparableHashSet <string> > left_combinations; if (shared_values_to_left_values.TryGetValue(shared_values, out left_combinations)) { foreach (var left_combination in left_combinations) { ComparableHashSet <string> new_combination = new ComparableHashSet <string>(right_combination); new_combination.UnionWith(left_combination); result.matching_combinations.Add(new_combination); } } } return(result.Simplify(pivotVsPivotValues)); } }