我遇到了这个question,有人可以从低到高生成一系列数字。
我是prolog的新手,所以我很难理解解决方案的确切运作方式。所以我想知道是否有人会亲自了解它对我的影响。
更具体地说,我很难理解回溯以及Prolog解释器如何获得解决方案。
我也想知道如何创建谓词 范围(上,K)....
所以当我打电话
范围(5,K)。 K = 1; K = 2; 。 。 K = 5;
为了清晰而编辑。
答案 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,执行停止。