Null move alterative in endgames

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

Uri Blass
Posts: 10302
Joined: Thu Mar 09, 2006 12:37 am
Location: Tel-Aviv Israel

Re: Null move alterative in endgames

Post by Uri Blass »

I think that it may be interesting also to try something based on this idea not in the endgame.

You start with the reverse move(in case that it is legal) with reduced depth with bigger reduction relative to null move.

If the reverse move works you do not need to try null move.

If the reverse move does not work then you try null move as second move and only if also the null move does not work you try the rest of the moves.

I guess that the idea is not going to work but you can know only if you try it.
lkaufman
Posts: 5960
Joined: Sun Jan 10, 2010 6:15 am
Location: Maryland USA

Re: Null move alterative in endgames

Post by lkaufman »

Uri Blass wrote:I think that it may be interesting also to try something based on this idea not in the endgame.

You start with the reverse move(in case that it is legal) with reduced depth with bigger reduction relative to null move.

If the reverse move works you do not need to try null move.

If the reverse move does not work then you try null move as second move and only if also the null move does not work you try the rest of the moves.

I guess that the idea is not going to work but you can know only if you try it.
I thought of this idea too. I guess the logic is that since the reverse move rule is probably safer than the null move, you can reduce an extra ply or so. It reminds me of the idea of doing two null moves with a bigger reduction. We tried that once but it didn't prove worthwhile. Your idea is probably worth a test, but I'm inclined to expect failure because of the similarity of the reverse move to null move; we would often be doing two tests instead of 1, for a limited gain. But as you say, we won't know unless we try it.
bob
Posts: 20943
Joined: Mon Feb 27, 2006 7:30 pm
Location: Birmingham, AL

Re: Null move alterative in endgames

Post by bob »

lkaufman wrote:
bob wrote:[OK, there is MUCH more to this than there appears to be at first glance.

(1) what if the move two plies earlier was a pawn more or a capture? You can't "unmake" that. Now what?

(2) what if the piece moved two plies earlier was captured by the opponent? You can't "unmake" that. Now what? In fact, the piece moved 2 plies earlier might have been your last piece, and when it was captured, it triggered this new "unmake-move" rather than "a normal null-move" search? The piece is gone and the move can't be unmade.

(3) I try nulls unless there are no pieces left. So moves are either pawn moves which can't be unmade, or else king moves which can not always be "unmade". I move my king, you move a pawn or your king, attacking the square my king was on, I now can't unmake that either. In short, one has to exclude this for any move 2 plies back that moves ANYTHING other than the king, as that is the only thing that can be "reversed" in a K+P position. And not all of those can be unmade as I said.

About all I can think of is to simply "give up" if any of the above are true and do nothing at all? It is a big percentage of the time in just king and pawn endings... Which means most of the time it can't even be done.

Working on trying this right now, but after seeing the exceptions above, I don't expect any gain at all, and now really expect it to lose something because the null-move observation is being totally factored out..

Would seem to me that if this is going to work, it should be done somewhere else. How about reducing a move that "unmakes" the move two plies back, when in a king and pawn endgame. Same effect... done in a more rational and logical way...

The bottom line is that the pseudo-code has to look something like this:

if (pieces_are_left()) { do normal null-move search }
else if (piece_moved_2plies_back == king, and from_2plies_back is not attacked by opponent)
{ Invert from/to on move 2 plies back and make that and do a reduced search exactly as done for null-move}

Working to clean it up and then test while I give a test in my x86 asm class.
Yes, I told Don just to "give up" when the move can't be unmade, such as a pawn move or a king move that would now be illegal. I think that there are generally more king moves than pawn moves in pawn endgames, though I'm not certain. Perhaps close to half the moves will not be eligible for this algorithm. But when no move is eligible, nothing is lost either!
As for reducing unmake moves, this could be done throuout the search, not just in pawn endings. It sounds good, but the problem is that most "unmake" moves (after good ones at least) will have very poor history and will already be near the end of the list and already get heavily reduced, assuming you now use history. If you don't, this might work for you but not for us. But I think it is more logical to do it as suggested in the null move context, because a move and its unmake are the equivalent of two null moves.
Testing for me is done. This had absolutely ZERO effect on Elo...

Crafty-23.5-2 2674 4 4 30000 63% 2567 22%
Crafty-23.5nmm 2673 3 3 60000 63% 2567 22%
Crafty-23.5-1 2672 4 4 30000 63% 2567 21%

I am not sure why my "nnm" version (which had two separate runs) was combined into one, but it made no difference in anything. I will go back after lunch and correct the names in one of the runs to separate them.]

