Free cookie consent management tool by TermsFeed Policy Generator

source: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/DoRangeExpressions.cs @ 14952

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

#2665 Added IsNoop to Expression, Made Expressions storable, Fixed Debugger, Fixed and improved problem data and result visualisation, Added custom ErcOption view, Added problem difficulty to problem data name

File size: 6.5 KB
Line 
1namespace HeuristicLab.Problems.ProgramSynthesis.Push.Expressions {
2  using System;
3
4  using Attributes;
5
6  using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
7
8  using Interpreter;
9  using Stack;
10
11  [Serializable]
12  [StorableClass]
13  public abstract class DoRangeExpression : LoopExpression {
14    protected DoRangeExpression() { }
15    protected DoRangeExpression(LoopState state) : base(state) { }
16    [StorableConstructor]
17    protected DoRangeExpression(bool deserializing) : base(deserializing) { }
18
19    protected override bool HasInsufficientArguments(IInternalPushInterpreter interpreter, IPushStack<Expression> sourceStack) {
20      return interpreter.IntegerStack.Count < 2 ||
21             sourceStack.Count == 0 ||
22             interpreter.IntegerStack.Top == interpreter.IntegerStack[1];
23    }
24
25    protected override LoopState InitState(IInternalPushInterpreter interpreter, IPushStack<Expression> sourceStack) {
26      var destinationIndex = interpreter.IntegerStack.Pop();
27      var incrementor = destinationIndex < interpreter.IntegerStack.Top ? -1 : 1;
28
29      return LoopState.Create(interpreter.PoolContainer.LoopStatePool,
30          body: sourceStack.Pop(),
31          currentIndex: interpreter.IntegerStack.Top + incrementor,
32          destinationIndex: destinationIndex,
33          incrementor: incrementor);
34    }
35  }
36
37  /// <summary>
38  ///     An iteration instruction that executes the top item on the CODE stack a number of times that depends on the
39  ///     top two integers, while also pushing the loop counter onto the INTEGER stack for possible access during the
40  ///     execution of
41  ///     the body of the loop. The top integer is the "destination index" and the second integer is the "current index."
42  ///     Last the code
43  ///     and the integer arguments are saved locally and popped. Then the integers are compared. If the integers are equal
44  ///     then the current
45  ///     index is pushed onto the INTEGER stack and the code (which is the "body" of the loop) is pushed onto the EXEC stack
46  ///     for subsequent
47  ///     execution. If the integers are not equal then the current index will still be pushed onto the INTEGER stack but two
48  ///     items will be
49  ///     pushed onto the EXEC stack -- first a recursive call to CODE.DO*RANGE (with the same code and destination index,
50  ///     but with a current
51  ///     index that has been either incremented or decremented by 1 to be closer to the destination index) and then the body
52  ///     code. Note that
53  ///     the range is inclusive of both endpoints; a call with integer arguments 3 and 5 will cause its body to be executed
54  ///     3 times, with the
55  ///     loop counter having the values 3, 4, and 5. Note also that one can specify a loop that "counts down" by providing a
56  ///     destination index
57  ///     that is less than the specified current index.
58  /// </summary>
59  [Serializable]
60  [StorableClass]
61  [PushExpression(StackTypes.Code, "CODE.DO*RANGE", StackTypes.Integer)]
62  public class CodeDoRangeExpression : DoRangeExpression {
63    public CodeDoRangeExpression() { }
64    public CodeDoRangeExpression(LoopState state) : base(state) { }
65    [StorableConstructor]
66    protected CodeDoRangeExpression(bool deserializing) : base(deserializing) { }
67
68    public override bool IsNoop(IInternalPushInterpreter interpreter) {
69      return State.Body == null && HasInsufficientArguments(interpreter, interpreter.CodeStack);
70    }
71
72    public override void Eval(IInternalPushInterpreter interpreter) {
73      Eval(interpreter, interpreter.CodeStack);
74    }
75
76    protected override LoopExpression Clone(LoopState state, IInternalPushInterpreter interpreter) {
77      var expression = interpreter.PoolContainer.GetStatefulExpression<CodeDoRangeExpression>();
78      expression.State = state;
79
80      return expression;
81    }
82  }
83
84  /// <summary>
85  ///     An iteration instruction that executes the top item on the EXEC stack a number of times that depends on the top two
86  ///     integers,
87  ///     while also pushing the loop counter onto the INTEGER stack for possible access during the execution of the body of
88  ///     the loop.
89  ///     This is similar to CODE.DO*COUNT except that it takes its code argument from the EXEC stack. The top integer is the
90  ///     "destination index" and the second integer is the "current index." Last the code and the integer arguments are
91  ///     saved locally
92  ///     and popped. Then the integers are compared. If the integers are equal then the current index is pushed onto the
93  ///     INTEGER stack
94  ///     and the code (which is the "body" of the loop) is pushed onto the EXEC stack for subsequent execution. If the
95  ///     integers are not
96  ///     equal then the current index will still be pushed onto the INTEGER stack but two items will be pushed onto the EXEC
97  ///     stack
98  ///     -- first a recursive call to EXEC.DO*RANGE (with the same code and destination index, but with a current index that
99  ///     has been
100  ///     either incremented or decremented by 1 to be closer to the destination index) and then the body code. Note that the
101  ///     range is
102  ///     inclusive of both endpoints; a call with integer arguments 3 and 5 will cause its body to be executed 3 times, with
103  ///     the loop
104  ///     counter having the values 3, 4, and 5. Note also that one can specify a loop that "counts down" by providing a
105  ///     destination
106  ///     index that is less than the specified current index.
107  /// </summary>
108  [Serializable]
109  [StorableClass]
110  [PushExpression(StackTypes.Exec, "EXEC.DO*RANGE", StackTypes.Integer)]
111  public class ExecDoRangeExpression : DoRangeExpression {
112    public ExecDoRangeExpression() { }
113
114    public ExecDoRangeExpression(LoopState state) : base(state) { }
115    [StorableConstructor]
116    protected ExecDoRangeExpression(bool deserializing) : base(deserializing) { }
117
118    public override bool IsNoop(IInternalPushInterpreter interpreter) {
119      return State.Body == null && HasInsufficientArguments(interpreter, interpreter.ExecStack);
120    }
121
122    public override void Eval(IInternalPushInterpreter interpreter) {
123      Eval(interpreter, interpreter.ExecStack);
124    }
125    protected override LoopExpression Clone(LoopState state, IInternalPushInterpreter interpreter) {
126      var expression = interpreter.PoolContainer.GetStatefulExpression<ExecDoRangeExpression>();
127      expression.State = state;
128
129      return expression;
130    }
131  }
132}
Note: See TracBrowser for help on using the repository browser.