Hacker News new | past | comments | ask | show | jobs | submit login

tl;dr - the disassembly for the UCI position/fen parser in the Watkins PDF is clearly NOT a verbatim copy from Fruit. The Watkins disassembly from Rybka does not and cannot match the Fruit source code. I know you don't have much time, but please tell me where I made a mistake in this conclusion!

(BTW, I'm taking it as granted that we are talking about copyright issues. I accept that it violates the uniqueness requirement.)

I looked again at the parsing code analysis described in http://www.chessvibes.com/plaatjes/rybkaevidence/RYBKA_FRUIT... . Did you realize that the two codes are different? Fruit does a strstr for "fen " and "moves " while Rybka does a search for "fen" and "moves". Note the difference in the trailing space. Is that a typo in the analysis? Yet there is such furor over the use of a "0." when it should be a "0". I'll assume that the analysis report (and associated disassembly) contain typos.

Note then the different call order between those two code snippets. Fruit calls "board_from_fen" only if fen != NULL, while in the disassembled Rybka code, it always calls the labeled "board_from_fen(), for startpos", and if v1 and v3 are not NULL, it calls the same function again.

Here's the quoted assembly code, as provided by Watkins:

    0x406958: callq  0x40cc40             # strstr call for "fen"
    0x40695d: lea    0x25d798(%rip),%rdx  # 0x6640fc "moves"
    0x406964: mov    %rbx,%rcx
    0x406967: mov    %rax,%rdi            # rdi has fen strstr ptr
    0x40696a: callq  0x40cc40             # strstr call for "moves"
    0x40696f: lea    0x25d74a(%rip),%rcx  # 0x6640c0 "rnbqkbnr..."
    0x406976: mov    %rax,%rbx            # rbx has moves strstr ptr
    0x406979: callq  0x402980             # board_from_fen("rnbqkbnr...")
    0x40697e: test   %rdi,%rdi            # if fen != NULL
    0x406981: je     0x406998* [0x406995] 
    0x406983: test   %rbx,%rbx              # if moves != NULL
    0x406986: je     0x40698c
    0x406988: movb   $0x0,-0x1(%rbx)          # moves[-1] = 0
The "0x406979: callq 0x402980" is always called, and it doesn't correspond to any code from Fruit.

This is important because in the Fruit code, board_from_fen is passed "fen+4", so fen cannot be NULL, which means "callq 0x402980" cannot be the same as "board_from_fen". This means the execution order difference in the above assembly code cannot be the result of a compiler optimization.

Which means this assembly code cannot be generated from a verbatim copy of the Fruit source code!

Not only that, but while my assembly isn't so good, it looks like only _one_ argument passed to the Rybka equivalent of board_from_fen, which takes _two_ parameters in Fruit. I'm guessing that the input board data structure in Rybka is a global.

Seriously? You count this as evidence for a copyright violation?

The author of the PDF calls that NUL insertion "odd". I couldn't understand why. It's something I've done in my own code. It's a very handy sanity check because it ensures there can be no buffer overrun. The PDF author goes on "In any case, the fact that “something is done” here that (in the end) serves no purpose makes this a mentionable commonality."

However, there's no indication of why there's no purpose to it.

So I downloaded the 2.1 code. I can tell the there's no purpose for it in Fruit now. There's no evidence, however, that it wasn't useful while bootstrapping the parser. There's no evidence for why it's not needed in Rybka.

Looking at the code, I realize that the PDF author omitted important code in the analysis. Here is the actual code from Fruit 2.1:

   if (fen != NULL) { // "fen" present

      if (moves != NULL) { // "moves" present
         ASSERT(moves>fen);
         moves[-1] = '\0'; // dirty, but so is UCI
      }

      board_from_fen(SearchInput->board,fen+4); // CHANGE ME

   } else {

      // HACK: assumes startpos

      board_from_fen(SearchInput->board,StartFen);
   }
 
Notice the "HACK" section? It was left out of the analysis. This defines the "startpos" case if the fen string isn't present.

The equivalent code in the Rybka code could be easily written as:

    parse_fen(startpos_board);  // Make sure we always have a valid board
    if (fen && moves) {
        moves[-1] = 0; // Ensure no overrun 
        parse_fen(fen);
    }
Notice how it always parses the startpos, and then only if the fen is available does it parse the fen? This is different code. The order of operations is different, the function call parameters are different.

Here too I used a different coding style, so the code doesn't even look the same, even though the final assembly code will look very similar.

In other words, the command parsing does NOT "exactly [match] that of certain parts of Fruit", even though you say it does, because in Rybka:

  - the strstr search strings don't end with a space
  - the "startpos" board is always parsed, instead only when there is no fen string
  - the parse function appears to take one parameter instead of two, and use a global data structure

Please explain this discrepancy. How could that assembly come from the Fruit source code?



Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: