如何定义`not_a_parent()`谓词?

时间:2017-05-23 03:41:23

标签: prolog

如何在GNU Prolog中创建这样的逻辑?如何定义not_a_parent()谓词?

parent(john,chris).
parent(mary,chris).
not_a_parent(X) :- \+ parent(X,Y).

类似问题的有趣答案是What is the logical 'not' in Prolog?。但我不知道如何在这里实现它。

3 个答案:

答案 0 :(得分:1)

你需要以某种方式列举所有人。例如

not_a_parent(X) :- ( X = john ; X = mary ; X = chris ), \+ parent(X,_).

在任何真正的程序中,你可能会有一些简单的方法来获取所有人,然后你可以做

not_a_parent(X) :- person(X), \+ parent(X,_).

答案 1 :(得分:1)

这对我有用:

parent(john,chris).
parent(mary,chris).
parent(mary,suzanne).
parent(suzanne,jane).
parent(suzanne,peter).
parent(peter,rose).
parent(jerry,rose).
parent(jane,carl).

not_a_parent(NonParents) :- setof(Z,Y^parent(Y,Z),SetOfChildren),
           findNonParents(SetOfChildren, NonParents, []),!.

findNonParents([],A,A).

findNonParents([H|SetOfChildren], NonParents, A):-
        not(call(parent(H,_))),
        findNonParents(SetOfChildren,NonParents,[H|A]).

findNonParents([_|SetOfChildren], NonParents, A):-
        findNonParents(SetOfChildren,NonParents,A).

查询not_a_parent(非父母)的结果是:

?- not_a_parent(NonParents).
NonParents = [rose, chris, carl].

答案 2 :(得分:0)

您需要获取parent/2的所有实例,以便X永远不会统一parent(X,_)findall(Template, Goal, Instances)执行目标直到失败,并使用统一模板的术语填充列表实例。这样,如果列表实例为空,则parent(X,_)不存在。

所以你的谓词就像:

not_a_parent(X):- findall(_, parent(X,_) , []).