Free cookie consent management tool by TermsFeed Policy Generator

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

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

#2665 BenchmarkSuite, all examples, partially tested, VectorExpressions added

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