Answers.Body: <p>To my knowledge the Syzygy tablebase doesn't have a function that magically returns all FEN positions from a file. I don't think it should because that's not what tablebase is designed for.</p>
  
  <p>However, there's nothing stopping you from constructing all possible FENs. You know from the file name you have four pawns in the endgame. All you need to is:</p>
  
  <ul>
  <li>Use <code>python-chess</code> package</li>
  <li>Generate all possible FENs</li>
  <li>For each FEN, use the Python package for probing</li>
  </ul>
  
  <p>Please take a look at:</p>
  
  <blockquote>
    <p><a href="http://talkchess.com/forum/viewtopic.php?start=0&amp;t=61003&amp;topic_view=flat" rel="noreferrer">http://talkchess.com/forum/viewtopic.php?start=0&amp;t=61003&amp;topic_view=flat</a></p>
  </blockquote>
  
  <p>for FEN generation. <code>Sven Schüle</code> is an experienced engine programmer, so please study his code and adjust it if necessary.</p>
  
  <pre><code>// Usage example: fengen.exe [-m|--mirror] Q r n 2p 
  // See http://www.talkchess.com/forum/viewtopic.php?t=61003 
  #include &lt;cstdio&gt; 
  #include &lt;cstdlib&gt; 
  #include &lt;cstring&gt; 
  #include &lt;cctype&gt; 
  #include &lt;algorithm&gt; 
  #include &lt;vector&gt; 
  
  // definitions for chess board representation 
  
  typedef int Color; 
  enum { White = 0, Black, Empty }; 
  
  typedef int Piece; 
  enum { NoPiece = 0, Pawn, Knight, Bishop, Rook, Queen, King }; 
  
  typedef int Square; 
  enum { 
      A1 = 0,B1,C1,D1,E1,F1,G1,H1, 
      A2,    B2,C2,D2,E2,F2,G2,H2, 
      A3,    B3,C3,D3,E3,F3,G3,H3, 
      A4,    B4,C4,D4,E4,F4,G4,H4, 
      A5,    B5,C5,D5,E5,F5,G5,H5, 
      A6,    B6,C6,D6,E6,F6,G6,H6, 
      A7,    B7,C7,D7,E7,F7,G7,H7, 
      A8,    B8,C8,D8,E8,F8,G8,H8, 
      FF = 0xff 
  }; 
  
  Color opponent(Color c) { return c ^ Black; } 
  Square makeSquare(int file, int rank) { return 8 * rank + file; } 
  
  struct Board { 
      Color   color[64]; 
      Piece   piece[64]; 
      bool isPiece(Square s, Color c, Piece p) const { return color[s] == c &amp;&amp; piece[s] == p; } 
      void set(Square s, Color c, Piece p) { color[s] = c; piece[s] = p; } 
      void clear(Square s) { set(s, Empty, NoPiece); } 
      Board() { for (Square s = A1; s &lt;= H8; s++) clear(s); } 
  
      void printFEN() 
      { 
          int nEmpty = 0; 
          for (int r = 7; r &gt;= 0; r--) { 
              for (int f = 0; f &lt;= 7; f++) { 
                  Square s = makeSquare(f, r); 
                  if (color[s] == Empty) { 
                      ++nEmpty; 
                  } else { 
                      if (nEmpty &gt; 0) { 
                          fputc('1' + nEmpty - 1, stdout); 
                          nEmpty = 0; 
                      } 
                      static char const pieceSym[] = ".pnbrqk"; 
                      if (color[s] == White) { 
                          fputc(toupper(pieceSym[piece[s]]), stdout); 
                      } else { 
                          fputc(tolower(pieceSym[piece[s]]), stdout); 
                      } 
                      nEmpty = 0; 
                  } 
              } 
              if (r &gt; 0) { 
                  if (nEmpty &gt; 0) { 
                      fputc('1' + nEmpty - 1, stdout); 
                      nEmpty = 0; 
                  } 
                  fputc('/', stdout); 
              } 
          } 
          fputs(" w ", stdout); 
          if (isPiece(E1, White, King) &amp;&amp; isPiece(H1, White, Rook)) fputc('K', stdout); 
          if (isPiece(E1, White, King) &amp;&amp; isPiece(A1, White, Rook)) fputc('Q', stdout); 
          if (isPiece(E8, Black, King) &amp;&amp; isPiece(H8, Black, Rook)) fputc('k', stdout); 
          if (isPiece(E8, Black, King) &amp;&amp; isPiece(A8, Black, Rook)) fputc('q', stdout); 
          fputs(" - 0 1\n", stdout); 
      } 
  }; 
  
  // definitions needed to set up the initial position 
  // usually more simple than that but we need to iterate over each group of pieces of same type 
  
  struct PieceInitDescr { 
      int     nPieces; 
      Square  initSqr[8]; 
  }; 
  
  PieceInitDescr pieceInitDescr[2][1+6] = { 
      { 
          { 0, { FF,FF,FF,FF,FF,FF,FF,FF } }, 
          { 8, { A2,B2,C2,D2,E2,F2,G2,H2 } }, 
          { 2, { B1,G1,FF,FF,FF,FF,FF,FF } }, 
          { 2, { C1,F1,FF,FF,FF,FF,FF,FF } }, 
          { 2, { A1,H1,FF,FF,FF,FF,FF,FF } }, 
          { 1, { D1,FF,FF,FF,FF,FF,FF,FF } }, 
          { 1, { E1,FF,FF,FF,FF,FF,FF,FF } }, 
      }, 
      { 
          { 0, { FF,FF,FF,FF,FF,FF,FF,FF } }, 
          { 8, { A7,B7,C7,D7,E7,F7,G7,H7 } }, 
          { 2, { B8,G8,FF,FF,FF,FF,FF,FF } }, 
          { 2, { C8,F8,FF,FF,FF,FF,FF,FF } }, 
          { 2, { A8,H8,FF,FF,FF,FF,FF,FF } }, 
          { 1, { D8,FF,FF,FF,FF,FF,FF,FF } }, 
          { 1, { E8,FF,FF,FF,FF,FF,FF,FF } }, 
      }, 
  }; 
  
  // data related to command line parameters 
  
  int missing[2][1+6] = { 
      { 0, 0, 0, 0, 0, 0, 0 }, 
      { 0, 0, 0, 0, 0, 0, 0 }, 
  }; 
  
  bool mirror = false; 
  
  template &lt;bool Mirror&gt; 
  void enumerate(Board &amp; b, Color c, Piece p) 
  { 
      Color cMiss = (Mirror ? opponent(c) : c); 
      Color cStop = (Mirror ? White : Black); 
  
      PieceInitDescr const &amp; d = pieceInitDescr[c][p]; 
  
      // setup initial pieces of given color and type 
      for (int i = 0; i &lt; d.nPieces; i++) { 
          b.set(d.initSqr[i], c, p); 
      } 
  
      if (p == King &amp;&amp; c == cStop) { 
          b.printFEN(); 
      } else { 
          // generate all permutations of missing pieces for the given color and piece type 
          int nPresent = d.nPieces - missing[cMiss][p]; 
          std::vector&lt;bool&gt; v(d.nPieces); 
          std::fill(v.end() - nPresent, v.end(), true); 
          do { 
              // remove missing pieces 
              for (int i = 0; i &lt; d.nPieces; i++) { 
                  if (!v[i]) { 
                      b.clear(d.initSqr[i]); 
                  } 
              } 
              // recursive call 
              Color cNext = (p == King) ? opponent(c) : c; 
              Piece pNext = (p == King) ? Pawn : p + 1; 
              enumerate&lt;Mirror&gt;(b, cNext, pNext); 
              // restore removed pieces 
              for (int i = 0; i &lt; d.nPieces; i++) { 
                  if (!v[i]) { 
                      b.set(d.initSqr[i], c, p); 
                  } 
              } 
          } while (std::next_permutation(v.begin(), v.end())); 
      } 
  
      // clear initial pieces 
      for (int i = 0; i &lt; d.nPieces; i++) { 
          b.clear(d.initSqr[i]); 
      } 
  } 
  
  int main(int argc, char * argv[]) 
  { 
      // scan parameters (illegal parameters are ignored for simplicity) 
      for (int i = 1; i &lt; argc; i++) { 
          char const * arg = argv[i]; 
          if (strcmp(arg, "-m") == 0 || strcmp(arg, "--mirror") == 0) { 
              mirror = true; 
          } else 
          if (strlen(arg) &lt;= 2) { 
              int number  = (strlen(arg) == 1) ? 1         : arg[0] + 1 - '1'; 
              char p      = (strlen(arg) == 1) ? arg[0]    : arg[1]; 
              Color color = (p == toupper(p)) ? White : Black; 
              Piece piece = NoPiece; 
              switch (tolower(p)) { 
                  case 'p': piece = Pawn;     break; 
                  case 'n': piece = Knight;   break; 
                  case 'b': piece = Bishop;   break; 
                  case 'r': piece = Rook;     break; 
                  case 'q': piece = Queen;    break; 
                  // king must not be missing 
                  default: break; 
              } 
              if (piece != NoPiece &amp;&amp; number &gt;= 1 &amp;&amp; number &lt;= pieceInitDescr[color][piece].nPieces) { 
                  missing[color][piece] = number; 
              } 
          } 
      } 
  
      // enumerate combinations of missing pieces 
      Board b; 
      enumerate&lt;false&gt;(b, White, Pawn); 
      if (mirror) { 
          enumerate&lt;true&gt;(b, Black, Pawn); 
      } 
      return 0; 
  }
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-09-17T07:42:32.357Z
Answers.Text: wow really thanks for an answer. I know that this not what the table was designed for, I just hoped that it is possible to extract this data somehow.
Answers.UserDisplayName: Salvador Dali
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-09-17T07:43:34.630Z
Answers.Text: @SalvadorDali I don't **think** so, at least I haven't seen anything like that.
Answers.UserDisplayName: SmallChess
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2024-02-23T00:34:17.097Z
Answers.Text: Can we describe without procedural code, the domain of FEN or EPD diagrams that are generated.  I assume there is no way, to ensure such EGTB input FEN is a legal continuation from any given initial positoin, including standard.
  
  so is that code going to only rule out all material combinations invovling 2 kings and other pieces AND which placements on 8x8 do not involve occupancy collisions.  or what?  I do not find the answer satisfying.  I think maybe, I thought the question was about all the FEN that EGTB admits as input in its math. and computed theorems of retrograde analysis.
