5

私が次のものを持っているとしましょう:

parent(alice, charlie).
parent(bob, charlie).
parent(bob, diane).
parent(alice, diane).
parent(bob, eve).
parent(alice, eve).    

% people are siblings of each other if they share a parent 
% and aren't the same person.
sibling(A, B) :-
  parent(X, A),
  parent(X, B),
  B \= A.

ダイアンの兄弟を尋ねると、チャーリーとイブが 2 回見つかります。1 回はボブから、もう 1 回はアリスからです。私はそれぞれ一度だけ欲しい。
バックトラックを完全に防ぐため、ここでカットを使用できるとは思いません。私が望むのは、存在するかどうを確認する方法です。

言い換え

sibling(A, B) :-
  ∃(parent(X, A), parent(X, B)),
  B \= A.

いくつかのカットを試しましたが、うまくいきませんでした。結果のリストが空でないかどうか
を試しfindall/3てみましたが、それはAまたはBを統一しません.(parent(X, A), parent(X, B))


setof/3以下で提案されているように使用すると機能しますが、質問で使用するのではなく、 の定義に組み込む方法を本当に見つけたいと思っていますsibling/2。私は本当に次のことができるようになりたいです:

?- sibling(diane, X).
X = charlie ;
X = eve ;
false.

またはこれ

?sibling(X, Y).
X = charlie,
Y = diane ;
X = charlie,
Y = eve ;
X = diane,
Y = charlie ;
X = diane,
Y = eve ;
X = eve,
Y = charlie ;
X = eve,
Y = diane ;
false.

以下で述べたように、この特定のケースに対する解決策があります。私が望んでいること、そして私が報奨金を設定しているのは、一般的な解決策です。

それ以外の

sibling(A, B) :-
  setof(D, X^(parent(X, A), parent(X, D)), Ds),
  member(B, Ds),
  B \= A.

やりたい

sibling(A, B) :-
  exists(X^(parent(X, A), parent(X, B))),
  B \= A.

Aとを一体化するものB

を定義するにはどうすればよいexists/1ですか?

4

4 に答える 4

5

Prolog でのカットの使用は非常にデリケートです。ほとんどのカットは本質的に正しくありませんが、特定の状況では引き続き機能します。正確に 1 つの答えが必要な場合は、ここでカットを使用できます。しかし、セット全体が必要なので、運が悪いです。そのセットを決定するには、すべての答えを調べる必要があります。

幸いなことに、そのためのエレガントなショートカット (しゃれを意図したもの) がありますsetof/3。だから聞いて

?- setof(t, sibling(diane, S), _).

のこの使用法でsetof/3は、最後の引数は重要ではありません。それは実際にあり[t]ます。

一般的な目的のためexists/1に、定義する

exists(XGoal) :- setof(t, XGoal, _).

これにより、存在量指定子を使用できます。

于 2013-11-23T20:18:15.910 に答える
1
parent(alice, charlie).
parent(bob, charlie).
parent(bob, diane).
parent(alice, diane).
parent(bob, eve).
parent(alice, eve).
    
% people are siblings of each other if they share a parent 
% and aren't the same person.
sibling(A, B) :-
  setof(D, X^(parent(X, A), parent(X, D)), Ds),
  member(B, Ds),
  B \= A.
    
?- sibling(X, Y).
X = charlie,
Y = diane ;
X = charlie,
Y = eve ;
X = diane,
Y = charlie ;
X = diane,
Y = eve ;
X = eve,
Y = charlie ;
X = eve,
Y = diane ;
false.

今、これを一般的な使用のためにメソッドに抽出する方法を考えていexists/1ます。

于 2013-11-23T23:35:33.107 に答える