2

次のように定義されたユーザーファクトのリストがあります。

user(@michael).
user(@ana).
user(@bob).
user(@george).
user(@john).

等々。さらに、次のような一連の事実があります。

follows(@michael,@ana).
follows(@ana,@bob).
follows(@bob,@michael).

user1 が間接的に user2 をフォローしているかどうかを教えてくれる関係 indirect(user1,user1) を書き込もうとしています。しかし、循環関係をなくすことはできません。

与えられた例のように、マイケル -> アナ -> ボブ -> マイケルはサイクルを引き起こします。

indirect(user1,user2) の結果からこれらのサイクルを排除する最良の方法は何ですか?

4

2 に答える 2

2

これまでに「見た」ユーザーの追加リストを渡し、これらのユーザーから発信されたフォローを無視するルールを作成できます: follows(A, B, Seen).

これを行うには、次のように、実際のルールをラップする「推移に従う」ルールを定義します。

follows_tx(A, B) :- follows(A, B, []).

follows/3これで、次のようにルールを定義できます。

follows(A, B, Seen) :-
    not_member(B, Seen),
    follows(A, B).
follows(A, B, Seen) :-
    follows(A, X),
    not_member(X, Seen),
    follows(X, B, [A|Seen]).

基本節は、A次の事実がある場合、以前にB見たことがない限り、述語が証明されたと見なすことを示していますB

それ以外の場合は、 をフォローしている人を見つけA、 をチェックしてそのユーザーをまだ見ていないことを確認しnot_member/2、最後にそのユーザーがBを直接的または間接的にフォローしているかどうかを確認します。

最後に、定義方法は次のnot_memberとおりです。

not_member(_, []).
not_member(X, [H|T]) :- dif(X, H), not_member(X, T).

デモ。

于 2014-12-02T21:24:49.290 に答える