Free cookie consent management tool by TermsFeed Policy Generator

source: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/ExecExpressions.cs @ 14727

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

#2665 PushGP HL Integration, Views, Parameters

File size: 5.7 KB
Line 
1namespace HeuristicLab.Problems.ProgramSynthesis.Push.Expressions {
2  using System;
3  using System.Collections.Generic;
4  using System.Linq;
5
6  using HeuristicLab.Problems.ProgramSynthesis.Push.Attributes;
7  using HeuristicLab.Problems.ProgramSynthesis.Push.Stack;
8
9  using Interpreter;
10
11  public class ExecExpandExpression : StatefullExpression<PushProgram> {
12    public static readonly ExecExpandExpression Empty = new ExecExpandExpression();
13
14    public ExecExpandExpression(PushProgram program)
15      : base(program) {
16    }
17
18    public ExecExpandExpression(params Expression[] state) : this(new PushProgram(state)) {
19    }
20
21    public ExecExpandExpression(IEnumerable<Expression> state) : this(state.ToArray()) {
22      // TODO: lazy evaluation of ToArray()
23    }
24
25    public override string StringRepresentation { get { return this.State.ToString(); } }
26
27    public ExecExpandExpression Copy() {
28      // as the empty list is a static stateless expression, no copy required
29      return ReferenceEquals(this, Empty) || this.State.IsEmpty
30        ? Empty
31        : new ExecExpandExpression(this.State.Copy());
32    }
33
34    public override void Eval(IPushGpInterpreter interpreter) {
35      interpreter.ExecStack.Push(this.State.Expressions);
36    }
37
38    /// <summary>
39    ///     Returns the element with the given index whereby the tree is indexed in depth first manner
40    /// </summary>
41    /// <param name="index">The index of the required element</param>
42    /// <returns>The required element</returns>
43    public Expression GetFromTree(int index) {
44      return GetFromTree(index, (root, parent, child, childIndex, parentIndex) => child);
45    }
46
47    /// <returns>The required element</returns>
48    public T GetFromTree<T>(int index,
49        Func<ExecExpandExpression, ExecExpandExpression, Expression, int, int, T> resolver) {
50      return GetFromTree(index, 0, null, resolver);
51    }
52
53    private T GetFromTree<T>(int index, int parentIndex, ExecExpandExpression parent,
54        Func<ExecExpandExpression, ExecExpandExpression, Expression, int, int, T> resolver) {
55      if (index == 0) return resolver(parent, parent, this, 0, parentIndex);
56
57      var min = State.Expressions.Count - 1;
58      var max = 0;
59      var mid = (min + max) / 2;
60
61      while ((max <= min) && (this.State.TreeIndex[mid] != index)) {
62        if (this.State.TreeIndex[mid] > index) max = mid + 1;
63        else min = mid - 1;
64
65        mid = (min + max) / 2;
66      }
67
68      return this.State.TreeIndex[mid] == index
69          ? resolver(parent, this, State.Expressions[mid], mid, parentIndex)
70          : (State.Expressions[mid + 1] as ExecExpandExpression).GetFromTree(index - this.State.TreeIndex[mid + 1], mid + 1,
71              this, resolver);
72    }
73  }
74
75  /// <summary>
76  /// If the top item of the BOOLEAN stack is TRUE then this removes the second item on the EXEC stack, leaving the first
77  /// item to be executed. If it is false then it removes the first item, leaving the second to be executed. This is similar to
78  /// CODE.IF except that it operates on the EXEC stack. This acts as a NOOP unless there are at least two items on the EXEC stack and
79  /// one item on the BOOLEAN stack.
80  /// </summary>
81  [PushExpression(StackType.Exec, "EXEC.IF")]
82  public class ExecIfExpression : StatelessExpression {
83    public override void Eval(IPushGpInterpreter interpreter) {
84      // not enough arguments on stack
85      if ((interpreter.BooleanStack.Count == 0) || (interpreter.ExecStack.Count < 2)) return;
86
87      var condition = interpreter.BooleanStack.Pop();
88
89      if (condition) interpreter.ExecStack.RemoveAt(interpreter.ExecStack.Count - 2);
90      else interpreter.ExecStack.RemoveTop();
91    }
92  }
93
94  /// <summary>
95  ///     Inserts beneath the top item of the EXEC stack a new item of the form
96  ///     "( EXEC.Y <TopItem> )".
97  /// </summary>
98  [PushExpression(StackType.Exec, "EXEC.Y")]
99  public class ExecYExpression : StatelessExpression {
100    public override void Eval(IPushGpInterpreter interpreter) {
101      // not enough arguments on stack
102      if (interpreter.ExecStack.Count == 0 ||
103          interpreter.Configuration.MaxPointsInProgram < 2)
104        return;
105
106      var top = interpreter.ExecStack.Top;
107      var result = new ExecExpandExpression(top, new ExecYExpression());
108
109      //interpreter.ExecStack.Insert(interpreter.ExecStack.Count - 1, result);
110      interpreter.ExecStack.SetTop(result);
111      interpreter.ExecStack.Add(top);
112    }
113  }
114
115  /// <summary>
116  ///     Removes the second item on the EXEC stack.
117  /// </summary>
118  [PushExpression(StackType.Exec, "EXEC.K")]
119  public class ExecKExpression : StatelessExpression {
120    public override void Eval(IPushGpInterpreter interpreter) {
121      if (interpreter.ExecStack.Count < 2) return;
122
123      var top = interpreter.ExecStack.Pop();
124      interpreter.ExecStack.SetTop(top);
125    }
126  }
127
128  /// <summary>
129  ///     Pops 3 items from the EXEC stack, which we will call A, B, and C
130  ///     (with A being the first one popped). Then pushes a list containing B and C back onto the EXEC stack, followed by
131  ///     another instance of C, followed by another instance of A.
132  /// </summary>
133  [PushExpression(StackType.Exec, "EXEC.S")]
134  public class ExecSExpression : StatelessExpression {
135    public override void Eval(IPushGpInterpreter interpreter) {
136      if (interpreter.ExecStack.Count < 3) return;
137
138      var expression = interpreter.ExecStack.Pop(2);
139      var a = expression[1];
140      var b = expression[0];
141      var c = interpreter.ExecStack.Top;
142
143      var newTop = new ExecExpandExpression(c, b);
144
145      interpreter.ExecStack.SetTop(newTop);
146      interpreter.ExecStack.Push(c, a);
147    }
148  }
149}
Note: See TracBrowser for help on using the repository browser.