Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 14834 was 14834, checked in by pkimmesw, 8 years ago

#2665 LexicaseSelector, Performance improvements, UI Fixes, Debugger only shows used stacks, fixed Debugger stepping, Added vector expressions, ERCOptions,

File size: 4.1 KB
Line 
1namespace HeuristicLab.Problems.ProgramSynthesis.Push.Expressions {
2  using System;
3
4  using HeuristicLab.Problems.ProgramSynthesis.Push.Attributes;
5  using HeuristicLab.Problems.ProgramSynthesis.Push.Data.Pool;
6  using HeuristicLab.Problems.ProgramSynthesis.Push.Interpreter;
7  using HeuristicLab.Problems.ProgramSynthesis.Push.Stack;
8
9  [Serializable]
10  public class LoopState : IPooledObject {
11    public static LoopState Create(
12      IManagedPool<LoopState> pool,
13      Expression body,
14      long currentIndex,
15      long destinationIndex,
16      long incrementor) {
17      var state = pool.Get(false);
18
19      state.Body = body;
20      state.CurrentIndex = currentIndex;
21      state.DestinationIndex = destinationIndex;
22      state.Incrementor = incrementor;
23
24      return state;
25    }
26
27    public Expression Body { get; private set; }
28    public long CurrentIndex { get; private set; }
29    public long DestinationIndex { get; private set; }
30    public long Incrementor { get; private set; }
31
32    private int? hashCode;
33    public override int GetHashCode() {
34      if (hashCode == null) hashCode = CalcHashCode();
35      return hashCode.Value;
36    }
37
38    public void Reset() {
39      Body = null;
40      CurrentIndex = default(long);
41      DestinationIndex = default(long);
42      Incrementor = default(long);
43    }
44
45    private int CalcHashCode() {
46      var hash = 19;
47
48      if (this.Body != null)
49        hash = hash * 31 + this.Body.GetHashCode();
50
51      hash = hash * 31 + this.CurrentIndex.GetHashCode();
52      hash = hash * 31 + this.DestinationIndex.GetHashCode();
53      hash = hash * 31 + this.Incrementor.GetHashCode();
54
55      return hash;
56    }
57  }
58
59  [Serializable]
60  public abstract class LoopExpression : StatefulExpression<LoopState> {
61    protected LoopExpression() : base(new LoopState()) { }
62    protected LoopExpression(LoopState state) : base(state) { }
63
64    protected bool Eval(IInternalPushInterpreter interpreter, IPushStack<Expression> sourceStack, bool pushCurrentIndex = false) {
65      // if not initialized
66      if (this.State.Body == null) {
67        if (this.HasInsufficientArguments(interpreter, sourceStack)) return false;
68
69        var state = this.InitState(interpreter, sourceStack);
70        var initLoopExpression = Clone(state, interpreter);
71
72        interpreter.ExecStack.Push(initLoopExpression, state.Body);
73        return true;
74      }
75
76      // if loop end reached
77      if (this.State.DestinationIndex == this.State.CurrentIndex) {
78        this.PushLastIteration(interpreter);
79        return true;
80      }
81
82      this.PushIteration(interpreter);
83
84      return true;
85    }
86
87    private string stringRepresentation;
88    public override string StringRepresentation
89    {
90      get
91      {
92        if (stringRepresentation == null) {
93          var attribute = (PushExpressionAttribute)Attribute.GetCustomAttribute(GetType(), typeof(PushExpressionAttribute));
94          stringRepresentation = attribute.ExpressionName;
95        }
96
97        return stringRepresentation;
98      }
99    }
100
101    protected virtual void PushIteration(IInternalPushInterpreter interpreter) {
102      interpreter.IntegerStack.Push(this.State.CurrentIndex);
103
104      var newState = LoopState.Create(
105        interpreter.PoolContainer.LoopStatePool,
106        State.Body,
107        State.CurrentIndex + State.Incrementor,
108        State.DestinationIndex,
109        State.Incrementor);
110
111      var nextLoopExpression = Clone(newState, interpreter);
112
113      interpreter.ExecStack.Push(nextLoopExpression, State.Body);
114    }
115
116    protected virtual void PushLastIteration(IInternalPushInterpreter interpreter) {
117      interpreter.IntegerStack.Push(State.CurrentIndex);
118      interpreter.ExecStack.Push(State.Body);
119    }
120
121    protected abstract LoopExpression Clone(LoopState state, IInternalPushInterpreter interpreter);
122    protected abstract bool HasInsufficientArguments(IInternalPushInterpreter interpreter, IPushStack<Expression> sourceStack);
123    protected abstract LoopState InitState(IInternalPushInterpreter interpreter, IPushStack<Expression> sourceStack);
124  }
125}
Note: See TracBrowser for help on using the repository browser.