Beispiel #1
0
        protected override bool ApplyImpl(IGraphProcessingEnvironment procEnv)
        {
            if(!ChooseRandom)
            {
                bool res;
                try
                {
#if LOG_SEQUENCE_EXECUTION
                    procEnv.Recorder.WriteLine("Applying rule all " + GetRuleCallString(procEnv));
#endif
                    res = procEnv.ApplyRewrite(ParamBindings, -1, -1, Special, Test, Filters) > 0;
                }
                catch (NullReferenceException)
                {
                    System.Console.Error.WriteLine("Null reference exception during rule execution (null parameter?): " + Symbol);
                    throw;
                }
#if LOG_SEQUENCE_EXECUTION
                if(res)
                {
                    procEnv.Recorder.WriteLine("Matched/Applied " + Symbol);
                    procEnv.Recorder.Flush();
                }
#endif
                return res;
            }
            else
            {
                // TODO: Code duplication! Compare with BaseGraph.ApplyRewrite.

                int curMaxMatches = procEnv.MaxMatches;

                object[] parameters;
                if(ParamBindings.ArgumentExpressions.Length > 0)
                {
                    parameters = ParamBindings.Arguments;
                    for(int i = 0; i < ParamBindings.ArgumentExpressions.Length; i++)
                    {
                        if(ParamBindings.ArgumentExpressions[i] != null)
                            parameters[i] = ParamBindings.ArgumentExpressions[i].Evaluate(procEnv);
                    }
                }
                else parameters = null;

                if(ParamBindings.Subgraph!=null)
                    procEnv.SwitchToSubgraph((IGraph)ParamBindings.Subgraph.GetVariableValue(procEnv));

#if DEBUGACTIONS || MATCHREWRITEDETAIL
                procEnv.PerformanceInfo.StartLocal();
#endif
                IMatches matches;
                try
                {
                    matches = ParamBindings.Action.Match(procEnv, curMaxMatches, parameters);
                    for(int i = 0; i < Filters.Count; ++i)
                        ParamBindings.Action.Filter(procEnv, matches, Filters[i]);
                }
                catch (NullReferenceException)
                {
                    System.Console.Error.WriteLine("Null reference exception during rule execution (null parameter?): " + Symbol);
                    throw;
                }
#if DEBUGACTIONS || MATCHREWRITEDETAIL
                procEnv.PerformanceInfo.StopMatch(); // total match time does NOT include listeners anymore
#endif
                procEnv.PerformanceInfo.MatchesFound += matches.Count;

                procEnv.Matched(matches, null, Special);

                bool result = Rewrite(procEnv, matches, null);

                if(ParamBindings.Subgraph != null)
                    procEnv.ReturnFromSubgraph();
                
                return result;
            }
        }
