Prolog Tail用于计算列表中未实例化变量的递归过程

时间:2011-07-12 19:32:40

标签: prolog

我正在尝试编写Tail Recursive过程来计算列表中未实例化变量的数量。我有点陷入困境,我哪里出错了。

我目前的查询如下:

count([S,L],N) :- var(S), !, N+1.
count([L],N).

3 个答案:

答案 0 :(得分:2)

注意:此答案提供了一种递归但不是尾递归的解决方案。对于尾递归解决方案,您应该使用累加器,如此问题的其他答案中所示。

与任何递归过程一样,您应该添加适当的基本案例。 在这种情况下,它应该是一个带有空列表的子句,它返回0与未实例化变量的数量:

count([], 0).

检查你写的条款。它将两个元素的列表作为输入,而不是表示为Head项和尾列表的列表,它实际上对N没有任何作用:

count([Head|Tail], M):- 
    var(Head), 
    !, 
    count(Tail, N), 
    M is N+1.

最后,当列表的第一项不是未实例化的变量时,你还应该添加一个句子来处理这个案例:

count([_|Tail], N):- count(Tail, N).

答案 1 :(得分:2)

这是一个用于计算列表中变量的尾递归。它使用累加器技术:

count(L, N) :- count(L, 0, N).     % L=list, N=count, 0=value of the sum accumulator S
count([], S, S) :- !.              % the innermost call, the accumulator S (2nd arg) "copied" to final result (3rd arg)
count([H| T], S, N):- var(H), !, S1 is S+1, count(T, S1, N). % increase accumulator if H is var
count([H| T], S, N):- count(T, S, N).    % keep accumulator if H is not var

所有子句中的最后一次递归调用都没有调用。

答案 2 :(得分:0)

此处没有递归,因为为了进行递归,您必须根据自身定义某些内容 - 您会注意到代码右侧缺少count/2规则。

% two paths, variable and non-variable
% and a base case to start the count
count([S|L], N) :- var(S), !, count(L, N0),  N is N0+1.
count([S|L], N) :- nonvar(S), !, count(L, N).
count([], 0).

或者,只需使用findall/3即可完成此操作。

count_alt(L, N) :- findall(S, (member(S, L), var(S)), D), length(D, N).