Я читаю книгу Thinking as Computation и написал код в главе 9.4:
plan(L) :-
initial_state(I),
goal_state(G),
reachable(I, L, G).
initial_state([]).
legal_move(S, A, [A | S]) :-
poss(A, S).
goal_state(S) :-
has_bananas(S).
reachable(S, [], S).
reachable(S1, [M | L], S3) :-
legal_move(S1, M, S2),
reachable(S2, L, S3).
location(box, loc3, []).
location(box, L, [push(L) | _]).
location(box, L, [A | S]) :-
\+ A = push(L),
location(box, L, S).
location(bananas, loc1, _).
location(monkey, loc2, []).
location(monkey, L, [push(L) | _]).
location(monkey, L, [go(L) | _]).
location(monkey, L, [climb_off | S]) :-
location(monkey, L, S).
location(monkey, L, [A | S]) :-
\+ A = push(_), \+ A = go(_), location(monkey, L, S).
on_box([climb_on | _]).
on_box([A | S]) :- \+ A = climb_off, on_box(S).
has_bananas([grab | S]) .
has_bananas([_ | S]) :- has_bananas(S).
poss(climb_off, S) :- on_box(S).
poss(go(_), S) :- \+ on_box(S).
poss(grab, S) :-
on_box(S), location(box, L, S), location(bananas, L, S).
poss(push(_), S) :- poss(climb_on, S).
poss(climb_on, S) :-
\+ on_box(S), location(box, L, S), location(monkey, L, S).
Но я обнаружил, что программа никогда не останавливается... После вывода информации о стеке я обнаружил, что goal_state
генерирует списки бесконечной длины. Я пытался ограничить длину списков в has_banana
has_bananas([grab | S], N) :- length(S, NS), NS is N - 1.
has_bananas([_ | S], N) :- \+ N = 0, has_bananas(S, N - 1).
который N
относится к длине L
в plan(L)
(например, N
равно 4 при запросе plan([M1, M2, M3, M4])
). Но это не работает.
Есть ли решение?
has_bananas/1
генерирует списки, в которых есть один экземплярgrab
, а остальные являются анонимными, неинстантированными переменными и неконкретным хвостом. Это то, что вы хотите, чтобы этот предикат делал? - person lurker   schedule 22.03.2016N = 4
, не так ли? - person false   schedule 23.03.2016