void DoIdpt()
        {
            graph = new LGSPGraph(new IndependentGraphModel());
            actions = new IndependentActions(graph);
            procEnv = new LGSPGraphProcessingEnvironment(graph, actions);

            procEnv.ApplyGraphRewriteSequence("create");

			Console.WriteLine(procEnv.PerformanceInfo.MatchesFound + " matches found.");
			Console.WriteLine(procEnv.PerformanceInfo.RewritesPerformed + " rewrites performed.");
			procEnv.PerformanceInfo.Reset();

            IMatches matches = actions.GetAction("findIndependent").Match(procEnv, 0, null);
            Console.WriteLine(matches.Count + " matches found.");

            graph.Clear();

            procEnv.ApplyGraphRewriteSequence("createIterated");

            Console.WriteLine(procEnv.PerformanceInfo.MatchesFound + " matches found.");
            Console.WriteLine(procEnv.PerformanceInfo.RewritesPerformed + " rewrites performed.");
            procEnv.PerformanceInfo.Reset();

            IAction_createIterated createIterated = actions.createIterated;
            IMatchesExact<Rule_createIterated.IMatch_createIterated> matchesCreateIterated = 
                createIterated.Match(procEnv, 0);
            IintNode beg;
            INode end;
            createIterated.Modify(procEnv, matchesCreateIterated.FirstExact, out beg, out end);

            IMatchesExact<Rule_findChainPlusChainToIntIndependent.IMatch_findChainPlusChainToIntIndependent> matchesFindChain =
                actions.findChainPlusChainToIntIndependent.Match(procEnv, 0, beg, end);
            Console.WriteLine(matchesFindChain.Count + " matches found.");
        }
Beispiel #2
0
        public static void Main(string[] args)
        {
            LGSPNamedGraph graph;
            LGSPActions actions;
            LGSPGraphProcessingEnvironment procEnv;

            try
            {
                new LGSPBackend().CreateNamedFromSpec("Mutex.grg", null, 0, out graph, out actions);
                procEnv = new LGSPGraphProcessingEnvironment(graph, actions);
            }
            catch(Exception ex)
            {
                Console.WriteLine("Unable to create graph from specification: " + ex.Message);
                return;
            }

            DumpInfo dumpInfo = new DumpInfo(graph.GetElementName);
            YCompClient ycomp = YCompClient.CreateYCompClient(graph, "Organic", dumpInfo);

            // Let yComp observe any changes to the graph
            ycomp.RegisterLibGrEvents();

            NodeType processType = graph.GetNodeType("Process");
            EdgeType nextType = graph.GetEdgeType("next");

            LGSPNode p1 = graph.AddLGSPNode(processType);
            LGSPNode p2 = graph.AddLGSPNode(processType);
            graph.AddEdge(nextType, p1, p2);
            graph.AddEdge(nextType, p2, p1);
            PrintAndWait("Initial 2-process ring constructed.", ycomp);

            procEnv.ApplyGraphRewriteSequence("newRule[5] && mountRule && requestRule[7]");
            PrintAndWait("Initialized 7-process ring with resource and requests.", ycomp);

            ycomp.UnregisterLibGrEvents();
            Console.WriteLine("Do many changes slowing down too much with YComp (not in this example)...");
            procEnv.ApplyGraphRewriteSequence("(takeRule && releaseRule && giveRule)*");
            PrintAndWait("Nothing changed so far on the display.", ycomp);

            ycomp.ClearGraph();
            UploadGraph(graph, ycomp);
            PrintAndWait("Graph newly uploaded to yComp.", ycomp);

            ycomp.RegisterLibGrEvents();

            actions.GetAction("newRule").ApplyMinMax(procEnv, 4, 4);
            PrintAndWait("Added 4 processes in the ring.", ycomp);

            ycomp.Close();
        }
        // Have a look at the .gm + .grg, the ExternalFiltersAndSequencesActionsExternalFunctions.cs,
        // and the ExternalFiltersAndSequencesActionsExternalFunctionsImpl.cs files.
        // They show how to declare external match filters and external sequences in the rules file, 
        // and how to use them in the sequences in the rule file or the shell script file.
        // The generated XXXExternalFunctions.cs file contains the partial classes of the filters and sequences
        // and the manually coded XXXExternalFunctionsImpl.cs file exemplifies how to implement these external functions.
        void DoEFS()
        {
            graph = new ExternalFiltersAndSequencesGraph();
            actions = new ExternalFiltersAndSequencesActions(graph);
            procEnv = new LGSPGraphProcessingEnvironment(graph, actions);

            // use graph rewrite sequence
            procEnv.ApplyGraphRewriteSequence("(::n)=init");

            Console.WriteLine(procEnv.PerformanceInfo.MatchesFound + " matches found.");
            Console.WriteLine(procEnv.PerformanceInfo.RewritesPerformed + " rewrites performed.");
            procEnv.PerformanceInfo.Reset();

            // use new 2.5 exact interface
            IMatchesExact<Rule_r.IMatch_r> matchesExact = actions.r.Match(procEnv, 0);
            Console.WriteLine(matchesExact.Count + " matches found.");
            actions.r.Modify(procEnv, matchesExact.FirstExact);

            procEnv.ApplyGraphRewriteSequence("(::x,::y,::z,::u,::v)=foo(42, 3.141, Enu::hurz, \"S21-heiteitei\", true)");
            procEnv.ApplyGraphRewriteSequence("filterBase\\f1");
        }
        // Have a look at the .gm + .grg, the ExternalAttributeEvaluationModelExternalFunctions.cs,
        // and the ExternalAttributeEvaluationModelExternalFunctionsImpl.cs files.
        // They show how to declare external classes and actions in the model file, 
        // and how to use them in the attribute calculations in the rule file.
        // The generated XXXExternalFunctions.cs file contains the partial classes of the data types and functions
        // and the manually coded XXXExternalFunctionsImpl.cs file exemplifies how to implement these external functions.
        void DoEAE()
        {
            graph = new ExternalAttributeEvaluationGraph();
            actions = new ExternalAttributeEvaluationActions(graph);
            procEnv = new LGSPGraphProcessingEnvironment(graph, actions);

            // use graph rewrite sequence
            procEnv.ApplyGraphRewriteSequence("init");

            Console.WriteLine(procEnv.PerformanceInfo.MatchesFound + " matches found.");
            Console.WriteLine(procEnv.PerformanceInfo.RewritesPerformed + " rewrites performed.");
            procEnv.PerformanceInfo.Reset();

            // use new 2.5 exact interface
            IMatchesExact<Rule_r.IMatch_r> matchesExact = actions.r.Match(procEnv, 0);
            Console.WriteLine(matchesExact.Count + " matches found.");
            actions.r.Modify(procEnv, matchesExact.FirstExact);
        }
