1

宿題のため、明示的なものは何もありません。

見つかった他のゴールを無視しながら、プログラムによって見つかった最初のゴールのみを返すように Prolog を取得する方法はありますか?

説明のために、プログラムを以下に示します。

permutation([X|Xs],Zs):-permutation(Xs,Ys), insert(X,Ys,Zs).
permutation([],[]).

プログラムが唯一の解決策として最初の順列のみを返すようにする方法はありますか? 次の場合:

| ?- permutation([1,2,3],X).

X = [1,2,3] ? ;

X = [1,3,2] ? ;

X = [2,1,3] ? ;

X = [2,3,1] ? ;

X = [3,1,2] ? ;

X = [3,2,1] ? ;

no

いただけますか

X = [1,2,3] ?;
no

解決策として?

4

3 に答える 3

6

カットはあなたが探しているコントロールです。ソリューションにコミットする必要がある場所に配置します(ここではトップレベルだと思います)。組み込みのonce/1もあり、コミットの範囲を「ローカルに」制限できます (たとえば、findall/3 でインライン化された接続詞の内部で役立ちます)。

于 2011-11-22T08:21:14.637 に答える
4

Prolog は、検索ツリーで別の分岐が可能な場合はいつでも選択ポイントを設定します。選択ポイントへのバックトラックとそのような代替案の探索を避けるために、カット ( !/0) を追加する必要があります。

プログラムのどこに選択ポイントが設定されているかを確認し、その呼び出しの後にカットを追加する必要があります。

于 2011-11-22T08:27:50.313 に答える
2

最初の解決策に固執する最善の方法はonce/1、これにより効果が可能な限りローカルに保たれるためです。の適用範囲がより広いため、を使用!/0すると、すでに意図しない効果が生じることがよくあり!/0ます。( X = 1 ; X = 2 ; X = 3 )非常に簡単な例を見てみましょう:

p(X) :- ( X = 1 ; X = 2 ; X = 3 ).
p(4).

を使用すると、次のonce/1ようになります。

p1(X) :- once( ( X = 1 ; X = 2 ; X = 3 ) ).
p1(4).

?- p1(X).
X = 1 ;
X = 4.

を使用する!と、1 つの答えしか得られません。

p2(X) :- ( X = 1 ; X = 2 ; X = 3 ), !.
p2(4).

?- p2(X).
X = 1.

多くの場合、これは意図したものではありません。

しかし、最初の解決策にコミットすることには、より一般的な問題があります。

?- p1(2).
true.

?- dif(X,1),p1(X).
X = 2 ;
X = 4.

それで、2も最初の解決策ですか?このような理由から、コミットは非常に慎重に使用する必要があります。揺るぎないものと同様の振る舞いを示す述語p1/1。このような述語は、実際のクエリによって意味が変わるため、関係として理解できません。

于 2011-11-22T18:04:15.910 に答える