0
votes

i have the next problem, "return the numbers of natural numbers of an array"

ex. naturales(R,[6,-7,-4,3,2,8]). R = 4

when a negative numbers appears return false and break my recursivity

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

4 Answers

1
votes

Here is a very short solution :

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

If your predicate really needs to have only 2 arguments, one being the result, R, and the other one the given list, [H|T], you can do something like this. Note that the first predicate calls the second "naturales" with 3 arguments and then, that one starts the recursive process. The C is only a counter where you can add the number of positive elements and then copy that value to the result, in the last line of code. The first line just its just to make sure the empty list returns 0 positive elements. There is probably better ways to do this, this one is probably the most intuitive.

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).
0
votes

A common prolog idiom is the use of a helper predicate with an accumulator (extra) variable. Try something like this:

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 ).
0
votes

As others pointed out, the recursive call cannot complete when there are negative numbers. So, you can just patch your program in this way

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

Now, nearly every Prolog out there (except mine :) implements (->)/2, also know as 'if-then-else'. So, the patch could also be written like

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

Given that naturales/2 is anyway not tail recursive (see @NicholasCarey answer for that), I think it has no practical relevance for you.