As I observed, if the only thing you can unmake is a king move, and you can't even unmake all of them, I could not see how this would be anything significant at all. It seems to be so...

23.5-1 and 23.5-1 are just two separate 30K tests of the most recent 23.5 version. 23.5nnm is that exact same source, but with the null-move replacement idea in pawn-only endings...

And again, make/unmaking a move is not quite the same thing as making a null-move. It is an extra reduction because you took two plies to play a "null". And many have other considerations, such as can you now allow a "double double-null" (consecutive make/unmake/make/unmake?) And then there is repetition, where if you disable repetition below a null you hurt performance, if you don't disable here, you have an artificial lower bound because of the "draw in hand" your opponent has, etc...

Seems like a lot of ifs, maybes, and effort. And for no return at all based on a quick 60,000 games...
bob
Posts: 20943
Joined: Mon Feb 27, 2006 7:30 pm
Location: Birmingham, AL

Re: Null move alterative in endgames

Post by bob »

lkaufman wrote:
Uri Blass wrote:I think that it may be interesting also to try something based on this idea not in the endgame.

You start with the reverse move(in case that it is legal) with reduced depth with bigger reduction relative to null move.

If the reverse move works you do not need to try null move.

If the reverse move does not work then you try null move as second move and only if also the null move does not work you try the rest of the moves.

I guess that the idea is not going to work but you can know only if you try it.
I thought of this idea too. I guess the logic is that since the reverse move rule is probably safer than the null move, you can reduce an extra ply or so. It reminds me of the idea of doing two null moves with a bigger reduction. We tried that once but it didn't prove worthwhile. Your idea is probably worth a test, but I'm inclined to expect failure because of the similarity of the reverse move to null move; we would often be doing two tests instead of 1, for a limited gain. But as you say, we won't know unless we try it.
It is "safer" but it does not have the same impact. A null does absolutely nothing to help or hurt your position, you just give the opponent time to make two consecutive moves and see if that hurts you or not. If not, you are in a strong position.

Unmaking a move is different. First, if the piece is threatened, you save it. That's not like a null-move at all, as a null never saves any threatened piece. Second, on occasion, just retreating is actually the best move, and that is also not as useful for the "null-move observation."

There might be merit in treating "unmakes" differently, but I don't think it is even remotely comparable to an actual null-move search...
bob
Posts: 20943
Joined: Mon Feb 27, 2006 7:30 pm
Location: Birmingham, AL

Re: Null move alterative in endgames

Post by bob »

marcelk wrote:
lkaufman wrote:
marcelk wrote:Even though I have not truly convinced myself yet that the null move in endgames is really a bad thing for game play, it is something that is useful to disable in specific positions. Your trick can be a nice substitute.
Null move in endgames is not a bad thing for game play. Null move in pawn endings is a bad thing, almost everyone agrees. Are you in doubt about this?
No, I meant endings in general.. I'm conservative currently and disable it when there is at most one slider left. At the time I didn't have a good test method yet and I will revisit it early next year as it can sure be improved. But like others I also have a hard time to believe that nulls could work in pawn-only endings.
Just for the record, a while back I used the "queen or more left, null-ok". Because, as an example, a rook can be zugged by a pair of pawns. A knight can be zugged by a single pawn. In testing, however, I found it significantly better to do null-move until there are zero pieces left, just pawns, then turn it off. That is what I do today. I'd think a bishop is difficult to zug compared to a knight.
bob
Posts: 20943
Joined: Mon Feb 27, 2006 7:30 pm
Location: Birmingham, AL

