这是我的事实:
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) 中使用它,但它似乎没有这样做。
有人可以向我解释一下有什么问题吗? 提前致谢!
答案 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'].