'Write a predicate called rlen(X,N) to be true when N counts the total number of occurrences of atoms in the list X

I want to get this solution for my question. For example, ?- rlen([a,[a,b],c],X). returns X = 4. I tried the following code but it returns answer 3. Maybe, it's taking [a,b] as one element. I am new to prolog and learning, any help would be really appreciated.

rlen([],0).
rlen([_|T],N) :- rlen(T,N1),N is N1+1. 


Solution 1:[1]

The code you wrote returns the number of elements in a list and [a,[a,b],c] has exactly 3 elements: a, [a,b] and c. If you want to do a nested count, I would suggest using the build-in predicate flatten/2 to flatten the list.

example (tested with SWISH):

?- rlen([a,[a,b],c],X).
X = 3.

?- flatten([a,[a,b],c],L).
L = [a, a, b, c].

?- flatten([a,[a,b],c],L), rlen(L,N).
L = [a, a, b, c],
N = 4.

However not using inbuild predicates is a bit more challenging, because you have to go through your list like in any normal length predicate, and for every Head element you have to distinguish between the case that the head element is a list or is not a list. If A is a list, count the elements of A, otherwise just add 1. (a -> b ; c ) is an if-then else: if a, then b, else c. Tested with SWISH:

rlen([],0).
rlen([A|T],N) :- 
    (   is_list(A)
    ->  rlen(A,NA)
    ;   NA is 1
    ), 
    rlen(T,NT),
    N is NA+NT.   

?- rlen([a,[a,b],c],X).
X = 4.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1