lol([]).
lol([H|T]) :- lol(T).
lol([H|T]) :- lol(H).
I tried using this, but it returns true even for a normal 1d list. how to get exactly true for 2d list? Or list in a list.
lol([]).
lol([H|T]) :- lol(T).
lol([H|T]) :- lol(H).
I tried using this, but it returns true even for a normal 1d list. how to get exactly true for 2d list? Or list in a list.
How about this:
A list has the "list of list" quality if and only if all of its elements are lists.
Or in code, where we relax the "if and only if" equivalence to "if", which is good enough for our purposes:
% A vacuous truth:
% The empty list can be considered a list-of-lists as it contains
% nothing at all
list_of_lists([]).
% A list with at head element E is a list-of-lists if E is a list
% and and the Rest of the list is a list-of-lists.
list_of_lists([E|Rest]) :- actually_a_list(E), list_of_lists(Rest).
What's this actually_a_list(E)? It's where we test whether E is actually a list.
% The empty list is actually a list
actually_a_list([]).
% A list with at head element we don't care about and name `_`
% is actually a list if the Rest of the list is actually a list
actually_a_list([_|Rest]) :- actually_a_list(Rest).
And so:
?- list_of_lists([]). % certainly a list-of-lists
true.
?- list_of_lists(foo). % clearly not a list, and not a list-of-lists
false.
?- list_of_lists([a,b,c]). % a list but not a list-of-lists
false.
?- list_of_lists([[a],[b,c]]). % here is one!
true.
?- list_of_lists([[a],x,[b,c]]). % nope
false.
?- list_of_lists([a,b|c]). % this is not even a list
false.
In case we give the predicate an "open list" which has an unbound ending, in generates trivial endings containing only open lists:
?- list_of_lists([[a,b],[c,d]|Fin]).
Fin = [] ;
Fin = [[]] ;
Fin = [[], []] ;
Fin = [[], [], []]
...
or perhaps clearer:
?- L=[[a,b],[c,d]|_],list_of_lists(L).
L = [[a, b], [c, d]] ;
L = [[a, b], [c, d], []] ;
L = [[a, b], [c, d], [], []] ;
L = [[a, b], [c, d], [], [], []] ;
L = [[a, b], [c, d], [], [], [], []] ;
L = [[a, b], [c, d], [], [], [], [], []]
...
1- lil predicate will check how many inner lists we have. If greater than 0 than return true, else false.
2- is_list built-in will check each H if it is a list.
3- Count will count each time is_list finds a list.
4- sum predicate simply sums the count list, i.e. [1,1,1] = 3.
lil([H|T]):-
Count=1,
lil1([H|T],Count,TotalCount),
sum(TotalCount,Sum),
Sum>0.
lil1([],_,[]).
lil1([H|T],Count,[Count|List]):-
is_list(H),
Count1 is Count+0,
lil1(T,Count1,List).
sum([],0).
sum([H|T],S):-
sum(T,S1),
S is S1+H.
Example:
?- lil([]).
false
?- lil([[w],[v,v,v]]).
true
?- lil([a,n,b,b]).
false
?- lil([[w],[v,v,v],s]).
false
?- lil([[w],[v,v,v],[s,s,s,s]]).
true
?- lil([[w]]).
true