2013-10-27 55 views
2

基于一些事实,我必须找到使用Prolog的最古老的人。例如:查找Prolog中最古老的人

age(john, 10). 
age(mary, 15). 
age(rose, 75). 
age(jack, 49). 
age(carl, 17). 
age(lucy, 66). 

控制台输出应该是:

?- oldest(rose). 
True. 

?- oldest(X). 
X = rose. 

我的代码如下,但它不工作:

oldest(P) :- age(P, X) , age(_, Y) , X >= Y. 

我找不到错误,但我猜猜这是跟回溯有关的东西。请有人帮助我吗?我是Prolog的新手。

回答

2

正确的应该是

oldest(P) :- age(P, X) , \+ (age(_, Y) , Y > X). 

即收益率上升,当然...

(\+)/1解读为not(目标),意味着'如果目标没有解决方案,就会失败'。

在SWI-Prolog的编辑,库(aggregate)可以做到这一点,以及更多...

oldest(P) :- aggregate(max(A,Pers), age(Pers,A), max(_,P)). 
+0

它的工作原理,谢谢!但是这个定义和我的区别是什么?为什么这个工作和我的不工作? – renatov

+1

你的代码找到了第一个拥有*几乎*一个更年轻的人​​ – CapelliC

+1

@renatov,如果你直接从字面上读取“最古老的”谓语,它说:“如果**'X'是' * *和*年龄为'Y',*和*'Y'小于或等于'X'“的人。如果它发现只有一个比“P”更年轻的人​​,它就会成功。它没有确定其他所有人都必须年轻的约束。 – lurker

1

你的oldest/1定义是无效的(和CapelliC的答案显示了为什么以及如何解决它)。

这里是另一种方式找到最长寿的人:

oldest(X) :- 
    findall((Age, Name), age(Name, Age), List), 
    sort(List, SList), 
    reverse(SList, [(_, X) | _]). 
+0

谢谢,它的工作。但是有没有更简洁的方法呢?噢,为什么我最老的/ 1的定义是无效的? – renatov