1

私は関係でいっぱいのファクトベースを持っていますinteracts:

% Drug, Drug, Interaction Effect
interacts(terbinafine,tramadol,muscle_spasm).
interacts(terbinafine,triazolam,amnesia).
interacts(terbinafine,warfarin,arterial_pressure_nos_decreased).
interacts(terbinafine,warfarin,bradycardia).
interacts(terbinafine,rosiglitazone,hyperglycaemia).
interacts(terbinafine,allopurinol,arterial_pressure_nos_decreased).

そして、2 つの薬物が相互作用するかどうかを判断する関数:

interacts_with(D1, D2) :-
  interacts(D1, D2, _) ; interacts(D2, D1, _).

与えられた 2 つの薬物の相互作用効果をすべてリストアップしようとしています。2 つの薬が相互に作用する ( interacts_with()return true) 場合、相互作用する 2 つの薬の副作用を収集するにはどうすればよいでしょうか?

例えば:

interacts_with(terbinafine, warfarin).

返す必要があります:

[arterial_pressure_nos_decreased, bradycardia]

を試してみましたがfindall/3、渡したものだけが、存在するより多くの一致を含むリストに返されます:

?- findall([terbinafine, warfarin], interacts_with(D1, D2), Foo).
Foo = [[terbinafine, warfarin], [terbinafine, warfarin], [terbinafine, warfarin], [terbinafine, warfarin], [terbinafine, warfarin], [terbinafine, warfarin], [terbinafine, warfarin], [terbinafine|...], [...|...]|...].

編集

@false が提案したものを実装しようとしました:

    interacts_with(D1, D2) :-
        interacts(D1, D2, _) ; interacts(D2, D1, _).

    print_effects(D1, D2) :-
        ( interacts_with(D1,D2)
            -> findall([D1, D2], interacts_with(D1, D2), [])
            ; write(D1), write(" does not interact with "), write(D2)
        ).

そして今、私は得ています:

?- print_effects(terbinafine, warfarin).
false.

渡された薬物のリストではなく、setofとの両方findallが返されます。false

4

1 に答える 1

4

まず第一に、知識ベースは事実の相互作用/3 で構成されています: 2 つの薬物とその相互作用です。次に、引数として 2 つの薬物のみを持つ述語 interacts_with/2 を定義します。インタラクションはルールの本体に隠されているため、基本的にはルールのインターフェースであるルールの先頭からアクセスすることはできません。interacts/3 をもう一度見てみると、2 つの薬を組み合わせた効果をインタラクティブに問い合わせることができます。

   ?- interacts(terbinafine,warfarin,I).
I = arterial_pressure_nos_decreased ? ;
I = bradycardia

クエリの結果はI、変数として残される述語引数 ( ) の 1 つであることに注意してください。Prolog は、この変数を両方の薬物に一致するすべての相互作用と統合しています。これは、頭からアクセス可能と書いたときに上で意味したことです...これは本質的にそのインターフェースです。findall/3 または setof/3 を使用して、上記のクエリのすべてのソリューションをリストとして一度に取得できます。

   ?- findall(I,interacts(terbinafine,warfarin,I),AI).
AI = [arterial_pressure_nos_decreased,bradycardia]

   ?- setof(I,interacts(terbinafine,warfarin,I),AI).
AI = [arterial_pressure_nos_decreased,bradycardia]

後者は、重複がある場合はリストから削除します。

于 2016-04-15T19:17:04.407 に答える