private static void BuildInterpretationPlan(LGSPGraph graph) { graph.matchingState.patternGraph = BuildPatternGraph(graph); PlanGraph planGraph = PlanGraphGenerator.GeneratePlanGraph(graph.Model, graph.statistics, graph.matchingState.patternGraph, false, false, false, new Dictionary <PatternElement, SetValueType>()); PlanGraphGenerator.MarkMinimumSpanningArborescence(planGraph, graph.matchingState.patternGraph.name, false); SearchPlanGraph searchPlanGraph = SearchPlanGraphGeneratorAndScheduler.GenerateSearchPlanGraph(planGraph); ScheduledSearchPlan scheduledSearchPlan = SearchPlanGraphGeneratorAndScheduler.ScheduleSearchPlan( searchPlanGraph, graph.matchingState.patternGraph, false, false); InterpretationPlanBuilder builder = new InterpretationPlanBuilder(scheduledSearchPlan, searchPlanGraph, graph.Model); graph.matchingState.interpretationPlan = builder.BuildInterpretationPlan("ComparisonMatcher_" + graph.GraphId); ++GraphMatchingState.numInterpretationPlans; graph.matchingState.changesCounterAtInterpretationPlanBuilding = graph.changesCounterAtLastAnalyze; Debug.Assert(graph.changesCounterAtLastAnalyze == graph.ChangesCounter); #if LOG_ISOMORPHY_CHECKING SourceBuilder sb = new SourceBuilder(); graph.matchingState.interpretationPlan.Dump(sb); writer.WriteLine(); writer.WriteLine(sb.ToString()); writer.WriteLine(); writer.Flush(); #endif }
private static void DumpScheduledSearchPlan(ScheduledSearchPlan ssp, IGraphModel model, String dumpname) { StreamWriter sw = new StreamWriter(dumpname + "-scheduledsp.txt", false); SourceBuilder sb = new SourceBuilder(); ScheduleExplainer.Explain(ssp, sb, model); sb.Append("\n"); sw.WriteLine(sb.ToString()); sw.Close(); }
private static void CompileComparisonMatchers() { for(int i = GraphMatchingState.candidatesForCompilation.Count - 1; i >= 0; --i) { LGSPGraph graph = GraphMatchingState.candidatesForCompilation[i]; if(graph.matchingState.changesCounterAtInterpretationPlanBuilding != graph.ChangesCounter) GraphMatchingState.candidatesForCompilation.RemoveAt(i); } SourceBuilder sourceCode = new SourceBuilder(); sourceCode.AppendFront("using System;\n" + "using System.Collections.Generic;\n" + "using GRGEN_LIBGR = de.unika.ipd.grGen.libGr;\n" + "using GRGEN_LGSP = de.unika.ipd.grGen.lgsp;\n\n"); sourceCode.AppendFront("namespace de.unika.ipd.grGen.lgspComparisonMatchers\n"); sourceCode.AppendFront("{\n"); sourceCode.Indent(); foreach(LGSPGraph graph in GraphMatchingState.candidatesForCompilation) ((InterpretationPlanStart)graph.matchingState.interpretationPlan).Emit(sourceCode); sourceCode.Append("}"); #if DUMP_COMPILED_MATCHER using(StreamWriter sw = new StreamWriter("comparison_matcher_" + GraphMatchingState.candidatesForCompilation[0].GraphId + ".cs")) sw.Write(sourceCode.ToString()); #endif // set up compiler CSharpCodeProvider compiler = new CSharpCodeProvider(); CompilerParameters compParams = new CompilerParameters(); compParams.ReferencedAssemblies.Add("System.dll"); compParams.ReferencedAssemblies.Add(Assembly.GetAssembly(typeof(BaseGraph)).Location); compParams.ReferencedAssemblies.Add(Assembly.GetAssembly(typeof(LGSPGraph)).Location); compParams.GenerateInMemory = true; compParams.CompilerOptions = "/optimize"; // building methods with MSIL would be highly preferable, but is much harder of course CompilerResults compResults = compiler.CompileAssemblyFromSource(compParams, sourceCode.ToString()); if(compResults.Errors.HasErrors) { String errorMsg = compResults.Errors.Count + " Errors:"; foreach(CompilerError error in compResults.Errors) errorMsg += Environment.NewLine + "Line: " + error.Line + " - " + error.ErrorText; throw new ArgumentException("Internal error: Illegal C# source code produced for graph comparison: " + errorMsg); } // create comparison matcher instances foreach(LGSPGraph graph in GraphMatchingState.candidatesForCompilation) { graph.matchingState.compiledMatcher = (GraphComparisonMatcher)compResults.CompiledAssembly.CreateInstance( "de.unika.ipd.grGen.lgspComparisonMatchers.ComparisonMatcher_" + graph.graphID); if(graph.matchingState.compiledMatcher == null) throw new ArgumentException("Internal error: Generated assembly does not contain comparison matcher 'ComparisonMatcher_" + graph.graphID + "'!"); ++GraphMatchingState.numCompiledMatchers; } GraphMatchingState.candidatesForCompilation.Clear(); ++GraphMatchingState.numCompilationPasses; }
public override string ToString() { String fromStr = ""; SourceBuilder sbFrom = new SourceBuilder(); if(From != null) { sbFrom.Append(Index.Name); if(IncludingFrom) sbFrom.Append("<="); else sbFrom.Append("<"); From.Emit(sbFrom); fromStr = sbFrom.ToString(); } String toStr = ""; SourceBuilder sbTo = new SourceBuilder(); if(To != null) { sbTo.Append(Index.Name); if(IncludingTo) sbTo.Append(">="); else sbTo.Append(">"); To.Emit(sbTo); toStr = sbTo.ToString(); } if(From == null && To == null) return "descending(" + Index.Name + ")"; else return "descending(" + fromStr + " " + toStr + ")"; }
/// <summary> /// Does action-backend dependent stuff. /// </summary> /// <param name="args">Any kind of parameters for the stuff to do</param> public override void Custom(params object[] args) { if(args.Length == 0) goto invalidCommand; switch((String) args[0]) { case "gen_searchplan": { if(graph.statistics.edgeCounts == null) throw new ArgumentException("Graph not analyzed yet!\nPlease execute 'custom graph analyze'!"); LGSPAction[] oldActions; if(args.Length == 1) { oldActions = new LGSPAction[actions.Count]; int i = 0; foreach(LGSPAction action in actions.Values) { oldActions[i] = action; ++i; } } else { oldActions = new LGSPAction[args.Length - 1]; for(int i = 0; i < oldActions.Length; i++) { oldActions[i] = (LGSPAction)GetAction((String)args[i + 1]); if(oldActions[i] == null) throw new ArgumentException("'" + (String)args[i + 1] + "' is not the name of an action!\n" + "Please use 'show actions' to get a list of the available names."); } } int startticks = Environment.TickCount; matcherGenerator.LazyNegativeIndependentConditionEvaluation = LazyNIC; matcherGenerator.InlineIndependents = InlineIndependents; matcherGenerator.Profile = Profile; LGSPAction[] newActions = matcherGenerator.GenerateActions(graph, modelAssemblyName, actionsAssemblyName, oldActions); int stopticks = Environment.TickCount; Console.Write("Searchplans for actions "); for(int i = 0; i < oldActions.Length; i++) { actions[oldActions[i].Name] = newActions[i]; if(i != 0) Console.Write(", "); Console.Write("'" + oldActions[i].Name + "'"); } Console.WriteLine(" generated in " + (stopticks - startticks) + " ms."); return; } case "dump_sourcecode": if(args.Length != 2) throw new ArgumentException("Usage: dump_sourcecode <bool>\n" + "If <bool> == true, C# files will be dumped for new searchplans."); if(!bool.TryParse((String) args[1], out matcherGenerator.DumpDynSourceCode)) throw new ArgumentException("Illegal bool value specified: \"" + (String) args[1] + "\""); return; case "dump_searchplan": if(args.Length != 2) throw new ArgumentException("Usage: dump_searchplan <bool>\n" + "If <bool> == true, VCG and TXT files will be dumped for new searchplans."); if(!bool.TryParse((String) args[1], out matcherGenerator.DumpSearchPlan)) throw new ArgumentException("Illegal bool value specified: \"" + (String) args[1] + "\""); return; case "explain": { if(args.Length != 2) throw new ArgumentException("Usage: explain <name>\n" + "Explains the searchplan of the given action."); LGSPAction action = (LGSPAction)GetAction((String)args[1]); if(action == null) throw new ArgumentException("'" + (String)args[1] + "' is not the name of an action!\n" + "Please use 'show actions' to get a list of the available names."); if(action.patternGraph.schedules[0] == null) { LGSPGraphStatistics graphStatistics = null; if(StatisticsPath != null) { Console.WriteLine("static search plans from " + StatisticsPath); graphStatistics = new LGSPGraphStatistics(graph.Model); graphStatistics.Parse(StatisticsPath); } else Console.WriteLine("static search plans"); LGSPMatcherGenerator matcherGen = new LGSPMatcherGenerator(graph.Model); matcherGen.FillInStaticSearchPlans(graphStatistics, InlineIndependents, action); } SourceBuilder sb = new SourceBuilder(); foreach(KeyValuePair<LGSPMatchingPattern, LGSPMatchingPattern> usedSubpattern in action.rulePattern.patternGraph.usedSubpatterns) { usedSubpattern.Key.patternGraph.Explain(sb, graph.Model); } action.patternGraph.Explain(sb, graph.Model); Console.WriteLine(sb.ToString()); return; } } invalidCommand: throw new ArgumentException("Possible commands:\n" + "- gen_searchplan: Generates a new searchplan for a given action\n" + " depending on a previous graph analysis\n" + "- explain: explains the searchplan in use for a given action\n" + "- dump_sourcecode: Sets dumping of C# files for new searchplans\n" + "- dump_searchplan: Sets dumping of VCG and TXT files of new\n" + " searchplans (with some intermediate steps)"); }
/// <summary> /// Generate new actions for the given actions, doing the same work, /// but hopefully faster by taking graph analysis information into account /// </summary> public LGSPAction[] GenerateActions(LGSPGraph graph, String modelAssemblyName, String actionsAssemblyName, params LGSPAction[] actions) { if(actions.Length == 0) throw new ArgumentException("No actions provided!"); SourceBuilder sourceCode = new SourceBuilder(CommentSourceCode); GenerateFileHeaderForActionsFile(sourceCode, model.GetType().Namespace, actions[0].rulePattern.GetType().Namespace); // use domain of dictionary as set with rulepatterns of the subpatterns of the actions, get them from pattern graph Dictionary<LGSPMatchingPattern, LGSPMatchingPattern> subpatternMatchingPatterns = new Dictionary<LGSPMatchingPattern, LGSPMatchingPattern>(); foreach (LGSPAction action in actions) { foreach (KeyValuePair<LGSPMatchingPattern, LGSPMatchingPattern> usedSubpattern in action.rulePattern.patternGraph.usedSubpatterns) { subpatternMatchingPatterns[usedSubpattern.Key] = usedSubpattern.Value; } } // generate code for subpatterns foreach (KeyValuePair<LGSPMatchingPattern, LGSPMatchingPattern> subpatternMatchingPattern in subpatternMatchingPatterns) { LGSPMatchingPattern smp = subpatternMatchingPattern.Key; GenerateScheduledSearchPlans(smp.patternGraph, graph, true, false, null); MergeNegativeAndIndependentSchedulesIntoEnclosingSchedules(smp.patternGraph); ParallelizeAsNeeded(smp); GenerateActionAndMatcher(sourceCode, smp, false); } // generate code for actions foreach(LGSPAction action in actions) { GenerateScheduledSearchPlans(action.rulePattern.patternGraph, graph, false, false, null); MergeNegativeAndIndependentSchedulesIntoEnclosingSchedules(action.rulePattern.patternGraph); ParallelizeAsNeeded(action.rulePattern); GenerateActionAndMatcher(sourceCode, action.rulePattern, false); } // close namespace sourceCode.Append("}"); if(DumpDynSourceCode) { using(StreamWriter writer = new StreamWriter("dynamic_" + actions[0].Name + ".cs")) writer.Write(sourceCode.ToString()); } // set up compiler CSharpCodeProvider compiler = new CSharpCodeProvider(); CompilerParameters compParams = GetDynCompilerSetup(modelAssemblyName, actionsAssemblyName); // compile generated code CompilerResults compResults = compiler.CompileAssemblyFromSource(compParams, sourceCode.ToString()); if(compResults.Errors.HasErrors) { String errorMsg = compResults.Errors.Count + " Errors:"; foreach(CompilerError error in compResults.Errors) errorMsg += Environment.NewLine + "Line: " + error.Line + " - " + error.ErrorText; throw new ArgumentException("Internal error: Illegal dynamic C# source code produced: " + errorMsg); } // create action instances LGSPAction[] newActions = new LGSPAction[actions.Length]; for(int i = 0; i < actions.Length; i++) { newActions[i] = (LGSPAction) compResults.CompiledAssembly.CreateInstance( "de.unika.ipd.grGen.lgspActions.DynAction_" + actions[i].Name); if(newActions[i] == null) throw new ArgumentException("Internal error: Generated assembly does not contain action '" + actions[i].Name + "'!"); } return newActions; }
/// <summary> /// Generates the parallelized search program for the given iterated pattern /// </summary> SearchProgram GenerateParallelizedSearchProgramIteratedAsNeeded(LGSPMatchingPattern matchingPattern, PatternGraph iter) { if(matchingPattern.patternGraph.parallelizedSchedule == null) return null; // build pass: build nested program from scheduled search plan of the all pattern SearchProgramBuilder searchProgramBuilder = new SearchProgramBuilder(); SearchProgram searchProgram = searchProgramBuilder.BuildSearchProgram(model, matchingPattern, iter, true, Profile); #if DUMP_SEARCHPROGRAMS // dump built search program for debugging SourceBuilder builder = new SourceBuilder(CommentSourceCode); searchProgram.Dump(builder); StreamWriter writer = new StreamWriter(matchingPattern.name + "_parallelized_" + iter.name + "_" + searchProgram.Name + "_built_dump.txt"); writer.Write(builder.ToString()); writer.Close(); #endif // complete pass: complete check operations in all search programs SearchProgramCompleter searchProgramCompleter = new SearchProgramCompleter(); searchProgramCompleter.CompleteCheckOperationsInAllSearchPrograms(searchProgram); #if DUMP_SEARCHPROGRAMS // dump completed search program for debugging builder = new SourceBuilder(CommentSourceCode); searchProgram.Dump(builder); writer = new StreamWriter(matchingPattern.name + "_parallelized_" + iter.name + "_" + searchProgram.Name + "_completed_dump.txt"); writer.Write(builder.ToString()); writer.Close(); #endif return searchProgram; }
/// <summary> /// Generates the parallelized search program(s) for the pattern graph of the given rule /// </summary> SearchProgram GenerateParallelizedSearchProgramAsNeeded(LGSPMatchingPattern matchingPattern) { PatternGraph patternGraph = matchingPattern.patternGraph; if(patternGraph.parallelizedSchedule == null) return null; SearchProgram searchProgramRoot = null; SearchProgram searchProgramListEnd = null; for(int i = 0; i < patternGraph.parallelizedSchedule.Length; ++i) // 2 for actions, 1 for subpatterns { ScheduledSearchPlan scheduledSearchPlan = patternGraph.parallelizedSchedule[i]; #if DUMP_SCHEDULED_SEARCH_PLAN StreamWriter sspwriter = new StreamWriter(matchingPattern.name + (i==1 ? "_parallelized_body" : "_parallelized") + "_ssp_dump.txt"); float prevCostToEnd = scheduledSearchPlan.Operations.Length > 0 ? scheduledSearchPlan.Operations[0].CostToEnd : 0f; foreach(SearchOperation so in scheduledSearchPlan.Operations) { sspwriter.Write(SearchOpToString(so) + " ; " + so.CostToEnd + " (+" + (prevCostToEnd-so.CostToEnd) + ")" + "\n"); prevCostToEnd = so.CostToEnd; } sspwriter.Close(); #endif // build pass: build nested program from scheduled search plan SearchProgramBuilder searchProgramBuilder = new SearchProgramBuilder(); if(matchingPattern is LGSPRulePattern) { SearchProgram sp = searchProgramBuilder.BuildSearchProgram(model, (LGSPRulePattern)matchingPattern, i, null, true, Profile); if(i == 0) searchProgramRoot = searchProgramListEnd = sp; else searchProgramListEnd = (SearchProgram)searchProgramListEnd.Append(sp); } else { Debug.Assert(searchProgramRoot == null); searchProgramRoot = searchProgramListEnd = searchProgramBuilder.BuildSearchProgram(model, matchingPattern, true, Profile); } } #if DUMP_SEARCHPROGRAMS // dump built search program for debugging SourceBuilder builder = new SourceBuilder(CommentSourceCode); searchProgramRoot.Dump(builder); StreamWriter writer = new StreamWriter(matchingPattern.name + (i==1 ? "_parallelized_body" : "_parallelized") + "_" + searchProgramRoot.Name + "_built_dump.txt"); writer.Write(builder.ToString()); writer.Close(); #endif // complete pass: complete check operations in all search programs SearchProgramCompleter searchProgramCompleter = new SearchProgramCompleter(); searchProgramCompleter.CompleteCheckOperationsInAllSearchPrograms(searchProgramRoot); #if DUMP_SEARCHPROGRAMS // dump completed search program for debugging builder = new SourceBuilder(CommentSourceCode); searchProgramRoot.Dump(builder); writer = new StreamWriter(matchingPattern.name + (i==1 ? "_parallelized_body" : "_parallelized") + "_" + searchProgramRoot.Name + "_completed_dump.txt"); writer.Write(builder.ToString()); writer.Close(); #endif return searchProgramRoot; }
/// <summary> /// Search program operations implementing the /// setup parallelized PickFromIndex search plan operation /// are created and inserted into search program /// </summary> private SearchProgramOperation buildParallelPickFromIndexSetup( SearchProgramOperation insertionPoint, SearchPlanNode target, IndexAccess index) { bool isNode = target.NodeType == PlanNodeType.Node; string negativeIndependentNamePrefix = ""; PatternGraph patternGraph = patternGraphWithNestingPatterns.Peek(); string iterationType = TypesHelper.TypeName(index.Index is AttributeIndexDescription ? ((AttributeIndexDescription)index.Index).GraphElementType : ((IncidenceCountIndexDescription)index.Index).StartNodeType); string indexSetType = NamesOfEntities.IndexSetType(model.ModelName); // iterate available index elements GetCandidateByIterationParallelSetup elementsIteration; if(index is IndexAccessEquality) { IndexAccessEquality indexEquality = (IndexAccessEquality)index; SourceBuilder equalityExpression = new SourceBuilder(); indexEquality.Expr.Emit(equalityExpression); elementsIteration = new GetCandidateByIterationParallelSetup( GetCandidateByIterationType.IndexElements, target.PatternElement.Name, index.Index.Name, iterationType, indexSetType, IndexAccessType.Equality, equalityExpression.ToString(), isNode, rulePatternClassName, patternGraph.name, parameterNames, wasIndependentInlined(patternGraph, indexOfSchedule), emitProfiling, packagePrefixedActionName, !firstLoopPassed); } else if(index is IndexAccessAscending) { IndexAccessAscending indexAscending = (IndexAccessAscending)index; SourceBuilder fromExpression = new SourceBuilder(); if(indexAscending.From != null) indexAscending.From.Emit(fromExpression); SourceBuilder toExpression = new SourceBuilder(); if(indexAscending.To != null) indexAscending.To.Emit(toExpression); elementsIteration = new GetCandidateByIterationParallelSetup( GetCandidateByIterationType.IndexElements, target.PatternElement.Name, index.Index.Name, iterationType, indexSetType, IndexAccessType.Ascending, indexAscending.From != null ? fromExpression.ToString() : null, indexAscending.IncludingFrom, indexAscending.To != null ? toExpression.ToString() : null, indexAscending.IncludingTo, isNode, rulePatternClassName, patternGraph.name, parameterNames, wasIndependentInlined(patternGraph, indexOfSchedule), emitProfiling, packagePrefixedActionName, !firstLoopPassed); } else //if(index is IndexAccessDescending) { IndexAccessDescending indexDescending = (IndexAccessDescending)index; SourceBuilder fromExpression = new SourceBuilder(); if(indexDescending.From != null) indexDescending.From.Emit(fromExpression); SourceBuilder toExpression = new SourceBuilder(); if(indexDescending.To != null) indexDescending.To.Emit(toExpression); elementsIteration = new GetCandidateByIterationParallelSetup( GetCandidateByIterationType.IndexElements, target.PatternElement.Name, index.Index.Name, iterationType, indexSetType, IndexAccessType.Descending, indexDescending.From != null ? fromExpression.ToString() : null, indexDescending.IncludingFrom, indexDescending.To != null ? toExpression.ToString() : null, indexDescending.IncludingTo, isNode, rulePatternClassName, patternGraph.name, parameterNames, wasIndependentInlined(patternGraph, indexOfSchedule), emitProfiling, packagePrefixedActionName, !firstLoopPassed); } return insertionPoint.Append(elementsIteration); }
/// <summary> /// Search program operations implementing the /// Condition search plan operation /// are created and inserted into search program /// </summary> private SearchProgramOperation buildCondition( SearchProgramOperation insertionPoint, int currentOperationIndex, PatternCondition condition) { // generate c#-code-string out of condition expression ast SourceBuilder conditionExpression = new SourceBuilder(); condition.ConditionExpression.Emit(conditionExpression); // check condition with current partial match CheckPartialMatchByCondition checkCondition = new CheckPartialMatchByCondition(conditionExpression.ToString(), condition.NeededNodes, condition.NeededEdges, condition.NeededVariables); insertionPoint = insertionPoint.Append(checkCondition); //--------------------------------------------------------------------------- // build next operation insertionPoint = BuildScheduledSearchPlanOperationIntoSearchProgram( currentOperationIndex + 1, insertionPoint); //--------------------------------------------------------------------------- return insertionPoint; }
private SearchProgramOperation insertVariableDeclarationsNegIdpt(SearchProgramOperation insertionPoint, PatternGraph patternGraph) { foreach(PatternNode node in patternGraph.nodesPlusInlined) { if(node.defToBeYieldedTo && patternGraph.WasInlinedHere(node.originalSubpatternEmbedding)) { insertionPoint = insertionPoint.Append( new DeclareDefElement(EntityType.Node, "GRGEN_LGSP.LGSPNode", node.Name, "null") ); } } foreach(PatternEdge edge in patternGraph.edgesPlusInlined) { if(edge.defToBeYieldedTo && patternGraph.WasInlinedHere(edge.originalSubpatternEmbedding)) { insertionPoint = insertionPoint.Append( new DeclareDefElement(EntityType.Edge, "GRGEN_LGSP.LGSPEdge", edge.Name, "null") ); } } foreach(PatternVariable var in patternGraph.variablesPlusInlined) { if(var.defToBeYieldedTo && patternGraph.WasInlinedHere(var.originalSubpatternEmbedding)) { String initializationExpression; if(var.initialization != null) { SourceBuilder builder = new SourceBuilder(); var.initialization.Emit(builder); initializationExpression = builder.ToString(); } else { string typeName = TypesHelper.XgrsTypeToCSharpType(TypesHelper.DotNetTypeToXgrsType(var.type), model); initializationExpression = TypesHelper.DefaultValueString(typeName, model); } insertionPoint = insertionPoint.Append( new DeclareDefElement(EntityType.Variable, TypesHelper.TypeName(var.type), var.Name, initializationExpression) ); } } return insertionPoint; }
/// <summary> /// Search program operations implementing the /// AssignVar search plan operation /// are created and inserted into search program /// </summary> private SearchProgramOperation buildAssignVar( SearchProgramOperation insertionPoint, int currentOperationIndex, PatternVariable variable, Expression expression) { // generate c#-code-string out of condition expression ast SourceBuilder assignmentExpression = new SourceBuilder(); expression.Emit(assignmentExpression); // get candidate from other element (the cast is simply the following type check) AssignVariableFromExpression assignVar = new AssignVariableFromExpression( variable.Name, TypesHelper.TypeName(variable.type), assignmentExpression.ToString()); insertionPoint = insertionPoint.Append(assignVar); //--------------------------------------------------------------------------- // build next operation insertionPoint = BuildScheduledSearchPlanOperationIntoSearchProgram( currentOperationIndex + 1, insertionPoint); //--------------------------------------------------------------------------- return insertionPoint; }
/// <summary> /// Search program operations implementing the /// PickByUnique or PickByUniqueDependent search plan operation /// are created and inserted into search program /// </summary> private SearchProgramOperation buildPickByUnique( SearchProgramOperation insertionPoint, int currentOperationIndex, SearchPlanNode target, UniqueLookup uniqueLookup, IsomorphyInformation isomorphy) { bool isNode = target.NodeType == PlanNodeType.Node; string negativeIndependentNamePrefix = NegativeIndependentNamePrefix(patternGraphWithNestingPatterns.Peek()); SourceBuilder expression = new SourceBuilder(); uniqueLookup.Expr.Emit(expression); // get candidate from unique index, only creates variable to hold it, get is fused with check for index membership GetCandidateByDrawing elementByUnique = new GetCandidateByDrawing( GetCandidateByDrawingType.MapByUnique, target.PatternElement.Name, expression.ToString(), isNode); insertionPoint = insertionPoint.Append(elementByUnique); // check existence of candidate in unique map CheckCandidateMapByUnique checkElementInUniqueMap = new CheckCandidateMapByUnique( target.PatternElement.Name, isNode); insertionPoint = insertionPoint.Append(checkElementInUniqueMap); // check type of candidate insertionPoint = decideOnAndInsertCheckType(insertionPoint, target); // check connectedness of candidate SearchProgramOperation continuationPointAfterConnectednessCheck; if(isNode) { insertionPoint = decideOnAndInsertCheckConnectednessOfNodeFromLookupOrPickOrMap( insertionPoint, (SearchPlanNodeNode)target, out continuationPointAfterConnectednessCheck); } else { insertionPoint = decideOnAndInsertCheckConnectednessOfEdgeFromLookupOrPickOrMap( insertionPoint, (SearchPlanEdgeNode)target, out continuationPointAfterConnectednessCheck); } if(continuationPointAfterConnectednessCheck == insertionPoint) continuationPointAfterConnectednessCheck = null; // check candidate for isomorphy if(isomorphy.CheckIsMatchedBit) { CheckCandidateForIsomorphy checkIsomorphy = new CheckCandidateForIsomorphy( target.PatternElement.Name, isomorphy.PatternElementsToCheckAgainstAsListOfStrings(), negativeIndependentNamePrefix, isNode, isoSpaceNeverAboveMaxIsoSpace, isomorphy.Parallel, isomorphy.LockForAllThreads); insertionPoint = insertionPoint.Append(checkIsomorphy); } // check candidate for global isomorphy if(programType == SearchProgramType.Subpattern || programType == SearchProgramType.AlternativeCase || programType == SearchProgramType.Iterated) { if(!isomorphy.TotallyHomomorph) { CheckCandidateForIsomorphyGlobal checkIsomorphy = new CheckCandidateForIsomorphyGlobal( target.PatternElement.Name, isomorphy.GloballyHomomorphPatternElementsAsListOfStrings(), isNode, isoSpaceNeverAboveMaxIsoSpace, isomorphy.Parallel); insertionPoint = insertionPoint.Append(checkIsomorphy); } } // check candidate for pattern path isomorphy if(patternGraphWithNestingPatterns.Peek().isPatternGraphOnPathFromEnclosingPatternpath) { CheckCandidateForIsomorphyPatternPath checkIsomorphy = new CheckCandidateForIsomorphyPatternPath( target.PatternElement.Name, isNode, patternGraphWithNestingPatterns.Peek().isPatternpathLocked, getCurrentLastMatchAtPreviousNestingLevel()); insertionPoint = insertionPoint.Append(checkIsomorphy); } // accept candidate (write isomorphy information) if(isomorphy.SetIsMatchedBit) { AcceptCandidate acceptCandidate = new AcceptCandidate( target.PatternElement.Name, negativeIndependentNamePrefix, isNode, isoSpaceNeverAboveMaxIsoSpace, isomorphy.Parallel, isomorphy.LockForAllThreads); insertionPoint = insertionPoint.Append(acceptCandidate); } // mark element as visited target.Visited = true; //--------------------------------------------------------------------------- // build next operation insertionPoint = BuildScheduledSearchPlanOperationIntoSearchProgram( currentOperationIndex + 1, insertionPoint); //--------------------------------------------------------------------------- // unmark element for possibly following run target.Visited = false; // abandon candidate (restore isomorphy information) if(isomorphy.SetIsMatchedBit) { // only if isomorphy information was previously written AbandonCandidate abandonCandidate = new AbandonCandidate( target.PatternElement.Name, negativeIndependentNamePrefix, isNode, isoSpaceNeverAboveMaxIsoSpace, isomorphy.Parallel, isomorphy.LockForAllThreads); insertionPoint = insertionPoint.Append(abandonCandidate); } if(continuationPointAfterConnectednessCheck != null) insertionPoint = continuationPointAfterConnectednessCheck; return insertionPoint; }
/// <summary> /// Search program operations implementing the /// DefElementToBeYieldedTo search plan operation /// are created and inserted into search program /// </summary> private SearchProgramOperation buildDefToBeYieldedTo( SearchProgramOperation insertionPoint, int currentOperationIndex, object target) { if(target is PatternVariable) { PatternVariable var = (PatternVariable)target; String initializationExpression; if(var.initialization != null) { SourceBuilder builder = new SourceBuilder(); var.initialization.Emit(builder); initializationExpression = builder.ToString(); } else { string typeName = TypesHelper.XgrsTypeToCSharpType(TypesHelper.DotNetTypeToXgrsType(var.type), model); initializationExpression = TypesHelper.DefaultValueString(typeName, model); } insertionPoint = insertionPoint.Append( new DeclareDefElement(EntityType.Variable, TypesHelper.TypeName(var.type), var.Name, initializationExpression) ); } else { if(((SearchPlanNode)target).PatternElement is PatternNode) { PatternNode node = (PatternNode)((SearchPlanNode)target).PatternElement; String initializationExpression; if(node.initialization != null) { SourceBuilder builder = new SourceBuilder(); node.initialization.Emit(builder); initializationExpression = builder.ToString(); } else { initializationExpression = "null"; } insertionPoint = insertionPoint.Append( new DeclareDefElement(EntityType.Node, "GRGEN_LGSP.LGSPNode", node.Name, initializationExpression) ); } else { PatternEdge edge = (PatternEdge)((SearchPlanNode)target).PatternElement; String initializationExpression; if(edge.initialization != null) { SourceBuilder builder = new SourceBuilder(); edge.initialization.Emit(builder); initializationExpression = builder.ToString(); } else { initializationExpression = "null"; } insertionPoint = insertionPoint.Append( new DeclareDefElement(EntityType.Edge, "GRGEN_LGSP.LGSPEdge", edge.Name, initializationExpression) ); } } //--------------------------------------------------------------------------- // build next operation insertionPoint = BuildScheduledSearchPlanOperationIntoSearchProgram( currentOperationIndex + 1, insertionPoint); //--------------------------------------------------------------------------- return insertionPoint; }
/// <summary> /// Search program operations implementing the /// parallelized PickFromIndex search plan operation /// are created and inserted into search program /// </summary> private SearchProgramOperation buildParallelPickFromIndex( SearchProgramOperation insertionPoint, int currentOperationIndex, SearchPlanNode target, IndexAccess index, IsomorphyInformation isomorphy) { bool isNode = target.NodeType == PlanNodeType.Node; string negativeIndependentNamePrefix = ""; string iterationType = TypesHelper.TypeName(index.Index is AttributeIndexDescription ? ((AttributeIndexDescription)index.Index).GraphElementType : ((IncidenceCountIndexDescription)index.Index).StartNodeType); string indexSetType = NamesOfEntities.IndexSetType(model.ModelName); // iterate available index elements GetCandidateByIterationParallel elementsIteration; if(index is IndexAccessEquality) { IndexAccessEquality indexEquality = (IndexAccessEquality)index; SourceBuilder equalityExpression = new SourceBuilder(); indexEquality.Expr.Emit(equalityExpression); elementsIteration = new GetCandidateByIterationParallel( GetCandidateByIterationType.IndexElements, target.PatternElement.Name, index.Index.Name, iterationType, indexSetType, IndexAccessType.Equality, equalityExpression.ToString(), isNode, emitProfiling, packagePrefixedActionName, !firstLoopPassed); } else if(index is IndexAccessAscending) { IndexAccessAscending indexAscending = (IndexAccessAscending)index; SourceBuilder fromExpression = new SourceBuilder(); if(indexAscending.From != null) indexAscending.From.Emit(fromExpression); SourceBuilder toExpression = new SourceBuilder(); if(indexAscending.To != null) indexAscending.To.Emit(toExpression); elementsIteration = new GetCandidateByIterationParallel( GetCandidateByIterationType.IndexElements, target.PatternElement.Name, index.Index.Name, iterationType, indexSetType, IndexAccessType.Ascending, indexAscending.From != null ? fromExpression.ToString() : null, indexAscending.IncludingFrom, indexAscending.To != null ? toExpression.ToString() : null, indexAscending.IncludingTo, isNode, emitProfiling, packagePrefixedActionName, !firstLoopPassed); } else //if(index is IndexAccessDescending) { IndexAccessDescending indexDescending = (IndexAccessDescending)index; SourceBuilder fromExpression = new SourceBuilder(); if(indexDescending.From != null) indexDescending.From.Emit(fromExpression); SourceBuilder toExpression = new SourceBuilder(); if(indexDescending.To != null) indexDescending.To.Emit(toExpression); elementsIteration = new GetCandidateByIterationParallel( GetCandidateByIterationType.IndexElements, target.PatternElement.Name, index.Index.Name, iterationType, indexSetType, IndexAccessType.Descending, indexDescending.From != null ? fromExpression.ToString() : null, indexDescending.IncludingFrom, indexDescending.To != null ? toExpression.ToString() : null, indexDescending.IncludingTo, isNode, emitProfiling, packagePrefixedActionName, !firstLoopPassed); } firstLoopPassed = true; SearchProgramOperation continuationPoint = insertionPoint.Append(elementsIteration); elementsIteration.NestedOperationsList = new SearchProgramList(elementsIteration); insertionPoint = elementsIteration.NestedOperationsList; // check type of candidate insertionPoint = decideOnAndInsertCheckType(insertionPoint, target); // check connectedness of candidate SearchProgramOperation continuationPointAfterConnectednessCheck; if(isNode) { insertionPoint = decideOnAndInsertCheckConnectednessOfNodeFromLookupOrPickOrMap( insertionPoint, (SearchPlanNodeNode)target, out continuationPointAfterConnectednessCheck); } else { insertionPoint = decideOnAndInsertCheckConnectednessOfEdgeFromLookupOrPickOrMap( insertionPoint, (SearchPlanEdgeNode)target, out continuationPointAfterConnectednessCheck); } // check candidate for isomorphy if(isomorphy.CheckIsMatchedBit) { CheckCandidateForIsomorphy checkIsomorphy = new CheckCandidateForIsomorphy( target.PatternElement.Name, isomorphy.PatternElementsToCheckAgainstAsListOfStrings(), negativeIndependentNamePrefix, isNode, isoSpaceNeverAboveMaxIsoSpace, isomorphy.Parallel, isomorphy.LockForAllThreads); insertionPoint = insertionPoint.Append(checkIsomorphy); } // accept candidate (write isomorphy information) if(isomorphy.SetIsMatchedBit) { AcceptCandidate acceptCandidate = new AcceptCandidate( target.PatternElement.Name, negativeIndependentNamePrefix, isNode, isoSpaceNeverAboveMaxIsoSpace, isomorphy.Parallel, isomorphy.LockForAllThreads); insertionPoint = insertionPoint.Append(acceptCandidate); } // mark element as visited target.Visited = true; //--------------------------------------------------------------------------- // build next operation insertionPoint = BuildScheduledSearchPlanOperationIntoSearchProgram( currentOperationIndex + 1, insertionPoint); //--------------------------------------------------------------------------- // unmark element for possibly following run target.Visited = false; // abandon candidate (restore isomorphy information) if(isomorphy.SetIsMatchedBit) { // only if isomorphy information was previously written AbandonCandidate abandonCandidate = new AbandonCandidate( target.PatternElement.Name, negativeIndependentNamePrefix, isNode, isoSpaceNeverAboveMaxIsoSpace, isomorphy.Parallel, isomorphy.LockForAllThreads); insertionPoint = insertionPoint.Append(abandonCandidate); } // everything nested within candidate iteration built by now - // continue at the end of the list after storage iteration insertionPoint = continuationPoint; return insertionPoint; }
private void DumpScheduledSearchPlan(ScheduledSearchPlan ssp, String dumpname) { StreamWriter sw = new StreamWriter(dumpname + "-scheduledsp.txt", false); SourceBuilder sb = new SourceBuilder(); ssp.Explain(sb, model); sb.Append("\n"); sw.WriteLine(sb.ToString()); sw.Close(); /* StreamWriter sw = new StreamWriter(dumpname + "-scheduledsp.vcg", false); sw.WriteLine("graph:{\ninfoname 1: \"Attributes\"\ndisplay_edge_labels: no\nport_sharing: no\nsplines: no\n" + "\nmanhattan_edges: no\nsmanhattan_edges: no\norientation: bottom_to_top\nedges: yes\nnodes: yes\nclassname 1: \"normal\""); sw.WriteLine("node:{title:\"root\" label:\"ROOT\"}\n"); SearchPlanNode root = new SearchPlanNode("root"); sw.WriteLine("graph:{{title:\"pattern\" label:\"{0}\" status:clustered color:lightgrey", dumpname); foreach(SearchOperation op in ssp.Operations) { switch(op.Type) { case SearchOperationType.Lookup: case SearchOperationType.Incoming: case SearchOperationType.Outgoing: case SearchOperationType.ImplicitSource: case SearchOperationType.ImplicitTarget: { SearchPlanNode spnode = (SearchPlanNode) op.Element; DumpNode(sw, spnode); SearchPlanNode src; switch(op.Type) { case SearchOperationType.Lookup: case SearchOperationType.ActionPreset: case SearchOperationType.NegPreset: src = root; break; default: src = op.SourceSPNode; break; } DumpEdge(sw, op.Type, src, spnode, op.CostToEnd, false); break; } case SearchOperationType.Condition: sw.WriteLine("node:{title:\"Condition\" label:\"CONDITION\"}\n"); break; case SearchOperationType.NegativePattern: sw.WriteLine("node:{title:\"NAC\" label:\"NAC\"}\n"); break; } }*/ }
/// <summary> /// Inserts code to yield, bubbling effects of nested yields upwards and computing local yields /// at the given position, returns position after inserted operations /// </summary> private SearchProgramOperation insertYields( SearchProgramOperation insertionPoint, PatternGraph patternGraph, String matchObjectName, bool inlined) { // the match object is built now with our local elements // and the match objects of our children // now 1. copy all def entities we share with children to our local variables foreach(PatternGraphEmbedding patternEmbedding in patternGraph.embeddedGraphsPlusInlined) { // in the inlined pass only the elements which were inlined into this pattern, in the non-inlined pass the original elements bool wasInlined = patternEmbedding.originalEmbedding != null; if(inlined == wasInlined) { // if the pattern embedding does not contain a def entity it can't yield to us if(!((PatternGraph)patternEmbedding.EmbeddedGraph).isDefEntityExistingPlusInlined) continue; // skip inlined embeddings (will be handled in 3.) if(patternEmbedding.inlined) continue; // in inlined pass bubble up from the components of the inlined patterns to the elements resulting from of the inlined pattern // (read from submatches to local variables, compute in local variables, writing will happen later from local variables to matches) string inlinedMatchObjectName = null; string patternEmbeddingName = patternEmbedding.Name; if(patternEmbedding.originalEmbedding != null) { if(patternGraph.WasInlinedHere(patternEmbedding.originalSubpatternEmbedding)) inlinedMatchObjectName = "match_" + patternEmbedding.originalSubpatternEmbedding.Name; patternEmbeddingName = patternEmbedding.originalEmbedding.name; } LGSPMatchingPattern matchingPattern = patternEmbedding.matchingPatternOfEmbeddedGraph; String nestedMatchObjectName = (inlinedMatchObjectName ?? matchObjectName) + "._" + patternEmbeddingName; Debug.Assert(matchingPattern.defNames.Length == patternEmbedding.yields.Length); for(int i = 0; i < patternEmbedding.yields.Length; ++i) { BubbleUpYieldAssignment bubble = new BubbleUpYieldAssignment( toBubbleUpYieldAssignmentType(matchingPattern.defs[i]), patternEmbedding.yields[i], nestedMatchObjectName, matchingPattern.defNames[i] ); insertionPoint = insertionPoint.Append(bubble); } } } foreach(Iterated iterated in patternGraph.iteratedsPlusInlined) { // in the inlined pass only the elements which were inlined into this pattern, in the non-inlined pass the original elements bool wasInlined = iterated.originalIterated != null; if(inlined == wasInlined) { // if the iterated does not contain a non local def entity it can't yield to us if(!iterated.iteratedPattern.isNonLocalDefEntityExistingPlusInlined) continue; // in inlined pass bubble up from the components of the inlined patterns to the elements resulting from of the inlined pattern // (read from submatches to local variables, compute in local variables, writing will happen later from local variables to matches) string inlinedMatchObjectName = null; string iteratedName = iterated.iteratedPattern.Name; if(iterated.originalIterated != null) { if(patternGraph.WasInlinedHere(iterated.originalSubpatternEmbedding)) inlinedMatchObjectName = "match_" + iterated.originalSubpatternEmbedding.Name; iteratedName = iterated.originalIterated.iteratedPattern.name; } String nestedMatchObjectName = (inlinedMatchObjectName ?? matchObjectName) + "._" + iteratedName; BubbleUpYieldIterated bubbleUpIterated = new BubbleUpYieldIterated(nestedMatchObjectName); bubbleUpIterated.NestedOperationsList = new SearchProgramList(bubbleUpIterated); SearchProgramOperation continuationPoint = insertionPoint.Append(bubbleUpIterated); insertionPoint = bubbleUpIterated.NestedOperationsList; insertYieldAssignments(insertionPoint, patternGraph, nestedMatchObjectName + ".Root", iterated.iteratedPattern); insertionPoint = continuationPoint; } } foreach(Alternative alternative in patternGraph.alternativesPlusInlined) { // in the inlined pass only the elements which were inlined into this pattern, in the non-inlined pass the original elements bool wasInlined = alternative.originalAlternative != null; if(inlined == wasInlined) { bool first = true; foreach(PatternGraph alternativeCase in alternative.alternativeCases) { // if the alternative case does not contain a non local def entity it can't yield to us if(!alternativeCase.isNonLocalDefEntityExistingPlusInlined) continue; // in inlined pass bubble up from the components of the inlined patterns to the elements resulting from of the inlined pattern // (read from submatches to local variables, compute in local variables, writing will happen later from local variables to matches) string inlinedMatchObjectName = matchObjectName; string inlinedNestedMatchObjectName = "_" + alternative.name; string inlinedPatternClassName = rulePatternClassName; string patternElementType = patternGraph.pathPrefix + patternGraph.name + "_" + alternative.name + "_" + alternativeCase.name; if(alternative.originalAlternative != null) { if(patternGraph.WasInlinedHere(alternative.originalSubpatternEmbedding)) inlinedMatchObjectName = "match_" + alternative.originalSubpatternEmbedding.name; inlinedNestedMatchObjectName = "_" + alternative.originalAlternative.name; inlinedPatternClassName = alternative.originalSubpatternEmbedding.matchingPatternOfEmbeddedGraph.GetType().Name; patternElementType = alternative.originalAlternative.pathPrefix + alternative.originalAlternative.name + "_" + alternativeCase.originalPatternGraph.name; } BubbleUpYieldAlternativeCase bubbleUpAlternativeCase = new BubbleUpYieldAlternativeCase( inlinedMatchObjectName, inlinedNestedMatchObjectName, inlinedPatternClassName + ".Match_" + patternElementType, "altCaseMatch", first); bubbleUpAlternativeCase.NestedOperationsList = new SearchProgramList(bubbleUpAlternativeCase); SearchProgramOperation continuationPoint = insertionPoint.Append(bubbleUpAlternativeCase); insertionPoint = bubbleUpAlternativeCase.NestedOperationsList; first = false; insertYieldAssignments(insertionPoint, patternGraph, "altCaseMatch", alternativeCase); insertionPoint = continuationPoint; } } } foreach(PatternGraph independent in patternGraph.independentPatternGraphsPlusInlined) { // in the inlined pass only the elements which were inlined into this pattern, in the non-inlined pass the original elements bool wasInlined = independent.originalPatternGraph != null; if(inlined == wasInlined) { // if the independent does not contain a non local def entity it can't yield to us if(!independent.isNonLocalDefEntityExistingPlusInlined) continue; // in inlined pass bubble up from the components of the inlined patterns to the elements resulting from of the inlined pattern // (read from submatches to local variables, compute in local variables, writing will happen later from local variables to matches) string inlinedMatchObjectName = null; if(independent.originalPatternGraph != null && patternGraph.WasInlinedHere(independent.originalSubpatternEmbedding)) { inlinedMatchObjectName = "match_" + independent.originalSubpatternEmbedding.Name; } String nestedMatchObjectName = NamesOfEntities.MatchedIndependentVariable(independent.pathPrefix + independent.name); ; insertionPoint = insertYieldAssignments(insertionPoint, patternGraph, inlinedMatchObjectName ?? nestedMatchObjectName, independent); } } ////////////////////////////////////////////////////// // then 2. compute all local yields PatternYielding[] patternYieldings; if(patternGraph.parallelizedSchedule != null) // in case of parallelization we've to use the parallelized yieldings patternYieldings = patternGraph.parallelizedYieldings; else patternYieldings = patternGraph.YieldingsPlusInlined; foreach(PatternYielding patternYielding in patternYieldings) { // in the inlined pass only the elements which were inlined into this pattern, in the non-inlined pass the original elements bool wasInlined = patternYielding.originalYielding != null; if(inlined == wasInlined) { YieldingBlock yieldingBlock = new YieldingBlock(patternYielding.Name); yieldingBlock.NestedOperationsList = new SearchProgramList(yieldingBlock); SearchProgramOperation continuationPointOuter = insertionPoint.Append(yieldingBlock); insertionPoint = yieldingBlock.NestedOperationsList; foreach(Yielding yielding in patternYielding.ElementaryYieldings) { // iterated potentially matching more than once can't be bubbled up normally, // they need accumulation with a for loop into a variable of the nesting pattern, // that's done in/with the yield statements of the parent if(yielding is IteratedAccumulationYield) { IteratedAccumulationYield accumulationYield = (IteratedAccumulationYield)yielding; foreach(Iterated iterated in patternGraph.iteratedsPlusInlined) { // skip the iterateds we're not interested in if(accumulationYield.Iterated != iterated.iteratedPattern.Name) continue; // in inlined pass bubble up from the components of the inlined patterns to the elements resulting from of the inlined pattern // (read from submatches to local variables, compute in local variables, writing will happen later from local variables to matches) string inlinedMatchObjectName = null; if(iterated.originalIterated != null) { inlinedMatchObjectName = "match_" + iterated.originalSubpatternEmbedding.Name; } String nestedMatchObjectName = (inlinedMatchObjectName ?? matchObjectName) + "._" + iterated.iteratedPattern.Name; AccumulateUpYieldIterated accumulateUpIterated = new AccumulateUpYieldIterated( nestedMatchObjectName, rulePatternClassName + ".Match_" + patternGraph.pathPrefix + patternGraph.name + "_" + iterated.iteratedPattern.name, "iteratedMatch"); accumulateUpIterated.NestedOperationsList = new SearchProgramList(accumulateUpIterated); SearchProgramOperation continuationPoint = insertionPoint.Append(accumulateUpIterated); insertionPoint = accumulateUpIterated.NestedOperationsList; accumulationYield.IteratedMatchVariable = "iteratedMatch._" + NamesOfEntities.Variable(accumulationYield.UnprefixedVariable); accumulationYield.ReplaceVariableByIterationVariable(accumulationYield); SourceBuilder yieldAssignmentSource = new SourceBuilder(); accumulationYield.Emit(yieldAssignmentSource); LocalYielding yieldAssignment = new LocalYielding(yieldAssignmentSource.ToString()); insertionPoint = insertionPoint.Append(yieldAssignment); insertionPoint = continuationPoint; } } else { SourceBuilder yieldAssignmentSource = new SourceBuilder(); yielding.Emit(yieldAssignmentSource); LocalYielding yieldAssignment = new LocalYielding(yieldAssignmentSource.ToString()); insertionPoint = insertionPoint.Append(yieldAssignment); } } insertionPoint = continuationPointOuter; } } ////////////////////////////////////////////////////// // 3. at the end of the inlined pass: // assign the def parameters from a subpattern which was inlined to the arguments yielded to // we can't read from the match objects of the inlined subpatterns cause they are not written yet, but from the corresponding local variables if(inlined) { foreach(PatternGraphEmbedding patternEmbedding in patternGraph.embeddedGraphsPlusInlined) { // only inlined embeddings if(!patternEmbedding.inlined) continue; for(int i = 0; i < patternEmbedding.yields.Length; ++i) { String targetName = patternEmbedding.yields[i]; String sourceName = patternEmbedding.matchingPatternOfEmbeddedGraph.defNames[i]; IPatternElement elem = getInlinedElementByOriginalUnprefixedName(patternGraph, patternEmbedding, sourceName); // find the one which was originating from inlining patternEmbedding, because of same originator bool isVariable = patternEmbedding.matchingPatternOfEmbeddedGraph.defs[i] is VarType; YieldAssignment assignment = new YieldAssignment( targetName, isVariable, patternEmbedding.matchingPatternOfEmbeddedGraph.defs[i] is VarType ? TypesHelper.TypeName(patternEmbedding.matchingPatternOfEmbeddedGraph.defs[i]) : patternEmbedding.matchingPatternOfEmbeddedGraph.defs[i].IsNodeType ? "GRGEN_LGSP.LGSPNode" : "GRGEN_LGSP.LGSPEdge", isVariable ? (Expression)new VariableExpression(elem.Name) : (Expression)new GraphEntityExpression(elem.Name) ); SourceBuilder yieldAssignmentSource = new SourceBuilder(); assignment.Emit(yieldAssignmentSource); LocalYielding yieldAssignment = new LocalYielding(yieldAssignmentSource.ToString()); insertionPoint = insertionPoint.Append(yieldAssignment); } } } return insertionPoint; }
/// <summary> /// Generates the search program for the given alternative /// </summary> SearchProgram GenerateSearchProgramAlternative(LGSPMatchingPattern matchingPattern, Alternative alt) { // build pass: build nested program from scheduled search plans of the alternative cases SearchProgramBuilder searchProgramBuilder = new SearchProgramBuilder(); SearchProgram searchProgram = searchProgramBuilder.BuildSearchProgram(model, matchingPattern, alt, false, Profile); #if DUMP_SEARCHPROGRAMS // dump built search program for debugging SourceBuilder builder = new SourceBuilder(CommentSourceCode); searchProgram.Dump(builder); StreamWriter writer = new StreamWriter(matchingPattern.name + "_" + alt.name + "_" + searchProgram.Name + "_built_dump.txt"); writer.Write(builder.ToString()); writer.Close(); #endif // complete pass: complete check operations in all search programs SearchProgramCompleter searchProgramCompleter = new SearchProgramCompleter(); searchProgramCompleter.CompleteCheckOperationsInAllSearchPrograms(searchProgram); #if DUMP_SEARCHPROGRAMS // dump completed search program for debugging builder = new SourceBuilder(CommentSourceCode); searchProgram.Dump(builder); writer = new StreamWriter(matchingPattern.name + "_" + alt.name + "_" + searchProgram.Name + "_completed_dump.txt"); writer.Write(builder.ToString()); writer.Close(); #endif return searchProgram; }
/// <summary> /// Inserts code to push the subpattern tasks to the open tasks stack /// at the given position, returns position after inserted operations /// </summary> private SearchProgramOperation insertPushSubpatternTasks(SearchProgramOperation insertionPoint) { PatternGraph patternGraph = patternGraphWithNestingPatterns.Peek(); string negativeIndependentNamePrefix = NegativeIndependentNamePrefix(patternGraph); string searchPatternpath = "false"; string matchOfNestingPattern = "null"; string lastMatchAtPreviousNestingLevel = "null"; if(patternGraph.patternGraphsOnPathToEnclosedPatternpath.Count > 0) { if(patternGraph.isPatternpathLocked) searchPatternpath = "true"; if((programType == SearchProgramType.Subpattern || programType == SearchProgramType.AlternativeCase || programType == SearchProgramType.Iterated) && patternGraphWithNestingPatterns.Count == 1) { searchPatternpath = "searchPatternpath"; } matchOfNestingPattern = NamesOfEntities.PatternpathMatch(patternGraph.pathPrefix + patternGraph.name); lastMatchAtPreviousNestingLevel = getCurrentLastMatchAtPreviousNestingLevel(); } // first alternatives, so that they get processed last // to handle subpatterns in linear order we've to push them in reverse order on the stack for (int i = patternGraph.alternativesPlusInlined.Length - 1; i >= 0; --i) { Alternative alternative = patternGraph.alternativesPlusInlined[i]; Dictionary<string, bool> neededNodes = new Dictionary<string, bool>(); Dictionary<string, bool> neededEdges = new Dictionary<string, bool>(); Dictionary<string, GrGenType> neededVariables = new Dictionary<string, GrGenType>(); foreach(PatternGraph altCase in alternative.alternativeCases) { foreach (KeyValuePair<string, bool> neededNode in altCase.neededNodes) neededNodes[neededNode.Key] = neededNode.Value; foreach (KeyValuePair<string, bool> neededEdge in altCase.neededEdges) neededEdges[neededEdge.Key] = neededEdge.Value; foreach(KeyValuePair<string, GrGenType> neededVariable in altCase.neededVariables) neededVariables[neededVariable.Key] = neededVariable.Value; } int numElements = neededNodes.Count + neededEdges.Count + neededVariables.Count; string[] connectionName = new string[numElements]; string[] argumentExpressions = new string[numElements]; int j = 0; foreach (KeyValuePair<string, bool> node in neededNodes) { connectionName[j] = node.Key; SourceBuilder argumentExpression = new SourceBuilder(); (new GraphEntityExpression(node.Key)).Emit(argumentExpression); argumentExpressions[j] = argumentExpression.ToString(); ++j; } foreach (KeyValuePair<string, bool> edge in neededEdges) { connectionName[j] = edge.Key; SourceBuilder argumentExpression = new SourceBuilder(); (new GraphEntityExpression(edge.Key)).Emit(argumentExpression); argumentExpressions[j] = argumentExpression.ToString(); ++j; } foreach(KeyValuePair<string, GrGenType> variable in neededVariables) { connectionName[j] = variable.Key; SourceBuilder argumentExpression = new SourceBuilder(); (new VariableExpression(variable.Key)).Emit(argumentExpression); argumentExpressions[j] = argumentExpression.ToString(); ++j; } string inlinedPatternClassName = rulePatternClassName; string pathPrefixInInlinedPatternClass = alternative.pathPrefix; string unprefixedNameInInlinedPatternClass = alternative.name; if(alternative.originalAlternative != null) { inlinedPatternClassName = alternative.originalSubpatternEmbedding.matchingPatternOfEmbeddedGraph.GetType().Name; pathPrefixInInlinedPatternClass = alternative.originalAlternative.pathPrefix; unprefixedNameInInlinedPatternClass = alternative.originalAlternative.name; } PushSubpatternTask pushTask = new PushSubpatternTask( PushAndPopSubpatternTaskTypes.Alternative, alternative.pathPrefix, alternative.name, inlinedPatternClassName, pathPrefixInInlinedPatternClass, unprefixedNameInInlinedPatternClass, connectionName, argumentExpressions, negativeIndependentNamePrefix, searchPatternpath, matchOfNestingPattern, lastMatchAtPreviousNestingLevel, parallelized ); insertionPoint = insertionPoint.Append(pushTask); } // then iterated patterns of the pattern // to handle iterated in linear order we've to push them in reverse order on the stack for (int i = patternGraph.iteratedsPlusInlined.Length - 1; i >= 0; --i) { PatternGraph iter = patternGraph.iteratedsPlusInlined[i].iteratedPattern; int numElements = iter.neededNodes.Count + iter.neededEdges.Count + iter.neededVariables.Count; string[] connectionName = new string[numElements]; string[] argumentExpressions = new string[numElements]; int j = 0; foreach (KeyValuePair<string, bool> node in iter.neededNodes) { connectionName[j] = node.Key; SourceBuilder argumentExpression = new SourceBuilder(); (new GraphEntityExpression(node.Key)).Emit(argumentExpression); argumentExpressions[j] = argumentExpression.ToString(); ++j; } foreach (KeyValuePair<string, bool> edge in iter.neededEdges) { connectionName[j] = edge.Key; SourceBuilder argumentExpression = new SourceBuilder(); (new GraphEntityExpression(edge.Key)).Emit(argumentExpression); argumentExpressions[j] = argumentExpression.ToString(); ++j; } foreach(KeyValuePair<string, GrGenType> variable in iter.neededVariables) { connectionName[j] = variable.Key; SourceBuilder argumentExpression = new SourceBuilder(); (new VariableExpression(variable.Key)).Emit(argumentExpression); argumentExpressions[j] = argumentExpression.ToString(); ++j; } PushSubpatternTask pushTask = new PushSubpatternTask( PushAndPopSubpatternTaskTypes.Iterated, iter.pathPrefix, iter.name, rulePatternClassName, "", "", connectionName, argumentExpressions, negativeIndependentNamePrefix, searchPatternpath, matchOfNestingPattern, lastMatchAtPreviousNestingLevel, parallelized ); insertionPoint = insertionPoint.Append(pushTask); } // and finally subpatterns of the pattern // to handle subpatterns in linear order we've to push them in reverse order on the stack for (int i = patternGraph.embeddedGraphsPlusInlined.Length - 1; i >= 0; --i) { PatternGraphEmbedding subpattern = patternGraph.embeddedGraphsPlusInlined[i]; if(subpattern.inlined) continue; Debug.Assert(subpattern.matchingPatternOfEmbeddedGraph.inputNames.Length == subpattern.connections.Length); string[] connectionName = subpattern.matchingPatternOfEmbeddedGraph.inputNames; string[] argumentExpressions = new string[subpattern.connections.Length]; for (int j = 0; j < subpattern.connections.Length; ++j) { SourceBuilder argumentExpression = new SourceBuilder(); subpattern.connections[j].Emit(argumentExpression); argumentExpressions[j] = argumentExpression.ToString(); } PushSubpatternTask pushTask = new PushSubpatternTask( PushAndPopSubpatternTaskTypes.Subpattern, subpattern.matchingPatternOfEmbeddedGraph.name, subpattern.name, connectionName, argumentExpressions, negativeIndependentNamePrefix, searchPatternpath, matchOfNestingPattern, lastMatchAtPreviousNestingLevel, parallelized ); insertionPoint = insertionPoint.Append(pushTask); } return insertionPoint; }
/// <summary> /// Generates an LGSPAction object for the given scheduled search plan. /// </summary> /// <param name="action">Needed for the rule pattern and the name</param> /// <param name="sourceOutputFilename">null if no output file needed</param> public LGSPAction GenerateAction(ScheduledSearchPlan scheduledSearchPlan, LGSPAction action, String modelAssemblyLocation, String actionAssemblyLocation, String sourceOutputFilename) { SourceBuilder sourceCode = new SourceBuilder(CommentSourceCode); GenerateFileHeaderForActionsFile(sourceCode, model.GetType().Namespace, action.rulePattern.GetType().Namespace); // can't generate new subpattern matchers due to missing scheduled search plans for them / missing graph analyze data Debug.Assert(action.rulePattern.patternGraph.embeddedGraphsPlusInlined.Length == 0); GenerateActionAndMatcher(sourceCode, action.rulePattern, false); // close namespace sourceCode.Append("}"); // write generated source to file if requested if(sourceOutputFilename != null) { StreamWriter writer = new StreamWriter(sourceOutputFilename); writer.Write(sourceCode.ToString()); writer.Close(); } // set up compiler CSharpCodeProvider compiler = new CSharpCodeProvider(); CompilerParameters compParams = GetDynCompilerSetup(modelAssemblyLocation, actionAssemblyLocation); // Stopwatch compilerWatch = Stopwatch.StartNew(); // compile generated code CompilerResults compResults = compiler.CompileAssemblyFromSource(compParams, sourceCode.ToString()); if(compResults.Errors.HasErrors) { String errorMsg = compResults.Errors.Count + " Errors:"; foreach(CompilerError error in compResults.Errors) errorMsg += Environment.NewLine + "Line: " + error.Line + " - " + error.ErrorText; throw new ArgumentException("Illegal dynamic C# source code produced for actions \"" + action.Name + "\": " + errorMsg); } // create action instance Object obj = compResults.CompiledAssembly.CreateInstance("de.unika.ipd.grGen.lgspActions.DynAction_" + action.Name); // long compSourceTicks = compilerWatch.ElapsedTicks; // Console.WriteLine("GenMatcher: Compile source: {0} us", compSourceTicks / (Stopwatch.Frequency / 1000000)); return (LGSPAction) obj; }
private static void AnalyzeAndInlineMatchingPatterns(bool inline, LGSPRuleAndMatchingPatterns ruleAndMatchingPatterns) { PatternGraphAnalyzer analyzer = new PatternGraphAnalyzer(); foreach(LGSPMatchingPattern matchingPattern in ruleAndMatchingPatterns.RulesAndSubpatterns) { analyzer.AnalyzeNestingOfPatternGraph(matchingPattern.patternGraph, false); PatternGraphAnalyzer.PrepareInline(matchingPattern.patternGraph); analyzer.RememberMatchingPattern(matchingPattern); } analyzer.ComputeInterPatternRelations(false); foreach(LGSPMatchingPattern matchingPattern in ruleAndMatchingPatterns.RulesAndSubpatterns) { // computes patternpath information, thus only in original pass analyzer.AnalyzeWithInterPatternRelationsKnown(matchingPattern.patternGraph); } if(inline) { foreach(LGSPMatchingPattern matchingPattern in ruleAndMatchingPatterns.RulesAndSubpatterns) { #if DUMP_PATTERNS // dump patterns for debugging - first original version without inlining SourceBuilder builder = new SourceBuilder(true); matchingPattern.patternGraph.DumpOriginal(builder); StreamWriter writer = new StreamWriter(matchingPattern.name + "_pattern_dump.txt"); writer.Write(builder.ToString()); #endif analyzer.InlineSubpatternUsages(matchingPattern.patternGraph); #if DUMP_PATTERNS // - then inlined version builder = new SourceBuilder(true); matchingPattern.patternGraph.DumpInlined(builder); writer.Write(builder.ToString()); writer.Close(); #endif } } // hardcore/ugly parameterization for inlined case, working on inlined members in inlined pass, and original members on original pass // working with accessors encapsulating the inlined versions and the original version behind a common interface to keep the analyze code without case distinctions gets terribly extensive foreach(LGSPMatchingPattern matchingPattern in ruleAndMatchingPatterns.RulesAndSubpatterns) matchingPattern.patternGraph.maxIsoSpace = 0; // reset of max iso space for computation of max iso space of inlined patterns foreach(LGSPMatchingPattern matchingPattern in ruleAndMatchingPatterns.RulesAndSubpatterns) { analyzer.AnalyzeNestingOfPatternGraph(matchingPattern.patternGraph, true); } analyzer.ComputeInterPatternRelations(true); }
/// <summary> /// Does action-backend dependent stuff. /// </summary> /// <param name="args">Any kind of parameters for the stuff to do; first parameter has to be the command</param> public override void Custom(params object[] args) { if (args.Length == 0) { throw new ArgumentException("No command given"); } String command = (String)args[0]; switch (command) { case "gen_searchplan": { if (graph.statistics.edgeCounts == null) { throw new ArgumentException("Graph not analyzed yet!\nPlease execute 'custom graph analyze'!"); } LGSPAction[] oldActions; if (args.Length == 1) { oldActions = new LGSPAction[actions.Count]; int i = 0; foreach (LGSPAction action in actions.Values) { oldActions[i] = action; ++i; } } else { oldActions = new LGSPAction[args.Length - 1]; for (int i = 0; i < oldActions.Length; i++) { oldActions[i] = (LGSPAction)GetAction((String)args[i + 1]); if (oldActions[i] == null) { throw new ArgumentException("'" + (String)args[i + 1] + "' is not the name of an action!\n" + "Please use 'show actions' to get a list of the available names."); } } } int startticks = Environment.TickCount; matcherGenerator.LazyNegativeIndependentConditionEvaluation = LazyNIC; matcherGenerator.InlineIndependents = InlineIndependents; matcherGenerator.Profile = Profile; LGSPAction[] newActions = matcherGenerator.GenerateActions(graph, modelAssemblyName, actionsAssemblyName, oldActions); int stopticks = Environment.TickCount; Console.Write("Searchplans for actions "); for (int i = 0; i < oldActions.Length; i++) { actions[oldActions[i].Name] = newActions[i]; if (i != 0) { Console.Write(", "); } Console.Write("'" + oldActions[i].Name + "'"); } Console.WriteLine(" generated in " + (stopticks - startticks) + " ms."); return; } case "dump_sourcecode": if (args.Length != 2) { throw new ArgumentException("Usage: dump_sourcecode <bool>\n" + "If <bool> == true, C# files will be dumped for new searchplans."); } if (!bool.TryParse((String)args[1], out matcherGenerator.DumpDynSourceCode)) { throw new ArgumentException("Illegal bool value specified: \"" + (String)args[1] + "\""); } return; case "dump_searchplan": if (args.Length != 2) { throw new ArgumentException("Usage: dump_searchplan <bool>\n" + "If <bool> == true, VCG and TXT files will be dumped for new searchplans."); } if (!bool.TryParse((String)args[1], out matcherGenerator.DumpSearchPlan)) { throw new ArgumentException("Illegal bool value specified: \"" + (String)args[1] + "\""); } return; case "explain": { if (args.Length != 2) { throw new ArgumentException("Usage: explain <name>\n" + "Explains the searchplan of the given action."); } LGSPAction action = (LGSPAction)GetAction((String)args[1]); if (action == null) { throw new ArgumentException("'" + (String)args[1] + "' is not the name of an action!\n" + "Please use 'show actions' to get a list of the available names."); } if (action.patternGraph.schedules[0] == null) { LGSPGraphStatistics graphStatistics = null; if (StatisticsPath != null) { Console.WriteLine("static search plans from " + StatisticsPath); graphStatistics = new LGSPGraphStatistics(graph.Model); GraphStatisticsParserSerializer parserSerializer = new GraphStatisticsParserSerializer(graphStatistics); parserSerializer.Parse(StatisticsPath); } else { Console.WriteLine("static search plans"); } LGSPMatcherGenerator matcherGen = new LGSPMatcherGenerator(graph.Model); matcherGen.FillInStaticSearchPlans(graphStatistics, InlineIndependents, action); } SourceBuilder sb = new SourceBuilder(); foreach (KeyValuePair <LGSPMatchingPattern, LGSPMatchingPattern> usedSubpattern in action.rulePattern.patternGraph.usedSubpatterns) { usedSubpattern.Key.patternGraph.Explain(sb, graph.Model); } action.patternGraph.Explain(sb, graph.Model); Console.WriteLine(sb.ToString()); return; } default: throw new ArgumentException("Unknown command: " + command); } }
private String WriteSourceAndExternalSource(SourceBuilder externalSource, SourceBuilder source, String actionsOutputFilename, string externalActionsExtensionOutputFilename) { String actionsOutputSource; actionsOutputSource = source.ToString(); if((flags & ProcessSpecFlags.KeepGeneratedFiles) != 0) { StreamWriter writer = new StreamWriter(actionsOutputFilename); writer.Write(actionsOutputSource); writer.Close(); } if(externalSource != null) { externalSource.Unindent(); externalSource.AppendFront("}\n"); StreamWriter writer = new StreamWriter(externalActionsExtensionOutputFilename); writer.Write(externalSource.ToString()); writer.Close(); } return actionsOutputSource; }
private static void CompileComparisonMatchers() { for (int i = GraphMatchingState.candidatesForCompilation.Count - 1; i >= 0; --i) { LGSPGraph graph = GraphMatchingState.candidatesForCompilation[i]; if (graph.matchingState.changesCounterAtInterpretationPlanBuilding != graph.ChangesCounter) { GraphMatchingState.candidatesForCompilation.RemoveAt(i); } } SourceBuilder sourceCode = new SourceBuilder(); sourceCode.AppendFront("using System;\n" + "using System.Collections.Generic;\n" + "using GRGEN_LIBGR = de.unika.ipd.grGen.libGr;\n" + "using GRGEN_LGSP = de.unika.ipd.grGen.lgsp;\n\n"); sourceCode.AppendFront("namespace de.unika.ipd.grGen.lgspComparisonMatchers\n"); sourceCode.AppendFront("{\n"); sourceCode.Indent(); foreach (LGSPGraph graph in GraphMatchingState.candidatesForCompilation) { ((InterpretationPlanStart)graph.matchingState.interpretationPlan).Emit(sourceCode); } sourceCode.Append("}"); #if DUMP_COMPILED_MATCHER using (StreamWriter sw = new StreamWriter("comparison_matcher_" + GraphMatchingState.candidatesForCompilation[0].GraphId + ".cs")) sw.Write(sourceCode.ToString()); #endif // set up compiler CSharpCodeProvider compiler = new CSharpCodeProvider(); CompilerParameters compParams = new CompilerParameters(); compParams.ReferencedAssemblies.Add("System.dll"); compParams.ReferencedAssemblies.Add(Assembly.GetAssembly(typeof(BaseGraph)).Location); compParams.ReferencedAssemblies.Add(Assembly.GetAssembly(typeof(LGSPGraph)).Location); compParams.GenerateInMemory = true; compParams.CompilerOptions = "/optimize"; // building methods with MSIL would be highly preferable, but is much harder of course CompilerResults compResults = compiler.CompileAssemblyFromSource(compParams, sourceCode.ToString()); if (compResults.Errors.HasErrors) { String errorMsg = compResults.Errors.Count + " Errors:"; foreach (CompilerError error in compResults.Errors) { errorMsg += Environment.NewLine + "Line: " + error.Line + " - " + error.ErrorText; } throw new ArgumentException("Internal error: Illegal C# source code produced for graph comparison: " + errorMsg); } // create comparison matcher instances foreach (LGSPGraph graph in GraphMatchingState.candidatesForCompilation) { graph.matchingState.compiledMatcher = (GraphComparisonMatcher)compResults.CompiledAssembly.CreateInstance( "de.unika.ipd.grGen.lgspComparisonMatchers.ComparisonMatcher_" + graph.GraphId); if (graph.matchingState.compiledMatcher == null) { throw new ArgumentException("Internal error: Generated assembly does not contain comparison matcher 'ComparisonMatcher_" + graph.GraphId + "'!"); } ++GraphMatchingState.numCompiledMatchers; } GraphMatchingState.candidatesForCompilation.Clear(); ++GraphMatchingState.numCompilationPasses; }
void EmitSequenceComputation(SequenceComputation seqComp, SourceBuilder source) { // take care that the operations returning a value are emitted similarily to expressions, // whereas the operations returning no value are emitted as statements switch(seqComp.SequenceComputationType) { case SequenceComputationType.Then: { SequenceComputationThen seqThen = (SequenceComputationThen)seqComp; EmitSequenceComputation(seqThen.left, source); EmitSequenceComputation(seqThen.right, source); source.AppendFront(SetResultVar(seqThen, GetResultVar(seqThen.right))); break; } case SequenceComputationType.Assignment: { SequenceComputationAssignment seqAssign = (SequenceComputationAssignment)seqComp; if(seqAssign.SourceValueProvider is SequenceComputationAssignment) { EmitSequenceComputation(seqAssign.SourceValueProvider, source); EmitAssignment(seqAssign.Target, GetResultVar(seqAssign.SourceValueProvider), source); source.AppendFront(SetResultVar(seqAssign, GetResultVar(seqAssign.Target))); } else { string comp = GetSequenceExpression((SequenceExpression)seqAssign.SourceValueProvider, source); EmitAssignment(seqAssign.Target, comp, source); source.AppendFront(SetResultVar(seqAssign, GetResultVar(seqAssign.Target))); } break; } case SequenceComputationType.VariableDeclaration: { SequenceComputationVariableDeclaration seqVarDecl = (SequenceComputationVariableDeclaration)seqComp; source.AppendFront(SetVar(seqVarDecl.Target, TypesHelper.DefaultValueString(seqVarDecl.Target.Type, model))); source.AppendFront(SetResultVar(seqVarDecl, GetVar(seqVarDecl.Target))); break; } case SequenceComputationType.ContainerAdd: { SequenceComputationContainerAdd seqAdd = (SequenceComputationContainerAdd)seqComp; string container = GetContainerValue(seqAdd); if(seqAdd.ContainerType(env) == "") { if(seqAdd.Attribute != null) { source.AppendFront("GRGEN_LIBGR.IGraphElement elem_" + seqAdd.Id + " = (GRGEN_LIBGR.IGraphElement)" + GetVar(seqAdd.Attribute.SourceVar) + ";\n"); source.AppendFront("GRGEN_LIBGR.AttributeType attrType_" + seqAdd.Id + " = elem_" + seqAdd.Id + ".Type.GetAttributeType(\"" + seqAdd.Attribute.AttributeName + "\");\n"); } string containerVar = "tmp_eval_once_" + seqAdd.Id; source.AppendFront("object " + containerVar + " = " + container + ";\n"); string sourceValue = "srcval_" + seqAdd.Id; source.AppendFront("object " + sourceValue + " = " + GetSequenceExpression(seqAdd.Expr, source) + ";\n"); string destinationValue = seqAdd.ExprDst == null ? null : "dstval_" + seqAdd.Id; source.AppendFront("if(" + containerVar + " is IList) {\n"); source.Indent(); if(destinationValue != null && !TypesHelper.IsSameOrSubtype(seqAdd.ExprDst.Type(env), "int", model)) source.AppendFront("throw new Exception(\"Can't add non-int key to array\");\n"); else { string array = "((System.Collections.IList)" + containerVar + ")"; if(destinationValue != null) source.AppendFront("int " + destinationValue + " = (int)" + GetSequenceExpression(seqAdd.ExprDst, source) + ";\n"); if(seqAdd.Attribute != null) { if(destinationValue != null) { source.AppendFront("if(elem_" + seqAdd.Id + " is GRGEN_LIBGR.INode)\n"); source.AppendFront("\tgraph.ChangingNodeAttribute((GRGEN_LIBGR.INode)elem_" + seqAdd.Id + ", attrType_" + seqAdd.Id + ", GRGEN_LIBGR.AttributeChangeType.PutElement, " + sourceValue + ", " + destinationValue + ");\n"); source.AppendFront("else\n"); source.AppendFront("\tgraph.ChangingEdgeAttribute((GRGEN_LIBGR.IEdge)elem_" + seqAdd.Id + ", attrType_" + seqAdd.Id + ", GRGEN_LIBGR.AttributeChangeType.PutElement, " + sourceValue + ", " + destinationValue + ");\n"); } else { source.AppendFront("if(elem_" + seqAdd.Id + " is GRGEN_LIBGR.INode)\n"); source.AppendFront("\tgraph.ChangingNodeAttribute((GRGEN_LIBGR.INode)elem_" + seqAdd.Id + ", attrType_" + seqAdd.Id + ", GRGEN_LIBGR.AttributeChangeType.PutElement, " + sourceValue + ", null);\n"); source.AppendFront("else\n"); source.AppendFront("\tgraph.ChangingEdgeAttribute((GRGEN_LIBGR.IEdge)elem_" + seqAdd.Id + ", attrType_" + seqAdd.Id + ", GRGEN_LIBGR.AttributeChangeType.PutElement, " + sourceValue + ", null);\n"); } } if(destinationValue == null) source.AppendFront(array + ".Add(" + sourceValue + ");\n"); else source.AppendFront(array + ".Insert(" + destinationValue + ", " + sourceValue + ");\n"); if(seqAdd.Attribute != null) { if(gen.FireDebugEvents) { source.AppendFront("if(elem_" + seqAdd.Id + " is GRGEN_LIBGR.INode)\n"); source.AppendFront("\tgraph.ChangedNodeAttribute((GRGEN_LIBGR.INode)elem_" + seqAdd.Id + ", attrType_" + seqAdd.Id + ");\n"); source.AppendFront("else\n"); source.AppendFront("\tgraph.ChangedEdgeAttribute((GRGEN_LIBGR.IEdge)elem_" + seqAdd.Id + ", attrType_" + seqAdd.Id + ");\n"); } } } source.Unindent(); source.AppendFront("} else if(" + containerVar + " is GRGEN_LIBGR.IDeque) {\n"); source.Indent(); if(destinationValue != null && !TypesHelper.IsSameOrSubtype(seqAdd.ExprDst.Type(env), "int", model)) source.AppendFront("throw new Exception(\"Can't add non-int key to deque\");\n"); else { string deque = "((GRGEN_LIBGR.IDeque)" + containerVar + ")"; if(destinationValue != null) source.AppendFront("int " + destinationValue + " = (int)" + GetSequenceExpression(seqAdd.ExprDst, source) + ";\n"); if(seqAdd.Attribute != null) { if(destinationValue != null) { source.AppendFront("if(elem_" + seqAdd.Id + " is GRGEN_LIBGR.INode)\n"); source.AppendFront("\tgraph.ChangingNodeAttribute((GRGEN_LIBGR.INode)elem_" + seqAdd.Id + ", attrType_" + seqAdd.Id + ", GRGEN_LIBGR.AttributeChangeType.PutElement, " + sourceValue + ", " + destinationValue + ");\n"); source.AppendFront("else\n"); source.AppendFront("\tgraph.ChangingEdgeAttribute((GRGEN_LIBGR.IEdge)elem_" + seqAdd.Id + ", attrType_" + seqAdd.Id + ", GRGEN_LIBGR.AttributeChangeType.PutElement, " + sourceValue + ", " + destinationValue + ");\n"); } else { source.AppendFront("if(elem_" + seqAdd.Id + " is GRGEN_LIBGR.INode)\n"); source.AppendFront("\tgraph.ChangingNodeAttribute((GRGEN_LIBGR.INode)elem_" + seqAdd.Id + ", attrType_" + seqAdd.Id + ", GRGEN_LIBGR.AttributeChangeType.PutElement, " + sourceValue + ", null);\n"); source.AppendFront("else\n"); source.AppendFront("\tgraph.ChangingEdgeAttribute((GRGEN_LIBGR.IEdge)elem_" + seqAdd.Id + ", attrType_" + seqAdd.Id + ", GRGEN_LIBGR.AttributeChangeType.PutElement, " + sourceValue + ", null);\n"); } } if(destinationValue == null) source.AppendFront(deque + ".Enqueue(" + sourceValue + ");\n"); else source.AppendFront(deque + ".EnqueueAt(" + destinationValue + ", " + sourceValue + ");\n"); if(seqAdd.Attribute != null) { if(gen.FireDebugEvents) { source.AppendFront("if(elem_" + seqAdd.Id + " is GRGEN_LIBGR.INode)\n"); source.AppendFront("\tgraph.ChangedNodeAttribute((GRGEN_LIBGR.INode)elem_" + seqAdd.Id + ", attrType_" + seqAdd.Id + ");\n"); source.AppendFront("else\n"); source.AppendFront("\tgraph.ChangedEdgeAttribute((GRGEN_LIBGR.IEdge)elem_" + seqAdd.Id + ", attrType_" + seqAdd.Id + ");\n"); } } } source.Unindent(); source.AppendFront("} else {\n"); source.Indent(); if(destinationValue != null) source.AppendFront("object " + destinationValue + " = " + GetSequenceExpression(seqAdd.ExprDst, source) + ";\n"); string dictionary = "((System.Collections.IDictionary)" + containerVar + ")"; if(seqAdd.Attribute != null) { if(seqAdd.ExprDst != null) // must be map { source.AppendFront("if(elem_" + seqAdd.Id + " is GRGEN_LIBGR.INode)\n"); source.AppendFront("\tgraph.ChangingNodeAttribute((GRGEN_LIBGR.INode)elem_" + seqAdd.Id + ", attrType_" + seqAdd.Id + ", GRGEN_LIBGR.AttributeChangeType.PutElement, " + destinationValue + ", " + sourceValue + ");\n"); source.AppendFront("else\n"); source.AppendFront("\tgraph.ChangingEdgeAttribute((GRGEN_LIBGR.IEdge)elem_" + seqAdd.Id + ", attrType_" + seqAdd.Id + ", GRGEN_LIBGR.AttributeChangeType.PutElement, " + destinationValue + ", " + sourceValue + ");\n"); } else { source.AppendFront("if(elem_" + seqAdd.Id + " is GRGEN_LIBGR.INode)\n"); source.AppendFront("\tgraph.ChangingNodeAttribute((GRGEN_LIBGR.INode)elem_" + seqAdd.Id + ", attrType_" + seqAdd.Id + ", GRGEN_LIBGR.AttributeChangeType.PutElement, " + sourceValue + ", " + destinationValue + ");\n"); source.AppendFront("else\n"); source.AppendFront("\tgraph.ChangingEdgeAttribute((GRGEN_LIBGR.IEdge)elem_" + seqAdd.Id + ", attrType_" + seqAdd.Id + ", GRGEN_LIBGR.AttributeChangeType.PutElement, " + sourceValue + ", " + destinationValue + ");\n"); } } if(destinationValue == null) source.AppendFront(dictionary + "[" + sourceValue + "] = null;\n"); else source.AppendFront(dictionary + "[" + sourceValue + "] = " + destinationValue + ";\n"); if(seqAdd.Attribute != null) { if(gen.FireDebugEvents) { source.AppendFront("if(elem_" + seqAdd.Id + " is GRGEN_LIBGR.INode)\n"); source.AppendFront("\tgraph.ChangedNodeAttribute((GRGEN_LIBGR.INode)elem_" + seqAdd.Id + ", attrType_" + seqAdd.Id + ");\n"); source.AppendFront("else\n"); source.AppendFront("\tgraph.ChangedEdgeAttribute((GRGEN_LIBGR.IEdge)elem_" + seqAdd.Id + ", attrType_" + seqAdd.Id + ");\n"); } } source.Unindent(); source.AppendFront("}\n"); source.AppendFront(SetResultVar(seqAdd, containerVar)); } else if(seqAdd.ContainerType(env).StartsWith("array")) { string array = container; string arrayValueType = TypesHelper.XgrsTypeToCSharpType(TypesHelper.ExtractSrc(seqAdd.ContainerType(env)), model); string sourceValue = "srcval_" + seqAdd.Id; source.AppendFront(arrayValueType + " " + sourceValue + " = (" + arrayValueType + ")" + GetSequenceExpression(seqAdd.Expr, source) + ";\n"); string destinationValue = seqAdd.ExprDst == null ? null : "dstval_" + seqAdd.Id; if(destinationValue != null) source.AppendFront("int " + destinationValue + " = (int)" + GetSequenceExpression(seqAdd.ExprDst, source) + ";\n"); if(seqAdd.Attribute != null) { source.AppendFront("GRGEN_LIBGR.IGraphElement elem_" + seqAdd.Id + " = (GRGEN_LIBGR.IGraphElement)" + GetVar(seqAdd.Attribute.SourceVar) + ";\n"); source.AppendFront("GRGEN_LIBGR.AttributeType attrType_" + seqAdd.Id + " = elem_" + seqAdd.Id + ".Type.GetAttributeType(\"" + seqAdd.Attribute.AttributeName + "\");\n"); if(destinationValue != null) { source.AppendFront("if(elem_" + seqAdd.Id + " is GRGEN_LIBGR.INode)\n"); source.AppendFront("\tgraph.ChangingNodeAttribute((GRGEN_LIBGR.INode)elem_" + seqAdd.Id + ", attrType_" + seqAdd.Id + ", GRGEN_LIBGR.AttributeChangeType.PutElement, " + sourceValue + ", " + destinationValue + ");\n"); source.AppendFront("else\n"); source.AppendFront("\tgraph.ChangingEdgeAttribute((GRGEN_LIBGR.IEdge)elem_" + seqAdd.Id + ", attrType_" + seqAdd.Id + ", GRGEN_LIBGR.AttributeChangeType.PutElement, " + sourceValue + ", " + destinationValue + ");\n"); } else { source.AppendFront("if(elem_" + seqAdd.Id + " is GRGEN_LIBGR.INode)\n"); source.AppendFront("\tgraph.ChangingNodeAttribute((GRGEN_LIBGR.INode)elem_" + seqAdd.Id + ", attrType_" + seqAdd.Id + ", GRGEN_LIBGR.AttributeChangeType.PutElement, " + sourceValue + ", null);\n"); source.AppendFront("else\n"); source.AppendFront("\tgraph.ChangingEdgeAttribute((GRGEN_LIBGR.IEdge)elem_" + seqAdd.Id + ", attrType_" + seqAdd.Id + ", GRGEN_LIBGR.AttributeChangeType.PutElement, " + sourceValue + ", null);\n"); } } if(destinationValue == null) source.AppendFront(array + ".Add(" + sourceValue + ");\n"); else source.AppendFront(array + ".Insert(" + destinationValue + ", " + sourceValue + ");\n"); if(seqAdd.Attribute != null) { if(gen.FireDebugEvents) { source.AppendFront("if(elem_" + seqAdd.Id + " is GRGEN_LIBGR.INode)\n"); source.AppendFront("\tgraph.ChangedNodeAttribute((GRGEN_LIBGR.INode)elem_" + seqAdd.Id + ", attrType_" + seqAdd.Id + ");\n"); source.AppendFront("else\n"); source.AppendFront("\tgraph.ChangedEdgeAttribute((GRGEN_LIBGR.IEdge)elem_" + seqAdd.Id + ", attrType_" + seqAdd.Id + ");\n"); } } source.AppendFront(SetResultVar(seqAdd, container)); } else if(seqAdd.ContainerType(env).StartsWith("deque")) { string deque = container; string dequeValueType = TypesHelper.XgrsTypeToCSharpType(TypesHelper.ExtractSrc(seqAdd.ContainerType(env)), model); string sourceValue = "srcval_" + seqAdd.Id; source.AppendFront(dequeValueType + " " + sourceValue + " = (" + dequeValueType + ")" + GetSequenceExpression(seqAdd.Expr, source) + ";\n"); string destinationValue = seqAdd.ExprDst == null ? null : "dstval_" + seqAdd.Id; if(destinationValue != null) source.AppendFront("int " + destinationValue + " = (int)" + GetSequenceExpression(seqAdd.ExprDst, source) + ";\n"); if(seqAdd.Attribute != null) { source.AppendFront("GRGEN_LIBGR.IGraphElement elem_" + seqAdd.Id + " = (GRGEN_LIBGR.IGraphElement)" + GetVar(seqAdd.Attribute.SourceVar) + ";\n"); source.AppendFront("GRGEN_LIBGR.AttributeType attrType_" + seqAdd.Id + " = elem_" + seqAdd.Id + ".Type.GetAttributeType(\"" + seqAdd.Attribute.AttributeName + "\");\n"); if(destinationValue != null) { source.AppendFront("if(elem_" + seqAdd.Id + " is GRGEN_LIBGR.INode)\n"); source.AppendFront("\tgraph.ChangingNodeAttribute((GRGEN_LIBGR.INode)elem_" + seqAdd.Id + ", attrType_" + seqAdd.Id + ", GRGEN_LIBGR.AttributeChangeType.PutElement, " + sourceValue + ", " + destinationValue + ");\n"); source.AppendFront("else\n"); source.AppendFront("\tgraph.ChangingEdgeAttribute((GRGEN_LIBGR.IEdge)elem_" + seqAdd.Id + ", attrType_" + seqAdd.Id + ", GRGEN_LIBGR.AttributeChangeType.PutElement, " + sourceValue + ", " + destinationValue + ");\n"); } else { source.AppendFront("if(elem_" + seqAdd.Id + " is GRGEN_LIBGR.INode)\n"); source.AppendFront("\tgraph.ChangingNodeAttribute((GRGEN_LIBGR.INode)elem_" + seqAdd.Id + ", attrType_" + seqAdd.Id + ", GRGEN_LIBGR.AttributeChangeType.PutElement, " + sourceValue + ", null);\n"); source.AppendFront("else\n"); source.AppendFront("\tgraph.ChangingEdgeAttribute((GRGEN_LIBGR.IEdge)elem_" + seqAdd.Id + ", attrType_" + seqAdd.Id + ", GRGEN_LIBGR.AttributeChangeType.PutElement, " + sourceValue + ", null);\n"); } } if(destinationValue == null) source.AppendFront(deque + ".Enqueue(" + sourceValue + ");\n"); else source.AppendFront(deque + ".EnqueueAt(" + destinationValue + ", " + sourceValue + ");\n"); if(seqAdd.Attribute != null) { if(gen.FireDebugEvents) { source.AppendFront("if(elem_" + seqAdd.Id + " is GRGEN_LIBGR.INode)\n"); source.AppendFront("\tgraph.ChangedNodeAttribute((GRGEN_LIBGR.INode)elem_" + seqAdd.Id + ", attrType_" + seqAdd.Id + ");\n"); source.AppendFront("else\n"); source.AppendFront("\tgraph.ChangedEdgeAttribute((GRGEN_LIBGR.IEdge)elem_" + seqAdd.Id + ", attrType_" + seqAdd.Id + ");\n"); } } source.AppendFront(SetResultVar(seqAdd, container)); } else { string dictionary = container; string dictSrcType = TypesHelper.XgrsTypeToCSharpType(TypesHelper.ExtractSrc(seqAdd.ContainerType(env)), model); string sourceValue = " srcval_" + seqAdd.Id; source.AppendFront(dictSrcType + " " + sourceValue + " = (" + dictSrcType + ")" + GetSequenceExpression(seqAdd.Expr, source) + ";\n"); string dictDstType = TypesHelper.XgrsTypeToCSharpType(TypesHelper.ExtractDst(seqAdd.ContainerType(env)), model); string destinationValue = seqAdd.ExprDst == null ? null : "dstval_" + seqAdd.Id; if(destinationValue != null) source.AppendFront(dictDstType + " " + destinationValue + " = (" + dictDstType + ")" + GetSequenceExpression(seqAdd.ExprDst, source) + ";\n"); if(seqAdd.Attribute != null) { source.AppendFront("GRGEN_LIBGR.IGraphElement elem_" + seqAdd.Id + " = (GRGEN_LIBGR.IGraphElement)" + GetVar(seqAdd.Attribute.SourceVar) + ";\n"); source.AppendFront("GRGEN_LIBGR.AttributeType attrType_" + seqAdd.Id + " = elem_" + seqAdd.Id + ".Type.GetAttributeType(\"" + seqAdd.Attribute.AttributeName + "\");\n"); if(destinationValue != null) // must be map { source.AppendFront("if(elem_" + seqAdd.Id + " is GRGEN_LIBGR.INode)\n"); source.AppendFront("\tgraph.ChangingNodeAttribute((GRGEN_LIBGR.INode)elem_" + seqAdd.Id + ", attrType_" + seqAdd.Id + ", GRGEN_LIBGR.AttributeChangeType.PutElement, " + destinationValue + ", " + sourceValue + ");\n"); source.AppendFront("else\n"); source.AppendFront("\tgraph.ChangingEdgeAttribute((GRGEN_LIBGR.IEdge)elem_" + seqAdd.Id + ", attrType_" + seqAdd.Id + ", GRGEN_LIBGR.AttributeChangeType.PutElement, " + destinationValue + ", " + sourceValue + ");\n"); } else { source.AppendFront("if(elem_" + seqAdd.Id + " is GRGEN_LIBGR.INode)\n"); source.AppendFront("\tgraph.ChangingNodeAttribute((GRGEN_LIBGR.INode)elem_" + seqAdd.Id + ", attrType_" + seqAdd.Id + ", GRGEN_LIBGR.AttributeChangeType.PutElement, " + sourceValue + ", null);\n"); source.AppendFront("else\n"); source.AppendFront("\tgraph.ChangingEdgeAttribute((GRGEN_LIBGR.IEdge)elem_" + seqAdd.Id + ", attrType_" + seqAdd.Id + ", GRGEN_LIBGR.AttributeChangeType.PutElement, " + sourceValue + ", null);\n"); } } if(destinationValue == null) source.AppendFront(dictionary + "[" + sourceValue + "] = null;\n"); else source.AppendFront(dictionary + "[" + sourceValue + "] = " + destinationValue + ";\n"); if(seqAdd.Attribute != null) { if(gen.FireDebugEvents) { source.AppendFront("if(elem_" + seqAdd.Id + " is GRGEN_LIBGR.INode)\n"); source.AppendFront("\tgraph.ChangedNodeAttribute((GRGEN_LIBGR.INode)elem_" + seqAdd.Id + ", attrType_" + seqAdd.Id + ");\n"); source.AppendFront("else\n"); source.AppendFront("\tgraph.ChangedEdgeAttribute((GRGEN_LIBGR.IEdge)elem_" + seqAdd.Id + ", attrType_" + seqAdd.Id + ");\n"); } } source.AppendFront(SetResultVar(seqAdd, container)); } break; } case SequenceComputationType.ContainerRem: { SequenceComputationContainerRem seqDel = (SequenceComputationContainerRem)seqComp; string container = GetContainerValue(seqDel); if(seqDel.ContainerType(env) == "") { if(seqDel.Attribute != null) { source.AppendFront("GRGEN_LIBGR.IGraphElement elem_" + seqDel.Id + " = (GRGEN_LIBGR.IGraphElement)" + GetVar(seqDel.Attribute.SourceVar) + ";\n"); source.AppendFront("GRGEN_LIBGR.AttributeType attrType_" + seqDel.Id + " = elem_" + seqDel.Id + ".Type.GetAttributeType(\"" + seqDel.Attribute.AttributeName + "\");\n"); } string containerVar = "tmp_eval_once_" + seqDel.Id; source.AppendFront("object " + containerVar + " = " + container + ";\n"); string sourceValue = seqDel.Expr == null ? null : "srcval_" + seqDel.Id; source.AppendFront("if(" + containerVar + " is IList) {\n"); source.Indent(); if(sourceValue != null && !TypesHelper.IsSameOrSubtype(seqDel.Expr.Type(env), "int", model)) source.AppendFront("throw new Exception(\"Can't remove non-int index from array\");\n"); else { string array = "((System.Collections.IList)" + containerVar + ")"; if(sourceValue != null) source.AppendFront("int " + sourceValue + " = (int)" + GetSequenceExpression(seqDel.Expr, source) + ";\n"); if(seqDel.Attribute != null) { if(sourceValue != null) { source.AppendFront("if(elem_" + seqDel.Id + " is GRGEN_LIBGR.INode)\n"); source.AppendFront("\tgraph.ChangingNodeAttribute((GRGEN_LIBGR.INode)elem_" + seqDel.Id + ", attrType_" + seqDel.Id + ", GRGEN_LIBGR.AttributeChangeType.RemoveElement, null, " + sourceValue + ");\n"); source.AppendFront("else\n"); source.AppendFront("\tgraph.ChangingEdgeAttribute((GRGEN_LIBGR.IEdge)elem_" + seqDel.Id + ", attrType_" + seqDel.Id + ", GRGEN_LIBGR.AttributeChangeType.RemoveElement, null, " + sourceValue + ");\n"); } else { source.AppendFront("if(elem_" + seqDel.Id + " is GRGEN_LIBGR.INode)\n"); source.AppendFront("\tgraph.ChangingNodeAttribute((GRGEN_LIBGR.INode)elem_" + seqDel.Id + ", attrType_" + seqDel.Id + ", GRGEN_LIBGR.AttributeChangeType.RemoveElement, null, null);\n"); source.AppendFront("else\n"); source.AppendFront("\tgraph.ChangingEdgeAttribute((GRGEN_LIBGR.IEdge)elem_" + seqDel.Id + ", attrType_" + seqDel.Id + ", GRGEN_LIBGR.AttributeChangeType.RemoveElement, null, null);\n"); } } if(sourceValue == null) source.AppendFront(array + ".RemoveAt(" + array + ".Count - 1);\n"); else source.AppendFront(array + ".RemoveAt(" + sourceValue + ");\n"); if(seqDel.Attribute != null) { if(gen.FireDebugEvents) { source.AppendFront("if(elem_" + seqDel.Id + " is GRGEN_LIBGR.INode)\n"); source.AppendFront("\tgraph.ChangedNodeAttribute((GRGEN_LIBGR.INode)elem_" + seqDel.Id + ", attrType_" + seqDel.Id + ");\n"); source.AppendFront("else\n"); source.AppendFront("\tgraph.ChangedEdgeAttribute((GRGEN_LIBGR.IEdge)elem_" + seqDel.Id + ", attrType_" + seqDel.Id + ");\n"); } } } source.Unindent(); source.AppendFront("} else if(" + containerVar + " is GRGEN_LIBGR.IDeque) {\n"); source.Indent(); if(sourceValue != null && !TypesHelper.IsSameOrSubtype(seqDel.Expr.Type(env), "int", model)) source.AppendFront("throw new Exception(\"Can't remove non-int index from deque\");\n"); else { string deque = "((GRGEN_LIBGR.IDeque)" + containerVar + ")"; if(sourceValue != null) source.AppendFront("int " + sourceValue + " = (int)" + GetSequenceExpression(seqDel.Expr, source) + ";\n"); if(seqDel.Attribute != null) { if(sourceValue != null) { source.AppendFront("if(elem_" + seqDel.Id + " is GRGEN_LIBGR.INode)\n"); source.AppendFront("\tgraph.ChangingNodeAttribute((GRGEN_LIBGR.INode)elem_" + seqDel.Id + ", attrType_" + seqDel.Id + ", GRGEN_LIBGR.AttributeChangeType.RemoveElement, null, " + sourceValue + ");\n"); source.AppendFront("else\n"); source.AppendFront("\tgraph.ChangingEdgeAttribute((GRGEN_LIBGR.IEdge)elem_" + seqDel.Id + ", attrType_" + seqDel.Id + ", GRGEN_LIBGR.AttributeChangeType.RemoveElement, null, " + sourceValue + ");\n"); } else { source.AppendFront("if(elem_" + seqDel.Id + " is GRGEN_LIBGR.INode)\n"); source.AppendFront("\tgraph.ChangingNodeAttribute((GRGEN_LIBGR.INode)elem_" + seqDel.Id + ", attrType_" + seqDel.Id + ", GRGEN_LIBGR.AttributeChangeType.RemoveElement, null, null);\n"); source.AppendFront("else\n"); source.AppendFront("\tgraph.ChangingEdgeAttribute((GRGEN_LIBGR.IEdge)elem_" + seqDel.Id + ", attrType_" + seqDel.Id + ", GRGEN_LIBGR.AttributeChangeType.RemoveElement, null, null);\n"); } } if(sourceValue == null) source.AppendFront(deque + ".Dequeue();\n"); else source.AppendFront(deque + ".DequeueAt(" + sourceValue + ");\n"); if(seqDel.Attribute != null) { if(gen.FireDebugEvents) { source.AppendFront("if(elem_" + seqDel.Id + " is GRGEN_LIBGR.INode)\n"); source.AppendFront("\tgraph.ChangedNodeAttribute((GRGEN_LIBGR.INode)elem_" + seqDel.Id + ", attrType_" + seqDel.Id + ");\n"); source.AppendFront("else\n"); source.AppendFront("\tgraph.ChangedEdgeAttribute((GRGEN_LIBGR.IEdge)elem_" + seqDel.Id + ", attrType_" + seqDel.Id + ");\n"); } } } source.Unindent(); source.AppendFront("} else {\n"); source.Indent(); string dictionary = "((System.Collections.IDictionary)" + containerVar + ")"; if(sourceValue != null) source.AppendFront("object " + sourceValue + " = " + GetSequenceExpression(seqDel.Expr, source) + ";\n"); if(seqDel.Attribute != null) { source.AppendFront("if(GRGEN_LIBGR.TypesHelper.ExtractDst(GRGEN_LIBGR.TypesHelper.AttributeTypeToXgrsType(attrType_" + seqDel.Id + ")) == \"SetValueType\")\n"); source.AppendFront("{\n"); source.Indent(); source.AppendFront("if(elem_" + seqDel.Id + " is GRGEN_LIBGR.INode)\n"); source.AppendFront("\tgraph.ChangingNodeAttribute((GRGEN_LIBGR.INode)elem_" + seqDel.Id + ", attrType_" + seqDel.Id + ", GRGEN_LIBGR.AttributeChangeType.RemoveElement, " + sourceValue + ", null);\n"); source.AppendFront("else\n"); source.AppendFront("\tgraph.ChangingEdgeAttribute((GRGEN_LIBGR.IEdge)elem_" + seqDel.Id + ", attrType_" + seqDel.Id + ", GRGEN_LIBGR.AttributeChangeType.RemoveElement, " + sourceValue + ", null);\n"); source.Unindent(); source.AppendFront("}\n"); source.AppendFront("else\n"); source.AppendFront("{\n"); source.Indent(); source.AppendFront("if(elem_" + seqDel.Id + " is GRGEN_LIBGR.INode)\n"); source.AppendFront("\tgraph.ChangingNodeAttribute((GRGEN_LIBGR.INode)elem_" + seqDel.Id + ", attrType_" + seqDel.Id + ", GRGEN_LIBGR.AttributeChangeType.RemoveElement, null, " + sourceValue + ");\n"); source.AppendFront("else\n"); source.AppendFront("\tgraph.ChangingEdgeAttribute((GRGEN_LIBGR.IEdge)elem_" + seqDel.Id + ", attrType_" + seqDel.Id + ", GRGEN_LIBGR.AttributeChangeType.RemoveElement, null, " + sourceValue + ");\n"); source.Unindent(); source.AppendFront("}\n"); } if(sourceValue == null) source.AppendFront("throw new Exception(\""+seqDel.Container.PureName+".rem() only possible on array or deque!\");\n"); else source.AppendFront(dictionary + ".Remove(" + sourceValue + ");\n"); if(seqDel.Attribute != null) { if(gen.FireDebugEvents) { source.AppendFront("if(elem_" + seqDel.Id + " is GRGEN_LIBGR.INode)\n"); source.AppendFront("\tgraph.ChangedNodeAttribute((GRGEN_LIBGR.INode)elem_" + seqDel.Id + ", attrType_" + seqDel.Id + ");\n"); source.AppendFront("else\n"); source.AppendFront("\tgraph.ChangedEdgeAttribute((GRGEN_LIBGR.IEdge)elem_" + seqDel.Id + ", attrType_" + seqDel.Id + ");\n"); } } source.Unindent(); source.AppendFront("}\n"); source.AppendFront(SetResultVar(seqDel, containerVar)); } else if(seqDel.ContainerType(env).StartsWith("array")) { string array = container; string sourceValue = seqDel.Expr == null ? null : "srcval_" + seqDel.Id; if(sourceValue != null) source.AppendFront("int " + sourceValue + " = (int)" + GetSequenceExpression(seqDel.Expr, source) + ";\n"); if(seqDel.Attribute != null) { source.AppendFront("GRGEN_LIBGR.IGraphElement elem_" + seqDel.Id + " = (GRGEN_LIBGR.IGraphElement)" + GetVar(seqDel.Attribute.SourceVar) + ";\n"); source.AppendFront("GRGEN_LIBGR.AttributeType attrType_" + seqDel.Id + " = elem_" + seqDel.Id + ".Type.GetAttributeType(\"" + seqDel.Attribute.AttributeName + "\");\n"); if(sourceValue != null) { source.AppendFront("if(elem_" + seqDel.Id + " is GRGEN_LIBGR.INode)\n"); source.AppendFront("\tgraph.ChangingNodeAttribute((GRGEN_LIBGR.INode)elem_" + seqDel.Id + ", attrType_" + seqDel.Id + ", GRGEN_LIBGR.AttributeChangeType.RemoveElement, null, " + sourceValue + ");\n"); source.AppendFront("else\n"); source.AppendFront("\tgraph.ChangingEdgeAttribute((GRGEN_LIBGR.IEdge)elem_" + seqDel.Id + ", attrType_" + seqDel.Id + ", GRGEN_LIBGR.AttributeChangeType.RemoveElement, null, " + sourceValue + ");\n"); } else { source.AppendFront("if(elem_" + seqDel.Id + " is GRGEN_LIBGR.INode)\n"); source.AppendFront("\tgraph.ChangingNodeAttribute((GRGEN_LIBGR.INode)elem_" + seqDel.Id + ", attrType_" + seqDel.Id + ", GRGEN_LIBGR.AttributeChangeType.RemoveElement, null, null);\n"); source.AppendFront("else\n"); source.AppendFront("\tgraph.ChangingEdgeAttribute((GRGEN_LIBGR.IEdge)elem_" + seqDel.Id + ", attrType_" + seqDel.Id + ", GRGEN_LIBGR.AttributeChangeType.RemoveElement, null, null);\n"); } } if(sourceValue == null) source.AppendFront(array + ".RemoveAt(" + array + ".Count - 1);\n"); else source.AppendFront(array + ".RemoveAt(" + sourceValue + ");\n"); if(seqDel.Attribute != null) { if(gen.FireDebugEvents) { source.AppendFront("if(elem_" + seqDel.Id + " is GRGEN_LIBGR.INode)\n"); source.AppendFront("\tgraph.ChangedNodeAttribute((GRGEN_LIBGR.INode)elem_" + seqDel.Id + ", attrType_" + seqDel.Id + ");\n"); source.AppendFront("else\n"); source.AppendFront("\tgraph.ChangedEdgeAttribute((GRGEN_LIBGR.IEdge)elem_" + seqDel.Id + ", attrType_" + seqDel.Id + ");\n"); } } source.AppendFront(SetResultVar(seqDel, container)); } else if(seqDel.ContainerType(env).StartsWith("deque")) { string deque = container; string sourceValue = seqDel.Expr == null ? null : "srcval_" + seqDel.Id; if(sourceValue != null) source.AppendFront("int " + sourceValue + " = (int)" + GetSequenceExpression(seqDel.Expr, source) + ";\n"); if(seqDel.Attribute != null) { source.AppendFront("GRGEN_LIBGR.IGraphElement elem_" + seqDel.Id + " = (GRGEN_LIBGR.IGraphElement)" + GetVar(seqDel.Attribute.SourceVar) + ";\n"); source.AppendFront("GRGEN_LIBGR.AttributeType attrType_" + seqDel.Id + " = elem_" + seqDel.Id + ".Type.GetAttributeType(\"" + seqDel.Attribute.AttributeName + "\");\n"); if(sourceValue != null) { source.AppendFront("if(elem_" + seqDel.Id + " is GRGEN_LIBGR.INode)\n"); source.AppendFront("\tgraph.ChangingNodeAttribute((GRGEN_LIBGR.INode)elem_" + seqDel.Id + ", attrType_" + seqDel.Id + ", GRGEN_LIBGR.AttributeChangeType.RemoveElement, null, " + sourceValue + ");\n"); source.AppendFront("else\n"); source.AppendFront("\tgraph.ChangingEdgeAttribute((GRGEN_LIBGR.IEdge)elem_" + seqDel.Id + ", attrType_" + seqDel.Id + ", GRGEN_LIBGR.AttributeChangeType.RemoveElement, null, " + sourceValue + ");\n"); } else { source.AppendFront("if(elem_" + seqDel.Id + " is GRGEN_LIBGR.INode)\n"); source.AppendFront("\tgraph.ChangingNodeAttribute((GRGEN_LIBGR.INode)elem_" + seqDel.Id + ", attrType_" + seqDel.Id + ", GRGEN_LIBGR.AttributeChangeType.RemoveElement, null, null);\n"); source.AppendFront("else\n"); source.AppendFront("\tgraph.ChangingEdgeAttribute((GRGEN_LIBGR.IEdge)elem_" + seqDel.Id + ", attrType_" + seqDel.Id + ", GRGEN_LIBGR.AttributeChangeType.RemoveElement, null, null);\n"); } } if(sourceValue == null) source.AppendFront(deque + ".Dequeue();\n"); else source.AppendFront(deque + ".DequeueAt(" + sourceValue + ");\n"); if(seqDel.Attribute != null) { if(gen.FireDebugEvents) { source.AppendFront("if(elem_" + seqDel.Id + " is GRGEN_LIBGR.INode)\n"); source.AppendFront("\tgraph.ChangedNodeAttribute((GRGEN_LIBGR.INode)elem_" + seqDel.Id + ", attrType_" + seqDel.Id + ");\n"); source.AppendFront("else\n"); source.AppendFront("\tgraph.ChangedEdgeAttribute((GRGEN_LIBGR.IEdge)elem_" + seqDel.Id + ", attrType_" + seqDel.Id + ");\n"); } } source.AppendFront(SetResultVar(seqDel, container)); } else { string dictionary = container; string dictSrcType = TypesHelper.XgrsTypeToCSharpType(TypesHelper.ExtractSrc(seqDel.ContainerType(env)), model); string sourceValue = "srcval_" + seqDel.Id; source.AppendFront(dictSrcType + " " + sourceValue + " = (" + dictSrcType + ")" + GetSequenceExpression(seqDel.Expr, source) + ";\n"); if(seqDel.Attribute != null) { source.AppendFront("GRGEN_LIBGR.IGraphElement elem_" + seqDel.Id + " = (GRGEN_LIBGR.IGraphElement)" + GetVar(seqDel.Attribute.SourceVar) + ";\n"); source.AppendFront("GRGEN_LIBGR.AttributeType attrType_" + seqDel.Id + " = elem_" + seqDel.Id + ".Type.GetAttributeType(\"" + seqDel.Attribute.AttributeName + "\");\n"); if(TypesHelper.ExtractDst(seqDel.ContainerType(env)) == "SetValueType") { source.AppendFront("if(elem_" + seqDel.Id + " is GRGEN_LIBGR.INode)\n"); source.AppendFront("\tgraph.ChangingNodeAttribute((GRGEN_LIBGR.INode)elem_" + seqDel.Id + ", attrType_" + seqDel.Id + ", GRGEN_LIBGR.AttributeChangeType.RemoveElement, " + sourceValue + ", null);\n"); source.AppendFront("else\n"); source.AppendFront("\tgraph.ChangingEdgeAttribute((GRGEN_LIBGR.IEdge)elem_" + seqDel.Id + ", attrType_" + seqDel.Id + ", GRGEN_LIBGR.AttributeChangeType.RemoveElement, " + sourceValue + ", null);\n"); } else { source.AppendFront("if(elem_" + seqDel.Id + " is GRGEN_LIBGR.INode)\n"); source.AppendFront("\tgraph.ChangingNodeAttribute((GRGEN_LIBGR.INode)elem_" + seqDel.Id + ", attrType_" + seqDel.Id + ", GRGEN_LIBGR.AttributeChangeType.RemoveElement, null, " + sourceValue + ");\n"); source.AppendFront("else\n"); source.AppendFront("\tgraph.ChangingEdgeAttribute((GRGEN_LIBGR.IEdge)elem_" + seqDel.Id + ", attrType_" + seqDel.Id + ", GRGEN_LIBGR.AttributeChangeType.RemoveElement, null, " + sourceValue + ");\n"); } } source.AppendFront(dictionary + ".Remove(" + sourceValue + ");\n"); if(seqDel.Attribute != null) { if(gen.FireDebugEvents) { source.AppendFront("if(elem_" + seqDel.Id + " is GRGEN_LIBGR.INode)\n"); source.AppendFront("\tgraph.ChangedNodeAttribute((GRGEN_LIBGR.INode)elem_" + seqDel.Id + ", attrType_" + seqDel.Id + ");\n"); source.AppendFront("else\n"); source.AppendFront("\tgraph.ChangedEdgeAttribute((GRGEN_LIBGR.IEdge)elem_" + seqDel.Id + ", attrType_" + seqDel.Id + ");\n"); } } source.AppendFront(SetResultVar(seqDel, container)); } break; } case SequenceComputationType.ContainerClear: { SequenceComputationContainerClear seqClear = (SequenceComputationContainerClear)seqComp; string container = GetContainerValue(seqClear); if(seqClear.ContainerType(env) == "") { if(seqClear.Attribute != null) { source.AppendFront("GRGEN_LIBGR.IGraphElement elem_" + seqClear.Id + " = (GRGEN_LIBGR.IGraphElement)" + GetVar(seqClear.Attribute.SourceVar) + ";\n"); source.AppendFront("GRGEN_LIBGR.AttributeType attrType_" + seqClear.Id + " = elem_" + seqClear.Id + ".Type.GetAttributeType(\"" + seqClear.Attribute.AttributeName + "\");\n"); } string containerVar = "tmp_eval_once_" + seqClear.Id; source.AppendFront("object " + containerVar + " = " + container + ";\n"); source.AppendFront("if(" + containerVar + " is IList) {\n"); source.Indent(); string array = "((System.Collections.IList)" + containerVar + ")"; if(seqClear.Attribute != null) { source.AppendFront("for(int i_" + seqClear.Id + " = " + array + ".Count; i_" + seqClear.Id + " >= 0; --i_" + seqClear.Id + ")\n"); source.AppendFront("\tif(elem_" + seqClear.Id + " is GRGEN_LIBGR.INode)\n"); source.AppendFront("\t\tgraph.ChangingNodeAttribute((GRGEN_LIBGR.INode)elem_" + seqClear.Id + ", attrType_" + seqClear.Id + ", GRGEN_LIBGR.AttributeChangeType.RemoveElement, null, i_" + seqClear.Id + ");\n"); source.AppendFront("\telse\n"); source.AppendFront("\t\tgraph.ChangingEdgeAttribute((GRGEN_LIBGR.IEdge)elem_" + seqClear.Id + ", attrType_" + seqClear.Id + ", GRGEN_LIBGR.AttributeChangeType.RemoveElement, null, i_" + seqClear.Id + ");\n"); } source.AppendFront(array + ".Clear();\n"); if(seqClear.Attribute != null) { if(gen.FireDebugEvents) { source.AppendFront("\tif(elem_" + seqClear.Id + " is GRGEN_LIBGR.INode)\n"); source.AppendFront("\t\tgraph.ChangedNodeAttribute((GRGEN_LIBGR.INode)elem_" + seqClear.Id + ", attrType_" + seqClear.Id + ");\n"); source.AppendFront("\telse\n"); source.AppendFront("\t\tgraph.ChangedEdgeAttribute((GRGEN_LIBGR.IEdge)elem_" + seqClear.Id + ", attrType_" + seqClear.Id + ");\n"); } } source.Unindent(); source.AppendFront("} else if(" + containerVar + " is GRGEN_LIBGR.IDeque) {\n"); source.Indent(); string deque = "((GRGEN_LIBGR.IDeque)" + containerVar + ")"; if(seqClear.Attribute != null) { source.AppendFront("for(int i_" + seqClear.Id + " = " + deque + ".Count; i_" + seqClear.Id + " >= 0; --i_" + seqClear.Id + ")\n"); source.AppendFront("\tif(elem_" + seqClear.Id + " is GRGEN_LIBGR.INode)\n"); source.AppendFront("\t\tgraph.ChangingNodeAttribute((GRGEN_LIBGR.INode)elem_" + seqClear.Id + ", attrType_" + seqClear.Id + ", GRGEN_LIBGR.AttributeChangeType.RemoveElement, null, i_" + seqClear.Id + ");\n"); source.AppendFront("\telse\n"); source.AppendFront("\t\tgraph.ChangingEdgeAttribute((GRGEN_LIBGR.IEdge)elem_" + seqClear.Id + ", attrType_" + seqClear.Id + ", GRGEN_LIBGR.AttributeChangeType.RemoveElement, null, i_" + seqClear.Id + ");\n"); } source.AppendFront(deque + ".Clear();\n"); if(seqClear.Attribute != null) { if(gen.FireDebugEvents) { source.AppendFront("\tif(elem_" + seqClear.Id + " is GRGEN_LIBGR.INode)\n"); source.AppendFront("\t\tgraph.ChangedNodeAttribute((GRGEN_LIBGR.INode)elem_" + seqClear.Id + ", attrType_" + seqClear.Id + ");\n"); source.AppendFront("\telse\n"); source.AppendFront("\t\tgraph.ChangedEdgeAttribute((GRGEN_LIBGR.IEdge)elem_" + seqClear.Id + ", attrType_" + seqClear.Id + ");\n"); } } source.Unindent(); source.AppendFront("} else {\n"); source.Indent(); string dictionary = "((System.Collections.IDictionary)" + containerVar + ")"; if(seqClear.Attribute != null) { source.AppendFront("if(GRGEN_LIBGR.TypesHelper.ExtractDst(GRGEN_LIBGR.TypesHelper.AttributeTypeToXgrsType(attrType_" + seqClear.Id + ")) == \"SetValueType\")\n"); source.AppendFront("{\n"); source.Indent(); source.AppendFront("foreach(DictionaryEntry kvp_" + seqClear.Id + " in " + dictionary + ")\n"); source.AppendFront("\tif(elem_" + seqClear.Id + " is GRGEN_LIBGR.INode)\n"); source.AppendFront("\t\tgraph.ChangingNodeAttribute((GRGEN_LIBGR.INode)elem_" + seqClear.Id + ", attrType_" + seqClear.Id + ", GRGEN_LIBGR.AttributeChangeType.RemoveElement, kvp_" + seqClear.Id + ", null);\n"); source.AppendFront("\telse\n"); source.AppendFront("\t\tgraph.ChangingEdgeAttribute((GRGEN_LIBGR.IEdge)elem_" + seqClear.Id + ", attrType_" + seqClear.Id + ", GRGEN_LIBGR.AttributeChangeType.RemoveElement, kvp_" + seqClear.Id + ", null);\n"); source.Unindent(); source.AppendFront("}\n"); source.AppendFront("else\n"); source.AppendFront("{\n"); source.Indent(); source.AppendFront("foreach(DictionaryEntry kvp_" + seqClear.Id + " in " + dictionary + ")\n"); source.AppendFront("\tif(elem_" + seqClear.Id + " is GRGEN_LIBGR.INode)\n"); source.AppendFront("\t\tgraph.ChangingNodeAttribute((GRGEN_LIBGR.INode)elem_" + seqClear.Id + ", attrType_" + seqClear.Id + ", GRGEN_LIBGR.AttributeChangeType.RemoveElement, null, kvp_" + seqClear.Id + ");\n"); source.AppendFront("\telse\n"); source.AppendFront("\t\tgraph.ChangingEdgeAttribute((GRGEN_LIBGR.IEdge)elem_" + seqClear.Id + ", attrType_" + seqClear.Id + ", GRGEN_LIBGR.AttributeChangeType.RemoveElement, null, kvp_" + seqClear.Id + ");\n"); source.Unindent(); source.AppendFront("}\n"); } source.AppendFront(dictionary + ".Clear();\n"); if(seqClear.Attribute != null) { if(gen.FireDebugEvents) { source.AppendFront("\tif(elem_" + seqClear.Id + " is GRGEN_LIBGR.INode)\n"); source.AppendFront("\t\tgraph.ChangedNodeAttribute((GRGEN_LIBGR.INode)elem_" + seqClear.Id + ", attrType_" + seqClear.Id + ");\n"); source.AppendFront("\telse\n"); source.AppendFront("\t\tgraph.ChangedEdgeAttribute((GRGEN_LIBGR.IEdge)elem_" + seqClear.Id + ", attrType_" + seqClear.Id + ");\n"); } } source.Unindent(); source.AppendFront("}\n"); source.AppendFront(SetResultVar(seqClear, containerVar)); } else if(seqClear.ContainerType(env).StartsWith("array")) { string array = container; if(seqClear.Attribute != null) { source.AppendFront("GRGEN_LIBGR.IGraphElement elem_" + seqClear.Id + " = (GRGEN_LIBGR.IGraphElement)" + GetVar(seqClear.Attribute.SourceVar) + ";\n"); source.AppendFront("GRGEN_LIBGR.AttributeType attrType_" + seqClear.Id + " = elem_" + seqClear.Id + ".Type.GetAttributeType(\"" + seqClear.Attribute.AttributeName + "\");\n"); source.AppendFront("for(int i_" + seqClear.Id + " = " + array + ".Count; i_" + seqClear.Id + " >= 0; --i_" + seqClear.Id + ")\n"); source.AppendFront("\tif(elem_" + seqClear.Id + " is GRGEN_LIBGR.INode)\n"); source.AppendFront("\t\tgraph.ChangingNodeAttribute((GRGEN_LIBGR.INode)elem_" + seqClear.Id + ", attrType_" + seqClear.Id + ", GRGEN_LIBGR.AttributeChangeType.RemoveElement, null, i_" + seqClear.Id + ");\n"); source.AppendFront("\telse\n"); source.AppendFront("\t\tgraph.ChangingEdgeAttribute((GRGEN_LIBGR.IEdge)elem_" + seqClear.Id + ", attrType_" + seqClear.Id + ", GRGEN_LIBGR.AttributeChangeType.RemoveElement, null, i_" + seqClear.Id + ");\n"); } source.AppendFront(array + ".Clear();\n"); if(seqClear.Attribute != null) { if(gen.FireDebugEvents) { source.AppendFront("\tif(elem_" + seqClear.Id + " is GRGEN_LIBGR.INode)\n"); source.AppendFront("\t\tgraph.ChangedNodeAttribute((GRGEN_LIBGR.INode)elem_" + seqClear.Id + ", attrType_" + seqClear.Id + ");\n"); source.AppendFront("\telse\n"); source.AppendFront("\t\tgraph.ChangedEdgeAttribute((GRGEN_LIBGR.IEdge)elem_" + seqClear.Id + ", attrType_" + seqClear.Id + ");\n"); } } source.AppendFront(SetResultVar(seqClear, container)); } else if(seqClear.ContainerType(env).StartsWith("deque")) { string deque = container; if(seqClear.Attribute != null) { source.AppendFront("GRGEN_LIBGR.IGraphElement elem_" + seqClear.Id + " = (GRGEN_LIBGR.IGraphElement)" + GetVar(seqClear.Attribute.SourceVar) + ";\n"); source.AppendFront("GRGEN_LIBGR.AttributeType attrType_" + seqClear.Id + " = elem_" + seqClear.Id + ".Type.GetAttributeType(\"" + seqClear.Attribute.AttributeName + "\");\n"); source.AppendFront("for(int i_" + seqClear.Id + " = " + deque + ".Count; i_" + seqClear.Id + " >= 0; --i_" + seqClear.Id + ")\n"); source.AppendFront("\tif(elem_" + seqClear.Id + " is GRGEN_LIBGR.INode)\n"); source.AppendFront("\t\tgraph.ChangingNodeAttribute((GRGEN_LIBGR.INode)elem_" + seqClear.Id + ", attrType_" + seqClear.Id + ", GRGEN_LIBGR.AttributeChangeType.RemoveElement, null, i_" + seqClear.Id + ");\n"); source.AppendFront("\telse\n"); source.AppendFront("\t\tgraph.ChangingEdgeAttribute((GRGEN_LIBGR.IEdge)elem_" + seqClear.Id + ", attrType_" + seqClear.Id + ", GRGEN_LIBGR.AttributeChangeType.RemoveElement, null, i_" + seqClear.Id + ");\n"); } source.AppendFront(deque + ".Clear();\n"); if(seqClear.Attribute != null) { if(gen.FireDebugEvents) { source.AppendFront("\tif(elem_" + seqClear.Id + " is GRGEN_LIBGR.INode)\n"); source.AppendFront("\t\tgraph.ChangedNodeAttribute((GRGEN_LIBGR.INode)elem_" + seqClear.Id + ", attrType_" + seqClear.Id + ");\n"); source.AppendFront("\telse\n"); source.AppendFront("\t\tgraph.ChangedEdgeAttribute((GRGEN_LIBGR.IEdge)elem_" + seqClear.Id + ", attrType_" + seqClear.Id + ");\n"); } } source.AppendFront(SetResultVar(seqClear, container)); } else { string dictionary = container; if(seqClear.Attribute != null) { source.AppendFront("GRGEN_LIBGR.IGraphElement elem_" + seqClear.Id + " = (GRGEN_LIBGR.IGraphElement)" + GetVar(seqClear.Attribute.SourceVar) + ";\n"); source.AppendFront("GRGEN_LIBGR.AttributeType attrType_" + seqClear.Id + " = elem_" + seqClear.Id + ".Type.GetAttributeType(\"" + seqClear.Attribute.AttributeName + "\");\n"); if(TypesHelper.ExtractDst(seqClear.ContainerType(env)) == "SetValueType") { source.AppendFront("foreach(DictionaryEntry kvp_" + seqClear.Id + " in " + dictionary + ")\n"); source.AppendFront("if(elem_" + seqClear.Id + " is GRGEN_LIBGR.INode)\n"); source.AppendFront("\tgraph.ChangingNodeAttribute((GRGEN_LIBGR.INode)elem_" + seqClear.Id + ", attrType_" + seqClear.Id + ", GRGEN_LIBGR.AttributeChangeType.RemoveElement, kvp_" + seqClear.Id + ", null);\n"); source.AppendFront("else\n"); source.AppendFront("\tgraph.ChangingEdgeAttribute((GRGEN_LIBGR.IEdge)elem_" + seqClear.Id + ", attrType_" + seqClear.Id + ", GRGEN_LIBGR.AttributeChangeType.RemoveElement, kvp_" + seqClear.Id + ", null);\n"); } else { source.AppendFront("foreach(DictionaryEntry kvp_" + seqClear.Id + " in " + dictionary + ")\n"); source.AppendFront("if(elem_" + seqClear.Id + " is GRGEN_LIBGR.INode)\n"); source.AppendFront("\tgraph.ChangingNodeAttribute((GRGEN_LIBGR.INode)elem_" + seqClear.Id + ", attrType_" + seqClear.Id + ", GRGEN_LIBGR.AttributeChangeType.RemoveElement, null, kvp_" + seqClear.Id + ");\n"); source.AppendFront("else\n"); source.AppendFront("\tgraph.ChangingEdgeAttribute((GRGEN_LIBGR.IEdge)elem_" + seqClear.Id + ", attrType_" + seqClear.Id + ", GRGEN_LIBGR.AttributeChangeType.RemoveElement, null, kvp_" + seqClear.Id + ");\n"); } } source.AppendFront(dictionary + ".Clear();\n"); if(seqClear.Attribute != null) { if(gen.FireDebugEvents) { source.AppendFront("if(elem_" + seqClear.Id + " is GRGEN_LIBGR.INode)\n"); source.AppendFront("\tgraph.ChangedNodeAttribute((GRGEN_LIBGR.INode)elem_" + seqClear.Id + ", attrType_" + seqClear.Id + ");\n"); source.AppendFront("else\n"); source.AppendFront("\tgraph.ChangedEdgeAttribute((GRGEN_LIBGR.IEdge)elem_" + seqClear.Id + ", attrType_" + seqClear.Id + ");\n"); } } source.AppendFront(SetResultVar(seqClear, container)); } break; } case SequenceComputationType.VAlloc: source.Append("graph.AllocateVisitedFlag()"); break; case SequenceComputationType.VFree: case SequenceComputationType.VFreeNonReset: { SequenceComputationVFree seqVFree = (SequenceComputationVFree)seqComp; if(seqVFree.Reset) source.AppendFront("graph.FreeVisitedFlag((int)" + GetSequenceExpression(seqVFree.VisitedFlagExpression, source) + ");\n"); else source.AppendFront("graph.FreeVisitedFlagNonReset((int)" + GetSequenceExpression(seqVFree.VisitedFlagExpression, source) + ");\n"); source.AppendFront(SetResultVar(seqVFree, "null")); break; } case SequenceComputationType.VReset: { SequenceComputationVReset seqVReset = (SequenceComputationVReset)seqComp; source.AppendFront("graph.ResetVisitedFlag((int)" + GetSequenceExpression(seqVReset.VisitedFlagExpression, source) + ");\n"); source.AppendFront(SetResultVar(seqVReset, "null")); break; } case SequenceComputationType.DebugAdd: { SequenceComputationDebugAdd seqDebug = (SequenceComputationDebugAdd)seqComp; source.AppendFront("procEnv.DebugEntering("); for(int i = 0; i < seqDebug.ArgExprs.Count; ++i) { if(i == 0) source.Append("(string)"); else source.Append(", "); source.Append(GetSequenceExpression(seqDebug.ArgExprs[i], source)); } source.Append(");\n"); source.AppendFront(SetResultVar(seqDebug, "null")); break; } case SequenceComputationType.DebugRem: { SequenceComputationDebugRem seqDebug = (SequenceComputationDebugRem)seqComp; source.AppendFront("procEnv.DebugExiting("); for(int i = 0; i < seqDebug.ArgExprs.Count; ++i) { if(i == 0) source.Append("(string)"); else source.Append(", "); source.Append(GetSequenceExpression(seqDebug.ArgExprs[i], source)); } source.Append(");\n"); source.AppendFront(SetResultVar(seqDebug, "null")); break; } case SequenceComputationType.DebugEmit: { SequenceComputationDebugEmit seqDebug = (SequenceComputationDebugEmit)seqComp; source.AppendFront("procEnv.DebugEmitting("); for(int i = 0; i < seqDebug.ArgExprs.Count; ++i) { if(i == 0) source.Append("(string)"); else source.Append(", "); source.Append(GetSequenceExpression(seqDebug.ArgExprs[i], source)); } source.Append(");\n"); source.AppendFront(SetResultVar(seqDebug, "null")); break; } case SequenceComputationType.DebugHalt: { SequenceComputationDebugHalt seqDebug = (SequenceComputationDebugHalt)seqComp; source.AppendFront("procEnv.DebugHalting("); for(int i = 0; i < seqDebug.ArgExprs.Count; ++i) { if(i == 0) source.Append("(string)"); else source.Append(", "); source.Append(GetSequenceExpression(seqDebug.ArgExprs[i], source)); } source.Append(");\n"); source.AppendFront(SetResultVar(seqDebug, "null")); break; } case SequenceComputationType.DebugHighlight: { SequenceComputationDebugHighlight seqDebug = (SequenceComputationDebugHighlight)seqComp; source.AppendFront("List<object> values = new List<object>();\n"); source.AppendFront("List<string> annotations = new List<string>();\n"); for(int i = 1; i < seqDebug.ArgExprs.Count; ++i) { if(i % 2 == 1) source.AppendFront("values.Add(" + GetSequenceExpression(seqDebug.ArgExprs[i], source) + ");\n"); else source.AppendFront("annotations.Add((string)" + GetSequenceExpression(seqDebug.ArgExprs[i], source) + ");\n"); } source.AppendFront("procEnv.DebugHighlighting(" + GetSequenceExpression(seqDebug.ArgExprs[0], source) + ", values, annotations);\n"); source.AppendFront(SetResultVar(seqDebug, "null")); break; } case SequenceComputationType.Emit: { SequenceComputationEmit seqEmit = (SequenceComputationEmit)seqComp; bool declarationEmitted = false; for(int i = 0; i < seqEmit.Expressions.Count; ++i) { if(!(seqEmit.Expressions[i] is SequenceExpressionConstant)) { string emitVal = "emitval_" + seqEmit.Id; if(!declarationEmitted) { source.AppendFront("object " + emitVal + ";\n"); declarationEmitted = true; } source.AppendFront(emitVal + " = " + GetSequenceExpression(seqEmit.Expressions[i], source) + ";\n"); if(seqEmit.Expressions[i].Type(env) == "" || seqEmit.Expressions[i].Type(env).StartsWith("set<") || seqEmit.Expressions[i].Type(env).StartsWith("map<") || seqEmit.Expressions[i].Type(env).StartsWith("array<") || seqEmit.Expressions[i].Type(env).StartsWith("deque<")) { source.AppendFront("if(" + emitVal + " is IDictionary)\n"); source.AppendFront("\tprocEnv.EmitWriter.Write(GRGEN_LIBGR.EmitHelper.ToString((IDictionary)" + emitVal + ", graph));\n"); source.AppendFront("else if(" + emitVal + " is IList)\n"); source.AppendFront("\tprocEnv.EmitWriter.Write(GRGEN_LIBGR.EmitHelper.ToString((IList)" + emitVal + ", graph));\n"); source.AppendFront("else if(" + emitVal + " is GRGEN_LIBGR.IDeque)\n"); source.AppendFront("\tprocEnv.EmitWriter.Write(GRGEN_LIBGR.EmitHelper.ToString((GRGEN_LIBGR.IDeque)" + emitVal + ", graph));\n"); source.AppendFront("else\n\t"); } source.AppendFront("procEnv.EmitWriter.Write(GRGEN_LIBGR.EmitHelper.ToString(" + emitVal + ", graph));\n"); } else { SequenceExpressionConstant constant = (SequenceExpressionConstant)seqEmit.Expressions[i]; if(constant.Constant is string) { String text = (string)constant.Constant; text = text.Replace("\n", "\\n"); text = text.Replace("\r", "\\r"); text = text.Replace("\t", "\\t"); source.AppendFront("procEnv.EmitWriter.Write(\"" + text + "\");\n"); } else source.AppendFront("procEnv.EmitWriter.Write(GRGEN_LIBGR.EmitHelper.ToString(" + GetSequenceExpression(seqEmit.Expressions[i], source) + ", graph));\n"); } } source.AppendFront(SetResultVar(seqEmit, "null")); break; } case SequenceComputationType.Record: { SequenceComputationRecord seqRec = (SequenceComputationRecord)seqComp; if(!(seqRec.Expression is SequenceExpressionConstant)) { string recVal = "recval_" + seqRec.Id; source.AppendFront("object " + recVal + " = " + GetSequenceExpression(seqRec.Expression, source) + ";\n"); if(seqRec.Expression.Type(env) == "" || seqRec.Expression.Type(env).StartsWith("set<") || seqRec.Expression.Type(env).StartsWith("map<") || seqRec.Expression.Type(env).StartsWith("array<") || seqRec.Expression.Type(env).StartsWith("deque<")) { source.AppendFront("if(" + recVal + " is IDictionary)\n"); source.AppendFront("\tprocEnv.Recorder.Write(GRGEN_LIBGR.EmitHelper.ToString((IDictionary)" + recVal + ", graph));\n"); source.AppendFront("else if(" + recVal + " is IList)\n"); source.AppendFront("\tprocEnv.Recorder.Write(GRGEN_LIBGR.EmitHelper.ToString((IList)" + recVal + ", graph));\n"); source.AppendFront("else if(" + recVal + " is GRGEN_LIBGR.IDeque)\n"); source.AppendFront("\tprocEnv.Recorder.Write(GRGEN_LIBGR.EmitHelper.ToString((GRGEN_LIBGR.IDeque)" + recVal + ", graph));\n"); source.AppendFront("else\n\t"); } source.AppendFront("procEnv.Recorder.Write(GRGEN_LIBGR.EmitHelper.ToString(" + recVal + ", graph));\n"); } else { SequenceExpressionConstant constant = (SequenceExpressionConstant)seqRec.Expression; if(constant.Constant is string) { String text = (string)constant.Constant; text = text.Replace("\n", "\\n"); text = text.Replace("\r", "\\r"); text = text.Replace("\t", "\\t"); source.AppendFront("procEnv.Recorder.Write(\"" + text + "\");\n"); } else source.AppendFront("procEnv.Recorder.Write(GRGEN_LIBGR.EmitHelper.ToString(" + GetSequenceExpression(seqRec.Expression, source) + ", graph));\n"); } source.AppendFront(SetResultVar(seqRec, "null")); break; } case SequenceComputationType.Export: { SequenceComputationExport seqExp = (SequenceComputationExport)seqComp; string expFileName = "expfilename_" + seqExp.Id; source.AppendFront("object " + expFileName + " = " + GetSequenceExpression(seqExp.Name, source) + ";\n"); string expArguments = "exparguments_" + seqExp.Id; source.AppendFront("List<string> " + expArguments + " = new List<string>();\n"); source.AppendFront(expArguments + ".Add(" + expFileName + ".ToString());\n"); string expGraph = "expgraph_" + seqExp.Id; if(seqExp.Graph != null) source.AppendFront("GRGEN_LIBGR.IGraph " + expGraph + " = (GRGEN_LIBGR.IGraph)" + GetSequenceExpression(seqExp.Graph, source) + ";\n"); else source.AppendFront("GRGEN_LIBGR.IGraph " + expGraph + " = graph;\n"); source.AppendFront(expArguments + ".Add(" + expFileName + ".ToString());\n"); source.AppendFront("if(" + expGraph + " is GRGEN_LIBGR.INamedGraph)\n"); source.AppendFront("\tGRGEN_LIBGR.Porter.Export((GRGEN_LIBGR.INamedGraph)" + expGraph + ", " + expArguments + ");\n"); source.AppendFront("else\n"); source.AppendFront("\tGRGEN_LIBGR.Porter.Export(" + expGraph + ", " + expArguments + ");\n"); source.AppendFront(SetResultVar(seqExp, "null")); break; } case SequenceComputationType.DeleteFile: { SequenceComputationDeleteFile seqDelFile = (SequenceComputationDeleteFile)seqComp; string delFileName = "delfilename_" + seqDelFile.Id; source.AppendFront("object " + delFileName + " = " + GetSequenceExpression(seqDelFile.Name, source) + ";\n"); source.AppendFront("\tSystem.IO.File.Delete((string)" + delFileName + ");\n"); source.AppendFront(SetResultVar(seqDelFile, "null")); break; } case SequenceComputationType.GraphAdd: { SequenceComputationGraphAdd seqAdd = (SequenceComputationGraphAdd)seqComp; if(seqAdd.ExprSrc == null) { string typeExpr = GetSequenceExpression(seqAdd.Expr, source); source.Append("GRGEN_LIBGR.GraphHelper.AddNodeOfType(" + typeExpr + ", graph)"); } else { string typeExpr = GetSequenceExpression(seqAdd.Expr, source); string srcExpr = GetSequenceExpression(seqAdd.ExprSrc, source); string tgtExpr = GetSequenceExpression(seqAdd.ExprDst, source); source.Append("GRGEN_LIBGR.GraphHelper.AddEdgeOfType(" + typeExpr + ", (GRGEN_LIBGR.INode)" + srcExpr + ", (GRGEN_LIBGR.INode)" + tgtExpr + ", graph)"); } break; } case SequenceComputationType.GraphRem: { SequenceComputationGraphRem seqRem = (SequenceComputationGraphRem)seqComp; string remVal = "remval_" + seqRem.Id; string seqRemExpr = GetSequenceExpression(seqRem.Expr, source); if(seqRem.Expr.Type(env) == "") { source.AppendFront("GRGEN_LIBGR.IGraphElement " + remVal + " = (GRGEN_LIBGR.IGraphElement)" + seqRemExpr + ";\n"); source.AppendFront("if(" + remVal + " is GRGEN_LIBGR.IEdge)\n"); source.AppendFront("\tgraph.Remove((GRGEN_LIBGR.IEdge)" + remVal + ");\n"); source.AppendFront("else\n"); source.AppendFront("\t{graph.RemoveEdges((GRGEN_LIBGR.INode)" + remVal + "); graph.Remove((GRGEN_LIBGR.INode)" + remVal + ");}\n"); } else { if(TypesHelper.IsSameOrSubtype(seqRem.Expr.Type(env), "Node", model)) { source.AppendFront("GRGEN_LIBGR.INode " + remVal + " = (GRGEN_LIBGR.INode)" + seqRemExpr + ";\n"); source.AppendFront("graph.RemoveEdges(" + remVal + "); graph.Remove(" + remVal + ");\n"); } else if(TypesHelper.IsSameOrSubtype(seqRem.Expr.Type(env), "Edge", model)) { source.AppendFront("GRGEN_LIBGR.IEdge " + remVal + " = (GRGEN_LIBGR.IEdge)" + seqRemExpr + ";\n"); source.AppendFront("\tgraph.Remove(" + remVal + ");\n"); } else source.AppendFront("throw new Exception(\"rem() on non-node/edge\");\n"); } source.AppendFront(SetResultVar(seqRem, "null")); break; } case SequenceComputationType.GraphClear: { SequenceComputationGraphClear seqClr = (SequenceComputationGraphClear)seqComp; source.AppendFront("graph.Clear();\n"); source.AppendFront(SetResultVar(seqClr, "null")); break; } case SequenceComputationType.GraphRetype: { SequenceComputationGraphRetype seqRetype = (SequenceComputationGraphRetype)seqComp; string typeExpr = GetSequenceExpression(seqRetype.TypeExpr, source); string elemExpr = GetSequenceExpression(seqRetype.ElemExpr, source); source.Append("GRGEN_LIBGR.GraphHelper.RetypeGraphElement((GRGEN_LIBGR.IGraphElement)" + elemExpr + ", " + typeExpr + ", graph)"); break; } case SequenceComputationType.GraphAddCopy: { SequenceComputationGraphAddCopy seqAddCopy = (SequenceComputationGraphAddCopy)seqComp; if(seqAddCopy.ExprSrc == null) { string nodeExpr = GetSequenceExpression(seqAddCopy.Expr, source); source.Append("GRGEN_LIBGR.GraphHelper.AddCopyOfNode(" + nodeExpr + ", graph)"); } else { string edgeExpr = GetSequenceExpression(seqAddCopy.Expr, source); string srcExpr = GetSequenceExpression(seqAddCopy.ExprSrc, source); string tgtExpr = GetSequenceExpression(seqAddCopy.ExprDst, source); source.Append("GRGEN_LIBGR.GraphHelper.AddCopyOfEdge(" + edgeExpr + ", (GRGEN_LIBGR.INode)" + srcExpr + ", (GRGEN_LIBGR.INode)" + tgtExpr + ", graph)"); } break; } case SequenceComputationType.GraphMerge: { SequenceComputationGraphMerge seqMrg = (SequenceComputationGraphMerge)seqComp; string tgtNodeExpr = GetSequenceExpression(seqMrg.TargetNodeExpr, source); string srcNodeExpr = GetSequenceExpression(seqMrg.SourceNodeExpr, source); source.AppendFrontFormat("graph.Merge((GRGEN_LIBGR.INode){0}, (GRGEN_LIBGR.INode){1}, \"merge\");\n", tgtNodeExpr, srcNodeExpr); source.AppendFront(SetResultVar(seqMrg, "null")); break; } case SequenceComputationType.GraphRedirectSource: { SequenceComputationGraphRedirectSource seqRedir = (SequenceComputationGraphRedirectSource)seqComp; string edgeExpr = GetSequenceExpression(seqRedir.EdgeExpr, source); string srcNodeExpr = GetSequenceExpression(seqRedir.SourceNodeExpr, source); source.AppendFrontFormat("graph.RedirectSource((GRGEN_LIBGR.IEdge){0}, (GRGEN_LIBGR.INode){1}, \"old source\");\n", edgeExpr, srcNodeExpr); source.AppendFront(SetResultVar(seqRedir, "null")); break; } case SequenceComputationType.GraphRedirectTarget: { SequenceComputationGraphRedirectTarget seqRedir = (SequenceComputationGraphRedirectTarget)seqComp; string edgeExpr = GetSequenceExpression(seqRedir.EdgeExpr, source); string tgtNodeExpr = GetSequenceExpression(seqRedir.TargetNodeExpr, source); source.AppendFrontFormat("graph.RedirectTarget((GRGEN_LIBGR.IEdge){0}, (GRGEN_LIBGR.INode){1}, \"old target\");\n", edgeExpr, tgtNodeExpr); source.AppendFront(SetResultVar(seqRedir, "null")); break; } case SequenceComputationType.GraphRedirectSourceAndTarget: { SequenceComputationGraphRedirectSourceAndTarget seqRedir = (SequenceComputationGraphRedirectSourceAndTarget)seqComp; string edgeExpr = GetSequenceExpression(seqRedir.EdgeExpr, source); string srcNodeExpr = GetSequenceExpression(seqRedir.SourceNodeExpr, source); string tgtNodeExpr = GetSequenceExpression(seqRedir.TargetNodeExpr, source); source.AppendFrontFormat("graph.RedirectSourceAndTarget((GRGEN_LIBGR.IEdge){0}, (GRGEN_LIBGR.INode){1}, (GRGEN_LIBGR.INode){2}, \"old source\", \"old target\");\n", edgeExpr, srcNodeExpr, tgtNodeExpr); source.AppendFront(SetResultVar(seqRedir, "null")); break; } case SequenceComputationType.Insert: { SequenceComputationInsert seqIns = (SequenceComputationInsert)seqComp; string graphExpr = GetSequenceExpression(seqIns.Graph, source); source.AppendFrontFormat("GRGEN_LIBGR.GraphHelper.Insert((GRGEN_LIBGR.IGraph){0}, graph);\n", graphExpr); source.AppendFront(SetResultVar(seqIns, "null")); break; } case SequenceComputationType.InsertCopy: { SequenceComputationInsertCopy seqInsCopy = (SequenceComputationInsertCopy)seqComp; string graphExpr = GetSequenceExpression(seqInsCopy.Graph, source); string rootNodeExpr = GetSequenceExpression(seqInsCopy.RootNode, source); source.AppendFormat("GRGEN_LIBGR.GraphHelper.InsertCopy((GRGEN_LIBGR.IGraph){0}, (GRGEN_LIBGR.INode){1}, graph)", graphExpr, rootNodeExpr); break; } case SequenceComputationType.InsertInduced: { SequenceComputationInsertInduced seqInsInd = (SequenceComputationInsertInduced)seqComp; source.Append("GRGEN_LIBGR.GraphHelper.InsertInduced((IDictionary<GRGEN_LIBGR.INode, GRGEN_LIBGR.SetValueType>)" + GetSequenceExpression(seqInsInd.NodeSet, source) + ", (GRGEN_LIBGR.INode)" + GetSequenceExpression(seqInsInd.RootNode, source) + ", graph)"); break; } case SequenceComputationType.InsertDefined: { SequenceComputationInsertDefined seqInsDef = (SequenceComputationInsertDefined)seqComp; source.Append("GRGEN_LIBGR.GraphHelper.InsertDefined((IDictionary<GRGEN_LIBGR.IEdge, GRGEN_LIBGR.SetValueType>)" + GetSequenceExpression(seqInsDef.EdgeSet, source) + ", (GRGEN_LIBGR.IEdge)" + GetSequenceExpression(seqInsDef.RootEdge, source) + ", graph)"); break; } case SequenceComputationType.Expression: { SequenceExpression seqExpr = (SequenceExpression)seqComp; source.AppendFront(SetResultVar(seqExpr, GetSequenceExpression(seqExpr, source))); break; } case SequenceComputationType.BuiltinProcedureCall: { SequenceComputationBuiltinProcedureCall seqCall = (SequenceComputationBuiltinProcedureCall)seqComp; SourceBuilder sb = new SourceBuilder(); EmitSequenceComputation(seqCall.BuiltinProcedure, sb); if(seqCall.ReturnVars.Count > 0) { source.AppendFront(SetVar(seqCall.ReturnVars[0], sb.ToString())); source.AppendFront(SetResultVar(seqCall, GetVar(seqCall.ReturnVars[0]))); } else { source.AppendFront(sb.ToString() + ";\n"); source.AppendFront(SetResultVar(seqCall, "null")); } break; } case SequenceComputationType.ProcedureCall: { SequenceComputationProcedureCall seqCall = (SequenceComputationProcedureCall)seqComp; String returnParameterDeclarations; String returnArguments; String returnAssignments; BuildReturnParameters(seqCall.ParamBindings, out returnParameterDeclarations, out returnArguments, out returnAssignments); if(returnParameterDeclarations.Length != 0) source.AppendFront(returnParameterDeclarations + "\n"); if(seqCall.IsExternalProcedureCalled) source.AppendFront("GRGEN_EXPR.ExternalProcedures."); else source.AppendFrontFormat("GRGEN_ACTIONS.{0}Procedures.", TypesHelper.GetPackagePrefixDot(seqCall.ParamBindings.Package)); source.Append(seqCall.ParamBindings.Name); source.Append("(procEnv, graph"); source.Append(BuildParameters(seqCall.ParamBindings)); source.Append(returnArguments); source.Append(");\n"); if(returnAssignments.Length != 0) source.AppendFront(returnAssignments + "\n"); source.AppendFront(SetResultVar(seqCall, "null")); break; } case SequenceComputationType.ProcedureMethodCall: { SequenceComputationProcedureMethodCall seqCall = (SequenceComputationProcedureMethodCall)seqComp; String type = seqCall.TargetExpr != null ? seqCall.TargetExpr.Type(env) : seqCall.TargetVar.Type; if(type == "") { string tmpVarName = "tmpvar_" + tmpVarCtr.ToString(); ++tmpVarCtr; source.AppendFront("object[] " + tmpVarName + " = "); source.Append("((GRGEN_LIBGR.IGraphElement)"); if(seqCall.TargetExpr != null) source.Append(GetSequenceExpression(seqCall.TargetExpr, source)); else source.Append(GetVar(seqCall.TargetVar)); source.Append(").ApplyProcedureMethod(procEnv, graph, "); source.Append("\"" + seqCall.ParamBindings.Name + "\""); source.Append(BuildParametersInObject(seqCall.ParamBindings)); source.Append(");\n"); for(int i = 0; i < seqCall.ParamBindings.ReturnVars.Length; i++) source.Append(SetVar(seqCall.ParamBindings.ReturnVars[i], tmpVarName)); } else { String returnParameterDeclarations; String returnArguments; String returnAssignments; BuildReturnParameters(seqCall.ParamBindings, TypesHelper.GetNodeOrEdgeType(type, model), out returnParameterDeclarations, out returnArguments, out returnAssignments); if(returnParameterDeclarations.Length != 0) source.AppendFront(returnParameterDeclarations + "\n"); source.AppendFront("(("); source.Append(TypesHelper.XgrsTypeToCSharpType(type, model)); source.Append(")"); if(seqCall.TargetExpr != null) source.Append(GetSequenceExpression(seqCall.TargetExpr, source)); else source.Append(GetVar(seqCall.TargetVar)); source.Append(")."); source.Append(seqCall.ParamBindings.Name); source.Append("(procEnv, graph"); source.Append(BuildParameters(seqCall.ParamBindings, TypesHelper.GetNodeOrEdgeType(type, model).GetProcedureMethod(seqCall.ParamBindings.Name))); source.Append(returnArguments); source.Append(");\n"); } source.AppendFront(SetResultVar(seqCall, "null")); break; } default: throw new Exception("Unknown sequence computation type: " + seqComp.SequenceComputationType); } }
public override string ToString() { SourceBuilder sb = new SourceBuilder(); Expr.Emit(sb); return Index.Name + "==" + sb.ToString(); }
// source is needed for a method call chain or expressions that require temporary variables, // to emit the state changing computation methods or the temporary variable declarations (not the assignement, needs to be computed from inside the expression) // before returning the final expression method call ready to be emitted private string GetSequenceExpression(SequenceExpression expr, SourceBuilder source) { switch(expr.SequenceExpressionType) { case SequenceExpressionType.Conditional: { SequenceExpressionConditional seqCond = (SequenceExpressionConditional)expr; return "( (bool)" + GetSequenceExpression(seqCond.Condition, source) + " ? (object)" + GetSequenceExpression(seqCond.TrueCase, source) + " : (object)" + GetSequenceExpression(seqCond.FalseCase, source) + " )"; } case SequenceExpressionType.LazyOr: { SequenceExpressionLazyOr seq = (SequenceExpressionLazyOr)expr; return "((bool)" + GetSequenceExpression(seq.Left, source) + " || (bool)" + GetSequenceExpression(seq.Right, source) + ")"; } case SequenceExpressionType.LazyAnd: { SequenceExpressionLazyAnd seq = (SequenceExpressionLazyAnd)expr; return "((bool)" + GetSequenceExpression(seq.Left, source) + " && (bool)" + GetSequenceExpression(seq.Right, source) + ")"; } case SequenceExpressionType.StrictOr: { SequenceExpressionStrictOr seq = (SequenceExpressionStrictOr)expr; return "((bool)" + GetSequenceExpression(seq.Left, source) + " | (bool)" + GetSequenceExpression(seq.Right, source) + ")"; } case SequenceExpressionType.StrictXor: { SequenceExpressionStrictXor seq = (SequenceExpressionStrictXor)expr; return "((bool)" + GetSequenceExpression(seq.Left, source) + " ^ (bool)" + GetSequenceExpression(seq.Right, source) + ")"; } case SequenceExpressionType.StrictAnd: { SequenceExpressionStrictAnd seq = (SequenceExpressionStrictAnd)expr; return "((bool)" + GetSequenceExpression(seq.Left, source) + " & (bool)" + GetSequenceExpression(seq.Right, source) + ")"; } case SequenceExpressionType.Equal: { SequenceExpressionEqual seq = (SequenceExpressionEqual)expr; string leftExpr = GetSequenceExpression(seq.Left, source); string rightExpr = GetSequenceExpression(seq.Right, source); string leftType = "GRGEN_LIBGR.TypesHelper.XgrsTypeOfConstant(" + leftExpr + ", graph.Model)"; string rightType = "GRGEN_LIBGR.TypesHelper.XgrsTypeOfConstant(" + rightExpr + ", graph.Model)"; if(seq.BalancedTypeStatic != "") return SequenceExpressionHelper.EqualStatic(leftExpr, rightExpr, seq.BalancedTypeStatic, seq.LeftTypeStatic, seq.RightTypeStatic, model); else return "GRGEN_LIBGR.SequenceExpressionHelper.EqualObjects(" + leftExpr + ", " + rightExpr + ", " + "GRGEN_LIBGR.SequenceExpressionHelper.Balance(GRGEN_LIBGR.SequenceExpressionType.Equal, " + leftType + ", " + rightType + ", graph.Model), " + leftType + ", " + rightType + ", graph)"; } case SequenceExpressionType.StructuralEqual: { SequenceExpressionStructuralEqual seq = (SequenceExpressionStructuralEqual)expr; string leftExpr = GetSequenceExpression(seq.Left, source); string rightExpr = GetSequenceExpression(seq.Right, source); return SequenceExpressionHelper.StructuralEqualStatic(leftExpr, rightExpr); } case SequenceExpressionType.NotEqual: { SequenceExpressionNotEqual seq = (SequenceExpressionNotEqual)expr; string leftExpr = GetSequenceExpression(seq.Left, source); string rightExpr = GetSequenceExpression(seq.Right, source); string leftType = "GRGEN_LIBGR.TypesHelper.XgrsTypeOfConstant(" + leftExpr + ", graph.Model)"; string rightType = "GRGEN_LIBGR.TypesHelper.XgrsTypeOfConstant(" + rightExpr + ", graph.Model)"; if(seq.BalancedTypeStatic != "") return SequenceExpressionHelper.NotEqualStatic(leftExpr, rightExpr, seq.BalancedTypeStatic, seq.LeftTypeStatic, seq.RightTypeStatic, model); else return "GRGEN_LIBGR.SequenceExpressionHelper.NotEqualObjects(" + leftExpr + ", " + rightExpr + ", " + "GRGEN_LIBGR.SequenceExpressionHelper.Balance(GRGEN_LIBGR.SequenceExpressionType.NotEqual, " + leftType + ", " + rightType + ", graph.Model), " + leftType + ", " + rightType + ", graph)"; } case SequenceExpressionType.Lower: { SequenceExpressionLower seq = (SequenceExpressionLower)expr; string leftExpr = GetSequenceExpression(seq.Left, source); string rightExpr = GetSequenceExpression(seq.Right, source); string leftType = "GRGEN_LIBGR.TypesHelper.XgrsTypeOfConstant(" + leftExpr + ", graph.Model)"; string rightType = "GRGEN_LIBGR.TypesHelper.XgrsTypeOfConstant(" + rightExpr + ", graph.Model)"; if(seq.BalancedTypeStatic != "") return SequenceExpressionHelper.LowerStatic(leftExpr, rightExpr, seq.BalancedTypeStatic, seq.LeftTypeStatic, seq.RightTypeStatic, model); else return "GRGEN_LIBGR.SequenceExpressionHelper.LowerObjects(" + leftExpr + ", " + rightExpr + ", " + "GRGEN_LIBGR.SequenceExpressionHelper.Balance(GRGEN_LIBGR.SequenceExpressionType.Lower, " + leftType + ", " + rightType + ", graph.Model)," + leftType + ", " + rightType + ", graph)"; } case SequenceExpressionType.Greater: { SequenceExpressionGreater seq = (SequenceExpressionGreater)expr; string leftExpr = GetSequenceExpression(seq.Left, source); string rightExpr = GetSequenceExpression(seq.Right, source); string leftType = "GRGEN_LIBGR.TypesHelper.XgrsTypeOfConstant(" + leftExpr + ", graph.Model)"; string rightType = "GRGEN_LIBGR.TypesHelper.XgrsTypeOfConstant(" + rightExpr + ", graph.Model)"; if(seq.BalancedTypeStatic != "") return SequenceExpressionHelper.GreaterStatic(leftExpr, rightExpr, seq.BalancedTypeStatic, seq.LeftTypeStatic, seq.RightTypeStatic, model); else return "GRGEN_LIBGR.SequenceExpressionHelper.GreaterObjects(" + leftExpr + ", " + rightExpr + ", " + "GRGEN_LIBGR.SequenceExpressionHelper.Balance(GRGEN_LIBGR.SequenceExpressionType.Greater, " + leftType + ", " + rightType + ", graph.Model)," + leftType + ", " + rightType + ", graph)"; } case SequenceExpressionType.LowerEqual: { SequenceExpressionLowerEqual seq = (SequenceExpressionLowerEqual)expr; string leftExpr = GetSequenceExpression(seq.Left, source); string rightExpr = GetSequenceExpression(seq.Right, source); string leftType = "GRGEN_LIBGR.TypesHelper.XgrsTypeOfConstant(" + leftExpr + ", graph.Model)"; string rightType = "GRGEN_LIBGR.TypesHelper.XgrsTypeOfConstant(" + rightExpr + ", graph.Model)"; if(seq.BalancedTypeStatic != "") return SequenceExpressionHelper.LowerEqualStatic(leftExpr, rightExpr, seq.BalancedTypeStatic, seq.LeftTypeStatic, seq.RightTypeStatic, model); else return "GRGEN_LIBGR.SequenceExpressionHelper.LowerEqualObjects(" + leftExpr + ", " + rightExpr + ", " + "GRGEN_LIBGR.SequenceExpressionHelper.Balance(GRGEN_LIBGR.SequenceExpressionType.LowerEqual, " + leftType + ", " + rightType + ", graph.Model)," + leftType + ", " + rightType + ", graph)"; } case SequenceExpressionType.GreaterEqual: { SequenceExpressionGreaterEqual seq = (SequenceExpressionGreaterEqual)expr; string leftExpr = GetSequenceExpression(seq.Left, source); string rightExpr = GetSequenceExpression(seq.Right, source); string leftType = "GRGEN_LIBGR.TypesHelper.XgrsTypeOfConstant(" + leftExpr + ", graph.Model)"; string rightType = "GRGEN_LIBGR.TypesHelper.XgrsTypeOfConstant(" + rightExpr + ", graph.Model)"; if(seq.BalancedTypeStatic != "") return SequenceExpressionHelper.GreaterEqualStatic(leftExpr, rightExpr, seq.BalancedTypeStatic, seq.LeftTypeStatic, seq.RightTypeStatic, model); else return "GRGEN_LIBGR.SequenceExpressionHelper.GreaterEqualObjects(" + leftExpr + ", " + rightExpr + ", " + "GRGEN_LIBGR.SequenceExpressionHelper.Balance(GRGEN_LIBGR.SequenceExpressionType.GreaterEqual, " + leftType + ", " + rightType + ", graph.Model)," + leftType + ", " + rightType + ", graph)"; } case SequenceExpressionType.Plus: { SequenceExpressionPlus seq = (SequenceExpressionPlus)expr; string leftExpr = GetSequenceExpression(seq.Left, source); string rightExpr = GetSequenceExpression(seq.Right, source); string leftType = "GRGEN_LIBGR.TypesHelper.XgrsTypeOfConstant(" + leftExpr + ", graph.Model)"; string rightType = "GRGEN_LIBGR.TypesHelper.XgrsTypeOfConstant(" + rightExpr + ", graph.Model)"; if(seq.BalancedTypeStatic != "") return SequenceExpressionHelper.PlusStatic(leftExpr, rightExpr, seq.BalancedTypeStatic, seq.LeftTypeStatic, seq.RightTypeStatic, model); else return "GRGEN_LIBGR.SequenceExpressionHelper.PlusObjects(" + leftExpr + ", " + rightExpr + ", " + "GRGEN_LIBGR.SequenceExpressionHelper.Balance(GRGEN_LIBGR.SequenceExpressionType.Plus, " + leftType + ", " + rightType + ", graph.Model)," + leftType + ", " + rightType + ", graph)"; } case SequenceExpressionType.Minus: { SequenceExpressionMinus seq = (SequenceExpressionMinus)expr; string leftExpr = GetSequenceExpression(seq.Left, source); string rightExpr = GetSequenceExpression(seq.Right, source); string leftType = "GRGEN_LIBGR.TypesHelper.XgrsTypeOfConstant(" + leftExpr + ", graph.Model)"; string rightType = "GRGEN_LIBGR.TypesHelper.XgrsTypeOfConstant(" + rightExpr + ", graph.Model)"; if(seq.BalancedTypeStatic != "") return SequenceExpressionHelper.MinusStatic(leftExpr, rightExpr, seq.BalancedTypeStatic, seq.LeftTypeStatic, seq.RightTypeStatic, model); else return "GRGEN_LIBGR.SequenceExpressionHelper.MinusObjects(" + leftExpr + ", " + rightExpr + ", " + "GRGEN_LIBGR.SequenceExpressionHelper.Balance(GRGEN_LIBGR.SequenceExpressionType.Minus, " + leftType + ", " + rightType + ", graph.Model)," + leftType + ", " + rightType + ", graph)"; } case SequenceExpressionType.Mul: { SequenceExpressionMul seq = (SequenceExpressionMul)expr; string leftExpr = GetSequenceExpression(seq.Left, source); string rightExpr = GetSequenceExpression(seq.Right, source); string leftType = "GRGEN_LIBGR.TypesHelper.XgrsTypeOfConstant(" + leftExpr + ", graph.Model)"; string rightType = "GRGEN_LIBGR.TypesHelper.XgrsTypeOfConstant(" + rightExpr + ", graph.Model)"; if(seq.BalancedTypeStatic != "") return SequenceExpressionHelper.MulStatic(leftExpr, rightExpr, seq.BalancedTypeStatic, seq.LeftTypeStatic, seq.RightTypeStatic, model); else return "GRGEN_LIBGR.SequenceExpressionHelper.MulObjects(" + leftExpr + ", " + rightExpr + ", " + "GRGEN_LIBGR.SequenceExpressionHelper.Balance(GRGEN_LIBGR.SequenceExpressionType.Mul, " + leftType + ", " + rightType + ", graph.Model)," + leftType + ", " + rightType + ", graph)"; } case SequenceExpressionType.Div: { SequenceExpressionDiv seq = (SequenceExpressionDiv)expr; string leftExpr = GetSequenceExpression(seq.Left, source); string rightExpr = GetSequenceExpression(seq.Right, source); string leftType = "GRGEN_LIBGR.TypesHelper.XgrsTypeOfConstant(" + leftExpr + ", graph.Model)"; string rightType = "GRGEN_LIBGR.TypesHelper.XgrsTypeOfConstant(" + rightExpr + ", graph.Model)"; if(seq.BalancedTypeStatic != "") return SequenceExpressionHelper.DivStatic(leftExpr, rightExpr, seq.BalancedTypeStatic, seq.LeftTypeStatic, seq.RightTypeStatic, model); else return "GRGEN_LIBGR.SequenceExpressionHelper.DivObjects(" + leftExpr + ", " + rightExpr + ", " + "GRGEN_LIBGR.SequenceExpressionHelper.Balance(GRGEN_LIBGR.SequenceExpressionType.Div, " + leftType + ", " + rightType + ", graph.Model)," + leftType + ", " + rightType + ", graph)"; } case SequenceExpressionType.Mod: { SequenceExpressionMod seq = (SequenceExpressionMod)expr; string leftExpr = GetSequenceExpression(seq.Left, source); string rightExpr = GetSequenceExpression(seq.Right, source); string leftType = "GRGEN_LIBGR.TypesHelper.XgrsTypeOfConstant(" + leftExpr + ", graph.Model)"; string rightType = "GRGEN_LIBGR.TypesHelper.XgrsTypeOfConstant(" + rightExpr + ", graph.Model)"; if(seq.BalancedTypeStatic != "") return SequenceExpressionHelper.ModStatic(leftExpr, rightExpr, seq.BalancedTypeStatic, seq.LeftTypeStatic, seq.RightTypeStatic, model); else return "GRGEN_LIBGR.SequenceExpressionHelper.ModObjects(" + leftExpr + ", " + rightExpr + ", " + "GRGEN_LIBGR.SequenceExpressionHelper.Balance(GRGEN_LIBGR.SequenceExpressionType.Mod, " + leftType + ", " + rightType + ", graph.Model)," + leftType + ", " + rightType + ", graph)"; } case SequenceExpressionType.Not: { SequenceExpressionNot seqNot = (SequenceExpressionNot)expr; return "!" + "((bool)" + GetSequenceExpression(seqNot.Operand, source) + ")"; } case SequenceExpressionType.Cast: { SequenceExpressionCast seqCast = (SequenceExpressionCast)expr; string targetType = "UNSUPPORTED TYPE CAST"; if(seqCast.TargetType is NodeType) targetType = ((NodeType)seqCast.TargetType).NodeInterfaceName; if(seqCast.TargetType is EdgeType) targetType = ((EdgeType)seqCast.TargetType).EdgeInterfaceName; // TODO: handle the non-node and non-edge-types, too return "((" + targetType + ")" + GetSequenceExpression(seqCast.Operand, source) + ")"; } case SequenceExpressionType.Def: { SequenceExpressionDef seqDef = (SequenceExpressionDef)expr; String condition = "("; bool isFirst = true; foreach(SequenceExpression var in seqDef.DefVars) { if(isFirst) isFirst = false; else condition += " && "; condition += GetSequenceExpression(var, source) + "!=null"; } condition += ")"; return condition; } case SequenceExpressionType.InContainer: { SequenceExpressionInContainer seqIn = (SequenceExpressionInContainer)expr; string container; string ContainerType; if(seqIn.ContainerExpr is SequenceExpressionAttributeAccess) { SequenceExpressionAttributeAccess seqInAttribute = (SequenceExpressionAttributeAccess)(seqIn.ContainerExpr); string element = "((GRGEN_LIBGR.IGraphElement)" + GetVar(seqInAttribute.SourceVar) + ")"; container = element + ".GetAttribute(\"" + seqInAttribute.AttributeName + "\")"; ContainerType = seqInAttribute.Type(env); } else { container = GetSequenceExpression(seqIn.ContainerExpr, source); ContainerType = seqIn.ContainerExpr.Type(env); } if(ContainerType == "") { SourceBuilder sb = new SourceBuilder(); string sourceExpr = GetSequenceExpression(seqIn.Expr, source); string containerVar = "tmp_eval_once_" + seqIn.Id; source.AppendFront("object " + containerVar + " = null;\n"); sb.AppendFront("((" + containerVar + " = " + container + ") is IList ? "); string array = "((System.Collections.IList)" + containerVar + ")"; sb.AppendFront(array + ".Contains(" + sourceExpr + ")"); sb.AppendFront(" : "); sb.AppendFront(containerVar + " is GRGEN_LIBGR.IDeque ? "); string deque = "((GRGEN_LIBGR.IDeque)" + containerVar + ")"; sb.AppendFront(deque + ".Contains(" + sourceExpr + ")"); sb.AppendFront(" : "); string dictionary = "((System.Collections.IDictionary)" + containerVar + ")"; sb.AppendFront(dictionary + ".Contains(" + sourceExpr + ")"); sb.AppendFront(")"); return sb.ToString(); } else if(ContainerType.StartsWith("array")) { string array = container; string arrayValueType = TypesHelper.XgrsTypeToCSharpType(TypesHelper.ExtractSrc(ContainerType), model); string sourceExpr = "((" + arrayValueType + ")" + GetSequenceExpression(seqIn.Expr, source) + ")"; return array + ".Contains(" + sourceExpr + ")"; } else if(ContainerType.StartsWith("deque")) { string deque = container; string dequeValueType = TypesHelper.XgrsTypeToCSharpType(TypesHelper.ExtractSrc(ContainerType), model); string sourceExpr = "((" + dequeValueType + ")" + GetSequenceExpression(seqIn.Expr, source) + ")"; return deque + ".Contains(" + sourceExpr + ")"; } else { string dictionary = container; string dictSrcType = TypesHelper.XgrsTypeToCSharpType(TypesHelper.ExtractSrc(ContainerType), model); string sourceExpr = "((" + dictSrcType + ")" + GetSequenceExpression(seqIn.Expr, source) + ")"; return dictionary + ".ContainsKey(" + sourceExpr + ")"; } } case SequenceExpressionType.IsVisited: { SequenceExpressionIsVisited seqIsVisited = (SequenceExpressionIsVisited)expr; return "graph.IsVisited(" + "(GRGEN_LIBGR.IGraphElement)" + GetVar(seqIsVisited.GraphElementVar) + ", (int)" + GetSequenceExpression(seqIsVisited.VisitedFlagExpr, source) + ")"; } case SequenceExpressionType.Nodes: { SequenceExpressionNodes seqNodes = (SequenceExpressionNodes)expr; string nodeType = ExtractNodeType(source, seqNodes.NodeType); string profilingArgument = seqNodes.EmitProfiling ? ", procEnv" : ""; return "GRGEN_LIBGR.GraphHelper.Nodes(graph, (GRGEN_LIBGR.NodeType)" + nodeType + profilingArgument + ")"; } case SequenceExpressionType.Edges: { SequenceExpressionEdges seqEdges = (SequenceExpressionEdges)expr; string edgeType = ExtractEdgeType(source, seqEdges.EdgeType); string profilingArgument = seqEdges.EmitProfiling ? ", procEnv" : ""; return "GRGEN_LIBGR.GraphHelper.Edges(graph, (GRGEN_LIBGR.EdgeType)" + edgeType + profilingArgument + ")"; } case SequenceExpressionType.CountNodes: { SequenceExpressionCountNodes seqNodes = (SequenceExpressionCountNodes)expr; string nodeType = ExtractNodeType(source, seqNodes.NodeType); string profilingArgument = seqNodes.EmitProfiling ? ", procEnv" : ""; return "GRGEN_LIBGR.GraphHelper.CountNodes(graph, (GRGEN_LIBGR.NodeType)" + nodeType + profilingArgument + ")"; } case SequenceExpressionType.CountEdges: { SequenceExpressionCountEdges seqEdges = (SequenceExpressionCountEdges)expr; string edgeType = ExtractEdgeType(source, seqEdges.EdgeType); string profilingArgument = seqEdges.EmitProfiling ? ", procEnv" : ""; return "GRGEN_LIBGR.GraphHelper.CountEdges(graph, (GRGEN_LIBGR.EdgeType)" + edgeType + profilingArgument + ")"; } case SequenceExpressionType.Now: { SequenceExpressionNow seqNow = (SequenceExpressionNow)expr; return "DateTime.UtcNow.ToFileTime()"; } case SequenceExpressionType.Empty: { SequenceExpressionEmpty seqEmpty = (SequenceExpressionEmpty)expr; return "(graph.NumNodes+graph.NumEdges==0)"; } case SequenceExpressionType.Size: { SequenceExpressionSize seqSize = (SequenceExpressionSize)expr; return "(graph.NumNodes+graph.NumEdges)"; } case SequenceExpressionType.AdjacentNodes: case SequenceExpressionType.AdjacentNodesViaIncoming: case SequenceExpressionType.AdjacentNodesViaOutgoing: case SequenceExpressionType.IncidentEdges: case SequenceExpressionType.IncomingEdges: case SequenceExpressionType.OutgoingEdges: { SequenceExpressionAdjacentIncident seqAdjInc = (SequenceExpressionAdjacentIncident)expr; string sourceNode = GetSequenceExpression(seqAdjInc.SourceNode, source); string incidentEdgeType = ExtractEdgeType(source, seqAdjInc.EdgeType); string adjacentNodeType = ExtractNodeType(source, seqAdjInc.OppositeNodeType); string function; switch(seqAdjInc.SequenceExpressionType) { case SequenceExpressionType.AdjacentNodes: function = "Adjacent"; break; case SequenceExpressionType.AdjacentNodesViaIncoming: function = "AdjacentIncoming"; break; case SequenceExpressionType.AdjacentNodesViaOutgoing: function = "AdjacentOutgoing"; break; case SequenceExpressionType.IncidentEdges: function = "Incident"; break; case SequenceExpressionType.IncomingEdges: function = "Incoming"; break; case SequenceExpressionType.OutgoingEdges: function = "Outgoing"; break; default: function = "INTERNAL ERROR"; break; } string profilingArgument = seqAdjInc.EmitProfiling ? ", procEnv" : ""; return "GRGEN_LIBGR.GraphHelper." + function + "((GRGEN_LIBGR.INode)" + sourceNode + ", (GRGEN_LIBGR.EdgeType)" + incidentEdgeType + ", (GRGEN_LIBGR.NodeType)" + adjacentNodeType + profilingArgument + ")"; } case SequenceExpressionType.CountAdjacentNodes: case SequenceExpressionType.CountAdjacentNodesViaIncoming: case SequenceExpressionType.CountAdjacentNodesViaOutgoing: case SequenceExpressionType.CountIncidentEdges: case SequenceExpressionType.CountIncomingEdges: case SequenceExpressionType.CountOutgoingEdges: { SequenceExpressionCountAdjacentIncident seqCntAdjInc = (SequenceExpressionCountAdjacentIncident)expr; string sourceNode = GetSequenceExpression(seqCntAdjInc.SourceNode, source); string incidentEdgeType = ExtractEdgeType(source, seqCntAdjInc.EdgeType); string adjacentNodeType = ExtractNodeType(source, seqCntAdjInc.OppositeNodeType); string function; switch(seqCntAdjInc.SequenceExpressionType) { case SequenceExpressionType.CountAdjacentNodes: function = "CountAdjacent"; break; case SequenceExpressionType.CountAdjacentNodesViaIncoming: function = "CountAdjacentIncoming"; break; case SequenceExpressionType.CountAdjacentNodesViaOutgoing: function = "CountAdjacentOutgoing"; break; case SequenceExpressionType.CountIncidentEdges: function = "CountIncident"; break; case SequenceExpressionType.CountIncomingEdges: function = "CountIncoming"; break; case SequenceExpressionType.CountOutgoingEdges: function = "CountOutgoing"; break; default: function = "INTERNAL ERROR"; break; } string profilingArgument = seqCntAdjInc.EmitProfiling ? ", procEnv" : ""; if(seqCntAdjInc.SequenceExpressionType == SequenceExpressionType.CountAdjacentNodes || seqCntAdjInc.SequenceExpressionType == SequenceExpressionType.CountAdjacentNodesViaIncoming || seqCntAdjInc.SequenceExpressionType == SequenceExpressionType.CountAdjacentNodesViaOutgoing) { return "GRGEN_LIBGR.GraphHelper." + function + "(graph, (GRGEN_LIBGR.INode)" + sourceNode + ", (GRGEN_LIBGR.EdgeType)" + incidentEdgeType + ", (GRGEN_LIBGR.NodeType)" + adjacentNodeType + profilingArgument + ")"; } else // SequenceExpressionType.CountIncidentEdges || SequenceExpressionType.CountIncomingEdges || SequenceExpressionType.CountOutgoingEdges { return "GRGEN_LIBGR.GraphHelper." + function + "((GRGEN_LIBGR.INode)" + sourceNode + ", (GRGEN_LIBGR.EdgeType)" + incidentEdgeType + ", (GRGEN_LIBGR.NodeType)" + adjacentNodeType + profilingArgument + ")"; } } case SequenceExpressionType.ReachableNodes: case SequenceExpressionType.ReachableNodesViaIncoming: case SequenceExpressionType.ReachableNodesViaOutgoing: case SequenceExpressionType.ReachableEdges: case SequenceExpressionType.ReachableEdgesViaIncoming: case SequenceExpressionType.ReachableEdgesViaOutgoing: { SequenceExpressionReachable seqReach = (SequenceExpressionReachable)expr; string sourceNode = GetSequenceExpression(seqReach.SourceNode, source); string incidentEdgeType = ExtractEdgeType(source, seqReach.EdgeType); string adjacentNodeType = ExtractNodeType(source, seqReach.OppositeNodeType); string function; switch(seqReach.SequenceExpressionType) { case SequenceExpressionType.ReachableNodes: function = "Reachable"; break; case SequenceExpressionType.ReachableNodesViaIncoming: function = "ReachableIncoming"; break; case SequenceExpressionType.ReachableNodesViaOutgoing: function = "ReachableOutgoing"; break; case SequenceExpressionType.ReachableEdges: function = "ReachableEdges"; break; case SequenceExpressionType.ReachableEdgesViaIncoming: function = "ReachableEdgesIncoming"; break; case SequenceExpressionType.ReachableEdgesViaOutgoing: function = "ReachableEdgesOutgoing"; break; default: function = "INTERNAL ERROR"; break; } string profilingArgument = seqReach.EmitProfiling ? ", procEnv" : ""; if(seqReach.SequenceExpressionType == SequenceExpressionType.ReachableNodes || seqReach.SequenceExpressionType == SequenceExpressionType.ReachableNodesViaIncoming || seqReach.SequenceExpressionType == SequenceExpressionType.ReachableNodesViaOutgoing) { return "GRGEN_LIBGR.GraphHelper." + function + "((GRGEN_LIBGR.INode)" + sourceNode + ", (GRGEN_LIBGR.EdgeType)" + incidentEdgeType + ", (GRGEN_LIBGR.NodeType)" + adjacentNodeType + profilingArgument + ")"; } else // SequenceExpressionType.ReachableEdges || SequenceExpressionType.ReachableEdgesViaIncoming || SequenceExpressionType.ReachableEdgesViaOutgoing { return "GRGEN_LIBGR.GraphHelper." + function + "(graph, (GRGEN_LIBGR.INode)" + sourceNode + ", (GRGEN_LIBGR.EdgeType)" + incidentEdgeType + ", (GRGEN_LIBGR.NodeType)" + adjacentNodeType + profilingArgument + ")"; } } case SequenceExpressionType.CountReachableNodes: case SequenceExpressionType.CountReachableNodesViaIncoming: case SequenceExpressionType.CountReachableNodesViaOutgoing: case SequenceExpressionType.CountReachableEdges: case SequenceExpressionType.CountReachableEdgesViaIncoming: case SequenceExpressionType.CountReachableEdgesViaOutgoing: { SequenceExpressionCountReachable seqCntReach = (SequenceExpressionCountReachable)expr; string sourceNode = GetSequenceExpression(seqCntReach.SourceNode, source); string incidentEdgeType = ExtractEdgeType(source, seqCntReach.EdgeType); string adjacentNodeType = ExtractNodeType(source, seqCntReach.OppositeNodeType); string function; switch(seqCntReach.SequenceExpressionType) { case SequenceExpressionType.CountReachableNodes: function = "CountReachable"; break; case SequenceExpressionType.CountReachableNodesViaIncoming: function = "CountReachableIncoming"; break; case SequenceExpressionType.CountReachableNodesViaOutgoing: function = "CountReachableOutgoing"; break; case SequenceExpressionType.CountReachableEdges: function = "CountReachableEdges"; break; case SequenceExpressionType.CountReachableEdgesViaIncoming: function = "CountReachableEdgesIncoming"; break; case SequenceExpressionType.CountReachableEdgesViaOutgoing: function = "CountReachableEdgesOutgoing"; break; default: function = "INTERNAL ERROR"; break; } string profilingArgument = seqCntReach.EmitProfiling ? ", procEnv" : ""; if(seqCntReach.SequenceExpressionType == SequenceExpressionType.CountReachableNodes || seqCntReach.SequenceExpressionType == SequenceExpressionType.CountReachableNodesViaIncoming || seqCntReach.SequenceExpressionType == SequenceExpressionType.CountReachableNodesViaOutgoing) { return "GRGEN_LIBGR.GraphHelper." + function + "((GRGEN_LIBGR.INode)" + sourceNode + ", (GRGEN_LIBGR.EdgeType)" + incidentEdgeType + ", (GRGEN_LIBGR.NodeType)" + adjacentNodeType + profilingArgument + ")"; } else // SequenceExpressionType.CountReachableEdges || SequenceExpressionType.CountReachableEdgesViaIncoming || SequenceExpressionType.CountReachableEdgesViaOutgoing { return "GRGEN_LIBGR.GraphHelper." + function + "(graph, (GRGEN_LIBGR.INode)" + sourceNode + ", (GRGEN_LIBGR.EdgeType)" + incidentEdgeType + ", (GRGEN_LIBGR.NodeType)" + adjacentNodeType + profilingArgument + ")"; } } case SequenceExpressionType.BoundedReachableNodes: case SequenceExpressionType.BoundedReachableNodesViaIncoming: case SequenceExpressionType.BoundedReachableNodesViaOutgoing: case SequenceExpressionType.BoundedReachableEdges: case SequenceExpressionType.BoundedReachableEdgesViaIncoming: case SequenceExpressionType.BoundedReachableEdgesViaOutgoing: { SequenceExpressionBoundedReachable seqBoundReach = (SequenceExpressionBoundedReachable)expr; string sourceNode = GetSequenceExpression(seqBoundReach.SourceNode, source); string depth = GetSequenceExpression(seqBoundReach.Depth, source); string incidentEdgeType = ExtractEdgeType(source, seqBoundReach.EdgeType); string adjacentNodeType = ExtractNodeType(source, seqBoundReach.OppositeNodeType); string function; switch(seqBoundReach.SequenceExpressionType) { case SequenceExpressionType.BoundedReachableNodes: function = "BoundedReachable"; break; case SequenceExpressionType.BoundedReachableNodesViaIncoming: function = "BoundedReachableIncoming"; break; case SequenceExpressionType.BoundedReachableNodesViaOutgoing: function = "BoundedReachableOutgoing"; break; case SequenceExpressionType.BoundedReachableEdges: function = "BoundedReachableEdges"; break; case SequenceExpressionType.BoundedReachableEdgesViaIncoming: function = "BoundedReachableEdgesIncoming"; break; case SequenceExpressionType.BoundedReachableEdgesViaOutgoing: function = "BoundedReachableEdgesOutgoing"; break; default: function = "INTERNAL ERROR"; break; } string profilingArgument = seqBoundReach.EmitProfiling ? ", procEnv" : ""; if(seqBoundReach.SequenceExpressionType == SequenceExpressionType.BoundedReachableNodes || seqBoundReach.SequenceExpressionType == SequenceExpressionType.BoundedReachableNodesViaIncoming || seqBoundReach.SequenceExpressionType == SequenceExpressionType.BoundedReachableNodesViaOutgoing) { return "GRGEN_LIBGR.GraphHelper." + function + "((GRGEN_LIBGR.INode)" + sourceNode + ", (int)" + depth + ", (GRGEN_LIBGR.EdgeType)" + incidentEdgeType + ", (GRGEN_LIBGR.NodeType)" + adjacentNodeType + profilingArgument + ")"; } else // SequenceExpressionType.BoundedReachableEdges || SequenceExpressionType.BoundedReachableEdgesViaIncoming || SequenceExpressionType.BoundedReachableEdgesViaOutgoing { return "GRGEN_LIBGR.GraphHelper." + function + "(graph, (GRGEN_LIBGR.INode)" + sourceNode + ", (int)" + depth + ", (GRGEN_LIBGR.EdgeType)" + incidentEdgeType + ", (GRGEN_LIBGR.NodeType)" + adjacentNodeType + profilingArgument + ")"; } } case SequenceExpressionType.BoundedReachableNodesWithRemainingDepth: case SequenceExpressionType.BoundedReachableNodesWithRemainingDepthViaIncoming: case SequenceExpressionType.BoundedReachableNodesWithRemainingDepthViaOutgoing: { SequenceExpressionBoundedReachableWithRemainingDepth seqBoundReach = (SequenceExpressionBoundedReachableWithRemainingDepth)expr; string sourceNode = GetSequenceExpression(seqBoundReach.SourceNode, source); string depth = GetSequenceExpression(seqBoundReach.Depth, source); string incidentEdgeType = ExtractEdgeType(source, seqBoundReach.EdgeType); string adjacentNodeType = ExtractNodeType(source, seqBoundReach.OppositeNodeType); string function; switch(seqBoundReach.SequenceExpressionType) { case SequenceExpressionType.BoundedReachableNodesWithRemainingDepth: function = "BoundedReachableWithRemainingDepth"; break; case SequenceExpressionType.BoundedReachableNodesWithRemainingDepthViaIncoming: function = "BoundedReachableWithRemainingDepthIncoming"; break; case SequenceExpressionType.BoundedReachableNodesWithRemainingDepthViaOutgoing: function = "BoundedReachableWithRemainingDepthOutgoing"; break; default: function = "INTERNAL ERROR"; break; } string profilingArgument = seqBoundReach.EmitProfiling ? ", procEnv" : ""; return "GRGEN_LIBGR.GraphHelper." + function + "((GRGEN_LIBGR.INode)" + sourceNode + ", (int)" + depth + ", (GRGEN_LIBGR.EdgeType)" + incidentEdgeType + ", (GRGEN_LIBGR.NodeType)" + adjacentNodeType + profilingArgument + ")"; } case SequenceExpressionType.CountBoundedReachableNodes: case SequenceExpressionType.CountBoundedReachableNodesViaIncoming: case SequenceExpressionType.CountBoundedReachableNodesViaOutgoing: case SequenceExpressionType.CountBoundedReachableEdges: case SequenceExpressionType.CountBoundedReachableEdgesViaIncoming: case SequenceExpressionType.CountBoundedReachableEdgesViaOutgoing: { SequenceExpressionCountBoundedReachable seqCntBoundReach = (SequenceExpressionCountBoundedReachable)expr; string sourceNode = GetSequenceExpression(seqCntBoundReach.SourceNode, source); string depth = GetSequenceExpression(seqCntBoundReach.Depth, source); string incidentEdgeType = ExtractEdgeType(source, seqCntBoundReach.EdgeType); string adjacentNodeType = ExtractNodeType(source, seqCntBoundReach.OppositeNodeType); string function; switch(seqCntBoundReach.SequenceExpressionType) { case SequenceExpressionType.CountBoundedReachableNodes: function = "CountBoundedReachable"; break; case SequenceExpressionType.CountBoundedReachableNodesViaIncoming: function = "CountBoundedReachableIncoming"; break; case SequenceExpressionType.CountBoundedReachableNodesViaOutgoing: function = "CountBoundedReachableOutgoing"; break; case SequenceExpressionType.CountBoundedReachableEdges: function = "CountBoundedReachableEdges"; break; case SequenceExpressionType.CountBoundedReachableEdgesViaIncoming: function = "CountBoundedReachableEdgesIncoming"; break; case SequenceExpressionType.CountBoundedReachableEdgesViaOutgoing: function = "CountBoundedReachableEdgesOutgoing"; break; default: function = "INTERNAL ERROR"; break; } string profilingArgument = seqCntBoundReach.EmitProfiling ? ", procEnv" : ""; if(seqCntBoundReach.SequenceExpressionType == SequenceExpressionType.CountBoundedReachableNodes || seqCntBoundReach.SequenceExpressionType == SequenceExpressionType.CountBoundedReachableNodesViaIncoming || seqCntBoundReach.SequenceExpressionType == SequenceExpressionType.CountBoundedReachableNodesViaOutgoing) { return "GRGEN_LIBGR.GraphHelper." + function + "((GRGEN_LIBGR.INode)" + sourceNode + ", (int)" + depth + ", (GRGEN_LIBGR.EdgeType)" + incidentEdgeType + ", (GRGEN_LIBGR.NodeType)" + adjacentNodeType + profilingArgument + ")"; } else // SequenceExpressionType.CountBoundedReachableEdges || SequenceExpressionType.CountBoundedReachableEdgesViaIncoming || SequenceExpressionType.CountBoundedReachableEdgesViaOutgoing { return "GRGEN_LIBGR.GraphHelper." + function + "(graph, (GRGEN_LIBGR.INode)" + sourceNode + ", (int)" + depth + ", (GRGEN_LIBGR.EdgeType)" + incidentEdgeType + ", (GRGEN_LIBGR.NodeType)" + adjacentNodeType + profilingArgument + ")"; } } case SequenceExpressionType.IsAdjacentNodes: case SequenceExpressionType.IsAdjacentNodesViaIncoming: case SequenceExpressionType.IsAdjacentNodesViaOutgoing: case SequenceExpressionType.IsIncidentEdges: case SequenceExpressionType.IsIncomingEdges: case SequenceExpressionType.IsOutgoingEdges: { SequenceExpressionIsAdjacentIncident seqIsAdjInc = (SequenceExpressionIsAdjacentIncident)expr; string sourceNode = GetSequenceExpression(seqIsAdjInc.SourceNode, source); string endElement = GetSequenceExpression(seqIsAdjInc.EndElement, source); string endElementType; string incidentEdgeType = ExtractEdgeType(source, seqIsAdjInc.EdgeType); string adjacentNodeType = ExtractNodeType(source, seqIsAdjInc.OppositeNodeType); string function; switch(seqIsAdjInc.SequenceExpressionType) { case SequenceExpressionType.IsAdjacentNodes: function = "IsAdjacent"; endElementType = "(GRGEN_LIBGR.INode)"; break; case SequenceExpressionType.IsAdjacentNodesViaIncoming: function = "IsAdjacentIncoming"; endElementType = "(GRGEN_LIBGR.INode)"; break; case SequenceExpressionType.IsAdjacentNodesViaOutgoing: function = "IsAdjacentOutgoing"; endElementType = "(GRGEN_LIBGR.INode)"; break; case SequenceExpressionType.IsIncidentEdges: function = "IsIncident"; endElementType = "(GRGEN_LIBGR.IEdge)"; break; case SequenceExpressionType.IsIncomingEdges: function = "IsIncoming"; endElementType = "(GRGEN_LIBGR.IEdge)"; break; case SequenceExpressionType.IsOutgoingEdges: function = "IsOutgoing"; endElementType = "(GRGEN_LIBGR.IEdge)"; break; default: function = "INTERNAL ERROR"; endElementType = "INTERNAL ERROR"; break; } string profilingArgument = seqIsAdjInc.EmitProfiling ? ", procEnv" : ""; return "GRGEN_LIBGR.GraphHelper." + function + "((GRGEN_LIBGR.INode)" + sourceNode + ", " + endElementType + " " + endElement + ", (GRGEN_LIBGR.EdgeType)" + incidentEdgeType + ", (GRGEN_LIBGR.NodeType)" + adjacentNodeType + profilingArgument + ")"; } case SequenceExpressionType.IsReachableNodes: case SequenceExpressionType.IsReachableNodesViaIncoming: case SequenceExpressionType.IsReachableNodesViaOutgoing: case SequenceExpressionType.IsReachableEdges: case SequenceExpressionType.IsReachableEdgesViaIncoming: case SequenceExpressionType.IsReachableEdgesViaOutgoing: { SequenceExpressionIsReachable seqIsReach = (SequenceExpressionIsReachable)expr; string sourceNode = GetSequenceExpression(seqIsReach.SourceNode, source); string endElement = GetSequenceExpression(seqIsReach.EndElement, source); string endElementType; string incidentEdgeType = ExtractEdgeType(source, seqIsReach.EdgeType); string adjacentNodeType = ExtractNodeType(source, seqIsReach.OppositeNodeType); string function; switch(seqIsReach.SequenceExpressionType) { case SequenceExpressionType.IsReachableNodes: function = "IsReachable"; endElementType = "(GRGEN_LIBGR.INode)"; break; case SequenceExpressionType.IsReachableNodesViaIncoming: function = "IsReachableIncoming"; endElementType = "(GRGEN_LIBGR.INode)"; break; case SequenceExpressionType.IsReachableNodesViaOutgoing: function = "IsReachableOutgoing"; endElementType = "(GRGEN_LIBGR.INode)"; break; case SequenceExpressionType.IsReachableEdges: function = "IsReachableEdges"; endElementType = "(GRGEN_LIBGR.IEdge)"; break; case SequenceExpressionType.IsReachableEdgesViaIncoming: function = "IsReachableEdgesIncoming"; endElementType = "(GRGEN_LIBGR.IEdge)"; break; case SequenceExpressionType.IsReachableEdgesViaOutgoing: function = "IsReachableEdgesOutgoing"; endElementType = "(GRGEN_LIBGR.IEdge)"; break; default: function = "INTERNAL ERROR"; endElementType = "INTERNAL ERROR"; break; } string profilingArgument = seqIsReach.EmitProfiling ? ", procEnv" : ""; return "GRGEN_LIBGR.GraphHelper." + function + "(graph, (GRGEN_LIBGR.INode)" + sourceNode + ", " + endElementType + " " + endElement + ", (GRGEN_LIBGR.EdgeType)" + incidentEdgeType + ", (GRGEN_LIBGR.NodeType)" + adjacentNodeType + profilingArgument + ")"; } case SequenceExpressionType.IsBoundedReachableNodes: case SequenceExpressionType.IsBoundedReachableNodesViaIncoming: case SequenceExpressionType.IsBoundedReachableNodesViaOutgoing: case SequenceExpressionType.IsBoundedReachableEdges: case SequenceExpressionType.IsBoundedReachableEdgesViaIncoming: case SequenceExpressionType.IsBoundedReachableEdgesViaOutgoing: { SequenceExpressionIsBoundedReachable seqIsBoundReach = (SequenceExpressionIsBoundedReachable)expr; string sourceNode = GetSequenceExpression(seqIsBoundReach.SourceNode, source); string endElement = GetSequenceExpression(seqIsBoundReach.EndElement, source); string depth = GetSequenceExpression(seqIsBoundReach.Depth, source); string incidentEdgeType = ExtractEdgeType(source, seqIsBoundReach.EdgeType); string adjacentNodeType = ExtractNodeType(source, seqIsBoundReach.OppositeNodeType); string function; switch(seqIsBoundReach.SequenceExpressionType) { case SequenceExpressionType.IsBoundedReachableNodes: function = "IsBoundedReachable"; break; case SequenceExpressionType.IsBoundedReachableNodesViaIncoming: function = "IsBoundedReachableIncoming"; break; case SequenceExpressionType.IsBoundedReachableNodesViaOutgoing: function = "IsBoundedReachableOutgoing"; break; case SequenceExpressionType.IsBoundedReachableEdges: function = "IsBoundedReachableEdges"; break; case SequenceExpressionType.IsBoundedReachableEdgesViaIncoming: function = "IsBoundedReachableEdgesIncoming"; break; case SequenceExpressionType.IsBoundedReachableEdgesViaOutgoing: function = "IsBoundedReachableEdgesOutgoing"; break; default: function = "INTERNAL ERROR"; break; } string profilingArgument = seqIsBoundReach.EmitProfiling ? ", procEnv" : ""; if(seqIsBoundReach.SequenceExpressionType == SequenceExpressionType.IsBoundedReachableNodes || seqIsBoundReach.SequenceExpressionType == SequenceExpressionType.IsBoundedReachableNodesViaIncoming || seqIsBoundReach.SequenceExpressionType == SequenceExpressionType.IsBoundedReachableNodesViaOutgoing) { return "GRGEN_LIBGR.GraphHelper." + function + "(graph, (GRGEN_LIBGR.INode)" + sourceNode + ", (GRGEN_LIBGR.INode)" + endElement + ", (int)" + depth + ", (GRGEN_LIBGR.EdgeType)" + incidentEdgeType + ", (GRGEN_LIBGR.NodeType)" + adjacentNodeType + profilingArgument + ")"; } else // SequenceExpressionType.IsBoundedReachableEdges || SequenceExpressionType.IsBoundedReachableEdgesViaIncoming || SequenceExpressionType.IsBoundedReachableEdgesViaOutgoing { return "GRGEN_LIBGR.GraphHelper." + function + "(graph, (GRGEN_LIBGR.INode)" + sourceNode + ", (GRGEN_LIBGR.IEdge)" + endElement + ", (int)" + depth + ", (GRGEN_LIBGR.EdgeType)" + incidentEdgeType + ", (GRGEN_LIBGR.NodeType)" + adjacentNodeType + profilingArgument + ")"; } } case SequenceExpressionType.InducedSubgraph: { SequenceExpressionInducedSubgraph seqInduced = (SequenceExpressionInducedSubgraph)expr; return "GRGEN_LIBGR.GraphHelper.InducedSubgraph((IDictionary<GRGEN_LIBGR.INode, GRGEN_LIBGR.SetValueType>)" + GetSequenceExpression(seqInduced.NodeSet, source) + ", graph)"; } case SequenceExpressionType.DefinedSubgraph: { SequenceExpressionDefinedSubgraph seqDefined = (SequenceExpressionDefinedSubgraph)expr; return "GRGEN_LIBGR.GraphHelper.DefinedSubgraph((IDictionary<GRGEN_LIBGR.IEdge, GRGEN_LIBGR.SetValueType>)" + GetSequenceExpression(seqDefined.EdgeSet, source) + ", graph)"; } case SequenceExpressionType.EqualsAny: { SequenceExpressionEqualsAny seqEqualsAny = (SequenceExpressionEqualsAny)expr; if(seqEqualsAny.IncludingAttributes) return "GRGEN_LIBGR.GraphHelper.EqualsAny((GRGEN_LIBGR.IGraph)" + GetSequenceExpression(seqEqualsAny.Subgraph, source) + ", (IDictionary<GRGEN_LIBGR.IGraph, GRGEN_LIBGR.SetValueType>)" + GetSequenceExpression(seqEqualsAny.SubgraphSet, source) + ", true)"; else return "GRGEN_LIBGR.GraphHelper.EqualsAny((GRGEN_LIBGR.IGraph)" + GetSequenceExpression(seqEqualsAny.Subgraph, source) + ", (IDictionary<GRGEN_LIBGR.IGraph, GRGEN_LIBGR.SetValueType>)" + GetSequenceExpression(seqEqualsAny.SubgraphSet, source) + ", false)"; } case SequenceExpressionType.Nameof: { SequenceExpressionNameof seqNameof = (SequenceExpressionNameof)expr; if(seqNameof.NamedEntity != null) return "GRGEN_LIBGR.GraphHelper.Nameof(" + GetSequenceExpression(seqNameof.NamedEntity, source) + ", graph)"; else return "GRGEN_LIBGR.GraphHelper.Nameof(null, graph)"; } case SequenceExpressionType.Uniqueof: { SequenceExpressionUniqueof seqUniqueof = (SequenceExpressionUniqueof)expr; if(seqUniqueof.UniquelyIdentifiedEntity != null) return "GRGEN_LIBGR.GraphHelper.Uniqueof(" + GetSequenceExpression(seqUniqueof.UniquelyIdentifiedEntity, source) + ", graph)"; else return "GRGEN_LIBGR.GraphHelper.Uniqueof(null, graph)"; } case SequenceExpressionType.Typeof: { SequenceExpressionTypeof seqTypeof = (SequenceExpressionTypeof)expr; return "GRGEN_LIBGR.TypesHelper.XgrsTypeOfConstant(" + GetSequenceExpression(seqTypeof.Entity, source) + ", graph.Model)"; } case SequenceExpressionType.ExistsFile: { SequenceExpressionExistsFile seqExistsFile = (SequenceExpressionExistsFile)expr; return "System.IO.File.Exists((string)" + GetSequenceExpression(seqExistsFile.Path, source) + ")"; } case SequenceExpressionType.Import: { SequenceExpressionImport seqImport = (SequenceExpressionImport)expr; return "GRGEN_LIBGR.GraphHelper.Import(" + GetSequenceExpression(seqImport.Path, source) + ", graph)"; } case SequenceExpressionType.Copy: { SequenceExpressionCopy seqCopy = (SequenceExpressionCopy)expr; if(seqCopy.ObjectToBeCopied.Type(env)=="graph") return "GRGEN_LIBGR.GraphHelper.Copy((GRGEN_LIBGR.IGraph)(" + GetSequenceExpression(seqCopy.ObjectToBeCopied, source) + "))"; else if(seqCopy.ObjectToBeCopied.Type(env).StartsWith("set<")) return "new " + TypesHelper.XgrsTypeToCSharpType(seqCopy.ObjectToBeCopied.Type(env), model) + "((" + TypesHelper.XgrsTypeToCSharpType(seqCopy.ObjectToBeCopied.Type(env), model) + ")" + "(" + GetSequenceExpression(seqCopy.ObjectToBeCopied, source) + "))"; else if(seqCopy.ObjectToBeCopied.Type(env).StartsWith("map<")) return "new " + TypesHelper.XgrsTypeToCSharpType(seqCopy.ObjectToBeCopied.Type(env), model) + "((" + TypesHelper.XgrsTypeToCSharpType(seqCopy.ObjectToBeCopied.Type(env), model) + ")" + "(" + GetSequenceExpression(seqCopy.ObjectToBeCopied, source) + "))"; else if(seqCopy.ObjectToBeCopied.Type(env).StartsWith("array<")) return "new " + TypesHelper.XgrsTypeToCSharpType(seqCopy.ObjectToBeCopied.Type(env), model) + "((" + TypesHelper.XgrsTypeToCSharpType(seqCopy.ObjectToBeCopied.Type(env), model) + ")" + "(" + GetSequenceExpression(seqCopy.ObjectToBeCopied, source) + "))"; else if(seqCopy.ObjectToBeCopied.Type(env).StartsWith("deque<")) return "new " + TypesHelper.XgrsTypeToCSharpType(seqCopy.ObjectToBeCopied.Type(env), model) + "((" + TypesHelper.XgrsTypeToCSharpType(seqCopy.ObjectToBeCopied.Type(env), model) + ")" + "(" + GetSequenceExpression(seqCopy.ObjectToBeCopied, source) + "))"; else if(seqCopy.ObjectToBeCopied.Type(env).StartsWith("match<")) { string rulePatternClassName = "Rule_" + TypesHelper.ExtractSrc(seqCopy.ObjectToBeCopied.Type(env)); string matchInterfaceName = rulePatternClassName + "." + NamesOfEntities.MatchInterfaceName(TypesHelper.ExtractSrc(seqCopy.ObjectToBeCopied.Type(env))); return "((" + matchInterfaceName + ")(" + GetSequenceExpression(seqCopy.ObjectToBeCopied, source) + ").Clone())"; } else //if(seqCopy.ObjectToBeCopied.Type(env) == "") return "GRGEN_LIBGR.TypesHelper.Clone(" + GetSequenceExpression(seqCopy.ObjectToBeCopied, source) + ")"; } case SequenceExpressionType.Canonize: { SequenceExpressionCanonize seqCanonize = (SequenceExpressionCanonize)expr; return "((GRGEN_LIBGR.IGraph)" + GetSequenceExpression(seqCanonize.Graph, source) + ").Canonize()"; } case SequenceExpressionType.Random: { SequenceExpressionRandom seqRandom = (SequenceExpressionRandom)expr; if(seqRandom.UpperBound != null) return "GRGEN_LIBGR.Sequence.randomGenerator.Next((int)" + GetSequenceExpression(seqRandom.UpperBound, source) + ")"; else return "GRGEN_LIBGR.Sequence.randomGenerator.NextDouble()"; } case SequenceExpressionType.ContainerSize: { SequenceExpressionContainerSize seqContainerSize = (SequenceExpressionContainerSize)expr; string container = GetContainerValue(seqContainerSize, source); if(seqContainerSize.ContainerType(env) == "") { SourceBuilder sb = new SourceBuilder(); string containerVar = "tmp_eval_once_" + seqContainerSize.Id; source.AppendFront("object " + containerVar + " = null;\n"); sb.AppendFront("((" + containerVar + " = " + container + ") is IList ? "); string array = "((System.Collections.IList)" + containerVar + ")"; sb.AppendFront(array + ".Count"); sb.AppendFront(" : "); sb.AppendFront(containerVar + " is GRGEN_LIBGR.IDeque ? "); string deque = "((GRGEN_LIBGR.IDeque)" + containerVar + ")"; sb.AppendFront(deque + ".Count"); sb.AppendFront(" : "); string dictionary = "((System.Collections.IDictionary)" + containerVar + ")"; sb.AppendFront(dictionary + ".Count"); sb.AppendFront(")"); return sb.ToString(); } else if(seqContainerSize.ContainerType(env).StartsWith("array")) { string array = container; return array + ".Count"; } else if(seqContainerSize.ContainerType(env).StartsWith("deque")) { string deque = container; return deque + ".Count"; } else { string dictionary = container; return dictionary + ".Count"; } } case SequenceExpressionType.ContainerEmpty: { SequenceExpressionContainerEmpty seqContainerEmpty = (SequenceExpressionContainerEmpty)expr; string container = GetContainerValue(seqContainerEmpty, source); if(seqContainerEmpty.ContainerType(env) == "") { SourceBuilder sb = new SourceBuilder(); string containerVar = "tmp_eval_once_" + seqContainerEmpty.Id; source.AppendFront("object " + containerVar + " = null;\n"); sb.AppendFront("((" + containerVar + " = " + container + ") is IList ? "); string array = "((System.Collections.IList)" + containerVar + ")"; sb.AppendFront(array + ".Count==0"); sb.AppendFront(" : "); sb.AppendFront(containerVar + " is GRGEN_LIBGR.IDeque ? "); string deque = "((GRGEN_LIBGR.IDeque)" + containerVar + ")"; sb.AppendFront(deque + ".Count==0"); sb.AppendFront(" : "); string dictionary = "((System.Collections.IDictionary)" + containerVar + ")"; sb.AppendFront(dictionary + ".Count==0"); sb.AppendFront(")"); return sb.ToString(); } else if(seqContainerEmpty.ContainerType(env).StartsWith("array")) { string array = container; return "(" + array + ".Count==0)"; } else if(seqContainerEmpty.ContainerType(env).StartsWith("deque")) { string deque = container; return "(" + deque + ".Count==0)"; } else { string dictionary = container; return "(" + dictionary + ".Count==0)"; } } case SequenceExpressionType.ContainerAccess: { SequenceExpressionContainerAccess seqContainerAccess = (SequenceExpressionContainerAccess)expr; // todo: dst type unknownTypesHelper.ExtractSrc(seqMapAccessToVar.Setmap.Type) string container; string ContainerType; if(seqContainerAccess.ContainerExpr is SequenceExpressionAttributeAccess) { SequenceExpressionAttributeAccess seqContainerAttribute = (SequenceExpressionAttributeAccess)(seqContainerAccess.ContainerExpr); string element = "((GRGEN_LIBGR.IGraphElement)" + GetVar(seqContainerAttribute.SourceVar) + ")"; container = element + ".GetAttribute(\"" + seqContainerAttribute.AttributeName + "\")"; if(seqContainerAttribute.SourceVar.Type == "") ContainerType = ""; else { GrGenType nodeOrEdgeType = TypesHelper.GetNodeOrEdgeType(seqContainerAttribute.SourceVar.Type, env.Model); AttributeType attributeType = nodeOrEdgeType.GetAttributeType(seqContainerAttribute.AttributeName); ContainerType = TypesHelper.AttributeTypeToXgrsType(attributeType); } } else { container = GetSequenceExpression(seqContainerAccess.ContainerExpr, source); ContainerType = seqContainerAccess.ContainerExpr.Type(env); } if(ContainerType == "") { SourceBuilder sb = new SourceBuilder(); string sourceExpr = GetSequenceExpression(seqContainerAccess.KeyExpr, source); string containerVar = "tmp_eval_once_" + seqContainerAccess.Id; source.AppendFront("object " + containerVar + " = null;\n"); sb.AppendFront("((" + containerVar + " = " + container + ") is IList ? "); string array = "((System.Collections.IList)" + containerVar + ")"; if(!TypesHelper.IsSameOrSubtype(seqContainerAccess.KeyExpr.Type(env), "int", model)) { sb.AppendFront(array + "[-1]"); } else { sb.AppendFront(array + "[(int)" + sourceExpr + "]"); } sb.AppendFront(" : "); sb.AppendFront(containerVar + " is GRGEN_LIBGR.IDeque ? "); string deque = "((GRGEN_LIBGR.IDeque)" + containerVar + ")"; if(!TypesHelper.IsSameOrSubtype(seqContainerAccess.KeyExpr.Type(env), "int", model)) { sb.AppendFront(deque + "[-1]"); } else { sb.AppendFront(deque + "[(int)" + sourceExpr + "]"); } sb.AppendFront(" : "); string dictionary = "((System.Collections.IDictionary)" + containerVar + ")"; sb.AppendFront(dictionary + "[" + sourceExpr + "]"); sb.AppendFront(")"); return sb.ToString(); } else if(ContainerType.StartsWith("array")) { string array = container; string sourceExpr = "((int)" + GetSequenceExpression(seqContainerAccess.KeyExpr, source) + ")"; return array + "[" + sourceExpr + "]"; } else if(ContainerType.StartsWith("deque")) { string deque = container; string sourceExpr = "((int)" + GetSequenceExpression(seqContainerAccess.KeyExpr, source) + ")"; return deque + "[" + sourceExpr + "]"; } else { string dictionary = container; string dictSrcType = TypesHelper.XgrsTypeToCSharpType(TypesHelper.ExtractSrc(ContainerType), model); string sourceExpr = "((" + dictSrcType + ")" + GetSequenceExpression(seqContainerAccess.KeyExpr, source) + ")"; return dictionary + "[" + sourceExpr + "]"; } } case SequenceExpressionType.ContainerPeek: { SequenceExpressionContainerPeek seqContainerPeek = (SequenceExpressionContainerPeek)expr; string container = GetContainerValue(seqContainerPeek, source); if(seqContainerPeek.KeyExpr != null) { if(seqContainerPeek.ContainerType(env) == "") { return "GRGEN_LIBGR.ContainerHelper.Peek(" + container + ", (int)" + GetSequenceExpression(seqContainerPeek.KeyExpr, source) + ")"; } else if(seqContainerPeek.ContainerType(env).StartsWith("array")) { return container + "[(int)" + GetSequenceExpression(seqContainerPeek.KeyExpr, source) + "]"; } else if(seqContainerPeek.ContainerType(env).StartsWith("deque")) { return container + "[(int)" + GetSequenceExpression(seqContainerPeek.KeyExpr, source) + "]"; } else // statically known set/map/deque { return "GRGEN_LIBGR.ContainerHelper.Peek(" + container + ", (int)" + GetSequenceExpression(seqContainerPeek.KeyExpr, source) + ")"; } } else { if(seqContainerPeek.ContainerType(env).StartsWith("array")) { return container + "[" + container + ".Count - 1]"; } else if(seqContainerPeek.ContainerType(env).StartsWith("deque")) { return container + "[0]"; } else { return "GRGEN_LIBGR.ContainerHelper.Peek(" + container + ")"; } } } case SequenceExpressionType.Constant: { SequenceExpressionConstant seqConst = (SequenceExpressionConstant)expr; return GetConstant(seqConst.Constant); } case SequenceExpressionType.This: { SequenceExpressionThis seqThis = (SequenceExpressionThis)expr; return "graph"; } case SequenceExpressionType.SetConstructor: case SequenceExpressionType.ArrayConstructor: case SequenceExpressionType.DequeConstructor: { SequenceExpressionContainerConstructor seqConstr = (SequenceExpressionContainerConstructor)expr; StringBuilder sb = new StringBuilder(); sb.Append("fillFromSequence_" + seqConstr.Id); sb.Append("("); for(int i = 0; i < seqConstr.ContainerItems.Length; ++i) { if(i > 0) sb.Append(", "); sb.Append("("); sb.Append(TypesHelper.XgrsTypeToCSharpType(seqConstr.ValueType, model)); sb.Append(")"); sb.Append("("); sb.Append(GetSequenceExpression(seqConstr.ContainerItems[i], source)); sb.Append(")"); } sb.Append(")"); return sb.ToString(); } case SequenceExpressionType.MapConstructor: { SequenceExpressionMapConstructor seqConstr = (SequenceExpressionMapConstructor)expr; StringBuilder sb = new StringBuilder(); sb.Append("fillFromSequence_" + seqConstr.Id); sb.Append("("); for(int i = 0; i < seqConstr.ContainerItems.Length; ++i) { if(i > 0) sb.Append(", "); sb.Append("("); sb.Append(TypesHelper.XgrsTypeToCSharpType(seqConstr.KeyType, model)); sb.Append(")"); sb.Append("("); sb.Append(GetSequenceExpression(seqConstr.MapKeyItems[i], source)); sb.Append("), "); sb.Append("("); sb.Append(TypesHelper.XgrsTypeToCSharpType(seqConstr.ValueType, model)); sb.Append(")"); sb.Append("("); sb.Append(GetSequenceExpression(seqConstr.ContainerItems[i], source)); sb.Append(")"); } sb.Append(")"); return sb.ToString(); } case SequenceExpressionType.GraphElementAttribute: { SequenceExpressionAttributeAccess seqAttr = (SequenceExpressionAttributeAccess)expr; string element = "((GRGEN_LIBGR.IGraphElement)" + GetVar(seqAttr.SourceVar) + ")"; string value = element + ".GetAttribute(\"" + seqAttr.AttributeName + "\")"; return "GRGEN_LIBGR.ContainerHelper.IfAttributeOfElementIsContainerThenCloneContainer(" + element + ", \"" + seqAttr.AttributeName + "\", " + value + ")"; } case SequenceExpressionType.ElementOfMatch: { SequenceExpressionMatchAccess seqMA = (SequenceExpressionMatchAccess)expr; String rulePatternClassName = "Rule_" + TypesHelper.ExtractSrc(seqMA.SourceVar.Type); String matchInterfaceName = rulePatternClassName + "." + NamesOfEntities.MatchInterfaceName(TypesHelper.ExtractSrc(seqMA.SourceVar.Type)); string match = "((" + matchInterfaceName + ")" + GetVar(seqMA.SourceVar) + ")"; if(TypesHelper.GetNodeType(seqMA.Type(env), model) != null) return match + ".node_" + seqMA.ElementName; else if(TypesHelper.GetNodeType(seqMA.Type(env), model) != null) return match + ".edge_" + seqMA.ElementName; else return match + ".var_" + seqMA.ElementName; } case SequenceExpressionType.ElementFromGraph: { SequenceExpressionElementFromGraph seqFromGraph = (SequenceExpressionElementFromGraph)expr; string profilingArgument = seqFromGraph.EmitProfiling ? ", procEnv" : ""; return "GRGEN_LIBGR.GraphHelper.GetGraphElement((GRGEN_LIBGR.INamedGraph)graph, \"" + seqFromGraph.ElementName + "\"" + profilingArgument + ")"; } case SequenceExpressionType.NodeByName: { SequenceExpressionNodeByName seqNodeByName = (SequenceExpressionNodeByName)expr; string profilingArgument = seqNodeByName.EmitProfiling ? ", procEnv" : ""; return "GRGEN_LIBGR.GraphHelper.GetNode((GRGEN_LIBGR.INamedGraph)graph, (string)" + GetSequenceExpression(seqNodeByName.NodeName, source) + profilingArgument + ")"; } case SequenceExpressionType.EdgeByName: { SequenceExpressionEdgeByName seqEdgeByName = (SequenceExpressionEdgeByName)expr; string profilingArgument = seqEdgeByName.EmitProfiling ? ", procEnv" : ""; return "GRGEN_LIBGR.GraphHelper.GetEdge((GRGEN_LIBGR.INamedGraph)graph, (string)" + GetSequenceExpression(seqEdgeByName.EdgeName, source) + profilingArgument + ")"; } case SequenceExpressionType.NodeByUnique: { SequenceExpressionNodeByUnique seqNodeByUnique = (SequenceExpressionNodeByUnique)expr; string profilingArgument = seqNodeByUnique.EmitProfiling ? ", procEnv" : ""; return "GRGEN_LIBGR.GraphHelper.GetNode(graph, (int)" + GetSequenceExpression(seqNodeByUnique.NodeUniqueId, source) + profilingArgument + ")"; } case SequenceExpressionType.EdgeByUnique: { SequenceExpressionEdgeByUnique seqEdgeByUnique = (SequenceExpressionEdgeByUnique)expr; string profilingArgument = seqEdgeByUnique.EmitProfiling ? ", procEnv" : ""; return "GRGEN_LIBGR.GraphHelper.GetEdge(graph, (int)" + GetSequenceExpression(seqEdgeByUnique.EdgeUniqueId, source) + profilingArgument + ")"; } case SequenceExpressionType.Source: { SequenceExpressionSource seqSrc = (SequenceExpressionSource)expr; return "((GRGEN_LIBGR.IEdge)" + GetSequenceExpression(seqSrc.Edge, source) + ").Source"; } case SequenceExpressionType.Target: { SequenceExpressionTarget seqTgt = (SequenceExpressionTarget)expr; return "((GRGEN_LIBGR.IEdge)" + GetSequenceExpression(seqTgt.Edge, source) + ").Target"; } case SequenceExpressionType.Opposite: { SequenceExpressionOpposite seqOpp = (SequenceExpressionOpposite)expr; return "((GRGEN_LIBGR.IEdge)" + GetSequenceExpression(seqOpp.Edge, source) + ").Opposite((GRGEN_LIBGR.INode)(" + GetSequenceExpression(seqOpp.Node, source) + "))"; } case SequenceExpressionType.Variable: { SequenceExpressionVariable seqVar = (SequenceExpressionVariable)expr; return GetVar(seqVar.Variable); } case SequenceExpressionType.FunctionCall: { SequenceExpressionFunctionCall seqFuncCall = (SequenceExpressionFunctionCall)expr; StringBuilder sb = new StringBuilder(); if(seqFuncCall.IsExternalFunctionCalled) sb.Append("GRGEN_EXPR.ExternalFunctions."); else sb.AppendFormat("GRGEN_ACTIONS.{0}Functions.", TypesHelper.GetPackagePrefixDot(seqFuncCall.ParamBindings.Package)); sb.Append(seqFuncCall.ParamBindings.Name); sb.Append("(procEnv, graph"); sb.Append(BuildParameters(seqFuncCall.ParamBindings)); sb.Append(")"); return sb.ToString(); } case SequenceExpressionType.FunctionMethodCall: { SequenceExpressionFunctionMethodCall seqFuncCall = (SequenceExpressionFunctionMethodCall)expr; StringBuilder sb = new StringBuilder(); if(seqFuncCall.TargetExpr.Type(env) == "") { sb.Append("((GRGEN_LIBGR.IGraphElement)"); sb.Append(GetSequenceExpression(seqFuncCall.TargetExpr, source)); sb.Append(").ApplyFunctionMethod(procEnv, graph, "); sb.Append("\"" + seqFuncCall.ParamBindings.Name+ "\""); sb.Append(BuildParametersInObject(seqFuncCall.ParamBindings)); sb.Append(")"); } else { sb.Append("(("); sb.Append(TypesHelper.XgrsTypeToCSharpType(seqFuncCall.TargetExpr.Type(env), model)); sb.Append(")"); sb.Append(GetSequenceExpression(seqFuncCall.TargetExpr, source)); sb.Append(")."); sb.Append(seqFuncCall.ParamBindings.Name); sb.Append("(procEnv, graph"); sb.Append(BuildParameters(seqFuncCall.ParamBindings, TypesHelper.GetNodeOrEdgeType(seqFuncCall.TargetExpr.Type(env), model).GetFunctionMethod(seqFuncCall.ParamBindings.Name))); sb.Append(")"); } return sb.ToString(); } default: throw new Exception("Unknown sequence expression type: " + expr.SequenceExpressionType); } }
public override string ToString() { SourceBuilder sb = new SourceBuilder(); Expr.Emit(sb); return "unique[" + sb.ToString() + "]"; }
private static void BuildInterpretationPlan(LGSPGraph graph) { LGSPMatcherGenerator matcherGen = new LGSPMatcherGenerator(graph.Model); graph.matchingState.patternGraph = matcherGen.BuildPatternGraph(graph); PlanGraph planGraph = matcherGen.GeneratePlanGraph(graph.statistics, graph.matchingState.patternGraph, false, false, new Dictionary<PatternElement, SetValueType>()); matcherGen.MarkMinimumSpanningArborescence(planGraph, graph.matchingState.patternGraph.name); SearchPlanGraph searchPlanGraph = matcherGen.GenerateSearchPlanGraph(planGraph); ScheduledSearchPlan scheduledSearchPlan = matcherGen.ScheduleSearchPlan( searchPlanGraph, graph.matchingState.patternGraph, false); InterpretationPlanBuilder builder = new InterpretationPlanBuilder(scheduledSearchPlan, searchPlanGraph, graph.Model); graph.matchingState.interpretationPlan = builder.BuildInterpretationPlan("ComparisonMatcher_" + graph.graphID); ++GraphMatchingState.numInterpretationPlans; graph.matchingState.changesCounterAtInterpretationPlanBuilding = graph.changesCounterAtLastAnalyze; Debug.Assert(graph.changesCounterAtLastAnalyze == graph.ChangesCounter); #if LOG_ISOMORPHY_CHECKING SourceBuilder sb = new SourceBuilder(); graph.matchingState.interpretationPlan.Dump(sb); writer.WriteLine(); writer.WriteLine(sb.ToString()); writer.WriteLine(); writer.Flush(); #endif }