Re: Null move alterative in endgames

Post by bob »

While waiting on the results of others (and rerunning mine since the name was not quite right and the two runs got combined) I decided to test on a few positions. Seemed like fine 70 would be a good starting point. With normal (no null-move until a pawn promotes) I get this (some snippage):

Code: Select all

               41->   1.46   3.52   1. Kb1 Kb7 2. Kc1 Kc7 3. Kd1 Kd7 4.
                                    Kc2 Kc7 5. Kd3 Kb7 6. Ke3 Kc7 7. Kf3
                                    Kd7 8. Kg3 Ke7 9. Kh4 Kf7 10. Kg5 Kg7
                                    11. Kxf5 Kf7 12. Kg5 Kg7 13. Kh5 Kf7
                                    14. f5 Kf6 15. Kg4 Kf7 16. Kg5 Kg7
                                    17. f6+ Kf8 18. Kg4 Kg8 19. Kf4 Kf8
                                    20. Ke4 Ke8 21. Kf5 Kf7
               42     1.62     +1   1. Kb1!
               42     1.71     +3   1. Kb1!                    
               42     1.95   4.96   1. Kb1 Kb7 2. Kc1 Kc7 3. Kd1 Kd7 4.
                                    Kc2 Kc7 5. Kd3 Kb7 6. Ke3 Kc7 7. Kf3
                                    Kd7 8. Kg3 Ke7 9. Kh4 Kf7 10. Kg5 Kg7
                                    11. Kxf5 Kf7 12. Kg5 Kg7 13. f5 Kf7
                                    14. f6 Kf8 15. Kg4 Kg8 16. Kf4 Kf8
                                    17. Kg5 Kg8 18. Kg6 Kh8 19. Kf5 Kg8
                                    20. Ke6 Kf8 21. Kxd6 Kf7 

...

               43->   2.30   4.97   1. Kb1 Kb7 2. Kc1 Kc7 3. Kd1 Kd7 4.
                                    Kc2 Kc7 5. Kd3 Kb7 6. Ke3 Kc7 7. Kf3
                                    Kd7 8. Kg3 Ke7 9. Kh4 Kf7 10. Kg5 Kg7
                                    11. Kxf5 Kf7 12. Kg5 Kg7 13. f5 Kf7
                                    14. f6 Kf8 15. Kg4 Kg8 16. Kf4 Kf8
                                    17. Kg5 Kg8 18. Kg6 Kh8 19. Kf5 Kg8
                                    20. Ke6 Kf8 21. Kxd6 Kf7 22. Ke5
               44     2.55     +1   1. Kb1!
               44     3.03   6.04   1. Kb1 Kb7 2. Kc1 Kc7 3. Kd1 Kd7 4.
                                    Kc2 Kc7 5. Kd3 Kb7 6. Ke3 Kc7 7. Kf3
                                    Kd7 8. Kg3 Ke7 9. Kh4 Kf7 10. Kg5 Kg7
                                    11. Kxf5 Kf7 12. Kg5 Kg7 13. f5 Kf7
                                    14. f6 Kf8 15. Kg4 Kg8 16. Kf4 Kf8
                                    17. Kg5 Kg8 18. Kg6 Kh8 19. Kf5 Kg8
                                    20. Ke6 Kf8 21. Kxd6 Kf7 22. Ke5 Kf8

