λProlog гипотетическое рассуждение Крестики-нолики
λProlog использует гипотетические рассуждения . Используя оператор (=>)/2, мы можем временно утвердить некоторое предложение. Можно ли это использовать для реализации состязательного поиска в λProlog?
Думал об игре в крестики-нолики. Вместо того, чтобы начинать с фактов ячейки/3, которые заполнены до нуля, мы могли бы также просто начать вообще без фактов ячейки/3.
Затем каждый игрок делает ход, добавляя факты в клетку/3. Любые соответствующие реализации вокруг? Я предполагаю, что они будут адаптациями этого кода здесь .
После двух перемещений база данных может выглядеть так:
cell(2, 2, x).
cell(1, 1, o).
1 ответ
Получается, что для поиска игры нам нужен только частный случай гипотетического рассуждения, который можно реализовать на чистом Прологе. Давайте используем оператор (-:)/2 для гипотетических рассуждений, тогда у нас есть это правило вывода:
Γ, F |- G
-------------
Γ |- F -: G
Таким образом, словесно решить подцель F -: G, факт F добавляется в базу данных Γ, а затем проверяется подцель G. Что сложного в том, что для каждого успеха G факт F должен снова исчезнуть из базы данных, потому что то, что доказано, отсутствует в базе данных.
Частный случай, который мы рассматриваем, состоит в том, что G детерминистична. То есть G либо удается один раз, либо терпит неудачу. В настоящее время мы также не принимаем исключения или F без заземления. При этих предположениях гипотетические рассуждения могут быть реализованы следующим образом:
:- op(1200, xfx, -:).
(F -: G) :-
assertz(F),
G, !,
retract(F).
(F -: _) :-
retract(F), fail.
Теперь можно переписать отсюда предикат ход/3 в предикат ход/2, который предлагает новый факт F. Основная процедура поиска состязательности читается следующим образом, где мы также соответственно изменили предикат выигрыш/2 и ничья/2. в win/1 и tie/1, чтобы проверить ячейку динамических фактов/3:
best(P, F) :-
move(P, F),
(F -:
( win(P) -> true
; other(P, Q),
\+ tie(Q),
\+ best(Q, _))).
Вот некоторые результаты. У первого хода нет выигрышной стратегии:
?- best(x, F).
false.
Если доска
[[x, -, o], [x, -, -], [o, -, -]]
игрок
x
имеет выигрышную стратегию:
?- (cell(1,1,x) -: (cell(3,1,o) -: (cell(1,2,x) -: (cell(1,3,o) -: best(x, F))))).
F = cell(2, 2, x).
Насколько эффективен assertz/retract по сравнению с игровым состоянием термина Prolog? ок. в 3 раза медленнее:
?- time(best(x, F)).
% 478,598 inferences, 0.094 CPU in 0.094 seconds (100% CPU, 5105045 Lips)
false.
Открытый исходный код:
Частный случай гипотетического рассуждения
https://gist.github.com/jburse/279b6280ab4311de456e458a7386c1da#file-hypo-pl
Код пролога для игры в крестики-нолики
Поиск мин-макс через отрицание
Игровая доска через факты
пролога