Beispiel #1
0
            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);
            }
Beispiel #2
0
            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);
            }
Beispiel #3
0
        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);
        }
Beispiel #4
0
            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));
                }
            }