Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Prolog 列出清单_Prolog_Dcg - Fatal编程技术网

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