Free cookie consent management tool by TermsFeed Policy Generator

source: addons/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Views/PushDebuggerView.cs @ 16958

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

#2665 Fixed analyzer, fixed Plush encoding + operators, adpated print evaluation according to McPhee

File size: 8.5 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Drawing;
4using System.Linq;
5using System.Windows.Forms;
6
7namespace HeuristicLab.Problems.ProgramSynthesis.Push.Views {
8  using Configuration;
9  using Core.Views;
10  using Expressions;
11
12  using HeuristicLab.Problems.ProgramSynthesis.Push.Solution;
13
14  using Interpreter;
15  using MainForm;
16  using Stack;
17
18  public partial class PushDebuggerView : ItemView {
19    private readonly IDictionary<StackTypes, ListBox> debugListDict = new Dictionary<StackTypes, ListBox>();
20    private readonly IDictionary<StackTypes, PushProgramTreeView> debugPushProgramDict = new Dictionary<StackTypes, PushProgramTreeView>();
21
22    private PooledPushInterpreter interpreter;
23    private PushInterpreterPool pool;
24
25    private const string GROUP_BOX_TEXT_STRING_FORMAT = "{0}[{1}]";
26    private const string EXEC_COUNT_LABEL_FORMAT = "{0}/{1} max. expressions evaluated";
27
28    public event EventHandler<IPushInterpreter> OnReset;
29
30    public PushDebuggerView() {
31      InitializeComponent();
32      InitEvents();
33    }
34
35    ~PushDebuggerView() {
36      interpreter.Dispose();
37    }
38
39    public new PushSolution Content
40    {
41      get { return (PushSolution)base.Content; }
42      set
43      {
44        base.Content = value;
45      }
46    }
47
48    protected override void OnContentChanged() {
49      if (Content == null) return;
50
51      Name = "Push Debugger";
52      pool = new PushInterpreterPool(Content.Config);
53
54      if (interpreter != null) {
55        interpreter.Dispose();
56      }
57
58      var random = Content.GetRandom();
59      interpreter = pool.Create(random);
60
61      InitDebugLists(Content.Config);
62      ClearDebugLists();
63      UpdateExecList();
64      UpdateDebugLists();
65      ResetDebugging();
66    }
67
68    private void UpdateExecCountLabel() {
69      execCountLabel.Text = string.Format(
70        EXEC_COUNT_LABEL_FORMAT,
71        interpreter.ExecCounter,
72        Content.Config.EvalPushLimit);
73    }
74
75    private void InitEvents() {
76      runButton.Click += RunButtonClick;
77      resetButton.Click += ResetButtonClick;
78      stepButton.Click += StepButtonClick;
79      simplifyButton.Click += SimplifyButtonClick;
80    }
81
82    private void RunButtonClick(object sender, EventArgs e) {
83      if (interpreter == null)
84        return;
85
86      interpreter.Resume();
87      UpdateStep();
88    }
89
90    private void StepButtonClick(object sender, EventArgs e) {
91      if (interpreter == null || stepWidthBox.Value <= 0)
92        return;
93
94      var count = Math.Min(stepWidthBox.Value, interpreter.ExecStack.Count);
95
96      for (var i = 0; i < count; i++) {
97        SkipNoops();
98
99        // run next none noop expression
100        interpreter.Step();
101      }
102
103      // skip trailing noops so next expression is a none noop in debugger
104      SkipNoops();
105
106      stepWidthBox.Maximum = Math.Max(1, interpreter.ExecStack.Count);
107      UpdateStep();
108    }
109
110    private void UpdateStep() {
111      UpdateExecList();
112      UpdateDebugLists();
113      UpdateExecCountLabel();
114      CheckIfButtonsCanBeEnabled();
115    }
116
117    private void SkipNoops() {
118      // skip noops
119      if (skipNoopsCheckBox.Checked) {
120        while (interpreter.CanStep && interpreter.ExecStack.Top.IsNoop(interpreter)) {
121          interpreter.Step();
122        }
123      }
124    }
125
126    private void CheckIfButtonsCanBeEnabled() {
127      runButton.Enabled = interpreter != null && interpreter.CanStep;
128      stepButton.Enabled = interpreter != null && interpreter.CanStep;
129      stepWidthBox.Enabled = interpreter != null && interpreter.CanStep;
130    }
131
132    private void ResetButtonClick(object sender, EventArgs e) {
133      ResetDebugging();
134    }
135
136    private void SimplifyButtonClick(object sender, EventArgs e) {
137      var newContent = Content.Simplify();
138
139      MainFormManager.MainForm.ShowContent(newContent, GetType());
140    }
141
142    public void ResetDebugging() {
143      if (Content == null ||
144          pool == null ||
145          Content.Program == null)
146        return;
147
148      if (interpreter != null) {
149        interpreter.Reset();
150      }
151
152      if (OnReset != null) {
153        OnReset(this, interpreter);
154      }
155
156      interpreter.Run(Content.Program, true);
157
158      stepWidthBox.Maximum = interpreter.ExecStack.Count;
159      UpdateStep();
160    }
161
162    private void ClearDebugLists() {
163      foreach (var list in debugListDict.Values) {
164        list.Items.Clear();
165      }
166
167      foreach (var treeView in debugPushProgramDict.Values) {
168        treeView.Nodes.Clear();
169      }
170    }
171
172    private void UpdateExecList() {
173      execTreeView.LoadExpressions(interpreter.ExecStack.Reverse());
174      exec2GroupBox.Text = string.Format(GROUP_BOX_TEXT_STRING_FORMAT, Enum.GetName(typeof(StackTypes), StackTypes.Exec), interpreter.ExecStack.Count);
175    }
176
177    private void InitDebugLists(IReadOnlyPushConfiguration config) {
178      debugListDict.Clear();
179      debugPushProgramDict.Clear();
180
181      // 2 = ExecList + EmptyColumn which is required to fill empty space
182      while (debugTableLayout.ColumnCount > 2) {
183        debugTableLayout.Controls.RemoveAt(1);
184        debugTableLayout.ColumnCount--;
185      }
186
187      foreach (StackTypes stackType in Enum.GetValues(typeof(StackTypes))) {
188        if (stackType == StackTypes.Exec || !config.IsStackEnabled(stackType))
189          continue;
190
191        switch (stackType) {
192          case StackTypes.Code:
193            var treeView = CreatePushProgramTreeView(stackType);
194            debugPushProgramDict.Add(stackType, treeView);
195            break;
196          default:
197            var list = CreateDebugList(stackType);
198            debugListDict.Add(stackType, list);
199            break;
200        }
201      }
202    }
203
204    private PushProgramTreeView CreatePushProgramTreeView(StackTypes type) {
205
206      var treeView = new PushProgramTreeView {
207        Dock = DockStyle.Fill
208      };
209
210      AddStackControlToTableLayout(type, treeView, 400);
211
212      return treeView;
213    }
214
215    private void AddStackControlToTableLayout(StackTypes type, Control control, int width) {
216      var groupBox = CreateStackGroupBox(type);
217      groupBox.Controls.Add(control);
218
219      debugTableLayout.ColumnCount++;
220      debugTableLayout.ColumnStyles.Insert(1, new ColumnStyle(SizeType.Absolute, width));
221      debugTableLayout.Controls.Add(groupBox);
222      debugTableLayout.Controls.SetChildIndex(groupBox, 1);
223    }
224
225    private ListBox CreateDebugList(StackTypes type) {
226      var list = new ListBox {
227        Dock = DockStyle.Fill
228      };
229
230      // align numbers right
231      if (type == StackTypes.Integer ||
232          type == StackTypes.Float) {
233        list.DrawMode = DrawMode.OwnerDrawFixed;
234        list.DrawItem += (sender, e) => {
235          if (e.Index <= -1) return;
236          var item = list.Items[e.Index];
237
238          e.DrawBackground();
239          e.DrawFocusRectangle();
240
241          var brush = new SolidBrush(e.ForeColor);
242          var size = e.Graphics.MeasureString(item.ToString(), e.Font);
243
244          e.Graphics.DrawString(
245            item.ToString(),
246            e.Font,
247            brush,
248            e.Bounds.Right - size.Width,
249            e.Bounds.Top + (e.Bounds.Height / 2 - size.Height / 2));
250        };
251      }
252
253      AddStackControlToTableLayout(type, list, 150);
254
255      return list;
256    }
257
258    private static GroupBox CreateStackGroupBox(StackTypes type) {
259      return new GroupBox {
260        Anchor = AnchorStyles.Bottom | AnchorStyles.Right | AnchorStyles.Left | AnchorStyles.Top,
261        AutoSize = true,
262        AutoSizeMode = AutoSizeMode.GrowAndShrink,
263        Text = Enum.GetName(typeof(StackTypes), type)
264      };
265    }
266
267    private void UpdateDebugLists() {
268      ClearDebugLists();
269
270      if (Content == null || interpreter == null)
271        return;
272
273      foreach (var pair in debugPushProgramDict) {
274        var name = Enum.GetName(typeof(StackTypes), pair.Key);
275        var stack = (IPushStack<Expression>)interpreter.Stacks[pair.Key];
276
277        pair.Value.AddExpressions(stack);
278        ((GroupBox)pair.Value.Parent).Text = string.Format(GROUP_BOX_TEXT_STRING_FORMAT, name, pair.Value.Nodes.Count);
279      }
280
281      foreach (var pair in debugListDict) {
282        var name = Enum.GetName(typeof(StackTypes), pair.Key);
283        var items = interpreter.StringifyStack(pair.Key).ToArray();
284
285        pair.Value.Items.AddRange(items);
286        ((GroupBox)pair.Value.Parent).Text = string.Format(GROUP_BOX_TEXT_STRING_FORMAT, name, pair.Value.Items.Count);
287      }
288    }
289
290  }
291}
Note: See TracBrowser for help on using the repository browser.