...

               45->   3.78   6.25   1. Kb1 Kb7 2. Kc1 Kc7 3. Kd1 Kd7 4.
                                    Kc2 Kc7 5. Kd3 Kb7 6. Ke3 Kc7 7. Kf3
                                    Kd7 8. Kg3 Ke7 9. Kh4 Kf7 10. Kg5 Kg7
                                    11. Kxf5 Kf7 12. Kg5 Kg7 13. f5 Kf7
                                    14. f6 Kf8 15. Kg4 Kg8 16. Kf4 Kf8
                                    17. Kg5 Kf7 18. Kf5 Kf8 19. Ke6 Ke8
                                    20. Kxd6 Kf7 21. Ke5 Kf8 22. Ke6 Ke8
                                    23. f7+ Kf8
               46     4.19     +1   1. Kb1!
               46     4.67     +3   1. Kb1!
               46     7.46     +M   1. Kb1!
               46    10.02   9.96   1. Kb1 Kb7 2. Kc1 Kc7 3. Kd1 Kd7 4.
                                    Kc2 Kc7 5. Kd3 Kb7 6. Ke3 Kc7 7. Kf3
                                    Kd7 8. Kg3 Ke7 9. Kh4 Kf6 10. Kh5 Kf7
                                    11. Kg5 Kg7 12. Kxf5 Kf7 13. Ke4 Kf6
                                    14. Kd3 Kf5 15. Kc4 Kxf4 16. Kb5 Ke4
                                    17. Kc6 Kxd4 18. Kxd6 Kc4 19. Kc6 Kb4
                                    20. d6 Kxa4 21. d7 Kb4 22. d8=Q a4
                                    23. Qf8+ Kb3 24. Qf3+ Kb4 25. Qe4+
                                    Kb3 26. Qd3+ Kb2 27. Qb5+ Ka3
That on my slow laptop, just using one core for repeatability. Notice the fail highs and the final scores...

Then using the new idea which does the "unmake" idea even in pawn endings, I get this.

Code: Select all

               43     0.91     +1   1. Kb1!            
               43     1.12   4.76   1. Kb1 Kb7 2. Kc1 Kc7 3. Kd1 Kd7 4.
                                    Kc2 Kc8 5. Kd2 Kc7 6. Kd3 Kb7 7. Ke3
                                    Kc7 8. Kf3 Kd7 9. Kg3 Ke7 10. Kh4 Kf6
                                    11. Kh5 Kf7 12. Kg5 Kg7 13. Kxf5 Kf7
                                    14. Kg5 Kg7 15. f5 Kf7 16. f6 Kf8 17.
                                    Kg4 Kg8 18. Kf4 Kf8 19. Kg5 Kg8 20.
                                    Kg6 Kh8 21. Kf5 Kg8 22. Ke6

...

               47     3.22     +1   1. Kb1!
               47     4.02   6.07   1. Kb1 Kb7 2. Kc1 Kc7 3. Kd1 Kd7 4.
                                    Kc2 Kc8 5. Kd2 Kc7 6. Kd3 Kb7 7. Ke3
                                    Kc7 8. Kf3 Kd7 9. Kg3 Ke7 10. Kh4 Kf6
                                    11. Kh5 Kf7 12. Kg5 Kg7 13. Kxf5 Kf7
                                    14. Kg5 Kg7 15. f5 Kf7 16. f6 Kf8 17.
                                    Kg4 Kg8 18. Kf4 Kf8 19. Kg5 Kf7 20.
                                    Kf5 Kf8 21. Ke6 Ke8 22. Kxd6 Kf7 23.
                                    Ke5 Kf8 24. Ke6
Get finished quicker, but with a much less accurate score. The intermediate fail highs happen at later depths and I don't see some of them...

Better? Doesn't look so.

other examples are not so starkly different, they show very little speed difference (wac2 to depth=24, for example, same machine). First is normal Crafty, second is new null-move version.

