Prolog编写oldestSon规则判断家庭长子 无需额外依赖单次输出
问题背景
给出的Prolog事实代码如下:
son(blake, john). son(blake, katey). son(toney, john). son(toney, katey). son(flory, john). son(flory, katey). son(charlie, stark). son(charlie, shrek). son(valenti, stark). son(valenti, shrek). age(blake, 13). age(toney, 15). age(flory, 19). age(charlie, 48). age(valenti, 49).
相关谓词定义:
son(X, Y):表示X是Y的儿子age(M, N):表示M的年龄为Nsiblings(P, Q):表示P和Q是兄弟姐妹
需求说明
编写名为oldestSon(X)的规则,当X是某家庭的长子时判定为真,满足:
- 查询
oldestSon(flory)返回true - 查询
oldestSon(valenti)返回true - 查询
oldestSon(toney)返回false
现有实现问题
你编写的原始规则如下:
oldestSon(X) :- son(X, _), son(Y, _), siblings(X, Y), age(X, ageX), age(Y, ageY), ageX >= ageY.
存在的问题:查询oldestSon(blake)会不断重复返回false,需要在不使用外部库、不新增其他规则的前提下,实现查询仅返回单次结果。
解决方案
修正后的oldestSon规则如下:
oldestSon(X) :- son(X, Father), son(X, Mother), age(X, AgeX), \+ (son(Y, Father), son(Y, Mother), Y \= X, age(Y, AgeY), AgeY > AgeX), !.
逻辑说明:
- 先绑定X的父母,确保后续对比的Y和X属于同一家庭,避免跨家庭匹配错误
- 通过否定判断确保不存在同家庭其他儿子的年龄大于X,满足长子判定条件
- 末尾添加标准Prolog内置的剪枝操作符
!,匹配完成后直接终止回溯,不管结果是true还是false都只会返回一次,不会重复输出。
测试结果符合要求:
oldestSon(flory)、oldestSon(valenti)返回trueoldestSon(toney)、oldestSon(blake)仅返回一次false,无重复输出。
内容的提问来源于stack exchange,提问作者adlofMerlin
相关产品推荐
相关产品推荐

