示例#1
0
        /// <summary>
        /// Copy constructor helper.
        /// </summary>
        /// <param name="dataSource">The LGSPGraph object to get the data from</param>
        /// <param name="newName">Name of the copied graph.</param>
        /// <param name="oldToNewMap">A map of the old elements to the new elements after cloning,
        /// just forget about it if you don't need it.</param>
        private void Copy(LGSPGraph dataSource, String newName, out IDictionary<IGraphElement, IGraphElement> oldToNewMap)
        {
            model = dataSource.model;
            name = newName;

            InitializeGraph();

            model.CreateAndBindIndexSet(this);

            if(dataSource.backend != null)
            {
                backend = dataSource.backend;
                modelAssemblyName = dataSource.modelAssemblyName;
            }

            oldToNewMap = new Dictionary<IGraphElement, IGraphElement>();

            for(int i = 0; i < dataSource.nodesByTypeHeads.Length; i++)
            {
                for(LGSPNode head = dataSource.nodesByTypeHeads[i], node = head.lgspTypePrev; node != head; node = node.lgspTypePrev)
                {
                    LGSPNode newNode = (LGSPNode) node.Clone();
                    AddNodeWithoutEvents(newNode, node.lgspType.TypeID);
                    oldToNewMap[node] = newNode;
                }
            }

            for(int i = 0; i < dataSource.edgesByTypeHeads.Length; i++)
            {
                for(LGSPEdge head = dataSource.edgesByTypeHeads[i], edge = head.lgspTypePrev; edge != head; edge = edge.lgspTypePrev)
                {
                    LGSPEdge newEdge = (LGSPEdge) edge.Clone((INode) oldToNewMap[edge.lgspSource], (INode) oldToNewMap[edge.lgspTarget]);
                    AddEdgeWithoutEvents(newEdge, newEdge.lgspType.TypeID);
                    oldToNewMap[edge] = newEdge;
                }
            }

            /* TODO: remove when cloning of graph variables was implemented
             * foreach(KeyValuePair<IGraphElement, LinkedList<Variable>> kvp in dataSource.ElementMap)
            {
                IGraphElement newElem = oldToNewMap[kvp.Key];
                foreach(Variable var in kvp.Value)
                    SetVariableValue(var.Name, newElem);
            }*/

            model.FillIndexSetAsClone(this, dataSource, oldToNewMap);

            statistics = new LGSPGraphStatistics(this.Model);
            statistics.Copy(dataSource);
        }
示例#2
0
 /// <summary>
 /// Constructs an LGSPGraph object with the given model, backend, and name.
 /// </summary>
 /// <param name="grmodel">The graph model.</param>
 /// <param name="lgspBackend">The responsible backend object, needed for import from the sequences.</param>
 /// <param name="grname">The name for the graph.</param>
 public LGSPGraph(IGraphModel grmodel, LGSPBackend lgspBackend, String grname)
     : this(grmodel, grname)
 {
     backend = lgspBackend;
 }
示例#3
0
 /// <summary>
 /// Constructs an LGSPGraph object.
 /// Deprecated.
 /// </summary>
 /// <param name="lgspBackend">The responsible backend object.</param>
 /// <param name="grmodel">The graph model.</param>
 /// <param name="grname">The name for the graph.</param>
 /// <param name="modelassemblyname">The name of the model assembly.</param>
 public LGSPGraph(LGSPBackend lgspBackend, IGraphModel grmodel, String grname, String modelassemblyname)
     : this(grmodel, grname)
 {
     backend = lgspBackend;
     modelAssemblyName = modelassemblyname;
 }
