Prolog 列出清单
我需要写一个函数,使列表平坦 例如:Prolog 列出清单,prolog,dcg,Prolog,Dcg,我需要写一个函数,使列表平坦 例如: flat([ c , [[[]]] , [] , k] , X). X=[c,k] 这就是我所做的: flat([],[]). flat([[A] |B] , R) :- flat([A|B],R). flat([[]|L],L1) :- flat(L,L1).! flat([[A|L]|W],R) :- flat([A|L],U), flat(W,W1), append(U,W1,R). flat([A|L], [
flat([ c , [[[]]] , [] , k] , X).
X=[c,k]
这就是我所做的:
flat([],[]).
flat([[A] |B] , R) :- flat([A|B],R).
flat([[]|L],L1) :- flat(L,L1).!
flat([[A|L]|W],R) :- flat([A|L],U), flat(W,W1), append(U,W1,R).
flat([A|L], [A|L1]) :- flat(L,L1).
我知道为什么这不是真的,但我不知道如何做到这一点。
谢谢
编辑:
几乎有效:
flat([],[]).
flat([[]|L],L1) :- flat(L,L1). --- i think something here missing
flat([[A|L]|W],R) :- flat([A|L],U), flat(W,W1), append(U,W1,R).
flat([A|L], [A|L1]) :- flat(L,L1).
?- flat([c , [[[]]] , [] , k],C).
C = [c, k] ;
C = [c, [], k] ;
C = [c, [], k] ;
C = [c, [], [], k] ;
C = [c, [[]], k] ;
C = [c, [[]], [], k] ;
C = [c, [[[]]], k] ;
C = [c, [[[]]], [], k].
那个砰的一声(…平坦的(L,L1)。!…)是个打字错误,不是吗
您可以研究SWI Prolog中的一个示例,它公开了它的代码并给出了预期的结果:
?- flatten([ c , [[[]]] , [] , k] , X).
X = [c, k].
否则,试着用一个简单的例子进行调试,看看你的代码在清理后失败的地方。
顺便说一句,您的代码似乎工作正常,只是产生了更多的解决方案,您需要删除一些不需要的路径:
?- flat([c , [[[]]] , [] , k],C).
C = [c, k] ;
C = [c, [], k] ;
C = [c, [], k] ;
C = [c, [], [], k] .
...
编辑以下是来自SWI Prolog库(列表)的代码
%% flatten(+List1, ?List2) is det.
%
% Is true if List2 is a non-nested version of List1.
%
% @deprecated Ending up needing flatten/3 often indicates,
% like append/3 for appending two lists, a bad
% design. Efficient code that generates lists
% from generated small lists must use difference
% lists, often possible through grammar rules for
% optimal readability.
% @see append/2
flatten(List, FlatList) :-
flatten(List, [], FlatList0), !,
FlatList = FlatList0.
flatten(Var, Tl, [Var|Tl]) :-
var(Var), !.
flatten([], Tl, Tl) :- !.
flatten([Hd|Tl], Tail, List) :- !,
flatten(Hd, FlatHeadTail, List),
flatten(Tl, Tail, FlatHeadTail).
flatten(NonList, Tl, [NonList|Tl]).
在您的评论中,您的代码似乎相当正确:
?- flat([1,2,[3,4]],[1,2,3,4]).
true ;
false.
这是Jan Wielemaker和Richard O'Keefe的swi prolog解决方案,
代码可以在prolog的library目录中的lists.pl文件中找到。代码已编辑(请参见注释)
另一种可能性是,使用DCG:
flat(L, FL) :-
flat(L, FL, []).
flat(X) -->
{var(X)},
!,
[X].
flat([]) -->
[],
!.
flat([X | T]) -->
flat(X),
!,
flat(T).
flat(X) --> [X].
现在我们得到:
?- flat([[a,b,c,d|r]], FL) .
FL = [a,b,c,d,r] .
?- flat([1,2,[3,4]],L).
L = [1,2,3,4] .
?- flat([1,2,[3,4]],[1,2,3,4]).
true .
?- flat([ c , [[[]]] , [] , k] , X).
X = [c,k] .
在哪里可以看到SWI prolog的实现?顺便说一句,我的例子几乎是成功的。但是这套公寓([1,2,3,4],[1,2,3,4])。返回false。我知道为什么,但我不知道如何编写好的解决方案再次感谢你,但我只需要展平(列表,平面列表)/2,而不需要展平(列表,平面列表,)/3,你说得对……这是一个工作:展平([1,2,[3,4]],[1,2,3,4])。非常好!考虑使用短语/ 2作为DCGs的官方接口。就我个人而言,我也会把这个/0位于大括号外,并将其放置在自己的行上。我认为DCG是一种非常优雅的处理方式。仔细想想,我会使用({is_list(X)}->flat(X);[X])。两者:
flat([[a,b,c,d | r]],FL)
成功地使用FL=[[a,b,c,d | r]]
。有意的?当然不是,但是,[a,b,c,d | r]不是一个合适的列表。然后把放平([[a]]| |,FL)
,这是一个包含列表的部分列表。
?- flat([[a,b,c,d|r]], FL) .
FL = [a,b,c,d,r] .
?- flat([1,2,[3,4]],L).
L = [1,2,3,4] .
?- flat([1,2,[3,4]],[1,2,3,4]).
true .
?- flat([ c , [[[]]] , [] , k] , X).
X = [c,k] .