递归列表中的自然数不正确

时间:2019-10-02 03:31:07

标签: prolog

我有下一个问题, “返回数组的自然数”

例如naturales(R,[6,-7,-4,3,2,8])。 R = 4

出现负数时返回false并破坏我的递归性

naturales(R,[Head|Tail]):-naturales(R1,Tail), Head >= 0, R is R1+1.
naturales(0,[]).

4 个答案:

答案 0 :(得分:1)

这是一个非常简短的解决方案:

naturales(In, Out) :-
    aggregate(count,X^(member(X, In), X >= 0), Out).

答案 1 :(得分:0)

如果您的谓词确实只需要有两个参数,一个是结果R,另一个是给定列表[H | T],则可以执行以下操作。请注意,第一个谓词使用3个参数调用第二个“自然”,然后,一个谓词开始递归过程。 C只是一个计数器,您可以在其中添加正数个元素,然后在最后一行代码中将该值复制到结果中。第一行只是为了确保空列表返回0个正元素。可能有更好的方法可以做到这一点,这可能是最直观的。

naturales(X, []):- X = 0.
naturales(R, [H|T]):- naturales(R, [H|T], 0).

naturales(R, [H|T], C):- (H > 0, C1 is C + 1, naturales(R1, T, C1), R = R1) ; naturales(R1, T, C), R = R1.
naturales(X, [], X).

答案 2 :(得分:0)

常见的序言成语是使用带有累加器(额外)变量的辅助谓词。尝试这样的事情:

natural_numbers( Xs, N ) :- natural_numbers( Xs, 0, N ).

natural_numbers( []     , N , N ) .
natural_numbers( [X|Xs] , T , N ) :-
  ( X > 0 -> T1 is T+1 ; T1 = T ) ,
  natural_numbers( Xs, T1, N ).

答案 3 :(得分:0)

正如其他人指出的,当存在负数时,递归调用无法完成。因此,您可以通过这种方式修补程序

naturales(R,[Head|Tail]):-naturales(R1,Tail), (Head >= 0, R is R1+1 ; R=R1).
naturales(0,[]).

现在,几乎所有Prolog(mine除外)都实现(->)/ 2,也称为'if-then-else'。因此,补丁也可以写为

naturales(R,[Head|Tail]):-naturales(R1,Tail), (Head >= 0 -> R is R1+1 ; R=R1).
naturales(0,[]).

鉴于naturales / 2并不是尾部递归的(请参阅@NicholasCarey的答案),我认为这与您没有任何实际意义。