0

このdel/3述語に対してこのクエリがどのように機能するかについては疑問があります。

/* BASE CASE: If I delete X from List and X is the HEAD of List, NewList is
              the Tail of List
*/
del(X, [X|Tail], Tail).

/* GENERAL CASE: If the head of List is not X then the program have to delete
                 X in the Tail of List
*/
del(X, [Y|Tail], [Y|Tail1]) :- del(X, Tail, Tail1).

述語ロジックは非常に単純です: リストから X 項目を削除し、X なしで新しいリストを作成します: X がリストの先頭にある場合、newlist はその末尾です。それ以外の場合、X 項目がリストの先頭にない場合は、Tail で検索 (および削除) して、新しい尾 Tail1 を作成します。

わかりましたので、述語ロジックに問題はありませんが、このクエリがどのように機能するかを理解しようとして問題が発生しています (別のプログラムで使用する必要があります)。

del([Top1|Stack1], [[a,b,c],[],[]], Stacks1).

したがって、このクエリは、スタックのリストである[[a,b,c],[],[] ]から[ Top1|Stack1]を削除する必要があります (この特定のケースでは、[a,b,c] の 3 つのスタックがあります)。および 2 つの空のスタック: []) Stacks1という名前のスタックの新しいリストを生成する

クエリのトレースを実行しようとすると、次のようになります。

[trace]  ?- del([Top1|Stack1], [[a,b,c],[],[]], Stacks1).
   Call: (7) del([_G389|_G390], [[a, b, c], [], []], _G412) ? creep
   Exit: (7) del([a, b, c], [[a, b, c], [], []], [[], []]) ? creep
Top1 = a,
Stack1 = [b, c],
Stacks1 = [[], []] .

理由を理解するのにいくつかの困難があります: [Top1|Stack1]は最初のスタック[a, b, c]と統合されています

編集:おそらくこのように機能すると思います: スタックのリストは: [[a,b,c],[],[]]です。これは、最初のリストが [a,b,c] であるリストのリストです: [a,b,c] ] (これはリストのこのリストの先頭です**

したがって、[Top1|Stack1]と書くと、次のようになります。

トップ 1 = [a,b,c] *スタック 1 = [[],[]] *

そのため、 Top1スタック リストの最初のスタックでありStack1は他のスタックのリストです。

だから私が述語を書くとき:

 del([Top1|Stack1], Stacks, Stacks1).

(例: Stacks = [[a,b,c],[],[]] )

次のように動作します。

スタック リストの最初のスタック[a,b,c]で Top1 を統合し、スタック リストから削除します...

次のように単純なクエリを実行すると、Prolog セマンティック Viz に関連する問題が発生します。

del(b, [a,b,c], NewList).

リストから b 項目を削除し、NewList=[a,c]

しかし、削除したアイテムのフィールドが次のようなものになった場合: [Head|Tail]削除する必要があるのは Head アイテムですか?

4

1 に答える 1

3

クエリは、の要素の中からD=[[a,b,c],[],[]], del([A|B], D, C)一致するリストを選択します。ここでの唯一の可能性はで、残り物はです。[A|B]D[A|B]=[a,b,c]C=[[],[]]

一般delに、すべての可能性を 1 つずつ見つけて、完全にバックトラックします。ここで、可能性は 1 つだけです。

をよりよく理解するには、次のことdelを試してください。

2 ?- del(X,[A,B,C],D).
X = A,
D = [B, C] ;
X = B,
D = [A, C] ;
X = C,
D = [A, B] ;
false.

「見つけようとしている」わけではありませんX。可能性の中から 1 つずつ選択するだけです (2 番目の引数)。それが、述語が / であると言っていることです。

もちろんリストが基本用語にインスタンス化されている場合、一部が一致せずに拒否される可能性があり、値が検索されているという印象を与えます。

4 ?- del(b, [a,b,c,d], R).
R = [a, c, d] ;
false.

5 ?- del(b, [a,b,X,d], R).
R = [a, X, d] ;
X = b,
R = [a, b, d] ;
false.

この用語[A|B]は、空でないリスト (または論理変数) と一致します。

6 ?- del([A|B], [[a],b,X,d], R).
A = a,
B = [],
R = [b, X, d] ;
X = [A|B],
R = [[a], b, d] ;
false.

7 ?- del([A|B], [[a],b,[],d], R).
A = a,
B = [],
R = [b, [], d] ;
false.

したがって、たとえばdel([A|B], [[1,2,3], [4,5], [], [6]], R)、このサンプル呼び出しの 2 番目の引数で指定された 4 つのリストから空でないリストが選択され、それが行われている間、選択されたリストAの先頭要素とB残りの要素にバインドされます。

この述語はselect/3in the wild として知られています。:)


図:

del(X, [X|Tail], Tail).

     X        X
     --------------------
              T        T
              a        a
              i        i
              l        l

del(X, [Y|Tail], [Y|Tail1]) :- del(X, Tail, Tail1).

              Y        Y
     --------------------
              T        T
       /      .        a
     X -      .        i
       \      .        l
              .        1
              l
于 2013-05-09T12:33:44.890 に答える