2010-03-05 90 views
0

好的,我最後一個序言問題。這是常見的基因學問題。Prolog作業幫助

我想採取事實的列表,並有一個名爲後裔的功能, 將返回一個包含所有後代的列表。例如:

給出的規則:

parent('Bob', 'Tim'). 
parent('Joe', 'Bob'). 

函數調用:

descendant('Joe', X). 

應該返回:

 X = ['Bob', 'Tim']. 

我能得到它返回的「直接後裔喬'但不是全線。這是我的。

% Recursive case 
    descendant(X,DList) :- parent(X,A), NewDList = [A|DList], 
         descendant(A, NewDList). 
% Base case, I have a feeling this is wrong. 
    descendant(_,[]). 

此代碼只似乎返回true或false,或者只是一個空的[]。

我可以使用一些幫助,我可能需要看看。謝謝。

回答

0

我的序言有點生疏,我不願意發表一個這樣的問題的答案 - 你不會學到太多。

我只是指出你不應該在那裏有那個賦值語句--NewDList = [A | DList] - 這在Prolog編程風格中被認爲是不好的形式 - 賦值只能用在有不是一種「純粹的」邏輯解決方案 - 當然不是這種情況。

乾杯, 克雷格。

0
parent('Bob', 'Tim'). 
parent('Joe', 'Bob'). 

descendant(X,[H|T]) :- parent(X,H), descendant(H, T). 
descendant(X,[]) . 

回報

?- descendant('Joe', L). 
L = ['Bob', 'Tim'] ; 
L = ['Bob'] ; 
L = []. 

實際上它是很難寫謂詞,因爲名單['Bob']也是有效只會['Bob', 'Tim']返回。如果你決定離開它變得太comlicated

只有產業鏈最長,如果我理解正確的問題這裏是一個版本:

desc(X, A) :- parent(X,H), desc(H, A). 
desc(X, A) :- X = A. 
+0

我不認爲這有效,如果有人超過o ne直接後代,例如,如果Joe也是Mary的父母。 – 2010-03-05 16:03:10

+0

你測試過了嗎?如果不是,請測試然後批評。我只是測試它。我工作正常。我確定它不適用於某些數據請給出一個證明 – Andrey 2010-03-05 16:06:23

+0

我給出的例子不起作用 - 如果我加上父母('Joe','Mary'),那麼Joe的後代仍然列出作爲鮑勃和蒂姆(雖然瑪麗是作爲回溯時的進一步結果) – 2010-03-05 16:16:48

1

首先,我們將創建一個能找到一個單一的後代謂語。

descendant(X, Y) :- parent(X, Y). 
descendant(X, Y) :- parent(X, Z), descendant(Z, Y). 

然後,我們可以使用findall謂詞來列出所有後代:

descendants(X, L) :- findall(A, descendant(X, A), L). 

所以,舉例來說:

parent(bob, tim). 
parent(joe, bob). 
parent(joe, mary). 

descendant(X, Y) :- parent(X, Y). 
descendant(X, Y) :- parent(X, Z), descendant(Z, Y). 

descendants(X, L) :- findall(A, descendant(X, A), L). 

給出:

?- descendants(joe, X). 
X = [bob, mary, tim]. 
+0

嗯有人說有6個孩子的問題,我希望它列出所有6作爲後代。然而,所給出的規則只有人有一個孩子,這使得奧德里的實施得以接受。但是我想知道如何做到這一點,以防它後來在測試中出現。我試過這個,但它返回的是直接後代,我做錯了什麼? – poorStudent 2010-03-05 18:46:49

+0

你確定'後代'(有s)正在使用,而不是'後代'(它將一個人與後代統一)嗎? – 2010-03-05 19:00:06

+0

是的,發生了什麼事是它會輸出X = [鮑勃] 我必須推;讓它步出並放出X = [mary]等等,直到它出錯。 – poorStudent 2010-03-05 19:08:31