Prolog findall/3规则转换为递归规则

Prolog findall/3规则转换为递归规则,prolog,prolog-findall,Prolog,Prolog Findall,我想使用递归转换这个规则,但我不确定如何转换。救命啊! 链接到回答此问题的上一个问题: 示例运行 % base case score([],0). % recursive case score([Movie|Movies],Total) :- takings(Movie,Profit), score(Movies,Total0), Total is Total0 + Profit. 代码说明 Prolog中的列表是使用|运算符递归构造和解构的。由于0是计算整数的初始值,

我想使用递归转换这个规则,但我不确定如何转换。救命啊! 链接到回答此问题的上一个问题:

示例运行

% base case
score([],0).
% recursive case
score([Movie|Movies],Total) :-
    takings(Movie,Profit),
    score(Movies,Total0),
    Total is Total0 + Profit.
代码说明

Prolog中的列表是使用|运算符递归构造和解构的。由于0是计算整数的初始值,[](称为空列表)是封闭列表的初始值。要递归地构建到封闭列表的前面,需要使用当前列表和操作符。在Prolog中使用时,通常将要添加的项称为头(H),将要添加的当前关闭列表称为尾(T),这就是为什么在Prolog中谈论列表时经常看到符号[H | T]

因此,要构造列表[1,2,3]将是[],然后添加1[1]

?- score([robots,hulk,bad_boys_ii],Y).
Y = 749200000.
添加2将是[1],然后添加2[2,1]

?- L = [1|[]].
L = [1].
要解构列表[1,2,3],需要使用变量,因此[H | T]将变成H为1,T为[2,3]

?- L = [2|[1]].
L = [2, 1].
当你到达列表的末尾时,它只是[]没有头

?- [H|T] = [1,2,3].
H = 1,
T = [2, 3].
因此,在代码
[Movie | Movies]
中,获取电影的输入列表,并将列表
Movie
的头部与第一部电影统一起来,并将列表
Movies
的尾部递归传递给谓词。只有当列表为空时,子句
score([],0)
才会匹配并统一
score(Movies,Total0)
中的
Total0

我知道在解释中可以有更多的细节,但这些解释在序言示例中随处可见。

这样:)


非常感谢你救了我。@ZisisKostakakis奇怪的是,你第一次用findall而不是递归来解决它。许多人一开始很难理解findall/3,直到他们看到一些例子,而好的findall例子并不容易找到。@ZisisKostakakis别忘了投票选出你喜欢的答案,然后点击答案旁边的复选标记,给出正确答案。我发现使用我自学的findall比使用[H | t]更容易在我难以理解的地方,我同意你的观点,即讲师并不擅长解释,因为英语不是他/她的主要语言。如果你是Prolog新手,你可以检查一下,它会教你Prolog的基本知识,而OP没有指定空列表中应该发生什么,返回0不是更好吗,而不是一张空列表的
false
?别生气了,我是想帮你:(没错,没有解释,但他/她可以搜索,这是为了让他/她学得更好。
?- [H|T] = [1,2,3].
H = 1,
T = [2, 3].
?- [H|T] = [1].
H = 1,
T = [].
recursive_score([H], CurrentMoney):-
    takings(H, Value),
    CurrentMoney is Value.
recursive_score([H|T], Money):-
    takings(H, Value),
    recursive_score(T, CurrentMoney),
    Money is CurrentMoney + Value.