Changeset 14777 for branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/CodeExpressions.cs
- Timestamp:
- 03/23/17 01:11:18 (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/CodeExpressions.cs
r14746 r14777 1 1 /// <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 the2 /// 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 4 4 /// CODE stack prior to execution. However, one may turn off all CODE instructions if code manipulation is not needed. 5 5 /// </summary> … … 20 20 /// manipulates the stack then this final pop may end up popping something else. 21 21 /// </summary> 22 [PushExpression(StackType .Code, "CODE.DO")]22 [PushExpression(StackTypes.Code, "CODE.DO", StackTypes.Exec)] 23 23 public class CodeDoExpression : StatelessExpression { 24 24 public override bool Eval(IPushInterpreter interpreter) { … … 36 36 /// Like CODE.DO but pops the stack before, rather than after, the recursive execution 37 37 /// </summary> 38 [PushExpression(StackType .Code, "CODE.DO*")]38 [PushExpression(StackTypes.Code, "CODE.DO*", StackTypes.Exec)] 39 39 public class CodeDoXExpression : StatelessExpression { 40 40 public override bool Eval(IPushInterpreter interpreter) { … … 52 52 /// Does nothing. 53 53 /// </summary> 54 [PushExpression(StackType .Code, "CODE.NOOP")]54 [PushExpression(StackTypes.Code, "CODE.NOOP")] 55 55 public class CodeNoopExpression : StatelessExpression { 56 56 public override bool Eval(IPushInterpreter interpreter) { … … 63 63 /// This can be implemented by moving the top item on the EXEC stack onto the CODE stack. 64 64 /// </summary> 65 [PushExpression(StackType .Code, "CODE.QUOTE")]65 [PushExpression(StackTypes.Code, "CODE.QUOTE", StackTypes.Exec)] 66 66 public class CodeQuoteExpression : StatelessExpression { 67 67 public override bool Eval(IPushInterpreter interpreter) { … … 81 81 /// (and the BOOLEAN value upon which the decision was made) are popped. 82 82 /// </summary> 83 [PushExpression(StackType .Code, "CODE.IF")]83 [PushExpression(StackTypes.Code, "CODE.IF", StackTypes.Exec | StackTypes.Boolean)] 84 84 public class CodeIfExpression : StatelessExpression { 85 85 public override bool Eval(IPushInterpreter interpreter) { … … 100 100 /// literal (that is, something not surrounded by parentheses) then it is surrounded by parentheses first. 101 101 /// </summary> 102 [PushExpression(StackType .Code, "CODE.APPEND")]102 [PushExpression(StackTypes.Code, "CODE.APPEND")] 103 103 public class CodeAppendExpression : StatelessExpression { 104 104 public override bool Eval(IPushInterpreter interpreter) { 105 105 if (interpreter.CodeStack.Count < 2) return false; 106 106 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; 112 137 113 138 PushProgram result; 114 139 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); 142 146 } 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); 144 152 } 145 153 … … 154 162 /// and FALSE otherwise (that is, if it is something surrounded by parentheses). 155 163 /// </summary> 156 [PushExpression(StackType .Code, "CODE.ATOM")]164 [PushExpression(StackTypes.Code, "CODE.ATOM", StackTypes.Boolean)] 157 165 public class CodeAtomExpression : StatelessExpression { 158 166 public override bool Eval(IPushInterpreter interpreter) { … … 173 181 /// The name derives from the similar Lisp function; a more generic name would be "FIRST". 174 182 /// </summary> 175 [PushExpression(StackType .Code, "CODE.CAR")]183 [PushExpression(StackTypes.Code, "CODE.CAR")] 176 184 public class CodeCarExpression : StatelessExpression { 177 185 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; 180 188 181 189 var expand = interpreter.CodeStack.Top as PushProgram; … … 195 203 /// the similar Lisp function; a more generic name would be "REST". 196 204 /// </summary> 197 [PushExpression(StackType .Code, "CODE.CDR")]205 [PushExpression(StackTypes.Code, "CODE.CDR")] 198 206 public class CodeCdrExpression : StatelessExpression { 199 207 public override bool Eval(IPushInterpreter interpreter) { … … 208 216 if (program.IsEmpty) return false; 209 217 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>); 211 222 } else { 212 223 result = PushProgram.Empty; … … 223 234 /// second piece of code is "X" then this pushes "( X A B )" (after popping the argument). 224 235 /// </summary> 225 [PushExpression(StackType .Code, "CODE.CONS")]236 [PushExpression(StackTypes.Code, "CODE.CONS")] 226 237 public class CodeConsExpression : StatelessExpression { 227 238 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)) 229 242 return false; 230 243 231 244 PushProgram result; 232 245 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); 245 251 } 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); 249 257 interpreter.CodeStack.SetTop(result); 258 250 259 return true; 251 260 } … … 260 269 /// container. 261 270 /// </summary> 262 [PushExpression(StackType .Code, "CODE.CONTAINER")]271 [PushExpression(StackTypes.Code, "CODE.CONTAINER")] 263 272 public class CodeContainerExpression : StatelessExpression { 264 273 public override bool Eval(IPushInterpreter interpreter) { … … 299 308 /// item anywhere (e.g. in a sub-list). 300 309 /// </summary> 301 [PushExpression(StackType .Code, "CODE.CONTAINS")]310 [PushExpression(StackTypes.Code, "CODE.CONTAINS", StackTypes.Boolean)] 302 311 public class CodeContainsExpression : StatelessExpression { 303 312 public override bool Eval(IPushInterpreter interpreter) { … … 321 330 /// may then be executed with a call to CODE.DO or a similar instruction). 322 331 /// </summary> 323 [PushExpression(StackType .Code, "CODE.DEFINITION")]332 [PushExpression(StackTypes.Code, "CODE.DEFINITION", StackTypes.Name)] 324 333 public class CodeDefinitionExpression : StatelessExpression { 325 334 public override bool Eval(IPushInterpreter interpreter) { … … 340 349 /// if the top two items are equivalent, and will be higher the 'more different' the items are from one another. The calculation 341 350 /// is as follows: 342 /// <list type ="bullet">351 /// <list types="bullet"> 343 352 /// <item> 344 353 /// <description> 345 354 /// Construct a list of all of the unique items in both of the lists(where uniqueness is determined by equalp). 346 355 /// Sub-lists and atoms all count as items. 356 /// </description> 347 357 /// </item> 348 358 /// <item> 349 /// <description>Initialize the result to zero. 359 /// <description>Initialize the result to zero.</description> 350 360 /// </item> 351 361 /// <item> … … 353 363 /// For each unique item increment the result by the difference between the number of occurrences of the 354 364 /// item in the two pieces of code. 365 /// </description> 355 366 /// </item> 356 367 /// <item> 357 /// <description>Push the result. 368 /// <description>Push the result.</description> 358 369 /// </item> 359 370 /// </list> 360 371 /// </summary> 361 [PushExpression(StackType .Code, "CODE.DISCREPANCY")]372 [PushExpression(StackTypes.Code, "CODE.DISCREPANCY", StackTypes.Integer)] 362 373 public class CodeDiscrepancyExpression : StatelessExpression { 363 374 public override bool Eval(IPushInterpreter interpreter) { … … 417 428 /// absolute value is taken in case it is negative) to ensure that it is within the meaningful range. 418 429 /// </summary> 419 [PushExpression(StackType .Code, "CODE.EXTRACT")]430 [PushExpression(StackTypes.Code, "CODE.EXTRACT", StackTypes.Integer)] 420 431 public class CodeExtractExpression : StatelessExpression { 421 432 public override bool Eval(IPushInterpreter interpreter) { … … 438 449 /// Pops the BOOLEAN stack and pushes the popped item (TRUE or FALSE) onto the CODE stack. 439 450 /// </summary> 440 [PushExpression(StackType .Code, "CODE.FROMBOOLEAN")]451 [PushExpression(StackTypes.Code, "CODE.FROMBOOLEAN", StackTypes.Boolean)] 441 452 public class CodeFromBooleanExpression : StatelessExpression { 442 453 public override bool Eval(IPushInterpreter interpreter) { … … 455 466 /// Pops the FLOAT stack and pushes the popped item onto the CODE stack. 456 467 /// </summary> 457 [PushExpression(StackType .Code, "CODE.FROMFLOAT")]468 [PushExpression(StackTypes.Code, "CODE.FROMFLOAT", StackTypes.Float)] 458 469 public class CodeFromFloatExpression : StatelessExpression { 459 470 public override bool Eval(IPushInterpreter interpreter) { … … 472 483 /// Pops the INTEGER stack and pushes the popped integer onto the CODE stack. 473 484 /// </summary> 474 [PushExpression(StackType .Code, "CODE.FROMINTEGER")]485 [PushExpression(StackTypes.Code, "CODE.FROMINTEGER", StackTypes.Integer)] 475 486 public class CodeFromIntegerExpression : StatelessExpression { 476 487 public override bool Eval(IPushInterpreter interpreter) { … … 489 500 /// Pops the NAME stack and pushes the popped item onto the CODE stack. 490 501 /// </summary> 491 [PushExpression(StackType .Code, "CODE.FROMNAME")]502 [PushExpression(StackTypes.Code, "CODE.FROMNAME", StackTypes.Name)] 492 503 public class CodeFromNameExpression : StatelessExpression { 493 504 public override bool Eval(IPushInterpreter interpreter) { … … 507 518 /// by the top item of the INTEGER stack (and replacing whatever was there formerly). 508 519 /// </summary> 509 [PushExpression(StackType .Code, "CODE.CODEINSERT")]520 [PushExpression(StackTypes.Code, "CODE.CODEINSERT", StackTypes.Integer)] 510 521 public class CodeInsertExpression : StatelessExpression { 511 522 public override bool Eval(IPushInterpreter interpreter) { … … 519 530 var index = (int)interpreter.IntegerStack.Pop(); 520 531 521 Expression[]newExpressions;532 IList<Expression> newExpressions; 522 533 if (!target.IsEmpty) { 523 534 index = target.Expressions.Count - 1 - Math.Abs(index % target.Expressions.Count); 524 525 newExpressions = target.CopyExpressions(); 535 newExpressions = target.CopyExpressions(interpreter.PoolContainer.ExpressionListPool); 536 526 537 newExpressions[index] = source.IsProgram 527 ? ((PushProgram)source).Copy(interpreter.P ushProgramPool)538 ? ((PushProgram)source).Copy(interpreter.PoolContainer.PushProgramPool) 528 539 : source; 529 540 } 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>); 534 546 interpreter.CodeStack.SetTop(result); 535 547 … … 544 556 /// matter what they contain. 545 557 /// </summary> 546 [PushExpression(StackType .Code, "CODE.LENGTH")]558 [PushExpression(StackTypes.Code, "CODE.LENGTH", StackTypes.Integer)] 547 559 public class CodeLengthExpression : StatelessExpression { 548 560 public override bool Eval(IPushInterpreter interpreter) { … … 564 576 /// Pushes a list of the top two items of the CODE stack onto the CODE stack. 565 577 /// </summary> 566 [PushExpression(StackType .Code, "CODE.LIST")]578 [PushExpression(StackTypes.Code, "CODE.LIST")] 567 579 public class CodeListExpression : StatelessExpression { 568 580 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; 570 585 571 586 var first = interpreter.CodeStack.Pop(); 572 587 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); 574 594 575 595 interpreter.CodeStack.SetTop(expandExpression); … … 583 603 /// (which is coerced to a list if necessary). Pushes FALSE onto the BOOLEAN stack otherwise. 584 604 /// </summary> 585 [PushExpression(StackType .Code, "CODE.MEMBER")]605 [PushExpression(StackTypes.Code, "CODE.MEMBER", StackTypes.Boolean)] 586 606 public class CodeMemberExpression : StatelessExpression { 587 607 public override bool Eval(IPushInterpreter interpreter) { … … 605 625 /// modulo the length of the expression into which it is indexing. 606 626 /// </summary> 607 [PushExpression(StackType .Code, "CODE.NTH")]627 [PushExpression(StackTypes.Code, "CODE.NTH", StackTypes.Integer)] 608 628 public class CodeNthExpression : StatelessExpression { 609 629 public override bool Eval(IPushInterpreter interpreter) { … … 643 663 /// its first element. 644 664 /// </summary> 645 [PushExpression(StackType .Code, "CODE.NTHCDR")]665 [PushExpression(StackTypes.Code, "CODE.NTHCDR", StackTypes.Integer)] 646 666 public class CodeNthCdrExpression : StatelessExpression { 647 667 public override bool Eval(IPushInterpreter interpreter) { … … 676 696 /// Pushes TRUE onto the BOOLEAN stack if the top item of the CODE stack is an empty list, or FALSE otherwise. 677 697 /// </summary> 678 [PushExpression(StackType .Code, "CODE.NULL")]698 [PushExpression(StackTypes.Code, "CODE.NULL", StackTypes.Boolean)] 679 699 public class CodeNullExpression : StatelessExpression { 680 700 public override bool Eval(IPushInterpreter interpreter) { 681 701 if (interpreter.CodeStack.Count == 0) return false; 682 702 683 var result = interpreter.CodeStack.Pop().Equals(PushProgram.Empty); 703 var top = interpreter.CodeStack.Pop(); 704 var result = top.IsProgram && ((PushProgram)top).IsEmpty; 684 705 interpreter.BooleanStack.Push(result); 685 706 … … 692 713 /// (which is coerced to a list if necessary). Pushes -1 if no match is found. 693 714 /// </summary> 694 [PushExpression(StackType .Code, "CODE.POSITION")]715 [PushExpression(StackTypes.Code, "CODE.POSITION", StackTypes.Integer)] 695 716 public class CodePositionExpression : StatelessExpression { 696 717 public override bool Eval(IPushInterpreter interpreter) { … … 704 725 if (first.IsProgram) { 705 726 var program = (PushProgram)first; 706 position = program. Expressions.Count - 1 - program.IndexOf(second);727 position = program.IndexOf(second); 707 728 } else if (first.Equals(second)) { 708 729 position = 0; … … 719 740 /// and pair of parentheses counts as a point. 720 741 /// </summary> 721 [PushExpression(StackType .Code, "CODE.SIZE")]742 [PushExpression(StackTypes.Code, "CODE.SIZE", StackTypes.Integer)] 722 743 public class CodeSizeExpression : StatelessExpression { 723 744 public override bool Eval(IPushInterpreter interpreter) { … … 741 762 /// cases with empty-list arguments. If any of these problematic possibilities occurs the stack is left unchanged. 742 763 /// </summary> 743 [PushExpression(StackType .Code, "CODE.SUBST")]764 [PushExpression(StackTypes.Code, "CODE.SUBST")] 744 765 public class CodeSubstitutionExpression : StatelessExpression { 745 766 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; 748 770 749 771 var expressions = interpreter.CodeStack.Pop(2); … … 752 774 var first = expressions[1] as PushProgram; 753 775 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); 763 788 764 789 interpreter.CodeStack.SetTop(result);
Note: See TracChangeset
for help on using the changeset viewer.