You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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.

关键修正说明

  1. 提问逻辑完善:使用Prolog的->条件语句处理输入1(断言症状)和输入2(直接跳转)的情况,确保无论用户输入1或2,程序都会继续下一个问题。
  2. 拼写统一:将erupcoes cutaneas改为erupcoes_cutaneas,与规则代码中的症状名称一致。
  3. 诊断逻辑优化:doenca规则添加\+ (if X then _)条件,排除用户输入的症状,仅输出推导的疾病;同时增加无匹配疾病时的提示。
  4. 治疗方案输出优化:tratamento规则仅针对推导的疾病输出方案,避免遍历所有事实导致的重复输出。

内容的提问来源于stack exchange,提问作者Francisca Ventura

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 22:17:31