コード例 #1
0
        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
        }
コード例 #2
0
ファイル: ScheduleDumper.cs プロジェクト: tmaierhofer/grgen
        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();
        }
コード例 #3
0
        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;
        }
コード例 #4
0
 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 + ")";
 }
コード例 #5
0
ファイル: lgspActions.cs プロジェクト: jblomer/GrGen.NET
        /// <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)");
        }
コード例 #6
0
        /// <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;
        }
コード例 #7
0
        /// <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;
        }
コード例 #8
0
        /// <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;
        }
コード例 #9
0
        /// <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);
        }
コード例 #10
0
        /// <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;
        }
コード例 #11
0
        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;
        }
コード例 #12
0
        /// <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;
        }
コード例 #13
0
        /// <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;
        }
コード例 #14
0
        /// <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;
        }
コード例 #15
0
        /// <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;
        }
コード例 #16
0
        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;
                }
            }*/
        }
コード例 #17
0
        /// <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;
        }
コード例 #18
0
        /// <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;
        }
コード例 #19
0
        /// <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;
        }
コード例 #20
0
        /// <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;
        }
コード例 #21
0
ファイル: lgspGrGen.cs プロジェクト: jblomer/GrGen.NET
        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);
        }
コード例 #22
0
ファイル: lgspActions.cs プロジェクト: GunterMueller/grgen
        /// <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);
            }
        }
コード例 #23
0
ファイル: lgspGrGen.cs プロジェクト: jblomer/GrGen.NET
        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;
        }
コード例 #24
0
        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;
        }
コード例 #25
0
  		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);
			}
		}
コード例 #26
0
 public override string ToString()
 {
     SourceBuilder sb = new SourceBuilder();
     Expr.Emit(sb);
     return Index.Name + "==" + sb.ToString();
 }
コード例 #27
0
        // 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);
            }
        }
コード例 #28
0
 public override string ToString()
 {
     SourceBuilder sb = new SourceBuilder();
     Expr.Emit(sb);
     return "unique[" + sb.ToString() + "]";
 }
コード例 #29
0
        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
        }