Prolog:猴子和香蕉,两个盒子

时间:2016-02-21 07:25:11

标签: prolog

说明:修改附加的程序,以便猴子到达香蕉,他必须站在一个较小的盒子上,他放在一个较大的盒子上面。在程序开始时,盒子应该在房间的两个不同位置。在屏幕上显示猴子的活动。

我一直在阅读教科书(人工智能的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状态)。

1 个答案:

答案 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更有经验时,您将越来越多地使用表示法来描述列表,以简化代码。我在这里留下这个版本供你学习:

moves(state(_ ,_ ,_ , has)) --> [].
moves(State0) --> [Move],
        { move(State0, Move, State) },
        moves(State).

用法示例,再次使用迭代深化来找到最短的解决方案:

?- length(Ms, _), phrase(moves(State0), Ms).

玩得开心,还可以尝试 Prolog的艺术

相关问题