using System; using System.Diagnostics; using System.IO; using HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration.GrammarEnumeration; using HeuristicLab.Common; using HeuristicLab.Core; namespace HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration { class SearchGraphVisualizer : Item, IGrammarEnumerationAnalyzer { private readonly string dotFileName = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + @"\searchgraph.dot"; private TextWriterTraceListener dotFileTrace; public SearchGraphVisualizer() { } protected SearchGraphVisualizer(SearchGraphVisualizer original, Cloner cloner) : base(original, cloner) { } public override IDeepCloneable Clone(Cloner cloner) { return new SearchGraphVisualizer(this, cloner); } public void Register(GrammarEnumerationAlgorithm algorithm) { algorithm.Started += GrammarEnumerationAlgorithmOnStarted; algorithm.Stopped += GrammarEnumerationAlgorithmOnStopped; algorithm.ExceptionOccurred += GrammarEnumerationAlgorithmOnStopped; algorithm.PhraseFetched += PhraseFetched; algorithm.PhraseDerived += PhraseDerived; algorithm.SentenceGenerated += SentenceGenerated; } public void Deregister(GrammarEnumerationAlgorithm algorithm) { algorithm.Started -= GrammarEnumerationAlgorithmOnStarted; algorithm.Stopped -= GrammarEnumerationAlgorithmOnStopped; algorithm.ExceptionOccurred -= GrammarEnumerationAlgorithmOnStopped; algorithm.PhraseFetched -= PhraseFetched; algorithm.PhraseDerived -= PhraseDerived; algorithm.SentenceGenerated -= SentenceGenerated; } private void GrammarEnumerationAlgorithmOnStarted(object sender, EventArgs eventArgs) { dotFileTrace = new TextWriterTraceListener(new FileStream(dotFileName, FileMode.Create)); ((StreamWriter)dotFileTrace.Writer).AutoFlush = true; dotFileTrace.WriteLine("digraph searchgraph { pad=0.02; nodesep=0.3; ranksep=0.02;ratio=0.5625;"); } private void GrammarEnumerationAlgorithmOnStopped(object sender, EventArgs eventArgs) { try { var alg = (GrammarEnumerationAlgorithm)sender; var phrase0 = new SymbolString(new[] { alg.Grammar.StartSymbol }); var phrase0Hash = alg.Grammar.Hasher.CalcHashCode(phrase0); dotFileTrace.WriteLine($"{phrase0Hash} [label=\"{phrase0}\", shape=doublecircle]; }}"); dotFileTrace.Flush(); } catch (Exception) { dotFileTrace.Close(); throw; } } private void PhraseFetched(object sender, PhraseEventArgs phraseEventArgs) { dotFileTrace.WriteLine($"{phraseEventArgs.Hash} [label=\"{phraseEventArgs.Phrase}\"];"); } private void PhraseDerived(object sender, PhraseAddedEventArgs args) { dotFileTrace.WriteLine($"{args.ParentHash} -> {args.NewHash} [label=\"{args.ExpandedSymbol.StringRepresentation} + → {args.ExpandedProduction}\"];"); } private void SentenceGenerated(object sender, PhraseAddedEventArgs args) { var alg = (GrammarEnumerationAlgorithm)sender; dotFileTrace.WriteLine($"{args.NewHash} [label=\"{alg.Grammar.ToInfixString(args.NewPhrase)}\", style=\"filled\", fillcolor=\"#f79423\", color=\"#f79423\"];"); } } }