What do you folks make of this ?

General discussion about computer chess...
User avatar
Chris Whittington
Posts: 437
Joined: Wed Jun 09, 2010 6:25 pm

Re: What do you folks make of this ?

Post by Chris Whittington » Fri Jul 02, 2010 12:10 pm

BB+ wrote:ZW has already addressed some of this, but I enlarge on some points.
One can only add the word suspicious if one have checked more programs (say 10-15) and found no such similarities. Perhaps things like these are common in many chess programs. Have Bob, Zach, you, checked 10-15 programs for its absence?
The exact numerology is much beyond a similarity (as I mentioned, merely having the same Rank/File/Line centralisation strategy for PST is a different bailiwick than having the same numbers from them). I can't find any engines other than Fruit and Rybka whose PST values are derived from (minor exceptions with Rybka in central pawns):

Code: Select all

static const int PawnFile[8] = {-3, -1, +0, +1, +1, +0, -1, -3,};
static const int KnightLine[8] = {-4, -2, +0, +1, +1, +0, -2, -4,};
static const int KnightRank[8] = {-2, -1, +0, +1, +2, +3, +2, +1,};
static const int BishopLine[8] = {-3, -1, +0, +1, +1, +0, -1, -3,};
static const int RookFile[8] = {-2, -1, +0, +1, +1, +0, -1, -2,};
static const int QueenLine[8] = { -3, -1, +0, +1, +1, +0, -1, -3,};
static const int KingLine[8] = {-3, -1, +0, +1, +1, +0, -1, -3,};
static const int KingFile[8] = { +3, +4, +2, +0, +0, +2, +4, +3,};
static const int KingRank[8] = { +1, +0, -2, -3, -4, -5, -6, -7,};
I can imagine someone with the same idea producing 4 or 5 of these arrays that are the same, but not all 9.
Mine has similar values. It's not suspicious at all. [on the 10, 30, 60, 100 scaling]
I think the point again is that the relative scaling is exactly the same, even to the matching of the output of the quad() function of Fruit. For instance, if I thought of 10-30-60-100 scaling, and took 4821 as my PassedOpeningMax and just rounded, I would get 482, 1446, 2893, 4821, not the 489, 1450, 2900, 4821 from the Fruit quad function (the differences appear in how the rounding in Fruit works, as 26 is not exactly 256/10) as appears in Rybka. And again there is not just one example of an array formed by Fruit code, but 5 or 6 in this genre. With both this and PST you can certainly argue that there is no "copyright violation", but my impression is that the standard in (say) WCCC events for "derivatives" is higher. Having two guys independently use 10, 30, 60, 100 scaling is reasonable, while its "hex-approximation" of 26, 77, 154, 256 is less likely. The use of rounding (rather than the floor function) with the quad() output is again something that needn't have been exactly the same if one merely took the idea in the abstract. The abstract idea of 10-30-60-100 scaling for various passed pawn elements appears in Rybka as exactly the output of the quad() function of Fruit, with there being no particular reason (and indeed, probably at best a 10% chance of a "random" implementation of this idea doing the same) for the minutiae to be identical (the most "obvious" in this sense is PassedFree array as { 0, 0, 0, 101, 300, 601, 1000, 1000 } -- from a human standpoint, clearly Rybka derived these numbers "mechanically", rather than a human writing them down as 100,300,600,1000 , and the Fruit quad() function is a mechanism that produces this somewhat peculiar output -- by this point, it should up to a defense to explain what alternative mechanism would yield the same numbers, not just similar ones).
UCI parsing: perhaps its code is public domain. Fabien took it and so did Vas. Has this option been researched by Zach, Bob and you?
You have transferred the burden of proof to the impossibility of proving a negative -- surely it is any putative defense's responsibility to provide such evidence that the code actually is public domain, not vice-versa?
Mine does the same, copy the board before the search starts. It doesn't matter if that is pointless, there are many things in mine that are not in use, they are either remains of previous ideas and forgotten to remove or I leave them there on purpose for future ideas.
The point of this was to note that there were three independent features in both Fruit/Rybka at the start of the search (position copying, 4 ply limit, setjmp), along with the time management. Of course you can argue that any one of the three is an accident. Again I feel that the preponderance of evidence has reached the point where it is the responsibility of the accused to rebut this laundry list by noting some other (independent) engine that replicates each of these three (or four, if you include time management here) elements [preferably in the same order], rather than trying chip away at each point individually [I think the derogatory phrase for this is "lawyering", usually done to impress the jury with useless addenda rather than the gravamen of the debate].
I deliberately take the Vas=innocent position for the sake of the discussion.
I don't quite know what the connotation of "innocent" is here, but my impression is that most who have taken a similar position seem to have been quickly reduced to a variety of bafflegab and misdirection (or ad hominem) in their explanations of the evidence. There is notable evidence of "copying" in Rybka 1.0 Beta beyond mere "ideas" (the nine specific arrays re-used in the generation of engine-specific PST, for instance ), this copying appears to go beyond what is (or has been) acceptable in the field of computer chess/games [and I strongly feel that this is the proper standard to use for "originality", as opposed to a "legalistic" one, where perhaps only "code" is considered], and I personally find the attempts to dismiss this all as happenstance (or "unimportant") to be a bit outré. That being said, there is also a tendency to exaggerate the Rybka/Fruit connection in some other circles. [And by now, I think Rybka 4 has almost zero connection to the Fruit origins].
on the topic of the UI parsing .......

with the caveat that I'm not a lawyer, but I was in biz, and one does make oneself aware of legal stuff. Oxford Softworks used to do a lot of work with one of the big Japanese console manufacturors. The manufacturor (I think they all tried this) wanted to control all software running on their machine, they would provide selected developers with kit and documentation and run their very strict quality control on the product. In turn, publishers had to pay them a substantial royalty and sell it through them. ie the manufacturor wanted to make sure they got the lions share of the software revenues.

To double protect themselves they created interface technology between the third party software and their hardware. The interface was coded, and you had to know the code algorithm etc. to get it to work. The manufacturor subjected the code (and everything else) to NDA and, cleverly, patented it (or some other tight legal method), I forget. So, if you broke the code, or had it leaked to you, they could sue you for not just copyright but patent breach etc. etc. Basically a clever use of patent/copyright law to prevent third parties making software for sale. Monopoly power, lack of competition blah-blah.

Now, possibly as a result of this, or similar cases, a law was passed in the EU that specifically allowed RE in order to render products mutually compatible. You could then investigate the interface software and reuse it, legally, including the fancy codes in order to make your product compatible with some other product.

My guess is that this would probably cover the UI code, although I seem to remember from the past many criticisms of the UI 'evidence' for other reasons. It was partly that that caused Zach to go away and produce a comparison that was about the engines instead.

hyatt
Posts: 1242
Joined: Thu Jun 10, 2010 2:13 am
Real Name: Bob Hyatt (Robert M. Hyatt)
Location: University of Alabama at Birmingham
Contact:

