예제 #1
0
            public IEnumerable <Pair <T, SubstitutionSet> > Unify(Stack <Name> stack, SubstitutionSet binding)
            {
                if (stack.Count == 0)                 //End stack
                {
                    if (m_hasValue)
                    {
                        yield return(Tuples.Create(m_value, binding));
                    }
                    yield break;
                }

                TreeNode nodeToEvaluate;
                Name     term = stack.Pop();

                if (!term.IsVariable)
                {
                    int numOfTerms = term.NumberOfTerms;
                    if (numOfTerms == 1)
                    {
                        var  selectedNodes = Enumerable.Empty <TreeNode>();
                        Name key           = term;
                        if (key.IsUniversal)
                        {
                            if (m_universal != null)
                            {
                                selectedNodes = selectedNodes.Append(m_universal);
                            }

                            selectedNodes = selectedNodes.Union(GetNextLevel().SelectMany(p => p.Item2));
                        }
                        else
                        {
                            if (m_nextSymbol != null && m_nextSymbol.TryGetValue(key, out nodeToEvaluate))
                            {
                                selectedNodes = selectedNodes.Append(nodeToEvaluate);
                            }

                            if (m_universal != null)
                            {
                                selectedNodes = selectedNodes.Append(m_universal);
                            }
                        }

                        foreach (var pair in selectedNodes.SelectMany(n => n.Unify(stack, binding)))
                        {
                            yield return(pair);
                        }
                    }
                    else
                    {
                        if (m_nextComposed != null && m_nextComposed.TryGetValue(numOfTerms, out nodeToEvaluate))
                        {
                            using (var it = term.GetTerms().Reverse().GetEnumerator())
                            {
                                while (it.MoveNext())
                                {
                                    stack.Push(it.Current);
                                }
                            }

                            foreach (var pair in nodeToEvaluate.Unify(stack, binding))
                            {
                                yield return(pair);
                            }

                            for (int i = 0; i < term.NumberOfTerms; i++)
                            {
                                stack.Pop();
                            }
                        }

                        if (m_universal != null)
                        {
                            foreach (var pair in m_universal.Unify(stack, binding))
                            {
                                yield return(pair);
                            }
                        }
                    }

                    if (m_nextVariable != null)
                    {
                        //Find bindings with stored variables
                        foreach (var pair in m_nextVariable)
                        {
                            var sub = new Substitution(pair.Key, new ComplexValue(term));
                            if (binding.Conflicts(sub))
                            {
                                continue;
                            }

                            var set = new SubstitutionSet(binding);
                            set.AddSubstitution(sub);
                            foreach (var r in pair.Value.Unify(stack, set))
                            {
                                yield return(r);
                            }
                        }
                    }
                }
                else
                {
                    //Find bindings
                    var nextLevel = GetNextLevel();
                    foreach (var pair in nextLevel)
                    {
                        SubstitutionSet set = binding;
                        if (!pair.Item1.IsVariable || pair.Item1 != term)
                        {
                            //Very odd trick to make certainty work
                            var sub = new Substitution(term, new ComplexValue(pair.Item1, 1));
                            if (binding.Conflicts(sub))
                            {
                                continue;
                            }

                            set = new SubstitutionSet(set);
                            set.AddSubstitution(sub);
                        }

                        foreach (var node in pair.Item2)
                        {
                            foreach (var r in node.Unify(stack, set))
                            {
                                yield return(r);
                            }
                        }
                    }
                }

                stack.Push(term);
            }