Free cookie consent management tool by TermsFeed Policy Generator

source: branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/GrammarEnumeration/GrammarEnumerationAlgorithm.cs @ 16022

Last change on this file since 16022 was 16022, checked in by bburlacu, 6 years ago

#2886: Remove MaxSentenceLength from priority calculation for the time being.

File size: 23.1 KB
RevLine 
[15765]1using System;
2using System.Collections.Generic;
[15712]3using System.Linq;
4using System.Threading;
5using HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration.GrammarEnumeration;
[15957]6using HeuristicLab.Collections;
[15712]7using HeuristicLab.Common;
8using HeuristicLab.Core;
9using HeuristicLab.Data;
10using HeuristicLab.Optimization;
[15722]11using HeuristicLab.Parameters;
[15712]12using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
13using HeuristicLab.Problems.DataAnalysis;
[15974]14using HeuristicLab.Problems.DataAnalysis.Symbolic;
15using HeuristicLab.Problems.DataAnalysis.Symbolic.Regression;
[15712]16
17namespace HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration {
18  [Item("Grammar Enumeration Symbolic Regression", "Iterates all possible model structures for a fixed grammar.")]
19  [StorableClass]
20  [Creatable(CreatableAttribute.Categories.DataAnalysisRegression, Priority = 250)]
21  public class GrammarEnumerationAlgorithm : FixedDataAnalysisAlgorithm<IRegressionProblem> {
[15746]22    #region properties and result names
[15803]23    private readonly string SearchStructureSizeName = "Search Structure Size";
24    private readonly string GeneratedPhrasesName = "Generated/Archived Phrases";
[15746]25    private readonly string GeneratedSentencesName = "Generated Sentences";
26    private readonly string DistinctSentencesName = "Distinct Sentences";
27    private readonly string PhraseExpansionsName = "Phrase Expansions";
[15860]28    private readonly string AverageSentenceComplexityName = "Avg. Sentence Complexity among Distinct";
[15821]29    private readonly string OverwrittenSentencesName = "Sentences overwritten";
30    private readonly string AnalyzersParameterName = "Analyzers";
[15824]31    private readonly string ExpansionsPerSecondName = "Expansions per second";
[15712]32
[15861]33    private readonly string OptimizeConstantsParameterName = "Optimize Constants";
[15910]34    private readonly string ErrorWeightParameterName = "Error Weight";
[15746]35    private readonly string SearchDataStructureParameterName = "Search Data Structure";
[15860]36    private readonly string MaxComplexityParameterName = "Max. Complexity";
[15722]37    private readonly string GuiUpdateIntervalParameterName = "GUI Update Interval";
[15930]38    private readonly string GrammarSymbolsParameterName = "Grammar Symbols";
[15974]39    private readonly string SearchDataStructureSizeParameterName = "Search Data Structure Size";
[15765]40
[15974]41    // result names
42    public static readonly string BestTrainingModelResultName = "Best model (Training)";
43    public static readonly string BestTrainingSolutionResultName = "Best solution (Training)";
44    public static readonly string BestComplexityResultName = "Best solution complexity";
45
[15960]46    public override bool SupportsPause { get { return true; } }
[15712]47
[15974]48    protected IFixedValueParameter<BoolValue> OptimizeConstantsParameter {
49      get { return (IFixedValueParameter<BoolValue>)Parameters[OptimizeConstantsParameterName]; }
[15861]50    }
51
52    public bool OptimizeConstants {
53      get { return OptimizeConstantsParameter.Value.Value; }
54      set { OptimizeConstantsParameter.Value.Value = value; }
55    }
56
[15974]57    protected IFixedValueParameter<IntValue> MaxComplexityParameter {
58      get { return (IFixedValueParameter<IntValue>)Parameters[MaxComplexityParameterName]; }
[15712]59    }
[15974]60
[15860]61    public int MaxComplexity {
62      get { return MaxComplexityParameter.Value.Value; }
63      set { MaxComplexityParameter.Value.Value = value; }
[15722]64    }
[15712]65
[15974]66    protected IFixedValueParameter<DoubleValue> ErrorWeightParameter {
67      get { return (IFixedValueParameter<DoubleValue>)Parameters[ErrorWeightParameterName]; }
[15910]68    }
[15974]69
[15910]70    public double ErrorWeight {
71      get { return ErrorWeightParameter.Value.Value; }
72      set { ErrorWeightParameter.Value.Value = value; }
73    }
74
[15974]75    protected IFixedValueParameter<IntValue> GuiUpdateIntervalParameter {
76      get { return (IFixedValueParameter<IntValue>)Parameters[GuiUpdateIntervalParameterName]; }
[15722]77    }
[15974]78
[15722]79    public int GuiUpdateInterval {
80      get { return GuiUpdateIntervalParameter.Value.Value; }
[15723]81      set { GuiUpdateIntervalParameter.Value.Value = value; }
[15722]82    }
[15712]83
[15974]84    protected IFixedValueParameter<EnumValue<StorageType>> SearchDataStructureParameter {
85      get { return (IFixedValueParameter<EnumValue<StorageType>>)Parameters[SearchDataStructureParameterName]; }
[15723]86    }
[15974]87
88    public IFixedValueParameter<IntValue> SearchDataStructureSizeParameter {
89      get { return (IFixedValueParameter<IntValue>)Parameters[SearchDataStructureSizeParameterName]; }
90    }
91
92    public int SearchDataStructureSize {
93      get { return SearchDataStructureSizeParameter.Value.Value; }
94    }
95
[15746]96    public StorageType SearchDataStructure {
97      get { return SearchDataStructureParameter.Value.Value; }
98      set { SearchDataStructureParameter.Value.Value = value; }
[15723]99    }
100
[15821]101    public IFixedValueParameter<ReadOnlyCheckedItemCollection<IGrammarEnumerationAnalyzer>> AnalyzersParameter {
102      get { return (IFixedValueParameter<ReadOnlyCheckedItemCollection<IGrammarEnumerationAnalyzer>>)Parameters[AnalyzersParameterName]; }
103    }
104
105    public ICheckedItemCollection<IGrammarEnumerationAnalyzer> Analyzers {
106      get { return AnalyzersParameter.Value; }
107    }
108
[15930]109    public IFixedValueParameter<ReadOnlyCheckedItemCollection<EnumValue<GrammarRule>>> GrammarSymbolsParameter {
110      get { return (IFixedValueParameter<ReadOnlyCheckedItemCollection<EnumValue<GrammarRule>>>)Parameters[GrammarSymbolsParameterName]; }
111    }
112
113    public ReadOnlyCheckedItemCollection<EnumValue<GrammarRule>> GrammarSymbols {
114      get { return GrammarSymbolsParameter.Value; }
115    }
116
[15975]117    [Storable]
[15824]118    public SymbolString BestTrainingSentence { get; set; }     // Currently set in RSquaredEvaluator: quite hacky, but makes testing much easier for now...
[15722]119    #endregion
[15712]120
[15960]121    [Storable]
[15860]122    public Dictionary<int, int> DistinctSentencesComplexity { get; private set; }  // Semantically distinct sentences and their length in a run.
[15960]123
124    [Storable]
[15812]125    public HashSet<int> ArchivedPhrases { get; private set; }
[15960]126
127    [Storable]
[15821]128    internal SearchDataStore OpenPhrases { get; private set; }           // Stack/Queue/etc. for fetching the next node in the search tree. 
[15812]129
[15993]130    [Storable]
131    public int MaxSentenceLength { get; private set; }
132
[15821]133    #region execution stats
[15974]134    [Storable]
[15821]135    public int AllGeneratedSentencesCount { get; private set; }
[15746]136
[15974]137    [Storable]
[15821]138    public int OverwrittenSentencesCount { get; private set; } // It is not guaranteed that shorter solutions are found first.
139                                                               // When longer solutions are overwritten with shorter ones,
140                                                               // this counter is increased.
[15974]141    [Storable]
[15821]142    public int PhraseExpansionCount { get; private set; }      // Number, how many times a nonterminal symbol is replaced with a production rule.
143    #endregion
144
[15975]145    [Storable]
[15800]146    public Grammar Grammar { get; private set; }
[15712]147
[15722]148    #region ctors
149    public override IDeepCloneable Clone(Cloner cloner) {
150      return new GrammarEnumerationAlgorithm(this, cloner);
151    }
[15712]152
[15975]153    [StorableConstructor]
154    protected GrammarEnumerationAlgorithm(bool deserializing) : base(deserializing) { }
155
[15979]156    private void RegisterEvents() {
157      // re-wire analyzer events
158      foreach (var analyzer in Analyzers.CheckedItems)
159        analyzer.Register(this);
160      Analyzers.CheckedItemsChanged += Analyzers_CheckedItemsChanged;
161
162      SearchDataStructureParameter.Value.ValueChanged += (o, e) => Prepare();
163      SearchDataStructureSizeParameter.Value.ValueChanged += (o, e) => Prepare();
164    }
165
166    private void DeregisterEvents() {
167      foreach (var analyzer in Analyzers.CheckedItems)
168        analyzer.Register(this);
169      Analyzers.CheckedItemsChanged -= Analyzers_CheckedItemsChanged;
170
171      SearchDataStructureParameter.Value.ValueChanged -= (o, e) => Prepare();
172      SearchDataStructureSizeParameter.Value.ValueChanged -= (o, e) => Prepare();
173    }
174
175    [StorableHook(HookType.AfterDeserialization)]
176    private void AfterDeserialization() {
177      RegisterEvents();
178    }
179
[15722]180    public GrammarEnumerationAlgorithm() {
[15974]181      Parameters.Add(new FixedValueParameter<BoolValue>(OptimizeConstantsParameterName, "Run constant optimization in sentence evaluation.", new BoolValue(false)));
182      Parameters.Add(new FixedValueParameter<DoubleValue>(ErrorWeightParameterName, "Defines, how much weight is put on a phrase's r² value when priorizing phrases during search.", new DoubleValue(0.8)));
183      Parameters.Add(new FixedValueParameter<IntValue>(MaxComplexityParameterName, "The maximum number of variable symbols in a sentence.", new IntValue(12)));
184      Parameters.Add(new FixedValueParameter<IntValue>(GuiUpdateIntervalParameterName, "Number of generated sentences, until GUI is refreshed.", new IntValue(5000)));
185      Parameters.Add(new FixedValueParameter<IntValue>(SearchDataStructureSizeParameterName, "The size of the search data structure.", new IntValue((int)1e5)));
[15993]186      Parameters.Add(new FixedValueParameter<EnumValue<StorageType>>(SearchDataStructureParameterName, new EnumValue<StorageType>(StorageType.SortedSet)));
[15821]187
[15974]188      SearchDataStructureParameter.Value.ValueChanged += (o, e) => Prepare();
189      SearchDataStructureSizeParameter.Value.ValueChanged += (o, e) => Prepare();
190
[15821]191      var availableAnalyzers = new IGrammarEnumerationAnalyzer[] {
192        new SearchGraphVisualizer(),
[15824]193        new SentenceLogger(),
194        new RSquaredEvaluator()
[15821]195      };
[15974]196
[15821]197      Parameters.Add(new FixedValueParameter<ReadOnlyCheckedItemCollection<IGrammarEnumerationAnalyzer>>(
198        AnalyzersParameterName,
199        new CheckedItemCollection<IGrammarEnumerationAnalyzer>(availableAnalyzers).AsReadOnly()));
200
[15957]201      Analyzers.CheckedItemsChanged += Analyzers_CheckedItemsChanged;
202
[15821]203      foreach (var analyzer in Analyzers) {
204        Analyzers.SetItemCheckedState(analyzer, false);
205      }
[15824]206      Analyzers.SetItemCheckedState(Analyzers.First(analyzer => analyzer is RSquaredEvaluator), true);
[15930]207
208      var grammarSymbols = Enum.GetValues(typeof(GrammarRule))
209        .Cast<GrammarRule>()
210        .Select(v => new EnumValue<GrammarRule>(v));
211
212      Parameters.Add(new FixedValueParameter<ReadOnlyCheckedItemCollection<EnumValue<GrammarRule>>>(
213        GrammarSymbolsParameterName,
214        new ReadOnlyCheckedItemCollection<EnumValue<GrammarRule>>(new CheckedItemCollection<EnumValue<GrammarRule>>(grammarSymbols))
215      ));
216      foreach (EnumValue<GrammarRule> grammarSymbol in GrammarSymbols) {
217        GrammarSymbols.SetItemCheckedState(grammarSymbol, true);
218      }
[15957]219
220      // set a default problem
221      Problem = new RegressionProblem() {
[15974]222        ProblemData = new Problems.Instances.DataAnalysis.PolyTen(seed: 1234).GenerateRegressionData()
[15957]223      };
[15722]224    }
[15712]225
[15910]226    public GrammarEnumerationAlgorithm(GrammarEnumerationAlgorithm original, Cloner cloner) : base(original, cloner) {
[15957]227      foreach (var analyzer in Analyzers.CheckedItems)
228        analyzer.Register(this);
229      Analyzers.CheckedItemsChanged += Analyzers_CheckedItemsChanged;
[15960]230
231      DistinctSentencesComplexity = new Dictionary<int, int>(original.DistinctSentencesComplexity);
232      ArchivedPhrases = new HashSet<int>(original.ArchivedPhrases);
233      OpenPhrases = cloner.Clone(original.OpenPhrases);
[15974]234      Grammar = cloner.Clone(original.Grammar);
[15960]235
236      AllGeneratedSentencesCount = original.AllGeneratedSentencesCount;
237      OverwrittenSentencesCount = original.OverwrittenSentencesCount;
238      PhraseExpansionCount = original.PhraseExpansionCount;
[15910]239    }
[15722]240    #endregion
[15712]241
[15975]242    [Storable]
[15950]243    private Dictionary<VariableTerminalSymbol, double> variableImportance;
244
[15957]245    public override void Prepare() {
246      DistinctSentencesComplexity = new Dictionary<int, int>();
[15812]247      ArchivedPhrases = new HashSet<int>();
[15821]248      AllGeneratedSentencesCount = 0;
249      OverwrittenSentencesCount = 0;
250      PhraseExpansionCount = 0;
[15746]251
[15930]252      Grammar = new Grammar(Problem.ProblemData.AllowedInputVariables.ToArray(), GrammarSymbols.CheckedItems.Select(v => v.Value));
[15993]253      OpenPhrases = new SearchDataStore(SearchDataStructure, SearchDataStructureSize); // Select search strategy
[15957]254      base.Prepare(); // this actually clears the results which will get reinitialized on Run()
255    }
256
[15960]257    protected override void Run(CancellationToken cancellationToken) {
258      // do not reinitialize the algorithm if we're resuming from pause
259      if (previousExecutionState != ExecutionState.Paused) {
260        InitResults();
261        var phrase0 = new SymbolString(new[] { Grammar.StartSymbol });
262        var phrase0Hash = Grammar.Hasher.CalcHashCode(phrase0);
[15974]263
[15960]264        OpenPhrases.Store(new SearchNode(phrase0Hash, 0.0, 0.0, phrase0));
265      }
266
[15993]267      MaxSentenceLength = Grammar.GetMaxSentenceLength(MaxComplexity);
[15950]268      var errorWeight = ErrorWeight;
[15993]269      var optimizeConstants = OptimizeConstants; // cache value to avoid parameter lookup
[15960]270      // main search loop
[15821]271      while (OpenPhrases.Count > 0) {
[15960]272        if (cancellationToken.IsCancellationRequested)
273          break;
[15746]274
[15915]275        SearchNode fetchedSearchNode = OpenPhrases.GetNext();
[15974]276
277        if (fetchedSearchNode == null)
278          continue;
279
[15915]280        SymbolString currPhrase = fetchedSearchNode.SymbolString;
[15722]281
[15915]282        OnPhraseFetched(fetchedSearchNode.Hash, currPhrase);
[15765]283
[15915]284        ArchivedPhrases.Add(fetchedSearchNode.Hash);
[15726]285
[15821]286        // expand next nonterminal symbols
[15827]287        int nonterminalSymbolIndex = currPhrase.NextNonterminalIndex();
288        NonterminalSymbol expandedSymbol = (NonterminalSymbol)currPhrase[nonterminalSymbolIndex];
[15834]289        var appliedProductions = Grammar.Productions[expandedSymbol];
[15734]290
[15827]291        for (int i = 0; i < appliedProductions.Count; i++) {
[15821]292          PhraseExpansionCount++;
[15734]293
[15827]294          SymbolString newPhrase = currPhrase.DerivePhrase(nonterminalSymbolIndex, appliedProductions[i]);
[15860]295          int newPhraseComplexity = Grammar.GetComplexity(newPhrase);
[15712]296
[15957]297          if (newPhraseComplexity > MaxComplexity)
298            continue;
[15765]299
[15957]300          var phraseHash = Grammar.Hasher.CalcHashCode(newPhrase);
[15800]301
[15957]302          OnPhraseDerived(fetchedSearchNode.Hash, fetchedSearchNode.SymbolString, phraseHash, newPhrase, expandedSymbol, appliedProductions[i]);
[15821]303
[15957]304          if (newPhrase.IsSentence()) {
305            AllGeneratedSentencesCount++;
[15821]306
[15957]307            OnSentenceGenerated(fetchedSearchNode.Hash, fetchedSearchNode.SymbolString, phraseHash, newPhrase, expandedSymbol, appliedProductions[i]);
308
309            // Is the best solution found? (only if RSquaredEvaluator is activated)
310            if (Results.ContainsKey(RSquaredEvaluator.BestTrainingQualityResultName)) {
311              double r2 = ((DoubleValue)Results[RSquaredEvaluator.BestTrainingQualityResultName].Value).Value;
312              if (r2.IsAlmost(1.0)) {
313                UpdateView(force: true);
314                return;
[15883]315              }
[15957]316            }
[15883]317
[15957]318            if (!DistinctSentencesComplexity.ContainsKey(phraseHash) || DistinctSentencesComplexity[phraseHash] > newPhraseComplexity) {
319              if (DistinctSentencesComplexity.ContainsKey(phraseHash)) OverwrittenSentencesCount++; // for analysis only
[15821]320
[15957]321              DistinctSentencesComplexity[phraseHash] = newPhraseComplexity;
322              OnDistinctSentenceGenerated(fetchedSearchNode.Hash, fetchedSearchNode.SymbolString, phraseHash, newPhrase, expandedSymbol, appliedProductions[i]);
323            }
324            UpdateView();
[15821]325
[15957]326          } else if (!OpenPhrases.Contains(phraseHash) && !ArchivedPhrases.Contains(phraseHash)) {
[15915]327
[15987]328            bool isCompleteSentence = IsCompleteSentence(newPhrase);
[15993]329            double r2 = isCompleteSentence ? Grammar.EvaluatePhrase(newPhrase, Problem.ProblemData, optimizeConstants) : fetchedSearchNode.R2;
330            double phrasePriority = GetPriority(newPhrase, r2, MaxSentenceLength);
[15915]331
[15957]332            SearchNode newSearchNode = new SearchNode(phraseHash, phrasePriority, r2, newPhrase);
333            OpenPhrases.Store(newSearchNode);
[15712]334          }
335        }
336      }
[15812]337      UpdateView(force: true);
[15746]338    }
[15723]339
[15993]340    protected static double GetPriority(SymbolString phrase, double r2, int maxSentenceLength) {
[16022]341      return (1 - r2) * phrase.Count();
[15910]342    }
343
[15987]344    private bool IsCompleteSentence(SymbolString phrase) {
345      return !phrase.Any(x => x is NonterminalSymbol && x != Grammar.Expr);
[15915]346    }
347
[15960]348    #region pause support
349    private ExecutionState previousExecutionState;
[15979]350
[15960]351    protected override void OnPaused() {
352      previousExecutionState = this.ExecutionState;
353      base.OnPaused();
354    }
[15979]355
[15960]356    protected override void OnPrepared() {
357      previousExecutionState = this.ExecutionState;
358      base.OnPrepared();
359    }
[15979]360
[15960]361    protected override void OnStarted() {
362      previousExecutionState = this.ExecutionState;
363      base.OnStarted();
364    }
[15979]365
[15960]366    protected override void OnStopped() {
367      previousExecutionState = this.ExecutionState;
[15987]368      // free memory at the end of the run (this saves a lot of memory)
369      ArchivedPhrases.Clear();
370      OpenPhrases.Clear();
371      DistinctSentencesComplexity.Clear();
[15974]372
373      if (BestTrainingSentence == null) {
374        base.OnStopped();
375        return;
376      }
377
[15993]378      var interpreter = new SymbolicDataAnalysisExpressionTreeLinearInterpreter();
[15974]379      var tree = Grammar.ParseSymbolicExpressionTree(BestTrainingSentence);
[15993]380      var model = new SymbolicRegressionModel(Problem.ProblemData.TargetVariable, tree, interpreter);
381
382      SymbolicRegressionConstantOptimizationEvaluator.OptimizeConstants(
383        interpreter,
384        model.SymbolicExpressionTree,
385        Problem.ProblemData,
386        Problem.ProblemData.TrainingIndices,
387        applyLinearScaling: true,
388        maxIterations: 10,
389        updateVariableWeights: false,
390        updateConstantsInTree: true);
391
[15994]392      model.Scale(Problem.ProblemData);
[15974]393      var bestTrainingSolution = new SymbolicRegressionSolution(model, Problem.ProblemData);
[15994]394
[15974]395      Results.AddOrUpdateResult(BestTrainingModelResultName, model);
396      Results.AddOrUpdateResult(BestTrainingSolutionResultName, bestTrainingSolution);
397      Results.AddOrUpdateResult(BestComplexityResultName, new IntValue(Grammar.GetComplexity(BestTrainingSentence)));
[15960]398      base.OnStopped();
399    }
400    #endregion
401
[15821]402    #region Visualization in HL
[15746]403    // Initialize entries in result set.
404    private void InitResults() {
[15957]405      Results.Clear();
[15803]406      Results.Add(new Result(GeneratedPhrasesName, new IntValue(0)));
407      Results.Add(new Result(SearchStructureSizeName, new IntValue(0)));
[15746]408      Results.Add(new Result(GeneratedSentencesName, new IntValue(0)));
409      Results.Add(new Result(DistinctSentencesName, new IntValue(0)));
410      Results.Add(new Result(PhraseExpansionsName, new IntValue(0)));
[15821]411      Results.Add(new Result(OverwrittenSentencesName, new IntValue(0)));
[15860]412      Results.Add(new Result(AverageSentenceComplexityName, new DoubleValue(1.0)));
[15824]413      Results.Add(new Result(ExpansionsPerSecondName, "In Thousand expansions per second", new IntValue(0)));
[15712]414    }
[15746]415
416    // Update the view for intermediate results in an algorithm run.
417    private int updates;
[15812]418    private void UpdateView(bool force = false) {
[15746]419      updates++;
420
[15812]421      if (force || updates % GuiUpdateInterval == 1) {
[15803]422        ((IntValue)Results[GeneratedPhrasesName].Value).Value = ArchivedPhrases.Count;
423        ((IntValue)Results[SearchStructureSizeName].Value).Value = OpenPhrases.Count;
[15821]424        ((IntValue)Results[GeneratedSentencesName].Value).Value = AllGeneratedSentencesCount;
[15860]425        ((IntValue)Results[DistinctSentencesName].Value).Value = DistinctSentencesComplexity.Count;
[15821]426        ((IntValue)Results[PhraseExpansionsName].Value).Value = PhraseExpansionCount;
[15974]427        ((DoubleValue)Results[AverageSentenceComplexityName].Value).Value = DistinctSentencesComplexity.Count > 0
428          ? DistinctSentencesComplexity.Select(pair => pair.Value).Average()
429          : 0;
[15821]430        ((IntValue)Results[OverwrittenSentencesName].Value).Value = OverwrittenSentencesCount;
[15824]431        ((IntValue)Results[ExpansionsPerSecondName].Value).Value = (int)((PhraseExpansionCount /
432                                                                          ExecutionTime.TotalSeconds) / 1000.0);
[15746]433      }
434    }
[15821]435    #endregion
[15746]436
[15821]437    #region events
[15957]438
439    // private event handlers for analyzers
440    private void Analyzers_CheckedItemsChanged(object sender, CollectionItemsChangedEventArgs<IGrammarEnumerationAnalyzer> args) {
441      // newly added items
442      foreach (var item in args.Items.Except(args.OldItems).Union(args.OldItems.Except(args.Items))) {
443        if (Analyzers.ItemChecked(item)) {
444          item.Register(this);
445        } else {
446          item.Deregister(this);
447        }
448      }
449    }
450
[15821]451    public event EventHandler<PhraseEventArgs> PhraseFetched;
452    private void OnPhraseFetched(int hash, SymbolString symbolString) {
453      if (PhraseFetched != null) {
454        PhraseFetched(this, new PhraseEventArgs(hash, symbolString));
[15746]455      }
456    }
[15812]457
[15821]458    public event EventHandler<PhraseAddedEventArgs> PhraseDerived;
459    private void OnPhraseDerived(int parentHash, SymbolString parentSymbolString, int addedHash, SymbolString addedSymbolString, Symbol expandedSymbol, Production expandedProduction) {
460      if (PhraseDerived != null) {
461        PhraseDerived(this, new PhraseAddedEventArgs(parentHash, parentSymbolString, addedHash, addedSymbolString, expandedSymbol, expandedProduction));
462      }
[15803]463    }
[15765]464
[15821]465    public event EventHandler<PhraseAddedEventArgs> SentenceGenerated;
466    private void OnSentenceGenerated(int parentHash, SymbolString parentSymbolString, int addedHash, SymbolString addedSymbolString, Symbol expandedSymbol, Production expandedProduction) {
467      if (SentenceGenerated != null) {
468        SentenceGenerated(this, new PhraseAddedEventArgs(parentHash, parentSymbolString, addedHash, addedSymbolString, expandedSymbol, expandedProduction));
469      }
470    }
471
472    public event EventHandler<PhraseAddedEventArgs> DistinctSentenceGenerated;
473    private void OnDistinctSentenceGenerated(int parentHash, SymbolString parentSymbolString, int addedHash, SymbolString addedSymbolString, Symbol expandedSymbol, Production expandedProduction) {
474      if (DistinctSentenceGenerated != null) {
475        DistinctSentenceGenerated(this, new PhraseAddedEventArgs(parentHash, parentSymbolString, addedHash, addedSymbolString, expandedSymbol, expandedProduction));
476      }
477    }
478
479    #endregion
480
[15712]481  }
[15821]482
483  #region events for analysis
484
485  public class PhraseEventArgs : EventArgs {
486    public int Hash { get; }
487
488    public SymbolString Phrase { get; }
489
490    public PhraseEventArgs(int hash, SymbolString phrase) {
491      Hash = hash;
492      Phrase = phrase;
493    }
494  }
495
496  public class PhraseAddedEventArgs : EventArgs {
497    public int ParentHash { get; }
498    public int NewHash { get; }
499
500    public SymbolString ParentPhrase { get; }
501    public SymbolString NewPhrase { get; }
502
503    public Symbol ExpandedSymbol { get; }
504
505    public Production ExpandedProduction { get; }
506
507    public PhraseAddedEventArgs(int parentHash, SymbolString parentPhrase, int newHash, SymbolString newPhrase, Symbol expandedSymbol, Production expandedProduction) {
508      ParentHash = parentHash;
509      ParentPhrase = parentPhrase;
510      NewHash = newHash;
511      NewPhrase = newPhrase;
512      ExpandedSymbol = expandedSymbol;
513      ExpandedProduction = expandedProduction;
514    }
515  }
516
517  #endregion
[15712]518}
Note: See TracBrowser for help on using the repository browser.