Re: What do you folks make of this ?

Post by hyatt » Fri Jul 02, 2010 12:44 pm

From past experience, the "black box" approach doesn't lead to this kind of duplication. How would two different people write the same "black box" and end up with pieces of identical code? You define the inputs, and the outputs, but the "how" in a black box is, by intention, not specified. I don't see this as a logical explanation of what has been found. It could certainly explain overall program structure similarities (each would have black boxes with similarities with respect to functionality) but it doesn't explain line-for-line and value-for-value similarities in various places.

User avatar
Chris Whittington
Posts: 437
Joined: Wed Jun 09, 2010 6:25 pm

Re: What do you folks make of this ?

Post by Chris Whittington » Fri Jul 02, 2010 1:09 pm

hyatt wrote:From past experience, the "black box" approach doesn't lead to this kind of duplication. How would two different people write the same "black box" and end up with pieces of identical code? You define the inputs, and the outputs, but the "how" in a black box is, by intention, not specified. I don't see this as a logical explanation of what has been found. It could certainly explain overall program structure similarities (each would have black boxes with similarities with respect to functionality) but it doesn't explain line-for-line and value-for-value similarities in various places.
well, at this stage, I can accept the evidence that there are bits and pieces of suspicious data lying around, but I am not accepting the 'identical code'.

Reasons: data structure has changed, therefore the code is different by force, the attacking side tries to get round this by talking of "functional equivalence", for example:

Doubled Pawns

Doubled pawns are the first and simplest pattern. In Fruit, we look behind the given pawn for a friendly pawn. In Rybka, we look ahead. These are of course equivalent. Rybka also has a score of zero for doubled pawns in the opening.
Fruit
if ((board->pawn_file[me][file] & BitLT[rank]) != 0)
doubled = true;
...
if (doubled) {
opening[me] -= DoubledOpening;
endgame[me] -= DoubledEndgame;
}

Rybka
if (MaskPawnDoubled[square] & Board.pieces[WP])
endgame -= DoubledEndgame;


Isolated Pawns

Isolated pawns come next. In Fruit, the variable t1 represents the bitwise OR of the rank-wise bitmasks of friendly pawns on adjacent files. So if t1==0, that means that no pawns are on either of the adjacent files to this pawn. Rybka's MaskPawnIsolated works the same way.
Fruit
if (t1 == 0)
isolated = true;
...
if (isolated) {
if (open) {
opening[me] -= IsolatedOpeningOpen;
endgame[me] -= IsolatedEndgame;
} else {
opening[me] -= IsolatedOpening;
endgame[me] -= IsolatedEndgame;
}
}

Rybka
if ((MaskPawnIsolated[square] & Board.pieces[WP]) == 0) {
if (open_file) {
opening -= IsolatedOpeningOpen;
endgame -= IsolatedEndgame;
} else {
opening -= IsolatedOpening;
endgame -= IsolatedEndgame;
}
}


Please riddle me this:

a) is there a chess program on the planet that doesn't contain snippets/code to identify doubled and isolated pawns and apply some sort of penalty?

b) please provide us with another fast and simple way for a bb program to detect either doubled or isolated pawns, other than by masking off against same side pawns on the appropriate squares (as ZW shows with Rybka above)? I would guess any other way would maddeningly slow, and that this is what you do in Crafty as well. Ie Crafty would match with Fruit in the above cases (functionally equivalent), it certainly would match with ChessSystemTal bitboard version - that's how I did it too.

I think what I'm trying to say is that putting bits of code that are pretty much forcedly in any chess program alongside each other and saying "these are functionally equivalent" and therefore make up part of the quantity on which the attacker's case depends is entirely misleading. There are things that have to be there, they are there in all programs, and there only is realistically one way to perform the function.

If the attackers want to claim line-for-line similarities in the code, they need to do two things: one, line up the code and two, demonstrate the alleged copy could have used another technique that was NOT functionally equivalent.

hyatt
Posts: 1242
Joined: Thu Jun 10, 2010 2:13 am
Real Name: Bob Hyatt (Robert M. Hyatt)
Location: University of Alabama at Birmingham
Contact:

Re: What do you folks make of this ?

Post by hyatt » Fri Jul 02, 2010 2:25 pm

Chris Whittington wrote:
hyatt wrote:From past experience, the "black box" approach doesn't lead to this kind of duplication. How would two different people write the same "black box" and end up with pieces of identical code? You define the inputs, and the outputs, but the "how" in a black box is, by intention, not specified. I don't see this as a logical explanation of what has been found. It could certainly explain overall program structure similarities (each would have black boxes with similarities with respect to functionality) but it doesn't explain line-for-line and value-for-value similarities in various places.
well, at this stage, I can accept the evidence that there are bits and pieces of suspicious data lying around, but I am not accepting the 'identical code'.

Reasons: data structure has changed, therefore the code is different by force, the attacking side tries to get round this by talking of "functional equivalence", for example:

Doubled Pawns

Doubled pawns are the first and simplest pattern. In Fruit, we look behind the given pawn for a friendly pawn. In Rybka, we look ahead. These are of course equivalent. Rybka also has a score of zero for doubled pawns in the opening.
Fruit
if ((board->pawn_file[me][file] & BitLT[rank]) != 0)
doubled = true;
...
if (doubled) {
opening[me] -= DoubledOpening;
endgame[me] -= DoubledEndgame;
}

Rybka
if (MaskPawnDoubled[square] & Board.pieces[WP])
endgame -= DoubledEndgame;


Isolated Pawns

Isolated pawns come next. In Fruit, the variable t1 represents the bitwise OR of the rank-wise bitmasks of friendly pawns on adjacent files. So if t1==0, that means that no pawns are on either of the adjacent files to this pawn. Rybka's MaskPawnIsolated works the same way.
Fruit
if (t1 == 0)
isolated = true;
...
if (isolated) {
if (open) {
opening[me] -= IsolatedOpeningOpen;
endgame[me] -= IsolatedEndgame;
} else {
opening[me] -= IsolatedOpening;
endgame[me] -= IsolatedEndgame;
}
}

Rybka
if ((MaskPawnIsolated[square] & Board.pieces[WP]) == 0) {
if (open_file) {
opening -= IsolatedOpeningOpen;
endgame -= IsolatedEndgame;
} else {
opening -= IsolatedOpening;
endgame -= IsolatedEndgame;
}
}


Please riddle me this:

a) is there a chess program on the planet that doesn't contain snippets/code to identify doubled and isolated pawns and apply some sort of penalty?
Again, step back one or two steps. Rather than looking at a single line of code, look at the "body" first. Yes, most recognize passed pawns. But do you recognize it in your normal pawn evaluation? In a separate procedure so you can use king position that is normally not a part of the pawn hash signature? What about in individual piece scoring functions where you blockade a passed pawn? The more interesting thing is the where/how/when about what is going on, when trying to compare different data structures. I could take Crafty's eval (and we had talked of doing the opposite more than once and plugging someone else's eval into our program just to see whether it was an improvement or a degradation) and convert it to Fruit's board representation, and it would look different if you compare groups of lines of code, because of the bitboard vs array representation. But would the actual code be functionally equivalent and provide exactly the same answers, or would it be completely new and original, even though it provides exactly the same answers?

