0

listsum(L, S)如果 L 是从 1 增加到某个 n 的自然数列表(即[1,2,..,n]) ,我需要编写一个正确的谓词。现在我让它适用于这种查询,listsum(L, <any number larger than 0>)但是当我尝试查询时,listsum([1,2,3], S)它说参数没有充分实例化。这是我的代码:

listsum(L,S) :- listsum(L,S,1).
listsum(L, 0, A) :- 
    N is A-1,
    N > 1,
    fromTo(1, N, L). ; true iff L is the list [1,2,...,N]
listsum(L, S, A) :-
    S > 0,
    SA is S-A,
    A1 is A+1,
    listsum(L, SA, A1).

如果有人可以帮助我了解如何以两种方式进行这项工作(同样对于 L 的给定值,查询 S),将不胜感激!

提前致谢。

4

1 回答 1

1

当初学者第一次遇到老式的 Prolog 代码时,这个错误是一个常见的问题。原因是谓词like不是真的(is)/2关系。相反,它们只有在它们的参数被充分实例化时才起作用。(>)/2

这会引起很多混乱,尤其是在初学者中,而且从实践的角度来看显然也是非常不幸的。在 Prolog 中编程时,我们希望从关系的普遍性中受益,而不是从一开始就陷入这种低级问题。

此类问题的声明式解决方案是约束。各种 Prolog 系统对它们的支持有所不同。然而,目前,最广泛使用的 Prolog 系统至少都带有整数约束。

例如,要在 GNU Prolog 中使用它们,只需对您的代码进行以下直接更改:

  • 替换(is)/2(#=)/2
  • 替换(>)/2(#>)/2.

因此,我们得到:

列表和(L,S):-列表和(L,S,1)。

列表和(L,0,A):-
    N #= A-1,
    N #> 1 ,
    从到(1,N,L)。
列表和(L,S,A):-
    S #> 0,
    SA #= SA,
    A1 #= A+1 ,
    列表和(L,SA,A1)。

此外,fromTo/3如果您的 Prolog 系统提供,我建议对 进行以下定义numlist/3

fromTo(1, N, Ls) :- numlist(1, N, Ls)。

我把实现numlist/3自己作为一个简单的练习。

通过这些更改,我们得到:

?- listsum([1,2,3], S)。
S = 6。

因此,至少我们得到了正确的解决方案,并且现在可以专注于剩余的问题。

例如,查询不会普遍终止,我们可以看到:

?- listsum([1,2,3], S), false不终止

我把纠正这个作为练习。

请注意,某些 Prolog 系统要求您导入库以使用声明性整数运算。

于 2017-03-28T18:43:30.103 回答