Free cookie consent management tool by TermsFeed Policy Generator

source: branches/2895_PushGP_GenealogyAnalysis/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/ExpressionTable.cs @ 16003

Last change on this file since 16003 was 15771, checked in by bburlacu, 7 years ago

#2895: Add solution skeleton for PushGP with genealogy analysis.

File size: 9.4 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4
5namespace HeuristicLab.Problems.ProgramSynthesis {
6
7  public static class ExpressionTable {
8    public static readonly IReadOnlyDictionary<Type, Expression> StatelessExpressionTable;
9    public static readonly IReadOnlyDictionary<Type, Func<Expression>> StatefulExpressionFactory;
10    public static readonly IReadOnlyList<string> ExpressionNames;
11    public static readonly int ExpressionCount;
12
13    private static readonly Dictionary<int, string> indexToNameTable = new Dictionary<int, string>();
14    private static readonly Dictionary<Type, string> typeToNameTable = new Dictionary<Type, string>();
15    private static readonly Dictionary<string, Type> nameToTypeTable = new Dictionary<string, Type>();
16    private static readonly Dictionary<StackTypes, IList<string>> stackTypeToNamesTable = new Dictionary<StackTypes, IList<string>>();
17    private static readonly Dictionary<StackTypes, IList<string>> stackDependencyToNamesTable = new Dictionary<StackTypes, IList<string>>();
18    private static readonly Dictionary<Type, PushExpressionAttribute> typeToAttributeTable = new Dictionary<Type, PushExpressionAttribute>();
19    private static readonly List<Expression> inExpressionTable = new List<Expression>();
20
21    public static readonly IReadOnlyList<Type> StatelessExpressionTypes;
22    public static readonly IReadOnlyList<Type> StatefulExpressionTypes;
23
24    static ExpressionTable() {
25      StatelessExpressionTypes = GetExpressionTypes(typeof(StatelessExpression)).ToList();
26      StatefulExpressionTypes = GetExpressionTypes(typeof(StatefulExpression<>)).ToList();
27
28      StatelessExpressionTable = GetStatelessExpressionTable();
29      StatefulExpressionFactory = GetStatefulExpressionFactory();
30
31      ExpressionNames = StatelessExpressionTable.Keys
32        .Concat(StatefulExpressionFactory.Keys)
33        .Where(t => typeToNameTable.ContainsKey(t))
34        .Select(type => typeToNameTable[type])
35        .ToList();
36
37      ExpressionCount = StatelessExpressionTable.Count + StatefulExpressionFactory.Count;
38    }
39
40    public static IReadOnlyDictionary<int, string> IndexToNameTable { get { return indexToNameTable; } }
41    public static IReadOnlyDictionary<Type, string> TypeToNameTable { get { return typeToNameTable; } }
42    public static IReadOnlyDictionary<string, Type> NameToTypeTable { get { return nameToTypeTable; } }
43    public static IReadOnlyList<Expression> InExpressionTable { get { return inExpressionTable; } }
44    public static IReadOnlyDictionary<StackTypes, IList<string>> StackTypeToNamesTable { get { return stackTypeToNamesTable; } }
45    public static IReadOnlyDictionary<StackTypes, IList<string>> StackDependencyToNamesTable { get { return stackDependencyToNamesTable; } }
46    public static IReadOnlyDictionary<Type, PushExpressionAttribute> TypeToAttributeTable { get { return typeToAttributeTable; } }
47
48    private static Dictionary<Type, Expression> GetStatelessExpressionTable() {
49      var dictionary = new Dictionary<Type, Expression>();
50
51      foreach (var type in StatelessExpressionTypes) {
52        var expression = Activator.CreateInstance(type) as Expression;
53        var attribute = (PushExpressionAttribute)Attribute.GetCustomAttribute(type, typeof(PushExpressionAttribute));
54
55        typeToAttributeTable.Add(type, attribute);
56        dictionary.Add(type, expression);
57
58        indexToNameTable.Add(indexToNameTable.Keys.Count, attribute.Name);
59        typeToNameTable.Add(type, attribute.Name);
60        nameToTypeTable.Add(attribute.Name, type);
61
62        if (attribute.IsInExpression) {
63          // ReSharper disable once AssignNullToNotNullAttribute
64          // ReSharper disable once PossibleInvalidOperationException
65          inExpressionTable.Insert(attribute.InExpressionNr.Value - 1, expression);
66        }
67
68        if (!stackTypeToNamesTable.ContainsKey(attribute.StackType)) {
69          stackTypeToNamesTable.Add(attribute.StackType, new List<string>());
70        }
71
72        stackTypeToNamesTable[attribute.StackType].Add(attribute.Name);
73
74        var dependencies = attribute.StackType | attribute.AdditionalStackDependencies;
75        if (!stackDependencyToNamesTable.ContainsKey(dependencies)) {
76          stackDependencyToNamesTable.Add(dependencies, new List<string>());
77        }
78
79        stackDependencyToNamesTable[dependencies].Add(attribute.Name);
80      }
81
82      return dictionary;
83    }
84
85    private static Dictionary<Type, Func<Expression>> GetStatefulExpressionFactory() {
86      var dictionary = new Dictionary<Type, Func<Expression>>();
87
88      foreach (var type in StatefulExpressionTypes) {
89        // Make a NewExpression that calls the ctor
90        var newExp = System.Linq.Expressions.Expression.New(type);
91
92        // Create a lambda with the New expression as body
93        var creator = System.Linq.Expressions.Expression.Lambda<Func<Expression>>(newExp).Compile();
94        var attribute = (PushExpressionAttribute)Attribute.GetCustomAttribute(type, typeof(PushExpressionAttribute));
95
96        typeToAttributeTable.Add(type, attribute);
97        dictionary.Add(type, creator);
98
99        // do not index hidden expressions like push expression in tables
100        if (attribute.IsHidden) continue;
101
102        indexToNameTable.Add(indexToNameTable.Keys.Count, attribute.Name);
103        typeToNameTable.Add(type, attribute.Name);
104        nameToTypeTable.Add(attribute.Name, type);
105
106        if (!stackTypeToNamesTable.ContainsKey(attribute.StackType)) {
107          stackTypeToNamesTable.Add(attribute.StackType, new List<string>());
108        }
109
110        stackTypeToNamesTable[attribute.StackType].Add(attribute.Name);
111
112        var dependencies = attribute.StackType | attribute.AdditionalStackDependencies;
113        if (!stackDependencyToNamesTable.ContainsKey(dependencies)) {
114          stackDependencyToNamesTable.Add(dependencies, new List<string>());
115        }
116
117        stackDependencyToNamesTable[dependencies].Add(attribute.Name);
118      }
119
120      return dictionary;
121    }
122
123
124
125    private static IEnumerable<Type> GetExpressionTypes(Type baseType) {
126      return from domainAssembly in AppDomain.CurrentDomain.GetAssemblies()
127             from assemblyType in domainAssembly.GetTypes()
128             where !assemblyType.IsAbstract &&
129                   assemblyType.IsSubclass(baseType) &&
130                   assemblyType.GetConstructor(Type.EmptyTypes) != null
131             select assemblyType;
132    }
133
134    public static IReadOnlyList<string> GetExpressionsByStackTypes(StackTypes allowedTypes) {
135      return stackDependencyToNamesTable
136          .Where(entry => (entry.Key & ~allowedTypes) == 0x0)
137          .SelectMany(entry => entry.Value)
138          .ToList();
139    }
140
141    public static PushProgram GetProgram(IManagedPool<PushProgram> pool, int[] index) {
142      var expressions = new Expression[index.Length];
143
144      for (var i = 0; i < index.Length; i++) {
145        expressions[i] = GetExpression(index[i]);
146      }
147
148      return PushProgram.Create(pool, expressions);
149    }
150
151    public static Expression GetExpression(int index) {
152      return GetExpression(indexToNameTable[index]);
153    }
154
155    public static Expression GetExpression(Type type) {
156      var name = TypeToNameTable[type];
157      return GetExpression(name);
158    }
159
160    public static Expression GetExpression(string name) {
161      Expression expression;
162
163      if (!TryGetStatelessExpression(name, out expression) &&
164          !TryGetStatefulExpression(name, out expression))
165        throw new InvalidOperationException(string.Format("Expression with name {0} not found", name));
166
167      return expression;
168    }
169
170    public static Expression GetStatelessExpression<T>() where T : StatelessExpression {
171      Expression expression;
172      var type = typeof(T);
173
174      if (StatelessExpressionTable.TryGetValue(type, out expression))
175        return expression;
176
177      throw new NotSupportedException("Expression not supported: " + type.Name);
178    }
179
180    public static Expression GetStatelessExpression(string name) {
181      Type type;
182      Expression expression;
183
184      if (NameToTypeTable.TryGetValue(name, out type) && StatelessExpressionTable.TryGetValue(type, out expression))
185        return expression;
186
187      throw new NotSupportedException("Expression not supported: " + name);
188    }
189
190    public static bool TryGetStatelessExpression(string name, out Expression expression) {
191      Type type;
192      if (!NameToTypeTable.TryGetValue(name, out type) || !StatelessExpressionTable.TryGetValue(type, out expression)) {
193        expression = null;
194        return false;
195      }
196
197      return true;
198    }
199
200    public static Expression GetStatefulExpression<T>() {
201      return GetStatefulExpression(typeToNameTable[typeof(T)]);
202    }
203
204    public static Expression GetStatefulExpression(string name) {
205      Type type;
206      Func<Expression> creator;
207
208      if (NameToTypeTable.TryGetValue(name, out type) && StatefulExpressionFactory.TryGetValue(type, out creator)) {
209        return creator();
210      }
211
212      throw new NotSupportedException("Expression not supported: " + name);
213    }
214
215    public static bool TryGetStatefulExpression(string name, out Expression expression) {
216      if (NameToTypeTable.ContainsKey(name)) {
217        expression = StatefulExpressionFactory[NameToTypeTable[name]]();
218        return true;
219      }
220
221      expression = default(Expression);
222      return false;
223    }
224  }
225}
Note: See TracBrowser for help on using the repository browser.