2012-05-09 27 views
1

我在回覆列表时遇到了麻烦,我将如何返回与某个人相关的每个人的列表。因此,如果我说亲属(A,B),A就是一个人,B是与该人有关的所有人的名单。我可以编写任何其他必要的规则来协助完成此操作。这是我到目前为止。用Prolog找到所有亲戚

man(joe). 
man(tim). 
man(milan). 
man(matt). 
man(eugene). 

woman(mary). 
woman(emily). 
woman(lily). 
woman(rosie). 
woman(chris). 

parent(milan, mary). 
parent(tim, milan). 
parent(mary, lily). 
parent(mary, joe). 
parent(mary, matt). 
parent(chris, rosie). 
parent(eugene, mary). 
parent(eugene, chris). 

cousins(A, B) :- parent(C, A), parent(D, B), parent(E, C), parent(E, D), not(parent(C, B)), not(parent(D, A)), A \=B. 

paternalgrandfather(A, C) :- man(A), man(B), parent(B, C), parent(A, B). 

sibling(A, B) :- parent(C, A), parent(C, B), A \= B. 

有人可以指导我如何去做这件事吗?谢谢。

+0

您需要一个递归函数,该函数附加到递归中的结果。 – keyser

回答

0

我认为你应该专注于'真实'关系,即parent(Old,Jung),其他谓词在这里是不相关的。明显的假设是,在parent/2中出现的原子是标识符(即名称是唯一的)。从这张照片看来,这里所有的人都是亲戚:

enter image description here

那么你的问题应该等于找到了在父母关系中的所有连接的顶点。您可以实现深度的首次访问,传承访问节点列表,以避免环路(请注意,你需要回到父母,下至儿童!),像

relatives(Person, Relatives) :- 
    relatives([], Person, [Person|Relatives]). 

relatives(Visited, Person, [Person|Relatives]) :- 
    findall(Relative, immediate(Person, Visited, R), Immediates), 
    ... find relatives of immediates and append all in relatives. 

immediate(Person, Visited, R) :- 
    (parent(Person, R) ; parent(R, Person)), 
    \+ member(R, Visited). 

看看你能不能完成这个片段。注意亲属/ 3中参数的顺序被选择为简单的maplist/3。

如果您愿意学习更高级的代码,SWI-Prolog library(ugraph)提供了一个reachable(+Vertex, +Graph, -Vertices)谓词,它可以在基于列表的图表表示上进行。

这里SWI-Prolog的片段来获得图像(被喂以dot文件):

graph(Fact2) :- 
    format('digraph ~s {~n', [Fact2]), 
    forall(call(Fact2, From, To), format(' ~s -> ~s;~n', [From, To])), 
    format('}\n'). 

,你可以这样调用:

?- tell('/tmp/parent.gv'),graph(parent),told. 

,然后问题就命令行dot -Tjpg /tmp/parent.gv | display

0

我认为你应该使用内置谓词的findall/3,也许排序/ 2,以避免重复

它会沿着这些路线走:

relatives(Person, Relatives):- 
    findall(Relative, is_relative(Person, Relative), LRelatives), 
    sort(LRelatives, Relatives). 

is_relative(Person, Relative):- 
    (cousins(Person, Relative) ; paternalgrandfather(Person, Relative) ; sibling(Person, Relative)). 

你可能要添加更多的条款,is_relative到获得更多的关系。