【发布时间】:2019-12-04 02:50:40
【问题描述】:
我想我在理解 prolog 方面有一些更大的问题,但由于我无法完全表述它,所以我专注于单个问题
我想创建一个规则 natural(X),如果 X 是 1,2,3,4,...
更重要的是,我希望:natural(5) 为真和 natural(X) 输出X=1; X=2; ...
所以,我解释如下规则(伪逻辑):
natural(1) must be true
natural(X) is true if natural(X-1) is true
或者,就序言而言:
natural(1).
natural(X) :- natural(X-1).
但我遇到了一个问题 - 如果我尝试 natural(5) 我会得到无限递归
调试器说程序评估:
natural(5)
natural(5-1)
natural(5-1-1)
natural(5-1-1-1)
natural(5-1-1-1-1)
natural(5-1-1-1-1-1)
natural(5-1-1-1-1-1-1)
...
我猜问题出在X-1 没有被评估?
让我们尝试解决这个问题:
natural(1).
natural(X) :-
Y is X-1,
natural(Y).
现在,natural(5) 按预期工作
但是,如果我使用natural(X),我会得到X=1; Exception: Arguments not sufficiently instantiated (Y is X-1)
好的,我想问题是我们尝试评估可能没有价值的东西
如果我尝试使用Y = X-1,我们会回到第一个问题。 Y == X-1 返回false
我发现唯一可行的解决方案是切换行和定义顺序:
natural(1).
natural(X) :-
natural(Y),
X is Y+1.
将最后一行更改为= 会得到“+1+1+1...”的结果。 == 失败了。
此解决方案在生成 X=1; X=2; ... 时效果很好,但是当我将其用作检查 (natural(5)) 时,它进入“0,(0,1),(0,1,2),(0,1 ,2,3),..." 顺序。是的,我得到了正确的结果,但是那里的路很长,不是我想象的那样。
如果我没有在以前的解决方案中看到检查 natural(5) 的更快方法,我会在这里停下来。
那么,我错过了创建此规则的更好方法吗?
我想一种方法是将“真/假”查询与生成器查询分开......但是有没有办法让它“评估是否可能评估”,即将唯一常量与有变量分开? var(X-1) 在某种程度上是错误的......
【问题讨论】:
-
首先使用successor-arithmetics 来定义自然数。在里面,一切都是自然的,
(is)/2是非常困难和不完整的。然后,使用library(clpfd),更加自然。想想:X #>= 0.
标签: prolog