3

次のルールがあります。

noRepetition([]).
noRepetition([Elem|Rest]):- not(member(Elem,Rest)), !, noRepetition(Rest).

このルールは、リストに繰り返し要素がないかどうかを決定するために作成され、メンバー ルールは、特定の要素がリストに属しているかどうかを決定します。私の質問は、このルールのカット演算子に関するものです。なぜなら、それが何をするかわからないからです。

私は次のトレースを作成しましたが?-noRepetition([a,b,b,c,d])、問題に遭遇しました (おそらくカット演算子の理解不足に関連しています):

?-noRepetition([a,b,b,c,d])
Unfies with the second noRepetion rule and instantiates variables to:
noRepetition([a|b,b,c,d] :- not(member(a,[b,b,c,d])), !, noRepetition([b,b,c,d]).

この場合、not member が true を返すため、カットが true であることが証明されたので、私は立ち往生していますが、このカットがプログラムが noRepetition (3 番目の目標) に行くのを妨げているのか、それとも何か他のことをしているのかはわかりません。実際にプログラムが noRepetition に移行するのを防ぐ場合、このルールは true と評価されますが、リストに繰り返しがあるため、これは当てはまりません。

4

2 に答える 2

4

あなたの質問に。私の意見:カットは不要です。カットが何をするかについての記憶をリフレッシュしたいかもしれません。ここに短い要約があります。経験則としては、カット前の最後のゴールを見て、それが選択ポイントを残しているかどうかを確認することです。そうであれば、それらはすべて破棄され (この節本体内の以前の目標からのすべての選択ポイントと共に)、最初の解決策のみが残されます。したがって、次のことを確認します。

\+ member(Elem, Rest) % just another way to say not...

これはいつ選択ポイントを残すことができますか? \+ Goalが false の場合はtrue Goal、そうでない場合は false。私が知る限り、\+ Goalが 2 回以上 true になることはありません。また、2 回以上 false になることもありません。では、なぜカットが必要なのですか?この状況では不要であり、実際には何もしません。

(そもそもなぜそこにカットを入れたのか知りたいです。否定 on を使用しない同様の述語はありましたmember/2か?)

より良い解決策を提供することは質問者に嫌われますが、この問題を解決するには少なくとも 2 つの方法があります。次の定義のために、それらをマッシュアップすることもできます。

all_dif_list(L) :-
    (   ground(L)
    ->  sort(L, S),
        length(L, N),
        length(S, N)
    ;   all_dif_list_nonground(L)
    ).

all_dif_list_nonground([]).
all_dif_list_nonground([X|Xs]) :-
    maplist(dif(X), Xs),
    all_dif_list_nonground(Xs).

リストが完全にインスタンス化されていることがわかっている場合は、並べ替えて長さを比較できます。sort/2重複を削除するため、繰り返しがあった場合、ソートされたリストは短くなります。

リストに変数が含まれている場合、リスト内の要素の各ペアが (そして常に) 異なると言うだけで安全です。

member/2また、単純な名前と単純な定義が示唆するよりも複雑であることを覚えておいてください。member/2もし私がそれから恩恵を受けると思ったら、私は簡単に の行動について 1000 語のエッセイを書くことができました.

于 2016-05-20T22:40:02.727 に答える
0
noRepetition([]).
noRepetition([Item|Rest]) :- member(Item,Rest), !, fail.
noRepetition([_|Rest]) :- noRepetition(Rest).

注: Item が基本用語でない場合、予期しない結果になる可能性があります。例えば:

noRepetition([X,a,b]).

失敗します...

于 2016-05-25T09:38:55.493 に答える