Free cookie consent management tool by TermsFeed Policy Generator

source: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Interpreter/PushGPInterpreter.cs @ 14727

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

#2665 PushGP HL Integration, Views, Parameters

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