internal override PivotsExpression ToPivotsExpression(Dictionary <string, Pivots.Pivot> pivotVsPivotValues, GetChoiceDelegate get_choice_fn) { var result = new PivotsExpression(); result.relevant_pivots = new HashSet <string>(); result.relevant_pivots.Add(pivot_name); result.matching_combinations = new ComparableHashSet <ComparableHashSet <string> >(); if (inverted) { foreach (string pivotValue in pivotVsPivotValues[pivot_name].Choices.Keys) { if (pivotValue != pivot_choice) { ComparableHashSet <string> choice = new ComparableHashSet <string>(); choice.Add(pivotValue); result.matching_combinations.Add(choice); } } } else { ComparableHashSet <string> choice = new ComparableHashSet <string>(); choice.Add(pivot_choice); result.matching_combinations.Add(choice); } return(result); }
internal ComparableHashSet <ComparableHashSet <string> > GetExpandedChoices(PivotsExpression expr, HashSet <string> pivots, Dictionary <string, Pivots.Pivot> pivotVsPivotValues) { ComparableHashSet <ComparableHashSet <string> > result = expr.matching_combinations; foreach (string pivot in pivots) { if (expr.relevant_pivots.Contains(pivot)) { continue; } ComparableHashSet <ComparableHashSet <string> > new_result = new ComparableHashSet <ComparableHashSet <string> >(); var pivot_choices = pivotVsPivotValues[pivot].Choices.Keys; foreach (var matching_combination in result) { foreach (string pivot_choice in pivot_choices) { ComparableHashSet <string> choices = new ComparableHashSet <string>(matching_combination); choices.Add(pivot_choice); new_result.Add(choices); } } result = new_result; } return(result); }
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(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)); } }