【发布时间】:2013-07-09 21:09:26
【问题描述】:
我的程序中的上下文如下:我有一些students,一些country和一些years的学习,如下这个prolog代码:
student('Steve Morris').
student('Joe Jez').
student('Carlos Sethi').
student('Natasha Carter').
country('Steve Morris', usa).
country('Joe Jez', usa).
country('Carlos Sethi', usa).
country('Natasha Carter', france).
years('Steve Morris', 3).
years('Joe Jez', 1).
years('Carlos Sethi', 4).
years('Natasha Carter', 4).
scholarship(A) :- country(A,B), B = france.
scholarship(A) :- years(A,C), C > 2.
我想给我的一名学生提供一份奖学金。为此,我将使用一些提高“奖学金系数”的规则,获得更大奖学金系数的学生将获得奖学金。
第一条规定学生必须来自法国,第二条规定学生必须有两年以上的学习。
所以,当我执行scholarship(X) 时,我得到的是:
?- scholarship(X).
X = 'Natasha Carter' ; % Only student who matches the first rule
X = 'Steve Morris' ; % All students from now on, match the second rule
X = 'Carlos Sethi' ;
X = 'Natasha Carter'.
话虽如此,我正在尝试做一个程序,试图获取最终获得奖学金的学生的姓名。首先,我尝试先执行一个谓词findall 来逐一过滤所有符合这些规则的学生,并将其放在一个列表中:
?- findall(X, scholarship(X), L).
L = ['Natasha Carter', 'Steve Morris', 'Carlos Sethi', 'Natasha Carter'].
这是预期结果,因为使用了scholarship(X)。
现在,看来我需要生成的列表来过滤结果并满足我的要求。请记住,在上面的示例中,我期望达到的结果至少是一个表明学生及其奖学金因素的列表,如下所示(不一定准确):
[['Natasha Carter', 2], ['Steve Morris', 1], ['Carlos Sethi', 1]].
这是一种操作findall生成的列表的方法吗?或者我当然需要另一种方法来解决这个问题?
编辑:问题建模有一点很重要:所有规则都有相同的奖学金因子值,所以当一个学生满足一个规则时,无论是哪一个,奖学金系数应升至 1。
问题更新:感谢 Mog,我有一个解决问题的方法,使用辅助列表应用 msort/2,这就是我所得到的:
?- findall(X, scholarship(X), L), msort(L, L1).
L = ['Natasha Carter', 'Steve Morris', 'Carlos Sethi', 'Natasha Carter'],
L1 = ['Carlos Sethi', 'Natasha Carter', 'Natasha Carter', 'Steve Morris'].
【问题讨论】:
-
感谢
msort/2,您可以从排序列表开始。完成后,可以编写一个简单的谓词,在每个连续的相似元素之后增加一个计数器并返回所需的结果。 -
次要:替换
country(A,B), B = france.parcountry(A, france). -
解决问题的一种方法,我执行了以下命令
?- findall(X, scholarship(X), L), msort(L, L1).,这是输出:L = ['Natasha Carter', 'Steve Morris', 'Carlos Sethi', 'Natasha Carter'], L1 = ['Carlos Sethi', 'Natasha Carter', 'Natasha Carter', 'Steve Morris'].