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

How do I use rule in another rule in 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) 中使用它,但它似乎没有这样做。

任何人都可以向我解释一下哪里出了问题吗? 提前致谢!

首先,您必须使用 rel1/2:

定义谓词 extends/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'].