4

リストをフラットにする関数を書く必要があります。

例えば:

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

3 に答える 3

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

これは、Jan Wielemaker と Richard O'Keefe による swi-prolog ソリューションです。コードは、prolog のライブラリ ディレクトリの lists.pl ファイルにあります。

于 2012-06-27T09:27:48.397 に答える
1

編集されたコード (コメントを参照)

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] .
于 2012-06-27T12:11:22.497 に答える
0

そのバン (...flat(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.
于 2012-06-27T06:56:34.087 に答える