hgm wrote:2. Hash clearing
The specs on the memory command will be beefed up a bit, to imply clearing the hash table (and other tables) even if the requested size is equal to the current size. Currently WinBoard sends the memory command after new on every game, but future interfaces could refrain from that, if the hash size can stay the same and they don't really want to reset the engine to a known state. To the specs of the new command the recommendation will be added that it should leave the hash table alone.
I too would prefer a new command here ("reset" sounds good). Allowing the user to clear the hash is pretty useful. "new" has its own semantics, starting games. Some engines might want to clear the hash, others not. The standard should be to keep it, but only if there is a reset command. Without a reset, the default should be to clear on "new". "memory" should only be sent when memory changes, "new" only for a new game, and "reset" only to clear hash. Doing otherwise would really just cause confusion here.
3. Thinking Output
Currently there is a hideous feature in WB protocol called 'periodic updates', whereby the engine is polled by the GUI for information it might or might not have. I want to deprecate that, as it is a clear case of totally wrong design. Polling is awful; the engine should volunteer this information, as it is the engine that knows when it has new information to present. And logically, the information belongs with the Thinking Output. In fact it even duplicates part of it (depth, time, nodes).
So I plan to make an extension to the specs for Thinking-Output lines, which can include this information. The engine can then send this info not only during analysis, but also during pondering and regular search. And as the PV in the olds protocol specs is a free-format field, there is automatic backward compatibility. Old interfaces that do not know about the new standard, would simply display the info as part of the PV. In fact, I already know some engines that use this technique (e.g. NanoSzachy), and it looks quite nice.
In particular, I want the new format to look as
depth score time nodes tbhits {move movenr/totalmoves} PV +-
In front of the PV, between braces, the engine can display the move it is currently considering in the root, the sequence number of that move, and the total number of root moves. (I.e., the info that formerly was in the stat01 lines.) In front of it, there can be an optional number to indicate the number of tablebase hits. Perhaps some more optional fields could be squeezed in here in the future; I would like to keep their number low, though, in order not to push the PV out of view on old interfaces. Prepending 0 {f3e5 3/20} (14-15 characters) seems still acceptable.
The 'time' parameter should specify CPU-time used (sum of all threads for SMP engines), so that the GUI can calculate CPU load. Sending wall-clock time here is kind of redundant, as the GUI can measure this itself.
Mate scores should be standardized, and preferably encoded in a way that does not break old interfaces. In Joker I use the system of encoding a mate in N (moves!) in the Thinking Output as 100000+N, and mated in N as -(100000+N). This keeps it purely numeric, and in a way that makes you immediately read the DTM on old interfaces, rather than having to do a mental subtraction from an obscure number such as 32,768. GUIs aware of the standard would of course convert it to a text like MATE6 in the score field.
At the end of the PV there can be an optional + or - to indicate fail high or fail low. If I understand correctly, the PV will never be longer than 1 move in that case, so it will always be in view.
I think if we're going to standardize thinking output, we should do it properly. This is one area where UCI excels. Though the syntax is ugly, the standardization is very nice. Xboard has a problem here due to backward compatibility. I think in this case, abandoning backward compatibility with old GUIs would be worth it for better thinking output.
I think some more flexibility would be desirable here, if we're going to redesign it. I have researched algorithms that don't use centipawns or depth, so requiring them in the thinking output is bad IMO. Since engines might have more resolution to their scores, floating point would be a good idea. Adding the possibility to specify scores as probabilities or mate-in-N values too. Scores should always be from the engine's POV. PVs should be in a standard format (coordinate or SAN I suppose), so that the GUI can interpret it. Sending time as CPU-time only is a good idea. Since the protocol now supports an arbitrary number of TB types, sending the type of TB hits would be good too.
My proposal would be something like this:
Code: Select all
d=14 sd=26 --> depth, seldepth
t=1:02.35 --> time, self explanatory
mv={f1b5} mv={f1b5 3/30} --> current move, move number (optional)
s=+0.4832 s=+#47 s=57.4% --> score in different units, pawns, mate, and probability respectively
pv={e2e4 c7c5 g1f3} --> pv, self explanatory
tb[nalimov]=4212 --> nalimov tb hits
The engine could send as much or as little as desired, and should just end it with a newline in order to flush the line to the GUI.
4. Multi-Session Time Control
When an engine sends feature xlevel=1 at startup, the GUI will send it a multi-session level command at the beginning of every session.
This is just like the old-style level command, except that it has an arbitrary number of MPS, TC, INC triplets on the same line. The first of these triplets will contain the parameters for the upcoming session. The following parameters will offer the engine a preview of what to expect in subsequent sessions.
Trustful engines could look only at the first three parameters, to know what to expect for the next MPS moves. (The TC will actually be a bit redundant, as it will immediately be superseeded by the following time command.) They will naively fall, however, for "treacherous" time controls like 40/60+100/0:01 (specified by level 40 60 0 100 0:01 0 before move 1 and level 100 0:01 0 before move 41). If the engine wants to be more clever, it can always look ahead, as far into the future as it deems necessary. (I can imagine that after seeing 40/60+20/15+..., it is not terribly interesting to know what will happen in the third session before the second session starts.)
There will be no guarantee that what the engine is told by the GUI is true; the engine should always obey the last level command that is received, even if that contradicts to what was said before. It would be perfectly valid for GUIs to implement a sort of handicap TC mode where the engine suddenly and unexpectedly has to speed up after a certain move, even before the end of he current session. So after receiving level 40 10 0 at the start of the game, promising classical 40/10 repeating TC, the GUI could surprise the engine by a level 0 5 0 command at move 30, forcing the engine to finish the game in 5 min under sudden-death rules. Conducting such games could by useful for certain types of testing, so the protocol should support this possibility.
I think sending level in the middle of a game is just going to cause bugs, even if the behavior is well defined. I don't see it as being too useful anyways.
Also, using only two parameters per session, except the last might be simpler. Or perhaps a delimiter between sessions (semicolon, plus, something). I don't feel too strongly about these points though, since I don't plan on implementing multi-session TCs.
