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).

以及确定两种药物是否相互作用的函数:

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

我试图列出两种给定药物的所有相互作用。鉴于两种药物相互作用(interacts_with()返回true),我将如何收集这两种药物相互作用的副作用?

例如:

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.

两者setoffindall返回false,而不是传入的药物清单

4

1 回答 1

4

首先,您的知识库包含事实相互作用/3:两种药物及其相互作用。然后定义一个谓词 interacts_with/2,它只有两种药物作为参数。交互隐藏在规则主体中,因此无法从规则头部访问,规则头部本质上是它的接口。再次查看 interacts/3,您可以交互地查询它以了解两种药物组合的效果:

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

请注意,查询的结果I是作为变量保留的谓词参数 ( ) 之一。然后,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 回答