说明:修改附加的程序,以便猴子到达香蕉,他必须站在一个较小的盒子上,他放在一个较大的盒子上面。在程序开始时,盒子应该在房间的两个不同位置。在屏幕上显示猴子的活动。
我一直在阅读教科书(人工智能的Prolog编程),而Prolog肯定难以接受。虽然本书讨论了如果有一个盒子如何解决问题,但它没有提到如果有多个盒子如何开始解决这个问题。任何指导/建议将不胜感激。
move(state(middle, onbox, middle, hasnot), grasp, state(middle, onbox, middle, has)).
move(state(Pos, onfloor, Pos, H), climb, state(Pos, onbox, Pos, H)).
move(state(P1, onfloor, P1, H), push(P1, P2), state(P2, onfloor, P2, H)).
move(state(P1, onfloor, P, H), walk(P1, P2), state(P2, onfloor, P, H)).
canget(state(_ ,_ ,_ , has)).
canget(state1) :-
move(State1, Move, State2),
canget(State2).
问题:
canget(state(atdoor, onfloor, atwindow, hasnot)). % (monkey's horizontal position, monkey's vertical position, position of the box, and whether or not the monkey has the banana).
我唯一能想到的是为第二个盒子的位置的每个子句添加另一个字段,例如state(水平pos,垂直pos,box1的pos,box2的pos和banana状态)。
答案 0 :(得分:2)
您建议的解决方案是解决此问题的一种方法:您确实可以在表示状态的术语中再添加一个参数。
然而,让我们瞄准更一般的事情:如果房间里不仅有一两个,而是 n ,你会怎么做?此外,我们假设这些方框的大小为S_1,...,S_n(S_i不一定是不同的),并且只能在顶部的方框小于放置它的方框时进行堆叠。
我建议用以下表示来表示这些状态:
我们将使用一对Pos-Size
来表示每个方框的位置和大小。这只是术语-(Pos, Size)
的中缀表示法,即仿函数-
和arity 2。
我们将使用此类对的列表,即[Pos1-Size1, Pos2-Size2, ..., Pos_n-Size_n]
来表示所有框。
当在相同位置堆放盒子时,我们需要确保已经位于相同位置的盒子允许这样的堆叠。我离开这是一个练习。
此外,canget/1
并不是那么有趣,是吗?我们真正关心的是将我们带入解决方案的行动清单!因此,我们用一个参数来扩展谓词,这个参数实际上让我们看到了顶层的所有移动,并使用更多的说话名称来表示我们实际描述的内容:
moves(state(_ ,_ ,_ , has), []).
moves(State0, [Move|Moves]) :-
move(State0, Move, State),
moves(State, Moves).
现在我们可以使用迭代深化来找到具体的解决方案:
?- length(Ms, _), moves(State0, Ms).
其中State0
是拼图的初始状态。
当您对Prolog更有经验时,您将越来越多地使用dcg表示法来描述列表,以简化代码。我在这里留下这个版本供你学习:
moves(state(_ ,_ ,_ , has)) --> [].
moves(State0) --> [Move],
{ move(State0, Move, State) },
moves(State).
用法示例,再次使用迭代深化来找到最短的解决方案:
?- length(Ms, _), phrase(moves(State0), Ms).
玩得开心,还可以尝试 Prolog的艺术!