Prolog家族树n代表/堂亲查询及隔代筛选功能实现问题咨询
Prolog堂表亲关系查询实现方案
基于已有的male/1、female/1、child/2基础事实(规则约定child(子女, 父母)表示亲子关系),完整实现如下:
1 基础递归规则(支持任意代际堂表亲匹配)
首先定义核心辅助规则,替代逐代编写的硬编码逻辑:
% 定义祖先关系 ancestor(X, Y) :- child(X, Y). ancestor(X, Y) :- child(X, Z), ancestor(Z, Y). % 计算X到祖先A的代距:1=父母,2=祖父母/外祖父母,以此类推 ancestor_depth(X, A, 1) :- child(X, A). ancestor_depth(X, A, D) :- child(X, Z), ancestor_depth(Z, A, D0), D is D0 + 1. % 匹配指定代际的堂表亲,排除自身、亲兄弟姐妹 cousin_of_degree(X, Y, Degree) :- X \= Y, ancestor_depth(X, CommonAnc, D1), ancestor_depth(Y, CommonAnc, D2), % 堂表亲代际计算规则:双方到共同祖先的最小代距减1 Degree is min(D1, D2) - 1, Degree >= 1, % 排除亲兄弟姐妹(共同祖先为父母的情况) \+ (child(X, P), child(Y, P)).
2 实现all_cousins/3查询规则
使用Prolog内置的findall收集符合条件的结果,sort自动去重(避免同一亲属因多个共同祖先重复命中):
all_cousins(Person, Degree, ListOfCousins) :- findall(Cousin, cousin_of_degree(Person, Cousin, Degree), RawList), sort(RawList, ListOfCousins).
调用示例:查询张三的第二代堂表亲:all_cousins(zhangsan, 2, List).
3 实现隔代堂表亲all_cousinsRemoved/4查询规则
隔代参数约定:removed(Number, Direction)中Number为隔代数,Direction取值up(对方为参考人的长辈)、down(对方为参考人的晚辈):
% 匹配隔代堂表亲 cousin_removed(Person, Cousin, Degree, removed(Num, Dir)) :- cousin_of_degree(Person, Cousin, Degree), ancestor_depth(Person, CommonAnc, D1), ancestor_depth(Cousin, CommonAnc, D2), Diff is D2 - D1, abs(Diff, Num), Num >= 1, (Diff < 0 -> Dir = up ; Dir = down). % 批量查询隔代堂表亲 all_cousinsRemoved(Person, Degree, removed(Num, Dir), ListOfCousins) :- findall(Cousin, cousin_removed(Person, Cousin, Degree, removed(Num, Dir)), RawList), sort(RawList, ListOfCousins).
调用示例:查询张三的第一代、向下隔1代的堂表亲(即表侄/表侄女):all_cousinsRemoved(zhangsan, 1, removed(1, down), List).
内容的提问来源于stack exchange,提问作者Gavonti Shawn Patton
相关产品推荐
相关产品推荐

