1

我正在研究“猴子和香蕉”问题,但用的是 2 盒而不是 1 盒。我尝试将代码从 1 个盒子调整为 2 个盒子,但我遇到了这个问题。

我需要保留一个“访问过的状态”列表,因为树变得太大并且我的程序崩溃了。在这个列表中是从开始到实际状态的所有已访问状态,因此如果我要进入已访问状态,则该子句将失败并发生回溯。

问题是有时会发生这种情况:

 Call: (8) lists:member(estado(_G3634, p0, ventana, centro, noapiladas, notiene), [estado(_G3619, p0, ventana, centro, noapiladas, notiene)]) ? creep
 Exit: (8) lists:member(estado(_G3619, p0, ventana, centro, noapiladas, notiene), [estado(_G3619, p0, ventana, centro, noapiladas, notiene)]) ? creep

在尝试查找所有可能的状态时,我需要检查所有可能的位置(例如:门(puerta)、窗口(ventana)和中间(centro)),但由于变量没有实例化,显然它们统一和成员(状态, List) 返回 true,因此程序回溯,我从不检查所有可能的状态。

我尝试使用 \== 检查成员资格,但发生了其他问题:由于状态(带有未实例化的变量)总是不同的(状态(_G1234)与状态(_2345)不同)我进入一个无限循环并且永远不会结束,因为它正在检查许多具有未实例化(但不同)变量的状态。

我怎么能解决这个问题?还是我应该尝试另一个近似值?我考虑过定义“位置”的预设,但我不确定在执行规则时如何检查所有不同的位置。

规则是这样的:

mover(estado(P, p0, P1, P2, A, E),
    desplazar(P, PD),
    estado(PD, p0, P1, P2, A, E)).

其中 estado(P, p0, P1, P2, A, E) 表示:

  1. 猴子的位置(X 轴)。
  2. 猴子的位置(Y 轴)。
  3. 第一个盒子的位置。
  4. 第二个盒子的位置。
  5. 盒子是否堆叠。
  6. 猴子有没有香蕉。

我应该尝试检查所有可能的 PD(猴子的命运位置),但我不知道该怎么做。

提前致谢。

4

1 回答 1

0

为了防止具有不同名称的变量列表统一,您可以使用alldif/1谓词

:- initialization(main).

main :-
    alldif([X,Y,Z]), % this goal succeeds
    Z=Y,
    alldif([X,Y,Z]). % this goal fails, since Z is unified with Y

alldif([]).
alldif([E|Es]) :-
   maplist(dif(E), Es),
   alldif(Es).
于 2019-01-13T22:28:49.857 回答