Построение списка в Прологе - PullRequest
2 голосов
/ 09 декабря 2011

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

puzzle(Size,start(StartX,StartY),goal(GoalX,GoalY),Clues,Path) :-
  solve(Size,StartX,StartY,XX,YY,Turns,Clues,GoalX,GoalY,[field(StartX,StartY)],Path).

solve(Size,X,Y,XX,YY,Turns,Clues,GoalX,GoalY,Visited,Path) :-
  X=GoalX, Y=GoalY,!;     
  Turns == 0, neighbor(X,Y,XX,YY), append(link(X,Y,XX,YY),Path,Newpath), solve(Size,XX,YY,XXX,YYY,Turns,Clues,GoalX,GoalY,Visited,Newpath);
  Turns > 1, turn(X,Y,XX,YY), append(link(X,Y,XX,YY), Path, Newpath), solve(Size,XX,YY,XXX,YYY,Turns,Clues,GoalX,GoalY,Visited,Newpath).

Я создаю путь, рекурсивно вызывая функцию решения и добавляя определенное действие к пути с каждым новым вызовом до достижения цели.Теперь моя проблема в том, что последний рекурсивный вызов имеет путь, который я ищу, однако, если я спрашиваю

?- puzzle(3, start(1,1), goal(3,3), [clue(2,1,2),clue(2,2,2)],Path)

, он не возвращает этот путь.Для иллюстрации:

   Exit: (13) solve(3, 3, 2, 0, 1, _G1027, _G1028, 1, 0, 1, [clue(2, 2, 2)], 3, 3, [feld(3, 2), feld(3, 1), feld(2, 1), feld(1, 1)], [link(3, 1, 3, 2), link(2, 1, 3, 1), link(1, 1, 2, 1), _G1012]) ? creep

[ссылка (3, 1, 3, 2), ссылка (2, 1, 3, 1), ссылка (1, 1, 2, 1), _G1012] - этопуть, который мне нужен.

   Exit: (12) move2(3, 3, 1, 1, 0, _G1027, _G1028, 1, 0, 2, [clue(2, 2, 2)], 3, 3, [feld(3, 1), feld(2, 1), feld(1, 1)], [link(2, 1, 3, 1), link(1, 1, 2, 1), _G1012]) ? creep
   Exit: (11) solve(3, 3, 1, 1, 0, _G1027, _G1028, _G1029, _G1030, 2, [clue(2, 2, 2)], 3, 3, [feld(3, 1), feld(2, 1), feld(1, 1)], [link(2, 1, 3, 1), link(1, 1, 2, 1), _G1012]) ? creep
   Exit: (10) stepfromclue(3, 2, 1, 1, 0, 2, [clue(2, 2, 2)], 3, 3, [feld(2, 1), feld(1, 1)], [link(1, 1, 2, 1), _G1012]) ? creep
   Exit: (9) checkclue(3, 2, 1, 1, 0, [clue(2, 1, 2), clue(2, 2, 2)], 3, 3, [feld(2, 1), feld(1, 1)], [link(1, 1, 2, 1), _G1012]) ? creep
   Exit: (8) solve(3, 1, 1, 1, 0, 2, 1, _G1029, _G1030, 0, [clue(2, 1, 2), clue(2, 2, 2)], 3, 3, [feld(1, 1)], [_G1012]) ? creep
   Exit: (7) puzzle(3, start(1, 1), goal(3, 3), [clue(2, 1, 2), clue(2, 2, 2)], [_G1012]) ? creep
   Exit: (6) puzzle(1, [_G1012]) ? creep

Path = [_G1012] - это путь, который я получаю.Я серьезно не могу понять, как я могу «попросить» путь, который мне нужен, не переписывая программу полностью.

1 Ответ

0 голосов
/ 09 декабря 2011

Не видя полного кода (включая факты link/4), довольно сложно догадаться, так как я не могу самостоятельно отследить программу.Но я думаю, что проблема заключается в следующем:

То, что вы пытаетесь сделать, это итеративно построить путь, добавляя ссылки на путь, создавая новый путь в переменной NewPath:

append(link(X,Y,XX,YY),Path,Newpath),

Здесь есть две проблемы.Во-первых, link(X,Y,XX,YY) не является списком, поэтому append/3 не удастся.Второе, более важное, это то, что Path является входной переменной, NewPath выходной, но вы передаете NewPath только до следующего вызова solve/11, но не вверх.Таким образом, полный путь никогда не передается вызывающей стороне.Таким образом, на уровне вызова puzzle/5 переменная Path остается необработанной.

Ваш код для solve, вероятно, должен выглядеть примерно так:

solve(_,X,Y,_,_,_,_,GoalX,GoalY,_,Path,Path) :-
    X=GoalX, Y=GoalY,!.
solve(Size,X,Y,XX,YY,Turns,Clues,GoalX,GoalY,Visited,PathIn,Path) :-
    Turns == 0, 
    neighbor(X,Y,XX,YY), 
    append(PathIn,[link(X,Y,XX,YY)],PathOut), 
    solve(Size,XX,YY,XXX,YYY,Turns,Clues,GoalX,GoalY,Visited,PathOut,Path).
solve(Size,X,Y,XX,YY,Turns,Clues,GoalX,GoalY,Visited,PathIn,Path) :-
    turn(X,Y,XX,YY), 
    append(PathIn,[link(X,Y,XX,YY)],PathOut), 
    solve(Size,XX,YY,XXX,YYY,Turns,Clues,GoalX,GoalY,Visited,PathOut,Path).

Itможно было бы упростить и дальше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...