Free cookie consent management tool by TermsFeed Policy Generator

source: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/ExpressionTable.cs @ 15189

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

#2665 Fixed small issues, testet benchmark suite, added INX Expressions

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