Beispiel #5
0
        void DoTNT()
        {
            graph = new LGSPGraph(new TNTGraphModel());
            actions = new TNTActions(graph);
            procEnv = new LGSPGraphProcessingEnvironment(graph, actions);

            // use graph rewrite sequence
            procEnv.ApplyGraphRewriteSequence("createTNT");

            Console.WriteLine(procEnv.PerformanceInfo.MatchesFound + " matches found.");
            Console.WriteLine(procEnv.PerformanceInfo.RewritesPerformed + " rewrites performed.");
            procEnv.PerformanceInfo.Reset();

            // use old inexact interface
            IMatches matchesInexact = actions.GetAction("TNT").Match(procEnv, 0, null);
            Console.WriteLine(matchesInexact.Count + " matches found.");

            // use new 2.5 exact interface
            IMatchesExact<Rule_ToluolCore.IMatch_ToluolCore> matchesExact = actions.ToluolCore.Match(procEnv, 0);
            Console.WriteLine(matchesExact.Count + " matches found.");
        }
        void DoAlt()
        {
            graph = new LGSPGraph(new AlternativesGraphModel());
            actions = new AlternativesActions(graph);
            procEnv = new LGSPGraphProcessingEnvironment(graph, actions);

            // use graph rewrite sequence
            procEnv.ApplyGraphRewriteSequence("createComplex");

            Console.WriteLine(procEnv.PerformanceInfo.MatchesFound + " matches found.");
            Console.WriteLine(procEnv.PerformanceInfo.RewritesPerformed + " rewrites performed.");
            procEnv.PerformanceInfo.Reset();

            // use old inexact interface
            IMatches matches = actions.GetAction("Complex").Match(procEnv, 0, null);
            Console.WriteLine(matches.Count + " Complex matches found.");

            // use new 2.5 exact interface
            IMatchesExact<Rule_ComplexMax.IMatch_ComplexMax> matchesExact = actions.ComplexMax.Match(procEnv, 0);
            Console.WriteLine(matchesExact.Count + " ComplexMax matches found.");
        }
