为何Prolog献血查询系统返回重复查询结果?
解决Prolog献血查询系统的重复结果问题
问题根源
你的pode_doar/2规则存在条件分支重叠的情况,同一个捐献匹配会被多个分支同时触发,Prolog回溯时就会返回重复结果。比如:
ph(O型Rh阴性)向pf(AB型Rh阴性)捐献时,同时满足(tipo_o(A),fator_n(A))和(tipo_ab(B),D=F)两个分支,导致pf被返回两次;ph向自身捐献时,同时满足(C=E,D=F)、(C=E,fator_n(A))、(tipo_o(A),fator_n(A))三个分支,导致ph被返回四次。
解决方案
方案1:查询时直接去重(快速临时解决)
利用Prolog的setof/3谓词收集所有唯一结果,它会自动对结果去重并排序。修改查询语句为:
?- setof(A, pode_doar(ph,A), UniqueResults), member(A, UniqueResults).
如果使用SWI-Prolog,也可以用更简洁的distinct/1:
?- distinct(pode_doar(ph,A)).
方案2:优化规则消除分支重叠(彻底解决)
重构pode_doar/2的条件逻辑,让每个捐献场景只匹配一个分支,避免重复触发。按血型兼容性优先级组织规则:
pode_doar(A,B):- apto(A), doador(A,_,_,_,C,D), doador(B,_,_,_,E,F), % 1. 同血型同Rh因子(最严格匹配) (C=E, D=F) % 2. 同血型,捐献者是Rh阴性(可给同血型任意Rh) ; (C=E, D=n) % 3. O型Rh阴性(万能捐献者,可给所有血型) ; (C=o, D=n) % 4. O型同Rh因子(给O型同Rh) ; (C=o, E=o, D=F) % 5. AB型受体接受同Rh因子的任意血型 ; (E=ab, D=F).
这里的分支是互斥的,每个匹配只会触发一个分支,不会产生重复结果。
验证结果
优化后执行?- pode_doar(ph,A).,会得到去重后的正确结果:
A = pa A = pb A = pc A = pd A = pe A = pf A = pg A = ph
内容的提问来源于stack exchange,提问作者Lucas Aquino de Assis
相关产品推荐
相关产品推荐

