Prolog递归跳过相同的结果

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)

但是我没能将它应用到我的代码中.请帮忙.

fal*_*lse 7

你的程序有一个纯粹的核心 - 或坚持医学术语 - 纯洁的心脏,但这与癌症的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的方法.

  • 欢迎!在学习 Prolog 时,尽量远离有副作用的内置函数。Prolog 的纯粹部分使它如此有趣。 (2认同)