Some of the fruit code does not have to be compared like this. Search is pretty independent of the board representation. I don't recall any bitmap stuff in my search, or NextMove() selection code, nor in hashing. Eval is the most dramatically different, move generation fairly different although one could merge the gnu movelist stuff and not throw all my move generation code away.

So it depends on where you look as to the approach you have to use to compare.


b) please provide us with another fast and simple way for a bb program to detect either doubled or isolated pawns, other than by masking off against same side pawns on the appropriate squares (as ZW shows with Rybka above)? I would guess any other way would maddeningly slow, and that this is what you do in Crafty as well. Ie Crafty would match with Fruit in the above cases (functionally equivalent), it certainly would match with ChessSystemTal bitboard version - that's how I did it too.
Again, wrong concept. When you compare two dissimilar approaches, you don't look at the individual lines of code, since they obviously won't match. You have to look at what is done, and where it is done, and any other specific details that look to be unique, and compare those features. Or, step out of the evaluation and go to the search or something that is board independent.


I think what I'm trying to say is that putting bits of code that are pretty much forcedly in any chess program alongside each other and saying "these are functionally equivalent" and therefore make up part of the quantity on which the attacker's case depends is entirely misleading. There are things that have to be there, they are there in all programs, and there only is realistically one way to perform the function.
This is a case of "I can't see the forest for all those damned trees..." I could take any program in existence and compare the eval with Crafty, and while I would likely find bits and pieces that are similar (a single AND to detect a passed pawn, or an isolated pawn, etc) but nobody would do things in the same order, in the same places. My evaluation is hardly the most sophisticated thing around. But it is also not simple. And the way I do things is simply the way that struck me as being best at the time. If I started the eval from scratch, and did not look at the current eval, I'd probably capture at least 95% of what is done, but it would not be done in the same way, or in the same place, etc. And that would be the absolute _ultimate_ example of "using ideas" since I know every idea in the code. For example, which do you evaluate first, static pawn location, isolated, weak, passed? 4 things to compute. There are 16 possible orders for doing those 4 things (and my pawn evaluation certainly has a lot more than just four features to look for, I omitted candidates and other stuff). So just doing those 4 things in the same order is a .05 probability event. If you do 7 features it is less than .01... That's how I compare evaluations.

I have to do this exact thing on programming assignments all the time. It is easy to change a data structure, which changes the look of the code (if you use a microscope) while it is obvious that the two programs are the same except for that small difference. I teach a course in distributed computing, and the last final assignment I gave was to write a program to reproduce Ed Thorpe's "a perfect strategy for playing blackjack". Simulating millions of hands to determine the best choice (hit, stand, double-down or split) for a player's first 2 cards and the dealer's up card is not that big a program. Hundred lines of code or so. Yet I _never_ get code that looks anything near the same from two different students. Because they know that I look. A chess engine is a "bit" larger, so doing everything the same way is unlikely in the extreme.


If the attackers want to claim line-for-line similarities in the code, they need to do two things: one, line up the code and two, demonstrate the alleged copy could have used another technique that was NOT functionally equivalent.
There are several ways to deal with isolated pawns. One mask to check both files at once. Two masks that check each adjacent file one at a time. Or if you evaluate rooks on open files, you can flag each open file and use that (an 8 bit value for the 8 files) to see if adjacent files are open. Or you might even not go for pure isolated, but prefer instead to go for detecting weak pawns. Is an isolated pawn any worse than a backward pawn that is on an open file and blocked by an enemy pawn on both adjacent files so the pawn can't move without giving the opponent a protected passed pawn? So even simple ideas have a lot of alternative implementations. If a program consistently chooses the same alternative as another program, coincidence only takes you so far as an explanation.

User avatar
Rebel
Posts: 515
Joined: Wed Jun 09, 2010 7:45 pm
Real Name: Ed Schroder

Re: What do you folks make of this ?

Post by Rebel » Fri Jul 02, 2010 2:40 pm

BB+ wrote: The exact numerology is much beyond a similarity (as I mentioned, merely having the same Rank/File/Line centralisation strategy for PST is a different bailiwick than having the same numbers from them). I can't find any engines other than Fruit and Rybka whose PST values are derived from (minor exceptions with Rybka in central pawns):

Code: Select all

static const int PawnFile[8] = {-3, -1, +0, +1, +1, +0, -1, -3,};
static const int KnightLine[8] = {-4, -2, +0, +1, +1, +0, -2, -4,};
static const int KnightRank[8] = {-2, -1, +0, +1, +2, +3, +2, +1,};
static const int BishopLine[8] = {-3, -1, +0, +1, +1, +0, -1, -3,};
static const int RookFile[8] = {-2, -1, +0, +1, +1, +0, -1, -2,};
static const int QueenLine[8] = { -3, -1, +0, +1, +1, +0, -1, -3,};
static const int KingLine[8] = {-3, -1, +0, +1, +1, +0, -1, -3,};
static const int KingFile[8] = { +3, +4, +2, +0, +0, +2, +4, +3,};
static const int KingRank[8] = { +1, +0, -2, -3, -4, -5, -6, -7,};
I can imagine someone with the same idea producing 4 or 5 of these arrays that are the same, but not all 9.
For the moment let me only comment on the above.

When I search the Rybka 1.0 executable for the above patterns they are NOT FOUND.

PawnFile[8] = {-3, -1, +0 } is present, there after nothing matches in the executable.
KnightLine[8] = {-4, -2 } the -4 -2 combination doesn't occur in the whole executable.

I stopped here, perhaps you can explain.

Interesting thing is that your quoted values do occur in Strelka, but that's an entire different subject.

Ed

zwegner
Posts: 57
Joined: Thu Jun 10, 2010 5:38 am

Re: What do you folks make of this ?

Post by zwegner » Fri Jul 02, 2010 4:12 pm

Rebel wrote:
BB+ wrote: The exact numerology is much beyond a similarity (as I mentioned, merely having the same Rank/File/Line centralisation strategy for PST is a different bailiwick than having the same numbers from them). I can't find any engines other than Fruit and Rybka whose PST values are derived from (minor exceptions with Rybka in central pawns):

Code: Select all

