Prolog if 子句 returns false
Prolog if clause returns false
我正在学习Prolog,我有一个小问题。
我正在研究一个 "builds" 塔的例子。
所以我定义了3个块a,b和c。
第三块 c 位于 a 和 b 之上 -> 所以它被 a 和 b 支撑。
block(a).
block(b).
block(c).
%supported(BLOCK, BY1, BY2)
supported(c,a,b).
level(BLOCK, LEVEL) :-
supported(BLOCK, X, _)
-> (level(X, LEV1), LEVEL is LEV1 + 1)
; LEVEL is 0.
我还有一个计算方块等级的函数。我遇到的问题如下:
?- level(X, 0).
false.
?- level(X, 1).
X = c.
为什么它对级别 0 返回 false,我该如何解决?
我想要一个方法 returns 我 a 和 b 级别 0.
考虑一下
?- level(a,0).
true.
很明显,当 BLOCK
空闲时,supported(BLOCK, X, _)
成功,将规则强加在意外的连词 level(X, LEV1), LEVEL is LEV1 + 1
上,这确实失败了。
要更正此行为,请绑定 BLOCK
:
level(BLOCK, LEVEL) :-
block(BLOCK),
(supported(BLOCK, X, _) -> level(X, LEV1), LEVEL is LEV1 + 1 ; LEVEL is 0).
可以使用 trace.
(添加缩进)进行调试:
[trace] ?- level(X, 0).
Call: (6) level(_G2697, 0) ? creep
Call: (7) supported(_G2697, _G2771, _G2772) ? creep
Exit: (7) supported(c, a, b) ? creep
Call: (7) level(a, _G2771) ? creep
Call: (8) supported(a, _G2771, _G2772) ? creep
Fail: (8) supported(a, _G2771, _G2772) ? creep
Redo: (7) level(a, _G2771) ? creep
Call: (8) _G2770 is 0 ? creep
Exit: (8) 0 is 0 ? creep
Exit: (7) level(a, 0) ? creep
Call: (7) 0 is 0+1 ? creep
Fail: (7) 0 is 0+1 ? creep
Fail: (6) level(_G2697, 0) ? creep
false.
所以发生了什么事?
首先调用level(X,0).
这个谓词调用支持supported(BLOCK,X,_).
有一个统一的答案:BLOCK=a
、X=b
和_=c
。所以这意味着 if-then-else 语句使用 then-part.
在 then 部分,它再次使用 level(b,LEV1)
查询 level/2
,现在这个调用导致调用 support(b,LEV1,_)
。对于这个调用,它无法解析调用,因为没有第一个值为 b
的 support
谓词。所以现在我们来看 else 部分。我们统一 LEV1 is 0
,因此 LEV1=0
和我们 return.
在return部分(在then-部分),level(b,0)
是结果。现在我们统一 LEVEL is LEV1+1
,但是 LEVEL
已经被定义为 0
而 0+1
是 1
。因此它在顶层失败。
分辨率大概是把supported
做的更细一些,定义为:support/2
.
程序如下:
block(a).
block(b).
block(c).
%supported(BLOCK, BY1, BY2)
supported(c,b).
supported(c,a).
supported(b,a).
现在 level
谓词为:
level(B,L) :-
supported(B,C),
level(C,LC),
L is LC+1.
level(_,0).
我正在学习Prolog,我有一个小问题。 我正在研究一个 "builds" 塔的例子。
所以我定义了3个块a,b和c。 第三块 c 位于 a 和 b 之上 -> 所以它被 a 和 b 支撑。
block(a).
block(b).
block(c).
%supported(BLOCK, BY1, BY2)
supported(c,a,b).
level(BLOCK, LEVEL) :-
supported(BLOCK, X, _)
-> (level(X, LEV1), LEVEL is LEV1 + 1)
; LEVEL is 0.
我还有一个计算方块等级的函数。我遇到的问题如下:
?- level(X, 0).
false.
?- level(X, 1).
X = c.
为什么它对级别 0 返回 false,我该如何解决? 我想要一个方法 returns 我 a 和 b 级别 0.
考虑一下
?- level(a,0).
true.
很明显,当 BLOCK
空闲时,supported(BLOCK, X, _)
成功,将规则强加在意外的连词 level(X, LEV1), LEVEL is LEV1 + 1
上,这确实失败了。
要更正此行为,请绑定 BLOCK
:
level(BLOCK, LEVEL) :-
block(BLOCK),
(supported(BLOCK, X, _) -> level(X, LEV1), LEVEL is LEV1 + 1 ; LEVEL is 0).
可以使用 trace.
(添加缩进)进行调试:
[trace] ?- level(X, 0).
Call: (6) level(_G2697, 0) ? creep
Call: (7) supported(_G2697, _G2771, _G2772) ? creep
Exit: (7) supported(c, a, b) ? creep
Call: (7) level(a, _G2771) ? creep
Call: (8) supported(a, _G2771, _G2772) ? creep
Fail: (8) supported(a, _G2771, _G2772) ? creep
Redo: (7) level(a, _G2771) ? creep
Call: (8) _G2770 is 0 ? creep
Exit: (8) 0 is 0 ? creep
Exit: (7) level(a, 0) ? creep
Call: (7) 0 is 0+1 ? creep
Fail: (7) 0 is 0+1 ? creep
Fail: (6) level(_G2697, 0) ? creep
false.
所以发生了什么事?
首先调用level(X,0).
这个谓词调用支持supported(BLOCK,X,_).
有一个统一的答案:BLOCK=a
、X=b
和_=c
。所以这意味着 if-then-else 语句使用 then-part.
在 then 部分,它再次使用 level(b,LEV1)
查询 level/2
,现在这个调用导致调用 support(b,LEV1,_)
。对于这个调用,它无法解析调用,因为没有第一个值为 b
的 support
谓词。所以现在我们来看 else 部分。我们统一 LEV1 is 0
,因此 LEV1=0
和我们 return.
在return部分(在then-部分),level(b,0)
是结果。现在我们统一 LEVEL is LEV1+1
,但是 LEVEL
已经被定义为 0
而 0+1
是 1
。因此它在顶层失败。
分辨率大概是把supported
做的更细一些,定义为:support/2
.
程序如下:
block(a).
block(b).
block(c).
%supported(BLOCK, BY1, BY2)
supported(c,b).
supported(c,a).
supported(b,a).
现在 level
谓词为:
level(B,L) :-
supported(B,C),
level(C,LC),
L is LC+1.
level(_,0).