当具有不同的名称时,阻止Prolog变量统一

时间:2015-03-29 13:59:09

标签: prolog unification

我正在研究猴子和香蕉"问题,但有2个盒而不是一个。我尝试将代码从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)),但由于变量未实例化,显然它们统一并且成员(State,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. 如果猴子是否有香蕉。
  7. 我应该尝试检查所有可能的PD(猴子的命运位置),但我不知道该怎么做。

    提前致谢。

1 个答案:

答案 0 :(得分:0)

要防止统一使用不同名称的变量列表,可以使用this alldif/1 predicate

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