1

我已经定义了房间门的列表:

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

这是房间列表,我必须将其从 a 传递到 f。run():- stdio::write("\nDroga zf do a"), R_list=["f"], go("f", "a", R_list), 失败。但是这个,一无所获。而且您可能会注意到,这与前一种情况正好相反。

4

1 回答 1

1

这个问题闻起来很像家庭作业。您应该适当地标记它。

door(A, B)A这是您定义中从到的有向边B door(A, B)并不意味着door(B, A)

事实上, f 不会导致任何其他房间。这是一个死胡同,或多或少。

免责声明:我不确定是否有比我建议的方式更好的方法。另外,我不确定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))

于 2011-06-30T10:07:33.173 回答