{
  "id": 181305,
  "title": "SAT Solvers",
  "url": "/competitions/conways-reverse-game-of-life-2020/discussion/181305",
  "author_name": "Ollie Perrée",
  "post_date": "2020-09-08T11:36:48.374000",
  "votes": 1,
  "comment_count": 10,
  "views": 0,
  "content": "<p>It's possible to determine a valid previous state by encoding the problem as a boolean formula (with 25^2 variables representing the initial state) and using a <a href=\"https://en.wikipedia.org/wiki/Boolean_satisfiability_problem\" target=\"_blank\">SAT solver</a> to find a satisfying assignment. I tried using <a href=\"https://github.com/Z3Prover/z3\" target=\"_blank\">Z3</a>'s python interface, but it was quite a bit too slow on my computer, taking over 30 seconds to determine the initial state (delta=1).</p>\n<p>Has anyone managed to get a SAT solver to perform well on this task?</p>",
  "messages": [
    {
      "id": 1002732,
      "postDate": "2020-09-08T11:36:48.373Z",
      "content": "<p>It's possible to determine a valid previous state by encoding the problem as a boolean formula (with 25^2 variables representing the initial state) and using a <a href=\"https://en.wikipedia.org/wiki/Boolean_satisfiability_problem\" target=\"_blank\">SAT solver</a> to find a satisfying assignment. I tried using <a href=\"https://github.com/Z3Prover/z3\" target=\"_blank\">Z3</a>'s python interface, but it was quite a bit too slow on my computer, taking over 30 seconds to determine the initial state (delta=1).</p>\n<p>Has anyone managed to get a SAT solver to perform well on this task?</p>",
      "rawMarkdown": "It's possible to determine a valid previous state by encoding the problem as a boolean formula (with 25^2 variables representing the initial state) and using a [SAT solver](https://en.wikipedia.org/wiki/Boolean_satisfiability_problem) to find a satisfying assignment. I tried using [Z3](https://github.com/Z3Prover/z3)'s python interface, but it was quite a bit too slow on my computer, taking over 30 seconds to determine the initial state (delta=1).\n\nHas anyone managed to get a SAT solver to perform well on this task?",
      "votes": 1
    },
    {
      "id": 1032251,
      "postDate": "2020-09-30T04:40:15.300Z",
      "content": "<p>I'm using PicoSAT, as that's what helped to resolve <a href=\"https://www.conwaylife.com/wiki/Grandfather_problem\" target=\"_blank\">Grandfather problem</a> (and Grand-grand-father too).<br>\nCurrently, main problem I see with SAT solvers is to prefer solutions that \"don't break what's not broken\". I'm thinking of limiting difference between current and previous step.</p>",
      "rawMarkdown": "I'm using PicoSAT, as that's what helped to resolve [Grandfather problem](https://www.conwaylife.com/wiki/Grandfather_problem) (and Grand-grand-father too).\nCurrently, main problem I see with SAT solvers is to prefer solutions that \"don't break what's not broken\". I'm thinking of limiting difference between current and previous step."
    },
    {
      "id": 1013854,
      "postDate": "2020-09-17T03:01:29.583Z",
      "content": "<p>A SAT solver, such as Z3 really is the way to go in this competition.</p>\n<p>Make sure to encode it using boolean rather than integer logic, as this provides 2-4 performance speedup.</p>\n<p>The search state space can be reduced somewhat by adding in additional constraints to remove zero-point energy solutions, ie cells with zero neighbours are assumed to be dead last turn as well (10% of the dataset requires distance=2 to be solvable). The search space may be large, but there are also a very large number of possible solutions for even the simplest of grids.</p>\n<p>Another unimplemented idea is to create a database of known repeating patterns and feed them into the SAT solver as constraints.</p>\n<p>Performance is an issue, especially with larger delta and larger cell counts. I'm guessing my solution will take something in the order of 1,000 - 10,000 hours of CPU time, but as the Russian's used to say \"quantity has a quality all of its own\", so I'm attempting to throw caching and cluster compute at the problem. </p>\n<ul>\n<li><a href=\"https://www.kaggle.com/jamesmcguigan/game-of-life-z3-constraint-satisfaction/\" target=\"_blank\">https://www.kaggle.com/jamesmcguigan/game-of-life-z3-constraint-satisfaction/</a></li>\n</ul>\n<p>The task complexity can also be reduced by realizing that 10% of the test dataset are geometric duplicates of each other, so you just need to solve for the transform between input grids. Also another 13% can be solved directly from finding geometric duplicates from the training dataset.</p>\n<ul>\n<li><a href=\"https://www.kaggle.com/jamesmcguigan/game-of-life-hashmap-solver/\" target=\"_blank\">https://www.kaggle.com/jamesmcguigan/game-of-life-hashmap-solver/</a></li>\n</ul>",
      "rawMarkdown": "A SAT solver, such as Z3 really is the way to go in this competition.\n\nMake sure to encode it using boolean rather than integer logic, as this provides 2-4 performance speedup.\n\nThe search state space can be reduced somewhat by adding in additional constraints to remove zero-point energy solutions, ie cells with zero neighbours are assumed to be dead last turn as well (10% of the dataset requires distance=2 to be solvable). The search space may be large, but there are also a very large number of possible solutions for even the simplest of grids.\n\nAnother unimplemented idea is to create a database of known repeating patterns and feed them into the SAT solver as constraints.\n\nPerformance is an issue, especially with larger delta and larger cell counts. I'm guessing my solution will take something in the order of 1,000 - 10,000 hours of CPU time, but as the Russian's used to say \"quantity has a quality all of its own\", so I'm attempting to throw caching and cluster compute at the problem. \n\n- https://www.kaggle.com/jamesmcguigan/game-of-life-z3-constraint-satisfaction/\n\n\nThe task complexity can also be reduced by realizing that 10% of the test dataset are geometric duplicates of each other, so you just need to solve for the transform between input grids. Also another 13% can be solved directly from finding geometric duplicates from the training dataset.\n- https://www.kaggle.com/jamesmcguigan/game-of-life-hashmap-solver/\n",
      "replies": [
        {
          "id": 1097011,
          "postDate": "2020-11-30T23:42:36.753Z",
          "content": "<p>After 5000h of CPU time, I was able to score: 0.08410</p>",
          "rawMarkdown": "After 5000h of CPU time, I was able to score: 0.08410"
        }
      ]
    },
    {
      "id": 1006804,
      "postDate": "2020-09-11T15:04:59.883Z",
      "content": "<p>Stepping back 1 round is quite easy for a SAT solver (I used pysat)</p>\n<p>Stepping back multiple rounds is not simply stepping back multiple times a single round (because there can be  multiple board states that can lead to to the current state). This also implies that not all board states have a previous state.</p>\n<p>Proof: There are many board states that lead to an empty board. So there are simply not enough previous board states to create all possible board.</p>\n<p>So stepping back multiple rounds must be done with single SAT solve.</p>\n<p>Stepping back 2 rounds is also fairly quick with a SAT solver (a least for the case I tried).</p>\n<p>Stepping back 3 rounds is possible,  but slow.</p>\n<p>Stepping back 4 rounds took too long to watch (it could also be be that it is impossible with the sample I tried).</p>\n<p>I currently only tested a handmade test case (and still need to connect it with the dataset)</p>",
      "rawMarkdown": "Stepping back 1 round is quite easy for a SAT solver (I used pysat)\n\nStepping back multiple rounds is not simply stepping back multiple times a single round (because there can be  multiple board states that can lead to to the current state). This also implies that not all board states have a previous state.\n\nProof: There are many board states that lead to an empty board. So there are simply not enough previous board states to create all possible board.\n\nSo stepping back multiple rounds must be done with single SAT solve.\n\nStepping back 2 rounds is also fairly quick with a SAT solver (a least for the case I tried).\n\nStepping back 3 rounds is possible,  but slow.\n\nStepping back 4 rounds took too long to watch (it could also be be that it is impossible with the sample I tried).\n\nI currently only tested a handmade test case (and still need to connect it with the dataset)\n\n",
      "replies": [
        {
          "id": 1021396,
          "postDate": "2020-09-21T19:51:22.840Z",
          "content": "<blockquote>\n  <p>Stepping back multiple rounds is not simply stepping back multiple times a single round (because there can be multiple board states that can lead to to the current state)</p>\n</blockquote>\n<p>I do not think this is true. We are asked to find any initial position. So (for delta=2) if P1 is a valid previous position of P0 and P2 is a valid previous position of P1, then P2 is an initial position for P0.</p>",
          "rawMarkdown": "> \nStepping back multiple rounds is not simply stepping back multiple times a single round (because there can be multiple board states that can lead to to the current state)\n> \n\nI do not think this is true. We are asked to find any initial position. So (for delta=2) if P1 is a valid previous position of P0 and P2 is a valid previous position of P1, then P2 is an initial position for P0."
        },
        {
          "id": 1048295,
          "postDate": "2020-10-13T11:13:14.623Z",
          "content": "<p>As Rudiger said, not every board state has a previous state. So imagine that P1 is determined to be a previous state for P0 but P1 does not have a previous state. We can imagine that there may be many previous states for P0, and we must determine which of these have valid previous states. This adds an extra layer of complexity to the problem of simply determining one previous state for each backward iteration.</p>",
          "rawMarkdown": "As Rudiger said, not every board state has a previous state. So imagine that P1 is determined to be a previous state for P0 but P1 does not have a previous state. We can imagine that there may be many previous states for P0, and we must determine which of these have valid previous states. This adds an extra layer of complexity to the problem of simply determining one previous state for each backward iteration."
        },
        {
          "id": 1048324,
          "postDate": "2020-10-13T11:41:07.277Z",
          "rawMarkdown": "",
          "isDeleted": true
        }
      ]
    },
    {
      "id": 1002806,
      "postDate": "2020-09-08T12:45:31.473Z",
      "content": "<p>It's an interesting idea, although possibly not practical for this particular contest, with 0.216 seconds of CPU time per position to be reversed (50,000 boards x average delta of 3, all to be done in 9 hours CPU time).</p>\n<p>I thought about using simulated annealing to search for the ancestor of each position, but concluded it probably  wasn't practical in this context for the same reason. Of course, having said that, someone may prove me completely wrong lol</p>",
      "rawMarkdown": "It's an interesting idea, although possibly not practical for this particular contest, with 0.216 seconds of CPU time per position to be reversed (50,000 boards x average delta of 3, all to be done in 9 hours CPU time).\n\nI thought about using simulated annealing to search for the ancestor of each position, but concluded it probably  wasn't practical in this context for the same reason. Of course, having said that, someone may prove me completely wrong lol",
      "replies": [
        {
          "id": 1003201,
          "postDate": "2020-09-08T18:25:42.873Z",
          "content": "<p>I agree it seems like it would be challenging to stay within the time limit. I'm not really taking part in the contest but here are some thoughts I had:</p>\n<ul>\n<li>For delta &gt; 1 you can still solve it by satisfying a single Boolean formula (don't know if it would be faster or slower than just stepping back multiple times)</li>\n<li>Presumably you can use multiple CPU cores</li>\n<li>Maybe it's possible to \"seed\" the solver with assignments which might be more likely to be correct than random ones (perhaps the stop state)</li>\n</ul>",
          "rawMarkdown": "I agree it seems like it would be challenging to stay within the time limit. I'm not really taking part in the contest but here are some thoughts I had:\n- For delta > 1 you can still solve it by satisfying a single Boolean formula (don't know if it would be faster or slower than just stepping back multiple times)\n- Presumably you can use multiple CPU cores\n- Maybe it's possible to \"seed\" the solver with assignments which might be more likely to be correct than random ones (perhaps the stop state)",
          "votes": 1
        }
      ]
    },
    {
      "id": 1021394,
      "postDate": "2020-09-21T19:49:39.620Z",
      "rawMarkdown": "",
      "isDeleted": true
    }
  ],
  "comments": [
    {
      "id": 1032251,
      "author_name": "Serhii Hrynko",
      "author_url": "",
      "post_date": "2020-09-30T04:40:15.300000",
      "content": "<p>I'm using PicoSAT, as that's what helped to resolve <a href=\"https://www.conwaylife.com/wiki/Grandfather_problem\" target=\"_blank\">Grandfather problem</a> (and Grand-grand-father too).<br>\nCurrently, main problem I see with SAT solvers is to prefer solutions that \"don't break what's not broken\". I'm thinking of limiting difference between current and previous step.</p>",
      "votes": 0,
      "replies": []
    },
    {
      "id": 1013854,
      "author_name": "James McGuigan",
      "author_url": "",
      "post_date": "2020-09-17T03:01:29.583000",
      "content": "<p>A SAT solver, such as Z3 really is the way to go in this competition.</p>\n<p>Make sure to encode it using boolean rather than integer logic, as this provides 2-4 performance speedup.</p>\n<p>The search state space can be reduced somewhat by adding in additional constraints to remove zero-point energy solutions, ie cells with zero neighbours are assumed to be dead last turn as well (10% of the dataset requires distance=2 to be solvable). The search space may be large, but there are also a very large number of possible solutions for even the simplest of grids.</p>\n<p>Another unimplemented idea is to create a database of known repeating patterns and feed them into the SAT solver as constraints.</p>\n<p>Performance is an issue, especially with larger delta and larger cell counts. I'm guessing my solution will take something in the order of 1,000 - 10,000 hours of CPU time, but as the Russian's used to say \"quantity has a quality all of its own\", so I'm attempting to throw caching and cluster compute at the problem. </p>\n<ul>\n<li><a href=\"https://www.kaggle.com/jamesmcguigan/game-of-life-z3-constraint-satisfaction/\" target=\"_blank\">https://www.kaggle.com/jamesmcguigan/game-of-life-z3-constraint-satisfaction/</a></li>\n</ul>\n<p>The task complexity can also be reduced by realizing that 10% of the test dataset are geometric duplicates of each other, so you just need to solve for the transform between input grids. Also another 13% can be solved directly from finding geometric duplicates from the training dataset.</p>\n<ul>\n<li><a href=\"https://www.kaggle.com/jamesmcguigan/game-of-life-hashmap-solver/\" target=\"_blank\">https://www.kaggle.com/jamesmcguigan/game-of-life-hashmap-solver/</a></li>\n</ul>",
      "votes": 0,
      "replies": [
        {
          "id": 1097011,
          "author_name": "James McGuigan",
          "author_url": "",
          "post_date": "2020-11-30T23:42:36.753000",
          "content": "<p>After 5000h of CPU time, I was able to score: 0.08410</p>",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 1006804,
      "author_name": "Rüdiger Jungbeck",
      "author_url": "",
      "post_date": "2020-09-11T15:04:59.883000",
      "content": "<p>Stepping back 1 round is quite easy for a SAT solver (I used pysat)</p>\n<p>Stepping back multiple rounds is not simply stepping back multiple times a single round (because there can be  multiple board states that can lead to to the current state). This also implies that not all board states have a previous state.</p>\n<p>Proof: There are many board states that lead to an empty board. So there are simply not enough previous board states to create all possible board.</p>\n<p>So stepping back multiple rounds must be done with single SAT solve.</p>\n<p>Stepping back 2 rounds is also fairly quick with a SAT solver (a least for the case I tried).</p>\n<p>Stepping back 3 rounds is possible,  but slow.</p>\n<p>Stepping back 4 rounds took too long to watch (it could also be be that it is impossible with the sample I tried).</p>\n<p>I currently only tested a handmade test case (and still need to connect it with the dataset)</p>",
      "votes": 0,
      "replies": [
        {
          "id": 1021396,
          "author_name": "MorDoron",
          "author_url": "",
          "post_date": "2020-09-21T19:51:22.840000",
          "content": "<blockquote>\n  <p>Stepping back multiple rounds is not simply stepping back multiple times a single round (because there can be multiple board states that can lead to to the current state)</p>\n</blockquote>\n<p>I do not think this is true. We are asked to find any initial position. So (for delta=2) if P1 is a valid previous position of P0 and P2 is a valid previous position of P1, then P2 is an initial position for P0.</p>",
          "votes": 0,
          "replies": []
        },
        {
          "id": 1048295,
          "author_name": "dohkev",
          "author_url": "",
          "post_date": "2020-10-13T11:13:14.623000",
          "content": "<p>As Rudiger said, not every board state has a previous state. So imagine that P1 is determined to be a previous state for P0 but P1 does not have a previous state. We can imagine that there may be many previous states for P0, and we must determine which of these have valid previous states. This adds an extra layer of complexity to the problem of simply determining one previous state for each backward iteration.</p>",
          "votes": 0,
          "replies": []
        },
        {
          "id": 1048324,
          "author_name": "",
          "author_url": "",
          "post_date": "2020-10-13T11:41:07.277000",
          "content": "",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 1002806,
      "author_name": "John Lucas",
      "author_url": "",
      "post_date": "2020-09-08T12:45:31.473000",
      "content": "<p>It's an interesting idea, although possibly not practical for this particular contest, with 0.216 seconds of CPU time per position to be reversed (50,000 boards x average delta of 3, all to be done in 9 hours CPU time).</p>\n<p>I thought about using simulated annealing to search for the ancestor of each position, but concluded it probably  wasn't practical in this context for the same reason. Of course, having said that, someone may prove me completely wrong lol</p>",
      "votes": 0,
      "replies": [
        {
          "id": 1003201,
          "author_name": "Ollie Perrée",
          "author_url": "",
          "post_date": "2020-09-08T18:25:42.873000",
          "content": "<p>I agree it seems like it would be challenging to stay within the time limit. I'm not really taking part in the contest but here are some thoughts I had:</p>\n<ul>\n<li>For delta &gt; 1 you can still solve it by satisfying a single Boolean formula (don't know if it would be faster or slower than just stepping back multiple times)</li>\n<li>Presumably you can use multiple CPU cores</li>\n<li>Maybe it's possible to \"seed\" the solver with assignments which might be more likely to be correct than random ones (perhaps the stop state)</li>\n</ul>",
          "votes": 1,
          "replies": []
        }
      ]
    },
    {
      "id": 1021394,
      "author_name": "",
      "author_url": "",
      "post_date": "2020-09-21T19:49:39.620000",
      "content": "",
      "votes": 0,
      "replies": []
    }
  ],
  "raw_markdown_by_id": {
    "1002732": "It's possible to determine a valid previous state by encoding the problem as a boolean formula (with 25^2 variables representing the initial state) and using a [SAT solver](https://en.wikipedia.org/wiki/Boolean_satisfiability_problem) to find a satisfying assignment. I tried using [Z3](https://github.com/Z3Prover/z3)'s python interface, but it was quite a bit too slow on my computer, taking over 30 seconds to determine the initial state (delta=1).\n\nHas anyone managed to get a SAT solver to perform well on this task?",
    "1032251": "I'm using PicoSAT, as that's what helped to resolve [Grandfather problem](https://www.conwaylife.com/wiki/Grandfather_problem) (and Grand-grand-father too).\nCurrently, main problem I see with SAT solvers is to prefer solutions that \"don't break what's not broken\". I'm thinking of limiting difference between current and previous step.",
    "1013854": "A SAT solver, such as Z3 really is the way to go in this competition.\n\nMake sure to encode it using boolean rather than integer logic, as this provides 2-4 performance speedup.\n\nThe search state space can be reduced somewhat by adding in additional constraints to remove zero-point energy solutions, ie cells with zero neighbours are assumed to be dead last turn as well (10% of the dataset requires distance=2 to be solvable). The search space may be large, but there are also a very large number of possible solutions for even the simplest of grids.\n\nAnother unimplemented idea is to create a database of known repeating patterns and feed them into the SAT solver as constraints.\n\nPerformance is an issue, especially with larger delta and larger cell counts. I'm guessing my solution will take something in the order of 1,000 - 10,000 hours of CPU time, but as the Russian's used to say \"quantity has a quality all of its own\", so I'm attempting to throw caching and cluster compute at the problem. \n\n- https://www.kaggle.com/jamesmcguigan/game-of-life-z3-constraint-satisfaction/\n\n\nThe task complexity can also be reduced by realizing that 10% of the test dataset are geometric duplicates of each other, so you just need to solve for the transform between input grids. Also another 13% can be solved directly from finding geometric duplicates from the training dataset.\n- https://www.kaggle.com/jamesmcguigan/game-of-life-hashmap-solver/\n",
    "1006804": "Stepping back 1 round is quite easy for a SAT solver (I used pysat)\n\nStepping back multiple rounds is not simply stepping back multiple times a single round (because there can be  multiple board states that can lead to to the current state). This also implies that not all board states have a previous state.\n\nProof: There are many board states that lead to an empty board. So there are simply not enough previous board states to create all possible board.\n\nSo stepping back multiple rounds must be done with single SAT solve.\n\nStepping back 2 rounds is also fairly quick with a SAT solver (a least for the case I tried).\n\nStepping back 3 rounds is possible,  but slow.\n\nStepping back 4 rounds took too long to watch (it could also be be that it is impossible with the sample I tried).\n\nI currently only tested a handmade test case (and still need to connect it with the dataset)\n\n",
    "1002806": "It's an interesting idea, although possibly not practical for this particular contest, with 0.216 seconds of CPU time per position to be reversed (50,000 boards x average delta of 3, all to be done in 9 hours CPU time).\n\nI thought about using simulated annealing to search for the ancestor of each position, but concluded it probably  wasn't practical in this context for the same reason. Of course, having said that, someone may prove me completely wrong lol",
    "1021394": ""
  }
}