Free cookie consent management tool by TermsFeed Policy Generator

source: branches/PushGP/HeuristicLab.Algorithms.PushGP/HeuristicLab.Algorithms.PushGP/Expressions/DoRangeExpressions.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: 4.7 KB
Line 
1using HeuristicLab.Algorithms.PushGP.Interpreter;
2using HeuristicLab.Algorithms.PushGP.Stack;
3
4namespace HeuristicLab.Algorithms.PushGP.Expressions
5{
6    public abstract class DoRangeExpression : LoopExpression
7    {
8        public DoRangeExpression(string stringRepresentation) : base(stringRepresentation) { }
9
10        protected override bool HasInsufficientArguments(IInterpreter interpreter, IStack<Expression> sourceStack)
11        {
12            return interpreter.IntegerStack.Count < 2 ||
13                   sourceStack.Count == 0 ||
14                   interpreter.IntegerStack.Top == interpreter.IntegerStack.ReverseElementAt(1);
15        }
16
17        protected override void InitState(IInterpreter interpreter, IStack<Expression> sourceStack)
18        {
19            this.body = sourceStack.Pop();
20            this.destinationIndex = interpreter.IntegerStack.Pop();
21            this.currentIndex = interpreter.IntegerStack.Top;
22            this.incrementor = this.destinationIndex < this.currentIndex ? -1 : 1;
23            this.currentIndex += this.incrementor;
24        }
25    }
26
27    /// <summary>
28    /// An iteration instruction that executes the top item on the CODE stack a number of times that depends on the
29    /// top two integers, while also pushing the loop counter onto the INTEGER stack for possible access during the execution of
30    /// the body of the loop. The top integer is the "destination index" and the second integer is the "current index." First the code
31    /// and the integer arguments are saved locally and popped. Then the integers are compared. If the integers are equal then the current
32    /// index is pushed onto the INTEGER stack and the code (which is the "body" of the loop) is pushed onto the EXEC stack for subsequent
33    /// execution. If the integers are not equal then the current index will still be pushed onto the INTEGER stack but two items will be
34    /// pushed onto the EXEC stack -- first a recursive call to CODE.DO*RANGE (with the same code and destination index, but with a current
35    /// index that has been either incremented or decremented by 1 to be closer to the destination index) and then the body code. Note that
36    /// the range is inclusive of both endpoints; a call with integer arguments 3 and 5 will cause its body to be executed 3 times, with the
37    /// loop counter having the values 3, 4, and 5. Note also that one can specify a loop that "counts down" by providing a destination index
38    /// that is less than the specified current index.
39    /// </summary>
40    [StatefullExpression]
41    public class CodeDoRangeExpression : DoRangeExpression
42    {
43        public CodeDoRangeExpression() : base("CODE.DO*RANGE") { }
44
45        public override void Eval(IInterpreter interpreter)
46        {
47            this.Eval(interpreter, interpreter.CodeStack);
48        }
49    }
50
51    /// <summary>
52    /// An iteration instruction that executes the top item on the EXEC stack a number of times that depends on the top two integers,
53    /// while also pushing the loop counter onto the INTEGER stack for possible access during the execution of the body of the loop.
54    /// This is similar to CODE.DO*COUNT except that it takes its code argument from the EXEC stack. The top integer is the
55    /// "destination index" and the second integer is the "current index." First the code and the integer arguments are saved locally
56    /// and popped. Then the integers are compared. If the integers are equal then the current index is pushed onto the INTEGER stack
57    /// and the code (which is the "body" of the loop) is pushed onto the EXEC stack for subsequent execution. If the integers are not
58    /// equal then the current index will still be pushed onto the INTEGER stack but two items will be pushed onto the EXEC stack
59    /// -- first a recursive call to EXEC.DO*RANGE (with the same code and destination index, but with a current index that has been
60    /// either incremented or decremented by 1 to be closer to the destination index) and then the body code. Note that the range is
61    /// inclusive of both endpoints; a call with integer arguments 3 and 5 will cause its body to be executed 3 times, with the loop
62    /// counter having the values 3, 4, and 5. Note also that one can specify a loop that "counts down" by providing a destination
63    /// index that is less than the specified current index.
64    /// </summary>
65    [StatefullExpression]
66    public class ExecDoRangeExpression : DoRangeExpression
67    {
68        public ExecDoRangeExpression() : base("EXEC.DO*RANGE") { }
69
70        public override void Eval(IInterpreter interpreter)
71        {
72            this.Eval(interpreter, interpreter.ExecStack);
73        }
74    }
75}
Note: See TracBrowser for help on using the repository browser.