Free cookie consent management tool by TermsFeed Policy Generator

source: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Configuration/PushConfiguration.cs @ 14907

Last change on this file since 14907 was 14905, checked in by pkimmesw, 8 years ago

#2665 Made ErcOptions checkable

File size: 11.4 KB
Line 
1namespace HeuristicLab.Problems.ProgramSynthesis.Push.Configuration {
2  using System;
3  using System.Collections.Generic;
4  using System.Linq;
5  using Base.Erc;
6  using Common;
7  using Core;
8  using Expressions;
9  using Persistence.Default.CompositeSerializers.Storable;
10  using Stack;
11
12  [StorableClass]
13  public class PushConfiguration : ParameterizedNamedItem, IReadOnlyPushConfiguration, IEnabledExpressionsConfiguration {
14    public PushConfiguration() {
15      Name = "Push Configuration";
16
17      enabledExpressions = ExpressionTable.ExpressionNames.ToList();
18      enabledStacks = new Dictionary<StackTypes, bool>();
19
20      ErcOptions = new ErcOptions();
21      EvalPushLimit = 1024;
22      MinPointsInProgram = 25;
23      MaxPointsInProgram = 200;
24      TopLevelPushCode = true;
25      TopLevelPopCode = false;
26      MaxPointsInRandomExpression = 64;
27      MaxStringLength = 128;
28      MaxVectorLength = 64;
29      MaxDepth = 32;
30
31      InitEnabledStacks();
32    }
33
34    private void InitEnabledStacks(bool state = true) {
35      foreach (StackTypes type in Enum.GetValues(typeof(StackTypes))) {
36        if (!enabledStacks.ContainsKey(type) && type != StackTypes.None)
37          enabledStacks.Add(type, state);
38      }
39    }
40
41    [StorableConstructor]
42    public PushConfiguration(bool deserializing)
43      : base(deserializing) {
44    }
45
46    public PushConfiguration(PushConfiguration origin, Cloner cloner) : base(origin, cloner) {
47      enabledExpressions = origin.EnabledExpressions.ToList();
48      enabledStacks = origin.EnabledStacks.ToDictionary(x => x.Key, x => x.Value);
49
50      ErcOptions = cloner.Clone(origin.ErcOptions);
51      EvalPushLimit = origin.EvalPushLimit;
52      MinPointsInProgram = origin.MinPointsInProgram;
53      MaxPointsInProgram = origin.MaxPointsInProgram;
54      MaxPointsInRandomExpression = origin.MaxPointsInRandomExpression;
55      TopLevelPushCode = origin.TopLevelPushCode;
56      TopLevelPopCode = origin.TopLevelPopCode;
57      MaxStringLength = origin.MaxStringLength;
58      MaxVectorLength = origin.MaxVectorLength;
59      MaxDepth = origin.MaxDepth;
60    }
61
62    [StorableHook(HookType.AfterDeserialization)]
63    // ReSharper disable once UnusedMember.Local
64    private void AfterDeserialization() {
65      // Ensures that all types added after last serialization are available in enabledStacks
66      InitEnabledStacks(false);
67    }
68
69
70    [Storable]
71    private readonly Dictionary<StackTypes, bool> enabledStacks;
72
73    public IReadOnlyDictionary<StackTypes, bool> EnabledStacks { get { return enabledStacks; } }
74
75    public event EventHandler<EnabledExpressionsChangedEventArgs> EnabledExpressionsChanged;
76
77    [Storable]
78    private readonly List<string> enabledExpressions;
79
80    public IList<string> EnabledExpressions
81    {
82      get { return enabledExpressions; }
83      set
84      {
85        var removedExpressions = enabledExpressions.ToArray();
86        enabledExpressions.Clear();
87        enabledExpressions.AddRange(value);
88
89        if (EnabledExpressionsChanged != null) {
90          EnabledExpressionsChanged(this, new EnabledExpressionsChangedEventArgs(value, removedExpressions));
91        }
92      }
93    }
94
95    IReadOnlyList<string> IReadOnlyPushConfiguration.EnabledExpressions { get { return enabledExpressions; } }
96
97    [Storable]
98    public ErcOptions ErcOptions { get; set; }
99
100    IReadOnlyErcOptions IReadOnlyPushConfiguration.ErcOptions { get { return ErcOptions; } }
101
102    /// <summary>
103    ///     This is the maximum allowed number of "executions" in a single top-level call to the interpreter.
104    ///     The execution of a single Push instruction counts as one execution, as does the processing of a single literal,
105    ///     as does the descent into one layer of parentheses (that is, the processing of the "(" counts as one execution).
106    ///     When this limit is exceeded the interpreter aborts immediately, leaving its stacks in the states they were in prior
107    ///     to the abort (so they may still be examined by a calling program). Whether or not this counts as an "abnormal"
108    ///     termination
109    ///     is up to the calling program.
110    /// </summary>
111    [Storable]
112    public int EvalPushLimit { get; set; }
113
114    /// <summary>
115    /// This is the maximum of depth a push program can have. Expressions, which lead to exceed this limit are interpreted as NOOP.
116    /// </summary>
117    [Storable]
118    public int MaxDepth { get; set; }
119
120    /// <summary>
121    ///     This is the minimum size of an item on the CODE stack, expressed as a number of points.
122    ///     A point is an instruction, a literal, or a pair of parentheses. Any instruction that would cause this limit to be
123    ///     exceeded should instead act as a NOOP, leaving all stacks in the states that they were in before the execution of the
124    ///     instruction.
125    /// </summary>
126    [Storable]
127    public int MinPointsInProgram { get; set; }
128
129    /// <summary>
130    ///     This is the maximum size of an item on the CODE stack, expressed as a number of points.
131    ///     A point is an instruction, a literal, or a pair of parentheses. Any instruction that would cause this limit to be
132    ///     exceeded should instead act as a NOOP, leaving all stacks in the states that they were in before the execution of the
133    ///     instruction.
134    /// </summary>
135    [Storable]
136    public int MaxPointsInProgram { get; set; }
137
138    /// <summary>
139    ///     The maximum number of points in an expression produced by the CODE.RAND instruction.
140    /// </summary>
141    [Storable]
142    public int MaxPointsInRandomExpression { get; set; }
143
144    /// <summary>
145    ///     When TRUE (which is the default), code passed to the top level of the interpreter
146    ///     will be pushed onto the CODE stack prior to execution.
147    /// </summary>
148    [Storable]
149    public bool TopLevelPushCode { get; set; }
150
151    /// <summary>
152    ///     When TRUE, the CODE stack will be popped at the end of top level calls to the interpreter. The default is FALSE.
153    /// </summary>
154    [Storable]
155    public bool TopLevelPopCode { get; set; }
156
157    [Storable]
158    public int MaxStringLength { get; set; }
159
160    [Storable]
161    public int MaxVectorLength { get; set; }
162
163
164    public void SetEnabledStacks(StackTypes types) {
165      // Disable all
166      EnabledExpressions.Clear();
167
168      // Enable those are required
169      foreach (StackTypes type in Enum.GetValues(types.GetType())) {
170        if (type == StackTypes.None) continue;
171
172        enabledStacks[type] = false;
173
174        if (types.HasFlag(type))
175          EnableStack(type, false, true);
176      }
177    }
178
179    public void EnableExpressionOfStack(StackTypes types) {
180      EnableExpressions(ExpressionTable.StackTypeToNamesTable[types]);
181    }
182
183    public void EnableExpressionDependentOnStack(StackTypes types) {
184      var names = ExpressionTable.StackDependencyToNamesTable[types].Where(
185        name => {
186          var type = ExpressionTable.NameToTypeTable[name];
187          var attribute = ExpressionTable.TypeToAttributeTable[type];
188
189          return (attribute.StackType | attribute.AdditionalStackDependencies)
190            .ToEnumerable()
191            .All(st => enabledStacks.ContainsKey(st) && enabledStacks[st]);
192        });
193
194      EnableExpressions(names);
195    }
196
197    private void EnableExpressions(IEnumerable<string> names) {
198      foreach (var name in names.Except(EnabledExpressions))
199        EnabledExpressions.Add(name);
200
201      if (EnabledExpressionsChanged != null) {
202        EnabledExpressionsChanged(this, new EnabledExpressionsChangedEventArgs(names, new string[0]));
203      }
204    }
205
206    public void DisableExpressionsOfStack(StackTypes types) {
207      DisableExpressions(ExpressionTable.StackTypeToNamesTable[types]);
208    }
209
210    public void DisableExpressionsDependentOnStack(StackTypes types) {
211      var names = ExpressionTable.StackDependencyToNamesTable
212          .Where(pair => pair.Key.HasFlag(types))
213          .SelectMany(pair => pair.Value);
214
215      DisableExpressions(names);
216    }
217
218    private void DisableExpressions(IEnumerable<string> names) {
219      foreach (var name in names.Intersect(EnabledExpressions))
220        EnabledExpressions.Remove(name);
221
222      if (EnabledExpressionsChanged != null) {
223        EnabledExpressionsChanged(this, new EnabledExpressionsChangedEventArgs(new string[0], names));
224      }
225    }
226
227    public void EnableExpression(string name, bool enableStackIfDisabled = false) {
228      if (EnabledExpressions.Contains(name)) return;
229
230      EnabledExpressions.Add(name);
231
232      if (enableStackIfDisabled) {
233        var type = ExpressionTable.TypeToNameTable.Single(x => x.Value == name).Key;
234        var attribute = ExpressionTable.TypeToAttributeTable[type];
235        enabledStacks[attribute.StackType] = true;
236      }
237
238      if (EnabledExpressionsChanged != null) {
239        EnabledExpressionsChanged(this, new EnabledExpressionsChangedEventArgs(
240          new[] { name },
241          new string[0]));
242      }
243    }
244
245    public void DisableExpression(string name, bool disableStackIfEnabled = false) {
246      if (!EnabledExpressions.Contains(name)) return;
247
248      EnabledExpressions.Remove(name);
249
250      if (disableStackIfEnabled) {
251        var type = ExpressionTable.TypeToNameTable.Single(x => x.Value == name).Key;
252        var attribute = ExpressionTable.TypeToAttributeTable[type];
253        enabledStacks[attribute.StackType] = false;
254      }
255
256      if (EnabledExpressionsChanged != null) {
257        EnabledExpressionsChanged(this, new EnabledExpressionsChangedEventArgs(
258          new string[0],
259          new[] { name }));
260      }
261    }
262
263    public void EnableExpression<T>(bool enableStackIfDisabled = false) where T : Expression {
264      var attribute = ExpressionTable.TypeToAttributeTable[typeof(T)];
265      EnableExpression(attribute.ExpressionName, enableStackIfDisabled);
266    }
267
268    public void DisableExpression<T>(bool disableStackIfEnabled = false) where T : Expression {
269      var attribute = ExpressionTable.TypeToAttributeTable[typeof(T)];
270      DisableExpression(attribute.ExpressionName, disableStackIfEnabled);
271    }
272
273    public void SetExpression(string name, bool state, bool cascadeForStack = false) {
274      if (state) EnableExpression(name, cascadeForStack);
275      else DisableExpression(name, cascadeForStack);
276    }
277
278    public void SetExpression<T>(bool state, bool cascadeForStack = false) where T : Expression {
279      if (state) EnableExpression<T>(cascadeForStack);
280      else DisableExpression<T>(cascadeForStack);
281    }
282
283    public void EnableStack(StackTypes type, bool enableExpressions = true, bool enableDependencies = true) {
284      enabledStacks[type] = true;
285
286      if (enableExpressions) EnableExpressionOfStack(type);
287      if (enableDependencies) EnableExpressionDependentOnStack(type);
288    }
289
290    public void DisableStack(StackTypes type, bool disableExpressions = true, bool disableDependencies = true) {
291      enabledStacks[type] = false;
292
293      if (disableExpressions) DisableExpressionsOfStack(type);
294      if (disableDependencies) DisableExpressionsDependentOnStack(type);
295    }
296
297    public void SetStack(StackTypes type, bool state, bool setExpressions = true, bool setDependencies = true) {
298      if (state) EnableStack(type, setExpressions, setDependencies);
299      else DisableStack(type, setExpressions, setDependencies);
300    }
301
302    public override IDeepCloneable Clone(Cloner cloner) {
303      return new PushConfiguration(this, cloner);
304    }
305  }
306}
Note: See TracBrowser for help on using the repository browser.