Free cookie consent management tool by TermsFeed Policy Generator

source: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Views/PushProgramDebuggerView.cs @ 14778

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

#2665 simplifier, push solution results view, performance improvements, small bug fixes, ui fixes

File size: 15.0 KB
Line 
1using System.Windows.Forms;
2
3using HeuristicLab.Core.Views;
4using HeuristicLab.MainForm;
5
6namespace HeuristicLab.Problems.ProgramSynthesis.Push.Views {
7  using System;
8  using System.Linq;
9
10  using HeuristicLab.BenchmarkSuite;
11  using HeuristicLab.BenchmarkSuite.Problems;
12  using HeuristicLab.BenchmarkSuite.Views;
13  using HeuristicLab.Problems.ProgramSynthesis.Push.Expressions;
14  using HeuristicLab.Problems.ProgramSynthesis.Push.Interpreter;
15  using HeuristicLab.Problems.ProgramSynthesis.Push.Problem;
16  using HeuristicLab.Problems.ProgramSynthesis.Push.Stack;
17  using HeuristicLab.Random;
18
19  [View("Push Program Debugger")]
20  [Content(typeof(PushSolution), true)]
21  public partial class PushProgramDebuggerView : NamedItemView {
22    private const string Separator = ", ";
23    private const string EmptySign = "-";
24    private PushProgram program;
25
26    private ListViewItem[] execListCache; //array to cache items for the virtual list
27    private int firstExecListItemIndex; //stores the index of the first item in the cache
28
29    private const string exampleSplitter = " => ";
30    private PushInterpreter interpreter;
31
32    public PushProgramDebuggerView() {
33      InitializeComponent();
34
35      Name = "Push Program Debugger";
36
37      InitEvents();
38      InitExecList();
39    }
40
41    private void InitEvents() {
42      exampleComboBox.SelectedIndexChanged += SelectedExampleIndexChanged;
43      runButton.Click += RunButtonClick;
44      resetButton.Click += ResetButtonClick;
45      stepButton.Click += StepButtonClick;
46      simplifyButton.Click += SimplifyButtonClick;
47    }
48
49    private void SimplifyButtonClick(object sender, EventArgs e) {
50
51    }
52
53    private void InitExecList() {
54      execList.RetrieveVirtualItem += ExecListRetrieveVirtualItem;
55      execList.CacheVirtualItems += ExecListCacheVirtualItems;
56
57      execList.View = View.Details;
58      execList.HeaderStyle = ColumnHeaderStyle.None;
59      execList.AutoResizeColumns(ColumnHeaderAutoResizeStyle.None);
60      execList.Columns.Add(new ColumnHeader { Width = execList.Width - 40 });
61      execList.VirtualMode = true;
62      execList.VirtualListSize = 100;
63    }
64
65    private void ExecListCacheVirtualItems(object sender, CacheVirtualItemsEventArgs e) {
66      //We've gotten a request to refresh the cache.
67      //First check if it's really neccesary.
68      if (execListCache != null &&
69        e.StartIndex >= firstExecListItemIndex &&
70        e.EndIndex <= firstExecListItemIndex + execListCache.Length) {
71        //If the newly requested cache is a subset of the old cache,
72        //no need to rebuild everything, so do nothing.
73        return;
74      }
75
76      //Now we need to rebuild the cache.
77      UpdateListCache(e.StartIndex, e.EndIndex);
78    }
79
80    private void ExecListRetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e) {
81      //check to see if the requested item is currently in the cache
82      if (execListCache == null ||
83        e.ItemIndex < firstExecListItemIndex ||
84        e.ItemIndex >= firstExecListItemIndex + execListCache.Length) {
85        UpdateListCache(e.ItemIndex, execList.VirtualListSize);
86      }
87
88      e.Item = e.ItemIndex >= firstExecListItemIndex && e.ItemIndex < firstExecListItemIndex + execListCache.Length
89          ? execListCache[e.ItemIndex - firstExecListItemIndex]
90          : e.Item = new ListViewItem();
91    }
92
93    private void UpdateListCache(int startIndex, int endIndex) {
94      if (interpreter == null) {
95        execListCache = new ListViewItem[0];
96        return;
97      }
98
99      this.firstExecListItemIndex = startIndex;
100      var length = Math.Min(endIndex - startIndex + 1, interpreter.ExecStack.Count); //indexes are inclusive
101      this.execListCache = new ListViewItem[length];
102
103      var expressions = this.interpreter.ExecStack.Peek(length);
104
105      //Fill the cache with the appropriate ListViewItems.
106      for (var i = 0; i < length; i++)
107        this.execListCache[i] = new ListViewItem(expressions[length - 1 - i].ToString());
108
109      execList.AutoResizeColumns(ColumnHeaderAutoResizeStyle.None);
110      execList.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent);
111    }
112
113    //protected override void OnEnabledChanged(EventArgs e) {
114    //  SetReadonlyFields();
115    //}
116
117    //protected override void OnReadOnlyChanged() {
118    //  base.OnReadOnlyChanged();
119
120    //  SetReadonlyFields();
121    //}
122
123    //protected override void SetEnabledStateOfControls()
124    //{
125    //  SetReadonlyFields();
126    //}
127
128    private void SetReadonlyFields() {
129      var enabled = !ReadOnly;
130
131      exampleComboBox.Enabled = enabled;
132      execList.Enabled = enabled;
133      codeList.Enabled = enabled;
134      nameList.Enabled = enabled;
135      integerList.Enabled = enabled;
136      floatList.Enabled = enabled;
137      booleanList.Enabled = enabled;
138      stringList.Enabled = enabled;
139      charList.Enabled = enabled;
140      stepButton.Enabled = enabled;
141      runButton.Enabled = enabled;
142      resetButton.Enabled = enabled;
143      skipNoopsCheckBox.Enabled = enabled;
144      stepWidthBox.Enabled = enabled;
145    }
146
147    private void RunButtonClick(object sender, EventArgs e) {
148      if (interpreter == null)
149        return;
150
151      interpreter.Resume();
152
153      UpdateExecList();
154      UpdateValueLists();
155      CheckIfButtonsCanBeEnabled();
156    }
157
158    private void SyncExecList() {
159      UpdateExecList();
160
161      this.execGroupBox.Text = string.Format("Exec [{0}]", this.interpreter.ExecStack.Count);
162    }
163
164    private void StepButtonClick(object sender, EventArgs e) {
165      if (interpreter == null || stepWidthBox.Value <= 0)
166        return;
167
168      var count = Math.Min(stepWidthBox.Value, interpreter.ExecStack.Count);
169
170      for (var i = 0; i < count; i++) {
171        if (skipNoopsCheckBox.Checked) {
172          bool noop;
173
174          do {
175            noop = !interpreter.Step();
176          }
177          while (interpreter.CanStep && noop);
178        } else interpreter.Step();
179      }
180
181      stepWidthBox.Maximum = interpreter.ExecStack.Count;
182
183      SyncExecList();
184      UpdateValueLists();
185      CheckIfButtonsCanBeEnabled();
186    }
187
188    private void CheckIfButtonsCanBeEnabled() {
189      if (interpreter == null)
190        return;
191
192      runButton.Enabled = interpreter.CanStep;
193      stepButton.Enabled = interpreter.CanStep;
194      stepWidthBox.Enabled = interpreter.CanStep;
195    }
196
197    private void ResetButtonClick(object sender, System.EventArgs e) {
198      Reset();
199    }
200
201    private void SelectedExampleIndexChanged(object sender, System.EventArgs e) {
202      Reset();
203    }
204
205    public new PushSolution Content
206    {
207      get { return (PushSolution)base.Content; }
208      set
209      {
210        base.Content = value;
211      }
212    }
213
214    private void Reset() {
215      if (Content == null ||
216        interpreter == null ||
217        this.exampleComboBox.SelectedIndex < 0)
218        return;
219
220      interpreter.Clear();
221
222      var example = Content.Data.Examples[this.exampleComboBox.SelectedIndex];
223
224      interpreter.BooleanStack.Push(example.InputBoolean);
225      interpreter.IntegerStack.Push(example.InputInt);
226      interpreter.FloatStack.Push(example.InputFloat);
227
228      interpreter.Run(program, true);
229      stepWidthBox.Maximum = interpreter.ExecStack.Count;
230
231      UpdateValueLists();
232      UpdateExecList();
233      CheckIfButtonsCanBeEnabled();
234    }
235
236    protected override void OnContentChanged() {
237      if (Content == null) return;
238
239      this.nameTextBox.Text = "Push Solution";
240
241      var random = Content.Random ?? new FastRandom();
242      interpreter = new PushInterpreter(Content.Config, random);
243      program = Content.IntegerVector.MapToPushProgram(Content.Config.EnabledExpressions);
244
245      UpdateExamples(Content.Data);
246      InitResultGrid();
247
248      if (this.exampleComboBox.SelectedIndex < 0) {
249        this.exampleComboBox.SelectedIndex = 0; // Triggers Reset via event
250      } else {
251        Reset();
252      }
253    }
254
255    private void InitResultGrid() {
256      var cellTemplate = new DataGridViewTextBoxCell();
257
258      for (var i = 0; i < Content.Data.InputArgumentTypes.Length; i++) {
259        var headerTypeName = ViewHelper.GetHeaderTypeName(Content.Data.InputArgumentTypes[i]);
260        var column = new DataGridViewColumn {
261          HeaderText = string.Format("Input {0} : {1}", i + 1, headerTypeName),
262          AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill,
263          CellTemplate = cellTemplate
264        };
265
266        resultsDataGrid.Columns.Add(column);
267      }
268
269      for (var i = 0; i < Content.Data.OutputArgumentTypes.Length; i++) {
270        var headerTypeName = ViewHelper.GetHeaderTypeName(Content.Data.OutputArgumentTypes[i]);
271
272        var estimatedOutputColumn = new DataGridViewColumn {
273          HeaderText = string.Format("Estimated Output {0} : {1}", i + 1, headerTypeName),
274          AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill,
275          CellTemplate = cellTemplate
276        };
277
278        var outputColumn = new DataGridViewColumn {
279          HeaderText = string.Format("Output {0} : {1}", i + 1, headerTypeName),
280          AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill,
281          CellTemplate = cellTemplate
282        };
283
284        resultsDataGrid.Columns.Add(estimatedOutputColumn);
285        resultsDataGrid.Columns.Add(outputColumn);
286      }
287
288      resultsDataGrid.Columns.Add(
289        new DataGridViewColumn {
290          HeaderText = "Absolute Diff.",
291          AutoSizeMode = DataGridViewAutoSizeColumnMode.ColumnHeader,
292          CellTemplate = cellTemplate
293        });
294
295      resultsDataGrid.Columns.Add(
296        new DataGridViewColumn {
297          HeaderText = "Relative Diff.",
298          AutoSizeMode = DataGridViewAutoSizeColumnMode.ColumnHeader,
299          CellTemplate = cellTemplate,
300        });
301
302      var pool = new PushInterpreterPool(Content.Config);
303      var program = Content.IntegerVector.MapToPushProgram(Content.Config.EnabledExpressions);
304
305      using (var pushInterpreter = pool.Create(Content.Random)) {
306        foreach (var example in Content.Data.Examples) {
307          var row = new DataGridViewRow();
308          var absoluteDiff = PushEvaluator.Evaluate(pushInterpreter, program, example, Content.Data.WorstResult);
309          var relativeDiff = absoluteDiff / Math.Abs(Content.Data.BestResult - Content.Data.WorstResult) * 100d;
310
311          row.HeaderCell.Value = row.Index + 1;
312          row.CreateCells(resultsDataGrid);
313
314          for (var i = 0; i < Content.Data.InputArgumentTypes.Length; i++) {
315            row.Cells[i].Value = ViewHelper.StringifyInput(Content.Data.InputArgumentTypes[i], example, Separator);
316          }
317
318          for (var i = 0; i < Content.Data.OutputArgumentTypes.Length; i++) {
319            row.Cells[Content.Data.InputArgumentTypes.Length + i * 2].Value = ViewHelper.StringifyOutput(Content.Data.OutputArgumentTypes[i], example, Separator);
320            row.Cells[Content.Data.InputArgumentTypes.Length + i * 2 + 1].Value = StringifyResult(Content.Data.OutputArgumentTypes[i], pushInterpreter, example, Separator);
321          }
322
323          row.Cells[Content.Data.TotalArgumentCount + 1].Value = absoluteDiff;
324          row.Cells[Content.Data.TotalArgumentCount + 2].Value = relativeDiff + "%";
325
326          this.resultsDataGrid.Rows.Add(row);
327          pushInterpreter.Clear();
328        }
329      }
330    }
331
332    private string StringifyResult(ExampleArgumentType type, IPushInterpreter interpreter, Example example, string valueSeparator) {
333      switch (type) {
334        case ExampleArgumentType.Integer:
335        case ExampleArgumentType.IntegerCollection: return interpreter.IntegerStack.IsEmpty ? EmptySign : string.Join(valueSeparator, interpreter.IntegerStack.Peek(GetCount(interpreter.IntegerStack, example.OutputInt)));
336
337        case ExampleArgumentType.Float:
338        case ExampleArgumentType.FloatCollection: return interpreter.FloatStack.IsEmpty ? EmptySign : string.Join(valueSeparator, interpreter.FloatStack.Peek(GetCount(interpreter.FloatStack, example.OutputFloat)));
339
340        case ExampleArgumentType.Bool: return interpreter.BooleanStack.IsEmpty ? EmptySign : interpreter.BooleanStack.Top.ToString();
341        case ExampleArgumentType.Char: return interpreter.CharStack.IsEmpty ? EmptySign : interpreter.CharStack.Top.ToString();
342
343        case ExampleArgumentType.String:
344        case ExampleArgumentType.StringCollection: return interpreter.StringStack.IsEmpty ? EmptySign : string.Join(valueSeparator, interpreter.StringStack.Peek(GetCount(interpreter.StringStack, example.OutputString)));
345        default: return string.Empty;
346      }
347    }
348
349    private int GetCount<T>(IStack<T> stack, T[] data) {
350      return Math.Max(0, Math.Min(data.Length, stack.Count));
351    }
352
353    private void ClearLists() {
354      codeList.Items.Clear();
355      nameList.Items.Clear();
356      booleanList.Items.Clear();
357      integerList.Items.Clear();
358      floatList.Items.Clear();
359    }
360
361    private void UpdateExecList() {
362      UpdateListCache(0, execList.VirtualListSize);
363      execList.Update();
364
365      this.execGroupBox.Text = string.Format("Exec [{0}]", this.execList.Items.Count);
366    }
367
368    private void UpdateValueLists() {
369      ClearLists();
370
371      if (Content == null || interpreter == null)
372        return;
373
374      ManageStackType(interpreter.Configuration.IsCodeStackEnabled, codeList, codeGroupBox, interpreter.CodeStack, "Code");
375      ManageStackType(interpreter.Configuration.IsIntegerStackEnabled, integerList, integerGroupBox, interpreter.IntegerStack, "Integer");
376      ManageStackType(interpreter.Configuration.IsFloatStackEnabled, floatList, floatGroupBox, interpreter.FloatStack, "Float");
377      ManageStackType(interpreter.Configuration.IsBooleanStackEnabled, booleanList, booleanGroupBox, interpreter.BooleanStack, "Boolean");
378      ManageStackType(interpreter.Configuration.IsNameStackEnabled, nameList, nameGroupBox, interpreter.NameStack, "Name");
379      ManageStackType(interpreter.Configuration.IsStringStackEnabled, stringList, stringGroupBox, interpreter.StringStack, "String");
380      ManageStackType(interpreter.Configuration.IsCharStackEnabled, charList, charGroupBox, interpreter.CharStack, "Char");
381    }
382
383    private void ManageStackType<T>(bool enabled, ListBox listbox, GroupBox groupBox, IStack<T> stack, string name) {
384      if (enabled) {
385        listbox.Enabled = true;
386
387        foreach (var item in stack.Reverse())
388          listbox.Items.Add(item);
389
390        groupBox.Text = string.Format("{0} [{1}]", name, listbox.Items.Count);
391      } else {
392        listbox.Enabled = false;
393        groupBox.Text = string.Format("{0} - DISABLED", name);
394      }
395    }
396
397    private void UpdateExamples(Data data) {
398      if (data == null) return;
399
400      var stringRepresentations = data.Examples.Select(e =>
401        string.Join(Separator, e.InputArgs) +
402        exampleSplitter +
403        string.Join(Separator, e.OutputArgs));
404
405      exampleComboBox.Items.Clear();
406      foreach (var str in stringRepresentations) {
407        exampleComboBox.Items.Add(str);
408      }
409    }
410  }
411}
Note: See TracBrowser for help on using the repository browser.