Beispiel #1
0
        private static void GetFilteredParametersAndSuffixedMatcherName(
            LGSPRulePattern rulePattern, PatternGraph patternGraph, int index,
            out String[] paramTypesArray, out String[] paramNamesArray, out String suffixedMatcherName)
        {
            List <String> paramTypes   = new List <String>();
            List <String> paramNames   = new List <String>();
            List <String> removedNames = new List <String>();

            for (int i = 0; i < rulePattern.Inputs.Length; ++i)
            {
                String inputName = rulePattern.InputNames[i];
                if (patternGraph.availabilityOfMaybeNullElements[index].ContainsKey(inputName) &&
                    !patternGraph.availabilityOfMaybeNullElements[index][inputName])
                {
                    removedNames.Add(rulePattern.InputNames[i]);
                }
                else
                {
                    paramTypes.Add(TypesHelper.TypeName(rulePattern.Inputs[i]));
                    paramNames.Add(rulePattern.InputNames[i]);
                }
            }
            paramTypesArray = new String[paramTypes.Count];
            paramNamesArray = new String[paramNames.Count];
            for (int i = 0; i < paramTypes.Count; ++i)
            {
                paramTypesArray[i] = paramTypes[i];
                paramNamesArray[i] = paramNames[i];
            }
            suffixedMatcherName = "myMatch";
            foreach (String removedName in removedNames)
            {
                suffixedMatcherName += "_MissingPreset_" + removedName;
            }
        }
        /// <summary>
        // generate implementation of the exact action interface,
        // delegate calls of the inexact action interface IAction to the exact action interface
        /// </summary>
        void GenerateActionImplementation(SourceBuilder sb, LGSPRulePattern matchingPattern)
        {
            StringBuilder sbInParameters = new StringBuilder();
            StringBuilder sbInArguments = new StringBuilder();
            StringBuilder sbInArgumentsFromArray = new StringBuilder();
            for(int i = 0; i < matchingPattern.Inputs.Length; ++i)
            {
                sbInParameters.Append(", ");
                sbInParameters.Append(TypesHelper.TypeName(matchingPattern.Inputs[i]));
                sbInParameters.Append(" ");
                sbInParameters.Append(matchingPattern.InputNames[i]);

                sbInArguments.Append(", ");
                sbInArguments.Append(matchingPattern.InputNames[i]);

                sbInArgumentsFromArray.Append(", (");
                sbInArgumentsFromArray.Append(TypesHelper.TypeName(matchingPattern.Inputs[i]));
                sbInArgumentsFromArray.Append(") parameters[");
                sbInArgumentsFromArray.Append(i);
                sbInArgumentsFromArray.Append("]");
            }
            String inParameters = sbInParameters.ToString();
            String inArguments = sbInArguments.ToString();
            String inArgumentsFromArray = sbInArgumentsFromArray.ToString();

            StringBuilder sbOutParameters = new StringBuilder();
            StringBuilder sbRefParameters = new StringBuilder();
            StringBuilder sbOutLocals = new StringBuilder();
            StringBuilder sbRefLocals = new StringBuilder();
            StringBuilder sbOutArguments = new StringBuilder();
            StringBuilder sbRefArguments = new StringBuilder();
            StringBuilder sbOutIntermediateLocalsAll = new StringBuilder();
            StringBuilder sbOutParametersAll = new StringBuilder();
            StringBuilder sbOutArgumentsAll = new StringBuilder();
            StringBuilder sbIntermediateLocalArgumentsAll = new StringBuilder();
            StringBuilder sbOutClassArgumentsAll = new StringBuilder();
            for(int i = 0; i < matchingPattern.Outputs.Length; ++i)
            {
                sbOutParameters.Append(", out ");
                sbOutParameters.Append(TypesHelper.TypeName(matchingPattern.Outputs[i]));
                sbOutParameters.Append(" output_");
                sbOutParameters.Append(i);

                sbRefParameters.Append(", ref ");
                sbRefParameters.Append(TypesHelper.TypeName(matchingPattern.Outputs[i]));
                sbRefParameters.Append(" output_");
                sbRefParameters.Append(i);

                sbOutLocals.Append(TypesHelper.TypeName(matchingPattern.Outputs[i]));
                sbOutLocals.Append(" output_");
                sbOutLocals.Append(i);
                sbOutLocals.Append("; ");

                sbRefLocals.Append(TypesHelper.TypeName(matchingPattern.Outputs[i]));
                sbRefLocals.Append(" output_");
                sbRefLocals.Append(i);
                sbRefLocals.Append(" = ");
                sbRefLocals.Append(TypesHelper.DefaultValueString(matchingPattern.Outputs[i].PackagePrefixedName, model));
                sbRefLocals.Append("; ");

                sbOutArguments.Append(", out output_");
                sbOutArguments.Append(i);

                sbRefArguments.Append(", ref output_");
                sbRefArguments.Append(i);

                sbOutIntermediateLocalsAll.Append(TypesHelper.TypeName(matchingPattern.Outputs[i]));
                sbOutIntermediateLocalsAll.Append(" output_local_");
                sbOutIntermediateLocalsAll.Append(i);
                sbOutIntermediateLocalsAll.Append("; ");

                sbOutParametersAll.Append(", List<");
                sbOutParametersAll.Append(TypesHelper.TypeName(matchingPattern.Outputs[i]));
                sbOutParametersAll.Append("> output_");
                sbOutParametersAll.Append(i);

                sbOutArgumentsAll.Append(", output_");
                sbOutArgumentsAll.Append(i);

                sbIntermediateLocalArgumentsAll.Append(", out output_local_");
                sbIntermediateLocalArgumentsAll.Append(i);

                sbOutClassArgumentsAll.Append(", output_list_");
                sbOutClassArgumentsAll.Append(i);
            }
            String outParameters = sbOutParameters.ToString();
            String refParameters = sbRefParameters.ToString();
            String outLocals = sbOutLocals.ToString();
            String refLocals = sbRefLocals.ToString();
            String outArguments = sbOutArguments.ToString();
            String refArguments = sbRefArguments.ToString();
            String outIntermediateLocalsAll = sbOutIntermediateLocalsAll.ToString();
            String outParametersAll = sbOutParametersAll.ToString();
            String outArgumentsAll = sbOutArgumentsAll.ToString();
            String intermediateLocalArgumentsAll = sbIntermediateLocalArgumentsAll.ToString();
            String outClassArgumentsAll = sbOutClassArgumentsAll.ToString();
 
            String matchingPatternClassName = matchingPattern.GetType().Name;
            String patternName = matchingPattern.name;
            String matchType = matchingPatternClassName + "." + NamesOfEntities.MatchInterfaceName(patternName);
            String matchesType = "GRGEN_LIBGR.IMatchesExact<" + matchType + ">";

            // implementation of exact action interface

            sb.AppendFront("/// <summary> Type of the matcher method (with parameters processing environment containing host graph, maximum number of matches to search for (zero=unlimited), and rule parameters; returning found matches). </summary>\n");
            sb.AppendFrontFormat("public delegate {0} MatchInvoker(GRGEN_LGSP.LGSPActionExecutionEnvironment actionEnv, int maxMatches{1});\n", matchesType, inParameters);

            sb.AppendFront("/// <summary> A delegate pointing to the current matcher program for this rule. </summary>\n");
            sb.AppendFront("public MatchInvoker DynamicMatch;\n");

            sb.AppendFront("/// <summary> The RulePattern object from which this LGSPAction object has been created. </summary>\n");
            sb.AppendFront("public GRGEN_LIBGR.IRulePattern RulePattern { get { return _rulePattern; } }\n");

            for(int i = 0; i < matchingPattern.Outputs.Length; ++i)
            {
                sb.AppendFront("List<");
                sb.Append(TypesHelper.TypeName(matchingPattern.Outputs[i]));
                sb.Append("> output_list_");
                sb.Append(i.ToString());
                sb.Append(" = new List<");
                sb.Append(TypesHelper.TypeName(matchingPattern.Outputs[i]));
                sb.Append(">();\n");
            }

            sb.AppendFrontFormat("public {0} Match(GRGEN_LIBGR.IActionExecutionEnvironment actionEnv, int maxMatches{1})\n", matchesType, inParameters);
            sb.AppendFront("{\n");
            sb.Indent();
            sb.AppendFrontFormat("return DynamicMatch((GRGEN_LGSP.LGSPActionExecutionEnvironment)actionEnv, maxMatches{0});\n", inArguments);
            sb.Unindent();
            sb.AppendFront("}\n");

            sb.AppendFrontFormat("public void Modify(GRGEN_LIBGR.IActionExecutionEnvironment actionEnv, {0} match{1})\n", matchType, outParameters);
            sb.AppendFront("{\n");
            sb.Indent();
            sb.AppendFrontFormat("_rulePattern.Modify((GRGEN_LGSP.LGSPActionExecutionEnvironment)actionEnv, match{0});\n", outArguments);
            sb.Unindent();
            sb.AppendFront("}\n");

            sb.AppendFrontFormat("public void ModifyAll(GRGEN_LIBGR.IActionExecutionEnvironment actionEnv, {0} matches{1})\n", matchesType, outParametersAll);
            sb.AppendFront("{\n");
            sb.Indent();
            sb.AppendFrontFormat("foreach({0} match in matches)\n", matchType);
            sb.AppendFront("{\n");
            sb.Indent();
            sb.AppendFrontFormat("{0}\n", outIntermediateLocalsAll);
            sb.AppendFrontFormat("_rulePattern.Modify((GRGEN_LGSP.LGSPActionExecutionEnvironment)actionEnv, match{0});\n", intermediateLocalArgumentsAll);
            for(int i = 0; i < matchingPattern.Outputs.Length; ++i) {
                sb.AppendFrontFormat("output_{0}.Add(output_local_{0});\n", i);
            }
            sb.Unindent();
            sb.AppendFront("}\n");
            sb.Unindent();
            sb.AppendFront("}\n");

            sb.AppendFrontFormat("public bool Apply(GRGEN_LIBGR.IActionExecutionEnvironment actionEnv{0}{1})\n", inParameters, refParameters);
            sb.AppendFront("{\n");
            sb.Indent();
            sb.AppendFrontFormat("{0} matches = DynamicMatch((GRGEN_LGSP.LGSPActionExecutionEnvironment)actionEnv, 1{1});\n", matchesType, inArguments);
            sb.AppendFront("if(matches.Count <= 0) return false;\n");
            sb.AppendFrontFormat("_rulePattern.Modify((GRGEN_LGSP.LGSPActionExecutionEnvironment)actionEnv, matches.First{0});\n", outArguments);
            sb.AppendFront("return true;\n");
            sb.Unindent();
            sb.AppendFront("}\n");

            sb.AppendFrontFormat("public int ApplyAll(int maxMatches, GRGEN_LIBGR.IActionExecutionEnvironment actionEnv{0}{1})\n", inParameters, outParametersAll);
            sb.AppendFront("{\n");
            sb.Indent();
            sb.AppendFrontFormat("{0} matches = DynamicMatch((GRGEN_LGSP.LGSPActionExecutionEnvironment)actionEnv, maxMatches{1});\n", matchesType, inArguments);
            sb.AppendFront("if(matches.Count <= 0) return 0;\n");
            sb.AppendFrontFormat("foreach({0} match in matches)\n", matchType);
            sb.AppendFront("{\n");
            sb.Indent();
            sb.AppendFrontFormat("{0}\n", outIntermediateLocalsAll);
            sb.AppendFrontFormat("_rulePattern.Modify((GRGEN_LGSP.LGSPActionExecutionEnvironment)actionEnv, match{0});\n", intermediateLocalArgumentsAll);
            for(int i = 0; i < matchingPattern.Outputs.Length; ++i) {
                sb.AppendFrontFormat("output_{0}.Add(output_local_{0});\n", i);
            }
            sb.Unindent();
            sb.AppendFront("}\n");
            sb.AppendFront("return matches.Count;\n");
            sb.Unindent();
            sb.AppendFront("}\n");

            sb.AppendFrontFormat("public bool ApplyStar(GRGEN_LIBGR.IActionExecutionEnvironment actionEnv{0})\n", inParameters);
            sb.AppendFront("{\n");
            sb.Indent();
            sb.AppendFrontFormat("{0} matches;\n", matchesType);
            sb.AppendFrontFormat("{0}\n", outLocals);

            sb.AppendFront("while(true)\n");
            sb.AppendFront("{\n");
            sb.Indent();
            sb.AppendFrontFormat("matches = DynamicMatch((GRGEN_LGSP.LGSPActionExecutionEnvironment)actionEnv, 1{0});\n", inArguments);
            sb.AppendFront("if(matches.Count <= 0) return true;\n");
            sb.AppendFrontFormat("_rulePattern.Modify((GRGEN_LGSP.LGSPActionExecutionEnvironment)actionEnv, matches.First{0});\n", outArguments);
            sb.Unindent();
            sb.AppendFront("}\n");
            sb.Unindent();
            sb.AppendFront("}\n");

            sb.AppendFrontFormat("public bool ApplyPlus(GRGEN_LIBGR.IActionExecutionEnvironment actionEnv{0})\n", inParameters);
            sb.AppendFront("{\n");
            sb.Indent();
            sb.AppendFrontFormat("{0} matches = DynamicMatch((GRGEN_LGSP.LGSPActionExecutionEnvironment)actionEnv, 1{1});\n", matchesType, inArguments);
            sb.AppendFront("if(matches.Count <= 0) return false;\n");
            sb.AppendFrontFormat("{0}\n", outLocals);
            sb.AppendFront("do\n");
            sb.AppendFront("{\n");
            sb.Indent();
            sb.AppendFrontFormat("_rulePattern.Modify((GRGEN_LGSP.LGSPActionExecutionEnvironment)actionEnv, matches.First{0});\n", outArguments);
            sb.AppendFrontFormat("matches = DynamicMatch((GRGEN_LGSP.LGSPActionExecutionEnvironment)actionEnv, 1{0});\n", inArguments);
            sb.Unindent();
            sb.AppendFront("}\n");
            sb.AppendFront("while(matches.Count > 0) ;\n");
            sb.AppendFront("return true;\n");
            sb.Unindent();
            sb.AppendFront("}\n");

            sb.AppendFrontFormat("public bool ApplyMinMax(GRGEN_LIBGR.IActionExecutionEnvironment actionEnv, int min, int max{0})\n", inParameters);
            sb.AppendFront("{\n");
            sb.Indent();
            sb.AppendFrontFormat("{0} matches;\n", matchesType);
            sb.AppendFrontFormat("{0}\n", outLocals);
            sb.AppendFront("for(int i = 0; i < max; i++)\n");
            sb.AppendFront("{\n");
            sb.Indent();
            sb.AppendFrontFormat("matches = DynamicMatch((GRGEN_LGSP.LGSPActionExecutionEnvironment)actionEnv, 1{0});\n", inArguments);
            sb.AppendFront("if(matches.Count <= 0) return i >= min;\n");
            sb.AppendFrontFormat("_rulePattern.Modify((GRGEN_LGSP.LGSPActionExecutionEnvironment)actionEnv, matches.First{0});\n", outArguments);
            sb.Unindent();
            sb.AppendFront("}\n");
            sb.AppendFront("return true;\n");
            sb.Unindent();
            sb.AppendFront("}\n");

            // implementation of inexact action interface by delegation to exact action interface
            sb.AppendFront("// implementation of inexact action interface by delegation to exact action interface\n");

            sb.AppendFront("public GRGEN_LIBGR.IMatches Match(GRGEN_LIBGR.IActionExecutionEnvironment actionEnv, int maxMatches, object[] parameters)\n");
            sb.AppendFront("{\n");
            sb.Indent();
            sb.AppendFrontFormat("return Match(actionEnv, maxMatches{0});\n", inArgumentsFromArray);
            sb.Unindent(); 
            sb.AppendFront("}\n");

            sb.AppendFront("public object[] Modify(GRGEN_LIBGR.IActionExecutionEnvironment actionEnv, GRGEN_LIBGR.IMatch match)\n");
            sb.AppendFront("{\n");
            sb.Indent();
            sb.AppendFrontFormat("{0}\n", outLocals);
            sb.AppendFrontFormat("Modify(actionEnv, ({0})match{1});\n", matchType, outArguments);
            for(int i = 0; i < matchingPattern.Outputs.Length; ++i) {
                sb.AppendFrontFormat("ReturnArray[{0}] = output_{0};\n", i);
            }
            sb.AppendFront("return ReturnArray;\n");
            sb.Unindent(); 
            sb.AppendFront("}\n");

            sb.AppendFront("public List<object[]> ModifyAll(GRGEN_LIBGR.IActionExecutionEnvironment actionEnv, GRGEN_LIBGR.IMatches matches)\n");
            sb.AppendFront("{\n");
            sb.Indent();

            for(int i = 0; i < matchingPattern.Outputs.Length; ++i)
            {
                sb.AppendFront("output_list_");
                sb.Append(i.ToString());
                sb.Append(".Clear();\n");
            }
            sb.AppendFrontFormat("ModifyAll(actionEnv, ({0})matches{1});\n", matchesType, outClassArgumentsAll);

            sb.AppendFront("while(AvailableReturnArrays.Count < matches.Count) AvailableReturnArrays.Add(new object[" + matchingPattern.Outputs.Length + "]);\n");
            sb.AppendFront("ReturnArrayListForAll.Clear();\n");
            sb.AppendFront("for(int i=0; i<matches.Count; ++i)\n");
            sb.AppendFront("{\n");
            sb.Indent();
            sb.AppendFront("ReturnArrayListForAll.Add(AvailableReturnArrays[i]);\n");
            for(int i = 0; i < matchingPattern.Outputs.Length; ++i) {
                sb.AppendFrontFormat("ReturnArrayListForAll[i][{0}] = output_list_{0}[i];\n", i);
            }
            sb.Unindent();
            sb.AppendFront("}\n");

            sb.AppendFront("return ReturnArrayListForAll;\n");
            sb.Unindent(); 
            sb.AppendFront("}\n");

            sb.AppendFront("object[] GRGEN_LIBGR.IAction.Apply(GRGEN_LIBGR.IActionExecutionEnvironment actionEnv)\n");
            sb.AppendFront("{\n");
            sb.Indent();
            if(matchingPattern.Inputs.Length == 0) {
                sb.AppendFrontFormat("{0}\n", refLocals);
                sb.AppendFrontFormat("if(Apply(actionEnv{0})) ", refArguments);
                sb.Append("{\n");
                sb.Indent();
                for(int i = 0; i < matchingPattern.Outputs.Length; ++i) {
                    sb.AppendFrontFormat("ReturnArray[{0}] = output_{0};\n", i);
                }
                sb.AppendFront("return ReturnArray;\n");
                sb.Unindent();
                sb.AppendFront("}\n");
                sb.AppendFront("else return null;\n");
            }
            else
                sb.AppendFront("throw new Exception();\n");
            sb.Unindent(); 
            sb.AppendFront("}\n");

            sb.AppendFront("object[] GRGEN_LIBGR.IAction.Apply(GRGEN_LIBGR.IActionExecutionEnvironment actionEnv, params object[] parameters)\n");
            sb.AppendFront("{\n");
            sb.Indent();
            sb.AppendFrontFormat("{0}\n", refLocals);
            sb.AppendFrontFormat("if(Apply(actionEnv{0}{1})) ", inArgumentsFromArray, refArguments);
            sb.Append("{\n");
            sb.Indent();
            for(int i = 0; i < matchingPattern.Outputs.Length; ++i) {
                sb.AppendFrontFormat("ReturnArray[{0}] = output_{0};\n", i);
            }
            sb.AppendFront("return ReturnArray;\n");
            sb.Unindent(); 
            sb.AppendFront("}\n");
            sb.AppendFront("else return null;\n");
            sb.Unindent();
            sb.AppendFront("}\n");

            sb.AppendFront("public List<object[]> Reserve(int numReturns)\n");
            sb.AppendFront("{\n");
            sb.Indent();
            sb.AppendFront("while(AvailableReturnArrays.Count < numReturns) AvailableReturnArrays.Add(new object[" + matchingPattern.Outputs.Length + "]);\n");
            sb.AppendFront("ReturnArrayListForAll.Clear();\n");
            sb.AppendFront("for(int i=0; i<numReturns; ++i)\n");
            sb.AppendFront("{\n");
            sb.Indent();
            sb.AppendFront("ReturnArrayListForAll.Add(AvailableReturnArrays[i]);\n");
            sb.Unindent();
            sb.AppendFront("}\n");
            sb.AppendFront("return ReturnArrayListForAll;\n");
            sb.Unindent();
            sb.AppendFront("}\n");

            sb.AppendFront("List<object[]> GRGEN_LIBGR.IAction.ApplyAll(int maxMatches, GRGEN_LIBGR.IActionExecutionEnvironment actionEnv)\n");
            sb.AppendFront("{\n");
            sb.Indent();
            if(matchingPattern.Inputs.Length == 0) {
                for(int i = 0; i < matchingPattern.Outputs.Length; ++i)
                {
                    sb.AppendFront("output_list_");
                    sb.Append(i.ToString());
                    sb.Append(".Clear();\n");
                }
                sb.AppendFrontFormat("int matchesCount = ApplyAll(maxMatches, actionEnv{0});\n", outClassArgumentsAll);
                sb.AppendFront("while(AvailableReturnArrays.Count < matchesCount) AvailableReturnArrays.Add(new object[" + matchingPattern.Outputs.Length + "]);\n");
                sb.AppendFront("ReturnArrayListForAll.Clear();\n");
                sb.AppendFront("for(int i=0; i<matchesCount; ++i)\n");
                sb.AppendFront("{\n");
                sb.Indent();
                sb.AppendFront("ReturnArrayListForAll.Add(AvailableReturnArrays[i]);\n");
                for(int i = 0; i < matchingPattern.Outputs.Length; ++i) {
                    sb.AppendFrontFormat("ReturnArrayListForAll[i][{0}] = output_list_{0}[i];\n", i);
                }
                sb.Unindent();
                sb.AppendFront("}\n");
                sb.AppendFront("return ReturnArrayListForAll;\n");
            }
            else
                sb.AppendFront("throw new Exception();\n");
            sb.Unindent(); 
            sb.AppendFront("}\n");

            sb.AppendFront("List<object[]> GRGEN_LIBGR.IAction.ApplyAll(int maxMatches, GRGEN_LIBGR.IActionExecutionEnvironment actionEnv, params object[] parameters)\n");
            sb.AppendFront("{\n");
            sb.Indent();
            for(int i = 0; i < matchingPattern.Outputs.Length; ++i)
            {
                sb.AppendFront("output_list_");
                sb.Append(i.ToString());
                sb.Append(".Clear();\n");
            }
            sb.AppendFrontFormat("int matchesCount = ApplyAll(maxMatches, actionEnv{0}{1});\n", inArgumentsFromArray, outClassArgumentsAll);
            sb.AppendFront("while(AvailableReturnArrays.Count < matchesCount) AvailableReturnArrays.Add(new object[" + matchingPattern.Outputs.Length + "]);\n");
            sb.AppendFront("ReturnArrayListForAll.Clear();\n");
            sb.AppendFront("for(int i=0; i<matchesCount; ++i)\n");
            sb.AppendFront("{\n");
            sb.Indent();
            sb.AppendFront("ReturnArrayListForAll.Add(AvailableReturnArrays[i]);\n");
            for(int i = 0; i < matchingPattern.Outputs.Length; ++i) {
                sb.AppendFrontFormat("ReturnArrayListForAll[i][{0}] = output_list_{0}[i];\n", i);
            }
            sb.Unindent();
            sb.AppendFront("}\n");
            sb.AppendFront("return ReturnArrayListForAll;\n");
            sb.Unindent();
            sb.AppendFront("}\n");

            sb.AppendFront("bool GRGEN_LIBGR.IAction.ApplyStar(GRGEN_LIBGR.IActionExecutionEnvironment actionEnv)\n");
            sb.AppendFront("{\n");
            sb.Indent();
            if(matchingPattern.Inputs.Length == 0)
                sb.AppendFront("return ApplyStar(actionEnv);\n");
            else
                sb.AppendFront("throw new Exception(); return false;\n");
            sb.Unindent(); 
            sb.AppendFront("}\n");

            sb.AppendFront("bool GRGEN_LIBGR.IAction.ApplyStar(GRGEN_LIBGR.IActionExecutionEnvironment actionEnv, params object[] parameters)\n");
            sb.AppendFront("{\n");
            sb.Indent();
            sb.AppendFrontFormat("return ApplyStar(actionEnv{0});\n", inArgumentsFromArray);
            sb.Unindent(); 
            sb.AppendFront("}\n");

            sb.AppendFront("bool GRGEN_LIBGR.IAction.ApplyPlus(GRGEN_LIBGR.IActionExecutionEnvironment actionEnv)\n");
            sb.AppendFront("{\n");
            sb.Indent();
            if(matchingPattern.Inputs.Length == 0)
                sb.AppendFront("return ApplyPlus(actionEnv);\n");
            else
                sb.AppendFront("throw new Exception(); return false;\n");
            sb.Unindent(); 
            sb.AppendFront("}\n");

            sb.AppendFront("bool GRGEN_LIBGR.IAction.ApplyPlus(GRGEN_LIBGR.IActionExecutionEnvironment actionEnv, params object[] parameters)\n");
            sb.AppendFront("{\n");
            sb.Indent();
            sb.AppendFrontFormat("return ApplyPlus(actionEnv{0});\n", inArgumentsFromArray);
            sb.Unindent(); 
            sb.AppendFront("}\n");

            sb.AppendFront("bool GRGEN_LIBGR.IAction.ApplyMinMax(GRGEN_LIBGR.IActionExecutionEnvironment actionEnv, int min, int max)\n");
            sb.AppendFront("{\n");
            sb.Indent();
            if(matchingPattern.Inputs.Length == 0)
                sb.AppendFront("return ApplyMinMax(actionEnv, min, max);\n");
            else 
                sb.AppendFront("throw new Exception(); return false;\n");
            sb.Unindent(); 
            sb.AppendFront("}\n");

            sb.AppendFront("bool GRGEN_LIBGR.IAction.ApplyMinMax(GRGEN_LIBGR.IActionExecutionEnvironment actionEnv, int min, int max, params object[] parameters)\n");
            sb.AppendFront("{\n");
            sb.Indent(); 
            sb.AppendFrontFormat("return ApplyMinMax(actionEnv, min, max{0});\n", inArgumentsFromArray);
            sb.Unindent(); 
            sb.AppendFront("}\n");

            sb.AppendFront("void GRGEN_LIBGR.IAction.Filter(GRGEN_LIBGR.IActionExecutionEnvironment actionEnv, GRGEN_LIBGR.IMatches matches, GRGEN_LIBGR.FilterCall filter)\n");
            sb.AppendFront("{\n");
            sb.Indent();
            sb.AppendFront("if(filter.IsAutoSupplied) {\n");
            sb.Indent();
            sb.AppendFront("switch(filter.Name) {\n");
            sb.Indent();
            sb.AppendFront("case \"keepFirst\": matches.FilterKeepFirst((int)(filter.ArgumentExpressions[0]!=null ? filter.ArgumentExpressions[0].Evaluate((GRGEN_LIBGR.IGraphProcessingEnvironment)actionEnv) : filter.Arguments[0])); break;\n");
            sb.AppendFront("case \"keepLast\": matches.FilterKeepLast((int)(filter.ArgumentExpressions[0]!=null ? filter.ArgumentExpressions[0].Evaluate((GRGEN_LIBGR.IGraphProcessingEnvironment)actionEnv) : filter.Arguments[0])); break;\n");
            sb.AppendFront("case \"keepFirstFraction\": matches.FilterKeepFirstFraction((double)(filter.ArgumentExpressions[0]!=null ? filter.ArgumentExpressions[0].Evaluate((GRGEN_LIBGR.IGraphProcessingEnvironment)actionEnv) : filter.Arguments[0])); break;\n");
            sb.AppendFront("case \"keepLastFraction\": matches.FilterKeepLastFraction((double)(filter.ArgumentExpressions[0]!=null ? filter.ArgumentExpressions[0].Evaluate((GRGEN_LIBGR.IGraphProcessingEnvironment)actionEnv) : filter.Arguments[0])); break;\n");
            sb.AppendFront("case \"removeFirst\": matches.FilterRemoveFirst((int)(filter.ArgumentExpressions[0]!=null ? filter.ArgumentExpressions[0].Evaluate((GRGEN_LIBGR.IGraphProcessingEnvironment)actionEnv) : filter.Arguments[0])); break;\n");
            sb.AppendFront("case \"removeLast\": matches.FilterRemoveLast((int)(filter.ArgumentExpressions[0]!=null ? filter.ArgumentExpressions[0].Evaluate((GRGEN_LIBGR.IGraphProcessingEnvironment)actionEnv) : filter.Arguments[0])); break;\n");
            sb.AppendFront("case \"removeFirstFraction\": matches.FilterRemoveFirstFraction((double)(filter.ArgumentExpressions[0]!=null ? filter.ArgumentExpressions[0].Evaluate((GRGEN_LIBGR.IGraphProcessingEnvironment)actionEnv) : filter.Arguments[0])); break;\n");
            sb.AppendFront("case \"removeLastFraction\": matches.FilterRemoveLastFraction((double)(filter.ArgumentExpressions[0]!=null ? filter.ArgumentExpressions[0].Evaluate((GRGEN_LIBGR.IGraphProcessingEnvironment)actionEnv) : filter.Arguments[0])); break;\n");
            sb.AppendFront("default: throw new Exception(\"Unknown auto supplied filter name!\");\n");
            sb.Unindent();
            sb.AppendFront("}\n");
            sb.AppendFront("return;\n");
            sb.Unindent();
            sb.AppendFront("}\n");
            sb.AppendFront("switch(filter.FullName) {\n");
            sb.Indent();
            foreach(IFilter filter in matchingPattern.Filters)
            {
                if(filter is IFilterAutoGenerated)
                {
                    if(((IFilterAutoGenerated)filter).Entity != null)
                    {
                        sb.AppendFrontFormat("case \"{1}<{2}>\": GRGEN_ACTIONS.{4}MatchFilters.Filter_{0}_{1}_{2}((GRGEN_LGSP.LGSPGraphProcessingEnvironment)actionEnv, ({3})matches); break;\n",
                            patternName, filter.Name, ((IFilterAutoGenerated)filter).Entity, matchesType, TypesHelper.GetPackagePrefixDot(filter.Package));
                        if(filter.Package != null)
                            sb.AppendFrontFormat("case \"{5}{1}<{2}>\": GRGEN_ACTIONS.{4}MatchFilters.Filter_{0}_{1}_{2}((GRGEN_LGSP.LGSPGraphProcessingEnvironment)actionEnv, ({3})matches); break;\n",
                                patternName, filter.Name, ((IFilterAutoGenerated)filter).Entity, matchesType, filter.Package + ".", filter.Package + "::");
                    }
                    else // auto
                    {
                        sb.AppendFrontFormat("case \"{1}\": GRGEN_ACTIONS.{3}MatchFilters.Filter_{0}_{1}((GRGEN_LGSP.LGSPGraphProcessingEnvironment)actionEnv, ({2})matches); break;\n",
                            patternName, filter.Name, matchesType, TypesHelper.GetPackagePrefixDot(filter.Package));
                        if(filter.Package != null)
                            sb.AppendFrontFormat("case \"{4}{1}\": GRGEN_ACTIONS.{3}MatchFilters.Filter_{0}_{1}((GRGEN_LGSP.LGSPGraphProcessingEnvironment)actionEnv, ({2})matches); break;\n",
                                patternName, filter.Name, matchesType, filter.Package + ".", filter.Package + "::");
                    }
                }
                else
                {
                    IFilterFunction filterFunction = (IFilterFunction)filter;
                    sb.AppendFrontFormat("case \"{0}\": GRGEN_ACTIONS.{1}MatchFilters.Filter_{2}((GRGEN_LGSP.LGSPGraphProcessingEnvironment)actionEnv, ({3})matches",
                        filterFunction.Name, TypesHelper.GetPackagePrefixDot(filterFunction.Package), filterFunction.Name, matchesType);
                    for(int i=0; i<filterFunction.Inputs.Length; ++i)
                    {
                        sb.AppendFormat(", ({0})(filter.ArgumentExpressions[{1}]!=null ? filter.ArgumentExpressions[{1}].Evaluate((GRGEN_LIBGR.IGraphProcessingEnvironment)actionEnv) : filter.Arguments[{1}])", 
                            TypesHelper.TypeName(filterFunction.Inputs[i]), i);
                    }
                    sb.Append("); break;\n");
                    if(filter.Package != null)
                    {
                        sb.AppendFrontFormat("case \"{4}{0}\": GRGEN_ACTIONS.{1}MatchFilters.Filter_{2}((GRGEN_LGSP.LGSPGraphProcessingEnvironment)actionEnv, ({3})matches",
                            filterFunction.Name, TypesHelper.GetPackagePrefixDot(filterFunction.Package), filterFunction.Name, matchesType, filter.Package + "::");
                        for(int i = 0; i < filterFunction.Inputs.Length; ++i)
                        {
                            sb.AppendFormat(", ({0})(filter.ArgumentExpressions[{1}]!=null ? filter.ArgumentExpressions[{1}].Evaluate((GRGEN_LIBGR.IGraphProcessingEnvironment)actionEnv) : filter.Arguments[{1}])",
                                TypesHelper.TypeName(filterFunction.Inputs[i]), i);
                        }
                        sb.Append("); break;\n");
                    }
                }
            }
            sb.AppendFront("default: throw new Exception(\"Unknown filter name!\");\n");
            sb.Unindent();
            sb.AppendFront("}\n");
            sb.Unindent();
            sb.AppendFront("}\n");
        }
        /// <summary>
        // generate the exact action interface
        /// </summary>
        void GenerateActionInterface(SourceBuilder sb, LGSPRulePattern matchingPattern)
        {
            String actionInterfaceName = "IAction_"+matchingPattern.name;
            String outParameters = "";
            String refParameters = "";
            String allParameters = "";
            for(int i = 0; i < matchingPattern.Outputs.Length; ++i)
            {
                outParameters += ", out " + TypesHelper.TypeName(matchingPattern.Outputs[i]) + " output_"+i;
                refParameters += ", ref " + TypesHelper.TypeName(matchingPattern.Outputs[i]) + " output_"+i;
                allParameters += ", List<" + TypesHelper.TypeName(matchingPattern.Outputs[i]) + "> output_"+i;
            }
 
            String inParameters = "";
            for(int i=0; i<matchingPattern.Inputs.Length; ++i) {
                inParameters += ", " + TypesHelper.TypeName(matchingPattern.Inputs[i]) + " " + matchingPattern.InputNames[i];
            }
            String matchingPatternClassName = matchingPattern.GetType().Name;
            String patternName = matchingPattern.name;
            String matchType = matchingPatternClassName + "." + NamesOfEntities.MatchInterfaceName(patternName);
            String matchesType = "GRGEN_LIBGR.IMatchesExact<" + matchType + ">" ;

            if(matchingPattern.PatternGraph.Package != null)
            {
                sb.AppendFrontFormat("namespace {0}\n", matchingPattern.PatternGraph.Package);
                sb.AppendFront("{\n");
                sb.Indent();
            }

            sb.AppendFront("/// <summary>\n");
            sb.AppendFront("/// An object representing an executable rule - same as IAction, but with exact types and distinct parameters.\n");
            sb.AppendFront("/// </summary>\n");
            sb.AppendFrontFormat("public interface {0}\n", actionInterfaceName);
            sb.AppendFront("{\n");
            sb.Indent();
            sb.AppendFront("/// <summary> same as IAction.Match, but with exact types and distinct parameters. </summary>\n");
            sb.AppendFrontFormat("{0} Match(GRGEN_LIBGR.IActionExecutionEnvironment actionEnv, int maxMatches{1});\n", matchesType, inParameters);

            sb.AppendFront("/// <summary> same as IAction.Modify, but with exact types and distinct parameters. </summary>\n");
            sb.AppendFrontFormat("void Modify(GRGEN_LIBGR.IActionExecutionEnvironment actionEnv, {0} match{1});\n", matchType, outParameters);

            sb.AppendFront("/// <summary> same as IAction.ModifyAll, but with exact types and distinct parameters. </summary>\n");
            sb.AppendFrontFormat("void ModifyAll(GRGEN_LIBGR.IActionExecutionEnvironment actionEnv, {0} matches{1});\n", matchesType, allParameters);

            sb.AppendFront("/// <summary> same as IAction.Apply, but with exact types and distinct parameters; returns true if applied </summary>\n");
            sb.AppendFrontFormat("bool Apply(GRGEN_LIBGR.IActionExecutionEnvironment actionEnv{0}{1});\n", inParameters, refParameters);

            sb.AppendFront("/// <summary> same as IAction.ApplyAll, but with exact types and distinct parameters; returns the number of matches found/applied. </summary>\n");
            sb.AppendFrontFormat("int ApplyAll(int maxMatches, GRGEN_LIBGR.IActionExecutionEnvironment actionEnv{0}{1});\n", inParameters, allParameters);

            sb.AppendFront("/// <summary> same as IAction.ApplyStar, but with exact types and distinct parameters. </summary>\n");
            sb.AppendFrontFormat("bool ApplyStar(GRGEN_LIBGR.IActionExecutionEnvironment actionEnv{0});\n", inParameters);

            sb.AppendFront("/// <summary> same as IAction.ApplyPlus, but with exact types and distinct parameters. </summary>\n");
            sb.AppendFrontFormat("bool ApplyPlus(GRGEN_LIBGR.IActionExecutionEnvironment actionEnv{0});\n", inParameters);

            sb.AppendFront("/// <summary> same as IAction.ApplyMinMax, but with exact types and distinct parameters. </summary>\n");
            sb.AppendFrontFormat("bool ApplyMinMax(GRGEN_LIBGR.IActionExecutionEnvironment actionEnv, int min, int max{0});\n", inParameters);
            sb.Unindent();
            sb.AppendFront("}\n");
            
            if(matchingPattern.PatternGraph.Package != null)
            {
                sb.Unindent();
                sb.AppendFront("}\n");
            }

            sb.AppendFront("\n");
        }
        /// <summary>
        /// Parallelize the scheduled search plan to the branching factor,
        /// splitting it at the first loop into a header part and a body part
        /// </summary>
        public void ParallelizeHeadBody(LGSPRulePattern rulePattern)
        {
            Debug.Assert(rulePattern.patternGraph.schedulesIncludingNegativesAndIndependents.Length == 1);
            ScheduledSearchPlan ssp = rulePattern.patternGraph.schedulesIncludingNegativesAndIndependents[0];
            
            int indexToSplitAt = 0;
            for(int i = 0; i < ssp.Operations.Length; ++i)
            {
                SearchOperation so = ssp.Operations[i];
                if(so.Type == SearchOperationType.Lookup || so.Type == SearchOperationType.Incident
                    || so.Type == SearchOperationType.Incoming || so.Type == SearchOperationType.Outgoing
                    || so.Type == SearchOperationType.PickFromStorage || so.Type == SearchOperationType.PickFromStorageDependent
                    || so.Type == SearchOperationType.PickFromIndex || so.Type == SearchOperationType.PickFromIndexDependent)
                {
                    indexToSplitAt = i;
                    break;
                }
            }

            rulePattern.patternGraph.parallelizedSchedule = new ScheduledSearchPlan[2];
            List<SearchOperation> headOperations = new List<SearchOperation>();
            List<SearchOperation> bodyOperations = new List<SearchOperation>();
            for(int i = 0; i < rulePattern.Inputs.Length; ++i)
            {
                if(rulePattern.Inputs[i] is VarType) // those don't appear in the schedule, they are only extracted into the search program
                {
                    VarType varType = (VarType)rulePattern.Inputs[i];
                    String varName = rulePattern.InputNames[i];
                    PatternVariable dummy = new PatternVariable(varType, varName, varName, i, false, null);
                    headOperations.Add(new SearchOperation(SearchOperationType.WriteParallelPresetVar,
                        dummy, null, 0));
                    bodyOperations.Add(new SearchOperation(SearchOperationType.ParallelPresetVar,
                        dummy, null, 0));
                }
            }
            for(int i = 0; i < ssp.Operations.Length; ++i)
            {
                SearchOperation so = ssp.Operations[i];
                if(i < indexToSplitAt)
                {
                    SearchOperation clone = (SearchOperation)so.Clone();
                    clone.Isomorphy.Parallel = true;
                    clone.Isomorphy.LockForAllThreads = true;
                    headOperations.Add(clone);
                    switch(so.Type)
                    {
                            // the target binding looping operations can't appear in the header, so we don't treat them here
                            // the non-target binding operations are completely handled by just adding them, happended already above
                            // the target binding non-looping operations are handled below,
                            // by parallel preset writing in the header and reading in the body
                            // with exception of def, its declaration and initializion is just re-executed in the body
                            // some presets can't appear in an action header, they are thus not taken care of
                        case SearchOperationType.ActionPreset:
                        case SearchOperationType.MapWithStorage:
                        case SearchOperationType.MapWithStorageDependent:
                        case SearchOperationType.Cast:
                        case SearchOperationType.Assign:
                        case SearchOperationType.Identity:
                        case SearchOperationType.ImplicitSource:
                        case SearchOperationType.ImplicitTarget:
                        case SearchOperationType.Implicit:
                            headOperations.Add(new SearchOperation(SearchOperationType.WriteParallelPreset,
                                (SearchPlanNode)so.Element, so.SourceSPNode, 0));
                            bodyOperations.Add(new SearchOperation(SearchOperationType.ParallelPreset, 
                                (SearchPlanNode)so.Element, so.SourceSPNode, 0));
                            break;
                        case SearchOperationType.AssignVar:
                            headOperations.Add(new SearchOperation(SearchOperationType.WriteParallelPresetVar,
                                (PatternVariable)so.Element, so.SourceSPNode, 0));
                            bodyOperations.Add(new SearchOperation(SearchOperationType.ParallelPresetVar,
                                (PatternVariable)so.Element, so.SourceSPNode, 0));
                            break;
                        case SearchOperationType.DefToBeYieldedTo:
                            bodyOperations.Add((SearchOperation)so.Clone());
                            break;
                    }                    
                }
                else if(i == indexToSplitAt)
                {
                    SearchOperation cloneHead = (SearchOperation)so.Clone();
                    headOperations.Add(cloneHead);
                    SearchOperation cloneBody = (SearchOperation)so.Clone();
                    cloneBody.Isomorphy.Parallel = true;
                    bodyOperations.Add(cloneBody);
                    switch(so.Type)
                    {
                        case SearchOperationType.Lookup:
                            cloneHead.Type = SearchOperationType.SetupParallelLookup;
                            cloneBody.Type = SearchOperationType.ParallelLookup;
                            break;
                        case SearchOperationType.Incident:
                            cloneHead.Type = SearchOperationType.SetupParallelIncident;
                            cloneBody.Type = SearchOperationType.ParallelIncident;
                            break;
                        case SearchOperationType.Incoming:
                            cloneHead.Type = SearchOperationType.SetupParallelIncoming;
                            cloneBody.Type = SearchOperationType.ParallelIncoming;
                            break;
                        case SearchOperationType.Outgoing:
                            cloneHead.Type = SearchOperationType.SetupParallelOutgoing;
                            cloneBody.Type = SearchOperationType.ParallelOutgoing;
                            break;
                        case SearchOperationType.PickFromStorage:
                            cloneHead.Type = SearchOperationType.SetupParallelPickFromStorage;
                            cloneBody.Type = SearchOperationType.ParallelPickFromStorage;
                            break;
                        case SearchOperationType.PickFromStorageDependent:
                            cloneHead.Type = SearchOperationType.SetupParallelPickFromStorageDependent;
                            cloneBody.Type = SearchOperationType.ParallelPickFromStorageDependent;
                            break;
                        case SearchOperationType.PickFromIndex:
                            cloneHead.Type = SearchOperationType.SetupParallelPickFromIndex;
                            cloneBody.Type = SearchOperationType.ParallelPickFromIndex;
                            break;
                        case SearchOperationType.PickFromIndexDependent:
                            cloneHead.Type = SearchOperationType.SetupParallelPickFromIndexDependent;
                            cloneBody.Type = SearchOperationType.ParallelPickFromIndexDependent;
                            break;
                    }
                }
                else
                {
                    SearchOperation clone = (SearchOperation)so.Clone();
                    clone.Isomorphy.Parallel = true;
                    bodyOperations.Add(clone);
                    if(clone.Element is PatternCondition)
                        SetNeedForParallelizedVersion((clone.Element as PatternCondition).ConditionExpression);
                }
            }
            ScheduledSearchPlan headSsp = new ScheduledSearchPlan(
                rulePattern.patternGraph, headOperations.ToArray(), headOperations.Count > 0 ? headOperations[0].CostToEnd : 0);
            rulePattern.patternGraph.parallelizedSchedule[0] = headSsp;
            ScheduledSearchPlan bodySsp = new ScheduledSearchPlan(
                rulePattern.patternGraph, bodyOperations.ToArray(), bodyOperations.Count > 0 ? bodyOperations[0].CostToEnd : 0);
            rulePattern.patternGraph.parallelizedSchedule[1] = bodySsp;
            ParallelizeNegativeIndependent(bodySsp);
            ParallelizeAlternativeIterated(rulePattern.patternGraph);
            ParallelizeYielding(rulePattern.patternGraph);
        }
