Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prolog - How to count the number of elements in a list that satisfy a specific condition?

Tags:

list

prolog

for example, if I have a list [1,1,2,3,5,1], I want to count the number of 1's in this list, how would I do that?

I wrote something like:

count([], 0).
count([H|T], N) :-
   count(T, X),
   (  H =:= 1
   -> N is X+1
   ;  N is X
   ),
   N > 0.

In this recursion, I want to do if Head equals 1, then the counting + 1, if Head is not 1, then counting stays the same. However, it returns false if I have things that are not 1 in the list. I know the problem is that it'd fail as soon as an element does not satisfy the if statement; and it can never reach the else statement. How do I fix this? Please help!!!!

like image 536
xsx Avatar asked Oct 24 '17 05:10

xsx


People also ask

How do you count elements in a list in Prolog?

Prolog has an ISO builtin predicate number/1 that checks whether the given parameter is a number. We can simply use an if-then-else statement that either increments N is N1+1 , or sets N = N1 , like: count([],0). count([H|Tail], N) :- count(Tail, N1), ( number(H) -> N is N1 + 1 ; N = N1 ).

How do you count facts in Prolog?

The simplest way to count them would be to use findall then take the length of the result: findall( _, reserve(bus(_), place(4), datetravel([_,_,_]), info([88032454321, robert,downe])), L), length(L, N). and then N is the count.

How do you find the nth element of a list in Prolog?

To find the nth element of a list (where n is relative to zero), something like this ought to suffice: find_nth_element_of_list( 0 , X , [X|_] ) .

Which method is used count the number of elements?

To count the number of elements of a string, the len() method can be used.


2 Answers

Try this:

count([],0).
count([1|T],N) :- count(T,N1), N is N1 + 1.
count([X|T],N) :- X \= 1, count(T,N).
like image 144
Enigmativity Avatar answered Sep 28 '22 23:09

Enigmativity


Alternative solution, which uses foldl/4 and defines higher order predicate (the one which takes another predicate as a parameter):

count_step(Condition, Item, CurrentCount, NewCount) :-
    call(Condition, Item) ->
        NewCount is CurrentCount + 1 ;
        NewCount = CurrentCount.

count(List, Condition, Count) :-
    foldl(count_step(Condition), List, 0, Count).

is_one(Expr) :-
    Expr =:= 1.

Usage example:

?- count([0, 2, 3, 0], is_one, Count).
Count = 0.

?- count([1, 2, 3, 1], is_one, Count).
Count = 2.

Another (rather dirty) approach is to use include/3 combined with length/2:

count(List, Condition, Count) :-
    include(Condition, List, Filtered),
    length(Filtered, Count).
like image 29
code_x386 Avatar answered Sep 28 '22 23:09

code_x386