Reputation: 35
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.
Upvotes: 2
Views: 630
Reputation: 878
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
Upvotes: 0
Reputation: 15316
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], [], [], [], [], []]
...
Upvotes: 3