Reputation: 836
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
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
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 prolog-dif 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
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