views:

812

answers:

2

How can I count nested list elements in prolog?

I have the following predicates defined, which will count a nested list as one element:

length([ ], 0).
length([H|T],N) :- length(T,M), N  is  M+1.

Usage:

?- length([a,b,c],Out).
Out = 3

This works, but I would like to count nested elements as well i.e.

length([a,b,[c,d,e],f],Output).
?- length([a,b,[c,d,e],f],Output).

Output = 6

A: 

I have managed to figure it out. It doesn't look like the most elegant solution:

append([],L,L).
append([X|L1],L2,[X|L3]) :- append(L1,L2,L3).

length([ ], 0). 
length([H|T],N) :- length(T,M) ,  N  is  M + 1.

flatten([],[]).
flatten([[]|L],L).
flatten([X|L1],[X|L2]) :- atom(X), flatten(L1,L2).
flatten([X|L1],L4) :- flatten(X,L2),
                      flatten(L1,L3),
                      append(L2,L3,L4).

count_list([], 0).
count_list([H|T],N) :-  flatten([H|T],O), length(O,N).
idea
+1  A: 
len([H|T],N) :-
    len(H, LH),
    len(T, LT),
    !,
    N is LH + LT.
len([], 0):-!.
len(_, 1):-!.

Test:

?- len([a,b,[c,d,e],f],Output).
Output = 6.
Xonix