Проблема лабиринта Prolog: код дает бесконечные пути от начала до конца и не возвращается - PullRequest
0 голосов
/ 07 января 2019

Я пытаюсь найти лабиринт в Прологе с помощью возврата.

Моя проблема в том, что когда я запускаю программу, она запускается правильно в первый раз, но после этого она принимает конечную позицию в качестве начальной позиции и продолжает находить пути оттуда, следовательно, идет в бесконечный цикл. Это работает правильно, когда путь не существует между двумя позициями. Я перепробовал много вещей, но, похоже, ничего не работает. Вот мой код:

path(Dest, Dest, _, [], _) :- !.

path([Row0,Col0],[Row1,Col1],M,Path,1) :-
    next_move([Row0,Col0],[Rnew,Cnew]),
    is_available(Rnew, Cnew,Ret),

    write(Rnew),
    write(Cnew),

    not(member([Rnew, Cnew], M)),
    path([Rnew, Cnew], [Row1, Col1], [[Rnew,Cnew]|M], Path, Ret).

path([X0,Y0], [X1,Y1], [[X0,Y0]|M], [[X,Y]|Path], 0) :-
    path([X,Y],[X1,Y1],M,Path,1).

Пример вывода:

?- solves([1,1],[1,7],P).
P = [[1, 2], [1, 3], [1, 4], [1, 5], [1, 6], [1, 7]] ;
P = [[1, 2], [1, 3], [1, 4], [1, 5], [1, 6], [2, 6], [2, 7], [2|...], 
    [...|...]|...] ;
P = [[1, 2], [1, 3], [1, 4], [1, 5], [1, 6], [2, 6], [2, 7], [2|...], 
    [...|...]|...] ;
P = [[1, 2], [1, 3], [1, 4], [1, 5], [1, 6], [2, 6], [2, 7], [2|...], 
    [...|...]|...] .

При выполнении программы она должна отображать все пути, если путь существует между двумя позициями. В противном случае он должен вернуть false. Как вы можете видеть выше, мой код идет в бесконечный цикл и продолжает генерировать пути.

Пожалуйста, помогите, поскольку я не очень опытен в Прологе. Спасибо.

Ответы [ 2 ]

0 голосов
/ 12 января 2019

Ха, здесь есть немало иронии, что я даже видел этот пост - ты на курсе PPL? :)

Обычно возвращать значение 0 или 1, чтобы сказать, является ли утверждение истинным или ложным, не нужно в прологе - это неявно в том, прошел ли предикат.

Например is_available (Rnew, Cnew, Ret) лучше было бы записать как is_available (Rnew, Cnew) - если is_available преобразуется в false, то он уже остановился бы и начал возвращаться к поиску других решений вдоль альтернативных строк, если альтернативы не было.

Кроме того, это будет означать, что если решения не существует, при попытке оценить лабиринт будет напечатано значение «ложь».

По вашим выходным проблемам - на самом деле это не «сломано»; это просто подавленный вывод! Попробуйте запустить это в своем SWI-терминале, прежде чем запускать выражение для решения лабиринта:

set_prolog_flag (answer_write_options, [max_depth (0)]).

согласно SWI-Пролог, как отобразить весь ответ (список)?

0 голосов
/ 07 января 2019

Первое предложение предиката path/5 и рекурсивный вызов во втором предложении неверны. Должно быть:

path(Dest, Dest, _, [], _) :- !.

path([Row0,Col0],[Row1,Col1],M,[[Rnew,Cnew]|Path],1) :-
    next_move([Row0,Col0],[Rnew,Cnew]),
    is_available(Rnew, Cnew,Ret),

    write(Rnew),
    write(Cnew),

    \+ member([Rnew, Cnew], M),
    path([Rnew, Cnew], [Row1, Col1], [[Rnew,Cnew]|M], Path, Ret).

Кроме того, используйте стандартный предикат ISO Prolog \+/1 вместо устаревшего предиката not/1.

...