1 | namespace HeuristicLab.Problems.ProgramSynthesis.Push.Expressions {
|
---|
2 |
|
---|
3 | using HeuristicLab.Problems.ProgramSynthesis.Push.Interpreter;
|
---|
4 | using HeuristicLab.Problems.ProgramSynthesis.Push.Stack;
|
---|
5 |
|
---|
6 | public class LoopState {
|
---|
7 | public LoopState() { }
|
---|
8 | public LoopState(Expression body, long currentIndex, long destinationIndex, long incrementor) {
|
---|
9 | this.Body = body;
|
---|
10 | this.CurrentIndex = currentIndex;
|
---|
11 | this.DestinationIndex = destinationIndex;
|
---|
12 | this.Incrementor = incrementor;
|
---|
13 | }
|
---|
14 |
|
---|
15 | public readonly Expression Body;
|
---|
16 | public readonly long CurrentIndex;
|
---|
17 | public readonly long DestinationIndex;
|
---|
18 | public readonly long Incrementor;
|
---|
19 |
|
---|
20 | public override int GetHashCode() {
|
---|
21 | var hash = 19;
|
---|
22 |
|
---|
23 | if (this.Body != null)
|
---|
24 | hash = hash * 31 + this.Body.GetHashCode();
|
---|
25 |
|
---|
26 | hash = hash * 31 + this.CurrentIndex.GetHashCode();
|
---|
27 | hash = hash * 31 + this.DestinationIndex.GetHashCode();
|
---|
28 | hash = hash * 31 + this.Incrementor.GetHashCode();
|
---|
29 |
|
---|
30 | return hash;
|
---|
31 | }
|
---|
32 | }
|
---|
33 |
|
---|
34 | public abstract class LoopExpression : StatefullExpression<LoopState> {
|
---|
35 | protected LoopExpression() : base(new LoopState()) { }
|
---|
36 | protected LoopExpression(LoopState state) : base(state) { }
|
---|
37 |
|
---|
38 | protected void Eval(IPushGpInterpreter interpreter, IStack<Expression> sourceStack, bool pushCurrentIndex = false) {
|
---|
39 | // if not initialized
|
---|
40 | if (this.State.Body == null) {
|
---|
41 | if (this.HasInsufficientArguments(interpreter, sourceStack)) return;
|
---|
42 |
|
---|
43 | var state = this.InitState(interpreter, sourceStack);
|
---|
44 | var initLoopExpression = Clone(state);
|
---|
45 |
|
---|
46 | interpreter.ExecStack.Push(initLoopExpression, state.Body);
|
---|
47 | return;
|
---|
48 | }
|
---|
49 |
|
---|
50 | // if loop end reached
|
---|
51 | if (this.State.DestinationIndex == this.State.CurrentIndex) {
|
---|
52 | this.PushLastIteration(interpreter);
|
---|
53 | return;
|
---|
54 | }
|
---|
55 |
|
---|
56 | this.PushIteration(interpreter);
|
---|
57 | }
|
---|
58 |
|
---|
59 | protected abstract LoopExpression Clone(LoopState state);
|
---|
60 |
|
---|
61 | protected virtual void PushIteration(IPushGpInterpreter interpreter) {
|
---|
62 | interpreter.IntegerStack.Push(this.State.CurrentIndex);
|
---|
63 |
|
---|
64 | var newState = new LoopState(State.Body, State.CurrentIndex + this.State.Incrementor, State.DestinationIndex, State.Incrementor);
|
---|
65 | var nextLoopExpression = Clone(newState);
|
---|
66 |
|
---|
67 | interpreter.ExecStack.Push(nextLoopExpression, this.State.Body);
|
---|
68 | }
|
---|
69 |
|
---|
70 | protected virtual void PushLastIteration(IPushGpInterpreter interpreter) {
|
---|
71 | interpreter.IntegerStack.Push(this.State.CurrentIndex);
|
---|
72 | interpreter.ExecStack.Push(this.State.Body);
|
---|
73 | }
|
---|
74 |
|
---|
75 | //public override bool Equals(object obj) {
|
---|
76 | // if (this == obj)
|
---|
77 | // return true;
|
---|
78 |
|
---|
79 | // if (obj == null || obj.GetType() != this.GetType())
|
---|
80 | // return false;
|
---|
81 |
|
---|
82 | // var other = obj as LoopExpression;
|
---|
83 |
|
---|
84 | // if (this.State.CurrentIndex != other.State.CurrentIndex ||
|
---|
85 | // this.State.DestinationIndex != other.State.DestinationIndex ||
|
---|
86 | // this.State.Incrementor != other.State.Incrementor)
|
---|
87 | // return false;
|
---|
88 |
|
---|
89 | // var isBodyEqual = this.State.Body == other.State.Body ||
|
---|
90 | // (this.State.Body != null &&
|
---|
91 | // other.State.Body != null &&
|
---|
92 | // this.State.Body.Equals(other.State.Body));
|
---|
93 |
|
---|
94 | // return isBodyEqual;
|
---|
95 | //}
|
---|
96 |
|
---|
97 | protected abstract bool HasInsufficientArguments(IPushGpInterpreter interpreter, IStack<Expression> sourceStack);
|
---|
98 |
|
---|
99 | protected abstract LoopState InitState(IPushGpInterpreter interpreter, IStack<Expression> sourceStack);
|
---|
100 | }
|
---|
101 | } |
---|