The source code and dockerfile for the GSW2024 AI Lab.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

165 lines
5.8 KiB

2 months ago
  1. /* Conway's Game of Life garden of eden checker */
  2. /* Written and converted to GNU MathProg by NASZVADI, Peter, 199x-2017
  3. <vuk@cs.elte.hu> */
  4. /*
  5. Conway's Game of Life (ref'd: CGoL) is a Cellular Automata described and
  6. inspected by John H. Conway in the 1970s. CGoL is nothing but a 0-player
  7. game on an infinite two-dimensional Euclydean grid. In the beginning of
  8. the "game", some 1 values are put on some of the grid vertices, and all
  9. others are set to 0. Grid vertices with values are called cells, and a
  10. cell is called "alive", if its value is 1, and called "dead" otherwise,
  11. these are the two "states". The game then turns to an infinite repetitive
  12. process: all cells change together independently at the same time their
  13. states depending only on their actual state and the actual number of
  14. living cells in their so called Moore-neighbourhood: the 4 orthogonal and
  15. 4 diagonal neighbouring cells. Conway also defined the transitions rule:
  16. dead cell become alive if it has exactly 3 living adjacents, and an alive
  17. cell survives only if it has 2 or 3 living neighbours. After executing a
  18. transition for all cells, the two patterns are in a relationship: the
  19. older is the father, the newer is the child.
  20. It is an interesting problem both in Mathematics and Phylosophy if
  21. there is a fatherless pattern (in CGoL). Fairly trivial existence
  22. proofs had been published since then, and immediately explicit
  23. constructions are followed.
  24. This GMPL model searches for a father pattern of the pattern specified in
  25. the c parameter matrix, and prints the found one if any both in human
  26. readable format and in RLE format, which could be open with some Cellular
  27. Automata simulators like Golly, for example.
  28. See more about Garden of Edens:
  29. http://conwaylife.com/wiki/Garden_of_Eden
  30. Golly CA simulator:
  31. http://golly.sourceforge.net/
  32. Tip for running with the example pattern:
  33. glpsol --math life_goe.mod --cuts --last
  34. WARNING: Rather CPU- and memory-intensive process to find out if a given
  35. pattern is a GOE if it really is!
  36. */
  37. param height, integer, > 0;
  38. /* height of the successor pattern */
  39. param width, integer, > 0;
  40. /* width of the successor pattern */
  41. set ROWS := 0..height + 1;
  42. /* set of rows of the predecessor */
  43. set COLUMNS := 0..width + 1;
  44. /* set of columns of the predecessor */
  45. set MOORE := {(0, 1), (0, -1), (1, 0), (-1, 0), (1, 1), (-1, 1), (1, -1),
  46. (-1, -1)};
  47. /* Moore-neighbourhood relative coordinates */
  48. param c{ROWS, COLUMNS}, >= 0;
  49. /* Denotes the cellspace of 1st generation, where 0, 1 and 2 means dead,
  50. alive or arbitrary cell values respectively. Usually the frame values
  51. must be set to "2", and also "2" is allowed in the inner rectangle. */
  52. set IJalive := setof{(i, j) in ROWS cross COLUMNS: c[i, j] = 1}(i, j);
  53. /* set of alive cells in the child */
  54. set IJdead := setof{(i, j) in ROWS cross COLUMNS: c[i, j] = 0}(i, j);
  55. /* set of dead cells in the child */
  56. set IJ := IJalive union IJdead;
  57. /* set of cells in the child with enforced states */
  58. var x{ROWS, COLUMNS}, binary;
  59. /* father's states */
  60. var dpos{ROWS, COLUMNS}, >= 0;
  61. /* positive part of the distances from 6 */
  62. var dneg{ROWS, COLUMNS}, >= 0;
  63. /* negative part of the distances from 6 */
  64. var dposup{ROWS, COLUMNS}, binary;
  65. /* positive part's upper bound enforcement */
  66. var dnegup{ROWS, COLUMNS}, binary;
  67. /* negative part's upper bound enforcement */
  68. s.t. maincons{(i, j) in IJ}:
  69. x[i, j] + sum{(a, b) in MOORE} (2 * x[i + a, j + b]) =
  70. 6 + dpos[i,j] - dneg[i,j];
  71. /* in the LHS, there is a function that maps from all possible 512 state
  72. combinations of a father cell and its Moore-neighbourhood to [0..17].
  73. And for CGoL, if the child is alive, then it should be between 5 and 7.
  74. Also implicit introduced "d" as distance from 6 in RHS, and immediately
  75. decomposed "d" into positive and negative parts denoted dpos and dneg. */
  76. s.t. posbound{(i,j) in IJ}: dpos[i,j] <= 11 * dposup[i,j];
  77. /* constraining positive part of distance */
  78. s.t. negbound{(i,j) in IJ}: dneg[i,j] <= 6 * dnegup[i,j];
  79. /* constraining negative part of distance */
  80. s.t. mutex{(i,j) in IJ}: dposup[i,j] + dnegup[i,j] = 1;
  81. /* Ensuring that at most one is positive among the pos./neg. parts */
  82. s.t. alive{(i,j) in IJalive}: dpos[i,j] + dneg[i,j] <= 1;
  83. /* LHS of maincons must be 5, 6 or 7 either due to child cell is alive */
  84. s.t. dead{(i,j) in IJdead}: dpos[i,j] + dneg[i,j] >= 2;
  85. /* LHS of maincons must be at most 4 or at least 8 */
  86. /* This is a feasibility problem, so no objective is needed */
  87. solve;
  88. printf '\nFound a father pattern:\n\n';
  89. for{i in ROWS}{
  90. for{j in COLUMNS}{
  91. printf '%s%s', if j then ' ' else '', x[i, j].val;
  92. }
  93. printf '\n';
  94. }
  95. printf '\nThe father pattern in rle format:\n\n';
  96. for{i in ROWS}{
  97. for{j in COLUMNS}{
  98. printf '%s', if x[i, j].val then 'o' else 'b';
  99. }
  100. printf '$';
  101. }
  102. printf '!\n\n';
  103. data;
  104. /*
  105. This example is a halved of a 10x10 garden of eden pattern from:
  106. http://wwwhomes.uni-bielefeld.de/achim/orphan_7th.html
  107. It has a 90 degree rotational symmetry, so if having enough resources,
  108. just comment the line denoted with "8", and uncomment the following part!
  109. And also do not forget to increase height parameter, respectively!
  110. */
  111. param height := 7;
  112. param width := 10;
  113. param c : 0 1 2 3 4 5 6 7 8 9 10 11 :=
  114. 0 2 2 2 2 2 2 2 2 2 2 2 2
  115. 1 2 0 1 0 1 1 1 0 1 0 0 2
  116. 2 2 0 0 1 0 1 0 1 0 0 1 2
  117. 3 2 1 0 1 1 1 0 0 1 1 0 2
  118. 4 2 0 1 0 1 1 1 1 1 0 1 2
  119. 5 2 1 0 0 1 0 0 1 1 1 1 2
  120. 6 2 1 1 1 1 0 0 1 0 0 1 2
  121. 7 2 1 0 1 1 1 1 1 0 1 0 2
  122. 8 2 2 2 2 2 2 2 2 2 2 2 2;
  123. /* 8 2 0 1 1 0 0 1 1 1 0 1 2
  124. 9 2 1 0 0 1 0 1 0 1 0 0 2
  125. 10 2 0 0 1 0 1 1 1 0 1 0 2
  126. 11 2 2 2 2 2 2 2 2 2 2 2 2; */
  127. end;