我有下一个问题, “返回数组的自然数”
例如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,[]).
答案 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的答案),我认为这与您没有任何实际意义。