Mez*_*zan 4 recursion prolog prolog-setof
我的代码运行但问题是它不止一次显示相同的结果.这是我的代码:
disease(hiv,[sore_throat,headache,fever,rash]).
disease(pregnancy,[fatigue,vomiting,light_headedness,increased_waistline]).
disease(flu,[fatigue,fever,tiredness,nasal_discharge]).
diagnose([], []).
diagnose(Name, [H|T]) :-
disease(The_Disease, Symptoms),
member(H, Symptoms),
write(Name), write(' has/is '), writeln(The_Disease),
diagnose(Name, T).
member(X,[X|_]).
member(X,[_|T]):-
member(X,T).
Run Code Online (Sandbox Code Playgroud)
在prolog中执行时的结果:
?- diagnose(kevin,[sore_throat,fatigue,tiredness,rash]).
kevin has/is hiv
kevin has/is pregnancy
kevin has/is flu
kevin has/is hiv
kevin has/is flu
kevin has/is flu
kevin has/is hiv
false.
Run Code Online (Sandbox Code Playgroud)
我该如何避免同样的结果?我尝试使用我在这里找到的其他方法:
filter_doubles([], []).
filter_doubles([X|L], Result) :-
(memberchk(X,L) ->
filter_doubles(L, Result)
;
filter_doubles(L, Result0),
Result = [X|Result0]
).
Run Code Online (Sandbox Code Playgroud)
但是我没能将它应用到我的代码中.请帮忙.
你的程序有一个纯粹的核心 - 或坚持医学术语 - 纯洁的心脏,但这与癌症的I/O组织交织在一起!以这种方式做正确的事情是非常困难的,如果不是不可能的话.例如,作为次要错误,您的程序失败kevin.但你可能意味着它会成功.另一方面,你将成为神秘的先生[]!那是谁?
所以让我们将纯净与不纯洁分开!
程序中的纯粹部分是将症状列表与可能的诊断相关联.你的工作假设是,如果有一种症状是疾病症状的一部分,我们将诊断出这种疾病 - 只是为了确定.那么为什么不叫这个symptoms_diagnosis/2呢?
symptoms_diagnosis(Symptoms, Diagnosis) :-
member(Symptom, Symptoms),
disease(Diagnosis, Indications),
member(Symptom, Indications).
?- symptoms_diagnosis([sore_throat,fatigue,tiredness,rash], Diagnosis).
Diagnosis = hiv ;
Diagnosis = pregnancy ;
Diagnosis = flu ;
Diagnosis = flu ;
Diagnosis = hiv ;
false.
Run Code Online (Sandbox Code Playgroud)
需要注意的是,即使没有任何废话少说,我们有较少的冗余解决方案比原来的计划.那么如何摆脱剩余的冗余解决方案呢?这样做的诀窍:
?- setof(t,symptoms_diagnosis([sore_throat,fatigue,tiredness,rash], Diagnosis),_).
Diagnosis = flu ;
Diagnosis = hiv ;
Diagnosis = pregnancy.
Run Code Online (Sandbox Code Playgroud)
因此,无论何时获得冗余解决方案,只需setof(t, ..., _)绕过目标即可.只要答案是基础答案,您就可以使用它.也就是说,答案中没有剩下的变量.
也许您更愿意将诊断列入自己的列表中?
?- setof(Diagnosis,symptoms_diagnosis([sore_throat,fatigue,tiredness,rash],Diagnosis),Diagnoses).
Diagnoses = [flu, hiv, pregnancy].
Run Code Online (Sandbox Code Playgroud)
那么,现在我们已经为普林斯顿普林斯伯勒教学医院做好了准备!如果House博士不接受Prolog的诊断,那只是迷信!
对于不纯的部分,请看@Mog的方法.