gintool / gin

GI in No Time - a Simple Microframework for Genetic Improvement
MIT License
43 stars 20 forks source link

Multiple CopyStatement to the same block are all applied at the same location #74

Closed bloa closed 3 years ago

bloa commented 3 years ago

Current behaviour:

When multiple statements are inserted into the same block they are all applied at the location of the earliest insertion.

Expected behaviour:

Insertions should happen at the positions at which they are applied individually.

Steps to reproduce:

1) Run the following command, inserting the statement delay(); in the source code: ("35 -> 34:61")

java -cp build/gin.jar gin.PatchAnalyser -f examples/triangle/Triangle.java -p "| gin.edit.statement.CopyStatement examples/triangle/Triangle.java:35 -> examples/triangle/Triangle.java:34:61 |"

Then diff examples/triangle/Triangle.java.original examples/triangle/Triangle.java.patched -c yields:

*** examples/triangle/Triangle.java.original    2020-12-10 20:44:36.721198276 +0000
--- examples/triangle/Triangle.java.patched 2020-12-10 21:07:01.147888414 +0000
***************
*** 16,21 ****
--- 16,22 ----
              a = b;
              b = tmp;
          }
+         delay();
          if (a > c) {
              int tmp = a;
              a = c;

2) Similarly, run the following command, inserting the statement delay(); 10 lines later in the source code: ("35 -> 34:96")

java -cp build/gin.jar gin.PatchAnalyser -f examples/triangle/Triangle.java -p "| gin.edit.statement.CopyStatement examples/triangle/Triangle.java:35 -> examples/triangle/Triangle.java:34:96 |"

diff examples/triangle/Triangle.java.original examples/triangle/Triangle.java.patched -c yields:

*** examples/triangle/Triangle.java.original    2020-12-10 20:44:36.721198276 +0000                
--- examples/triangle/Triangle.java.patched 2020-12-10 21:15:36.664564081 +0000
***************
*** 26,31 ****
--- 26,32 ----
              b = c;
              c = tmp;
          }
+         delay();
          if (a + b <= c) {
              return INVALID;
          } else if (a == b && b == c) {

3) Applied at the same time, both insertions happen at the same position. ("35 -> 34:61 | 35 -> 34:96" is incorrectly applied as "35 -> 34:61 | 35 -> 34:61")

java -cp build/gin.jar gin.PatchAnalyser -f examples/triangle/Triangle.java -p "| gin.edit.statement.CopyStatement examples/triangle/Triangle.java:35 -> examples/triangle/Triangle.java:34:61 | gin.edit.statement.CopyStatement examples/triangle/Triangle.java:35 -> examples/triangle/Triangle.java:34:96 |"

The diff yields:

*** examples/triangle/Triangle.java.original    2020-12-10 20:44:36.721198276 +0000                
--- examples/triangle/Triangle.java.patched 2020-12-10 21:18:07.734566718 +0000
***************
*** 16,21 ****
--- 16,23 ----
              a = b;
              b = tmp;
          }
+         delay();
+         delay();
          if (a > c) {
              int tmp = a;
              a = c;

4) Expected behaviour: the diff should yield instead:

*** examples/triangle/Triangle.java.original    2020-12-10 21:21:21.964570109 +0000               
--- examples/triangle/Triangle.java.patched 2020-12-10 21:21:04.691236475 +0000
***************
*** 16,21 ****
--- 16,22 ----
              a = b;
              b = tmp;
          }
+         delay();
          if (a > c) {
              int tmp = a;
              a = c;
***************
*** 26,31 ****
--- 27,33 ----
              b = c;
              c = tmp;
          }
+         delay();
          if (a + b <= c) {
              return INVALID;
          } else if (a == b && b == c) {
sandybrownlee commented 3 years ago

Nice catch! The inserted statement doesn't have an ID, which is causing the loop to drop out early when we try to insert the second one. Your proposed fix looks correct to me. Accepting PR.