Free cookie consent management tool by TermsFeed Policy Generator

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

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

#2665 LexicaseSelector, Performance improvements, UI Fixes, Debugger only shows used stacks, fixed Debugger stepping, Added vector expressions, ERCOptions,

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