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); }
public string NormalizeExpression(string expression) { // the non dynamic way. var pivotExpression = PivotsExpression.ReadExpression(_pivots, (string item, out string choice, out string name) => { Pivot pivot; var result = GetChoice(item, out choice, out pivot); name = pivot.Name; return(result); }, expression); return(_normalizedPivots.GetOrAdd(pivotExpression, () => expression)); }
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); }
public string NormalizeExpression(string expression) { #if USE_DYNAMIC_CRAP if (Environment.GetEnvironmentVariable("USE_DYNAMIC").IsTrue()) { if (string.IsNullOrEmpty(expression)) { return(expression); } /* * if (_canonicalExpressions.Keys.Contains(expression)) { * return expression; * }*/ foreach (var i in _canonicalExpressions.Keys.ToArray()) { if (_canonicalExpressions[i].Contains(expression)) { return(i); } } foreach (var i in _canonicalExpressions.Keys.ToArray()) { if (CompareExpressions(i, expression)) { _canonicalExpressions[i].Add(expression); return(i); } } _canonicalExpressions.GetOrAdd(expression, () => new List <string> { expression }); return(expression); } #endif // the non dynamic way. var pivotExpression = PivotsExpression.ReadExpression(_pivots, (string item, out string choice, out string name) => { Pivot pivot; var result = GetChoice(item, out choice, out pivot); name = pivot.Name; return(result); }, expression); return(_normalizedPivots.GetOrAdd(pivotExpression, () => expression)); }
public override bool Equals(object obj) { if (obj is PivotsExpression) { PivotsExpression expr = obj as PivotsExpression; if (expr.invariant != this.invariant) { return(false); } if (this.invariant) { return(expr.invariant_result == this.invariant_result); } return(matching_combinations.Equals(expr.matching_combinations)); } return(base.Equals(obj)); }
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 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) { 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 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 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 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 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); }