Example #1
0
        private void ExecuteRewriteForRule(InterpreterEvaluationTerm termToRewrite, TrsReductionRule rule, UnificationResult composedUnifier)
        {
            bool rewritingTookPlaceLocal = false;

            if (composedUnifier.Succeed)
            {
                if (rule.Tail.GetType() == typeof(TrsNativeKeyword))
                {
                    // Replacing term value with a native function generated value
                    var nativeTermInHead = ((TrsTermBase)termToRewrite.CurrentSubTerm.CreateCopy()).ApplySubstitutions(composedUnifier.Unifier);
                    foreach (var native in nativeFunctions)
                    {
                        var processedTerm = native.Evaluate(nativeTermInHead);
                        if (processedTerm == null)
                        {
                            throw new Exception(string.Format("Native function in type {0} returned null", native.GetType().FullName));
                        }
                        // If the rewrite result is the same, no rewriting took place ...
                        if (!nativeTermInHead.Equals(processedTerm))
                        {
                            var newTerm = termToRewrite.RootTerm.CreateCopyAndReplaceSubTerm(termToRewrite.CurrentSubTerm, processedTerm);
                            rewritingTookPlaceLocal = true;
                            var newTermWrapper = new InterpreterTerm(newTerm);
                            newTermWrapper.IsNewTerm = true;
                            executionCache.Add(newTermWrapper);
                        }
                    }
                }
                else
                {
                    // Normal rewriting without native eval functions
                    var replacementTerm = ((TrsTermBase)rule.Tail.CreateCopy()).ApplySubstitutions(composedUnifier.Unifier);
                    if (!termToRewrite.CurrentSubTerm.Equals(replacementTerm))
                    {
                        var newTerm = termToRewrite.RootTerm.CreateCopyAndReplaceSubTerm(termToRewrite.CurrentSubTerm, replacementTerm);
                        rewritingTookPlaceLocal = true;
                        var newTermWrapper = new InterpreterTerm(newTerm);
                        newTermWrapper.IsNewTerm = true;
                        executionCache.Add(newTermWrapper);
                    }
                }
            }
            if (rewritingTookPlaceLocal)
            {
                rewritingTookPlace = true; // stops rewriting on next rewrite step
                termToRewrite.CacheSourceTerm.MustDeletFromCache = true;
            }
        }
Example #2
0
        private void ApplyReductionRuleToCache(TrsReductionRule rule)
        {
            // This data structure stores the Cartesian product used for term products
            // The length of each sub-List is the size of an alphabet for calculating a "Godel string" of terms.
            // This avoids the need for seperate sub-enumerators.
            var rewriteCandidates = new List <List <InterpreterEvaluationTerm> >();

            // Populate the rewriteCandidates
            TrsTermProduct ruleHead      = (TrsTermProduct)rule.Head;
            int            productLength = ruleHead.TermList.Count;

            for (int termProductIndex = 0; termProductIndex < productLength; termProductIndex++)
            {
                rewriteCandidates.Add(new List <InterpreterEvaluationTerm>());
                foreach (var termInCache in executionCache)
                {
                    // Do not rewrite new terms, we are doing one rewrite step at a time
                    if (termInCache.IsNewTerm)
                    {
                        continue;
                    }

                    // Test all sub-terms
                    var expantionStack = new Stack <TrsTermBase>();
                    expantionStack.Push(termInCache.RootTerm);
                    while (expantionStack.Count > 0)
                    {
                        var current = expantionStack.Pop();

                        // Ignore the "variable only" case to avoid matching all rewrite rules to a sub-term.
                        if (current is TrsVariable)
                        {
                            continue;
                        }

                        // Type rules applied here ... cater for multiple unification results by duplicating candidates
                        foreach (var unifier in mguCalculation.GetUnifier(ruleHead.TermList[termProductIndex], current))
                        {
                            if (IsUnifierValid(unifier, ruleHead.TermList[termProductIndex]))
                            {
                                rewriteCandidates[termProductIndex].Add(new InterpreterEvaluationTerm(termInCache.RootTerm, current, termInCache, unifier));
                            }
                        }

                        // Apply rewrite rule to subterms
                        if (current is TrsTerm)
                        {
                            foreach (var subTerm in ((TrsTerm)current).Arguments)
                            {
                                expantionStack.Push(subTerm);
                            }
                        }
                        else if (current is TrsAcTerm)
                        {
                            foreach (var subTerm in ((TrsAcTerm)current).OnfArguments)
                            {
                                expantionStack.Push(subTerm.Term);
                            }
                        }
                    }
                }
            }

            // Execute rewite step ... iterate over cartesian term product
            // This iterationCount variable will prevent rewriting in the case where any of the lists are empty
            int iterationCount = rewriteCandidates.First().Count;

            foreach (var termList in rewriteCandidates.Skip(1))
            {
                iterationCount *= termList.Count;
            }
            var matchTupple = new List <InterpreterEvaluationTerm>(rewriteCandidates.Count);

            for (int tuppleNumber = 0; tuppleNumber < iterationCount; tuppleNumber++)
            {
                var currDiv = tuppleNumber;
                UnificationResult currentUnifier = null;
                UnificationResult testUnifier    = null;
                matchTupple.Clear();
                // In order to do a substitution, all variables must bind to the same values across the tupple members
                for (int termColumn = 0; termColumn < rewriteCandidates.Count; termColumn++)
                {
                    var currMod = currDiv % rewriteCandidates[termColumn].Count;
                    currDiv = currDiv / rewriteCandidates[termColumn].Count;
                    var targetTerm = rewriteCandidates[termColumn][currMod];
                    currentUnifier = targetTerm.Unifier;
                    if (testUnifier == null)
                    {
                        testUnifier = currentUnifier;
                    }
                    matchTupple.Add(targetTerm);
                }
                var termProductUnifier = ComposeUnifiers(matchTupple.Select(term => term.Unifier));
                if (termProductUnifier.Succeed)
                {
                    foreach (var term in matchTupple)
                    {
                        ExecuteRewriteForRule(term, rule, termProductUnifier);
                    }
                }
            }
        }