如何在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?。但我不知道如何在这里实现它。
答案 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,_) , []).