このように機能させたいので、d
消えます。
?- remove_last_item([a,b,c,d], L).
L = [a, b, c] ?
この行を取得したので、これを行う方法を誰かが知っていますが、これに他の行を追加して、
上記を達成できるようにする必要があります。
このように機能させたいので、d
消えます。
?- remove_last_item([a,b,c,d], L).
L = [a, b, c] ?
この行を取得したので、これを行う方法を誰かが知っていますが、これに他の行を追加して、
上記を達成できるようにする必要があります。
Prolog では通常、質問を理解するということは、すでに答えを持っているということです。したがって、最後の項目がないremove_last_item(A,B)
ような述語を定義する必要があります。では、Prolog のリストとは何ですか? Lisp のように、ペアの上で再帰的に定義され、「リストの終わり」を示す特別な記号 - 空のリスト - が付けられます。B
A
どういう意味ですか?ペア は'.'(A,B)
明らかに 2 つの部分を持っています。次に、リスト[a,b,c,d]
は としてエンコードされ'.'(a,'.'(b,'.'(c,'.'(d,[]))))
ます。[a|[b,c,d]]
これは、 、 または[a,b|[c,d]]
、 または[a,b,c|[d]]
、またはと書くこともできます[a,b,c,d|[]]
。リストの「頭」と「尾」または「残り」a
と呼ばれるものは次のとおりです。[b,c,d]
[a,b,c,d]
したがって、述語に伝えたいことを、最も単純なケースから順に書き留めます。
remove_last_item([_A],[]).
remove_last_item([A|B],[A|C]):- B=[_|_], remove_last_item(B,C).
「シングルトンリストから最後の項目を削除すると、空のリストが残ります。複数の要素のリストから最後の項目を削除すると、リストの残りの部分から最後の項目を削除することを意味し、その先頭に続きます」.
編集:それを見る別の方法は、「上から始める」ことです:述語が従わなければならない同等の「法則」を書き留めます:
remove_last_item(L,R):- is_list(L), is_list(R), same_head(L,R),
tail(L,L1), tail(R,R1),
remove_last_item(L1,R1).
私たちはまだ何を「する」のかを「知らない」remove_last_item
わけではありません。しかし、それはまさに私たちが求めている定義そのものになります。連想させる名前をすべて肉付けして、
remove_last_item(L,R):- L=[A|L1], R=[A|R1], remove_last_item(L1,R1).
したがって、これをリストの構造的再帰として認識し、終了句を追加して、それに「実体」を追加するだけです。
?- append(L, [_], [a,b,c,d]).
[_]
が単一の任意の要素を持つリストを表していることを確認してください。したがって、このクエリは「単一の要素リストを追加すると、どのリストが返されるか」L
を尋ねます。[a,b,c,d]
別の方法は、プロローグに再帰を実行させることです..これは、「リスト項目のインデックスがリストの最後の項目のインデックスと等しくないリスト内のすべての項目を見つけることを意味します(そのインデックスはリスト)。(とにかくnth1を使用する場合..nth0は機能しません...
rli(List, Res) :-
length(List, Y),
findall(Item, (nth1(Idx, List, Item), not(Idx =:= Y)), Res).