Free cookie consent management tool by TermsFeed Policy Generator

source: branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Views/PushDebuggerView.cs @ 15273

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

#2665 Started Plush Encoding, Added Zero Error Individual Count Analyzer

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