[14727] | 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 | } |
---|