Prolog - Return 如果列表的元素是空列表则为 false
Prolog - Return false if element of a list is an empty list
我想确保列表不包含空列表,但我的尝试似乎没有效果:
Predic(X) :- foreach (member (A, X) A \= []).
谁能提供 correction/better 替代方案?
谢谢
您希望列表不包含空列表。这强烈建议您否则需要一个非空列表。
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).
使用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/2
和dif/2
:保证L
不会包含[]
如果您想保证部分列表 L
的任何未来实例在其元素 和 中没有 []
L
是一个自由变量,不会与[]
统一,则使用dif/2
(更多示例参见prolog-dif)和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, []) .
好吧,你可以自己动手:
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=[]),[]) .
我想确保列表不包含空列表,但我的尝试似乎没有效果:
Predic(X) :- foreach (member (A, X) A \= []).
谁能提供 correction/better 替代方案?
谢谢
您希望列表不包含空列表。这强烈建议您否则需要一个非空列表。
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).
使用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/2
和dif/2
:保证L
不会包含[]
如果您想保证部分列表 L
的任何未来实例在其元素 和 中没有 []
L
是一个自由变量,不会与[]
统一,则使用dif/2
(更多示例参见prolog-dif)和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, []) .
好吧,你可以自己动手:
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=[]),[]) .