/// <summary> /// Searches for a symmetric partner for the match at the index in this /// Returns true if it was possible in the end to map every match in this to a match in that /// </summary> private static bool AreIterationsSymmetric(IMatches this_, IMatches that, IGraph graph, int index) { if (index >= this_.Count) { return(true); } for (int j = 0; j < that.Count; ++j) { if (that.GetMatch(j).IsMarked()) { continue; } if (!AreSymmetric(this_.GetMatch(index), that.GetMatch(j), graph)) { continue; } that.GetMatch(j).Mark(true); bool wereSymmetric = AreIterationsSymmetric(this_, that, graph, index + 1); that.GetMatch(j).Mark(false); if (wereSymmetric) { return(true); } } return(false); }
public List <object[]> Replace(IMatches matches, int which) { List <object[]> returns; object[] retElems; if (which != -1) { if (which < 0 || which >= matches.Count) { throw new ArgumentOutOfRangeException("\"which\" is out of range!"); } returns = matches.Producer.Reserve(0); retElems = matches.Producer.Modify(this, matches.GetMatch(which)); returns.Add(retElems); ++PerformanceInfo.RewritesPerformed; } else { returns = matches.Producer.Reserve(matches.Count); int curResultNum = 0; bool first = true; foreach (IMatch match in matches) { if (first) { first = false; } else if (OnRewritingNextMatch != null) { OnRewritingNextMatch(); } retElems = matches.Producer.Modify(this, match); object[] curResult = returns[curResultNum]; retElems.CopyTo(curResult, 0); ++PerformanceInfo.RewritesPerformed; ++curResultNum; } } return(returns); }
public List <object[]> Replace(IMatches matches, int which) { List <object[]> returns; object[] retElems = null; if (which != -1) { if (which < 0 || which >= matches.Count) { throw new ArgumentOutOfRangeException("\"which\" is out of range!"); } returns = matches.Producer.Reserve(0); retElems = matches.Producer.Modify(this, matches.GetMatch(which)); returns.Add(retElems); PerformanceInfo.RewritesPerformed++; } else { bool first = true; returns = matches.Producer.Reserve(matches.Count); int curResultNum = 0; foreach (IMatch match in matches) { if (first) { first = false; } else if (OnRewritingNextMatch != null) { OnRewritingNextMatch(); } retElems = matches.Producer.Modify(this, match); object[] curResult = returns[curResultNum]; for (int i = 0; i < retElems.Length; ++i) { curResult[i] = retElems[i]; } PerformanceInfo.RewritesPerformed++; curResultNum++; } if (retElems == null) { retElems = Sequence.NoElems; } } return(returns); }
/// <summary> /// Dumps the given matches. /// </summary> /// <param name="dumper">The graph dumper to be used.</param> /// <param name="dumpInfo">Specifies how the graph shall be dumped.</param> /// <param name="matches">An IMatches object containing the matches.</param> /// <param name="which">Which match to dump, or AllMatches for dumping all matches /// adding connections between them, or OnlyMatches to dump the matches only</param> public static void DumpMatchOnly(IDumper dumper, DumpInfo dumpInfo, IMatches matches, DumpMatchSpecial which, ref Set <INode> matchedNodes, ref Set <INode> multiMatchedNodes, ref Set <IEdge> matchedEdges, ref Set <IEdge> multiMatchedEdges) { matchedNodes = new Set <INode>(); matchedEdges = new Set <IEdge>(); if ((int)which >= 0 && (int)which < matches.Count) { // Show exactly one match IMatch match = matches.GetMatch((int)which); matchedNodes.Add(match.Nodes); matchedEdges.Add(match.Edges); } else { GrColor vnodeColor = dumpInfo.GetNodeDumpTypeColor(GrElemDumpType.VirtualMatch); GrColor vedgeColor = dumpInfo.GetEdgeDumpTypeColor(GrElemDumpType.VirtualMatch); GrColor vnodeBorderColor = dumpInfo.GetNodeDumpTypeBorderColor(GrElemDumpType.VirtualMatch); GrColor vnodeTextColor = dumpInfo.GetNodeDumpTypeTextColor(GrElemDumpType.VirtualMatch); GrColor vedgeTextColor = dumpInfo.GetEdgeDumpTypeTextColor(GrElemDumpType.VirtualMatch); GrNodeShape vnodeShape = dumpInfo.GetNodeDumpTypeShape(GrElemDumpType.VirtualMatch); GrLineStyle vedgeLineStyle = dumpInfo.GetEdgeDumpTypeLineStyle(GrElemDumpType.VirtualMatch); int vedgeThickness = dumpInfo.GetEdgeDumpTypeThickness(GrElemDumpType.VirtualMatch); multiMatchedNodes = new Set <INode>(); multiMatchedEdges = new Set <IEdge>(); // TODO: May edges to nodes be dumped before those nodes exist?? // TODO: Should indices in strings start at 0 or 1? (original: 0) // Dump all matches with virtual nodes int i = 0; foreach (IMatch match in matches) { VirtualNode virtNode = new VirtualNode(-i - 1); dumper.DumpNode(virtNode, String.Format("{0}. match of {1}", i + 1, matches.Producer.Name), null, vnodeTextColor, vnodeColor, vnodeBorderColor, vnodeShape); int j = 1; foreach (INode node in match.Nodes) { dumper.DumpEdge(virtNode, node, String.Format("node {0}", ++j), null, vedgeTextColor, vedgeColor, vedgeLineStyle, vedgeThickness); if (matchedNodes.Contains(node)) { multiMatchedNodes.Add(node); } else { matchedNodes.Add(node); } } // Collect matched edges foreach (IEdge edge in match.Edges) { if (matchedEdges.Contains(edge)) { multiMatchedEdges.Add(edge); } else { matchedEdges.Add(edge); } } ++i; } if (which == DumpMatchSpecial.OnlyMatches) { // Dump the matches only // First dump the matched nodes foreach (INode node in matchedNodes) { GrElemDumpType dumpType; if (multiMatchedNodes.Contains(node)) { dumpType = GrElemDumpType.MultiMatched; } else { dumpType = GrElemDumpType.SingleMatched; } DumpNode(node, dumpInfo.GetNodeDumpTypeTextColor(dumpType), dumpInfo.GetNodeDumpTypeColor(dumpType), dumpInfo.GetNodeDumpTypeBorderColor(dumpType), dumpInfo.GetNodeDumpTypeShape(dumpType), dumper, dumpInfo); } // Now add the matched edges (possibly including "Not matched" nodes) foreach (IEdge edge in matchedEdges) { if (!matchedNodes.Contains(edge.Source)) { DumpNode(edge.Source, dumpInfo.GetNodeTypeTextColor(edge.Source.Type), dumpInfo.GetNodeTypeColor(edge.Source.Type), dumpInfo.GetNodeTypeBorderColor(edge.Source.Type), dumpInfo.GetNodeTypeShape(edge.Source.Type), dumper, dumpInfo); } if (!matchedNodes.Contains(edge.Target)) { DumpNode(edge.Target, dumpInfo.GetNodeTypeTextColor(edge.Target.Type), dumpInfo.GetNodeTypeColor(edge.Target.Type), dumpInfo.GetNodeTypeBorderColor(edge.Target.Type), dumpInfo.GetNodeTypeShape(edge.Target.Type), dumper, dumpInfo); } GrElemDumpType dumpType; if (multiMatchedEdges.Contains(edge)) { dumpType = GrElemDumpType.MultiMatched; } else { dumpType = GrElemDumpType.SingleMatched; } DumpEdge(edge, dumpInfo.GetEdgeDumpTypeTextColor(dumpType), dumpInfo.GetEdgeDumpTypeColor(dumpType), dumpInfo.GetEdgeDumpTypeLineStyle(dumpType), dumpInfo.GetEdgeDumpTypeThickness(dumpType), dumper, dumpInfo); } return; } } }
/// <summary> /// Searches for a symmetric partner for the match at the index in this /// Returns true if it was possible in the end to map every match in this to a match in that /// </summary> private static bool AreIterationsSymmetric(IMatches this_, IMatches that, IGraph graph, int index) { if(index >= this_.Count) return true; for(int j = 0; j < that.Count; ++j) { if(that.GetMatch(j).IsMarked()) continue; if(!AreSymmetric(this_.GetMatch(index), that.GetMatch(j), graph)) continue; that.GetMatch(j).Mark(true); bool wereSymmetric = AreIterationsSymmetric(this_, that, graph, index + 1); that.GetMatch(j).Mark(false); if(wereSymmetric) return true; } return false; }
/// <summary> /// returns the maybe user altered match to apply next for the sequence given /// the randomly chosen match is supplied; the object with all available matches is supplied /// </summary> public int ChooseMatch(int matchToApply, IMatches matches, int numFurtherMatchesToApply, Sequence seq) { context.highlightSeq = seq; context.choice = true; PrintSequence(debugSequences.Peek(), context, debugSequences.Count); Console.WriteLine(); context.choice = false; if(matches.Count <= 1 + numFurtherMatchesToApply && lazyChoice) { context.workaround.PrintHighlighted("Skipping choicepoint ", HighlightingMode.Choicepoint); Console.WriteLine("as no choice needed (use the (l) command to toggle this behaviour)."); return matchToApply; } context.workaround.PrintHighlighted("Please choose: Which match to apply?", HighlightingMode.Choicepoint); Console.WriteLine(" Showing the match chosen by random. (" + numFurtherMatchesToApply + " following)"); Console.WriteLine("Press (0)...(9) to show the corresponding match or (e) to enter the number of the match to show." + " Press (s) or (n) to commit to the currently shown match and continue."); if(detailedMode) { MarkMatches(matches, null, null); AnnotateMatches(matches, false); } ycompClient.UpdateDisplay(); ycompClient.Sync(); int newMatchToRewrite = matchToApply; while(true) { MarkMatch(matches.GetMatch(matchToApply), null, null); AnnotateMatch(matches.GetMatch(matchToApply), false); matchToApply = newMatchToRewrite; MarkMatch(matches.GetMatch(matchToApply), realizers.MatchedNodeRealizer, realizers.MatchedEdgeRealizer); AnnotateMatch(matches.GetMatch(matchToApply), true); ycompClient.UpdateDisplay(); ycompClient.Sync(); Console.WriteLine("Showing match " + matchToApply + " (of " + matches.Count + " matches available)"); ConsoleKeyInfo key = ReadKeyWithCancel(); switch(key.KeyChar) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': int num = key.KeyChar - '0'; if(num >= matches.Count) { Console.WriteLine("You must specify a number between 0 and " + (matches.Count - 1) + "!"); break; } newMatchToRewrite = num; break; case 'e': Console.Write("Enter number of match to show: "); String numStr = Console.ReadLine(); if(int.TryParse(numStr, out num)) { if(num < 0 || num >= matches.Count) { Console.WriteLine("You must specify a number between 0 and " + (matches.Count - 1) + "!"); break; } newMatchToRewrite = num; break; } Console.WriteLine("You must enter a valid integer number!"); break; case 's': case 'n': MarkMatch(matches.GetMatch(matchToApply), null, null); AnnotateMatch(matches.GetMatch(matchToApply), false); ycompClient.UpdateDisplay(); ycompClient.Sync(); return matchToApply; default: Console.WriteLine("Illegal choice (Key = " + key.Key + ")! Only (0)...(9), (e)nter number, (s)/(n) to commit and continue allowed! "); break; } } }
/// <summary> /// Dumps the given matches. /// </summary> /// <param name="dumper">The graph dumper to be used.</param> /// <param name="dumpInfo">Specifies how the graph shall be dumped.</param> /// <param name="matches">An IMatches object containing the matches.</param> /// <param name="which">Which match to dump, or AllMatches for dumping all matches /// adding connections between them, or OnlyMatches to dump the matches only</param> public static void DumpMatchOnly(IDumper dumper, DumpInfo dumpInfo, IMatches matches, DumpMatchSpecial which, ref Set<INode> matchedNodes, ref Set<INode> multiMatchedNodes, ref Set<IEdge> matchedEdges, ref Set<IEdge> multiMatchedEdges) { matchedNodes = new Set<INode>(); matchedEdges = new Set<IEdge>(); if((int)which >= 0 && (int)which < matches.Count) { // Show exactly one match IMatch match = matches.GetMatch((int)which); matchedNodes.Add(match.Nodes); matchedEdges.Add(match.Edges); } else { GrColor vnodeColor = dumpInfo.GetNodeDumpTypeColor(GrElemDumpType.VirtualMatch); GrColor vedgeColor = dumpInfo.GetEdgeDumpTypeColor(GrElemDumpType.VirtualMatch); GrColor vnodeBorderColor = dumpInfo.GetNodeDumpTypeBorderColor(GrElemDumpType.VirtualMatch); GrColor vnodeTextColor = dumpInfo.GetNodeDumpTypeTextColor(GrElemDumpType.VirtualMatch); GrColor vedgeTextColor = dumpInfo.GetEdgeDumpTypeTextColor(GrElemDumpType.VirtualMatch); GrNodeShape vnodeShape = dumpInfo.GetNodeDumpTypeShape(GrElemDumpType.VirtualMatch); GrLineStyle vedgeLineStyle = dumpInfo.GetEdgeDumpTypeLineStyle(GrElemDumpType.VirtualMatch); int vedgeThickness = dumpInfo.GetEdgeDumpTypeThickness(GrElemDumpType.VirtualMatch); multiMatchedNodes = new Set<INode>(); multiMatchedEdges = new Set<IEdge>(); // TODO: May edges to nodes be dumped before those nodes exist?? // TODO: Should indices in strings start at 0 or 1? (original: 0) // Dump all matches with virtual nodes int i = 0; foreach(IMatch match in matches) { VirtualNode virtNode = new VirtualNode(-i - 1); dumper.DumpNode(virtNode, String.Format("{0}. match of {1}", i + 1, matches.Producer.Name), null, vnodeTextColor, vnodeColor, vnodeBorderColor, vnodeShape); int j = 1; foreach(INode node in match.Nodes) { dumper.DumpEdge(virtNode, node, String.Format("node {0}", j++), null, vedgeTextColor, vedgeColor, vedgeLineStyle, vedgeThickness); if(matchedNodes.Contains(node)) multiMatchedNodes.Add(node); else matchedNodes.Add(node); } // Collect matched edges foreach(IEdge edge in match.Edges) { if(matchedEdges.Contains(edge)) multiMatchedEdges.Add(edge); else matchedEdges.Add(edge); } i++; } if(which == DumpMatchSpecial.OnlyMatches) { // Dump the matches only // First dump the matched nodes foreach(INode node in matchedNodes) { GrElemDumpType dumpType; if(multiMatchedNodes.Contains(node)) dumpType = GrElemDumpType.MultiMatched; else dumpType = GrElemDumpType.SingleMatched; DumpNode(node, dumpInfo.GetNodeDumpTypeTextColor(dumpType), dumpInfo.GetNodeDumpTypeColor(dumpType), dumpInfo.GetNodeDumpTypeBorderColor(dumpType), dumpInfo.GetNodeDumpTypeShape(dumpType), dumper, dumpInfo); } // Now add the matched edges (possibly including "Not matched" nodes) foreach(IEdge edge in matchedEdges) { if(!matchedNodes.Contains(edge.Source)) DumpNode(edge.Source, dumpInfo.GetNodeTypeTextColor(edge.Source.Type), dumpInfo.GetNodeTypeColor(edge.Source.Type), dumpInfo.GetNodeTypeBorderColor(edge.Source.Type), dumpInfo.GetNodeTypeShape(edge.Source.Type), dumper, dumpInfo); if(!matchedNodes.Contains(edge.Target)) DumpNode(edge.Target, dumpInfo.GetNodeTypeTextColor(edge.Target.Type), dumpInfo.GetNodeTypeColor(edge.Target.Type), dumpInfo.GetNodeTypeBorderColor(edge.Target.Type), dumpInfo.GetNodeTypeShape(edge.Target.Type), dumper, dumpInfo); GrElemDumpType dumpType; if(multiMatchedEdges.Contains(edge)) dumpType = GrElemDumpType.MultiMatched; else dumpType = GrElemDumpType.SingleMatched; DumpEdge(edge, dumpInfo.GetEdgeDumpTypeTextColor(dumpType), dumpInfo.GetEdgeDumpTypeColor(dumpType), dumpInfo.GetEdgeDumpTypeLineStyle(dumpType), dumpInfo.GetEdgeDumpTypeThickness(dumpType), dumper, dumpInfo); } return; } } }