示例#4
0
		static void Main(string[] args)
		{
			bool verbose = false, onlyNew = false, append = false;
			int filesStart = -1;
			if(args.Length > 0)
			{
				for(int i = 0; i < args.Length; i++)
				{
					if(args[i][0] == '-')
					{
						switch(args[i])
						{
							case "-a": append = true; break;

							case "-c":
								Console.Write("Cleaning ...");
								foreach(String dir in Directory.GetDirectories("."))
								{
									foreach(String subdir in Directory.GetDirectories(dir, "*_out"))
										Directory.Delete(subdir, true);
								}
								Console.WriteLine(" OK");
								return;

							case "-d":
								ShowDiff();
								return;

							case "-n": onlyNew = true; break;
							case "-v": verbose = true; break;

                            case "--help":
                            case "-?":
                            case "/?":
                                Usage();
                                return;

							default:
								Console.WriteLine("Unknown option: " + args[i] + "\n");
                                Usage();
								return;
						}
					}
					else
					{
						filesStart = i;
						break;
					}
				}
			}
			List<String> files = new List<string>();
			if(filesStart == -1)
			{
				files.AddRange(Directory.GetFiles("should_pass", "*.grg"));
				files.AddRange(Directory.GetFiles("should_warn", "*.grg"));
				files.AddRange(Directory.GetFiles("should_fail", "*.grg"));
			}
			else
			{
				for(int i = filesStart; i < args.Length; i++)
					files.Add(args[i]);
			}

			LGSPBackend backend = new LGSPBackend();

			using(StreamWriter logFile = new StreamWriter("summary.log", append))
			{
				foreach(String file in files)
				{
					if(!file.EndsWith(".grg"))
					{
						Console.WriteLine("Error: Filename does not end with \".grg\": " + file);
						continue;
					}

					if(!File.Exists(file))
					{
						Console.WriteLine("Error: File does not exist: " + file);
						continue;
					}

					String outDir = file.Replace(".grg", "_out");
                    String fileForLog = file.Replace('\\', '/');

					if(Directory.Exists(outDir))
					{
						if(onlyNew && Directory.GetLastWriteTime(outDir) > Directory.GetLastWriteTime(file)) continue;
						Directory.Delete(outDir, true);
					}
					Directory.CreateDirectory(outDir);

					TextWriter oldOut = Console.Out;

                    Console.Write("===> TEST " + fileForLog);
					StringWriter log = new StringWriter();
					Console.SetError(log);
					Console.SetOut(log);
					bool failed = false;
					try
					{
                        backend.ProcessSpecification(file, outDir + Path.DirectorySeparatorChar, outDir, null, ProcessSpecFlags.KeepGeneratedFiles);
					}
					catch(Exception ex)
					{
						failed = true;
						log.Write(ex.Message);
					}

					Console.SetOut(oldOut);

					String javaOutput = null;
					String logStr = log.ToString();
					if(logStr.Contains("Exception in thread"))
					{
						Console.WriteLine(" ... ABEND");
                        logFile.WriteLine("ABEND  " + fileForLog);
					}
					else if(logStr.Contains("ERROR"))
					{	
						Console.WriteLine(" ... ERROR");
                        logFile.WriteLine("ERROR  " + fileForLog);
					}
					else if(logStr.Contains("Illegal model") || logStr.Contains("Illegal actions"))
					{
						Console.WriteLine(" ... FAILED");
                        logFile.WriteLine("FAILED " + fileForLog);
					}
					else if(!failed)
					{
					    if(logStr.Contains("WARNING"))
					    {
						    Console.WriteLine(" ... WARNED");
                            logFile.WriteLine("WARNED " + fileForLog);
					    }
						else if(File.Exists(outDir + Path.DirectorySeparatorChar + "printOutput.txt"))
						{
							using(StreamReader sr = new StreamReader(outDir + Path.DirectorySeparatorChar + "printOutput.txt"))
								javaOutput = sr.ReadToEnd();
							if(javaOutput.Contains("WARNING"))
							{
								Console.WriteLine(" ... WARNED");
                                logFile.WriteLine("WARNED " + fileForLog);
							}
							else
							{
								javaOutput = null;
								Console.WriteLine(" ... OK");
                                logFile.WriteLine("OK     " + fileForLog);
							}
						}
						else
						{
							Console.WriteLine(" ... OK");
                            logFile.WriteLine("OK     " + fileForLog);
						}
					}
					else
					{
						Console.WriteLine(" ... ABEND");
                        logFile.WriteLine("ABEND  " + fileForLog);
					}

					if(verbose)
					{
						if(javaOutput != null)
							Console.WriteLine(javaOutput);
						Console.WriteLine(log.ToString());
					}
				}
			}
			ShowDiff();
		}
