Free cookie consent management tool by TermsFeed Policy Generator

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

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

#2665 Fixed bias 0 issue, PushExpressionFrequencyAnalyzer, Fixed probability for ERC settings, Fixed enable/disable instructions, Added expression descriptions

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