Code: Select all


               23->  13.98  -5.89   1. ... Rxb2 2. Rxb2 c3 3. Rb6+ Ke7
                                    4. Rc6 c2 5. Kf2 d2 6. Rxc2 d1=Q 7.
                                    Rc7+ Kd6 8. Rxh7 Qd2+ 9. Kf3 Qd5+ 10.
                                    Kf2 Qa2+ 11. Kf3 Qxa3 12. Rh6+ Kd5
                                    13. Rh7 Qa1 14. Rd7+ Kc5 15. Rc7+ Kd6
                                    16. Ra7 Qf1+ 17. Kg3
               24    28.86  -6.01   1. ... Rxb2 2. Rxb2 c3 3. Rb6+ Ke7
                                    4. Rc6 c2 5. Kf2 d2 6. Rxc2 d1=Q 7.
                                    Rc7+ Kd6 8. Rxh7 Qd2+ 9. Kf3 Qd5+ 10.
                                    Kf2 Qa2+ 11. Kf3 Qxa3 12. Ra7 Qd3 13.
                                    Kf2 a3 14. h4 Qd2+ 15. Kf3 Qd1+ 16.
                                    Kf2 Qd2+ 17. Kf3 Qd5+ 18. Ke2
               24->  29.65  -6.01   1. ... Rxb2 2. Rxb2 c3 3. Rb6+ Ke7
                                    4. Rc6 c2 5. Kf2 d2 6. Rxc2 d1=Q 7.
                                    Rc7+ Kd6 8. Rxh7 Qd2+ 9. Kf3 Qd5+ 10.
                                    Kf2 Qa2+ 11. Kf3 Qxa3 12. Ra7 Qd3 13.
                                    Kf2 a3 14. h4 Qd2+ 15. Kf3 Qd1+ 16.
                                    Kf2 Qd2+ 17. Kf3 Qd5+ 18. Ke2



               23->  13.75  -5.89   1. ... Rxb2 2. Rxb2 c3 3. Rb6+ Ke7
                                    4. Rc6 c2 5. Kf2 d2 6. Rxc2 d1=Q 7.
                                    Rc7+ Kd6 8. Rxh7 Qd2+ 9. Kf3 Qd5+ 10.
                                    Kf2 Qa2+ 11. Kf3 Qxa3 12. Rh8 Qb2 13.
                                    Rh7 Qb1 14. Ra7 Qf1+ 15. Kg3 Qe1+ 16.
                                    Kf3 Qh1+ 17. Kg3
               24    27.83  -6.01   1. ... Rxb2 2. Rxb2 c3 3. Rb6+ Ke7
                                    4. Rc6 c2 5. Kf2 d2 6. Rxc2 d1=Q 7.
                                    Rc7+ Kd6 8. Rxh7 Qd2+ 9. Kf3 Qd5+ 10.
                                    Kf2 Qa2+ 11. Kf3 Qxa3 12. Ra7 Qd3 13.
                                    Kf2 a3 14. h4 Qd2+ 15. Kf3 Qd1+ 16.
                                    Kf2 Qd2+ 17. Kf3 Qd5+ 18. Ke2
               24->   1:02  -6.01   1. ... Rxb2 2. Rxb2 c3 3. Rb6+ Ke7
                                    4. Rc6 c2 5. Kf2 d2 6. Rxc2 d1=Q 7.
                                    Rc7+ Kd6 8. Rxh7 Qd2+ 9. Kf3 Qd5+ 10.
                                    Kf2 Qa2+ 11. Kf3 Qxa3 12. Ra7 Qd3 13.
                                    Kf2 a3 14. h4 Qd2+ 15. Kf3 Qd1+ 16.
                                    Kf2 Qd2+ 17. Kf3 Qd5+ 18. Ke2
Fairly close until something happens in depth=24 to make the newer version search a larger tree...
lkaufman
Posts: 5960
Joined: Sun Jan 10, 2010 6:15 am
Location: Maryland USA

Re: Null move alterative in endgames

Post by lkaufman »

bob wrote:Testing for me is done. This had absolutely ZERO effect on Elo...

Crafty-23.5-2 2674 4 4 30000 63% 2567 22%
Crafty-23.5nmm 2673 3 3 60000 63% 2567 22%
Crafty-23.5-1 2672 4 4 30000 63% 2567 21%

I am not sure why my "nnm" version (which had two separate runs) was combined into one, but it made no difference in anything. I will go back after lunch and correct the names in one of the runs to separate them.]

As I observed, if the only thing you can unmake is a king move, and you can't even unmake all of them, I could not see how this would be anything significant at all. It seems to be so...

23.5-1 and 23.5-1 are just two separate 30K tests of the most recent 23.5 version. 23.5nnm is that exact same source, but with the null-move replacement idea in pawn-only endings...