示例#5
0
 /// <summary>
 /// Constructs an LGSPGraph object with the given model and backend, and an automatically generated name.
 /// </summary>
 /// <param name="grmodel">The graph model.</param>
 /// <param name="lgspBackend">The responsible backend object, needed for import from the sequences.</param>
 public LGSPGraph(IGraphModel grmodel, LGSPBackend lgspBackend)
     : this(grmodel, lgspBackend, GetNextGraphName())
 {
 }
示例#6
0
 /// <summary>
 /// Constructs an LGSPNamedGraph object with the given model, backend, name, and capacity.
 /// </summary>
 /// <param name="grmodel">The graph model.</param>
 /// <param name="backend">The backend.</param>
 /// <param name="grname">The name for the graph.</param>
 /// <param name="capacity">The initial capacity for the name maps (performance optimization, use 0 if unsure).</param>
 public LGSPNamedGraph(IGraphModel grmodel, LGSPBackend backend, String grname, int capacity)
     : base(grmodel, backend, grname)
 {
     NameToElem = new Dictionary <String, IGraphElement>(capacity);
     ElemToName = new Dictionary <IGraphElement, String>(capacity);
 }
        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);
        }
示例#8
0
 /// <summary>
 /// Constructs an LGSPNamedGraph object.
 /// Deprecated.
 /// </summary>
 /// <param name="lgspBackend">The responsible backend object.</param>
 /// <param name="grmodel">The graph model.</param>
 /// <param name="grname">The name for the graph.</param>
 /// <param name="modelassemblyname">The name of the model assembly.</param>
 /// <param name="capacity">The initial capacity for the name maps (performance optimization, use 0 if unsure).</param>
 public LGSPNamedGraph(LGSPBackend lgspBackend, IGraphModel grmodel, String grname, String modelassemblyname, int capacity)
     : base(lgspBackend, grmodel, grname, modelassemblyname)
 {
     NameToElem = new Dictionary <String, IGraphElement>(capacity);
     ElemToName = new Dictionary <IGraphElement, String>(capacity);
 }
示例#9
0
 /// <summary>
 /// Constructs an LGSPNamedGraph object with the given model, backend, name, and capacity.
 /// </summary>
 /// <param name="grmodel">The graph model.</param>
 /// <param name="backend">The backend.</param>
 /// <param name="grname">The name for the graph.</param>
 /// <param name="capacity">The initial capacity for the name maps (performance optimization, use 0 if unsure).</param>
 public LGSPNamedGraph(IGraphModel grmodel, LGSPBackend backend, String grname, int capacity)
     : base(grmodel, backend, grname)
 {
     NameToElem = new Dictionary<String, IGraphElement>(capacity);
     ElemToName = new Dictionary<IGraphElement, String>(capacity);
 }
示例#10
0
 /// <summary>
 /// Constructs an LGSPNamedGraph object.
 /// Deprecated.
 /// </summary>
 /// <param name="lgspBackend">The responsible backend object.</param>
 /// <param name="grmodel">The graph model.</param>
 /// <param name="grname">The name for the graph.</param>
 /// <param name="modelassemblyname">The name of the model assembly.</param>
 /// <param name="capacity">The initial capacity for the name maps (performance optimization, use 0 if unsure).</param>
 public LGSPNamedGraph(LGSPBackend lgspBackend, IGraphModel grmodel, String grname, String modelassemblyname, int capacity)
     : base(lgspBackend, grmodel, grname, modelassemblyname)
 {
     NameToElem = new Dictionary<String, IGraphElement>(capacity);
     ElemToName = new Dictionary<IGraphElement, String>(capacity);
 }
