Free cookie consent management tool by TermsFeed Policy Generator

source: addons/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/ExpressionTable.cs @ 16958

Last change on this file since 16958 was 15341, checked in by pkimmesw, 7 years ago

#2665 Testet Problems, Improved Performance

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