Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
04/10/17 00:27:31 (7 years ago)
Author:
pkimmesw
Message:

#2665 LexicaseSelector, Performance improvements, UI Fixes, Debugger only shows used stacks, fixed Debugger stepping, Added vector expressions, ERCOptions,

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Views/PushProgramDebuggerView.cs

    r14777 r14834  
    66namespace HeuristicLab.Problems.ProgramSynthesis.Push.Views {
    77  using System;
     8  using System.Collections.Generic;
     9  using System.Drawing;
     10  using System.Globalization;
    811  using System.Linq;
    912
     
    1114  using HeuristicLab.BenchmarkSuite.Problems;
    1215  using HeuristicLab.BenchmarkSuite.Views;
     16  using HeuristicLab.Core;
     17  using HeuristicLab.Encodings.IntegerVectorEncoding;
     18  using HeuristicLab.Problems.ProgramSynthesis.Push.Configuration;
    1319  using HeuristicLab.Problems.ProgramSynthesis.Push.Expressions;
    1420  using HeuristicLab.Problems.ProgramSynthesis.Push.Interpreter;
    1521  using HeuristicLab.Problems.ProgramSynthesis.Push.Problem;
    1622  using HeuristicLab.Problems.ProgramSynthesis.Push.Stack;
    17   using HeuristicLab.Random;
    1823
    1924  [View("Push Program Debugger")]
    2025  [Content(typeof(PushSolution), true)]
    2126  public partial class PushProgramDebuggerView : NamedItemView {
     27    private readonly IDictionary<StackTypes, ListBox> debugControlDict = new Dictionary<StackTypes, ListBox>();
     28
    2229    private const string Separator = ", ";
    2330    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
    2440    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;
    3144
    3245    public PushProgramDebuggerView() {
     
    3649
    3750      InitEvents();
    38       InitExecList();
     51    }
     52
     53    ~PushProgramDebuggerView() {
     54      interpreter.Dispose();
     55      interpreter2.Dispose();
    3956    }
    4057
     
    4865
    4966    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());
    14578    }
    14679
     
    15689    }
    15790
    158     private void SyncExecList() {
    159       UpdateExecList();
    160 
    161       this.execGroupBox.Text = string.Format("Exec [{0}]", this.interpreter.ExecStack.Count);
    162     }
    163 
    16491    private void StepButtonClick(object sender, EventArgs e) {
    16592      if (interpreter == null || stepWidthBox.Value <= 0)
     
    16895      var count = Math.Min(stepWidthBox.Value, interpreter.ExecStack.Count);
    16996
     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
    170107      for (var i = 0; i < count; i++) {
    171108        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();
    184122      UpdateValueLists();
    185123      CheckIfButtonsCanBeEnabled();
    186124    }
    187125
     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
    188144    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();
    203156    }
    204157
     
    212165    }
    213166
    214     private void Reset() {
     167    private void ResetDebugging() {
    215168      if (Content == null ||
    216         interpreter == null ||
    217         this.exampleComboBox.SelectedIndex < 0)
     169          pool == null ||
     170          program == null ||
     171          exampleComboBox.SelectedIndex < 0)
    218172        return;
    219173
    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      }
    223180
    224181      interpreter.BooleanStack.Push(example.InputBoolean);
     
    226183      interpreter.FloatStack.Push(example.InputFloat);
    227184
     185      interpreter2.BooleanStack.Push(example.InputBoolean);
     186      interpreter2.IntegerStack.Push(example.InputInt);
     187      interpreter2.FloatStack.Push(example.InputFloat);
     188
    228189      interpreter.Run(program, true);
     190      interpreter2.Run(program, true);
     191
    229192      stepWidthBox.Maximum = interpreter.ExecStack.Count;
    230193
     
    237200      if (Content == null) return;
    238201
    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);
    244218
    245219      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);
    246228      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();
    253232    }
    254233
    255234    private void InitResultGrid() {
     235      resultsDataGrid.Columns.Clear();
     236      resultsDataGrid.Rows.Clear();
     237
    256238      var cellTemplate = new DataGridViewTextBoxCell();
    257239
     
    259241        var headerTypeName = ViewHelper.GetHeaderTypeName(Content.Data.InputArgumentTypes[i]);
    260242        var column = new DataGridViewColumn {
    261           HeaderText = string.Format("Input {0} : {1}", i + 1, headerTypeName),
     243          HeaderText = string.Format(InputHeaderStringFormat, i + 1, headerTypeName),
    262244          AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill,
    263245          CellTemplate = cellTemplate
    264246        };
    265247
     248        column.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
    266249        resultsDataGrid.Columns.Add(column);
    267250      }
     
    271254
    272255        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),
    274263          AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill,
    275264          CellTemplate = cellTemplate
    276265        };
    277266
    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;
    283269
    284270        resultsDataGrid.Columns.Add(estimatedOutputColumn);
     
    286272      }
    287273
    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);
    304291
    305292      using (var pushInterpreter = pool.Create(Content.Random)) {
     
    325312
    326313          this.resultsDataGrid.Rows.Add(row);
    327           pushInterpreter.Clear();
     314          pushInterpreter.Reset();
    328315        }
    329316      }
     
    336323
    337324        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)));
    339326
    340327        case ExampleArgumentType.Bool: return interpreter.BooleanStack.IsEmpty ? EmptySign : interpreter.BooleanStack.Top.ToString();
     
    347334    }
    348335
    349     private int GetCount<T>(IStack<T> stack, T[] data) {
     336    private int GetCount<T>(IPushStack<T> stack, T[] data) {
    350337      return Math.Max(0, Math.Min(data.Length, stack.Count));
    351338    }
    352339
    353340    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      }
    359344    }
    360345
    361346    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
    367422
    368423    private void UpdateValueLists() {
     
    372427        return;
    373428
    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);
    394435      }
    395436    }
    396437
    397438    private void UpdateExamples(Data data) {
     439      exampleComboBox.Items.Clear();
    398440      if (data == null) return;
    399441
     
    403445        string.Join(Separator, e.OutputArgs));
    404446
    405       exampleComboBox.Items.Clear();
    406447      foreach (var str in stringRepresentations) {
    407448        exampleComboBox.Items.Add(str);
Note: See TracChangeset for help on using the changeset viewer.