Prolog - 如果列表的元素是空列表,则返回false

时间:2015-01-20 16:17:17

标签: list prolog

我想确保一个列表不包含空列表,但是我的尝试似乎不起作用:

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

任何人都可以提供更正/更好的替代方案吗?

由于

3 个答案:

答案 0 :(得分:2)

您希望列表不包含空列表。这强烈建议你想要一个非空列表。

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).

答案 1 :(得分:1)

使用foreach/2:循环播放部分列表

您的解决方案只需要一些小的修正:

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

如果L是列表,则此方法有效:

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

但如果L是部分列表,则循环:

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

并且它不是纯粹的,并且由于后来的统一可能导致像这样的结果:

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

仅使用member/2:部分列表失败

检查元素之间的统一失败和[] [而不是测试非等价]通过失败解决了上述问题。

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

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

使用maplist/2dif/2:它保证L不会包含[]

如果您想保证部分列表L的任何未来实例化在其元素中没有[]L的任何元素都可以是免费变量不会与[]统一,然后使用dif/2(有关更多示例,请参阅)和maplist/2。见这个例子:

?- 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, []) .

答案 2 :(得分:1)

嗯,你可以自己动手:

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

另一种选择可能是使用member/3

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

您可以使用append/3,但在此上下文中,它不会对member/2提供任何改进:

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

你甚至可以使用findall/3(但同样,你也可以使用member/2):

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