如何在序言中的另一个规则中使用规则

时间:2021-05-19 15:39:03

标签: prolog

这是我的事实:

object('Human').
object('Machine').
object('Robot').
object('Hunter').
object('WallE').

action('Kill').
action('Run').

rel1('Hunter', 'Human').
rel1('Robot', 'Machine').
rel1('WallE', 'Robot'). 

rel2('Human', 'Run').
rel2('Machine', 'Run').
rel2('Robot', 'Kill').

我正在尝试查找实现给定操作的所有对象的列表。例如,如果我运行这个:

?-provides_action(’Run’, X).

它给出了结果: X = [’Human’, ’Machine’, ’Hunter’, ’Robot’, ’WallE’].

?-provides_action(’Kill’, X).

它给出了结果:

X = ['WallE'].

我已经试过了

provides_action2(X, L) :- findall(Y, (rel2(Y,X)),L).
provides_action3(X, L) :- provides_action2(X, L1), findall(Z, rel1(Z,L1), L2), append(L1,L2,L).

它没有给我正确的答案,我想使用第一个规则 (L1) 的结果并在第二个 findall extends(Z,L1) 中使用它,但它似乎没有这样做。

有人可以向我解释一下有什么问题吗? 提前致谢!

1 个答案:

答案 0 :(得分:0)

首先,您必须使用 extends/2 定义谓词 rel1/2

extends(A, C) :- rel1(A, C).
extends(A, C) :- rel1(A, B), extends(B, C).

示例:

?- extends(X, 'Human').
X = 'Hunter' ;
false.

?- extends(X, 'Machine').
X = 'Robot' ;
X = 'WallE' ;
false.

之后,您可以使用此谓词来定义provides_action/2,如下所示:

provides_action(X, L) :-
   findall(Y, rel2(Y,X), L1),
   findall(C, (member(A, L1), extends(C, A)), L2),
   append(L1, L2, L).

请注意,迭代列表 member(A, L1) 需要 L1

运行示例:

?- provides_action('Run', L).
L = ['Human', 'Machine', 'Hunter', 'Robot', 'WallE'].
相关问题