1

私はPrologが初めてで、理解しようとしています。

私はいくつかの簡単なプログラムから始めました。これは次のようにする必要があります。

  • 要素がリストの残りの部分に含まれているかどうかを確認します
    • FALSE の場合は何もしない
    • TRUE の場合、2 番目のリストに追加します。(2 番目のリストには char を 1 回だけ追加する必要があります)。

期待される結果の例:

?- occ([a,b,c,a,a,b,e,f,g], Y).
Y = [a,b].

?- occ([a,a,a,a,a], Y).
Y = [a].

?- occ([a,b,c,d,e,f,g], Y).
Y = [].

これが私が書いたコードですが、いくつか問題があります (常に を返しますtrue)。

occ([],[]).
occ([],_Y).
occ([X|Xs],[X|Y]) :-
   occ(Xs,Y),
   member(X,Xs),
   not(member(X,Y)),
   !.
occ([_X|_Xs],_Y).

デバッガーを使用してみましたが、not(member(X,Y))is alwaysfalseであり、バインディング セクションにはXand Xsand neverしかないことがわかりましたY。どんなアドバイスでも大歓迎です!ありがとうございました。

アップデート

私はそれを解決したと思います、これがコードです:

occ([],[]).
occ([X|Xs],[X|Y]) :-
   occ(Xs,Y),
   member(X,Xs),
   not(member(X,Y)),
   !.
occ([_X|_Xs],[]).

しかし、なぜ今それが機能するのかよくわかりません... 3番目にwithoccを変更しました..しかし、なぜ結果が変わるのですか?_Y[]

4

1 に答える 1

2

この回答では、 をand とtpartition/4組み合わせて使用​​します。if_/3(=)/3

list_duplicateset/2次のように定義します。

list_duplicateset([], [])。
list_duplicateset([E|Xs0], Ys0) :-
   tpartition ( = (E), Xs0, Es, Xs),
    if_ (Es = [],
       Ys0 = Ys,
       Ys0 = [E|Ys]),
   list_duplicateset(Xs, Ys)。

まず、同様の質問に対するこの回答から抜粋したサンプル クエリを実行します。

?- list_duplicateset([1,2,2,3,4,5,7,6,7], Xs). 
Xs = [2,7].

次に、OP が指定したクエリを実行しましょう。

?- list_duplicateset([a,b,c,a,a,b,e,f,g], Xs).
Xs = [a, b].

?- list_duplicateset([a,a,a,a,a], Xs).
Xs = [a].

?- list_duplicateset([a,b,c,d,e,f,g], Xs).
Xs = [].

上記のすべてのクエリは、期待どおりの回答を提供し、決定論的に成功することに注意してください。

于 2015-11-26T16:01:53.720 に答える