Beispiel #2
0
        protected override bool ApplyImpl(IGraphProcessingEnvironment procEnv)
        {
            // first get all matches of the rule
            object[] parameters;
            if(Rule.ParamBindings.ArgumentExpressions.Length > 0)
            {
                parameters = Rule.ParamBindings.Arguments;
                for(int j = 0; j < Rule.ParamBindings.ArgumentExpressions.Length; j++)
                {
                    if(Rule.ParamBindings.ArgumentExpressions[j] != null)
                        parameters[j] = Rule.ParamBindings.ArgumentExpressions[j].Evaluate(procEnv);
                }
            }
            else parameters = null;

#if LOG_SEQUENCE_EXECUTION
            procEnv.Recorder.WriteLine("Matching backtrack all " + Rule.GetRuleCallString(procEnv));
#endif

#if DEBUGACTIONS || MATCHREWRITEDETAIL
            procEnv.PerformanceInfo.StartLocal();
#endif
            IMatches matches = Rule.ParamBindings.Action.Match(procEnv, procEnv.MaxMatches, parameters);
            for(int i=0; i<Rule.Filters.Count; ++i)
                Rule.ParamBindings.Action.Filter(procEnv, matches, Rule.Filters[i]);

#if DEBUGACTIONS || MATCHREWRITEDETAIL
            procEnv.PerformanceInfo.StopMatch(); // total match time does NOT include listeners anymore
#endif
            procEnv.PerformanceInfo.MatchesFound += matches.Count;

            if(matches.Count == 0)
            {
                Rule.executionState = SequenceExecutionState.Fail;
                return false;
            }

#if LOG_SEQUENCE_EXECUTION
            for(int i = 0; i < matches.Count; ++i)
            {
                procEnv.Recorder.WriteLine("match " + i + ": " + MatchPrinter.ToString(matches.GetMatch(i), procEnv.Graph, ""));
            }
#endif

            // the rule might be called again in the sequence, overwriting the matches object of the action
            // normally it's safe to assume the rule is not called again until its matches were processed,
            // allowing for the one matches object memory optimization, but here we must clone to prevent bad side effect
            // TODO: optimization; if it's ensured the sequence doesn't call this action again, we can omit this, requires call analysis
            matches = matches.Clone();

#if LOG_SEQUENCE_EXECUTION
            for(int i = 0; i < matches.Count; ++i)
            {
                procEnv.Recorder.WriteLine("cloned match " + i + ": " + MatchPrinter.ToString(matches.GetMatch(i), procEnv.Graph, ""));
            }
#endif

            // apply the rule and the following sequence for every match found,
            // until the first rule and sequence execution succeeded
            // rolling back the changes of failing executions until then
            int matchesTried = 0;
            foreach(IMatch match in matches)
            {
                ++matchesTried;
#if LOG_SEQUENCE_EXECUTION
                procEnv.Recorder.WriteLine("Applying backtrack match " + matchesTried + "/" + matches.Count + " of " + Rule.GetRuleCallString(procEnv));
                procEnv.Recorder.WriteLine("match: " + MatchPrinter.ToString(match, procEnv.Graph, ""));
#endif

                // start a transaction
                int transactionID = procEnv.TransactionManager.Start();
                int oldRewritesPerformed = procEnv.PerformanceInfo.RewritesPerformed;

                procEnv.EnteringSequence(Rule);
                Rule.executionState = SequenceExecutionState.Underway;
#if LOG_SEQUENCE_EXECUTION
                procEnv.Recorder.WriteLine("Before executing sequence " + Rule.Id + ": " + Rule.Symbol);
#endif
                procEnv.Matched(matches, match, Rule.Special);
                bool result = Rule.Rewrite(procEnv, matches, match);
#if LOG_SEQUENCE_EXECUTION
                procEnv.Recorder.WriteLine("After executing sequence " + Rule.Id + ": " + Rule.Symbol + " result " + result);
#endif
                Rule.executionState = result ? SequenceExecutionState.Success : SequenceExecutionState.Fail;
                procEnv.ExitingSequence(Rule);

                // rule applied, now execute the sequence
                result = Seq.Apply(procEnv);

                // if sequence execution failed, roll the changes back and try the next match of the rule
                if(!result)
                {
                    procEnv.TransactionManager.Rollback(transactionID);
                    procEnv.PerformanceInfo.RewritesPerformed = oldRewritesPerformed;
                    if(matchesTried < matches.Count)
                    {
                        procEnv.EndOfIteration(true, this);
                        Rule.ResetExecutionState();
                        Seq.ResetExecutionState();
                        continue;
                    }
                    else
                    {
                        // all matches tried, all failed later on -> end in fail
#if LOG_SEQUENCE_EXECUTION
                        procEnv.Recorder.WriteLine("Applying backtrack match exhausted " + Rule.GetRuleCallString(procEnv));
#endif
                        procEnv.EndOfIteration(false, this);
                        return false;
                    }
                }

                // if sequence execution succeeded, commit the changes so far and succeed
                procEnv.TransactionManager.Commit(transactionID);
                procEnv.EndOfIteration(false, this);
                return true;
            }

            return false; // to satisfy the compiler, we return from inside the loop
        }
