Prolog 查找具有匹配谓词的所有事实

Prolog 查找具有匹配谓词的所有事实,prolog,prolog-setof,Prolog,Prolog Setof,我有一个充满互动关系的事实库: % Drug, Drug, Interaction Effect interacts(terbinafine,tramadol,muscle_spasm). interacts(terbinafine,triazolam,amnesia). interacts(terbinafine,warfarin,arterial_pressure_nos_decreased). interacts(terbinafine,warfarin,bradycardia). int

我有一个充满互动关系的事实库:

% 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, _).
我试图列出两种给定药物的所有相互作用效应。鉴于两种药物相互作用(
interactions_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.

setof
findall
都返回了
false
而不是传入的药物列表。首先,你的知识库由事实相互作用/3组成:两种药物及其相互作用。然后定义一个谓词与/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]

后者将删除列表中的重复项(如果有)。

首先,您的知识库由相互作用的事实组成/3:两种药物及其相互作用。然后定义一个谓词与/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]

后者从列表中删除重复项(如果有)。

。。。findall([D1,D2],与(D1,D2),Foo进行交互。
可以。但是,应该使用
setof(D1-D2,与(D1,D2),Foo交互)
。这也会删除重复项。我已经尝试实现了您的建议,现在我得到了
false
请重新阅读我写的内容。我从来没有建议你写你现在做的事
findall(…,…,[])
在这个上下文中没有任何意义
。。。findall([D1,D2],与(D1,D2),Foo进行交互。
可以。但是,应该使用
setof(D1-D2,与(D1,D2),Foo交互)
。这也会删除重复项。我已经尝试实现了您的建议,现在我得到了
false
请重新阅读我写的内容。我从来没有建议你写你现在做的事
findall(…,…,[])
在这种情况下毫无意义
setof
不仅删除重复项:其结果与如何找到解决方案的顺序无关。
setof
不仅删除重复项:其结果与如何找到解决方案的顺序无关。