Free cookie consent management tool by TermsFeed Policy Generator

source: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/LoopExpression.cs @ 14744

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

#2665 Renamings due to typos, ManagedPool tests, Skip Noops in Debugger

File size: 2.8 KB
Line 
1namespace HeuristicLab.Problems.ProgramSynthesis.Push.Expressions {
2
3  using HeuristicLab.Problems.ProgramSynthesis.Push.Interpreter;
4  using HeuristicLab.Problems.ProgramSynthesis.Push.Stack;
5
6  public struct 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 : StatefulExpression<LoopState> {
35    protected LoopExpression() : base(new LoopState()) { }
36    protected LoopExpression(LoopState state) : base(state) { }
37
38    protected bool Eval(IPushInterpreter interpreter, IStack<Expression> sourceStack, bool pushCurrentIndex = false) {
39      // if not initialized
40      if (this.State.Body == null) {
41        if (this.HasInsufficientArguments(interpreter, sourceStack)) return false;
42
43        var state = this.InitState(interpreter, sourceStack);
44        var initLoopExpression = Clone(state);
45
46        interpreter.ExecStack.Push(initLoopExpression, state.Body);
47        return true;
48      }
49
50      // if loop end reached
51      if (this.State.DestinationIndex == this.State.CurrentIndex) {
52        this.PushLastIteration(interpreter);
53        return true;
54      }
55
56      this.PushIteration(interpreter);
57
58      return true;
59    }
60
61    protected virtual void PushIteration(IPushInterpreter 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(IPushInterpreter interpreter) {
71      interpreter.IntegerStack.Push(this.State.CurrentIndex);
72      interpreter.ExecStack.Push(this.State.Body);
73    }
74
75    protected abstract LoopExpression Clone(LoopState state);
76    protected abstract bool HasInsufficientArguments(IPushInterpreter interpreter, IStack<Expression> sourceStack);
77    protected abstract LoopState InitState(IPushInterpreter interpreter, IStack<Expression> sourceStack);
78  }
79}
Note: See TracBrowser for help on using the repository browser.