2010-03-05 65 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