static const int PawnFile[8] = {-3, -1, +0, +1, +1, +0, -1, -3,};
static const int KnightLine[8] = {-4, -2, +0, +1, +1, +0, -2, -4,};
static const int KnightRank[8] = {-2, -1, +0, +1, +2, +3, +2, +1,};
static const int BishopLine[8] = {-3, -1, +0, +1, +1, +0, -1, -3,};
static const int RookFile[8] = {-2, -1, +0, +1, +1, +0, -1, -2,};
static const int QueenLine[8] = { -3, -1, +0, +1, +1, +0, -1, -3,};
static const int KingLine[8] = {-3, -1, +0, +1, +1, +0, -1, -3,};
static const int KingFile[8] = { +3, +4, +2, +0, +0, +2, +4, +3,};
static const int KingRank[8] = { +1, +0, -2, -3, -4, -5, -6, -7,};
I can imagine someone with the same idea producing 4 or 5 of these arrays that are the same, but not all 9.
For the moment let me only comment on the above.

When I search the Rybka 1.0 executable for the above patterns they are NOT FOUND.

PawnFile[8] = {-3, -1, +0 } is present, there after nothing matches in the executable.
KnightLine[8] = {-4, -2 } the -4 -2 combination doesn't occur in the whole executable.

I stopped here, perhaps you can explain.

Interesting thing is that your quoted values do occur in Strelka, but that's an entire different subject.

Ed
Yes--these values are used in Fruit to calculate the PSTs (using constants like KnightCentreOpening). Perhaps you are familiar. In Rybka 1.0, the values of these constants are changed, but only the output of the array is in the binary. Basically some offline code was coded that was obviously very similar to Fruit's, and that output a big array.

If you take the weights (my webpage has them all) and plug them into the Fruit pst_init() function, you get nearly exactly the values below. The only exception is the pawn correction that BB mentioned. Fruit:

Code: Select all

P(piece,D3,Opening) += 10;
P(piece,E3,Opening) += 10;

P(piece,D4,Opening) += 20;
P(piece,E4,Opening) += 20;

P(piece,D5,Opening) += 10;
P(piece,E5,Opening) += 10;
And Rybka:

Code: Select all

P(piece,D5,Opening) += 74;
P(piece,E5,Opening) += 74;
The other correction that Fruit/Rybka has, the KnightTrapped penalty for knights on A8/H8, is the same value in both programs, exactly one pawn (100 in Fruit, 3200 in Rybka).

Here's the full PST values from the Rybka binary, along with the address along the side (copied and pasted from IDA, which can't handle signed words very well obviously):

Code: Select all