Beispiel #7
0
    static void Main(string[] args)
    {
        LGSPNamedGraph graph;
        LGSPActions actions;

        new LGSPBackend().CreateNamedFromSpec("Mutex.grg", null, 0, out graph, out actions);

        LGSPGraphProcessingEnvironment procEnv = new LGSPGraphProcessingEnvironment(graph, actions);

        NodeType processType = graph.GetNodeType("Process");
        EdgeType nextType = graph.GetEdgeType("next");

        INode p1 = graph.AddNode(processType);
        INode p2 = graph.AddNode(processType);
        graph.AddEdge(nextType, p1, p2);
        graph.AddEdge(nextType, p2, p1);

        procEnv.ApplyGraphRewriteSequence("newRule[3] && mountRule && requestRule[5] "
            + "&& (takeRule && releaseRule && giveRule)*");

        using(VCGDumper dumper = new VCGDumper("HelloMutex.vcg"))
            GraphDumper.Dump(graph, dumper);
    }
Beispiel #8
0
        void DoEdge1()
        {
            graph = new StdGraph();
            actions = new edge1Actions(graph);
            procEnv = new LGSPGraphProcessingEnvironment(graph, actions);

            // use graph rewrite sequence
            procEnv.ApplyGraphRewriteSequence("init3");

			Console.WriteLine(procEnv.PerformanceInfo.MatchesFound + " matches found.");
            Console.WriteLine(procEnv.PerformanceInfo.RewritesPerformed + " rewrites performed.");
            procEnv.PerformanceInfo.Reset();

            // use old inexact interface
            IMatches matches = actions.GetAction("findTripleCircle").Match(procEnv, 0, null);
            Console.WriteLine(matches.Count + " matches found.");

            // use new exact interface
            IMatchesExact<Rule_findTripleCircle.IMatch_findTripleCircle> matchesExact =
                actions.findTripleCircle.Match(procEnv, 0);
            Console.WriteLine(matchesExact.Count + " matches found.");
            actions.findTripleCircle.Modify(procEnv, matchesExact.FirstExact); // rewrite first match (largely nop, as findTripleCircle is a test)
        }
        void DoIt()
        {
            // create the LibGr Search Plan backend we want to use
            LGSPBackend backend = new LGSPBackend();

            // the graph model we'll use
            JavaProgramGraphsGraphModel model = new JavaProgramGraphsGraphModel();

            // the actions object for the rules we'll to use
            IActions ba;

            // import the instance graph we created with gxl2grs, using the the .gm we created by hand
            // (can't use import gxl for the program graph, because the given .gxl is severly rotten)
            // we throw away the named graph cause we don't need names here and they require about the same amount of memory as the graph itself; 
            INamedGraph importedNamedGraph = (INamedGraph)Porter.Import("InstanceGraph.grs", backend, model, out ba);
            LGSPGraph graph = new LGSPGraph((LGSPNamedGraph)importedNamedGraph, "unnamed");
            importedNamedGraph = null;
            
            // get the actions object for the rules we want to use
            JavaProgramGraphsActions actions = ba!=null ? (JavaProgramGraphsActions)ba : new JavaProgramGraphsActions(graph);

            // the graph processing environment we'll use
            LGSPGraphProcessingEnvironment procEnv = new LGSPGraphProcessingEnvironment(graph, actions);

            // the instance graph script uses variables to build up the graph,
            // we query some of them here, to get the elements to refactor
            // (instead of variables one could use the element names)
            Class src = (Class)procEnv.GetNodeVarValue("I176"); // class Node
            Class tgt = (Class)procEnv.GetNodeVarValue("I194"); // class Packet - use if parameter is used in moving method
            //Class tgt = (Class)graph.GetNodeVarValue("I617"); // class String - use if instance variable is used in moving method
            MethodBody mb = (MethodBody)procEnv.GetNodeVarValue("I409"); // method body of send

            // get operation for method body by: 
            // get action, match action pattern with given parameters, apply rewrite filling given out parameters
            IMatchesExact<Rule_getOperation.IMatch_getOperation> matches = actions.getOperation.Match(procEnv, 1, mb);
            IOperation op;
            actions.getOperation.Modify(procEnv, matches.FirstExact, out op);

            // iterated application of action marking the body of the expression
            // (shows second way of getting action)
            int visitedFlagId = graph.AllocateVisitedFlag();
            Debug.Assert(visitedFlagId==0);
            IGraphElement[] param = new LGSPNode[1];
            param[0] = mb;
            IMatches matchesInexact;
            while((matchesInexact = actions.GetAction("markExpressionOfBody").Match(procEnv, 1, param)).Count == 1)
            {
                actions.GetAction("markExpressionOfBody").Modify(procEnv, matchesInexact.First);
            }

            // application of a graph rewrite sequence
            procEnv.SetVariableValue("src", src);
            procEnv.SetVariableValue("tgt", tgt);
            procEnv.SetVariableValue("mb", mb);
            procEnv.SetVariableValue("op", op);
            procEnv.ApplyGraphRewriteSequence(
                @"(p)=someParameterOfTargetType(mb,tgt) 
                    && !callToSuperExists && !isStatic(mb) && !methodNameExists(mb,tgt) 
                    && (!thisIsAccessed || thisIsAccessed && (srcparam)=addSourceParameter(op,src) && useSourceParameter(srcparam)*) 
                    && relinkOperationAndMethodBody(op,mb,src,tgt) 
                    && ( (call,pe)=getUnprocessedCallWithActualParameter(op,p) 
                         && ((def(srcparam) && addSourceToCall(call,srcparam)) || true) 
                         && (replaceAccess_Parameter_AccessWithoutLink(c,pe) || replaceAccess_Parameter_AccessWithLinkToExpression(c,pe)) 
                       )*");

            Console.WriteLine(procEnv.PerformanceInfo.MatchesFound + " matches found.");
            procEnv.PerformanceInfo.Reset();

            // unmark the body of the expression by searching all occurences and modifying them
            actions.unmarkExpression.ApplyAll(0, procEnv);
            graph.FreeVisitedFlag(visitedFlagId);

            // export changed graph (alternatively you may export it as InstanceGraphAfter.gxl)
            // if we'd use a NamedGraph we'd get the graph exported with its persistent names; so we get it exported with some hash names
            List<String> exportParameters = new List<string>();
            exportParameters.Add("InstanceGraphAfter.grs");
            Porter.Export(graph, exportParameters);
        }
Beispiel #10
0
        /// <summary>
        /// Executes the Mutex benchmark with a problem size of n.
        /// This variant uses BaseActions.ApplyGraphRewriteSequence.
        /// Although this provides the fastest way to program rule applications
        /// for simple scenarios, it needs aprox. 12% more running time than
        /// via Apply or Match/Modify.
        /// </summary>
        /// <param name="n">The problem size, i.e. the number of Process nodes</param>
        static void AlternativeThree(int n)
        {
            int startTime = Environment.TickCount;

			MutexGraph graph = new MutexGraph();
			MutexPimpedActions actions = new MutexPimpedActions(graph);
            LGSPGraphProcessingEnvironment procEnv = new LGSPGraphProcessingEnvironment(graph, actions);

			LGSPNode p1 = graph.CreateNodeProcess();
			LGSPNode p2 = graph.CreateNodeProcess();
			LGSPEdge n1 = graph.CreateEdgenext(p1, p2);
			LGSPEdge n2 = graph.CreateEdgenext(p2, p1);

            procEnv.ApplyGraphRewriteSequence("newRule[" + (n - 2) + "] && mountRule && requestRule[" + n
                + "] && (takeRule && releaseRule && giveRule)[" + n + "]");

            int endTime = Environment.TickCount;

            PrintResults(endTime - startTime, graph);
        }
Beispiel #11
0
        void DoBusyBeaver()
        {
            long startBytes = System.GC.GetTotalMemory(true);
            int startTime = Environment.TickCount;

            graph = new Turing3Graph();
            actions = new Turing3Actions(graph);
            procEnv = new LGSPGraphProcessingEnvironment(graph, actions);

            // Initialize tape
            BandPosition bp = graph.CreateNodeBandPosition();

            // Initialize states
            State sA = graph.CreateNodeState();
            procEnv.SetVariableValue("sA", sA);
            State sB = graph.CreateNodeState();
            procEnv.SetVariableValue("sB", sB);
            State sC = graph.CreateNodeState();
            procEnv.SetVariableValue("sC", sC);
            State sD = graph.CreateNodeState();
            procEnv.SetVariableValue("sD", sD);
            State sE = graph.CreateNodeState();
            procEnv.SetVariableValue("sE", sE);
            State sH = graph.CreateNodeState();
            procEnv.SetVariableValue("sH", sH);

            // Create state transitions
            GenStateTransition("sA", 0, "sB", 1, L);
            GenStateTransition("sA", 1, "sD", 1, L);
            GenStateTransition("sB", 0, "sC", 1, R);
            GenStateTransition("sB", 1, "sE", 0, R);
            GenStateTransition("sC", 0, "sA", 0, L);
            GenStateTransition("sC", 1, "sB", 0, R);
            GenStateTransition("sD", 0, "sE", 1, L);
            GenStateTransition("sD", 1, "sH", 1, L);
            GenStateTransition("sE", 0, "sC", 1, R);
            GenStateTransition("sE", 1, "sC", 1, L);

            // Initialize head
            procEnv.SetVariableValue("curState", sA);
            procEnv.SetVariableValue("curPos", bp);

            // A little warm up for the beaver
            // Using a graph rewrite sequence with the new and more expressive syntax
            procEnv.ApplyGraphRewriteSequence(
                  @"(
                       ((curValue:WriteValue)=readOneRule(curState, curPos)
                       || (curValue)=readZeroRule(curState,curPos))
                    && (ensureMoveLeftValidRule(curValue, curPos)
                       || ensureMoveRightValidRule(curValue, curPos)
                       || true)
                    && ((curState, curPos)=moveLeftRule(curValue, curPos)
                       || (curState, curPos)=moveRightRule(curValue, curPos))
                   )[100]");

			Console.WriteLine(procEnv.PerformanceInfo.MatchesFound + " matches found.");

            // Reset counters of the PerformanceInfo object
			procEnv.PerformanceInfo.Reset();

            // Calculate search plans to optimize performance
            graph.AnalyzeGraph();
            actions.GenerateActions("readOneRule", "readZeroRule",
                "ensureMoveLeftValidRule", "ensureMoveRightValidRule", "moveLeftRule", "moveRightRule");

            // Go, beaver, go!
#if USE_SEQUENCE
            procEnv.ApplyGraphRewriteSequence(
                  @"(
                       ((curValue:WriteValue)=readOneRule(curState, curPos)
                       || (curValue)=readZeroRule(curState,curPos))
                    && (ensureMoveLeftValidRule(curValue, curPos)
                       || ensureMoveRightValidRule(curValue, curPos)
                       || true)
                    && ((curState, curPos)=moveLeftRule(curValue, curPos)
                       || (curState, curPos)=moveRightRule(curValue, curPos))
                   )*");
#else
            // the graph rewrite sequence from above formulated in C# with the API of GrGen.NET 2.5
            IState curState = (IState)procEnv.GetVariableValue("curState");
            IBandPosition curPos = (IBandPosition)procEnv.GetVariableValue("curPos");
            IWriteValue curValue = (IWriteValue)procEnv.GetVariableValue("curValue");
            bool expressionToIterateSucceeded;
            do
            {
                expressionToIterateSucceeded =
                    ( actions.readOneRule.Apply(procEnv, curState, curPos, ref curValue)
                    || actions.readZeroRule.Apply(procEnv, curState, curPos, ref curValue) )
                && ( actions.ensureMoveLeftValidRule.Apply(procEnv, curValue, curPos)
                    || actions.ensureMoveRightValidRule.Apply(procEnv, curValue, curPos)
                    || true )
                && ( actions.moveLeftRule.Apply(procEnv, curValue, curPos, ref curState, ref curPos)
                    || actions.moveRightRule.Apply(procEnv, curValue, curPos, ref curState, ref curPos) );
            }
            while(expressionToIterateSucceeded);
#endif

            int stopTime = Environment.TickCount;

            // Count "BandPosition" nodes with a "value" attribute being one
            int numOnes = 0;
            foreach(BandPosition bpNode in graph.GetExactNodes(BandPosition.TypeInstance))
                if(bpNode.value == 1)
                    numOnes++;

            int countTime = Environment.TickCount - stopTime;

			Console.WriteLine(procEnv.PerformanceInfo.MatchesFound + " matches found."
                + "\nNumber of ones written: " + numOnes
                + "\nTime needed for counting ones: " + countTime + " ms");

            long endBytes = System.GC.GetTotalMemory(true);

            Console.WriteLine("Time: " + (stopTime - startTime) + " ms"
                + "\nMemory usage: " + (endBytes - startBytes) + " bytes"
                + "\nNum nodes: " + graph.NumNodes
                + "\nNum edges: " + graph.NumEdges);
        }
        static void Main(string[] args)
        {
            if(args.Length < 2 || args.Length > 3)
            {
                Console.WriteLine("usage: MovieDatabaseBenchmarker <name of rule to apply> <name of grs file to import or number of creation iterations of synthetic graph> [\"sequence to execute\"]");
                Console.WriteLine("example: MovieDatabaseBenchmarker findCouplesOpt imdb-0005000-50176.movies.xmi.grs");
                Console.WriteLine("example: MovieDatabaseBenchmarker findCliquesOf3Opt imdb-0130000-712130.movies.xmi.grs \"[cliques3WithRating\\orderDescendingBy<avgRating>\\keepFirst(15)] ;> [cliques3WithRating\\orderDescendingBy<numMovies>\\keepFirst(15)]\"");
                return;
            }

            // the graph we'll work on
            LGSPGraph graph;

            // the actions we'll use
            MovieDatabaseActions actions;

            // the graph processing environment we'll use
            LGSPGraphProcessingEnvironment procEnv;

            int dummy;
            if(Int32.TryParse(args[1], out dummy))
            {
                Console.WriteLine("Synthesizing test graph with iteration count " + args[1] + " ...");

                graph = new MovieDatabaseModelGraph();
                actions = new MovieDatabaseActions(graph);
                procEnv = new LGSPGraphProcessingEnvironment(graph, actions);

                int startTimeSynth = Environment.TickCount;

                procEnv.ApplyGraphRewriteSequence("createExample(" + args[1] + ")");

                Console.WriteLine("...needed " + (Environment.TickCount - startTimeSynth) + "ms for synthesizing");
            }
            else
            {
                Console.WriteLine("Importing " + args[1] + " ...");

                // the libGr search plan backend we'll use
                LGSPBackend backend = new LGSPBackend();

                // the graph model we'll use
                MovieDatabaseModelGraphModel model = new MovieDatabaseModelGraphModel();

                // import the graph, result (of grs import) will be a named graph
                IActions ba;
                INamedGraph importedNamedGraph = (INamedGraph)Porter.Import(args[1], backend, model, out ba);

                // we throw away the named graph cause we don't need names here and they require a huge amount of memory
                graph = new LGSPGraph((LGSPNamedGraph)importedNamedGraph, "unnamed");
                importedNamedGraph = null;
                GC.Collect();

                actions = ba != null ? (MovieDatabaseActions)ba : new MovieDatabaseActions(graph);
                procEnv = new LGSPGraphProcessingEnvironment(graph, actions);
            }

            // calculate search plans to optimize performance (I'm not going to fiddle with loading saved analysis data here)
            graph.AnalyzeGraph();
            actions.GenerateActions(args[0]);

            Console.WriteLine("Number of Movie: " + graph.nodesByTypeCounts[graph.Model.NodeModel.GetType("Movie").TypeID]);
            Console.WriteLine("Number of Actor: " + graph.nodesByTypeCounts[graph.Model.NodeModel.GetType("Actor").TypeID]);
            Console.WriteLine("Number of Actress: " + graph.nodesByTypeCounts[graph.Model.NodeModel.GetType("Actress").TypeID]);
            Console.WriteLine("Number of personToMovie: " + graph.edgesByTypeCounts[graph.Model.EdgeModel.GetType("personToMovie").TypeID]);

            Console.WriteLine("Start matching " + args[0] + " ...");

            int startTime = Environment.TickCount;

            // get action, search for all matches, apply rewrite
            IAction ruleToApply = actions.GetAction(args[0]);
            IMatches matches = ruleToApply.Match(procEnv, 0, new object[0]);

            Console.WriteLine("...needed " + (Environment.TickCount - startTime) + "ms for finding the matches");

            Console.WriteLine("...continue with rewriting...");

            ruleToApply.ModifyAll(procEnv, matches);

            Console.WriteLine("...needed " + (Environment.TickCount - startTime) + "ms for finding the matches and adding the couples/cliques");

            Console.WriteLine("Number of Couple: " + graph.nodesByTypeCounts[graph.Model.NodeModel.GetType("Couple").TypeID]);
            Console.WriteLine("Number of Clique: " + graph.nodesByTypeCounts[graph.Model.NodeModel.GetType("Clique").TypeID]);
            Console.WriteLine("Number of commonMovies: " + graph.edgesByTypeCounts[graph.Model.EdgeModel.GetType("commonMovies").TypeID]);

            if(args.Length == 3)
            {
                procEnv.ApplyGraphRewriteSequence(args[2]);
            }
        }