2017-01-17 11 views
2

私は述語convert/2を書き​​たいと思っています。 それは私が最初のリストの長さを見つけるために持っていることを、私は知っている。このprologに述語変換/ 2を書くには?

? - convert([a,[a,a],[a,b],[b,a],[[a,b]],[d],c],X). 
X = [a,c,[a],[d],[a,b],[[a,b]]] 
yes 

? - convert([[a,[a,b]],[a,[c,b]],[[a,b],a]], X). 
X = [[a,[a,b]],[a,[b,c]]] 
yes 

? - convert([[a,b],[a,[a]],[a,b,c]],X). 
X = [[a,b],[a,[a]],[a,b,c]] 
yes 

のように動作するはずです。 それから私はそれを並べ替える必要があり、最後に私は要素を複製する必要があります。

+0

例は良好です。アルゴリズムを定義しようとする試みもうまくいきます。 'convert/2'が実際に何をしているのかを明示的に定義するのに役立ちます。 –

+0

各個別の要素が一度しか表示されず、特定の順序が使用されるリストにリストを減らす述語convert/2を書き​​たいと思います(おそらく 重複要素あり)。 –

+0

私は特に一つの細部を理解するのが難しいです:なぜ[[a、b] 'は' [[a、b]] 'の前に来るのですか? 'convert([[a、[b、c]]、[a、b、c]]、X)'をクエリした結果はどうなりますか? –

答えて

2

だから、あなたのソートアルゴリズムが正確に何を知らなくても、私は概念実証する、やや一般的な例を作成しました:これは再帰的にリスト内の各リストを変換し

convert(X, X) :- \+is_list(X). 
convert([],[]). 
convert([InHead|InTail], OutList) :- 
    convert(InHead, OutHead), 
    convert(InTail, OutTail), 
    append([OutHead], OutTail, UnsortedList), 
    sort(UnsortedList, DeduplicatedList), 
    custom_sort(DeduplicatedList, OutList). 

custom_sort(List,Sorted) :- 
    permutation(List,Sorted), 
    is_sorted(Sorted). 

is_sorted([]). 
is_sorted([_]). 
is_sorted([X,Y|T]) :- 
    % perform any number of tests on X and Y here 
    % default is: 
    X @=< Y, 
    is_sorted([Y|T]). 

を、その後、組み込みの並べ替えを使用しています重複を削除して、カスタムソートを適用します(単純なソートで構築されます)。

私は最初に、リストの深さ(ソートの深さが0)、リストの長さ(アトムの長さが0)、ソートアルゴリズムの要素リスト)と、次のを思い付いた:

list_length(X, 0) :- 
    \+is_list(X). 
list_length(X, Y) :- 
    is_list(X), length(X, Y). 

list_depth(X, 0) :- \+is_list(X). 
list_depth([], 0). 
list_depth([Head|Tail], Y) :- 
    list_depth(Head, YH), 
    list_depth(Tail, YTP), 
    YT is YTP - 1, 
    Y is max(YH, YT) + 1. 

is_sorted([X,Y|T]) :- 
    list_length(X, XL), 
    list_length(Y, YL), 
    list_depth(X, XD), 
    list_depth(Y, YD), 
    (XD < YD ; 
     (XD = YD, 
     (XL < YL ; 
      (XL = YL, 
      X @=< Y) 
     ) 
    ) 
    ), 
    is_sorted([Y|T]). 

を...しかし、これは[[A]]、[a、b、c]の深さ2は、深さ1に続いたあなたの第三の例、失敗のために、私はあなたの喜びのために上のコードを何よりも提示します。

編集: 私は、扁平長さでソートすると、その後、深さはこのようになりますこれは、あなたのすべての例のために働くことを実現するのボリスからのコメントは十分だった:

list_length(X, 0) :- 
    \+is_list(X). 
list_length(X, Y) :- 
    is_list(X), 
    flatten(X, Z), 
    length(Z, Y). 

list_depth(X, 0) :- \+is_list(X). 
list_depth([], 0). 
list_depth([Head|Tail], Y) :- 
    list_depth(Head, YH), 
    list_depth(Tail, YTP), 
    YT is YTP - 1, 
    Y is max(YH, YT) + 1. 

is_sorted([X,Y|T]) :- 
    list_length(X, XL), 
    list_length(Y, YL), 
    list_depth(X, XD), 
    list_depth(Y, YD), 
    (XL < YL ; 
     (XL = YL, 
     (XD < YD ; 
      (XD = YD, 
      X @=< Y) 
     ) 
    ) 
    ), 
    is_sorted([Y|T]). 
0

[OK]を、しかしすることができます組み込み関数 'sort'を他のものに置き換えますか?ここで最も重要です

+0

私はそれを解決しました。私は使った:insert(X、[]、[X])。 insert(X、[Y | Tail]、[Y | L1]): - Y @ rafaluf

+0

あなたの答えは質問であり、あなたの解答はコメントですか?これは後ろ向きです。あなたの答えを編集して質問を削除し、あなたの答えを答えに入れてください! –