.rdata:00661300 Pst             dw 64993,  291,65355,   97,    0,    0,  181,65439,  181,65439,    0,    0,65355,   97,64993,  291
.rdata:00661300                                         ; DATA XREF: board_opening+1Fr
.rdata:00661300                                         ; board_endgame+1Fr
.rdata:00661300                 dw 64993,  291,65355,   97,    0,    0,  181,65439,  181,65439,    0,    0,65355,   97,64993,  291
.rdata:00661300                 dw 64993,  291,65355,   97,    0,    0,  181,65439,  181,65439,    0,    0,65355,   97,64993,  291
.rdata:00661300                 dw 64993,  291,65355,   97,    0,    0,  181,65439,  181,65439,    0,    0,65355,   97,64993,  291
.rdata:00661300                 dw 64993,  291,65355,   97,    0,    0,  255,65439,  255,65439,    0,    0,65355,   97,64993,  291
.rdata:00661300                 dw 64993,  291,65355,   97,    0,    0,  181,65439,  181,65439,    0,    0,65355,   97,64993,  291
.rdata:00661300                 dw 64993,  291,65355,   97,    0,    0,  181,65439,  181,65439,    0,    0,65355,   97,64993,  291
.rdata:00661300                 dw 64993,  291,65355,   97,    0,    0,  181,65439,  181,65439,    0,    0,65355,   97,64993,  291
.rdata:00661300                 dw   543,65245,  181,65439,    0,    0,65355,   97,65355,   97,    0,    0,  181,65439,  543,65245
.rdata:00661300                 dw   543,65245,  181,65439,    0,    0,65355,   97,65355,   97,    0,    0,  181,65439,  543,65245
.rdata:00661300                 dw   543,65245,  181,65439,    0,    0,65355,   97,65355,   97,    0,    0,  181,65439,  543,65245
.rdata:00661300                 dw   543,65245,  181,65439,    0,    0,65281,   97,65281,   97,    0,    0,  181,65439,  543,65245
.rdata:00661300                 dw   543,65245,  181,65439,    0,    0,65355,   97,65355,   97,    0,    0,  181,65439,  543,65245
.rdata:00661300                 dw   543,65245,  181,65439,    0,    0,65355,   97,65355,   97,    0,    0,  181,65439,  543,65245
.rdata:00661300                 dw   543,65245,  181,65439,    0,    0,65355,   97,65355,   97,    0,    0,  181,65439,  543,65245
.rdata:00661300                 dw   543,65245,  181,65439,    0,    0,65355,   97,65355,   97,    0,    0,  181,65439,  543,65245
.rdata:00661300                 dw 62044,65088,62738,65200,63432,65312,63779,65368,63779,65368,63432,65312,62738,65200,62044,65088
.rdata:00661300                 dw 63096,65200,63790,65312,64484,65424,64831,65480,64831,65480,64484,65424,63790,65312,63096,65200
.rdata:00661300                 dw 64148,65312,64842,65424,    0,    0,  347,   56,  347,   56,    0,    0,64842,65424,64148,65312
.rdata:00661300                 dw 64853,65368,   11,65480,  705,   56, 1052,  112, 1052,  112,  705,   56,   11,65480,64853,65368
.rdata:00661300                 dw 65211,65368,  369,65480, 1063,   56, 1410,  112, 1410,  112, 1063,   56,  369,65480,65211,65368
.rdata:00661300                 dw 65222,65312,  380,65424, 1074,    0, 1421,   56, 1421,   56, 1074,    0,  380,65424,65222,65312
.rdata:00661300                 dw 64170,65200,64864,65312,   22,65424,  369,65480,  369,65480,   22,65424,64864,65312,64170,65200
.rdata:00661300                 dw 59918,65088,63812,65200,64506,65312,64853,65368,64853,65368,64506,65312,63812,65200,59918,65088
.rdata:00661300                 dw  5618,  448, 1724,  336, 1030,  224,  683,  168,  683,  168, 1030,  224, 1724,  336, 5618,  448
.rdata:00661300                 dw  1366,  336,  672,  224,65514,  112,65167,   56,65167,   56,65514,  112,  672,  224, 1366,  336
.rdata:00661300                 dw   314,  224,65156,  112,64462,    0,64115,65480,64115,65480,64462,    0,65156,  112,  314,  224
.rdata:00661300                 dw   325,  168,65167,   56,64473,65480,64126,65424,64126,65424,64473,65480,65167,   56,  325,  168
.rdata:00661300                 dw   683,  168,65525,   56,64831,65480,64484,65424,64484,65424,64831,65480,65525,   56,  683,  168
.rdata:00661300                 dw  1388,  224,  694,  112,    0,    0,65189,65480,65189,65480,    0,    0,  694,  112, 1388,  224
.rdata:00661300                 dw  2440,  336, 1746,  224, 1052,  112,  705,   56,  705,   56, 1052,  112, 1746,  224, 2440,  336
.rdata:00661300                 dw  3492,  448, 2798,  336, 2104,  224, 1757,  168, 1757,  168, 2104,  224, 2798,  336, 3492,  448
.rdata:00661300                 dw 64781,65242,64697,65340,64844,65389,64991,65438,64991,65438,64844,65389,64697,65340,64781,65242
.rdata:00661300                 dw 64948,65340,   84,65438,65389,65487,    0,    0,    0,    0,65389,65487,   84,65438,64948,65340
.rdata:00661300                 dw 65095,65389,65389,65487,  378,    0,  147,   49,  147,   49,  378,    0,65389,65487,65095,65389
.rdata:00661300                 dw 65242,65438,    0,    0,  147,   49,  672,   98,  672,   98,  147,   49,    0,    0,65242,65438
.rdata:00661300                 dw 65242,65438,    0,    0,  147,   49,  672,   98,  672,   98,  147,   49,    0,    0,65242,65438
.rdata:00661300                 dw 65095,65389,65389,65487,  378,    0,  147,   49,  147,   49,  378,    0,65389,65487,65095,65389
.rdata:00661300                 dw 64948,65340,   84,65438,65389,65487,    0,    0,    0,    0,65389,65487,   84,65438,64948,65340
.rdata:00661300                 dw 65032,65242,64948,65340,65095,65389,65242,65438,65242,65438,65095,65389,64948,65340,65032,65242
.rdata:00661300                 dw   504,  294,  588,  196,  441,  147,  294,   98,  294,   98,  441,  147,  588,  196,  504,  294
.rdata:00661300                 dw   588,  196,65452,   98,  147,   49,    0,    0,    0,    0,  147,   49,65452,   98,  588,  196
.rdata:00661300                 dw   441,  147,  147,   49,65158,    0,65389,65487,65389,65487,65158,    0,  147,   49,  441,  147
.rdata:00661300                 dw   294,   98,    0,    0,65389,65487,64864,65438,64864,65438,65389,65487,    0,    0,  294,   98
.rdata:00661300                 dw   294,   98,    0,    0,65389,65487,64864,65438,64864,65438,65389,65487,    0,    0,  294,   98
.rdata:00661300                 dw   441,  147,  147,   49,65158,    0,65389,65487,65389,65487,65158,    0,  147,   49,  441,  147
.rdata:00661300                 dw   588,  196,65452,   98,  147,   49,    0,    0,    0,    0,  147,   49,65452,   98,  588,  196
.rdata:00661300                 dw   755,  294,  839,  196,  692,  147,  545,   98,  545,   98,  692,  147,  839,  196,  755,  294
.rdata:00661300                 dw 65328,    0,65432,    0,    0,    0,  104,    0,  104,    0,    0,    0,65432,    0,65328,    0
.rdata:00661300                 dw 65328,    0,65432,    0,    0,    0,  104,    0,  104,    0,    0,    0,65432,    0,65328,    0
.rdata:00661300                 dw 65328,    0,65432,    0,    0,    0,  104,    0,  104,    0,    0,    0,65432,    0,65328,    0
.rdata:00661300                 dw 65328,    0,65432,    0,    0,    0,  104,    0,  104,    0,    0,    0,65432,    0,65328,    0
.rdata:00661300                 dw 65328,    0,65432,    0,    0,    0,  104,    0,  104,    0,    0,    0,65432,    0,65328,    0
.rdata:00661300                 dw 65328,    0,65432,    0,    0,    0,  104,    0,  104,    0,    0,    0,65432,    0,65328,    0
.rdata:00661300                 dw 65328,    0,65432,    0,    0,    0,  104,    0,  104,    0,    0,    0,65432,    0,65328,    0
.rdata:00661300                 dw 65328,    0,65432,    0,    0,    0,  104,    0,  104,    0,    0,    0,65432,    0,65328,    0
.rdata:00661300                 dw   208,    0,  104,    0,    0,    0,65432,    0,65432,    0,    0,    0,  104,    0,  208,    0
.rdata:00661300                 dw   208,    0,  104,    0,    0,    0,65432,    0,65432,    0,    0,    0,  104,    0,  208,    0
.rdata:00661300                 dw   208,    0,  104,    0,    0,    0,65432,    0,65432,    0,    0,    0,  104,    0,  208,    0
.rdata:00661300                 dw   208,    0,  104,    0,    0,    0,65432,    0,65432,    0,    0,    0,  104,    0,  208,    0
.rdata:00661300                 dw   208,    0,  104,    0,    0,    0,65432,    0,65432,    0,    0,    0,  104,    0,  208,    0
.rdata:00661300                 dw   208,    0,  104,    0,    0,    0,65432,    0,65432,    0,    0,    0,  104,    0,  208,    0
.rdata:00661300                 dw   208,    0,  104,    0,    0,    0,65432,    0,65432,    0,    0,    0,  104,    0,  208,    0
.rdata:00661300                 dw   208,    0,  104,    0,    0,    0,65432,    0,65432,    0,    0,    0,  104,    0,  208,    0
.rdata:00661300                 dw 64747,64888,64943,65104,65041,65212,65139,65320,65139,65320,65041,65212,64943,65104,64747,64888
.rdata:00661300                 dw 65144,65104,65340,65320,65438,65428,    0,    0,    0,    0,65438,65428,65340,65320,65144,65104
.rdata:00661300                 dw 65242,65212,65438,65428,    0,    0,   98,  108,   98,  108,    0,    0,65438,65428,65242,65212
.rdata:00661300                 dw 65340,65320,    0,    0,   98,  108,  196,  216,  196,  216,   98,  108,    0,    0,65340,65320
.rdata:00661300                 dw 65340,65320,    0,    0,   98,  108,  196,  216,  196,  216,   98,  108,    0,    0,65340,65320
.rdata:00661300                 dw 65242,65212,65438,65428,    0,    0,   98,  108,   98,  108,    0,    0,65438,65428,65242,65212
.rdata:00661300                 dw 65144,65104,65340,65320,65438,65428,    0,    0,    0,    0,65438,65428,65340,65320,65144,65104
.rdata:00661300                 dw 64948,64888,65144,65104,65242,65212,65340,65320,65340,65320,65242,65212,65144,65104,64948,64888
.rdata:00661300                 dw   588,  648,  392,  432,  294,  324,  196,  216,  196,  216,  294,  324,  392,  432,  588,  648
.rdata:00661300                 dw   392,  432,  196,  216,   98,  108,    0,    0,    0,    0,   98,  108,  196,  216,  392,  432
.rdata:00661300                 dw   294,  324,   98,  108,    0,    0,65438,65428,65438,65428,    0,    0,   98,  108,  294,  324
.rdata:00661300                 dw   196,  216,    0,    0,65438,65428,65340,65320,65340,65320,65438,65428,    0,    0,  196,  216
.rdata:00661300                 dw   196,  216,    0,    0,65438,65428,65340,65320,65340,65320,65438,65428,    0,    0,  196,  216
.rdata:00661300                 dw   294,  324,   98,  108,    0,    0,65438,65428,65438,65428,    0,    0,   98,  108,  294,  324
.rdata:00661300                 dw   392,  432,  196,  216,   98,  108,    0,    0,    0,    0,   98,  108,  196,  216,  392,  432
.rdata:00661300                 dw   789,  648,  593,  432,  495,  324,  397,  216,  397,  216,  495,  324,  593,  432,  789,  648
.rdata:00661300                 dw  1407,63130, 1876,63932,  938,64333,    0,64734,    0,64734,  938,64333, 1876,63932, 1407,63130
.rdata:00661300                 dw  1407,63932, 1876,64734,  938,65135,    0,    0,    0,    0,  938,65135, 1876,64734, 1407,63932
.rdata:00661300                 dw  1407,64333, 1876,65135,  938,    0,    0,  401,    0,  401,  938,    0, 1876,65135, 1407,64333
.rdata:00661300                 dw  1407,64734, 1876,    0,  938,  401,    0,  802,    0,  802,  938,  401, 1876,    0, 1407,64734
.rdata:00661300                 dw  1407,64734, 1876,    0,  938,  401,    0,  802,    0,  802,  938,  401, 1876,    0, 1407,64734
.rdata:00661300                 dw  1407,64333, 1876,65135,  938,    0,    0,  401,    0,  401,  938,    0, 1876,65135, 1407,64333
.rdata:00661300                 dw  1407,63932, 1876,64734,  938,65135,    0,    0,    0,    0,  938,65135, 1876,64734, 1407,63932
.rdata:00661300                 dw  1407,63130, 1876,63932,  938,64333,    0,64734,    0,64734,  938,64333, 1876,63932, 1407,63130
.rdata:00661300                 dw 64129, 2406,63660, 1604,64598, 1203,    0,  802,    0,  802,64598, 1203,63660, 1604,64129, 2406
.rdata:00661300                 dw 64129, 1604,63660,  802,64598,  401,    0,    0,    0,    0,64598,  401,63660,  802,64129, 1604
.rdata:00661300                 dw 64129, 1203,63660,  401,64598,    0,    0,65135,    0,65135,64598,    0,63660,  401,64129, 1203
.rdata:00661300                 dw 64129,  802,63660,    0,64598,65135,    0,64734,    0,64734,64598,65135,63660,    0,64129,  802
.rdata:00661300                 dw 64129,  802,63660,    0,64598,65135,    0,64734,    0,64734,64598,65135,63660,    0,64129,  802
.rdata:00661300                 dw 64129, 1203,63660,  401,64598,    0,    0,65135,    0,65135,64598,    0,63660,  401,64129, 1203
.rdata:00661300                 dw 64129, 1604,63660,  802,64598,  401,    0,    0,    0,    0,64598,  401,63660,  802,64129, 1604
.rdata:00661300                 dw 64129, 2406,63660, 1604,64598, 1203,    0,  802,    0,  802,64598, 1203,63660, 1604,64129, 2406

