Free cookie consent management tool by TermsFeed Policy Generator

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