Визуальный пролог - проблема лабиринта - PullRequest
1 голос
/ 30 июня 2011

Я определил список дверей в комнатах:

class facts
door : (string Room1, string Room2).
skarb : (string Skarb, string Room).

class predicates
go : (string Room1, string Room2, string* R_list) nondeterm anyflow.
is_Member : (string Room, string* R_list) nondeterm .
write_list : (string* R_list) nondeterm .
    clauses
door("a", "b"). 
door("b", "e"). 
door("b", "c"). 
door("d", "e"). 
door("c", "d").
door("e", "f").
door("g", "e").
door("g", "a").
door("h", "b").
door("h", "a").
door("h", "f").
door("i", "b").
door("i", "h").
door("i", "c").
door("i", "k").
skarb("bomba", "d").

И некоторые предикаты:

go(Room, Room, R_list) :- stdio::write("\n\nJest droga:"), write_list(R_list), !.
go(Room1, Room2, R_list) :- door(Room1, X), not(is_Member(X, R_list)), go(X, Room2, [X | R_list]).

go(Room1, Room2, R_list) :- door(X, Room1), not(is_Member(X, R_list)), go(Room2, X, [X | R_list]).

is_Member(Room, [Room | _]) :- !. is_Member(Room, [_ | Tail]) :- is_Member(Room, Tail).

write_list([]) :- !.
write_list([Head | Tail]) :- stdio::write( Head), write_list(Tail).

И я ищу путь из комнаты в комнату:

run():-
stdio::write("\nDroga z a do f"),
R_list=["a"],
go("a", "f", R_list),
fail.

Этот предикат работает и возвращает:

Jest droga: feba

Jest droga: fedcba

Какой список комнат,что я должен передать от а до ф.run (): - stdio :: write ("\ nDroga zf do a"), R_list = ["f"], go ("f", "a", R_list), сбой.Но этот ничего не возвращает.И, как вы можете заметить, это просто обратная сторона предыдущего случая.

1 Ответ

1 голос
/ 30 июня 2011

Этот вопрос очень похож на домашнюю работу.Вы должны пометить его соответствующим образом.

door(A, B) здесь направленное ребро от A до B door(A, B) в вашем определении также не означает door(B, A)

На самом делее не приводит ни к каким другим комнатам.Это тупик, более или менее.

Отказ от ответственности: я не уверен, есть ли лучший способ, чем тот, который я предлагаю.Кроме того, я не уверен, что path написано правильно, поскольку я не могу проверить это прямо сейчас.

Вы можете построить новое правило, например, так:

reversible_door(A,B):- door(A,B).
reversible_door(A,B):- door(B,A).

НоВы все еще должны следить за циклами.Вы можете избежать циклов, отслеживая посещенные комнаты.

path(A,B,_):- reversible_door(A,B).
path(A,B,Nodes):- reversible_door(A,X), 
                  not(member(X,Nodes)), 
                  path(X,B,[A|Nodes]).

Конечно, это также предполагает, что нет собственных краев, как door(A, A). Если это уже подразумевается, отлично.Но вы также можете проверить это, если хотите.

Это не имеет прямого отношения к вопросу, но вы можете проверить, есть ли в комнате «бомба» с not(skarb("bomba",A))

...