SWI-Prolog医疗诊断界面代码卡顿问题求助
SWI-Prolog医疗诊断程序卡顿问题修复
核心错误分析
- 问题跳转逻辑缺失:每个提问规则仅处理输入1的情况,未处理输入2的分支,导致输入2时规则失败,程序终止。
- 拼写不一致:症状名称
erupcoes cutaneas使用空格,与规则代码中的erupcoes_cutaneas(下划线)不匹配,导致后续诊断无法识别该症状。 - 诊断逻辑偏差:
doenca规则调用demo(X)时,会优先匹配用户输入的症状(fact(X)),而非推导的疾病。 - 治疗方案输出混乱:
tratamento规则遍历所有事实,导致重复输出治疗方案。
修正后的代码
规则代码(无需修改,需与界面代码合并或加载)
:- dynamic (fact/1), [interface]. :- dynamic (demo/1). %A simple backward chaining rule interpreter :- op( 800, fx, if). :- op( 700, xfx, then). :- op( 300, xfy, or). :- op( 200, xfy, and). demo( Q) :- fact( Q). demo( Q) :- if Condition then Q, %A relevant rule demo( Condition). %whose condition is true demo( Q1 and Q2) :- demo( Q1), demo( Q2). demo( Q1 or Q2) :- demo( Q1) ; demo( Q2). %Simple forward chaining in Prolog demo:- new_derived_fact( P), %A new fact !, write( 'Derived: '), write( P), nl, assert( fact( P)), demo. demo:- write( 'No more facts'). %All facts derived new_derived_fact( Concl) :- if Cond then Concl, %A rule \+ fact( Concl), %Rule's conclusion not yet a fact composed_fact( Cond). %Condition true? composed_fact( Cond) :- fact( Cond). %Simple fact composed_fact( Cond1 and Cond2) :- composed_fact( Cond1), composed_fact( Cond2). %Both conjuncts true composed_fact( Cond1 or Cond2) :- composed_fact( Cond1) ; composed_fact( Cond2). %Associating symptoms with diseases if febre and tosse and dor_de_cabeca and cansaco then gripe. if cansaco and palidez then anemia. if dificuldade_respiratoria and tosse then asma. if dor_abdominal and nausea and diarreia and vomito then gastroenterite. if dor_de_cabeca and nausea and sensibilidade_a_luz then migranea. if febre and dor_muscular and dor_de_cabeca and erupcoes_cutaneas then dengue. if dor_abdominal and febre and nausea and perda_de_apetite then apendicite. if febre and tosse and dificuldade_respiratoria and dor_no_peito then pneumonia. if febre and dor_de_cabeca and cansaco and dor_de_garganta and inchaco_nos_ganglios then mono. if cansaco and aumento_de_peso and intolerancia_ao_frio then hipotireoidismo. if perda_de_peso and taquicardia and nervosismo and intolerancia_ao_calor then hipertireoidismo. if sede_excessiva and fome_frequente and urinacao_frequente and perda_de_peso then diabetes. if dor_lombar and rigidez_muscular then lombalgia. if erupcoes_cutaneas and coceira and vermelhidao_na_pele then urticaria. if dor_abdominal and diarreia and perda_de_peso and presenca_de_sangue_nas_fezes then colite_ulcerativa. if tosse and tosse_prolongada and febre and suores_noturnos and perda_de_peso then tuberculose. if dor_de_cabeca and tontura and falta_de_ar then hipertensao. if dificuldade_respiratoria and cansaco and inchaco_nas_pernas and tosse and tosse_seca then insuficiencia_cardiaca. %Treatments tratamento(nome_tratamento, [tratamentos], custo, duracao). tratamento(gripe, [repouso, hidratacao, paracetamol], 7, 7). tratamento(anemia, [dieta, suplemento_ferro], 15, 15). tratamento(asma, [inalador], 40, 10). tratamento(gastroenterite, [hidratacao, dieta], 0, 30). tratamento(migranea, [aspirina, repouso], 10, 10). tratamento(dengue, [hidratacao, paracetamol], 3, 15). tratamento(apendicite, [cirurgia], 1500, 1). tratamento(pneumonia, [antibiotico], 10, 15). tratamento(mono, [hidratacao, repouso], 0, 10). tratamento(hipotireoidismo, [terapia_hormonal], 90, 3). tratamento(hipertireoidismo, [antitireoidiano], 35, 5). tratamento(diabetes, [dieta, exercicio, insulina], 15, 5). tratamento(lombalgia, [fisioterapia, brufen], 10, 15). tratamento(urticaria, [antihistaminico], 20, 5). tratamento(colite_ulcerativa, [antiinflamatorio], 15, 7). tratamento(tuberculose, [antibiotico], 30, 30). tratamento(hipertensao, [dieta, antihipertensivo], 5, 15). tratamento(insuficiencia_cardiaca, [dieta, vasodilatador, diuretico], 5, 15).
修正后的界面代码
:- dynamic (fact/1). :- dynamic (demo/1). %Iniciate consultation iniciar_consulta :- retractall(fact(_)), writeln('Bem-vindo ao sistema de diagnostico medico.'), writeln('Por favor, responda às seguintes perguntas com 1 (sim) ou 2 (nao):'), perg1. % 完善每个提问规则,处理输入1和输入2的情况 perg1 :- writeln('Tem febre?'), read(S), (S == 1 -> assert(fact(febre)) ; true), perg2. perg2 :- writeln('Tem tosse?'), read(S), (S == 1 -> assert(fact(tosse)) ; true), perg3. perg3 :- writeln('Tem tosse seca?'), read(S), (S == 1 -> assert(fact(tosse_seca)) ; true), perg4. perg4 :- writeln('Tem tosse prolongada?'), read(S), (S == 1 -> assert(fact(tosse_prolongada)) ; true), perg5. perg5 :- writeln('Tem cansaço?'), read(S), (S == 1 -> assert(fact(cansaco)) ; true), perg6. perg6 :- writeln('Tem nervosismo?'), read(S), (S == 1 -> assert(fact(nervosismo)) ; true), perg7. perg7 :- writeln('Tem naúseas?'), read(S), (S == 1 -> assert(fact(nausea)) ; true), perg8. perg8 :- writeln('Tem diarreia?'), read(S), (S == 1 -> assert(fact(diarreia)) ; true), perg9. perg9 :- writeln('Tem vómitos?'), read(S), (S == 1 -> assert(fact(vomito)) ; true), perg10. perg10 :- writeln('Tem coceira?'), read(S), (S == 1 -> assert(fact(coceira)) ; true), perg11. perg11 :- writeln('Tem taquicardia?'), read(S), (S == 1 -> assert(fact(taquicardia)) ; true), perg12. perg12 :- writeln('Tem tonturas?'), read(S), (S == 1 -> assert(fact(tontura)) ; true), perg13. perg13 :- writeln('Tem dor abdominal?'), read(S), (S == 1 -> assert(fact(dor_abdominal)) ; true), perg14. perg14 :- writeln('Tem dor de cabeca?'), read(S), (S == 1 -> assert(fact(dor_de_cabeca)) ; true), perg15. perg15 :- writeln('Tem dor muscular?'), read(S), (S == 1 -> assert(fact(dor_muscular)) ; true), perg16. perg16 :- writeln('Tem dor no peito?'), read(S), (S == 1 -> assert(fact(dor_no_peito)) ; true), perg17. perg17 :- writeln('Tem dor de garganta?'), read(S), (S == 1 -> assert(fact(dor_de_garganta)) ; true), perg18. perg18 :- writeln('Tem dificuldade respiratória?'), read(S), (S == 1 -> assert(fact(dificuldade_respiratoria)) ; true), perg19. perg19 :- writeln('Tem rigidez muscular?'), read(S), (S == 1 -> assert(fact(rigidez_muscular)) ; true), perg20. perg20 :- writeln('Tem perda de apetite?'), read(S), (S == 1 -> assert(fact(perda_de_apetite)) ; true), perg21. perg21 :- writeln('Tem inchaço nos gânglios?'), read(S), (S == 1 -> assert(fact(inchaco_nos_ganglios)) ; true), perg22. perg22 :- writeln('Tem inchaço nas pernas?'), read(S), (S == 1 -> assert(fact(inchaco_nas_pernas)) ; true), perg23. perg23 :- writeln('Tem erupções cutâneas?'), read(S), (S == 1 -> assert(fact(erupcoes_cutaneas)) ; true), % 修正拼写,使用下划线 perg24. perg24 :- writeln('Tem vermelhidão na pele?'), read(S), (S == 1 -> assert(fact(vermelhidao_na_pele)) ; true), perg25. perg25 :- writeln('Tem sensibilidade à luz?'), read(S), (S == 1 -> assert(fact(sensibilidade_a_luz)) ; true), perg26. perg26 :- writeln('Tem perdido peso?'), read(S), (S == 1 -> assert(fact(perda_de_peso)) ; true), perg27. perg27 :- writeln('Tem ganho peso?'), read(S), (S == 1 -> assert(fact(aumento_de_peso)) ; true), perg28. perg28 :- writeln('Tem intolerância ao frio?'), read(S), (S == 1 -> assert(fact(intolerancia_ao_frio)) ; true), perg29. perg29 :- writeln('Tem intolerância ao calor?'), read(S), (S == 1 -> assert(fact(intolerancia_ao_calor)) ; true), % 修正提问文本格式 perg30. perg30 :- writeln('Tem urinado frequentemente?'), read(S), (S == 1 -> assert(fact(urinacao_frequente)) ; true), perg31. perg31 :- writeln('Tem sede excessiva?'), read(S), (S == 1 -> assert(fact(sede_excessiva)) ; true), perg32. perg32 :- writeln('Tem fome frequente?'), read(S), (S == 1 -> assert(fact(fome_frequente)) ; true), perg33. perg33 :- writeln('Tem presença de sangue nas fezes?'), read(S), (S == 1 -> assert(fact(presenca_de_sangue_nas_fezes)) ; true), perg34. perg34 :- writeln('Tem suores noturnos?'), read(S), (S == 1 -> assert(fact(suores_noturnos)) ; true), perg35. perg35 :- writeln('Tem falta de ar?'), read(S), (S == 1 -> assert(fact(falta_de_ar)) ; true). %Diagnosing the disease - 仅输出推导的疾病,排除用户输入的症状 doenca :- demo(X), % 检查X是否是推导的疾病(即不存在对应的if规则以X为条件) \+ (if X then _), writeln('Baseado nos sintomas fornecidos, pode ter:'), writeln(X), nl. doenca :- writeln('Não conseguimos diagnosticar uma doença com os sintomas fornecidos.'), nl. %Providing Treatment - 仅针对推导的疾病输出治疗方案 tratamento :- demo(X), \+ (if X then _), tratamento(X, Tratamentos, Custo, Duracao), writeln('Tratamento recomendado:'), write('Para tratar '), write(X), write(' recomendamos o seguinte tratamento: '), writeln(Tratamentos), write('Este tratamento terá um custo total de: '), writeln(Custo), write('E uma duração (em dias) de: '), writeln(Duracao), nl. tratamento :- true. % 无匹配疾病时不报错 %Main Function to Execute Consultation consulta :- iniciar_consulta, demo, % 执行前向推理,推导疾病 doenca, tratamento.
关键修正说明
- 提问逻辑完善:使用Prolog的
->条件语句处理输入1(断言症状)和输入2(直接跳转)的情况,确保无论用户输入1或2,程序都会继续下一个问题。 - 拼写统一:将
erupcoes cutaneas改为erupcoes_cutaneas,与规则代码中的症状名称一致。 - 诊断逻辑优化:
doenca规则添加\+ (if X then _)条件,排除用户输入的症状,仅输出推导的疾病;同时增加无匹配疾病时的提示。 - 治疗方案输出优化:
tratamento规则仅针对推导的疾病输出方案,避免遍历所有事实导致的重复输出。
内容的提问来源于stack exchange,提问作者Francisca Ventura
相关产品推荐
相关产品推荐