Answers.UserDisplayName: dbdb
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-09-17T06:44:32.337Z
Answers.LastActivityDate: 2017-09-17T06:50:05.547Z
Answers.LastEditDate: 2017-09-17T06:50:05.547Z
Answers.UserDisplayName: SmallChess
Body: <p>This is a programming question related to chess syzygy endgame tables. I believe that it is better suited on chess stack exchange than on SO because it is too specific to chess and asks for a recommendation. Also I noticed that there are enough people with a lot of programming knowledge here.</p>
  
  <hr>
  
  <p>I have a syzygy WDL endgame table (just for example I uploaded the <a href="https://ufile.io/rpzsu" rel="noreferrer">file KPPPPvK.rtbw</a>) and for my own purposes I need to iterate over all FENs in this table and see the results for each position.</p>
  
  <p>Is there a library (preferably with python interface) to do this? Most of the libraries that I have seen so far only allows to probe a table.</p>
  
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2024-02-23T00:38:28.487Z
Comments.Text: Do you mean, all the FEN that the tablebase generation algorithm mathematically allows as input for which it can give some ouput.  The EGTB FEN(or EPD) domain, as a function?
  I would have also the same question, for the contruction "function" that has the EGTB or its generator object as output, taking e.g. checkmates as input.  How to iterated over "all" of them.
