Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
03/23/17 01:11:18 (7 years ago)
Author:
pkimmesw
Message:

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/CodeExpressions.cs

    r14746 r14777  
    11/// <summary>
    2 /// For explicit code manipulation and execution. May also be used as a general list data type.
    3 /// This type must always be present, as the top level interpreter will push any code to be executed on the
     2/// For explicit code manipulation and execution. May also be used as a general list data types.
     3/// This types must always be present, as the top level interpreter will push any code to be executed on the
    44/// CODE stack prior to execution. However, one may turn off all CODE instructions if code manipulation is not needed.
    55/// </summary>
     
    2020  ///     manipulates the stack then this final pop may end up popping something else.
    2121  /// </summary>
    22   [PushExpression(StackType.Code, "CODE.DO")]
     22  [PushExpression(StackTypes.Code, "CODE.DO", StackTypes.Exec)]
    2323  public class CodeDoExpression : StatelessExpression {
    2424    public override bool Eval(IPushInterpreter interpreter) {
     
    3636  ///     Like CODE.DO but pops the stack before, rather than after, the recursive execution
    3737  /// </summary>
    38   [PushExpression(StackType.Code, "CODE.DO*")]
     38  [PushExpression(StackTypes.Code, "CODE.DO*", StackTypes.Exec)]
    3939  public class CodeDoXExpression : StatelessExpression {
    4040    public override bool Eval(IPushInterpreter interpreter) {
     
    5252  ///     Does nothing.
    5353  /// </summary>
    54   [PushExpression(StackType.Code, "CODE.NOOP")]
     54  [PushExpression(StackTypes.Code, "CODE.NOOP")]
    5555  public class CodeNoopExpression : StatelessExpression {
    5656    public override bool Eval(IPushInterpreter interpreter) {
     
    6363  ///     This can be implemented by moving the top item on the EXEC stack onto the CODE stack.
    6464  /// </summary>
    65   [PushExpression(StackType.Code, "CODE.QUOTE")]
     65  [PushExpression(StackTypes.Code, "CODE.QUOTE", StackTypes.Exec)]
    6666  public class CodeQuoteExpression : StatelessExpression {
    6767    public override bool Eval(IPushInterpreter interpreter) {
     
    8181  ///     (and the BOOLEAN value upon which the decision was made) are popped.
    8282  /// </summary>
    83   [PushExpression(StackType.Code, "CODE.IF")]
     83  [PushExpression(StackTypes.Code, "CODE.IF", StackTypes.Exec | StackTypes.Boolean)]
    8484  public class CodeIfExpression : StatelessExpression {
    8585    public override bool Eval(IPushInterpreter interpreter) {
     
    100100  ///     literal (that is, something not surrounded by parentheses) then it is surrounded by parentheses first.
    101101  /// </summary>
    102   [PushExpression(StackType.Code, "CODE.APPEND")]
     102  [PushExpression(StackTypes.Code, "CODE.APPEND")]
    103103  public class CodeAppendExpression : StatelessExpression {
    104104    public override bool Eval(IPushInterpreter interpreter) {
    105105      if (interpreter.CodeStack.Count < 2) return false;
    106106
    107       var first = interpreter.CodeStack.Pop();
    108       var second = interpreter.CodeStack.Top;
    109 
    110       var isFirstList = first.IsProgram;
    111       var isSecondList = second.IsProgram;
     107      var first = interpreter.CodeStack.Top;
     108      var second = interpreter.CodeStack.ReverseElementAt(1);
     109      PushProgram firstProgram = null;
     110      PushProgram secondProgram = null;
     111
     112      if (first.IsProgram) {
     113        firstProgram = (PushProgram)first;
     114
     115        if (firstProgram.Depth > interpreter.Configuration.MaxDepth) return false;
     116
     117        if (second.IsProgram) {
     118          secondProgram = (PushProgram)second;
     119
     120          if (secondProgram.Depth > interpreter.Configuration.MaxDepth ||
     121              firstProgram.Count + secondProgram.Count > interpreter.Configuration.MaxPointsInProgram)
     122            return false;
     123        } else if (firstProgram.Count + 1 > interpreter.Configuration.MaxPointsInProgram) return false;
     124      } else if (second.IsProgram) {
     125        secondProgram = (PushProgram)second;
     126
     127        if (secondProgram.Depth > interpreter.Configuration.MaxDepth
     128            || secondProgram.Count + 1 > interpreter.Configuration.MaxPointsInProgram) return false;
     129      } else if (interpreter.Configuration.MaxPointsInProgram <= 2) {
     130        return false;
     131      }
     132
     133      interpreter.CodeStack.Pop();
     134
     135      //var first = interpreter.CodeStack.Pop();
     136      //var second = interpreter.CodeStack.Top;
    112137
    113138      PushProgram result;
    114139
    115       if (isFirstList) {
    116         var program1 = first as PushProgram;
    117 
    118         if (isSecondList) {
    119           var program2 = second as PushProgram;
    120           var size = program2.Expressions.Count + program1.Expressions.Count;
    121 
    122           // if size > maxPointsInProgram this expressions results in a NOOP
    123           if (size > interpreter.Configuration.MaxPointsInProgram) return false;
    124 
    125           result = PushProgram.Merge(interpreter.PushProgramPool, program2, program1);
    126         } else {
    127           var size = program1.Expressions.Count + 1;
    128 
    129           // if size > maxPointsInProgram this expressions results in a NOOP
    130           if (size > interpreter.Configuration.MaxPointsInProgram) return false;
    131 
    132           result = PushProgram.Merge(interpreter.PushProgramPool, second, program1);
    133         }
    134       } else if (isSecondList) {
    135         var program2 = second as PushProgram;
    136         var size = program2.Expressions.Count + 1;
    137 
    138         // if size > maxPointsInProgram this expressions results in a NOOP
    139         if (size > interpreter.Configuration.MaxPointsInProgram) return false;
    140 
    141         result = PushProgram.Merge(interpreter.PushProgramPool, first, program2);
     140      if (firstProgram != null) {
     141        result = secondProgram != null
     142          ? PushProgram.Merge(interpreter.PoolContainer.PushProgramPool, interpreter.PoolContainer.ExpressionListPool, secondProgram, firstProgram)
     143          : PushProgram.Merge(interpreter.PoolContainer.PushProgramPool, interpreter.PoolContainer.ExpressionListPool, second, firstProgram);
     144      } else if (secondProgram != null) {
     145        result = PushProgram.Merge(interpreter.PoolContainer.PushProgramPool, interpreter.PoolContainer.ExpressionListPool, first, secondProgram);
    142146      } else {
    143         result = PushProgram.Create(interpreter.PushProgramPool, second, first);
     147        var expressions = interpreter.PoolContainer.ExpressionListPool.Get();
     148        expressions.Add(second);
     149        expressions.Add(first);
     150
     151        result = PushProgram.Create(interpreter.PoolContainer.PushProgramPool, expressions);
    144152      }
    145153
     
    154162  ///     and FALSE otherwise (that is, if it is something surrounded by parentheses).
    155163  /// </summary>
    156   [PushExpression(StackType.Code, "CODE.ATOM")]
     164  [PushExpression(StackTypes.Code, "CODE.ATOM", StackTypes.Boolean)]
    157165  public class CodeAtomExpression : StatelessExpression {
    158166    public override bool Eval(IPushInterpreter interpreter) {
     
    173181  ///     The name derives from the similar Lisp function; a more generic name would be "FIRST".
    174182  /// </summary>
    175   [PushExpression(StackType.Code, "CODE.CAR")]
     183  [PushExpression(StackTypes.Code, "CODE.CAR")]
    176184  public class CodeCarExpression : StatelessExpression {
    177185    public override bool Eval(IPushInterpreter interpreter) {
    178       if ((interpreter.CodeStack.Count == 0) ||
    179           (interpreter.CodeStack.Top.GetType() != typeof(PushProgram))) return false;
     186      if (interpreter.CodeStack.Count == 0 ||
     187          interpreter.CodeStack.Top.IsProgram) return false;
    180188
    181189      var expand = interpreter.CodeStack.Top as PushProgram;
     
    195203  ///     the similar Lisp function; a more generic name would be "REST".
    196204  /// </summary>
    197   [PushExpression(StackType.Code, "CODE.CDR")]
     205  [PushExpression(StackTypes.Code, "CODE.CDR")]
    198206  public class CodeCdrExpression : StatelessExpression {
    199207    public override bool Eval(IPushInterpreter interpreter) {
     
    208216        if (program.IsEmpty) return false;
    209217
    210         result = program.Copy(interpreter.PushProgramPool, 0, program.Expressions.Count - 1);
     218        var expressions = program.CopyExpressions(interpreter.PoolContainer.ExpressionListPool);
     219        expressions.RemoveAt(expressions.Count - 1);
     220
     221        result = PushProgram.Create(interpreter.PoolContainer.PushProgramPool, expressions as IReadOnlyList<Expression>);
    211222      } else {
    212223        result = PushProgram.Empty;
     
    223234  ///     second piece of code is "X" then this pushes "( X A B )" (after popping the argument).
    224235  /// </summary>
    225   [PushExpression(StackType.Code, "CODE.CONS")]
     236  [PushExpression(StackTypes.Code, "CODE.CONS")]
    226237  public class CodeConsExpression : StatelessExpression {
    227238    public override bool Eval(IPushInterpreter interpreter) {
    228       if (interpreter.CodeStack.Count < 2)
     239      if (interpreter.CodeStack.Count < 2 ||
     240         (interpreter.CodeStack.Top.IsProgram &&
     241         ((PushProgram)interpreter.CodeStack.Top).Expressions.Count + 1 > interpreter.Configuration.MaxPointsInProgram))
    229242        return false;
    230243
    231244      PushProgram result;
    232245
    233       if (interpreter.CodeStack.Top.IsProgram) {
    234         var first = (PushProgram)interpreter.CodeStack.Pop();
    235         var size = first.Expressions.Count + 1;
    236 
    237         if (size > interpreter.Configuration.MaxPointsInProgram) return false;
    238 
    239         var expressions = new Expression[size];
    240 
    241         first.CopyExpressionsTo(expressions);
    242         expressions[first.Expressions.Count] = interpreter.CodeStack.Top;
    243 
    244         result = PushProgram.Create(interpreter.PushProgramPool, expressions);
     246      var expressions = interpreter.PoolContainer.ExpressionListPool.Get();
     247      var first = interpreter.CodeStack.Pop();
     248
     249      if (first.IsProgram) {
     250        expressions.AddRange(((PushProgram)first).Expressions);
    245251      } else {
    246         result = PushProgram.Create(interpreter.PushProgramPool, interpreter.CodeStack.Top);
    247       }
    248 
     252        expressions.Add(first);
     253      }
     254
     255      expressions.Add(interpreter.CodeStack.Top);
     256      result = PushProgram.Create(interpreter.PoolContainer.PushProgramPool, expressions);
    249257      interpreter.CodeStack.SetTop(result);
     258
    250259      return true;
    251260    }
     
    260269  ///     container.
    261270  /// </summary>
    262   [PushExpression(StackType.Code, "CODE.CONTAINER")]
     271  [PushExpression(StackTypes.Code, "CODE.CONTAINER")]
    263272  public class CodeContainerExpression : StatelessExpression {
    264273    public override bool Eval(IPushInterpreter interpreter) {
     
    299308  ///     item anywhere (e.g. in a sub-list).
    300309  /// </summary>
    301   [PushExpression(StackType.Code, "CODE.CONTAINS")]
     310  [PushExpression(StackTypes.Code, "CODE.CONTAINS", StackTypes.Boolean)]
    302311  public class CodeContainsExpression : StatelessExpression {
    303312    public override bool Eval(IPushInterpreter interpreter) {
     
    321330  ///     may then be executed with a call to CODE.DO or a similar instruction).
    322331  /// </summary>
    323   [PushExpression(StackType.Code, "CODE.DEFINITION")]
     332  [PushExpression(StackTypes.Code, "CODE.DEFINITION", StackTypes.Name)]
    324333  public class CodeDefinitionExpression : StatelessExpression {
    325334    public override bool Eval(IPushInterpreter interpreter) {
     
    340349  ///     if the top two items are equivalent, and will be higher the 'more different' the items are from one another. The calculation
    341350  ///     is as follows:
    342   ///     <list type="bullet">
     351  ///     <list types="bullet">
    343352  ///         <item>
    344353  ///             <description>
    345354  ///                 Construct a list of all of the unique items in both of the lists(where uniqueness is determined by equalp).
    346355  ///                 Sub-lists and atoms all count as items.
     356  ///             </description>
    347357  ///         </item>
    348358  ///         <item>
    349   ///             <description>Initialize the result to zero.
     359  ///             <description>Initialize the result to zero.</description>
    350360  ///         </item>
    351361  ///         <item>
     
    353363  ///                 For each unique item increment the result by the difference between the number of occurrences of the
    354364  ///                 item in the two pieces of code.
     365  ///             </description>
    355366  ///         </item>
    356367  ///         <item>
    357   ///             <description>Push the result.
     368  ///             <description>Push the result.</description>
    358369  ///         </item>
    359370  ///     </list>
    360371  /// </summary>
    361   [PushExpression(StackType.Code, "CODE.DISCREPANCY")]
     372  [PushExpression(StackTypes.Code, "CODE.DISCREPANCY", StackTypes.Integer)]
    362373  public class CodeDiscrepancyExpression : StatelessExpression {
    363374    public override bool Eval(IPushInterpreter interpreter) {
     
    417428  ///     absolute value is taken in case it is negative) to ensure that it is within the meaningful range.
    418429  /// </summary>
    419   [PushExpression(StackType.Code, "CODE.EXTRACT")]
     430  [PushExpression(StackTypes.Code, "CODE.EXTRACT", StackTypes.Integer)]
    420431  public class CodeExtractExpression : StatelessExpression {
    421432    public override bool Eval(IPushInterpreter interpreter) {
     
    438449  ///     Pops the BOOLEAN stack and pushes the popped item (TRUE or FALSE) onto the CODE stack.
    439450  /// </summary>
    440   [PushExpression(StackType.Code, "CODE.FROMBOOLEAN")]
     451  [PushExpression(StackTypes.Code, "CODE.FROMBOOLEAN", StackTypes.Boolean)]
    441452  public class CodeFromBooleanExpression : StatelessExpression {
    442453    public override bool Eval(IPushInterpreter interpreter) {
     
    455466  ///     Pops the FLOAT stack and pushes the popped item onto the CODE stack.
    456467  /// </summary>
    457   [PushExpression(StackType.Code, "CODE.FROMFLOAT")]
     468  [PushExpression(StackTypes.Code, "CODE.FROMFLOAT", StackTypes.Float)]
    458469  public class CodeFromFloatExpression : StatelessExpression {
    459470    public override bool Eval(IPushInterpreter interpreter) {
     
    472483  ///     Pops the INTEGER stack and pushes the popped integer onto the CODE stack.
    473484  /// </summary>
    474   [PushExpression(StackType.Code, "CODE.FROMINTEGER")]
     485  [PushExpression(StackTypes.Code, "CODE.FROMINTEGER", StackTypes.Integer)]
    475486  public class CodeFromIntegerExpression : StatelessExpression {
    476487    public override bool Eval(IPushInterpreter interpreter) {
     
    489500  ///     Pops the NAME stack and pushes the popped item onto the CODE stack.
    490501  /// </summary>
    491   [PushExpression(StackType.Code, "CODE.FROMNAME")]
     502  [PushExpression(StackTypes.Code, "CODE.FROMNAME", StackTypes.Name)]
    492503  public class CodeFromNameExpression : StatelessExpression {
    493504    public override bool Eval(IPushInterpreter interpreter) {
     
    507518  ///     by the top item of the INTEGER stack (and replacing whatever was there formerly).
    508519  /// </summary>
    509   [PushExpression(StackType.Code, "CODE.CODEINSERT")]
     520  [PushExpression(StackTypes.Code, "CODE.CODEINSERT", StackTypes.Integer)]
    510521  public class CodeInsertExpression : StatelessExpression {
    511522    public override bool Eval(IPushInterpreter interpreter) {
     
    519530      var index = (int)interpreter.IntegerStack.Pop();
    520531
    521       Expression[] newExpressions;
     532      IList<Expression> newExpressions;
    522533      if (!target.IsEmpty) {
    523534        index = target.Expressions.Count - 1 - Math.Abs(index % target.Expressions.Count);
    524 
    525         newExpressions = target.CopyExpressions();
     535        newExpressions = target.CopyExpressions(interpreter.PoolContainer.ExpressionListPool);
     536
    526537        newExpressions[index] = source.IsProgram
    527             ? ((PushProgram)source).Copy(interpreter.PushProgramPool)
     538            ? ((PushProgram)source).Copy(interpreter.PoolContainer.PushProgramPool)
    528539            : source;
    529540      } else {
    530         newExpressions = new[] { source };
    531       }
    532 
    533       var result = PushProgram.Create(interpreter.PushProgramPool, newExpressions);
     541        newExpressions = interpreter.PoolContainer.ExpressionListPool.Get();
     542        newExpressions.Add(source);
     543      }
     544
     545      var result = PushProgram.Create(interpreter.PoolContainer.PushProgramPool, newExpressions as IReadOnlyList<Expression>);
    534546      interpreter.CodeStack.SetTop(result);
    535547
     
    544556  ///     matter what they contain.
    545557  /// </summary>
    546   [PushExpression(StackType.Code, "CODE.LENGTH")]
     558  [PushExpression(StackTypes.Code, "CODE.LENGTH", StackTypes.Integer)]
    547559  public class CodeLengthExpression : StatelessExpression {
    548560    public override bool Eval(IPushInterpreter interpreter) {
     
    564576  ///     Pushes a list of the top two items of the CODE stack onto the CODE stack.
    565577  /// </summary>
    566   [PushExpression(StackType.Code, "CODE.LIST")]
     578  [PushExpression(StackTypes.Code, "CODE.LIST")]
    567579  public class CodeListExpression : StatelessExpression {
    568580    public override bool Eval(IPushInterpreter interpreter) {
    569       if (interpreter.CodeStack.Count < 2) return false;
     581      if (interpreter.CodeStack.Count < 2 ||
     582         (interpreter.CodeStack.Top.IsProgram && ((PushProgram)interpreter.CodeStack.Top).Depth == interpreter.Configuration.MaxDepth) ||
     583         (interpreter.CodeStack.ReverseElementAt(1).IsProgram && ((PushProgram)interpreter.CodeStack.ReverseElementAt(1)).Depth == interpreter.Configuration.MaxDepth))
     584        return false;
    570585
    571586      var first = interpreter.CodeStack.Pop();
    572587      var second = interpreter.CodeStack.Top;
    573       var expandExpression = PushProgram.Create(interpreter.PushProgramPool, second, first);
     588
     589      var expressions = interpreter.PoolContainer.ExpressionListPool.Get();
     590      expressions.Add(second);
     591      expressions.Add(first);
     592
     593      var expandExpression = PushProgram.Create(interpreter.PoolContainer.PushProgramPool, expressions);
    574594
    575595      interpreter.CodeStack.SetTop(expandExpression);
     
    583603  ///     (which is coerced to a list if necessary). Pushes FALSE onto the BOOLEAN stack otherwise.
    584604  /// </summary>
    585   [PushExpression(StackType.Code, "CODE.MEMBER")]
     605  [PushExpression(StackTypes.Code, "CODE.MEMBER", StackTypes.Boolean)]
    586606  public class CodeMemberExpression : StatelessExpression {
    587607    public override bool Eval(IPushInterpreter interpreter) {
     
    605625  ///     modulo the length of the expression into which it is indexing.
    606626  /// </summary>
    607   [PushExpression(StackType.Code, "CODE.NTH")]
     627  [PushExpression(StackTypes.Code, "CODE.NTH", StackTypes.Integer)]
    608628  public class CodeNthExpression : StatelessExpression {
    609629    public override bool Eval(IPushInterpreter interpreter) {
     
    643663  ///     its first element.
    644664  /// </summary>
    645   [PushExpression(StackType.Code, "CODE.NTHCDR")]
     665  [PushExpression(StackTypes.Code, "CODE.NTHCDR", StackTypes.Integer)]
    646666  public class CodeNthCdrExpression : StatelessExpression {
    647667    public override bool Eval(IPushInterpreter interpreter) {
     
    676696  ///     Pushes TRUE onto the BOOLEAN stack if the top item of the CODE stack is an empty list, or FALSE otherwise.
    677697  /// </summary>
    678   [PushExpression(StackType.Code, "CODE.NULL")]
     698  [PushExpression(StackTypes.Code, "CODE.NULL", StackTypes.Boolean)]
    679699  public class CodeNullExpression : StatelessExpression {
    680700    public override bool Eval(IPushInterpreter interpreter) {
    681701      if (interpreter.CodeStack.Count == 0) return false;
    682702
    683       var result = interpreter.CodeStack.Pop().Equals(PushProgram.Empty);
     703      var top = interpreter.CodeStack.Pop();
     704      var result = top.IsProgram && ((PushProgram)top).IsEmpty;
    684705      interpreter.BooleanStack.Push(result);
    685706
     
    692713  ///     (which is coerced to a list if necessary). Pushes -1 if no match is found.
    693714  /// </summary>
    694   [PushExpression(StackType.Code, "CODE.POSITION")]
     715  [PushExpression(StackTypes.Code, "CODE.POSITION", StackTypes.Integer)]
    695716  public class CodePositionExpression : StatelessExpression {
    696717    public override bool Eval(IPushInterpreter interpreter) {
     
    704725      if (first.IsProgram) {
    705726        var program = (PushProgram)first;
    706         position = program.Expressions.Count - 1 - program.IndexOf(second);
     727        position = program.IndexOf(second);
    707728      } else if (first.Equals(second)) {
    708729        position = 0;
     
    719740  ///     and pair of parentheses counts as a point.
    720741  /// </summary>
    721   [PushExpression(StackType.Code, "CODE.SIZE")]
     742  [PushExpression(StackTypes.Code, "CODE.SIZE", StackTypes.Integer)]
    722743  public class CodeSizeExpression : StatelessExpression {
    723744    public override bool Eval(IPushInterpreter interpreter) {
     
    741762  ///     cases with empty-list arguments. If any of these problematic possibilities occurs the stack is left unchanged.
    742763  /// </summary>
    743   [PushExpression(StackType.Code, "CODE.SUBST")]
     764  [PushExpression(StackTypes.Code, "CODE.SUBST")]
    744765  public class CodeSubstitutionExpression : StatelessExpression {
    745766    public override bool Eval(IPushInterpreter interpreter) {
    746       if ((interpreter.CodeStack.Count < 3) || (interpreter.CodeStack.Top.GetType() !=
    747                                                 typeof(PushProgram))) return false;
     767      if ((interpreter.CodeStack.Count < 3) ||
     768          (interpreter.CodeStack.Top.GetType() != typeof(PushProgram)))
     769        return false;
    748770
    749771      var expressions = interpreter.CodeStack.Pop(2);
     
    752774      var first = expressions[1] as PushProgram;
    753775      var firstExpressions = first.Expressions;
    754       var newExpressions = new Expression[firstExpressions.Count];
    755 
    756       for (var i = 0; i < firstExpressions.Count; i++)
    757         newExpressions[i] = firstExpressions[i].Equals(third)
    758             ? second
    759             /* no cloning needed here because first is removed and therefore newExpression is the only container of sub expressions */
    760             : firstExpressions[i];
    761 
    762       var result = PushProgram.Create(interpreter.PushProgramPool, newExpressions);
     776      var newExpressions = interpreter.PoolContainer.ExpressionListPool.Get();
     777
     778      for (var i = 0; i < firstExpressions.Count; i++) {
     779        var expression = firstExpressions[i].Equals(third)
     780                           ? second
     781                           /* no cloning needed here because first is removed and therefore newExpression is the only container of sub expressions */
     782                           : firstExpressions[i];
     783
     784        newExpressions.Add(expression);
     785      }
     786
     787      var result = PushProgram.Create(interpreter.PoolContainer.PushProgramPool, newExpressions);
    763788
    764789      interpreter.CodeStack.SetTop(result);
Note: See TracChangeset for help on using the changeset viewer.