2012-05-09 59 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到獲得更多的關係。