User avatar
Chris Whittington
Posts: 437
Joined: Wed Jun 09, 2010 6:25 pm

Re: What do you folks make of this ?

Post by Chris Whittington » Fri Jul 02, 2010 7:37 pm

hyatt wrote:From past experience, the "black box" approach doesn't lead to this kind of duplication. How would two different people write the same "black box" and end up with pieces of identical code? You define the inputs, and the outputs, but the "how" in a black box is, by intention, not specified. I don't see this as a logical explanation of what has been found. It could certainly explain overall program structure similarities (each would have black boxes with similarities with respect to functionality) but it doesn't explain line-for-line and value-for-value similarities in various places.
Easy one. They're both chess programmers and like all other chess programmers they've had a good look around at what other people do, read the same material, talked to the same set of people, it's called group think and most will do stuff in the same sort of way, with occasionally someone discovering something better, when all then switch to that as soon as it too becomes part of the group think.

There is no line-for-line similarity in the engine code because of three things

a) the data structure is radically different which forces the code to be radically different

b) much stuff is done by lookup in one program and by code in the other program

c) you don't have access to Rybka source, so the comparison would be between Rybka assembley code and Fruit C-code, except that Zach (who has courageously admitted his bias) converted the Rybka assembler into C-code with all the problems that a non-independent witness is then going to have with bias wanting to prove guilt (ie a lot of magical thought) and also back-converted the lookup tables into C-code that, again magic thinking, could have produced them (note: could have not did).

You've also invented the concept of "functional equivalence" to cover the lack of direct comparison capability but omit to mention that chess programs contain code chunks which by force do the same thing, whether it be check if pawn is doubled or count the number of pieces attacking the eight squares around the king. I posit that HOWEVER such code gets written, whether by lookup or changed data structure, you're going to say the magic words "Functionally Equivalent!". Well, I say "Of Course It Is! It Does The Same Thing, Like Everybody Else Does!"

I remain open to being convinced, but the overwhelming evidence is that there are bits of suspicious data similarities but no suspicious bits of code similarities.

User avatar
Chris Whittington
Posts: 437
Joined: Wed Jun 09, 2010 6:25 pm

Re: What do you folks make of this ?

Post by Chris Whittington » Fri Jul 02, 2010 8:09 pm

hyatt wrote:
Chris Whittington wrote:
hyatt wrote:From past experience, the "black box" approach doesn't lead to this kind of duplication. How would two different people write the same "black box" and end up with pieces of identical code? You define the inputs, and the outputs, but the "how" in a black box is, by intention, not specified. I don't see this as a logical explanation of what has been found. It could certainly explain overall program structure similarities (each would have black boxes with similarities with respect to functionality) but it doesn't explain line-for-line and value-for-value similarities in various places.
well, at this stage, I can accept the evidence that there are bits and pieces of suspicious data lying around, but I am not accepting the 'identical code'.

Reasons: data structure has changed, therefore the code is different by force, the attacking side tries to get round this by talking of "functional equivalence", for example:

Doubled Pawns

Doubled pawns are the first and simplest pattern. In Fruit, we look behind the given pawn for a friendly pawn. In Rybka, we look ahead. These are of course equivalent. Rybka also has a score of zero for doubled pawns in the opening.
Fruit
if ((board->pawn_file[me][file] & BitLT[rank]) != 0)
doubled = true;
...
if (doubled) {
opening[me] -= DoubledOpening;
endgame[me] -= DoubledEndgame;
}

Rybka
if (MaskPawnDoubled[square] & Board.pieces[WP])
endgame -= DoubledEndgame;


Isolated Pawns

