Free cookie consent management tool by TermsFeed Policy Generator

source: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Interpreter/PushInterpreter.cs @ 14778

Last change on this file since 14778 was 14777, checked in by pkimmesw, 8 years ago

#2665 simplifier, push solution results view, performance improvements, small bug fixes, ui fixes

File size: 8.1 KB
Line 
1namespace HeuristicLab.Problems.ProgramSynthesis.Push.Interpreter {
2  using System;
3  using System.Collections.Generic;
4#if DEBUG
5#endif
6  using System.Runtime.CompilerServices;
7  using System.Threading;
8  using System.Threading.Tasks;
9  using HeuristicLab.Core;
10  using HeuristicLab.Problems.ProgramSynthesis.Push.Configuration;
11  using HeuristicLab.Problems.ProgramSynthesis.Push.Expressions;
12  using HeuristicLab.Problems.ProgramSynthesis.Push.Parser;
13  using HeuristicLab.Problems.ProgramSynthesis.Push.Stack;
14  using HeuristicLab.Random;
15
16  public class PushInterpreter : IPushInterpreter {
17    private Task currentTask;
18
19
20    public PushInterpreter(IReadOnlyPushConfiguration config = null, IRandom random = null, InterpreterPoolContainer poolContainer = null) {
21      Random = random ?? new FastRandom();
22
23      Configuration = config ?? new PushConfiguration();
24
25      // setting the capacity of the stacks to max points ensures that there will be enough memory at runtime
26      ExecStack = new PushStack<Expression>(Configuration.EvalPushLimit);
27
28      CodeStack = new PushStack<Expression>(Configuration.EvalPushLimit) {
29        IsEnabled = Configuration.IsCodeStackEnabled
30      };
31
32      NameStack = new PushStack<string> {
33        IsEnabled = Configuration.IsNameStackEnabled
34      };
35      BooleanStack = new PushStack<bool> {
36        IsEnabled = Configuration.IsBooleanStackEnabled
37      };
38      IntegerStack = new PushStack<long> {
39        IsEnabled = Configuration.IsIntegerStackEnabled
40      };
41      FloatStack = new PushStack<double> {
42        IsEnabled = Configuration.IsFloatStackEnabled
43      };
44      CharStack = new PushStack<char> {
45        IsEnabled = Configuration.IsCharStackEnabled
46      };
47      StringStack = new PushStack<string> {
48        IsEnabled = Configuration.IsStringStackEnabled
49      };
50
51      CustomExpressions = new Dictionary<string, Expression>();
52
53      PoolContainer = poolContainer ?? new InterpreterPoolContainer();
54    }
55
56    public PushInterpreter(int seed, IReadOnlyPushConfiguration config = null)
57      : this(config, new FastRandom(seed)) {
58    }
59
60    public IRandom Random { get; set; }
61
62    public int ExecCounter { get; private set; }
63
64    public bool IsPaused { get; private set; }
65
66    public bool IsAborted { get; private set; }
67
68    public bool IsRunning
69    {
70      get
71      {
72        return !ExecStack.IsEmpty &&
73               !IsPaused &&
74               !IsAborted &&
75               (ExecCounter < Configuration.EvalPushLimit);
76      }
77    }
78
79    public bool IsCompleted
80    {
81      get
82      {
83        return ExecStack.Count == 0;
84      }
85    }
86
87    public bool CanStep
88    {
89      get
90      {
91        return !IsCompleted && !IsAborted && IsPaused;
92      }
93    }
94
95    public InterpreterPoolContainer PoolContainer { get; private set; }
96
97    public IReadOnlyPushConfiguration Configuration { get; protected set; }
98
99    public IStack<Expression> CodeStack { get; private set; }
100
101    public IStack<Expression> ExecStack { get; private set; }
102
103    public IStack<string> NameStack { get; private set; }
104
105    public IStack<bool> BooleanStack { get; private set; }
106
107    public IStack<long> IntegerStack { get; private set; }
108
109    public IStack<double> FloatStack { get; private set; }
110    public IStack<char> CharStack { get; private set; }
111    public IStack<string> StringStack { get; private set; }
112
113    public IDictionary<string, Expression> CustomExpressions { get; private set; }
114
115    public bool IsNameQuoteFlagSet { get; set; }
116
117    public Task RunAsync(string code, bool stepwise = false, CancellationToken token = default(CancellationToken)) {
118      var program = PushParser.Parse(code);
119
120      currentTask = RunAsync(program, stepwise, token);
121
122      return currentTask;
123    }
124    public async Task RunAsync(
125      Expression expression,
126      bool stepwise = false,
127      CancellationToken token = default(CancellationToken)) {
128      await Task.Run(() => Run(expression, stepwise), token);
129    }
130
131    public void Run(string code, bool stepwise = false) {
132      var program = PushParser.Parse(code);
133      Run(program, stepwise);
134    }
135
136    public void Run(Expression program, bool stepwise = false) {
137      PoolContainer.CreatePools();
138
139      IsPaused = stepwise;
140
141      /* Push top expression so the loop is able to enter
142       * If the top expression is a single statement then the loop has nothing to do
143       * Otherwise the expand expression will be evaluated and pushes code onto the EXEC stack */
144      ExecStack.Push(program);
145
146      if (Configuration.TopLevelPushCode) CodeStack.Insert(0, program);
147
148      // run top expression
149      DoStep();
150      Interpret();
151
152      PoolContainer.DisposePools();
153    }
154
155    public async Task AbortAsync() {
156      if (IsAborted || IsCompleted) return;
157
158      IsAborted = true;
159
160      PoolContainer.DisposePools();
161
162      if (currentTask != null) await currentTask;
163    }
164
165    public async Task AbortAndResetAsync() {
166      await AbortAsync();
167      Reset();
168    }
169
170    public async Task PauseAsync() {
171      if (IsPaused || IsCompleted) return;
172
173      IsPaused = true;
174
175      if (currentTask != null) await currentTask;
176    }
177
178    public async Task ResumeAsync() {
179      if (IsPaused || !IsAborted) {
180        IsPaused = false;
181        await InterpretAsync();
182      } else await currentTask;
183    }
184
185    public void Resume() {
186      if (!IsPaused && IsAborted)
187        return;
188
189      IsPaused = false;
190      Interpret();
191    }
192
193    [MethodImpl(MethodImplOptions.AggressiveInlining)]
194    public bool Step() {
195      if (!CanStep) return false;
196
197      var successful = DoStep();
198      Finally();
199
200      return successful;
201    }
202
203    [MethodImpl(MethodImplOptions.AggressiveInlining)]
204    public void Step(int count) {
205      for (var i = 0; i < count; i++) Step();
206    }
207
208    public void PrintStacks() {
209      PrintStack("EXEC", ExecStack);
210      PrintStack("CODE", CodeStack);
211      PrintStack("NAME", NameStack);
212      PrintStack("BOOLEAN", BooleanStack);
213      PrintStack("FLOAT", FloatStack);
214      PrintStack("INTEGER", IntegerStack);
215
216      if (CustomExpressions.Count > 0) {
217        Console.WriteLine("--------- Custom Expressions ---------");
218        foreach (var ce in CustomExpressions) {
219          Console.WriteLine("{0}: {1}", ce.Key, ce.Value);
220        }
221      }
222    }
223
224    /// <summary>
225    /// Clears stacks
226    /// </summary>
227    public void Reset() {
228      IsAborted = false;
229      IsPaused = false;
230      currentTask = null;
231
232      Clear();
233    }
234
235    /// <summary>
236    /// Clears stacks
237    /// </summary>
238    public void Clear() {
239      ExecCounter = 0;
240
241      ExecStack.Clear();
242      CodeStack.Clear();
243
244      NameStack.Clear();
245      BooleanStack.Clear();
246      IntegerStack.Clear();
247      FloatStack.Clear();
248
249      CustomExpressions.Clear();
250    }
251
252    [MethodImpl(MethodImplOptions.AggressiveInlining)]
253    private void Interpret() {
254      while (IsRunning) {
255        DoStep();
256        ExecCounter++;
257      }
258
259      Finally();
260    }
261
262    [MethodImpl(MethodImplOptions.AggressiveInlining)]
263    private void Finally() {
264      if (!IsCompleted)
265        return;
266
267      if (Configuration.TopLevelPopCode && (CodeStack.Count > 0))
268        CodeStack.Pop();
269    }
270
271#if DEBUG
272    private Expression last;
273    private bool DoStep() {
274      var expression = ExecStack.Pop();
275
276      //if (ExecStack.Any(e => e == null)) {
277      //  throw new InvalidProgramException();
278      //}
279
280      var succ = expression.Eval(this);
281      //last = expression;
282
283      return succ;
284    }
285#else
286    [MethodImpl(MethodImplOptions.AggressiveInlining)]
287    private bool DoStep() {
288      return ExecStack.Pop().Eval(this);
289    }
290#endif
291
292    private Task InterpretAsync() {
293      currentTask = Task.Run(() => Interpret());
294
295      return currentTask;
296    }
297
298    private void PrintStack<T>(string name, IStack<T> stack) {
299      if (stack.IsEmpty) return;
300      Console.WriteLine("--------- {0} ---------\n{1}\n", name, stack);
301    }
302  }
303}
Note: See TracBrowser for help on using the repository browser.