Free cookie consent management tool by TermsFeed Policy Generator

source: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/ExecExpressions.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: 5.8 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 : StatefulExpression<PushProgram> {
12    public static readonly ExecExpandExpression Empty = new ExecExpandExpression(PushProgram.Empty);
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 bool Eval(IPushInterpreter interpreter) {
35      interpreter.ExecStack.Push(this.State.Expressions);
36      return true;
37    }
38
39    /// <summary>
40    ///     Returns the element with the given index whereby the tree is indexed in depth first manner
41    /// </summary>
42    /// <param name="index">The index of the required element</param>
43    /// <returns>The required element</returns>
44    public Expression GetFromTree(int index) {
45      return GetFromTree(index, (root, parent, child, childIndex, parentIndex) => child);
46    }
47
48    /// <returns>The required element</returns>
49    public T GetFromTree<T>(int index,
50        Func<ExecExpandExpression, ExecExpandExpression, Expression, int, int, T> resolver) {
51      return GetFromTree(index, 0, null, resolver);
52    }
53
54    private T GetFromTree<T>(int index, int parentIndex, ExecExpandExpression parent,
55        Func<ExecExpandExpression, ExecExpandExpression, Expression, int, int, T> resolver) {
56      if (index == 0) return resolver(parent, parent, this, 0, parentIndex);
57
58      var min = State.Expressions.Count - 1;
59      var max = 0;
60      var mid = (min + max) / 2;
61
62      while ((max <= min) && (this.State.TreeIndex[mid] != index)) {
63        if (this.State.TreeIndex[mid] > index) max = mid + 1;
64        else min = mid - 1;
65
66        mid = (min + max) / 2;
67      }
68
69      return this.State.TreeIndex[mid] == index
70          ? resolver(parent, this, State.Expressions[mid], mid, parentIndex)
71          : (State.Expressions[mid + 1] as ExecExpandExpression).GetFromTree(index - this.State.TreeIndex[mid + 1], mid + 1,
72              this, resolver);
73    }
74  }
75
76  /// <summary>
77  /// If the top item of the BOOLEAN stack is TRUE then this removes the second item on the EXEC stack, leaving the first
78  /// item to be executed. If it is false then it removes the first item, leaving the second to be executed. This is similar to
79  /// 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
80  /// one item on the BOOLEAN stack.
81  /// </summary>
82  [PushExpression(StackType.Exec, "EXEC.IF")]
83  public class ExecIfExpression : StatelessExpression {
84    public override bool Eval(IPushInterpreter interpreter) {
85      // not enough arguments on stack
86      if ((interpreter.BooleanStack.Count == 0) || (interpreter.ExecStack.Count < 2)) return false;
87
88      var condition = interpreter.BooleanStack.Pop();
89
90      if (condition) interpreter.ExecStack.RemoveAt(interpreter.ExecStack.Count - 2);
91      else interpreter.ExecStack.RemoveTop();
92
93      return true;
94    }
95  }
96
97  /// <summary>
98  ///     Inserts beneath the top item of the EXEC stack a new item of the form
99  ///     "( EXEC.Y <TopItem> )".
100  /// </summary>
101  [PushExpression(StackType.Exec, "EXEC.Y")]
102  public class ExecYExpression : StatelessExpression {
103    public override bool Eval(IPushInterpreter interpreter) {
104      // not enough arguments on stack
105      if (interpreter.ExecStack.Count == 0 ||
106          interpreter.Configuration.MaxPointsInProgram < 2)
107        return false;
108
109      var top = interpreter.ExecStack.Top;
110      var execYExpression = ExpressionTable.GetStatelessExpression<ExecYExpression>();
111
112      var result = new ExecExpandExpression(top, execYExpression);
113
114      interpreter.ExecStack.SetTop(result);
115      interpreter.ExecStack.Add(top);
116
117      return true;
118    }
119  }
120
121  /// <summary>
122  ///     Removes the second item on the EXEC stack.
123  /// </summary>
124  [PushExpression(StackType.Exec, "EXEC.K")]
125  public class ExecKExpression : StatelessExpression {
126    public override bool Eval(IPushInterpreter interpreter) {
127      if (interpreter.ExecStack.Count < 2) return false;
128
129      var top = interpreter.ExecStack.Pop();
130      interpreter.ExecStack.SetTop(top);
131
132      return true;
133    }
134  }
135
136  /// <summary>
137  ///     Pops 3 items from the EXEC stack, which we will call A, B, and C
138  ///     (with A being the first one popped). Then pushes a list containing B and C back onto the EXEC stack, followed by
139  ///     another instance of C, followed by another instance of A.
140  /// </summary>
141  [PushExpression(StackType.Exec, "EXEC.S")]
142  public class ExecSExpression : StatelessExpression {
143    public override bool Eval(IPushInterpreter interpreter) {
144      if (interpreter.ExecStack.Count < 3) return false;
145
146      var expression = interpreter.ExecStack.Pop(2);
147      var a = expression[1];
148      var b = expression[0];
149      var c = interpreter.ExecStack.Top;
150
151      var newTop = new ExecExpandExpression(c, b);
152
153      interpreter.ExecStack.SetTop(newTop);
154      interpreter.ExecStack.Push(c, a);
155
156      return true;
157    }
158  }
159}
Note: See TracBrowser for help on using the repository browser.