Isolated pawns come next. In Fruit, the variable t1 represents the bitwise OR of the rank-wise bitmasks of friendly pawns on adjacent files. So if t1==0, that means that no pawns are on either of the adjacent files to this pawn. Rybka's MaskPawnIsolated works the same way.
Fruit
if (t1 == 0)
isolated = true;
...
if (isolated) {
if (open) {
opening[me] -= IsolatedOpeningOpen;
endgame[me] -= IsolatedEndgame;
} else {
opening[me] -= IsolatedOpening;
endgame[me] -= IsolatedEndgame;
}
}

Rybka
if ((MaskPawnIsolated[square] & Board.pieces[WP]) == 0) {
if (open_file) {
opening -= IsolatedOpeningOpen;
endgame -= IsolatedEndgame;
} else {
opening -= IsolatedOpening;
endgame -= IsolatedEndgame;
}
}


Please riddle me this:

a) is there a chess program on the planet that doesn't contain snippets/code to identify doubled and isolated pawns and apply some sort of penalty?
Again, step back one or two steps. Rather than looking at a single line of code, look at the "body" first. Yes, most recognize passed pawns. But do you recognize it in your normal pawn evaluation? In a separate procedure so you can use king position that is normally not a part of the pawn hash signature? What about in individual piece scoring functions where you blockade a passed pawn? The more interesting thing is the where/how/when about what is going on, when trying to compare different data structures. I could take Crafty's eval (and we had talked of doing the opposite more than once and plugging someone else's eval into our program just to see whether it was an improvement or a degradation) and convert it to Fruit's board representation, and it would look different if you compare groups of lines of code, because of the bitboard vs array representation. But would the actual code be functionally equivalent and provide exactly the same answers, or would it be completely new and original, even though it provides exactly the same answers?

Some of the fruit code does not have to be compared like this. Search is pretty independent of the board representation. I don't recall any bitmap stuff in my search, or NextMove() selection code, nor in hashing. Eval is the most dramatically different, move generation fairly different although one could merge the gnu movelist stuff and not throw all my move generation code away.

So it depends on where you look as to the approach you have to use to compare.


b) please provide us with another fast and simple way for a bb program to detect either doubled or isolated pawns, other than by masking off against same side pawns on the appropriate squares (as ZW shows with Rybka above)? I would guess any other way would maddeningly slow, and that this is what you do in Crafty as well. Ie Crafty would match with Fruit in the above cases (functionally equivalent), it certainly would match with ChessSystemTal bitboard version - that's how I did it too.
Again, wrong concept. When you compare two dissimilar approaches, you don't look at the individual lines of code, since they obviously won't match. You have to look at what is done, and where it is done, and any other specific details that look to be unique, and compare those features. Or, step out of the evaluation and go to the search or something that is board independent.


I think what I'm trying to say is that putting bits of code that are pretty much forcedly in any chess program alongside each other and saying "these are functionally equivalent" and therefore make up part of the quantity on which the attacker's case depends is entirely misleading. There are things that have to be there, they are there in all programs, and there only is realistically one way to perform the function.
This is a case of "I can't see the forest for all those damned trees..." I could take any program in existence and compare the eval with Crafty, and while I would likely find bits and pieces that are similar (a single AND to detect a passed pawn, or an isolated pawn, etc) but nobody would do things in the same order, in the same places. My evaluation is hardly the most sophisticated thing around. But it is also not simple. And the way I do things is simply the way that struck me as being best at the time. If I started the eval from scratch, and did not look at the current eval, I'd probably capture at least 95% of what is done, but it would not be done in the same way, or in the same place, etc. And that would be the absolute _ultimate_ example of "using ideas" since I know every idea in the code. For example, which do you evaluate first, static pawn location, isolated, weak, passed? 4 things to compute. There are 16 possible orders for doing those 4 things (and my pawn evaluation certainly has a lot more than just four features to look for, I omitted candidates and other stuff). So just doing those 4 things in the same order is a .05 probability event. If you do 7 features it is less than .01... That's how I compare evaluations.

I have to do this exact thing on programming assignments all the time. It is easy to change a data structure, which changes the look of the code (if you use a microscope) while it is obvious that the two programs are the same except for that small difference. I teach a course in distributed computing, and the last final assignment I gave was to write a program to reproduce Ed Thorpe's "a perfect strategy for playing blackjack". Simulating millions of hands to determine the best choice (hit, stand, double-down or split) for a player's first 2 cards and the dealer's up card is not that big a program. Hundred lines of code or so. Yet I _never_ get code that looks anything near the same from two different students. Because they know that I look. A chess engine is a "bit" larger, so doing everything the same way is unlikely in the extreme.


If the attackers want to claim line-for-line similarities in the code, they need to do two things: one, line up the code and two, demonstrate the alleged copy could have used another technique that was NOT functionally equivalent.
There are several ways to deal with isolated pawns. One mask to check both files at once. Two masks that check each adjacent file one at a time. Or if you evaluate rooks on open files, you can flag each open file and use that (an 8 bit value for the 8 files) to see if adjacent files are open. Or you might even not go for pure isolated, but prefer instead to go for detecting weak pawns. Is an isolated pawn any worse than a backward pawn that is on an open file and blocked by an enemy pawn on both adjacent files so the pawn can't move without giving the opponent a protected passed pawn? So even simple ideas have a lot of alternative implementations. If a program consistently chooses the same alternative as another program, coincidence only takes you so far as an explanation.

Maybe the forest will still be standing but meanwhile the trees I looked at have Dutch Elm Disease and will have to be felled, and we need to track down the other diseased trees to determine if there's any good forest or whether the whole thing should be condemned.

And, since the first two trees I took a look at have problems, perhaps you'ld like to compute the chances that, just by incredible chance, I managed to select at random the only two bad trees in the 100 tree forest? Is it 0.01% perchance?

Bob wrote
For example, which do you evaluate first, static pawn location, isolated, weak, passed? 4 things to compute. There are 16 possible orders for doing those 4 things (and my pawn evaluation certainly has a lot more than just four features to look for, I omitted candidates and other stuff). So just doing those 4 things in the same order is a .05 probability event. If you do 7 features it is less than .01... That's how I compare evaluations


We're not talking about what happens in Crafty, we're talking about what happens in Fruit and Rybka. But, for Crafty, if you select four independent functions which could be carried out in any order, or even in parallel, having no dependence on each other, then you're fine for suggesting they could be in any random order. A chess program is not a book, the ordering of much stuff is not relevent, whereas in a book the ordering is fundamental.

Now, reverting to the programs in question, Rybka and Fruit, Zach indeed points (similarly to you) to the ordering of some sub-functions in the pawn eval being the same (pawn-get-info he calls it),

Zach wrote:
it should be noted that each evaluation uses the exact same terms in the exact same order: doubled, isolated, backwards, passers, candidates


although he does not make the leap as you did to suggest the odds.
When I read that I thought to myself "although I no longer have the code to CSTal, I think it used the same ordering" and because I'm not part of the guilty-already-for-sure groupthink, I asked myself why that could be, why does some ancient old program from the 1990's use the same ordering, why did I order in that way? Does everybody, or most?

