Free cookie consent management tool by TermsFeed Policy Generator

source: branches/PushGP/HeuristicLab.Algorithms.PushGP/HeuristicLab.Algorithms.PushGP/Interpreter/PushGPInterpreter.cs @ 14392

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

#2665 Full Push 3.0 instruction set and tests; Added first benchmark test (count odds) for random walk tests;

File size: 7.4 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Threading;
4using System.Threading.Tasks;
5using HeuristicLab.Algorithms.PushGP.Expressions;
6using HeuristicLab.Algorithms.PushGP.Generators;
7using HeuristicLab.Algorithms.PushGP.Stack;
8
9namespace HeuristicLab.Algorithms.PushGP.Interpreter
10{
11    public class PushGPInterpreter : IInterpreter
12    {
13        private Task currentTask;
14
15
16        public PushGPInterpreter(Configuration config = null)
17        {
18            this.Configuration = config ?? new Configuration();
19
20            this.CodeStack = new PushGPStack<Expression>(128);
21            this.ExecStack = new PushGPStack<Expression>(128);
22            this.NameStack = new PushGPStack<string>(16);
23            this.BooleanStack = new PushGPStack<bool>(16);
24            this.IntegerStack = new PushGPStack<long>(16);
25            this.FloatStack = new PushGPStack<double>(16);
26
27            this.CustomExpressions = new Dictionary<string, Expression>();
28
29            this.CodeGenerator = new CodeGenerator(this);
30        }
31
32        public Configuration Configuration { get; private set; }
33
34        public int ExecCounter { get; private set; }
35        public bool IsPaused { get; private set; }
36        public bool IsAborted { get; private set; }
37        public bool IsRunning { get { return this.ExecStack.Count > 0 && !IsPaused && !IsAborted && ExecCounter < Configuration.EvalPushLimit; } }
38        public bool IsCompleted { get { return this.ExecStack.Count == 0; } }
39        public bool CanStep { get { return !IsCompleted && !IsAborted && IsPaused; } }
40
41        public IStack<Expression> CodeStack { get; private set; }
42        public IStack<Expression> ExecStack { get; private set; }
43        public IStack<string> NameStack { get; private set; }
44        public IStack<bool> BooleanStack { get; private set; }
45        public IStack<long> IntegerStack { get; private set; }
46        public IStack<double> FloatStack { get; private set; }
47
48        public IDictionary<string, Expression> CustomExpressions { get; private set; }
49
50        public CodeGenerator CodeGenerator { get; private set; }
51
52        public bool IsNameQuoteFlagSet { get; set; }
53
54        public void Reset()
55        {
56            this.IsAborted = false;
57            this.IsPaused = false;
58            this.currentTask = null;
59
60            this.Clear();
61        }
62
63        public void Clear()
64        {
65            this.ExecCounter = 0;
66
67            this.ExecStack.Clear();
68            this.CodeStack.Clear();
69            this.NameStack.Clear();
70            this.BooleanStack.Clear();
71            this.IntegerStack.Clear();
72            this.FloatStack.Clear();
73
74            this.CustomExpressions.Clear();
75        }
76
77        public void Interpret(string code)
78        {
79            var program = Encode(code);
80            this.Interpret(program);
81        }
82
83        public Task InterpretAsync(string code, bool paused = false, CancellationToken token = default(CancellationToken))
84        {
85            var program = Encode(code);
86
87            this.currentTask = this.InterpretAsync(program, paused, token);
88
89            return currentTask;
90        }
91
92        public Task InterpretAsync(Expression program, bool paused = false, CancellationToken token = default(CancellationToken))
93        {
94            this.IsPaused = paused;
95            this.currentTask = Task.Run(() => this.Interpret(program), token);
96
97            return currentTask;
98        }
99
100        public void Interpret(Expression program)
101        {
102            /* Push top expression so the loop is able to enter
103             * If the top expression is a single statement then the loop has nothing to do
104             * Otherwise the expand expression will be evaluated and pushes code onto the EXEC stack */
105            this.ExecStack.Push(program);
106
107            if (this.Configuration.TopLevelPushCode)
108            {
109                this.CodeStack.Insert(0, program);
110            }
111
112            // run top expression
113            this.ExecStack.Pop().Eval(this);
114
115            this.Interpret();
116        }
117
118        private void Interpret()
119        {
120            while (this.IsRunning)
121            {
122                this.DoStep();
123                this.ExecCounter++;
124            }
125
126            this.Finally();
127        }
128
129        private void Finally()
130        {
131            if (this.IsCompleted && this.Configuration.TopLevelPopCode && this.CodeStack.Count > 0)
132            {
133                this.CodeStack.Pop();
134            }
135        }
136
137        private void DoStep()
138        {
139            this.ExecStack.Pop().Eval(this);
140        }
141
142        private Task InterpreteAsync()
143        {
144            this.currentTask = Task.Run(() => this.Interpret());
145
146            return this.currentTask;
147        }
148
149        public async Task AbortAsync()
150        {
151            if (this.IsAborted || this.IsCompleted)
152                return;
153
154            this.IsAborted = true;
155
156            if (this.currentTask != null)
157            {
158                await this.currentTask;
159            }
160        }
161
162        public async Task AbortAndResetAsync()
163        {
164            await this.AbortAsync();
165            this.Reset();
166        }
167
168        public async Task PauseAsync()
169        {
170            if (this.IsPaused || this.IsCompleted)
171                return;
172
173            this.IsPaused = true;
174
175            if (this.currentTask != null)
176            {
177                await this.currentTask;
178            }
179        }
180
181        public Task ResumeAsync()
182        {
183            if (this.IsPaused || !this.IsAborted)
184            {
185                this.IsPaused = false;
186                return this.InterpreteAsync();
187            }
188
189            return this.currentTask;
190        }
191
192        public void Step()
193        {
194            if (this.CanStep)
195            {
196                this.DoStep();
197                this.Finally();
198            }
199        }
200
201        public void Step(int count)
202        {
203            for (var i = 0; i < count; i++)
204            {
205                this.Step();
206            }
207        }
208
209        public static Expression Encode(string code)
210        {
211            return Parser.Parse(code);
212        }
213
214        public static Task<Expression> EncodeAsync(string code, CancellationToken token = default(CancellationToken))
215        {
216            return Task.Run(() => Encode(code), token);
217        }
218
219        public static string Decode(Expression expression)
220        {
221            return string.Concat(expression.ToString());
222        }
223
224        public static Task<string> DecodeAsync(Expression expression, CancellationToken token = default(CancellationToken))
225        {
226            return Task.Run(() => Decode(expression), token);
227        }
228
229        public void PrintStacks()
230        {
231            this.PrintStack("EXEC", this.ExecStack);
232            this.PrintStack("CODE", this.CodeStack);
233            this.PrintStack("NAME", this.NameStack);
234            this.PrintStack("BOOLEAN", this.BooleanStack);
235            this.PrintStack("FLOAT", this.FloatStack);
236            this.PrintStack("INTEGER", this.IntegerStack);
237        }
238
239        private void PrintStack<T>(string name, IStack<T> stack)
240        {
241            Console.WriteLine(string.Format(
242                "--- {0} ---\n{1}\n---------------------------------------------------",
243                name,
244                stack));
245        }
246    }
247}
Note: See TracBrowser for help on using the repository browser.