查找具有匹配谓词的所有事实
Find all facts with matching predicates
我有一个充满 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()
returns true
),我将如何收集这两种药物相互作用的副作用?
例如:
interacts_with(terbinafine, warfarin).
应该return:
[arterial_pressure_nos_decreased, bradycardia]
我一直在尝试使用 findall/3
,但我只得到我在 return 中传递的内容,该列表包含更多存在的匹配项:
?- 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
都是 returning false
而不是传入的药物列表
首先,您的知识库包含事实interacts/3:两种药物及其相互作用。然后定义一个谓词 interacts_with/2,它只有两种药物作为参数。交互隐藏在规则的主体中,因此不能从规则的头部访问,规则的头部本质上是它的接口。再次查看 interacts/3 您可以交互式查询它以了解两种药物联合使用的效果:
?- interacts(terbinafine,warfarin,I).
I = arterial_pressure_nos_decreased ? ;
I = bradycardia
请注意,查询的结果是作为变量保留的谓词参数之一 (I
)。 Prolog 然后将此变量与匹配两种药物的所有相互作用统一起来。这就是我在上面写 accessible from the head 时的意思……本质上是它的接口。您可以使用 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]
后者会从列表中删除重复项(如果有的话)。
我有一个充满 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()
returns true
),我将如何收集这两种药物相互作用的副作用?
例如:
interacts_with(terbinafine, warfarin).
应该return:
[arterial_pressure_nos_decreased, bradycardia]
我一直在尝试使用 findall/3
,但我只得到我在 return 中传递的内容,该列表包含更多存在的匹配项:
?- 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
都是 returning false
而不是传入的药物列表
首先,您的知识库包含事实interacts/3:两种药物及其相互作用。然后定义一个谓词 interacts_with/2,它只有两种药物作为参数。交互隐藏在规则的主体中,因此不能从规则的头部访问,规则的头部本质上是它的接口。再次查看 interacts/3 您可以交互式查询它以了解两种药物联合使用的效果:
?- interacts(terbinafine,warfarin,I).
I = arterial_pressure_nos_decreased ? ;
I = bradycardia
请注意,查询的结果是作为变量保留的谓词参数之一 (I
)。 Prolog 然后将此变量与匹配两种药物的所有相互作用统一起来。这就是我在上面写 accessible from the head 时的意思……本质上是它的接口。您可以使用 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]
后者会从列表中删除重复项(如果有的话)。