Prolog - 计数所有患者的症状 [英] Prolog - Count all patient's symptoms

查看:345
本文介绍了Prolog - 计数所有患者的症状的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想计算所有病人的症状来计算疾病的确定性因素,但我只是得到每种疾病的一个症状。

结果也显示一些重复项。

确定性因子是患者症状数/疾病症状总数:

  start: -  
write('输入病人的姓名'),读取(Patient),
write症状:'),阅读(症状),写('\\\
'),
countSint(疾病,症状,病人)。

countSint(Diseases,Symptoms,Patient): -
findall(Sint,member(Sint,Symptoms),L1),length(L1,Size),
; 2
- > writeln('Enter with at least 3 symptoms ... \\\
'),start
; Size> 1
- > write('\\\
输入分号...:\\\
\\\
'),写('Patient:'),写(Patient),
diagnose(症状,疾病,L)
)。

diagnose(症状,疾病,L): - 搜索(症状,疾病,L)。

%疾病(疾病,症状,数字)。
疾病(脑膜炎,[fever,stiff_neck],2)。
疾病(登革热,[发烧,呕吐,red_spots],3)。

%search(症状,疾病,L)。
search([H | T],Diseases,L): -
disease(Disease,Symptoms,Num),
疾病0 = [疾病,疾病] ,症状),
search(T,Diseases0,L),
write('has'),write(Disease),writeln(':'),
setof (疾病,症状,数字),
成员(H,症状)),L),
长度(L,大小),
calc_cf(Num,Size,R)。

calc_cf(Num,Size,R): - %计算确定性因子
R是Size / Num * 100,
write('确定性因子是'),
write(R),
writeln('%')。

任何人都可以帮助我吗?

解决方案

这似乎没有用:

  findall(Sint, L1)

只是将症状重写为L1。为什么?



在此片段中

  b $ b  - > writeln('Enter with at least 3 symptoms ... \\\
'),start
; Size> 1
- > write('\\\
输入分号。 ..:\\\
\\\
'),写('Patient:'),写(Patient),
diagnose(症状,疾病,L)



此事实

疾病(疾病,症状,数字)。应该是无用的,但它会引入非绑定变量,使任何进一步的处理更困难。



可以考虑看看图书馆( aggregate ),您可以在其中找到用于计数解决方案的精心设计的谓词,例如

  countSint(Diseases,Symptoms,Patient): -  
aggregate(count,diagnose(Symptoms,Diseases,_),Count),
format :〜d for:〜w〜n',[Count,Patient])。

编辑



最好将逻辑与表示分开,并在这里获得一些好的反馈,我认为你应该删除写/读从代码,并显示一些你关心的例子。现在我显示您需要的必要公式,我可以从您的评论中猜出:

 脑膜炎,[发烧,僵硬])。 
疾病(登革热,[发烧,呕吐,red_spots])。

%从症状中发现疾病,按确定因子排序
诊断(症状,疾病): -
setof(CF-疾病,常见症状(症状,疾病, )。

common_symptoms(Symptoms_Patient,Disease,CF): -
disease(Disease,Symptoms_Disease),
intersection(Symptoms_Patient,Symptoms_Disease,Common_Symptoms),
length(Common_Symptoms, NCS),
length(Symptoms_Disease,NSD),
CF是NCS / NSD * 100.

测试:

 ? - 诊断([fever,stiff_neck],L)。 
L = [33.33333333333333-dengue,100-meningitis]。


I'm trying to count all patient's symptoms to calculate the certainty factor for the disease, but I'm just getting one symptom of each disease.
Also the result shows some duplicates.
The certainty factor is the number of patient's symptoms/the total of symptoms of the disease:

start:- 
  write('Enter the name of the patient: '), read(Patient),
  write('Enter the symptoms: '), read(Symptoms), write('\n'),
  countSint(Diseases, Symptoms , Patient).

countSint(Diseases, Symptoms , Patient) :-
  findall(Sint , member(Sint, Symptoms),   L1), length(L1 , Size),
  (  Size < 2
  -> writeln('Enter with at least 3 symptoms...\n'), start
  ;  Size > 1
  -> write('\n Enter semicolon...:\n\n'), write('Patient: '), write(Patient),
     diagnose(Symptoms,Diseases, L)
  ).

diagnose(Symptoms,Diseases,L) :- search(Symptoms, Diseases, L).

% disease(Disease, Symptoms, Num).
disease(meningitis,[fever, stiff_neck],2).
disease(dengue,[fever, vomiting, red_spots], 3).

% search(Symptoms, Diseases, L).
search([H|T] , Diseases, L) :-
  disease(Disease, Symptoms, Num),
  Disease0 = [Disease,Diseases],
  member(H, Symptoms),
  search(T , Diseases0, L),
  write('has '), write(Disease), writeln(': '),
  setof(H, (disease(Disease, Symptoms, Num),
            member(H, Symptoms)), L),
  length(L, Size),
  calc_cf(Num, Size, R).

calc_cf(Num, Size, R):- % Calculate the certainty factor
  R is Size / Num * 100,
  write('The certainty factor is '),
  write(R),
  writeln('%').

Can anyone help me, please?

解决方案

this seems useless:

findall(Sint , member(Sint, Symptoms),   L1)

simply rewrite Symptoms as L1. Why?

In this snippet

  (  Size < 2
  -> writeln('Enter with at least 3 symptoms...\n'), start
  ;  Size > 1
  -> write('\n Enter semicolon...:\n\n'), write('Patient: '), write(Patient),
     diagnose(Symptoms,Diseases, L)
  )

there should be another alternative.

This fact disease(Disease, Symptoms, Num). should be useless, but it will introduce unbound variables that make more difficult any further processing.

You could consider to take a look to library(aggregate), where you find well crafted predicates for counting solutions, something like

countSint(Diseases, Symptoms, Patient) :-
  aggregate(count, diagnose(Symptoms, Diseases, _), Count),
  format('diagnosed:~d for:~w~n', [Count, Patient]).

edit

It's better to separate logic from presentation, and to get some good feedback here on SO I think you should remove write/read from code, and show instead some example you care about. Now I show the essential formula you need, as I can guess from your comment:

disease(meningitis, [fever, stiff_neck]).
disease(dengue, [fever, vomiting, red_spots]).

% find diseases from symptoms, sort by certainty factor
diagnose(Symptoms, Diseases) :-
     setof(CF-Disease, common_symptoms(Symptoms, Disease, CF), Diseases).

common_symptoms(Symptoms_Patient, Disease, CF) :-
    disease(Disease, Symptoms_Disease),
    intersection(Symptoms_Patient, Symptoms_Disease, Common_Symptoms),
    length(Common_Symptoms, NCS),
    length(Symptoms_Disease, NSD),
    CF is NCS / NSD * 100.

test:

?- diagnose([fever, stiff_neck],L).
L = [33.33333333333333-dengue, 100-meningitis].

这篇关于Prolog - 计数所有患者的症状的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