我的程序中的上下文如下:我有一些students
,一定的country
和一定years
的研究,在这个序言代码中如下:
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'].