在 Prolog 中选择数字的一部分和检查列表

Selecting parts of a number and checking lists in Prolog

我根据问题中提供的信息制作了这个知识库:

student(jill,12071992,computer_science,[tennis,lacrosse]).
student(joe,14021993,mathematics,[tennis,rugby,football]).

代表学生的姓名、出生日期、学科和参加的运动。

问题 1 -

born_before(N,Y) - 名为 N 的学生出生于 Y 年之前

born_before(N,Y):-student(N,____X,_,_), Y > X.

显然上面的方法不起作用,我的问题是我不知道如何在序言中将 YYYY 与 DDMMYYYY 术语分开,然后将其设置为 X,以便与 Y 值进行比较。

问题 2 -

plays_sport(N,S) - 名为 N 的学生参加运动 S.

我的尝试

plays_sport(N,S):-student(N,_,_,[S|Sx]), plays_sport(N,Sx). 

这总是 returns 错误。我尝试使用尾递归,以便可以从知识库中的运动列表中匹配该运动。

对于问题的第一部分,您可以编写规则从表示 ddmmyyyy 格式的日期的整数中提取年、月和日,如下所示:

extract_year(DDMMYYYY, YYYY) :- YYYY is mod(DDMMYYYY, 10000).
extract_day(DDMMYYYY, DD) :- DD is DDMMYYYY // 1000000.
extract_month(DDMMMYYYY, MM) :- DDMM is DDMMMYYYY // 10000, MM is mod(DDMM, 100).

// 运算符表示整数除法,当小数部分从答案中删除时。 mod/3是求整数除法余数的运算

然后您可以将它们组合回 yyyymmdd 格式,并作为整数进行比较 (demo)。

对于第二部分,您可以使用 memberchk(Element, List) 检查列表中是否存在所需的运动:

plays_sport(N,S) :- student(N,_,_,AllSports), memberchk(S, AllSports).