如果我有以下谓词门,它声明两个房间之间有一扇门:
door(office, hall).
door(kitchen, office).
door(hall, "dining room").
door(kitchen, cellar).
door("dining room", kitchen).
谓词门户,它声明了一扇门的状态:
doorstate(hall, office, closed).
doorstate(hall, "dining room", opened).
doorstate("dining room", kitchen, opened).
doorstate(kitchen, office, opened).
doorstate(kitchen, cellar, opened).
如果两个房间之间的所有门都打开,那么两个房间之间就有一条通道。
如何编写规则以发现两个房间之间是否有这样的路径?
答案 0 :(得分:5)
prolog的可怕恐怖回归太快了。
wayopen(Room1,Room2) :- doorstate(Room1, Room2, opened).
wayopen(Room1,Room2) :- doorstate(Room1, RoomX, opened), wayopen(RoomX,Room2).
所以我不只是为你做功课,这里是如何理解它:
请注意,这些规则只能在一个方向上通过门。 你的作业是让它在两个方向都有效。
我们从哪里可以到达大厅?
?- wayopen(hall, X).
X = diningroom ;
X = kitchen ;
X = office ;
X = cellar ;
false.
以下是您可以从中获取的所有房间:
?- wayopen(Room1,Room2).
Room1 = hall,
Room2 = diningroom ;
Room1 = diningroom,
Room2 = kitchen ;
Room1 = kitchen,
Room2 = office ;
Room1 = kitchen,
Room2 = cellar ;
Room1 = hall,
Room2 = kitchen ;
Room1 = hall,
Room2 = office ;
Room1 = hall,
Room2 = cellar ;
Room1 = diningroom,
Room2 = office ;
Room1 = diningroom,
Room2 = cellar ;
false.
答案 1 :(得分:1)
您需要描述一个对称且可传递的关系(exists_way/2
)。
% Base cases
exists_way_(hall, 'dining room').
exists_way_('dining room', kitchen).
exists_way_(kitchen, office).
exists_way_(kitchen, cellar).
% Symmetric
exists_way(R1, R2) :- exists_way_(R1, R2) ; exists_way_(R2, R1).
% Transitive
exists_way(R1, R2) :-
exists_way_(R1, R3),
exists_way(R3, R2).
此代码过度生成解决方案。因此,您需要稍后过滤掉重复项。
答案 2 :(得分:1)
您需要描述一个对称且可传递的关系(exists_way/2
)。
在支持制表的Prolog(例如XSB)中,您可以以非常自然的方式表达这些关系,即它们在数学书籍中表达。
:- table exists_way/2.
% Open doors
exists_way(hall, 'dining room').
exists_way('dining room', kitchen).
exists_way(kitchen, office).
exists_way(kitchen, cellar).
% Symmetry
exists_way(R1, R2) :-
exists_way(R2, R1).
% Transitivity
exists_way(R1, R2) :-
exists_way(R1, R3),
exists_way(R3, R2).
在这种情况下,查询exists_way(R1, R2)
提供了25个独特的解决方案。
答案 3 :(得分:-1)
本着学习的精神:这与你在prolog课程的第一周可能做的祖父母问题是同一个问题。
事实证明,你在prolog中做的很多事情在结构上会非常相似。因此,请确保掌握有关递归谓词的概念,以及这些条款必须遵循的顺序,以便进行更正和性能。
例如,您应该尽可能避免非尾递归。