我是 Prolog 新手,很抱歉这个琐碎的问题。
让我们考虑以下代码:
at(X, Y, 0) :-
X =:=1,
Y =:=1,
!.
at(X, Y, S) :-
S \== 0,
at(XP, Y, SP),
S is SP + 1,
X is XP + 1.
运行时at(1, 1, 1)
,我收到以下错误:
错误:参数没有充分实例化
错误:在:
错误:[10] _2090=:=1
错误:[9] at(_2116,2,0) at /tmp/d.pl:1
错误:[8] at( 1,2,1) 在 /tmp/d.pl:2
错误:[7]
我理解这个错误,但我找不到解决方案。
我也使用过at(1, 1, 0).
,但在这种情况下它堆栈溢出。
显然,这段代码是我项目的简化版本。出于这个原因,我不能简单地重新考虑at
谓词如下:
at(X, Y, S) :-
Y =:= 1,
X =:= S + 1.
如果可行,如何在at
不完全重新考虑实现的情况下修复谓词?
谢谢你的帮助。
根据@lurker 的要求,我正在添加有关我所面临的原始问题的更多详细信息。基本上,我正在尝试使用 Prolog 来解决Wumpus world的推理系统。我对可以在 Prolog 中使用哪些功能提出了限制:没有 assert*
和相关说明。
基本思想是定义一个变量 S,它是系统的状态,它是大多数功能的输入。然后我尝试实现定义代理在系统某个状态下所处位置的功能。
这是我的at
函数的最后一个(错误)版本:
at(1, 1, S) :- S =:= 0, !.
at(X, Y, S) :-
writef('Am I at %w, %w at status %w?\n', [X, Y, S]),
(
S \== 0,
(
at(XP, Y, SP), forwarded(XP, Y, SP), direction(XP, Y, 0, SP), S is SP + 1, X is XP + 1, X > 0, !;
at(X, YP, SP), forwarded(X, YP, SP), direction(X, YP, 1, SP), S is SP + 1, Y > 0, Y is YP + 1, !;
at(XP, Y, SP), forwarded(XP, Y, SP), direction(XP, Y, 2, SP), S is SP + 1, X is XP - 1, !;
at(X, YP, SP), forwarded(X, YP, SP), direction(X, YP, 3, SP), S is SP + 1, Y is YP - 1, !
),
writef('--------> I am at %w, %w, status %w\n', [X, Y, S])
);
(writef('--------> I am NOT at %w, %w, status %w\n', [X, Y, S]), fail).
上面的代码片段引用了两个附加函数:
forwarded/3
:如果代理在某个状态下决定朝当前方向移动,则为真direction/4
:如果代理处于某个状态(和位置......好吧,我可能可以从这个函数中删除这些变量。不确定......)有一个特定的方向,这是真的
所以基本思想,比如,如果agent在(1, 1),方向0,状态0(方向可以分别是0,1,2,3,右,上,左,下),那么在状态 1 处,它位于 (2, 1)。
由于代理如果持有金牌并且处于起点则获胜,因此我的目标函数是:
win(S) :- hold_gold(S), X is 1, Y is 1, at(X, Y, S).
如果我调用解释器并写入win(S)
(我想知道代理在哪个状态下获胜),它将进入无限递归。如上所述,我理解原因,但我看不到在 Prolog 中建模问题的方法。我不知道如何定义整个推理结构,因为它看起来很简单。
谢谢。