Exemple #1
0
        public FindData[] Optimize(RuleTable rules, ConstraintSystem environment, CancellationToken cancel)
        {
            //// Step 1. Try to split the items into connected components.
            var itemDats = new Map <Term, ItemData>(Term.Compare);
            var useLists = new Map <Term, Set <ItemData> >(Term.Compare);

            foreach (var kv in findPatterns)
            {
                itemDats.Add(kv.Key, RegisterUses(new ItemData(kv.Key, kv.Value.Item1), useLists));
            }

            foreach (var con in constraints)
            {
                itemDats.Add(con, RegisterUses(new ItemData(con), useLists));
            }

            FindData f1, f2;
            Tuple <ItemData, LinkedList <ItemData> > partialRule;
            var components = ComputeComponents(itemDats, useLists);

            if (components.Length == 0)
            {
                return(new FindData[] { rules.CompilePartialRule(default(FindData), default(FindData), new Set <Term>(Term.Compare), environment) });
            }

            var outputs = new FindData[components.Length];

            for (int i = 0; i < components.Length; ++i)
            {
                var ordering = OrderComponents(i, components[i], useLists);
                Contract.Assert(ordering != null && ordering.Count > 0);

                //// Debug_PrintOrderData(i, ordering);
                //// Console.WriteLine();

                using (var it = ordering.GetEnumerator())
                {
                    it.MoveNext();
                    partialRule = it.Current;
                    if (partialRule.Item1 != null)
                    {
                        f1 = new FindData(partialRule.Item1.Item, findPatterns[partialRule.Item1.Item].Item1, findPatterns[partialRule.Item1.Item].Item2);
                    }
                    else
                    {
                        f1 = default(FindData);
                    }

                    var constrs = new Set <Term>(Term.Compare);
                    foreach (var c in partialRule.Item2)
                    {
                        constrs.Add(c.Item);
                    }

                    if (ordering.Count == 1)
                    {
                        outputs[i] = rules.CompilePartialRule(f1, default(FindData), constrs, environment);
                        continue;
                    }

                    while (it.MoveNext())
                    {
                        partialRule = it.Current;
                        if (constrs == null)
                        {
                            constrs = new Set <Term>(Term.Compare);
                        }

                        if (partialRule.Item1 != null)
                        {
                            f2 = new FindData(partialRule.Item1.Item, findPatterns[partialRule.Item1.Item].Item1, findPatterns[partialRule.Item1.Item].Item2);
                        }
                        else
                        {
                            f2 = default(FindData);
                        }

                        foreach (var c in partialRule.Item2)
                        {
                            constrs.Add(c.Item);
                        }

                        f1         = rules.CompilePartialRule(f1, f2, constrs, environment);
                        outputs[i] = f1;
                        constrs    = null;
                    }
                }
            }

            return(outputs);
        }