Free cookie consent management tool by TermsFeed Policy Generator

source: branches/PushGP/HeuristicLab.Algorithms.PushGP/HeuristicLab.Algorithms.PushGP/Interpreter/Interpreter.cs @ 14328

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

#2665 Set .NET version to 4.5, C# version to 5.0, Added expression templates and factory

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