【发布时间】:2015-03-29 13:59:09
【问题描述】:
我正在处理“猴子和香蕉”问题,但使用的是 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)),但是由于变量没有实例化,显然它们统一和成员(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) 表示:
- 猴子的位置(X 轴)。
- 猴子的位置(Y 轴)。
- 第一个盒子的位置。
- 第二个盒子的位置。
- 盒子是否堆叠。
- 猴子有没有香蕉。
我应该尝试检查所有可能的 PD(猴子的命运位置),但我不知道该怎么做。
提前致谢。
【问题讨论】:
-
有一点我不清楚,为什么
estado的第一个参数是您访问状态列表中的变量?它代表猴子的坐标,对吧?那么为什么它根本就是一个变量,为什么还没有统一到一个坐标呢?在我看来,这就是你的问题。 -
@Oskar 抱歉,我不确定您要解释什么,我几个月前就开始使用 Prolog,所以我没有完全掌握统一的概念。我想尝试我的问题中定义的所有不同位置,但是在original code 中似乎不存在不同位置的列表,它们似乎通过“反复试验”来工作。我尝试创建一系列位置(中心)。位置(puerta)等;然后是一个名为 es_posicion(X) 的函数:- posicion(X) 但仅适用于 centro,因为未检查其他选项。
-
@Oskar 我的意思是,如何将变量统一为坐标?正如我之前所说,在原始代码中,我尝试调整变量似乎在以后统一(检查不同位置时):
Call: (10) move(state(_G3220, onfloor, _G3220, hasnot), _G3235, _G3236) ? creep Exit: (10) move(state(_G3220, onfloor, _G3220, hasnot), climb, state(_G3220, onbox, _G3220, hasnot)) ? creep Call: (10) canget(state(_G3220, onbox, _G3220, hasnot)) ? creep Call: (11) move(state(_G3220, onbox, _G3220, hasnot), _G3240, _G3241) ? creep
标签: prolog unification