Well, I guess the answer is that some functions are dependent on others - I don't bother looking more at the backward pawns in doubled pawns, if a pawn is isolated I won't bother looking to see if it can be supported by another pawn.

Some things are that way for historical reasons. Once apon a time I never even bothered to compute passers so I have a tendency to leave them till last anyway.

Some things are that way because they might need to pass data on to something else later, I tend to do that stuff last, and save the pass on params last when done.

Some are easier to calculate - I do easy things first, doubled and isolated seem easier.

Some things pass info onwards (ie more dependency within the bunch of pawn evals), I tend to do the things that pass info on as close as possible to the thing that uses the info.

You may come back and say "how stupid", well maybe, but we humans are psychological creatures and if stuff can be done in any order, we quite possibly sub-consciously make an ordering based on our human makeup - for example, easy things first.

Needless to say, I do not accept your statistics about ordering of functions. Technically you may be correct, but in terms of interdependency and human behaviours, you are not.

hyatt
Posts: 1242
Joined: Thu Jun 10, 2010 2:13 am
Real Name: Bob Hyatt (Robert M. Hyatt)
Location: University of Alabama at Birmingham
Contact:

Re: What do you folks make of this ?

Post by hyatt » Fri Jul 02, 2010 9:55 pm

We're just going to disagree. My passed pawn code is not even in the EvaluatePawns() procedure, in fact. While some king safety code is in there since I am looking at pawns for the 1st approximation to king safety. In my pawn code, I do the following things in this order:

(0) Figure out how far each pawn can safely advance for either side.

(1) recognize and flag (using 8 bit value) files that are open. I do this by flagging any file with a pawn as closed when I pick up a pawn for analysis.

(2) pc/sq value (static score)

(3) Isolated pawns. then if on half-open file, another penalty.

(4) weak pawns, which use some complex code to determine which pawns are free to advance on which files, how far they can advance safely, so that I can decide whether a pawn can be defended by a pawn or not. I use the info from (0) above.

(5) doubled pawns.

(6) recognize a duo (mobile pair of pawns)

(7) flag (but do not evaluate) files with passed pawns, for use in another procedure.

(8) evaluate candidate passed pawns and do some scoring here, as well as flag the files with candidate passers for later use.

(8) evaluate "hidden" passed pawns. Example is white pawns at h6 and g5, black pawn at h7. g5 pawn is weak (backward) but h6 pawn is passed, because if white plays g6, if black takes the h pawn is passed, if black ignores, white takes on h7 and it is still passed.

(9) evaluate the king safety pawn shelter for the left and right wings, and the center, since we can't do it just for where the king sits since I can't use the king's location here since it is not part of the pawn hash sig. Instead, since I get over 99% pawn hash hits, I just evaluate all 3 as it costs nothing.

I bet no one does those things in the same order and using similar "ideas" as to how to pull each concept off...

That is just for pawns. Same thing occurs for all sorts of other eval ideas. Same order -> _strong_ suspicion.

BB+
Posts: 1484
Joined: Thu Jun 10, 2010 4:26 am

Re: What do you folks make of this ?

Post by BB+ » Fri Jul 02, 2010 11:14 pm

My guess is that this would probably cover the UI code, although I seem to remember from the past many criticisms of the UI 'evidence' for other reasons.
I actually brought up "fair use" for the interface code in an email to ZW maybe a week ago. I think the main case-law is with SEGA, though I'm not sure it is really relevant here. See http://digital-law-online.info/cases/24PQ2D1561.htm though there might be another one other than this case with Accolade. I personally think "fair use" would be much more likely to apply if one were to re-use the UCI code of SMK (as he is the author/promulgulator of UCI) than that of Letouzey. But I'm also not a lawyer. :)

Code: Select all

Accolade learned of the impending release of the Genesis III in the United States in January 1991, when the Genesis III was displayed at a consumer electronics show. When a demonstration at the consumer electronics show revealed that Accolade’s “Ishido” game cartridges would not operate on the Genesis III, Accolade returned to the drawing board. During the reverse engineering process, Accolade engineers had discovered a small segment of code – the TMSS initialization code – that was included in the “power-up” sequence of every Sega game, but that had no identifiable function. The games would operate on the original Genesis console even if the code segment was removed. Mike Lorenzen, <977 F.2d 1516> the Accolade engineer with primary responsibility for reverse engineering the interface procedures for the Genesis console, sent a memo regarding the code segment to Alan Miller, his supervisor and the current president of Accolade, in which he noted that “it is possible that some future Sega peripheral device might require it for proper initialization.”

In the second round of reverse engineering, Accolade engineers focused on the code segment identified by Lorenzen. After further study, Accolade added the code to its development manual in the form of a standard header file to be used in all games. The file contains approximately twenty to twenty-five bytes of data. Each of Accolade’s games contains a total of 500,000 to 1,500,000 bytes. According to Accolade employees, the header file is the only portion of Sega’s Code that Accolade copied into its own game programs.
The case was actually more about "false designation of origin", as due to the compatibility hack, the Sega system would recognise the Accolade product, and therefore say that it was "PRODUCED BY OR UNDER LICENSE FROM SEGA ENTERPRISES LTD."
I think what I'm trying to say is that putting bits of code that are pretty much forcedly in any chess program alongside each other and saying "these are functionally equivalent" and therefore make up part of the quantity on which the attacker's case depends is entirely misleading. There are things that have to be there, they are there in all programs, and there only is realistically one way to perform the function.
I had similar misgivings about some of the evidence. One particular thing that got me was the use of C code for the Rybka stuff: as the bitboards make direct code comparison nugatory, I would have just presented it (and thus also Fruit) as pseudo-code for a comparison. Something like

Code: Select all

Check if pawn is doubled, if so, subtract penalties
Check if pawn is isolated.
  If on open files, subtract a penalty
  Else if on a closed file, subtract a different penalty
Check if pawn is backward.
   If on open files, subtract a penalty
   Else if on a closed file, subtract a different penalty
In Fruit it looks like

Code: Select all

Determine if pawn is doubled, isolated, and/or backward.
If doubled, subtract a penalty.
If isolated
  If on open files, subtract a penalty
  Else if on a closed file, subtract a different penalty
If backward
   If on open files, subtract a penalty
   Else if on a closed file, subtract a different penalty
As you say, most engines do something similar, so once one admits the opening/endgame split as valid, all that is really left is the ordering of these pawn elements.
My passed pawn code is not even in the EvaluatePawns() procedure, in fact.
Just an aside, but Fruit 2.1 has the nice comment (in the pawn eval):

Code: Select all

         // this was moved to the dynamic evaluation

/*
         if (passed) {
            opening[me] += quad(PassedOpeningMin,PassedOpeningMax,rank);
            endgame[me] += quad(PassedEndgameMin,PassedEndgameMax,rank);
         }
*/

Post Reply