Beispiel #5
0
        /// <summary>
        /// Parallelize the scheduled search plan to the branching factor,
        /// splitting it at the first loop into a header part and a body part
        /// </summary>
        public static void ParallelizeHeadBody(LGSPRulePattern rulePattern)
        {
            Debug.Assert(rulePattern.patternGraph.schedulesIncludingNegativesAndIndependents.Length == 1);
            ScheduledSearchPlan ssp = rulePattern.patternGraph.schedulesIncludingNegativesAndIndependents[0];

            int indexToSplitAt = 0;

            for (int i = 0; i < ssp.Operations.Length; ++i)
            {
                SearchOperation so = ssp.Operations[i];
                if (so.Type == SearchOperationType.Lookup || so.Type == SearchOperationType.Incident ||
                    so.Type == SearchOperationType.Incoming || so.Type == SearchOperationType.Outgoing ||
                    so.Type == SearchOperationType.PickFromStorage || so.Type == SearchOperationType.PickFromStorageDependent ||
                    so.Type == SearchOperationType.PickFromIndex || so.Type == SearchOperationType.PickFromIndexDependent)
                {
                    indexToSplitAt = i;
                    break;
                }
            }

            rulePattern.patternGraph.parallelizedSchedule = new ScheduledSearchPlan[2];
            List <SearchOperation> headOperations = new List <SearchOperation>();
            List <SearchOperation> bodyOperations = new List <SearchOperation>();

            for (int i = 0; i < rulePattern.Inputs.Length; ++i)
            {
                if (rulePattern.Inputs[i] is VarType) // those don't appear in the schedule, they are only extracted into the search program
                {
                    VarType         varType = (VarType)rulePattern.Inputs[i];
                    String          varName = rulePattern.InputNames[i];
                    PatternVariable dummy   = new PatternVariable(varType, varName, varName, i, false, null);
                    headOperations.Add(new SearchOperation(SearchOperationType.WriteParallelPresetVar,
                                                           dummy, null, 0));
                    bodyOperations.Add(new SearchOperation(SearchOperationType.ParallelPresetVar,
                                                           dummy, null, 0));
                }
            }
            for (int i = 0; i < ssp.Operations.Length; ++i)
            {
                SearchOperation so = ssp.Operations[i];
                if (i < indexToSplitAt)
                {
                    SearchOperation clone = (SearchOperation)so.Clone();
                    clone.Isomorphy.Parallel          = true;
                    clone.Isomorphy.LockForAllThreads = true;
                    headOperations.Add(clone);
                    switch (so.Type)
                    {
                    // the target binding looping operations can't appear in the header, so we don't treat them here
                    // the non-target binding operations are completely handled by just adding them, happended already above
                    // the target binding non-looping operations are handled below,
                    // by parallel preset writing in the header and reading in the body
                    // with exception of def, its declaration and initializion is just re-executed in the body
                    // some presets can't appear in an action header, they are thus not taken care of
                    case SearchOperationType.ActionPreset:
                    case SearchOperationType.MapWithStorage:
                    case SearchOperationType.MapWithStorageDependent:
                    case SearchOperationType.Cast:
                    case SearchOperationType.Assign:
                    case SearchOperationType.Identity:
                    case SearchOperationType.ImplicitSource:
                    case SearchOperationType.ImplicitTarget:
                    case SearchOperationType.Implicit:
                        headOperations.Add(new SearchOperation(SearchOperationType.WriteParallelPreset,
                                                               (SearchPlanNode)so.Element, so.SourceSPNode, 0));
                        bodyOperations.Add(new SearchOperation(SearchOperationType.ParallelPreset,
                                                               (SearchPlanNode)so.Element, so.SourceSPNode, 0));
                        break;

                    case SearchOperationType.AssignVar:
                        headOperations.Add(new SearchOperation(SearchOperationType.WriteParallelPresetVar,
                                                               (PatternVariable)so.Element, so.SourceSPNode, 0));
                        bodyOperations.Add(new SearchOperation(SearchOperationType.ParallelPresetVar,
                                                               (PatternVariable)so.Element, so.SourceSPNode, 0));
                        break;

                    case SearchOperationType.DefToBeYieldedTo:
                        bodyOperations.Add((SearchOperation)so.Clone());
                        break;
                    }
                }
                else if (i == indexToSplitAt)
                {
                    SearchOperation cloneHead;
                    SearchOperation cloneBody;
                    switch (so.Type)
                    {
                    case SearchOperationType.Lookup:
                        cloneHead = (SearchOperation)so.Clone(SearchOperationType.SetupParallelLookup);
                        cloneBody = (SearchOperation)so.Clone(SearchOperationType.ParallelLookup);
                        break;

                    case SearchOperationType.Incident:
                        cloneHead = (SearchOperation)so.Clone(SearchOperationType.SetupParallelIncident);
                        cloneBody = (SearchOperation)so.Clone(SearchOperationType.ParallelIncident);
                        break;

                    case SearchOperationType.Incoming:
                        cloneHead = (SearchOperation)so.Clone(SearchOperationType.SetupParallelIncoming);
                        cloneBody = (SearchOperation)so.Clone(SearchOperationType.ParallelIncoming);
                        break;

                    case SearchOperationType.Outgoing:
                        cloneHead = (SearchOperation)so.Clone(SearchOperationType.SetupParallelOutgoing);
                        cloneBody = (SearchOperation)so.Clone(SearchOperationType.ParallelOutgoing);
                        break;

                    case SearchOperationType.PickFromStorage:
                        cloneHead = (SearchOperation)so.Clone(SearchOperationType.SetupParallelPickFromStorage);
                        cloneBody = (SearchOperation)so.Clone(SearchOperationType.ParallelPickFromStorage);
                        break;

                    case SearchOperationType.PickFromStorageDependent:
                        cloneHead = (SearchOperation)so.Clone(SearchOperationType.SetupParallelPickFromStorageDependent);
                        cloneBody = (SearchOperation)so.Clone(SearchOperationType.ParallelPickFromStorageDependent);
                        break;

                    case SearchOperationType.PickFromIndex:
                        cloneHead = (SearchOperation)so.Clone(SearchOperationType.SetupParallelPickFromIndex);
                        cloneBody = (SearchOperation)so.Clone(SearchOperationType.ParallelPickFromIndex);
                        break;

                    case SearchOperationType.PickFromIndexDependent:
                        cloneHead = (SearchOperation)so.Clone(SearchOperationType.SetupParallelPickFromIndexDependent);
                        cloneBody = (SearchOperation)so.Clone(SearchOperationType.ParallelPickFromIndexDependent);
                        break;

                    default: // failure, operation at this index cannot be parallelized/parallelization not supported
                        cloneHead = null;
                        cloneBody = null;
                        break;
                    }
                    headOperations.Add(cloneHead);
                    cloneBody.Isomorphy.Parallel = true;
                    bodyOperations.Add(cloneBody);
                }
                else
                {
                    SearchOperation clone = (SearchOperation)so.Clone();
                    clone.Isomorphy.Parallel = true;
                    bodyOperations.Add(clone);
                    if (clone.Element is PatternCondition)
                    {
                        SetNeedForParallelizedVersion((clone.Element as PatternCondition).ConditionExpression);
                    }
                }
            }
            ScheduledSearchPlan headSsp = new ScheduledSearchPlan(
                rulePattern.patternGraph, headOperations.ToArray(), headOperations.Count > 0 ? headOperations[0].CostToEnd : 0);

            rulePattern.patternGraph.parallelizedSchedule[0] = headSsp;
            ScheduledSearchPlan bodySsp = new ScheduledSearchPlan(
                rulePattern.patternGraph, bodyOperations.ToArray(), bodyOperations.Count > 0 ? bodyOperations[0].CostToEnd : 0);

            rulePattern.patternGraph.parallelizedSchedule[1] = bodySsp;
            ParallelizeNegativeIndependent(bodySsp);
            ParallelizeAlternativeIterated(rulePattern.patternGraph);
            ParallelizeYielding(rulePattern.patternGraph);
        }
Beispiel #6
0
        /// <summary>
        /// Builds search program from scheduled search plan at given index in pattern graph of the action rule pattern
        /// </summary>
        public static SearchProgram BuildSearchProgram(
            IGraphModel model,
            LGSPRulePattern rulePattern,
            int index,
            string nameOfSearchProgram,
            bool parallelized,
            bool emitProfiling)
        {
            PatternGraph patternGraph         = rulePattern.patternGraph;
            String       rulePatternClassName = NamesOfEntities.RulePatternClassName(rulePattern.name, rulePattern.PatternGraph.Package, false);

            // filter out parameters which are implemented by lookup due to maybe null unfolding
            // and suffix matcher method name by missing parameters which get computed by lookup here
            string[] parameterTypes;
            string[] parameterNames;
            String   name;

            GetFilteredParametersAndSuffixedMatcherName(
                rulePattern, patternGraph, parallelized ? 0 : index,
                out parameterTypes, out parameterNames, out name);

            SearchProgramBodyBuilder builder = new SearchProgramBodyBuilder(
                SearchProgramType.Action,
                model,
                rulePatternClassName,
                rulePattern.patternGraph.Package != null ? rulePattern.patternGraph.Package + "::" + rulePattern.name : rulePattern.name,
                parameterNames,
                parameterTypes,
                patternGraph,
                emitProfiling,
                parallelized,
                index
                );

            // this is the all presets available method (index 0) and there are presets which may be null?
            // -> collect data for missing preset calls
            List <String[]> paramTypesList          = null;
            List <String[]> paramNamesList          = null;
            List <String>   suffixedMatcherNameList = null;

            if (patternGraph.schedules.Length > 1 && index == 0)
            {
                paramTypesList          = new List <String[]>();
                paramNamesList          = new List <String[]>();
                suffixedMatcherNameList = new List <String>();
                for (int i = 0; i < patternGraph.schedules.Length; ++i)
                {
                    String[] paramTypes;
                    String[] paramNames;
                    String   suffixedMatcherName;
                    GetFilteredParametersAndSuffixedMatcherName(
                        rulePattern, patternGraph, i,
                        out paramTypes, out paramNames, out suffixedMatcherName);
                    paramTypesList.Add(paramTypes);
                    paramNamesList.Add(paramNames);
                    suffixedMatcherNameList.Add(suffixedMatcherName);
                }
            }

            // build outermost search program operation, create the list anchor starting its program
            bool containsSubpatterns = patternGraph.embeddedGraphsPlusInlined.Length > 0 ||
                                       patternGraph.iteratedsPlusInlined.Length > 0 ||
                                       patternGraph.alternativesPlusInlined.Length > 0;
            SearchProgram searchProgram;

            if (parallelized)
            {
                if (index == 1)
                {
                    List <String> matchingPatternClassTypeNames = new List <String>();
                    List <Dictionary <PatternGraph, bool> > nestedIndependents = new List <Dictionary <PatternGraph, bool> >();
                    ExtractNestedIndependents(matchingPatternClassTypeNames, nestedIndependents, rulePattern, patternGraph);

                    searchProgram = new SearchProgramOfActionParallelizationBody(
                        rulePatternClassName,
                        patternGraph.name, name + "_parallelized_body",
                        rulePattern.patternGraph.patternGraphsOnPathToEnclosedPatternpath,
                        containsSubpatterns, builder.wasIndependentInlined(patternGraph, index),
                        matchingPatternClassTypeNames, nestedIndependents,
                        emitProfiling, patternGraph.PackagePrefixedName);
                }
                else // index == 0
                {
                    searchProgram = new SearchProgramOfActionParallelizationHead(
                        rulePatternClassName,
                        patternGraph.name, parameterTypes, parameterNames, name + "_parallelized",
                        emitProfiling, patternGraph.PackagePrefixedName);
                }
            }
            else
            {
                List <String> matchingPatternClassTypeNames = new List <String>();
                List <Dictionary <PatternGraph, bool> > nestedIndependents = new List <Dictionary <PatternGraph, bool> >();
                ExtractNestedIndependents(matchingPatternClassTypeNames, nestedIndependents, rulePattern, patternGraph);

                searchProgram = new SearchProgramOfAction(
                    rulePatternClassName,
                    patternGraph.name, parameterTypes, parameterNames, name,
                    rulePattern.patternGraph.patternGraphsOnPathToEnclosedPatternpath,
                    containsSubpatterns, builder.wasIndependentInlined(patternGraph, 0),
                    matchingPatternClassTypeNames, nestedIndependents,
                    emitProfiling, patternGraph.PackagePrefixedName,
                    patternGraph.maybeNullElementNames, suffixedMatcherNameList, paramNamesList);
            }
            searchProgram.OperationsList = new SearchProgramList(searchProgram);
            SearchProgramOperation insertionPoint = searchProgram.OperationsList;

            if (!parallelized || index == 0)
            {
                insertionPoint = insertVariableDeclarations(insertionPoint, patternGraph);
            }

            // start building with first operation in scheduled search plan
            insertionPoint = builder.BuildScheduledSearchPlanOperationIntoSearchProgram(
                0, insertionPoint);

            return(searchProgram);
        }
        void GenerateKeepSameFilter(SourceBuilder source, LGSPRulePattern rulePattern, String filterVariable, bool sameAsFirst)
        {
            String rulePatternClassName = TypesHelper.GetPackagePrefixDot(rulePattern.PatternGraph.Package) + rulePattern.GetType().Name;
            String matchInterfaceName = rulePatternClassName + "." + NamesOfEntities.MatchInterfaceName(rulePattern.name);
            String matchesListType = "GRGEN_LIBGR.IMatchesExact<" + matchInterfaceName + ">";
            String filterName = sameAsFirst ? "keepSameAsFirst_" + filterVariable : "keepSameAsLast_" + filterVariable;

            source.AppendFrontFormat("public static void Filter_{0}_{1}(GRGEN_LGSP.LGSPGraphProcessingEnvironment procEnv, {2} matches)\n", 
                rulePattern.name, filterName, matchesListType);

            source.AppendFront("{\n");
            source.Indent();

            source.AppendFrontFormat("List<{0}> matchesArray = matches.ToList();\n", matchInterfaceName);

            if(sameAsFirst)
            {
                source.AppendFront("int pos = 0 + 1;\n");
                source.AppendFrontFormat("while(pos < matchesArray.Count && matchesArray[pos].{0} == matchesArray[0].{0})\n", 
                    NamesOfEntities.MatchName(filterVariable, EntityType.Variable));
                source.AppendFront("{\n");
                source.AppendFront("\t++pos;\n");
                source.AppendFront("}\n");
                source.AppendFront("for(; pos < matchesArray.Count; ++pos)\n");
                source.AppendFront("{\n");
                source.AppendFront("\tmatchesArray[pos] = null;\n");
                source.AppendFront("}\n");
            }
            else
            {
                source.AppendFront("int pos = matchesArray.Count-1 - 1;\n");
                source.AppendFrontFormat("while(pos >= 0 && matchesArray[pos].{0} == matchesArray[matchesArray.Count-1].{0})\n",
                    NamesOfEntities.MatchName(filterVariable, EntityType.Variable));
                source.AppendFront("{\n");
                source.AppendFront("\t--pos;\n");
                source.AppendFront("}\n");
                source.AppendFront("for(; pos >= 0; --pos)\n");
                source.AppendFront("{\n");
                source.AppendFront("\tmatchesArray[pos] = null;\n");
                source.AppendFront("}\n");
            }

            source.AppendFront("matches.FromList();\n");

            source.Unindent();
            source.AppendFront("}\n");
        }
        /// <summary>
        /// Builds search program from scheduled search plan at given index in pattern graph of the action rule pattern
        /// </summary>
        public SearchProgram BuildSearchProgram(
            IGraphModel model,
            LGSPRulePattern rulePattern,
            int index,
            string nameOfSearchProgram,
            bool parallelized,
            bool emitProfiling)
        {
            PatternGraph patternGraph = rulePattern.patternGraph;
            this.model = model;
            patternGraphWithNestingPatterns = new Stack<PatternGraph>();
            patternGraphWithNestingPatterns.Push(patternGraph);
            this.parallelized = parallelized;
            isoSpaceNeverAboveMaxIsoSpace = patternGraphWithNestingPatterns.Peek().maxIsoSpace < (int)LGSPElemFlags.MAX_ISO_SPACE;
            isNegative = false;
            isNestedInNegative = false;
            rulePatternClassName = NamesOfEntities.RulePatternClassName(rulePattern.name, rulePattern.PatternGraph.Package, false);
            this.emitProfiling = emitProfiling;
            packagePrefixedActionName = rulePattern.patternGraph.Package != null ? rulePattern.patternGraph.Package + "::" + rulePattern.name : rulePattern.name;
            firstLoopPassed = false;
            
            // filter out parameters which are implemented by lookup due to maybe null unfolding
            // and suffix matcher method name by missing parameters which get computed by lookup here
            String name;
            GetFilteredParametersAndSuffixedMatcherName(
                rulePattern, patternGraph, parallelized ? 0 : index,
                out parameterTypes, out parameterNames, out name);

            // this is the all presets available method (index 0) and there are presets which may be null?
            // -> collect data for missing preset calls
            List<String[]> paramTypesList = null;
            List<String[]> paramNamesList = null;
            List<String> suffixedMatcherNameList = null;
            if(patternGraph.schedules.Length>1 && index==0)
            {
                paramTypesList = new List<String[]>();
                paramNamesList = new List<String[]>();
                suffixedMatcherNameList = new List<String>();
                for(int i=0; i<patternGraph.schedules.Length; ++i)
                {
                    String[] paramTypes;
                    String[] paramNames;
                    String suffixedMatcherName;
                    GetFilteredParametersAndSuffixedMatcherName(
                        rulePattern, patternGraph, i,
                        out paramTypes, out paramNames, out suffixedMatcherName);
                    paramTypesList.Add(paramTypes);
                    paramNamesList.Add(paramNames);
                    suffixedMatcherNameList.Add(suffixedMatcherName);
                }
            }

            // build outermost search program operation, create the list anchor starting its program
            bool containsSubpatterns = patternGraph.embeddedGraphsPlusInlined.Length > 0
                || patternGraph.iteratedsPlusInlined.Length > 0
                || patternGraph.alternativesPlusInlined.Length > 0;
            SearchProgram searchProgram;
            if(parallelized)
            {
                if(index == 1)
                {
                    searchProgram = new SearchProgramOfActionParallelizationBody(
                        rulePatternClassName,
                        patternGraph.name, name + "_parallelized_body",
                        rulePattern.patternGraph.patternGraphsOnPathToEnclosedPatternpath,
                        containsSubpatterns, wasIndependentInlined(patternGraph, index), 
                        emitProfiling, patternGraph.PackagePrefixedName);
                }
                else // index == 0
                {
                    searchProgram = new SearchProgramOfActionParallelizationHead(
                        rulePatternClassName,
                        patternGraph.name, parameterTypes, parameterNames, name + "_parallelized",
                        emitProfiling, patternGraph.PackagePrefixedName);
                }
            }
            else
            {
                searchProgram = new SearchProgramOfAction(
                    rulePatternClassName,
                    patternGraph.name, parameterTypes, parameterNames, name,
                    rulePattern.patternGraph.patternGraphsOnPathToEnclosedPatternpath,
                    containsSubpatterns, wasIndependentInlined(patternGraph, indexOfSchedule), 
                    emitProfiling, patternGraph.PackagePrefixedName,
                    patternGraph.maybeNullElementNames, suffixedMatcherNameList, paramNamesList);
            } 
            searchProgram.OperationsList = new SearchProgramList(searchProgram);
            SearchProgramOperation insertionPoint = searchProgram.OperationsList;

            if(!parallelized || index == 0)
                insertionPoint = insertVariableDeclarations(insertionPoint, patternGraph);

            // start building with first operation in scheduled search plan
            indexOfSchedule = index;
            insertionPoint = BuildScheduledSearchPlanOperationIntoSearchProgram(
                0, insertionPoint);

            patternGraphWithNestingPatterns.Pop();

            return searchProgram;
        }
        private static void GenerateOrderByFilter(SourceBuilder source, LGSPRulePattern rulePattern, String filterVariable, bool ascending)
        {
            String rulePatternClassName = TypesHelper.GetPackagePrefixDot(rulePattern.PatternGraph.Package) + rulePattern.GetType().Name;
            String matchInterfaceName = rulePatternClassName + "." + NamesOfEntities.MatchInterfaceName(rulePattern.name);
            String matchesListType = "GRGEN_LIBGR.IMatchesExact<" + matchInterfaceName + ">";
            String filterName = ascending ? "orderAscendingBy_" + filterVariable : "orderDescendingBy_" + filterVariable;

            source.AppendFrontFormat("public static void Filter_{0}_{1}(GRGEN_LGSP.LGSPGraphProcessingEnvironment procEnv, {2} matches)\n", 
                rulePattern.name, filterName, matchesListType);
            source.AppendFront("{\n");
            source.Indent();

            source.AppendFrontFormat("List<{0}> matchesArray = matches.ToList();\n", matchInterfaceName);
            source.AppendFrontFormat("matchesArray.Sort(new Comparer_{0}_{1}());\n", rulePattern.name, filterName);
            source.AppendFront("matches.FromList();\n");

            source.Unindent();
            source.AppendFront("}\n");

            source.AppendFrontFormat("class Comparer_{0}_{1} : Comparer<{2}>\n", rulePattern.name, filterName, matchInterfaceName);
            source.AppendFront("{\n");
            source.Indent();

            source.AppendFrontFormat("public override int Compare({0} left, {0} right)\n", matchInterfaceName);
            source.AppendFront("{\n");
            source.Indent();
            if(ascending)
                source.AppendFrontFormat("return left.{0}.CompareTo(right.{0});\n", NamesOfEntities.MatchName(filterVariable, EntityType.Variable));
            else
                source.AppendFrontFormat("return -left.{0}.CompareTo(right.{0});\n", NamesOfEntities.MatchName(filterVariable, EntityType.Variable));
            source.Unindent();
            source.AppendFront("}\n");

            source.Unindent();
            source.AppendFront("}\n");
        }
        void GenerateGroupByFilter(SourceBuilder source, LGSPRulePattern rulePattern, String filterVariable)
        {
            String rulePatternClassName = TypesHelper.GetPackagePrefixDot(rulePattern.PatternGraph.Package) + rulePattern.GetType().Name;
            String matchInterfaceName = rulePatternClassName + "." + NamesOfEntities.MatchInterfaceName(rulePattern.name);
            String matchesListType = "GRGEN_LIBGR.IMatchesExact<" + matchInterfaceName + ">";
            String filterName = "groupBy_" + filterVariable;

            if(true) // does the type of the variable to group-by support ordering? then order, is more efficient than equality comparisons
            {
                source.AppendFrontFormat("public static void Filter_{0}_{1}(GRGEN_LGSP.LGSPGraphProcessingEnvironment procEnv, {2} matches)\n",
                    rulePattern.name, filterName, matchesListType);
                source.AppendFront("{\n");
                source.Indent();

                source.AppendFrontFormat("List<{0}> matchesArray = matches.ToList();\n", matchInterfaceName);
                source.AppendFrontFormat("matchesArray.Sort(new Comparer_{0}_{1}());\n", rulePattern.name, filterName);
                source.AppendFront("matches.FromList();\n");

                source.Unindent();
                source.AppendFront("}\n");

                source.AppendFrontFormat("class Comparer_{0}_{1} : Comparer<{2}>\n", rulePattern.name, filterName, matchInterfaceName);
                source.AppendFront("{\n");
                source.Indent();

                source.AppendFrontFormat("public override int Compare({0} left, {0} right)\n", matchInterfaceName);
                source.AppendFront("{\n");
                source.Indent();
                source.AppendFrontFormat("return left.{0}.CompareTo(right.{0});\n", NamesOfEntities.MatchName(filterVariable, EntityType.Variable));
                source.Unindent();
                source.AppendFront("}\n");

                source.Unindent();
                source.AppendFront("}\n");
            }
            else
            {
                // ensure that if two elements are equal, they are neighbours or only separated by equal elements
                // not needed yet, as of now we only support numerical types and string, that support ordering in addition to equality comparison
                /*List<T> matchesArray;
                for(int i = 0; i < matchesArray.Count - 1; ++i)
                {
                    for(int j = i + 1; j < matchesArray.Count; ++j)
                    {
                        if(matchesArray[i] == matchesArray[j])
                        {
                            T tmp = matchesArray[i + 1];
                            matchesArray[i + 1] = matchesArray[j];
                            matchesArray[j] = tmp;
                            break;
                        }
                    }
                }*/
            }
        }
        private static void GenerateAutomorphyFilter(SourceBuilder source, LGSPRulePattern rulePattern)
        {
            String rulePatternClassName = TypesHelper.GetPackagePrefixDot(rulePattern.PatternGraph.Package) + rulePattern.GetType().Name;
            String matchInterfaceName = rulePatternClassName + "." + NamesOfEntities.MatchInterfaceName(rulePattern.name);
            String matchClassName = rulePatternClassName + "." + NamesOfEntities.MatchClassName(rulePattern.name);
            String matchesListType = "GRGEN_LIBGR.IMatchesExact<" + matchInterfaceName + ">";
            String filterName = "auto";
            
            source.AppendFrontFormat("public static void Filter_{0}_{1}(GRGEN_LGSP.LGSPGraphProcessingEnvironment procEnv, {2} matches)\n", 
                rulePattern.name, filterName, matchesListType);
            source.AppendFront("{\n");
            source.Indent();

            source.AppendFront("if(matches.Count < 2)\n");
            source.AppendFront("\treturn;\n");
            source.AppendFrontFormat("List<{0}> matchesArray = matches.ToList();\n", matchInterfaceName);

            source.AppendFrontFormat("if(matches.Count < 5 || {0}.Instance.patternGraph.nodes.Length + {0}.Instance.patternGraph.edges.Length < 1)\n", rulePatternClassName);
            source.AppendFront("{\n");
            source.Indent();

            source.AppendFront("for(int i = 0; i < matchesArray.Count; ++i)\n");
            source.AppendFront("{\n");
            source.Indent();
            source.AppendFront("if(matchesArray[i] == null)\n");
            source.AppendFront("\tcontinue;\n");
            source.AppendFront("for(int j = i + 1; j < matchesArray.Count; ++j)\n");
            source.AppendFront("{\n");
            source.Indent();
            source.AppendFront("if(matchesArray[j] == null)\n");
            source.AppendFront("\tcontinue;\n");
            source.AppendFront("if(GRGEN_LIBGR.SymmetryChecker.AreSymmetric(matchesArray[i], matchesArray[j], procEnv.graph))\n");
            source.AppendFront("\tmatchesArray[j] = null;\n");
            source.Unindent();
            source.AppendFront("}\n");
            source.Unindent();
            source.AppendFront("}\n");

            source.Unindent();
            source.AppendFront("}\n");
            source.AppendFront("else\n");
            source.AppendFront("{\n");
            source.Indent();

            source.AppendFrontFormat("Dictionary<int, {0}> foundMatchesOfSameMainPatternHash = new Dictionary<int, {0}>();\n", 
                matchClassName);
            source.AppendFront("for(int i = 0; i < matchesArray.Count; ++i)\n");
            source.AppendFront("{\n");
            source.Indent();
            source.AppendFrontFormat("{0} match = ({0})matchesArray[i];\n", matchClassName);
            source.AppendFront("int duplicateMatchHash = 0;\n");
            source.AppendFront("for(int j = 0; j < match.NumberOfNodes; ++j) duplicateMatchHash ^= match.getNodeAt(j).GetHashCode();\n");
            source.AppendFront("for(int j = 0; j < match.NumberOfEdges; ++j) duplicateMatchHash ^= match.getEdgeAt(j).GetHashCode();\n");
            source.AppendFront("bool contained = foundMatchesOfSameMainPatternHash.ContainsKey(duplicateMatchHash);\n");
            source.AppendFront("if(contained)\n");
            source.AppendFront("{\n");
            source.Indent();
            source.AppendFrontFormat("{0} duplicateMatchCandidate = foundMatchesOfSameMainPatternHash[duplicateMatchHash];\n", matchClassName);
            source.AppendFront("do\n");
            source.AppendFront("{\n");
            source.Indent();
            source.AppendFront("if(GRGEN_LIBGR.SymmetryChecker.AreSymmetric(match, duplicateMatchCandidate, procEnv.graph))\n");
            source.AppendFront("{\n");
            source.Indent();
            source.AppendFront("matchesArray[i] = null;\n");
            source.AppendFrontFormat("goto label_auto_{0};\n", rulePatternClassName.Replace('.', '_'));
            source.Unindent();
            source.AppendFront("}\n");
            source.Unindent();
            source.AppendFront("}\n");
            source.AppendFront("while((duplicateMatchCandidate = duplicateMatchCandidate.nextWithSameHash) != null);\n");
            source.Unindent();
            source.AppendFront("}\n");
            source.AppendFront("if(!contained)\n");
            source.AppendFront("\tfoundMatchesOfSameMainPatternHash[duplicateMatchHash] = match;\n");
            source.AppendFront("else\n");
            source.AppendFront("{\n");
            source.Indent();
            source.AppendFrontFormat("{0} duplicateMatchCandidate = foundMatchesOfSameMainPatternHash[duplicateMatchHash];\n", matchClassName);
            source.AppendFront("while(duplicateMatchCandidate.nextWithSameHash != null) duplicateMatchCandidate = duplicateMatchCandidate.nextWithSameHash;\n");
            source.AppendFront("duplicateMatchCandidate.nextWithSameHash = match;\n");
            source.Unindent();
            source.AppendFront("}\n");
            source.AppendFormat("label_auto_{0}: ;\n", rulePatternClassName.Replace('.', '_'));
            source.Unindent();
            source.AppendFront("}\n");
            source.AppendFrontFormat("foreach({0} toClean in foundMatchesOfSameMainPatternHash.Values) toClean.CleanNextWithSameHash();\n", matchClassName);
            
            source.Unindent();
            source.AppendFront("}\n");

            source.AppendFront("matches.FromList();\n");

            source.Unindent();
            source.AppendFront("}\n");
        }
        public void GenerateFilters(SourceBuilder source, LGSPRulePattern rulePattern)
        {
            foreach(IFilter f in rulePattern.Filters)
            {
                if(f is IFilterAutoGenerated)
                {
                    IFilterAutoGenerated filter = (IFilterAutoGenerated)f;

                    if(filter.Package != null)
                    {
                        source.AppendFrontFormat("namespace {0}\n", filter.Package);
                        source.AppendFront("{\n");
                        source.Indent();
                    }
                    source.AppendFront("public partial class MatchFilters\n");
                    source.AppendFront("{\n");
                    source.Indent();

                    if(filter.Name == "auto")
                        GenerateAutomorphyFilter(source, rulePattern);
                    else
                    {
                        if(filter.Name == "orderAscendingBy")
                            GenerateOrderByFilter(source, rulePattern, filter.Entity, true);
                        if(filter.Name == "orderDescendingBy")
                            GenerateOrderByFilter(source, rulePattern, filter.Entity, false);
                        if(filter.Name == "groupBy")
                            GenerateGroupByFilter(source, rulePattern, filter.Entity);
                        if(filter.Name == "keepSameAsFirst")
                            GenerateKeepSameFilter(source, rulePattern, filter.Entity, true);
                        if(filter.Name == "keepSameAsLast")
                            GenerateKeepSameFilter(source, rulePattern, filter.Entity, false);
                        if(filter.Name == "keepOneForEach")
                            GenerateKeepOneForEachFilter(source, rulePattern, filter.Entity);
                    }

                    source.Unindent();
                    source.AppendFront("}\n");
                    if(filter.Package != null)
                    {
                        source.Unindent();
                        source.AppendFront("}\n");
                    }
                }
            }
        }
        public void GenerateFilterStubs(SourceBuilder source, LGSPRulePattern rulePattern)
        {
            String rulePatternClassName = rulePattern.GetType().Name;
            String matchInterfaceName = rulePatternClassName + "." + NamesOfEntities.MatchInterfaceName(rulePattern.name);
            String matchesListType = "GRGEN_LIBGR.IMatchesExact<" + matchInterfaceName + ">";

            foreach(IFilter filter in rulePattern.Filters)
            {
                if(filter is IFilterAutoGenerated)
                    continue;

                IFilterFunction filterFunction = (IFilterFunction)filter;
                if(!filterFunction.IsExternal)
                    continue;

                if(filter.Package != null)
                {
                    source.AppendFrontFormat("namespace {0}\n", filter.Package);
                    source.AppendFront("{\n");
                    source.Indent();
                }
                source.AppendFront("public partial class MatchFilters\n");
                source.AppendFront("{\n");
                source.Indent();

                source.AppendFrontFormat("//public static void Filter_{0}(GRGEN_LGSP.LGSPGraphProcessingEnvironment procEnv, {1} matches", filter.Name, matchesListType);
                for(int i = 0; i < filterFunction.Inputs.Length; ++i)
                {
                    source.AppendFormat(", {0} {1}", TypesHelper.TypeName(filterFunction.Inputs[i]), filterFunction.InputNames[i]);
                }
                source.Append(")\n");

                source.Unindent();
                source.AppendFront("}\n");
                if(filter.Package != null)
                {
                    source.Unindent();
                    source.AppendFront("}\n");
                }
            }
        }
        /// <summary>
        /// Generates matcher class head source code for the pattern of the rulePattern into given source builder
        /// isInitialStatic tells whether the initial static version or a dynamic version after analyze is to be generated.
        /// </summary>
        void GenerateMatcherClassHeadAction(SourceBuilder sb, LGSPRulePattern rulePattern, 
            bool isInitialStatic, SearchProgram searchProgram)
        {
            PatternGraph patternGraph = (PatternGraph)rulePattern.PatternGraph;
                
            String namePrefix = (isInitialStatic ? "" : "Dyn") + "Action_";
            String className = namePrefix + rulePattern.name;
            String rulePatternClassName = rulePattern.GetType().Name;
            String matchClassName = rulePatternClassName + "." + "Match_" + rulePattern.name;
            String matchInterfaceName = rulePatternClassName + "." + "IMatch_" + rulePattern.name;
            String actionInterfaceName = "IAction_" + rulePattern.name;

            if(patternGraph.Package != null)
            {
                sb.AppendFrontFormat("namespace {0}\n", patternGraph.Package);
                sb.AppendFront("{\n");
                sb.Indent();
            }

            sb.AppendFront("public class " + className + " : GRGEN_LGSP.LGSPAction, "
                + "GRGEN_LIBGR.IAction, " + actionInterfaceName + "\n");
            sb.AppendFront("{\n");
            sb.Indent(); // class level

            sb.AppendFront("public " + className + "() {\n");
            sb.Indent(); // method body level
            sb.AppendFront("_rulePattern = " + rulePatternClassName + ".Instance;\n");
            sb.AppendFront("patternGraph = _rulePattern.patternGraph;\n");
            if(rulePattern.patternGraph.branchingFactor < 2)
            {
                sb.AppendFront("DynamicMatch = myMatch;\n");
                if(!isInitialStatic)
                    sb.AppendFrontFormat("GRGEN_ACTIONS.Action_{0}.Instance.DynamicMatch = myMatch;\n", rulePattern.name);
            }
            else
            {
                sb.AppendFront("if(Environment.ProcessorCount == 1)\n");
                sb.AppendFront("{\n");
                sb.AppendFront("\tDynamicMatch = myMatch;\n");
                if(!isInitialStatic)
                    sb.AppendFrontFormat("\tGRGEN_ACTIONS.Action_{0}.Instance.DynamicMatch = myMatch;\n", rulePattern.name);
                sb.AppendFront("}\n");
                sb.AppendFront("else\n");
                sb.AppendFront("{\n");
                sb.Indent();
                sb.AppendFront("DynamicMatch = myMatch_parallelized;\n");
                if(!isInitialStatic)
                    sb.AppendFrontFormat("GRGEN_ACTIONS.Action_{0}.Instance.DynamicMatch = myMatch_parallelized;\n", rulePattern.name);
                sb.AppendFrontFormat("numWorkerThreads = GRGEN_LGSP.WorkerPool.EnsurePoolSize({0});\n", rulePattern.patternGraph.branchingFactor);
                sb.AppendFrontFormat("parallelTaskMatches = new GRGEN_LGSP.LGSPMatchesList<{0}, {1}>[numWorkerThreads];\n", matchClassName, matchInterfaceName);
                sb.AppendFront("moveHeadAfterNodes = new List<GRGEN_LGSP.LGSPNode>[numWorkerThreads];\n");
                sb.AppendFront("moveHeadAfterEdges = new List<GRGEN_LGSP.LGSPEdge>[numWorkerThreads];\n");
                sb.AppendFront("moveOutHeadAfter = new List<KeyValuePair<GRGEN_LGSP.LGSPNode, GRGEN_LGSP.LGSPEdge>>[numWorkerThreads];\n");
                sb.AppendFront("moveInHeadAfter = new List<KeyValuePair<GRGEN_LGSP.LGSPNode, GRGEN_LGSP.LGSPEdge>>[numWorkerThreads];\n");
                sb.AppendFront("for(int i=0; i<numWorkerThreads; ++i)\n");
                sb.AppendFront("{\n");
                sb.Indent();
                sb.AppendFront("moveHeadAfterNodes[i] = new List<GRGEN_LGSP.LGSPNode>();\n");
                sb.AppendFront("moveHeadAfterEdges[i] = new List<GRGEN_LGSP.LGSPEdge>();\n");
                sb.AppendFront("moveOutHeadAfter[i] = new List<KeyValuePair<GRGEN_LGSP.LGSPNode, GRGEN_LGSP.LGSPEdge>>();\n");
                sb.AppendFront("moveInHeadAfter[i] = new List<KeyValuePair<GRGEN_LGSP.LGSPNode, GRGEN_LGSP.LGSPEdge>>();\n");
                sb.Unindent();
                sb.AppendFront("}\n");

                sb.AppendFront("for(int i=0; i<parallelTaskMatches.Length; ++i)\n");
                sb.AppendFrontFormat("\tparallelTaskMatches[i] = new GRGEN_LGSP.LGSPMatchesList<{0}, {1}>(this);\n", matchClassName, matchInterfaceName);
                sb.Unindent();
                sb.AppendFront("}\n");
            }
            sb.AppendFrontFormat("ReturnArray = new object[{0}];\n", rulePattern.Outputs.Length);
            sb.AppendFront("matches = new GRGEN_LGSP.LGSPMatchesList<" + matchClassName +", " + matchInterfaceName + ">(this);\n");
            sb.Unindent(); // class level
            sb.AppendFront("}\n\n");

            sb.AppendFront("public " + rulePatternClassName + " _rulePattern;\n");
            sb.AppendFront("public override GRGEN_LGSP.LGSPRulePattern rulePattern { get { return _rulePattern; } }\n");
            sb.AppendFront("public override string Name { get { return \"" + rulePattern.name + "\"; } }\n");
            sb.AppendFront("private GRGEN_LGSP.LGSPMatchesList<" + matchClassName + ", " + matchInterfaceName + "> matches;\n\n");

            if (isInitialStatic)
            {
                sb.AppendFront("public static " + className + " Instance { get { return instance; } set { instance = value; } }\n");
                sb.AppendFront("private static " + className + " instance = new " + className + "();\n");
            }

            GenerateIndependentsMatchObjects(sb, rulePattern, patternGraph);

            sb.AppendFront("\n");

            GenerateParallelizationSetupAsNeeded(sb, rulePattern, searchProgram);
        }
        void GenerateKeepOneForEachFilter(SourceBuilder source, LGSPRulePattern rulePattern, String filterVariable)
        {
            String rulePatternClassName = TypesHelper.GetPackagePrefixDot(rulePattern.PatternGraph.Package) + rulePattern.GetType().Name;
            String matchInterfaceName = rulePatternClassName + "." + NamesOfEntities.MatchInterfaceName(rulePattern.name);
            String matchesListType = "GRGEN_LIBGR.IMatchesExact<" + matchInterfaceName + ">";
            String filterName = "keepOneForEach_" + filterVariable;

            source.AppendFrontFormat("public static void Filter_{0}_{1}(GRGEN_LGSP.LGSPGraphProcessingEnvironment procEnv, {2} matches)\n",
                 rulePattern.name, filterName, matchesListType);
            source.AppendFront("{\n");
            source.Indent();

            source.AppendFrontFormat("List<{0}> matchesArray = matches.ToList();\n", matchInterfaceName);

            source.AppendFront("int cmpPos = 0;\n");
            source.AppendFront("int pos = 0 + 1;\n");
            source.AppendFront("for(; pos < matchesArray.Count; ++pos)\n");
            source.AppendFront("{\n");
            source.AppendFrontFormat("\tif(matchesArray[pos].{0} == matchesArray[cmpPos].{0})\n", NamesOfEntities.MatchName(filterVariable, EntityType.Variable));
            source.AppendFront("\t\tmatchesArray[pos] = null;\n");
            source.AppendFront("\telse\n");
            source.AppendFront("\t\tcmpPos = pos;\n");
            source.AppendFront("}\n");

            source.AppendFront("matches.FromList();\n");

            source.Unindent();
            source.AppendFront("}\n");
        }
        void GenerateParallelizationSetupAsNeeded(SourceBuilder sb, LGSPRulePattern rulePattern, SearchProgram searchProgram)
        {
            if(rulePattern.patternGraph.branchingFactor < 2)
                return;

            foreach(SearchOperation so in rulePattern.patternGraph.parallelizedSchedule[0].Operations)
            {
                switch(so.Type)
                {
                    case SearchOperationType.WriteParallelPreset:
                        if(so.Element is SearchPlanNodeNode)
                            sb.AppendFrontFormat("GRGEN_LGSP.LGSPNode {0};\n", NamesOfEntities.IterationParallelizationParallelPresetCandidate(((SearchPlanNodeNode)so.Element).PatternElement.Name));
                        else //SearchPlanEdgeNode
                            sb.AppendFrontFormat("GRGEN_LGSP.LGSPEdge {0};\n", NamesOfEntities.IterationParallelizationParallelPresetCandidate(((SearchPlanEdgeNode)so.Element).PatternElement.Name));
                        break;
                    case SearchOperationType.WriteParallelPresetVar:
                        sb.AppendFrontFormat("{0} {1};\n",
                            TypesHelper.TypeName(((PatternVariable)so.Element).Type),
                            NamesOfEntities.IterationParallelizationParallelPresetCandidate(((PatternVariable)so.Element).Name));
                        break;
                    case SearchOperationType.SetupParallelLookup:
                        if(so.Element is SearchPlanNodeNode)
                        {
                            sb.AppendFrontFormat("GRGEN_LGSP.LGSPNode {0};\n", NamesOfEntities.IterationParallelizationListHead(((SearchPlanNodeNode)so.Element).PatternElement.Name));
                            sb.AppendFrontFormat("GRGEN_LGSP.LGSPNode {0};\n", NamesOfEntities.IterationParallelizationNextCandidate(((SearchPlanNodeNode)so.Element).PatternElement.Name));
                        }
                        else
                        {
                            sb.AppendFrontFormat("GRGEN_LGSP.LGSPEdge {0};\n", NamesOfEntities.IterationParallelizationListHead(((SearchPlanEdgeNode)so.Element).PatternElement.Name));
                            sb.AppendFrontFormat("GRGEN_LGSP.LGSPEdge {0};\n", NamesOfEntities.IterationParallelizationNextCandidate(((SearchPlanEdgeNode)so.Element).PatternElement.Name));
                        }
                        break;
                    case SearchOperationType.SetupParallelPickFromStorage:
                        if(TypesHelper.DotNetTypeToXgrsType(so.Storage.Variable.type).StartsWith("set") || TypesHelper.DotNetTypeToXgrsType(so.Storage.Variable.type).StartsWith("map"))
                        {
                            sb.AppendFrontFormat("IEnumerator<KeyValuePair<{0},{1}>> {2};\n",
                                TypesHelper.XgrsTypeToCSharpType(TypesHelper.ExtractSrc(TypesHelper.DotNetTypeToXgrsType(so.Storage.Variable.Type)), model),
                                TypesHelper.XgrsTypeToCSharpType(TypesHelper.ExtractDst(TypesHelper.DotNetTypeToXgrsType(so.Storage.Variable.Type)), model),
                                NamesOfEntities.IterationParallelizationIterator(((SearchPlanNode)so.Element).PatternElement.Name));
                        }
                        else
                        {
                            sb.AppendFrontFormat("IEnumerator<{0}> {1};\n",
                                TypesHelper.XgrsTypeToCSharpType(TypesHelper.ExtractSrc(TypesHelper.DotNetTypeToXgrsType(so.Storage.Variable.Type)), model),
                                NamesOfEntities.IterationParallelizationIterator(((SearchPlanNode)so.Element).PatternElement.Name));
                        }
                        break;
                    case SearchOperationType.SetupParallelPickFromStorageDependent:
                        if(TypesHelper.AttributeTypeToXgrsType(so.Storage.Attribute.Attribute).StartsWith("set") || TypesHelper.AttributeTypeToXgrsType(so.Storage.Attribute.Attribute).StartsWith("map"))
                        {
                            sb.AppendFrontFormat("IEnumerator<KeyValuePair<{0},{1}>> {2};\n",
                               TypesHelper.XgrsTypeToCSharpType(TypesHelper.ExtractSrc(TypesHelper.AttributeTypeToXgrsType(so.Storage.Attribute.Attribute)), model),
                               TypesHelper.XgrsTypeToCSharpType(TypesHelper.ExtractDst(TypesHelper.AttributeTypeToXgrsType(so.Storage.Attribute.Attribute)), model),
                               NamesOfEntities.IterationParallelizationIterator(((SearchPlanNode)so.Element).PatternElement.Name));
                        }
                        else
                        {
                            sb.AppendFrontFormat("IEnumerator<{0}> {1};\n",
                               TypesHelper.XgrsTypeToCSharpType(TypesHelper.ExtractSrc(TypesHelper.AttributeTypeToXgrsType(so.Storage.Attribute.Attribute)), model),
                               NamesOfEntities.IterationParallelizationIterator(((SearchPlanNode)so.Element).PatternElement.Name));
                        }
                        break;
                    case SearchOperationType.SetupParallelPickFromIndex:
                        sb.AppendFrontFormat("IEnumerator<{0}> {1};\n",
                           TypesHelper.TypeName(so.IndexAccess.Index is AttributeIndexDescription ?
                               ((AttributeIndexDescription)so.IndexAccess.Index).GraphElementType :
                               ((IncidenceCountIndexDescription)so.IndexAccess.Index).StartNodeType),
                           NamesOfEntities.IterationParallelizationIterator(((SearchPlanNode)so.Element).PatternElement.Name));
                        break;
                    case SearchOperationType.SetupParallelPickFromIndexDependent:
                        sb.AppendFrontFormat("IEnumerator<{0}> {1};\n",
                           TypesHelper.TypeName(so.IndexAccess.Index is AttributeIndexDescription ?
                               ((AttributeIndexDescription)so.IndexAccess.Index).GraphElementType :
                               ((IncidenceCountIndexDescription)so.IndexAccess.Index).StartNodeType),
                           NamesOfEntities.IterationParallelizationIterator(((SearchPlanNode)so.Element).PatternElement.Name));
                        break;
                    case SearchOperationType.SetupParallelIncoming:
                    case SearchOperationType.SetupParallelOutgoing:
                        sb.AppendFrontFormat("GRGEN_LGSP.LGSPEdge {0};\n", NamesOfEntities.IterationParallelizationListHead(((SearchPlanEdgeNode)so.Element).PatternElement.Name));
                        sb.AppendFrontFormat("GRGEN_LGSP.LGSPEdge {0};\n", NamesOfEntities.IterationParallelizationNextCandidate(((SearchPlanEdgeNode)so.Element).PatternElement.Name));
                        break;
                    case SearchOperationType.SetupParallelIncident:
                        sb.AppendFrontFormat("GRGEN_LGSP.LGSPEdge {0};\n", NamesOfEntities.IterationParallelizationListHead(((SearchPlanEdgeNode)so.Element).PatternElement.Name));
                        sb.AppendFrontFormat("GRGEN_LGSP.LGSPEdge {0};\n", NamesOfEntities.IterationParallelizationNextCandidate(((SearchPlanEdgeNode)so.Element).PatternElement.Name));
                        sb.AppendFrontFormat("int {0};\n", NamesOfEntities.IterationParallelizationDirectionRunCounterVariable(((SearchPlanEdgeNode)so.Element).PatternElement.Name));
                        break;
                }
            }
            sb.AppendFront("\n");

            String rulePatternClassName = rulePattern.GetType().Name;
            String matchClassName = rulePatternClassName + "." + "Match_" + rulePattern.name;
            String matchInterfaceName = rulePatternClassName + "." + "IMatch_" + rulePattern.name;
            sb.AppendFront("private static GRGEN_LGSP.LGSPMatchesList<" + matchClassName + ", " + matchInterfaceName + ">[] parallelTaskMatches;\n");
            sb.AppendFront("private static int numWorkerThreads;\n");
            sb.AppendFront("private static int iterationNumber;\n");
            sb.AppendFront("private static int iterationLock;\n");
            sb.AppendFront("[ThreadStatic] private static int currentIterationNumber;\n");
            sb.AppendFront("[ThreadStatic] private static int threadId;\n");
            sb.AppendFront("private static GRGEN_LGSP.LGSPActionExecutionEnvironment actionEnvParallel;\n");
            sb.AppendFront("private static int maxMatchesParallel;\n");
            sb.AppendFront("private static bool maxMatchesFound = false;\n");

            sb.AppendFront("private static List<GRGEN_LGSP.LGSPNode>[] moveHeadAfterNodes;\n");
            sb.AppendFront("private static List<GRGEN_LGSP.LGSPEdge>[] moveHeadAfterEdges;\n");
            sb.AppendFront("private static List<KeyValuePair<GRGEN_LGSP.LGSPNode, GRGEN_LGSP.LGSPEdge>>[] moveOutHeadAfter;\n");
            sb.AppendFront("private static List<KeyValuePair<GRGEN_LGSP.LGSPNode, GRGEN_LGSP.LGSPEdge>>[] moveInHeadAfter;\n");
            sb.AppendFront("\n");
        }
 public void GetFilteredParametersAndSuffixedMatcherName(
     LGSPRulePattern rulePattern, PatternGraph patternGraph, int index,
     out String[] paramTypesArray, out String[] paramNamesArray, out String suffixedMatcherName)
 {
     List<String> paramTypes = new List<String>();
     List<String> paramNames = new List<String>();
     List<String> removedNames = new List<String>();
     for(int i = 0; i < rulePattern.Inputs.Length; ++i)
     {
         String inputName = rulePattern.InputNames[i];
         if(patternGraph.availabilityOfMaybeNullElements[index].ContainsKey(inputName)
             && !patternGraph.availabilityOfMaybeNullElements[index][inputName])
         {
             removedNames.Add(rulePattern.InputNames[i]);
         }
         else
         {
             paramTypes.Add(TypesHelper.TypeName(rulePattern.Inputs[i]));
             paramNames.Add(rulePattern.InputNames[i]);
         }
     }
     paramTypesArray = new String[paramTypes.Count];
     paramNamesArray = new String[paramNames.Count];
     for(int i = 0; i < paramTypes.Count; ++i)
     {
         paramTypesArray[i] = paramTypes[i];
         paramNamesArray[i] = paramNames[i];
     }
     suffixedMatcherName = "myMatch";
     foreach(String removedName in removedNames)
     {
         suffixedMatcherName += "_MissingPreset_"+removedName;
     }
 }