我的出发点是 Prolog Tic-Tac-Toe tictac.p,链接在帖子末尾。但我没有使用 tnot/1,只有 table/1 指令。首先,我们必须小心添加正确的表格。
因此,下面首先添加 table/1 指令是无稽之谈,因为在作为失败元参数的否定中递归调用 best/3 具有隐式存在量词。第三个参数将使 best/3 不确定
并炸毁桌子:
:- table best/3.
best(X, P, Y) :-
move(X, P, Y),
(win(Y, P) -> true;
other(P, Q),
\+ tie(Y, Q),
\+ best(Y, Q, _)).
更好的方法是只采用 best/3 的第一个解决方案
一个新的谓词 best/2。这不会改变否定的结果
作为失败。然后将这个新谓词表最好/2:
:- table best/2.
best(X, P) :-
best(X, P, _), !.
best(X, P, Y) :-
move(X, P, Y),
(win(Y, P) -> true;
other(P, Q),
\+ tie(Y, Q),
\+ best(Y, Q)).
有趣的发现,SWI-Prolog 否定,因为失败要快得多
比我的,但它被一些开销所困扰,因为当
切换到桌面它不能加快游戏搜索。曾是
比较 Prolog 文本 tictac.p 和 tictac2.pl:
/* SWI-Prolog 8.3.19 */
?- time((between(1,50,_), tictac, fail; true)).
% 5,087,251 inferences, 1.034 CPU in 1.044 seconds (99% CPU, 4920224 Lips)
true.
?- time((between(1,50,_), abolish_all_tables, tictac, fail; true)).
% 4,472,251 inferences, 1.343 CPU in 1.426 seconds (94% CPU, 3329897 Lips)
true.
另一方面,我得到了一个 ca。两倍加速:
/* Jekejeke Prolog 1.4.7 */
?- time((between(1,50,_), tictac, fail; true)).
% Up 3,218 ms, GC 10 ms, Threads 3,201 ms (Current 02/14/21 01:04:15)
Yes
?- time((between(1,50,_), retractall_table(_), tictac, fail; true)).
% Up 1,703 ms, GC 11 ms, Threads 1,688 ms (Current 02/14/21 01:06:50)
Yes
开源:
井字游戏不打牌
https://github.com/jburse/jekejeke-samples/blob/master/jekrun/benchmark/tests/tictac.p
井字游戏与桌面游戏
https://gist.github.com/jburse/713b6ad2b7e28de89fe51b98be3d0943#file-tictac2-pl