And again, make/unmaking a move is not quite the same thing as making a null-move. It is an extra reduction because you took two plies to play a "null". And many have other considerations, such as can you now allow a "double double-null" (consecutive make/unmake/make/unmake?) And then there is repetition, where if you disable repetition below a null you hurt performance, if you don't disable here, you have an artificial lower bound because of the "draw in hand" your opponent has, etc...

Seems like a lot of ifs, maybes, and effort. And for no return at all based on a quick 60,000 games...
Our results were similar. At fixed depths of 8,9, and 10 ply the node reduction averaged about 0.2%, with elo effect so close to zero to be meaningless. Whether the elo loss is tiny enough to accept for 0.2% is of course impossible to determine practically, it would take about a million games. If we made a database of just pawn endings we could probably determine if it helps or not, but since the overall effect is plus or minus a tiny fraction of an elo point it's not worth our time to do this. Maybe your idea of just reducing such moves is worth a try.
bob
Posts: 20943
Joined: Mon Feb 27, 2006 7:30 pm
Location: Birmingham, AL

Re: Null move alterative in endgames

Post by bob »

lkaufman wrote:
bob wrote:Testing for me is done. This had absolutely ZERO effect on Elo...

Crafty-23.5-2 2674 4 4 30000 63% 2567 22%
Crafty-23.5nmm 2673 3 3 60000 63% 2567 22%
Crafty-23.5-1 2672 4 4 30000 63% 2567 21%

I am not sure why my "nnm" version (which had two separate runs) was combined into one, but it made no difference in anything. I will go back after lunch and correct the names in one of the runs to separate them.]

As I observed, if the only thing you can unmake is a king move, and you can't even unmake all of them, I could not see how this would be anything significant at all. It seems to be so...

23.5-1 and 23.5-1 are just two separate 30K tests of the most recent 23.5 version. 23.5nnm is that exact same source, but with the null-move replacement idea in pawn-only endings...

And again, make/unmaking a move is not quite the same thing as making a null-move. It is an extra reduction because you took two plies to play a "null". And many have other considerations, such as can you now allow a "double double-null" (consecutive make/unmake/make/unmake?) And then there is repetition, where if you disable repetition below a null you hurt performance, if you don't disable here, you have an artificial lower bound because of the "draw in hand" your opponent has, etc...

Seems like a lot of ifs, maybes, and effort. And for no return at all based on a quick 60,000 games...
Our results were similar. At fixed depths of 8,9, and 10 ply the node reduction averaged about 0.2%, with elo effect so close to zero to be meaningless. Whether the elo loss is tiny enough to accept for 0.2% is of course impossible to determine practically, it would take about a million games. If we made a database of just pawn endings we could probably determine if it helps or not, but since the overall effect is plus or minus a tiny fraction of an elo point it's not worth our time to do this. Maybe your idea of just reducing such moves is worth a try.
Do you guys do the same with null-move as I do? IE only shut 'em off when all pieces are gone? I have not (yet) tested to see what might happen with turning null-move off a bit earlier and then relying on this a little heavier. Certainly with just king and pawns, there is little opportunity to use this trick since it only applies to some of the king moves but not all. And only when you reach pieceless endings, where most games are already resolved, result-wise.
lkaufman
Posts: 5960
Joined: Sun Jan 10, 2010 6:15 am
Location: Maryland USA

Re: Null move alterative in endgames

Post by lkaufman »

