Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Algorithms.GeneticProgramming/GenericSymbExprGrammar.cs @ 14035

Last change on this file since 14035 was 11857, checked in by gkronber, 10 years ago

#2283: solution reorg

File size: 4.4 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Diagnostics;
4using System.Linq;
5using System.Text;
6using System.Text.RegularExpressions;
7using HeuristicLab.Common;
8using HeuristicLab.Core;
9using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
10using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
11using HeuristicLab.PluginInfrastructure;
12
13namespace HeuristicLab.Problems.GrammaticalOptimization {
14  [NonDiscoverableType]
15  [StorableClass]
16  [Item("GenericSymbExprGrammar", "Represents a general grammar for grammatical optimization problems.")]
17  public class GenericSymbExprGrammar : SymbolicExpressionGrammar {
18    [StorableClass]
19    [Item("GenericSymbol", "")]
20    public sealed class GenericSymbol : Symbol {
21      private readonly int minimumArity = 1;
22      private readonly int maximumArity = byte.MaxValue;
23
24      public override int MinimumArity { get { return minimumArity; } }
25      public override int MaximumArity { get { return maximumArity; } }
26
27      [StorableConstructor]
28      private GenericSymbol(bool deserializing) : base(deserializing) { }
29      private GenericSymbol(GenericSymbol original, Cloner cloner) : base(original, cloner) { }
30      public override IDeepCloneable Clone(Cloner cloner) {
31        return new GenericSymbol(this, cloner);
32      }
33      public GenericSymbol(char s, int minArity, int maxArity)
34        : base(s.ToString(), string.Empty) {
35        this.minimumArity = minArity;
36        this.maximumArity = maxArity;
37      }
38    }
39
40    [StorableConstructor]
41    public GenericSymbExprGrammar(bool deserializing) : base(deserializing) { }
42
43    public GenericSymbExprGrammar(SymbolicExpressionGrammar original, Cloner cloner) : base(original, cloner) { }
44
45    public GenericSymbExprGrammar(IGrammar grammar)
46      : base(ItemAttribute.GetName(typeof(GenericSymbExprGrammar)), ItemAttribute.GetDescription(typeof(GenericSymbExprGrammar))) {
47
48      var ntSymbs = new List<GenericSymbol>();
49      var tSymbs = new List<GenericSymbol>();
50      // for terminal and nonterminal symbol in the grammar create a symbol class
51      // for non-terminals set the arity and the allowed children
52      // for terminals set arity to 0 and allowed children to empty
53      foreach (var nt in grammar.NonTerminalSymbols) {
54        var ntSymb = CreateSymbol(grammar, nt);
55        AddSymbol(ntSymb);
56        SetSubtreeCount(ntSymb, ntSymb.MinimumArity, ntSymb.MaximumArity);
57        ntSymbs.Add(ntSymb);
58      }
59      foreach (var t in grammar.TerminalSymbols) {
60        var tSymb = new GenericSymbol(t, 0, 0);
61        AddSymbol(tSymb);
62        SetSubtreeCount(tSymb, 0, 0);
63        tSymbs.Add(tSymb);
64      }
65
66      Func<char, GenericSymbol> findSymb = (char s) => {
67        var selectedSymb = ntSymbs.SingleOrDefault(symb => symb.Name == s.ToString());
68        if (selectedSymb != null) return selectedSymb;
69        return tSymbs.SingleOrDefault(symb => symb.Name == s.ToString());
70      };
71
72      // set the sentence symbol as the allowed start symbol
73      AddAllowedChildSymbol(StartSymbol, findSymb(grammar.SentenceSymbol));
74
75      foreach (var nt in ntSymbs) {
76        // either all alts are only a single symbol
77        // or all alts only use a single symbol (see assertion in CreateSymbol)
78        var alts = grammar.GetAlternatives(nt.Name[0]); // all symbols only have a single character name
79        Debug.Assert(alts.All(alt => alt.Length == 1 || alt.Distinct().Count() == 1));
80
81        foreach (var alt in alts) {
82          Debug.Assert(alt.All(ch => ch == alt[0]));
83          AddAllowedChildSymbol(nt, findSymb(alt.First()));
84        }
85      }
86    }
87
88    private GenericSymbol CreateSymbol(IGrammar g, char s) {
89
90      var minArity = g.GetAlternatives(s).Select(alt => alt.Length).Min();
91      var maxArity = g.GetAlternatives(s).Select(alt => alt.Length).Max();
92      // either the min and max arity is 1 or the alternatives all use the same symbol (hl doesn't know about dependencies between positions in the alternative
93      Debug.Assert(
94        (minArity == 1 && maxArity == 1) ||
95        g.GetAlternatives(s).Select(alt => alt.Distinct()).All(alt => alt.Count() == 1));
96      var symb = new GenericSymbol(s, minArity, maxArity);
97      return symb;
98    }
99
100    public override IDeepCloneable Clone(Cloner cloner) {
101      return new GenericSymbExprGrammar(this, cloner);
102    }
103  }
104}
Note: See TracBrowser for help on using the repository browser.