Prolog数字范围

时间:2014-12-07 18:21:04

标签: prolog

我遇到了这个question,有人可以从低到高生成一系列数字。

我是prolog的新手,所以我很难理解解决方案的确切运作方式。所以我想知道是否有人会亲自了解它对我的影响。

更具体地说,我很难理解回溯以及Prolog解释器如何获得解决方案。

我也想知道如何创建谓词 范围(上,K)....

所以当我打电话

范围(5,K)。 K = 1; K = 2; 。 。 K = 5;

为了清晰而编辑。

1 个答案:

答案 0 :(得分:1)

对于range(+U, -K),最好的答案是使用between/3内置谓词。但这是一个可能的实现:

range(_, 1).
range(U, K):- range(U, K1), (K1 >= U, !, false ; K is K1+1).

有比这更好的解决方案,但我认为用它来解释是件好事。它并不完美,因为给出一个负面的U会给你一个错误的解决方案,但你可以从这里开始做到完美。

示例

假设您运行以下查询:

?- range(2, K).

Prolog将通过寻找与其统一的规则来尝试满足给定的目标。可以使用第一个规则(range(_, 1))并创建选择点,因为可以考虑其他选择(即第二个规则)。因此,因为匿名变量_与2统一,1与K统一,所以您得到第一个答案:

K = 1 ;

现在Prolog回溯到最后一个选择点并尝试使用第二个规则来满足range(2, K)。它通过将U与2,变量K与规则中的变量K统一并将条件放在目标堆栈上来实现这一点,现在看起来像这样:

range(2, K1), (K1 >= 2, !, false ; K is K1 + 1)

为了满足第一个目标,Prolog考虑第一个规则并创建一个选择点。 K1被实例化为1,目标堆栈变为:

(1 >= 2, !, false ; K is 1 + 1)

现在,因为有一个或运算符(;),Prolog将尝试满足第一组子目标并在此处创建另一个选择点。但是,1>=2是错误的,所以它回溯到最后一个选择点,并尝试通过将K is 1 + 1实例化为2来满足K成功。因此,您获得了第二个结果:

K = 2 ;

Prolog现在回溯到为range(2, K1)创建的选择点并使用第二个规则。目标堆栈变为:

range(2, K2), (K2 >= 2, !, false ; K1 is K2+1), (K1 >= 2, !, false ; K is K1 + 1)

同样,Prolog尝试使用第一条规则来满足range(2, K2),该规则将K2与1统一起来并创建一个选择点。

(1 >= 2, ! false ; K1 is 1+1), (K1 >= 2, !, false ; K is K1+1)

现在Prolog有两个替代方案,因为or运算符,但第一个失败,因为1 >= 2是假的。第二个是满足K1被实例化为2。

(2 >= 2, !, false ; K is 2 + 1)

现在,Prolog创建一个选择点,获取第一组目标(2 >= 2, !, false)并尝试满足它们。 2>=2为真,然后切割运算符(!)会破坏所有先前的选择点。 false为false,执行停止。