Beispiel #3
0
        protected override bool ApplyImpl(IGraphProcessingEnvironment procEnv)
        {
            bool res = true;

            // first get all matches of the rule
            object[] parameters;
            if(Rule.ParamBindings.ArgumentExpressions.Length > 0)
            {
                parameters = Rule.ParamBindings.Arguments;
                for(int j = 0; j < Rule.ParamBindings.ArgumentExpressions.Length; j++)
                {
                    if(Rule.ParamBindings.ArgumentExpressions[j] != null)
                        parameters[j] = Rule.ParamBindings.ArgumentExpressions[j].Evaluate(procEnv);
                }
            }
            else parameters = null;

#if LOG_SEQUENCE_EXECUTION
            procEnv.Recorder.WriteLine("Matching for rule " + Rule.GetRuleCallString(procEnv));
#endif

#if DEBUGACTIONS || MATCHREWRITEDETAIL
            procEnv.PerformanceInfo.StartLocal();
#endif
            IMatches matches = Rule.ParamBindings.Action.Match(procEnv, procEnv.MaxMatches, parameters);
            for(int i=0; i<Rule.Filters.Count; ++i)
                Rule.ParamBindings.Action.Filter(procEnv, matches, Rule.Filters[i]);
#if DEBUGACTIONS || MATCHREWRITEDETAIL
            procEnv.PerformanceInfo.StopMatch(); // total match time does NOT include listeners anymore
#endif
            procEnv.PerformanceInfo.MatchesFound += matches.Count;

            if(matches.Count == 0)
            {
                procEnv.EndOfIteration(false, this);
                Rule.executionState = SequenceExecutionState.Fail;
                return res;
            }

#if LOG_SEQUENCE_EXECUTION
            procEnv.Recorder.WriteLine("Rule " + Rule.GetRuleCallString(procEnv) + " matched " + matches.Count + " times");
#endif

            // the rule might be called again in the sequence, overwriting the matches object of the action
            // normally it's safe to assume the rule is not called again until its matches were processed,
            // allowing for the one matches object memory optimization, but here we must clone to prevent bad side effect
            // TODO: optimization; if it's ensured the sequence doesn't call this action again, we can omit this, requires call analysis
            matches = matches.Clone();

            // apply the sequence for every match found
            bool first = true;
            foreach(IMatch match in matches)
            {
                if(!first) procEnv.EndOfIteration(true, this);
                Var.SetVariableValue(match, procEnv);
#if LOG_SEQUENCE_EXECUTION
                procEnv.Recorder.WriteLine("Iterating match: " + MatchPrinter.ToString(match, procEnv.Graph, ""));
#endif

                procEnv.EnteringSequence(Rule);
                Rule.executionState = SequenceExecutionState.Underway;
                procEnv.Matched(matches, match, Rule.Special);
                Rule.executionState = SequenceExecutionState.Success;
                procEnv.ExitingSequence(Rule);

                // rule matching simulated so it can be shown in the debugger, now execute the sequence
                Seq.ResetExecutionState();
                res &= Seq.Apply(procEnv);
                first = false;
            }
            procEnv.EndOfIteration(false, this);
            return res;
        }
Beispiel #4
0
        protected bool ApplyRule(SequenceRuleCall rule, IGraphProcessingEnvironment procEnv, IMatches matches, IMatch match)
        {
            bool result;
            procEnv.EnteringSequence(rule);
            rule.executionState = SequenceExecutionState.Underway;
#if LOG_SEQUENCE_EXECUTION
            procEnv.Recorder.WriteLine("Before executing sequence " + rule.Id + ": " + rule.Symbol);
#endif
            procEnv.Matched(matches, null, rule.Special);
            result = rule.Rewrite(procEnv, matches, match);
#if LOG_SEQUENCE_EXECUTION
            procEnv.Recorder.WriteLine("After executing sequence " + rule.Id + ": " + rule.Symbol + " result " + result);
#endif
            rule.executionState = result ? SequenceExecutionState.Success : SequenceExecutionState.Fail;
            procEnv.ExitingSequence(rule);
            return result;
        }