Changeset 14834 for branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Views/PushProgramDebuggerView.cs
- Timestamp:
- 04/10/17 00:27:31 (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Views/PushProgramDebuggerView.cs
r14777 r14834 6 6 namespace HeuristicLab.Problems.ProgramSynthesis.Push.Views { 7 7 using System; 8 using System.Collections.Generic; 9 using System.Drawing; 10 using System.Globalization; 8 11 using System.Linq; 9 12 … … 11 14 using HeuristicLab.BenchmarkSuite.Problems; 12 15 using HeuristicLab.BenchmarkSuite.Views; 16 using HeuristicLab.Core; 17 using HeuristicLab.Encodings.IntegerVectorEncoding; 18 using HeuristicLab.Problems.ProgramSynthesis.Push.Configuration; 13 19 using HeuristicLab.Problems.ProgramSynthesis.Push.Expressions; 14 20 using HeuristicLab.Problems.ProgramSynthesis.Push.Interpreter; 15 21 using HeuristicLab.Problems.ProgramSynthesis.Push.Problem; 16 22 using HeuristicLab.Problems.ProgramSynthesis.Push.Stack; 17 using HeuristicLab.Random;18 23 19 24 [View("Push Program Debugger")] 20 25 [Content(typeof(PushSolution), true)] 21 26 public partial class PushProgramDebuggerView : NamedItemView { 27 private readonly IDictionary<StackTypes, ListBox> debugControlDict = new Dictionary<StackTypes, ListBox>(); 28 22 29 private const string Separator = ", "; 23 30 private const string EmptySign = "-"; 31 32 private const string exampleSplitter = " => "; 33 private const string AbsoluteDiffHeaderText = "Absolute Diff."; 34 private const string RelativeDiffHeaderText = "Relative Diff."; 35 private const string InputHeaderStringFormat = "Input {0} : {1}"; 36 private const string EstimatedOuputHeaderStringFormat = "Estimated Output {0} : {1}"; 37 private const string OutputHeaderStringFormat = "Output {0} : {1}"; 38 private const string GroupBoxTextStringFormat = "{0}[{1}]"; 39 24 40 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; 41 private PooledPushInterpreter interpreter; 42 private PooledPushInterpreter interpreter2; // used to determine noops 43 private PushInterpreterPool pool; 31 44 32 45 public PushProgramDebuggerView() { … … 36 49 37 50 InitEvents(); 38 InitExecList(); 51 } 52 53 ~PushProgramDebuggerView() { 54 interpreter.Dispose(); 55 interpreter2.Dispose(); 39 56 } 40 57 … … 48 65 49 66 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; 67 var newContent = new PushSolution( 68 (IntegerVector)Content.IntegerVector.Clone(), 69 Content.Quality, 70 (Data)Content.Data.Clone(), 71 (IRandom)Content.Random.Clone(), 72 Content.Config, 73 Content.DataStart, 74 Content.DataEnd, 75 true); 76 77 MainFormManager.MainForm.ShowContent(newContent, GetType()); 145 78 } 146 79 … … 156 89 } 157 90 158 private void SyncExecList() {159 UpdateExecList();160 161 this.execGroupBox.Text = string.Format("Exec [{0}]", this.interpreter.ExecStack.Count);162 }163 164 91 private void StepButtonClick(object sender, EventArgs e) { 165 92 if (interpreter == null || stepWidthBox.Value <= 0) … … 168 95 var count = Math.Min(stepWidthBox.Value, interpreter.ExecStack.Count); 169 96 97 if (!interpreter.CanStep) 98 return; 99 100 // skip leading noops 101 if (interpreter2.ExecCounter == (program.IsProgram ? 1 : 0) && 102 skipNoopsCheckBox.Checked && 103 SkipNoops()) { 104 count = 0; // no entries left, cause all were noops 105 } 106 170 107 for (var i = 0; i < count; i++) { 171 108 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(); 109 interpreter.Step(); 110 111 if (SkipNoops()) 112 break; 113 } else { 114 interpreter.Step(); 115 interpreter2.Step(); 116 } 117 } 118 119 stepWidthBox.Maximum = Math.Max(1, interpreter.ExecStack.Count); 120 121 UpdateExecList(); 184 122 UpdateValueLists(); 185 123 CheckIfButtonsCanBeEnabled(); 186 124 } 187 125 126 private bool SkipNoops() { 127 var skipCount = 0; 128 bool isNoop; 129 130 do { 131 skipCount++; 132 isNoop = !interpreter2.Step(); 133 } while (interpreter2.CanStep && isNoop); 134 135 if (isNoop) { 136 interpreter.Step(skipCount); 137 } else if (skipCount > 1) { 138 interpreter.Step(skipCount - 1); 139 } 140 141 return isNoop; 142 } 143 188 144 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(); 145 runButton.Enabled = interpreter != null && interpreter.CanStep; 146 stepButton.Enabled = interpreter != null && interpreter.CanStep; 147 stepWidthBox.Enabled = interpreter != null && interpreter.CanStep; 148 } 149 150 private void ResetButtonClick(object sender, EventArgs e) { 151 this.ResetDebugging(); 152 } 153 154 private void SelectedExampleIndexChanged(object sender, EventArgs e) { 155 this.ResetDebugging(); 203 156 } 204 157 … … 212 165 } 213 166 214 private void Reset () {167 private void ResetDebugging() { 215 168 if (Content == null || 216 interpreter == null || 217 this.exampleComboBox.SelectedIndex < 0) 169 pool == null || 170 program == null || 171 exampleComboBox.SelectedIndex < 0) 218 172 return; 219 173 220 interpreter.Clear(); 221 222 var example = Content.Data.Examples[this.exampleComboBox.SelectedIndex]; 174 var example = Content.Data.Examples[exampleComboBox.SelectedIndex]; 175 176 if (interpreter != null) { 177 interpreter.Reset(); 178 interpreter2.Reset(); 179 } 223 180 224 181 interpreter.BooleanStack.Push(example.InputBoolean); … … 226 183 interpreter.FloatStack.Push(example.InputFloat); 227 184 185 interpreter2.BooleanStack.Push(example.InputBoolean); 186 interpreter2.IntegerStack.Push(example.InputInt); 187 interpreter2.FloatStack.Push(example.InputFloat); 188 228 189 interpreter.Run(program, true); 190 interpreter2.Run(program, true); 191 229 192 stepWidthBox.Maximum = interpreter.ExecStack.Count; 230 193 … … 237 200 if (Content == null) return; 238 201 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); 202 Name = "Push Solution"; 203 nameTextBox.Text = Name; 204 205 pool = new PushInterpreterPool(Content.Config); 206 program = Content.IntegerVector.ToPushProgram(Content.Config); 207 208 if (interpreter != null) { 209 interpreter.Dispose(); 210 interpreter2.Dispose(); 211 } 212 213 interpreter = pool.Create(Content.Random); 214 interpreter2 = pool.Create(Content.Random); 215 216 if (Content.Simplify) 217 program = Simplifier.Simplifier.Simplify(program, p => PushEvaluator.Evaluate(p, pool, Content.Random, Content.Data, Content.DataStart, Content.DataEnd).TotalQuality); 244 218 245 219 UpdateExamples(Content.Data); 220 221 if (exampleComboBox.SelectedIndex < 0) { 222 exampleComboBox.SelectedIndex = 0; // Triggers ResetDebugging via event 223 } else { 224 ResetDebugging(); 225 } 226 227 InitDebugLists(Content.Config); 246 228 InitResultGrid(); 247 248 if (this.exampleComboBox.SelectedIndex < 0) { 249 this.exampleComboBox.SelectedIndex = 0; // Triggers Reset via event 250 } else { 251 Reset(); 252 } 229 ClearLists(); 230 UpdateExecList(); 231 UpdateValueLists(); 253 232 } 254 233 255 234 private void InitResultGrid() { 235 resultsDataGrid.Columns.Clear(); 236 resultsDataGrid.Rows.Clear(); 237 256 238 var cellTemplate = new DataGridViewTextBoxCell(); 257 239 … … 259 241 var headerTypeName = ViewHelper.GetHeaderTypeName(Content.Data.InputArgumentTypes[i]); 260 242 var column = new DataGridViewColumn { 261 HeaderText = string.Format( "Input {0} : {1}", i + 1, headerTypeName),243 HeaderText = string.Format(InputHeaderStringFormat, i + 1, headerTypeName), 262 244 AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill, 263 245 CellTemplate = cellTemplate 264 246 }; 265 247 248 column.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight; 266 249 resultsDataGrid.Columns.Add(column); 267 250 } … … 271 254 272 255 var estimatedOutputColumn = new DataGridViewColumn { 273 HeaderText = string.Format("Estimated Output {0} : {1}", i + 1, headerTypeName), 256 HeaderText = string.Format(EstimatedOuputHeaderStringFormat, i + 1, headerTypeName), 257 AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill, 258 CellTemplate = cellTemplate, 259 }; 260 261 var outputColumn = new DataGridViewColumn { 262 HeaderText = string.Format(OutputHeaderStringFormat, i + 1, headerTypeName), 274 263 AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill, 275 264 CellTemplate = cellTemplate 276 265 }; 277 266 278 var outputColumn = new DataGridViewColumn { 279 HeaderText = string.Format("Output {0} : {1}", i + 1, headerTypeName), 280 AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill, 281 CellTemplate = cellTemplate 282 }; 267 estimatedOutputColumn.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight; 268 outputColumn.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight; 283 269 284 270 resultsDataGrid.Columns.Add(estimatedOutputColumn); … … 286 272 } 287 273 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); 274 var absoluteDiffColumn = new DataGridViewColumn { 275 HeaderText = AbsoluteDiffHeaderText, 276 AutoSizeMode = DataGridViewAutoSizeColumnMode.ColumnHeader, 277 CellTemplate = cellTemplate 278 }; 279 280 var relativeDiffColumn = new DataGridViewColumn { 281 HeaderText = RelativeDiffHeaderText, 282 AutoSizeMode = DataGridViewAutoSizeColumnMode.ColumnHeader, 283 CellTemplate = cellTemplate, 284 }; 285 286 absoluteDiffColumn.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight; 287 relativeDiffColumn.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight; 288 289 resultsDataGrid.Columns.Add(absoluteDiffColumn); 290 resultsDataGrid.Columns.Add(relativeDiffColumn); 304 291 305 292 using (var pushInterpreter = pool.Create(Content.Random)) { … … 325 312 326 313 this.resultsDataGrid.Rows.Add(row); 327 pushInterpreter. Clear();314 pushInterpreter.Reset(); 328 315 } 329 316 } … … 336 323 337 324 case ExampleArgumentType.Float: 338 case ExampleArgumentType.FloatCollection: return interpreter.FloatStack.IsEmpty ? EmptySign : string.Join(valueSeparator, interpreter.FloatStack.Peek(GetCount(interpreter.FloatStack, example.OutputFloat)) );325 case ExampleArgumentType.FloatCollection: return interpreter.FloatStack.IsEmpty ? EmptySign : string.Join(valueSeparator, interpreter.FloatStack.Peek(GetCount(interpreter.FloatStack, example.OutputFloat)).Select(d => d.ToString(CultureInfo.CurrentUICulture))); 339 326 340 327 case ExampleArgumentType.Bool: return interpreter.BooleanStack.IsEmpty ? EmptySign : interpreter.BooleanStack.Top.ToString(); … … 347 334 } 348 335 349 private int GetCount<T>(I Stack<T> stack, T[] data) {336 private int GetCount<T>(IPushStack<T> stack, T[] data) { 350 337 return Math.Max(0, Math.Min(data.Length, stack.Count)); 351 338 } 352 339 353 340 private void ClearLists() { 354 codeList.Items.Clear(); 355 nameList.Items.Clear(); 356 booleanList.Items.Clear(); 357 integerList.Items.Clear(); 358 floatList.Items.Clear(); 341 foreach (var list in debugControlDict.Values) { 342 list.Items.Clear(); 343 } 359 344 } 360 345 361 346 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 } 347 execList.Items.Clear(); 348 var expressions = interpreter.ExecStack 349 .Reverse() 350 .Select(e => e.StringRepresentation) 351 .ToArray(); 352 353 execList.Items.AddRange(expressions); 354 execGroupBox.Text = string.Format(GroupBoxTextStringFormat, Enum.GetName(typeof(StackTypes), StackTypes.Exec), interpreter.ExecStack.Count); 355 } 356 357 private void InitDebugLists(IReadOnlyPushConfiguration config) { 358 debugControlDict.Clear(); 359 360 // 2 = ExecList + EmptyColumn which is required to fill empty space 361 while (debugTableLayout.ColumnCount > 2) { 362 debugTableLayout.Controls.RemoveAt(1); 363 debugTableLayout.ColumnCount--; 364 } 365 366 foreach (StackTypes stackType in Enum.GetValues(typeof(StackTypes))) { 367 if (stackType != StackTypes.Exec && 368 ExpressionTable.GetExpressionsByStackTypes(stackType).Intersect(config.EnabledExpressions).Any()) { 369 var list = GetDebugList(stackType); 370 debugControlDict.Add(stackType, list); 371 } 372 } 373 } 374 375 private ListBox GetDebugList(StackTypes type) { 376 var groupBox = new GroupBox { 377 Anchor = AnchorStyles.Bottom | AnchorStyles.Right | AnchorStyles.Left | AnchorStyles.Top, 378 AutoSize = true, 379 AutoSizeMode = AutoSizeMode.GrowAndShrink, 380 Text = Enum.GetName(typeof(StackTypes), type) 381 }; 382 383 var list = new ListBox { 384 Dock = DockStyle.Fill, 385 DrawMode = DrawMode.OwnerDrawFixed 386 }; 387 388 var stackEntryType = type.GetStackEntryType(); 389 if (stackEntryType == typeof(double) || 390 stackEntryType == typeof(long)) { 391 list.DrawItem += (sender, e) => { 392 if (e.Index <= -1) return; 393 var item = list.Items[e.Index]; 394 395 e.DrawBackground(); 396 e.DrawFocusRectangle(); 397 398 var brush = new SolidBrush(e.ForeColor); 399 var size = e.Graphics.MeasureString(item.ToString(), e.Font); 400 401 e.Graphics.DrawString( 402 item.ToString(), 403 e.Font, 404 brush, 405 e.Bounds.Right - size.Width, 406 e.Bounds.Top + (e.Bounds.Height / 2 - size.Height / 2)); 407 }; 408 } 409 410 groupBox.Controls.Add(list); 411 412 var columnWidth = stackEntryType == typeof(Expression) ? 250 : 150; 413 414 debugTableLayout.ColumnCount++; 415 debugTableLayout.ColumnStyles.Insert(1, new ColumnStyle(SizeType.Absolute, columnWidth)); 416 debugTableLayout.Controls.Add(groupBox); 417 debugTableLayout.Controls.SetChildIndex(groupBox, 1); 418 419 return list; 420 } 421 367 422 368 423 private void UpdateValueLists() { … … 372 427 return; 373 428 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); 429 foreach (var pair in debugControlDict) { 430 var stack = interpreter.GetStackEntriesByType<object>(pair.Key); 431 var name = Enum.GetName(typeof(StackTypes), pair.Key); 432 433 pair.Value.Items.AddRange(stack.Reverse().ToArray()); 434 ((GroupBox)pair.Value.Parent).Text = string.Format(GroupBoxTextStringFormat, name, pair.Value.Items.Count); 394 435 } 395 436 } 396 437 397 438 private void UpdateExamples(Data data) { 439 exampleComboBox.Items.Clear(); 398 440 if (data == null) return; 399 441 … … 403 445 string.Join(Separator, e.OutputArgs)); 404 446 405 exampleComboBox.Items.Clear();406 447 foreach (var str in stringRepresentations) { 407 448 exampleComboBox.Items.Add(str);
Note: See TracChangeset
for help on using the changeset viewer.