Visual Prolog - 迷宫问题

发布于 2024-11-18 00:10:49 字数 1481 浏览 3 评论 0原文

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

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.

这个谓词有效并返回:

开玩笑:feba

开玩笑:fedcba

这是房间列表,我必须从 a 传递到 f。 跑步():- stdio::write("\nDroga zf 做一个"), R_list=["f"], 去(“f”,“a”,R_list), 失败。 但这一次,什么也没返回。正如您可能注意到的,这与之前的情况正好相反。

I have defined list of doors in rooms:

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").

And some Predicates:

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).

And I'm looking for a way from room to room:

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

This predicate works and return:

Jest droga:feba

Jest droga:fedcba

Which is list of rooms, that I must pass the from a to f.
run():-
stdio::write("\nDroga z f do a"),
R_list=["f"],
go("f", "a", R_list),
fail.
But this one, returns nothing. And As you may notice it's just reverse of the previous case.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

木有鱼丸 2024-11-25 00:10:49

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

door(A, B) 这里是从 AB 的有向边
您定义中的 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)) 检查房间是否有“bomba”

This question smells a lot like homework. You should tag it appropriately.

door(A, B) here is a directed edge from A to B
door(A, B) in your definition does not also imply door(B, A)

In fact, f doesn't lead to any other rooms. It's a dead end, more or less.

Disclaimer: I'm not sure if there's a better way than the way I'm suggesting.
Also, I'm not positively sure path is written correctly, as I can't test it right now.

You could build a new rule like so:

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

But you still have to watch out for cycles. You can avoid cycles by tracking visited rooms.

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

Of course, this is also assuming there are no self edges, like door(A, A). If that's already implied, great. But you can also check for that, if you wanted to.

This isn't directly related to the question, but you can check if a room has a 'bomba' with not(skarb("bomba",A))

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文