Comments.UserDisplayName: dbdb
Tags: <endgame><programming>
Title: How to iterate over all FENs in Syzygy table?
ThreadText: # How to iterate over all FENs in Syzygy table?
  
  (Asked by: username_0 on 2017-09-17)
  
  This is a programming question related to chess syzygy endgame tables. I believe that it is better suited on chess stack exchange than on SO because it is too specific to chess and asks for a recommendation. Also I noticed that there are enough people with a lot of programming knowledge here.
  
  ---
  
  I have a syzygy WDL endgame table (just for example I uploaded the [file KPPPPvK.rtbw](https://ufile.io/rpzsu)) and for my own purposes I need to iterate over all FENs in this table and see the results for each position.
  
  Is there a library (preferably with python interface) to do this? Most of the libraries that I have seen so far only allows to probe a table.
  
  **Tags:** endgame, programming
  
  > **Comments:**
  > **username_1**: Do you mean, all the FEN that the tablebase generation algorithm mathematically allows as input for which it can give some ouput.  The EGTB FEN(or EPD) domain, as a function? I would have also the same question, for the contruction "function" that has the EGTB or its generator object as output, taking e.g. checkmates as input.  How to iterated over "all" of them.  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_2 on 2017-09-17. Score: 6 | Accepted answer
  
  To my knowledge the Syzygy tablebase doesn't have a function that magically returns all FEN positions from a file. I don't think it should because that's not what tablebase is designed for.
  
  However, there's nothing stopping you from constructing all possible FENs. You know from the file name you have four pawns in the endgame. All you need to is:
  
  * Use `python-chess` package
  * Generate all possible FENs
  * For each FEN, use the Python package for probing
  
  Please take a look at:
  
  > <http://talkchess.com/forum/viewtopic.php?start=0&t=61003&topic_view=flat>
  
  for FEN generation. `Sven Schüle` is an experienced engine programmer, so please study his code and adjust it if necessary.
  
  ```
  // Usage example: fengen.exe [-m|--mirror] Q r n 2p 
  // See http://www.talkchess.com/forum/viewtopic.php?t=61003 
  #include <cstdio> 
  #include <cstdlib> 
  #include <cstring> 
  #include <cctype> 
  #include <algorithm> 
  #include <vector> 
  
  // definitions for chess board representation 
  
  typedef int Color; 
  enum { White = 0, Black, Empty }; 
  
  typedef int Piece; 
  enum { NoPiece = 0, Pawn, Knight, Bishop, Rook, Queen, King }; 
  
  typedef int Square; 
  enum { 
      A1 = 0,B1,C1,D1,E1,F1,G1,H1, 
      A2,    B2,C2,D2,E2,F2,G2,H2, 
      A3,    B3,C3,D3,E3,F3,G3,H3, 
      A4,    B4,C4,D4,E4,F4,G4,H4, 
      A5,    B5,C5,D5,E5,F5,G5,H5, 
      A6,    B6,C6,D6,E6,F6,G6,H6, 
      A7,    B7,C7,D7,E7,F7,G7,H7, 
      A8,    B8,C8,D8,E8,F8,G8,H8, 
      FF = 0xff 
  }; 
  
  Color opponent(Color c) { return c ^ Black; } 
  Square makeSquare(int file, int rank) { return 8 * rank + file; } 
  
  struct Board { 
      Color   color[64]; 
      Piece   piece[64]; 
      bool isPiece(Square s, Color c, Piece p) const { return color[s] == c && piece[s] == p; } 
      void set(Square s, Color c, Piece p) { color[s] = c; piece[s] = p; } 
      void clear(Square s) { set(s, Empty, NoPiece); } 
      Board() { for (Square s = A1; s <= H8; s++) clear(s); } 
  
      void printFEN() 
      { 
          int nEmpty = 0; 
          for (int r = 7; r >= 0; r--) { 
              for (int f = 0; f <= 7; f++) { 
                  Square s = makeSquare(f, r); 
                  if (color[s] == Empty) { 
                      ++nEmpty; 
                  } else { 
                      if (nEmpty > 0) { 
                          fputc('1' + nEmpty - 1, stdout); 
                          nEmpty = 0; 
                      } 
                      static char const pieceSym[] = ".pnbrqk"; 
                      if (color[s] == White) { 
                          fputc(toupper(pieceSym[piece[s]]), stdout); 
                      } else { 
                          fputc(tolower(pieceSym[piece[s]]), stdout); 
                      } 
                      nEmpty = 0; 
                  } 
              } 
              if (r > 0) { 
                  if (nEmpty > 0) { 
                      fputc('1' + nEmpty - 1, stdout); 
                      nEmpty = 0; 
                  } 
                  fputc('/', stdout); 
              } 
          } 
          fputs(" w ", stdout); 
          if (isPiece(E1, White, King) && isPiece(H1, White, Rook)) fputc('K', stdout); 
          if (isPiece(E1, White, King) && isPiece(A1, White, Rook)) fputc('Q', stdout); 
          if (isPiece(E8, Black, King) && isPiece(H8, Black, Rook)) fputc('k', stdout); 
          if (isPiece(E8, Black, King) && isPiece(A8, Black, Rook)) fputc('q', stdout); 
          fputs(" - 0 1\n", stdout); 
      } 
  }; 
  
  // definitions needed to set up the initial position 
  // usually more simple than that but we need to iterate over each group of pieces of same type 
  
  struct PieceInitDescr { 
      int     nPieces; 
      Square  initSqr[8]; 
  }; 
  
  PieceInitDescr pieceInitDescr[2][1+6] = { 
      { 
          { 0, { FF,FF,FF,FF,FF,FF,FF,FF } }, 
          { 8, { A2,B2,C2,D2,E2,F2,G2,H2 } }, 
          { 2, { B1,G1,FF,FF,FF,FF,FF,FF } }, 
          { 2, { C1,F1,FF,FF,FF,FF,FF,FF } }, 
          { 2, { A1,H1,FF,FF,FF,FF,FF,FF } }, 
          { 1, { D1,FF,FF,FF,FF,FF,FF,FF } }, 
          { 1, { E1,FF,FF,FF,FF,FF,FF,FF } }, 
      }, 
      { 
          { 0, { FF,FF,FF,FF,FF,FF,FF,FF } }, 
          { 8, { A7,B7,C7,D7,E7,F7,G7,H7 } }, 
          { 2, { B8,G8,FF,FF,FF,FF,FF,FF } }, 
          { 2, { C8,F8,FF,FF,FF,FF,FF,FF } }, 
          { 2, { A8,H8,FF,FF,FF,FF,FF,FF } }, 
          { 1, { D8,FF,FF,FF,FF,FF,FF,FF } }, 
          { 1, { E8,FF,FF,FF,FF,FF,FF,FF } }, 
      }, 
  }; 
  
  // data related to command line parameters 
  
  int missing[2][1+6] = { 
      { 0, 0, 0, 0, 0, 0, 0 }, 
      { 0, 0, 0, 0, 0, 0, 0 }, 
  }; 
  
  bool mirror = false; 
  
  template <bool Mirror> 
  void enumerate(Board & b, Color c, Piece p) 
  { 
      Color cMiss = (Mirror ? opponent(c) : c); 
      Color cStop = (Mirror ? White : Black); 
  
      PieceInitDescr const & d = pieceInitDescr[c][p]; 
  
      // setup initial pieces of given color and type 
      for (int i = 0; i < d.nPieces; i++) { 
          b.set(d.initSqr[i], c, p); 
      } 
  
      if (p == King && c == cStop) { 
          b.printFEN(); 
      } else { 
          // generate all permutations of missing pieces for the given color and piece type 
          int nPresent = d.nPieces - missing[cMiss][p]; 
          std::vector<bool> v(d.nPieces); 
          std::fill(v.end() - nPresent, v.end(), true); 
          do { 
              // remove missing pieces 
              for (int i = 0; i < d.nPieces; i++) { 
                  if (!v[i]) { 
                      b.clear(d.initSqr[i]); 
                  } 
              } 
              // recursive call 
              Color cNext = (p == King) ? opponent(c) : c; 
              Piece pNext = (p == King) ? Pawn : p + 1; 
              enumerate<Mirror>(b, cNext, pNext); 
              // restore removed pieces 
              for (int i = 0; i < d.nPieces; i++) { 
                  if (!v[i]) { 
                      b.set(d.initSqr[i], c, p); 
                  } 
              } 
          } while (std::next_permutation(v.begin(), v.end())); 
      } 
  
      // clear initial pieces 
      for (int i = 0; i < d.nPieces; i++) { 
          b.clear(d.initSqr[i]); 
      } 
  } 
  
  int main(int argc, char * argv[]) 
  { 
      // scan parameters (illegal parameters are ignored for simplicity) 
      for (int i = 1; i < argc; i++) { 
          char const * arg = argv[i]; 
          if (strcmp(arg, "-m") == 0 || strcmp(arg, "--mirror") == 0) { 
              mirror = true; 
          } else 
          if (strlen(arg) <= 2) { 
              int number  = (strlen(arg) == 1) ? 1         : arg[0] + 1 - '1'; 
              char p      = (strlen(arg) == 1) ? arg[0]    : arg[1]; 
              Color color = (p == toupper(p)) ? White : Black; 
              Piece piece = NoPiece; 
              switch (tolower(p)) { 
                  case 'p': piece = Pawn;     break; 
                  case 'n': piece = Knight;   break; 
                  case 'b': piece = Bishop;   break; 
                  case 'r': piece = Rook;     break; 
                  case 'q': piece = Queen;    break; 
                  // king must not be missing 
                  default: break; 
              } 
              if (piece != NoPiece && number >= 1 && number <= pieceInitDescr[color][piece].nPieces) { 
                  missing[color][piece] = number; 
              } 
          } 
      } 
  
      // enumerate combinations of missing pieces 
      Board b; 
      enumerate<false>(b, White, Pawn); 
      if (mirror) { 
          enumerate<true>(b, Black, Pawn); 
      } 
      return 0; 
  }
  
  ```
  
  > **Comments:**
  > **username_0**: wow really thanks for an answer. I know that this not what the table was designed for, I just hoped that it is possible to extract this data somehow.  
  > **username_2**: @username_0 I don't **think** so, at least I haven't seen anything like that.  
  > **username_1**: Can we describe without procedural code, the domain of FEN or EPD diagrams that are generated.  I assume there is no way, to ensure such EGTB input FEN is a legal continuation from any given initial positoin, including standard.  so is that code going to only rule out all material combinations invovling 2 kings and other pieces AND which placements on 8x8 do not involve occupancy collisions.  or what?  I do not find the answer satisfying.  I think maybe, I thought the question was about all the FEN that EGTB admits as input in its math. and computed theorems of retrograde analysis.  
  
  ---
  
  