示例#11
0
        static int Main(string[] args)
        {
            String specFile = null;
            String dirname = null;
            String destDir = null;
            ProcessSpecFlags flags = ProcessSpecFlags.UseNoExistingFiles;
            IBackend backend = null;
            List<String> externalAssemblies = new List<String>();
            String statisticsPath = null;

            for(int i = 0; i < args.Length; i++)
            {
                if(args[i][0] == '-')
                {
                    switch(args[i])
                    {
                        case "-o":
                            if(i + 1 >= args.Length)
                            {
                                Console.Error.WriteLine("Missing parameter for -o option!");
                                specFile = null;         // show usage
                                break;
                            }
                            destDir = args[++i];
                            if(!Directory.Exists(destDir))
                            {
                                Console.Error.WriteLine("Specified output directory does not exist!");
                                return 1;
                            }
                            if(destDir[destDir.Length - 1] != Path.DirectorySeparatorChar)
                                destDir += Path.DirectorySeparatorChar;
                            break;

                        case "-b":
                            if(i + 1 >= args.Length)
                            {
                                Console.Error.WriteLine("Missing parameter for -b option!");
                                specFile = null;         // show usage
                                break;
                            }
                            backend = LoadBackend(args[++i]);
                            if(backend == null)
                                return 1;
                            Console.WriteLine("Using backend \"" + backend.Name + "\".");
                            break;

                        case "-r":
                            if (i + 1 >= args.Length)
                            {
                                Console.Error.WriteLine("Missing parameter for -r option!");
                                specFile = null;         // show usage
                                break;
                            }
                            externalAssemblies.Add(args[++i]);
                            break;

                        case "-keep":
                            flags |= ProcessSpecFlags.KeepGeneratedFiles;
                            if(specFile != null)                // specFile already specified?
                            {
                                if(i + 1 >= args.Length)        // yes. is there another parameter?
                                    break;
                            }
                            else if(i + 2 >= args.Length)       // no. are there two more parameters?
                                break;
                            if(args[i + 1][0] == '-')           // is the next parameter an option?
                                break;
                            dirname = args[++i];                // no, use it as a gen-dir
                            break;

                        case "-use":
                            if(i + 1 >= args.Length)
                            {
                                Console.Error.WriteLine("Missing parameter for -use option!");
                                specFile = null;         // show usage
                                break;
                            }
                            if(dirname != null)
                            {
                                Console.Error.WriteLine("The -d option may not specify a directory if -use is used!");
                                specFile = null;
                                break;
                            }
                            dirname = args[++i];
                            flags |= ProcessSpecFlags.UseJavaGeneratedFiles;
                            if(!Directory.Exists(dirname))
                            {
                                Console.Error.WriteLine("Illegal directory specified! It does not exist!");
                                return 1;
                            }
                            break;

                        case "-usefull":
                            if(i + 1 >= args.Length)
                            {
                                Console.Error.WriteLine("Missing parameter for -usefull option!");
                                specFile = null;         // show usage
                                break;
                            }
                            if(dirname != null)
                            {
                                Console.Error.WriteLine("The -d option may not specify a directory if -usefull is used!");
                                specFile = null;
                                break;
                            }
                            dirname = args[++i];
                            flags |= ProcessSpecFlags.UseAllGeneratedFiles;
                            if(!Directory.Exists(dirname))
                            {
                                Console.Error.WriteLine("Illegal directory specified! It does not exist!");
                                return 1;
                            }
                            break;

                        case "-debug":
                            flags |= ProcessSpecFlags.CompileWithDebug;
                            break;

                        case "-noevents":
                            flags |= ProcessSpecFlags.NoEvents;
                            flags |= ProcessSpecFlags.NoDebugEvents;
                            break;

                        case "-nodebugevents":
                            flags |= ProcessSpecFlags.NoDebugEvents;
                            break;

                        case "-lazynic":
                            flags |= ProcessSpecFlags.LazyNIC;
                            break;

                        case "-noinline":
                            flags |= ProcessSpecFlags.Noinline;
                            break;

                        case "-statistics":
                            if(i + 1 >= args.Length)
                            {
                                Console.Error.WriteLine("Missing parameter for -statistics option!");
                                specFile = null;         // show usage
                                break;
                            }
                            statisticsPath = args[++i];
                            if(!File.Exists(statisticsPath))
                            {
                                Console.Error.WriteLine("Specified statistics file \"" + statisticsPath + "\" does not exist!");
                                return 1;
                            }
                            break;

                        case "-profile":
                            flags |= ProcessSpecFlags.Profile;
                            break;

                        default:
                            Console.Error.WriteLine("Illegal option: " + args[i]);
                            specFile = null;
                            i = args.Length;        // leave for loop
                            break;
                    }
                }
                else if(specFile != null)
                {
                    Console.Error.WriteLine("Two rule specification files specified: \"" + specFile + "\" and \"" + args[i] + "\"");
                    specFile = null;
                    break;
                }
                else specFile = args[i];
            }

            // flags |= ProcessSpecFlags.Profile; // uncomment to test profiling

            if(specFile == null)
            {
                Console.WriteLine(
                      "Usage: GrGen [OPTIONS] <grg-file>[.grg]\n"
                    + "Options:\n"
                    + "  -o <output-dir>       Output directory for the generated assemblies\n"
                    + "  -keep [<gen-dir>]     Don't delete generated files making it possible\n"
                    + "                        to use the files in a C# project directly.\n"
                    + "                        This way you can also debug non-matching rules.\n"
                    + "                        Optionally you can specify a destination directory.\n"
                    + "  -debug                Compiles the assemblies with debug information\n"
                    + "  -r <assembly-path>    Assembly path to reference, i.e. link into\n"
                    + "                        the generated assembly\n"
                    + "  -statistics <path>    Build matchers based on the graph statistics\n"
                    + "                        contained in the specified file\n"
                    + "  -use <existing-dir>   Use old C# files generated by the Java frontend\n"
                    + "                        using the -keep option in the specified directory\n"
                    + "  -usefull <exist-dir>  Use all old C# files generated using the -keep option\n"
                    + "                        in the specified directory\n"
                    + "  -b <backend-dll>      Use the specified backend library\n"
                    + "                        (default: LGSPBackend)\n"
                    + "  -lazynic              Negatives, Independents, and Conditions are only\n"
                    + "                        executed at the end of matching (normally asap)\n"
                    + "  -noinline             disables subpattern and independent inlining\n"
                    + "Optimizing options:\n"
                    + "  -nodebugevents        Do not fire debug events in the generated code.\n"
                    + "                        Mostly action events, impacts debugging.\n"
                    + "  -noevents             Do not fire events in the generated code.\n"
                    + "                        Mostly attribute change events.\n"
                    + "                        Impacts transactions, recording, debugging.\n"
                    + "  -noperfinfo           Do not try to update the performance info object\n"
                    + "                        counting number of matches and rewrites.");
                return 1;
            }
            if(!File.Exists(specFile))
            {
                if(File.Exists(specFile + ".grg"))
                    specFile += ".grg";
                else
                {
                    Console.Error.WriteLine("The GRG-file \"" + specFile + "\" does not exist!");
                    return 1;
                }
            }

            specFile = FixDirectorySeparators(specFile);

            String specDir;
            int index = specFile.LastIndexOf(Path.DirectorySeparatorChar);
            if(index == -1)
                specDir = "";
            else
            {
                specDir = specFile.Substring(0, index + 1);
                if(!Directory.Exists(specDir))
                {
                    Console.Error.WriteLine("Something is wrong with the directory of the specification file:\n\"" + specDir + "\" does not exist!");
                    return 1;
                }
            }

            if(destDir == null) destDir = specDir;

            if(dirname == null)
            {
                int id = 0;
                do
                {
                    dirname = specDir + "tmpgrgen" + id + "";
                    id++;
                }
                while(Directory.Exists(dirname));
            }
            if(!Directory.Exists(dirname))
            {
                try
                {
                    Directory.CreateDirectory(dirname);
                }
                catch(Exception)
                {
                    Console.Error.WriteLine("Unable to create temporary directory \"" + dirname + "\"!");
                    return 1;
                }
            }

            if((flags & ProcessSpecFlags.KeepGeneratedFiles) != 0)
                Console.WriteLine("The generated files will be kept in: " + dirname);

            if(backend == null)
                backend = new LGSPBackend();

            int ret = 0;
            try
            {
                backend.ProcessSpecification(specFile, destDir, dirname, statisticsPath, flags, externalAssemblies.ToArray());
            }
            catch(Exception ex)
            {
				Console.Error.WriteLine((flags & ProcessSpecFlags.CompileWithDebug) != 0 ? ex.ToString() : ex.Message);
                ret = 1;
            }

            if((flags & ProcessSpecFlags.KeepGeneratedFiles) == 0 && (flags & ProcessSpecFlags.UseExistingMask) == ProcessSpecFlags.UseNoExistingFiles)
                Directory.Delete(dirname, true);
            return ret;
        }
        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]);
            }
        }