AndrewB
AndrewB

Reputation: 836

Prolog - Return false if element of a list is an empty list

I would like to ensure a list does not contain an empty list, however my attempt does not seem to be working:

Predic(X) :- foreach (member (A, X) A \= []).

Can anyone offer a correction/better alternative?

Thanks

Upvotes: 1

Views: 2089

Answers (3)

Nicholas Carey
Nicholas Carey

Reputation: 74197

Well, you can roll your own:

list_does_not_contain_empty_list( []     ).
list_does_not_contain_empty_list( [X|Xs] ) :-
  X \= [] ,
  list_does_not_contain_empty_list(Xs)
  .

Another alternative might be to use use member/3:

list_does_not_contain_empty_list(Xs) :- \+ member([],Xs) .

You could use append/3, but in this context, it doesn't offer any improvements over member/2:

list_does_not_contain_empty_list(Xs) :- \+ append(_,[[]|_],Xs) .

And you could even use findall/3 (but again, you might as well just use member/2):

list_does_not_contain_empty_list(Xs) :- findall(X,(member(X,Xs),X=[]),[]) .

Upvotes: 1

Tudor Berariu
Tudor Berariu

Reputation: 4910

Using foreach/2: loops for partial lists

Your solution just needs some minor correction:

no_empty_list_inside(L):-
    foreach(member(X,L), X \== []).

This works if L is a list:

?- L = [a,b,c], foreach(member(X,L), X \== []).
L = [a, b, c].

but loops if L is a partial list:

?- L = [z,z|_], foreach(member(X,L), X \== []).
ERROR: Out of global stack

and it's not pure and might lead to results like this one due to later unifications:

?- L =[E], foreach(member(X,L), X \== []), E=[].
L = [[]],
E = [].

Using just member/2: fails for partial lists

Checking for unification failure between elements and [] [instead of testing for non-equivalence] solves the above problems by failing.

?- L = [z,z|_], \+ member([], L).
false.

?- L = [X], \+ member([], L).
false.

Using maplist/2 and dif/2: it guarantees L will not contain []

If you want to guarantee that any future instantiation of the partial list L will have no [] among its elements and that any element of L that is a free variable won't be unified with [], then use dif/2 (see for more examples) and maplist/2. See this example:

?- L=[X], maplist(dif([]), L).
L = [X],
dif(X, []).

?- L = [z,z|_], maplist(dif([]), L).
L = [z, z] ;
L = [z, z, _G1153],
dif(_G1153, []) ;
L = [z, z, _G1197, _G1200],
dif(_G1197, []),
dif(_G1200, []) ;
L = [z, z, _G1241, _G1244, _G1247],
dif(_G1241, []),
dif(_G1244, []),
dif(_G1247, []) .

Upvotes: 1

false
false

Reputation: 10102

You want that a list does not contain an empty list. This highly suggests that you want a non-empty list otherwise.

without_empty_list1([]).
without_empty_list1([E|Es]) :-
   E = [_|_],   % or more costly dif([], E)
   without_empty_list1(Es).

without_empty_list2(Es) :-
   maplist(dif([]), Es).

without_empty_list3(Es) :-
   maplist(\[_|_]^true, Es).

Upvotes: 2

Related Questions