2016-05-31 21 views
1

今日はずっとそれを掲載する予定はありませんでしたが、私はこの仕事をすることができないというのは馬鹿げています。私は3つの要素で入力リスト3を移動するための作業コードを持っています。しかし、私はそれが3つの要素のリストに対してのみ機能することを認識しました。入力すると失敗します。意味をなさないだから、私は各要素を一つずつ持ち、このように両方のリストを移動するルールを作ろうとしています。両方のリストが同じ長さなので、同時に停止して、出力リストも以前と同じにする必要があります。リストnをn個の要素で移動する方法

しかし、チャンスではなく、まっすぐに失敗します。私はこの問題を間違った方法で見ていると思います。それはそれほど難しい作業ではないからです。

3つの要素のための

元、作業のアイデア:

crearEnum(_, [], []). 
crearEnum([Ha,Hb,Hc], [[H1,H2,H3]| PermNodes], [[enum(H1,Ha), enum(H2,Hb), enum(H3,Hc)] |SalidaCreacionEnum]):- 
    crearEnum([Ha,Hb,Hc], PermNodes, SalidaCreacionEnum). 

私がこれまでに得たもの:

は私が(大きなルールのそれの一部)これでそれを呼び出す:

crearEnum(NodeListUnique, IDsPermuted, [], SalidaCreacionEnum), 


crearEnum(_, [], L, L). 
crearEnum(NodeListUnique, [CabezaPermNodes| PermNodes], [EnumsFormados |EntradaCreacionEnum], SalidaCreacionEnum):- 
    formaEnums(NodeListUnique, CabezaPermNodes, EnumsFormados), 
    crearEnum(NodeListUnique, PermNodes, EntradaCreacionEnum, SalidaCreacionEnum). 

formaEnums([],[],_). 
formaEnums([Ha|NodeListUnique], [H1|CabezaPermNodes], [enum(H1,Ha)|EnumsFormados]):- 
    formaEnums(NodeListUnique, CabezaPermNodes, EnumsFormados). 

そして私はこのハードに失敗して私に唖然としている理由であるトレース:

Call:crearEnum([c, b, a], [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]], [], _G5349) 
Fail:crearEnum([c, b, a], [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]], [], _G5349) 

基本的に私は同様の操作を行ってきましたが、これはまっすぐに失敗します。統一しているか、ベースケースなのかな?しかし、私は他のリストとの違いはあまり見られません。どのように旅行しているのか、彼らは働いているのが分かります。本当にこれについて間違っているのかは分かりません。

答えて

1

申し訳ありません。私は空のリストの頭と尾を分けようとしていたので、答えは失敗し、実行できません。

だから、このようにする必要があります:空のリストと呼ばれるように起こっている場合

crearEnum(NodeListUnique, [CabezaPermNodes| PermNodes], [EntradaCreacionEnum], SalidaCreacionEnum):- 

。それは必要以上にWAYにかかった。

+0

これは正しい解決策であると私は何とか疑う。 [tag:dcg]を使用してリストを記述するか、特定のリストを続けてインスタンス化する方がよいでしょう。後者は、 'Ls = [First | Rest]'のような目標を持つか、節の* head *に '[First | Rest]'のようなパターンがあることを意味します。 – mat

+0

与えられたリストをさらに連続的にインスタンス化した例がいくつかありますか?私はそれが私のコードを読みやすくするだけでなくパフォーマンスにも簡単にするような気がしますが、今のところ私はこの解決策に悩まされています(このような問題を解決する方法だと思います。本当に別のものを見ないでください)。 dcgについては、後で試してみるかもしれませんが、私が持っている時間にそれを習得するつもりはないと思います。 – keont

3

この場合の根本的な問題は、[First|Rest]は、 とは異なる何かを意味するということです。それは最初の要素Firstであるリストを意味します。 ではないは「で始まるリストはFirstに含まれています」という意味です。したがって、Firstがそれ自身リストである場合、[First|Rest]は最初の要素のリストであるリストです。

この問題は、特に[EnumsFormados|EntradaCreacionEnum]に記載されています。EnumsFormadosは、自体がです。

複数の述を通じて記載されているリストについてReasonsingは非常にエラーが発生しやすいと面倒なこと、そしてこのような理由のために、私たちは、PrologでDCG  表記  ()を持つことができます。これは特に、はるかに簡単にリストを記述します単一のリストの記述が複数の規則にまたがる場合。

私はあなたのユースケースに大まかに関連する1つの例を挙げます。小さな変更を加えると、このDCGを使用して重要なリストを記述することができます。私は  enum(Unique,Node)の形式の用語のリストを記述します。

 
enums([], _) --> []. 
enums([U|Us], Nodes) --> 
    enums_(Nodes, U), 
    enums(Us, Nodes). 

enums_([], _) --> []. 
enums_([N|Nodes], U) --> 
    [enum(U,N)], 
    enums_(Nodes, U). 

サンプルクエリと答え:引数がが同じ長さを持つ必要がないこと

 
?- phrase(enums([a,b], [x,y,z]), Ls). 
Ls = [enum(a, x), enum(a, y), enum(a, z), enum(b, x), enum(b, y), enum(b, z)]. 

注意!また、この定義は複数の句にまたがっていますが、リストの要素を記述するのは非常に簡単です。 DCG  構文[Terminal]は、特定のProlog用語  Terminalが記載されたリストのその位置で発生することを示すために使用されます。

関連する問題