[quote="bobDo you guys do the same with null-move as I do? IE only shut 'em off when all pieces are gone? I have not (yet) tested to see what might happen with turning null-move off a bit earlier and then relying on this a little heavier. Certainly with just king and pawns, there is little opportunity to use this trick since it only applies to some of the king moves but not all. And only when you reach pieceless endings, where most games are already resolved, result-wise.[/quote]

Yes, we also shut off null-move only in pawn endings. Today we tried what you suggest, turning null-move off a bit earlier in favor of this reversed move idea. When I tried it in all endings with one minor piece each or less, the result was negative. When I tried it only in knight endings (and the pawn endings), the results were mixed; overall a tiny elo gain at fixed depth for a tiny node increase. As is often the case, it will probably be too difficult to measure whether this is an improvement or not, but perhaps I'll try.
jwes
Posts: 778
Joined: Sat Jul 01, 2006 7:11 am

Re: Null move alterative in endgames

Post by jwes »

bob wrote:
lkaufman wrote:
bob wrote:[OK, there is MUCH more to this than there appears to be at first glance.

(1) what if the move two plies earlier was a pawn more or a capture? You can't "unmake" that. Now what?

(2) what if the piece moved two plies earlier was captured by the opponent? You can't "unmake" that. Now what? In fact, the piece moved 2 plies earlier might have been your last piece, and when it was captured, it triggered this new "unmake-move" rather than "a normal null-move" search? The piece is gone and the move can't be unmade.

(3) I try nulls unless there are no pieces left. So moves are either pawn moves which can't be unmade, or else king moves which can not always be "unmade". I move my king, you move a pawn or your king, attacking the square my king was on, I now can't unmake that either. In short, one has to exclude this for any move 2 plies back that moves ANYTHING other than the king, as that is the only thing that can be "reversed" in a K+P position. And not all of those can be unmade as I said.

About all I can think of is to simply "give up" if any of the above are true and do nothing at all? It is a big percentage of the time in just king and pawn endings... Which means most of the time it can't even be done.

Working on trying this right now, but after seeing the exceptions above, I don't expect any gain at all, and now really expect it to lose something because the null-move observation is being totally factored out..

Would seem to me that if this is going to work, it should be done somewhere else. How about reducing a move that "unmakes" the move two plies back, when in a king and pawn endgame. Same effect... done in a more rational and logical way...

The bottom line is that the pseudo-code has to look something like this:

if (pieces_are_left()) { do normal null-move search }
else if (piece_moved_2plies_back == king, and from_2plies_back is not attacked by opponent)
{ Invert from/to on move 2 plies back and make that and do a reduced search exactly as done for null-move}

Working to clean it up and then test while I give a test in my x86 asm class.
Yes, I told Don just to "give up" when the move can't be unmade, such as a pawn move or a king move that would now be illegal. I think that there are generally more king moves than pawn moves in pawn endgames, though I'm not certain. Perhaps close to half the moves will not be eligible for this algorithm. But when no move is eligible, nothing is lost either!
As for reducing unmake moves, this could be done throuout the search, not just in pawn endings. It sounds good, but the problem is that most "unmake" moves (after good ones at least) will have very poor history and will already be near the end of the list and already get heavily reduced, assuming you now use history. If you don't, this might work for you but not for us. But I think it is more logical to do it as suggested in the null move context, because a move and its unmake are the equivalent of two null moves.
Testing for me is done. This had absolutely ZERO effect on Elo...

Crafty-23.5-2 2674 4 4 30000 63% 2567 22%
Crafty-23.5nmm 2673 3 3 60000 63% 2567 22%
Crafty-23.5-1 2672 4 4 30000 63% 2567 21%

I am not sure why my "nnm" version (which had two separate runs) was combined into one, but it made no difference in anything. I will go back after lunch and correct the names in one of the runs to separate them.]

As I observed, if the only thing you can unmake is a king move, and you can't even unmake all of them, I could not see how this would be anything significant at all. It seems to be so...

23.5-1 and 23.5-1 are just two separate 30K tests of the most recent 23.5 version. 23.5nnm is that exact same source, but with the null-move replacement idea in pawn-only endings...

And again, make/unmaking a move is not quite the same thing as making a null-move. It is an extra reduction because you took two plies to play a "null". And many have other considerations, such as can you now allow a "double double-null" (consecutive make/unmake/make/unmake?) And then there is repetition, where if you disable repetition below a null you hurt performance, if you don't disable here, you have an artificial lower bound because of the "draw in hand" your opponent has, etc...

Seems like a lot of ifs, maybes, and effort. And for no return at all based on a quick 60,000 games...
It might be interesting to insert counters to see how often the new code is executed. One consequence of your testing methodology is that a change that makes a significant difference in relatively rare situations may well not be recognized as clearly better. Another way to estimate the possible size of the change is to test regular null move in pawn endings and see how many elo worse it is (you may have already done this at some time).