3

カットの使い方がよくわかりません。たとえば、この場合: flatten、本当に必要ですか? 両方のカット述語がなくても機能します(削除してみました)。カットにバックトラックが発生する可能性があるのはどのような場合ですか? カットを削除すると、本「The art of prolog」(Shapiro E.、Sterling L.) と同じ実装が得られます。

flatten([X|Xs],Ys) :-
    flatten(X,Ysl), 
    flatten(Xs,Ys2), 
    append(Ys1,Ys2,Ys).
flatten(X,[X]) :- 
    constant(X), 
    X\=[].
flatten([],[]).

これは別の質問につながります.2番目の節でリストではないかどうかを確認する必要がありますか? 単項だと前節と統一しない…ですね。

4

1 に答える 1

2

質問にリンクされているプログラムは、カット!演算子を使用して、回答のコードが他の句と統合されるのを防ぎます。flatten2/2答えからのこれらの切り取りがなければ、最初の引数の空のリストを句 1 と 3 で統一します。つまり、

flatten2([], []) :- !.
flatten2(L, [L]).

同様に、2 番目の句をカットしないと、2 番目flatten2/2と 3 番目の句で空でないリストが統合され、誤った動作につながります。

一方、コードには、 の各節がflatten/21 つの特定の状況を確実に処理するための明示的なチェックがあります。

  • 最初の句は、空でないリストを再帰的に平坦化します
  • 2 番目の節は、空リスト以外の定数から単一項目のリストを作成します
  • 3 番目の句は、空のリストを「平坦化」します。

各条項は左側の 1 つのタイプのアイテムにのみ適用されるため、カットは必要ありません。2 番目と 3 番目の節を切り替えて、空のリストに一致した後にカットを追加することで、コードをカットで書き直すこともできますが、これを行うことはお勧めしません ( demo )。

それがリストではないかどうかを確認するために2番目の句が必要ですか?

空のリストは定数と見なされるため、このチェックが必要です。そのため、フラット化されるリスト ( demo[] )に空のリストが存在すると、プログラムが正しく動作しなくなります。

于 2015-09-14T16:06:24.743 に答える