定义谓词序言
Define the predicate Prolog
我正在为即将到来的考试复习一些练习,但在这方面遇到了困难。
Given a list of integers L, define the predicate: add(L,S) which returns a list of integers S in which each element is the sum of all the elements in L up to the same position.
Example:
?- add([1,2,3,4,5],S).
S = [1,3,6,10,15].
所以我的问题是定义谓词是什么意思?看起来很一般。我读过一些线程,但它们提供的内容不多。谢谢!
定义谓词只是指编写一个谓词来完成问题的要求。
在您的问题中,您必须编写 add/2 谓词的定义(“/2”表示它有两个参数)。你可以写下定义:
add(L,S):- add1(L,0,S).
add1([],_,[]).
add1([H|T],Sum,[H1|T1]):- H1 is Sum+H,NSum is Sum+H,add1(T,NSum,T1).
以上谓词为您提供了所需的输出。一个简单的例子:
?- add([1,2,3,4,5],S).
S = [1, 3, 6, 10, 15].
我认为以上或类似的谓词是有人在测试中等待看到的。
一些额外的信息问题
上面谓词的问题是,如果你查询例如:
?- add(S,L).
S = L, L = [] ;
ERROR: is/2: Arguments are not sufficiently instantiated
正如您看到的,当您尝试询问谓词何时成功时,它会给出一个明显的解决方案,而对于进一步的解决方案,它会抛出一个错误。这不是一个很好的愿望 属性。您可以通过使用模块 CLPFD
:
来改进它
:- use_module(library(clpfd)).
add(L,S):- add1(L,0,S).
add1([],_,[]).
add1([H|T],Sum,[H1|T1]):- H1 #= Sum+H,NSum #= Sum+H,add1(T,NSum,T1).
现在一些查询:
?- add([1,2,3,4,5],S).
S = [1, 3, 6, 10, 15].
?- add(S,[1,3,6]).
S = [1, 2, 3].
?- add(S,L).
S = L, L = [] ;
S = L, L = [_G1007],
_G1007 in inf..sup ;
S = [_G1282, _G1285],
L = [_G1282, _G1297],
_G1282+_G1285#=_G1307,
_G1282+_G1285#=_G1297 ;
...and goes on..
如您所见,谓词现在可以提供您询问的任何信息!那是因为现在它具有更多的关系行为,而不是之前由于 is/2
谓词而具有的功能行为。 (这些是改进谓词行为的更多信息。对于测试,您可能不允许使用库等...因此您可以只编写一个至少可以回答问题的简单解决方案)。
这是一个很好的练习,可以让您熟悉两个重要的 Prolog 概念:
- 声明性整数算法 对所有方向的整数进行推理
- 元谓词 以缩短您的代码。
我们从一个非常简单的关系开始,将整数 I
和整数 S0
的 sum 与新的总和 S
相关联:
sum_(I, S0, S) :- S #= S0 + I.
根据您的 Prolog 系统,您可能需要如下指令:
:- use_module(library(clpfd)).
使用声明性整数算法。
其次,有一个强大的元谓词家族(参见meta-predicate) called scanl/N
, which are described in Richard O'Keefe's Prolog library proposal,并且已经在一些系统中实现。在我们的例子中,我们只需要scanl/4
.
示例查询:
?- scanl(sum_, [1,2,3,4,5], 0, Sums).
Sums = [0, 1, 3, 6, 10, 15].
完成!
其实,比做的多,因为我们可以全方位使用这个,例如:
?- scanl(sum_, Is, 0, Sums).
Is = [],
Sums = [0] ;
Is = [_2540],
Sums = [0, _2540],
_2540 in inf..sup ;
Is = [_3008, _3014],
Sums = [0, _3008, _3044],
_3008+_3014#=_3044 ;
etc.
这就是我们对真正关系型解决方案的期望!
另请注意 0
作为部分和列表中第一个元素的出现。它满足您对任务的文字描述,但不满足您发布的示例。我将对齐这些作为练习。
我正在为即将到来的考试复习一些练习,但在这方面遇到了困难。
Given a list of integers L, define the predicate: add(L,S) which returns a list of integers S in which each element is the sum of all the elements in L up to the same position.
Example:
?- add([1,2,3,4,5],S).
S = [1,3,6,10,15].
所以我的问题是定义谓词是什么意思?看起来很一般。我读过一些线程,但它们提供的内容不多。谢谢!
定义谓词只是指编写一个谓词来完成问题的要求。 在您的问题中,您必须编写 add/2 谓词的定义(“/2”表示它有两个参数)。你可以写下定义:
add(L,S):- add1(L,0,S).
add1([],_,[]).
add1([H|T],Sum,[H1|T1]):- H1 is Sum+H,NSum is Sum+H,add1(T,NSum,T1).
以上谓词为您提供了所需的输出。一个简单的例子:
?- add([1,2,3,4,5],S).
S = [1, 3, 6, 10, 15].
我认为以上或类似的谓词是有人在测试中等待看到的。
一些额外的信息问题
上面谓词的问题是,如果你查询例如:
?- add(S,L).
S = L, L = [] ;
ERROR: is/2: Arguments are not sufficiently instantiated
正如您看到的,当您尝试询问谓词何时成功时,它会给出一个明显的解决方案,而对于进一步的解决方案,它会抛出一个错误。这不是一个很好的愿望 属性。您可以通过使用模块 CLPFD
:
:- use_module(library(clpfd)).
add(L,S):- add1(L,0,S).
add1([],_,[]).
add1([H|T],Sum,[H1|T1]):- H1 #= Sum+H,NSum #= Sum+H,add1(T,NSum,T1).
现在一些查询:
?- add([1,2,3,4,5],S).
S = [1, 3, 6, 10, 15].
?- add(S,[1,3,6]).
S = [1, 2, 3].
?- add(S,L).
S = L, L = [] ;
S = L, L = [_G1007],
_G1007 in inf..sup ;
S = [_G1282, _G1285],
L = [_G1282, _G1297],
_G1282+_G1285#=_G1307,
_G1282+_G1285#=_G1297 ;
...and goes on..
如您所见,谓词现在可以提供您询问的任何信息!那是因为现在它具有更多的关系行为,而不是之前由于 is/2
谓词而具有的功能行为。 (这些是改进谓词行为的更多信息。对于测试,您可能不允许使用库等...因此您可以只编写一个至少可以回答问题的简单解决方案)。
这是一个很好的练习,可以让您熟悉两个重要的 Prolog 概念:
- 声明性整数算法 对所有方向的整数进行推理
- 元谓词 以缩短您的代码。
我们从一个非常简单的关系开始,将整数 I
和整数 S0
的 sum 与新的总和 S
相关联:
sum_(I, S0, S) :- S #= S0 + I.
根据您的 Prolog 系统,您可能需要如下指令:
:- use_module(library(clpfd)).
使用声明性整数算法。
其次,有一个强大的元谓词家族(参见meta-predicate) called scanl/N
, which are described in Richard O'Keefe's Prolog library proposal,并且已经在一些系统中实现。在我们的例子中,我们只需要scanl/4
.
示例查询:
?- scanl(sum_, [1,2,3,4,5], 0, Sums). Sums = [0, 1, 3, 6, 10, 15].
完成!
其实,比做的多,因为我们可以全方位使用这个,例如:
?- scanl(sum_, Is, 0, Sums). Is = [], Sums = [0] ; Is = [_2540], Sums = [0, _2540], _2540 in inf..sup ; Is = [_3008, _3014], Sums = [0, _3008, _3044], _3008+_3014#=_3044 ; etc.
这就是我们对真正关系型解决方案的期望!
另请注意 0
作为部分和列表中第一个元素的出现。它满足您对任务的文字描述,但不满足您发布的示例。我将对齐这些作为练习。