我正在构建一个界面,其目的是诊断某人并提供一种治疗形式,包括治疗方法、治疗费用和持续时间。我首先提供症状列表,并询问用户是否有症状(插入 1)或是否没有(插入 2)。然后我将症状列表与某种疾病联系起来,并提供治疗信息。理论上是这样。因为当我在 SWI-Prolog 中运行代码时,我得到的结果是:
Derived: gripe
No more factsBaseado nos sintomas fornecidos, pode ter:
gripe
No more factsTem dor muscular?
|:
这意味着我能够诊断并告诉用户他们患有的疾病,但之后我们应该去治疗,但由于某种原因,它一直回到问题 15 (perg15)。
我已经在这里提出了类似的问题,但与此同时更改了我的代码,随之而来的是新问题的出现。我对序言非常陌生,如果有人能准确解释我的代码中需要更改的内容,我将非常感激。
这是我设置规则的代码:
:- dynamic (fact/1).
:- 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).
%Main Function to execute consultation
consulta :-
iniciar_consulta,
doenca,
tratamento.
%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.
perg1 :- writeln('Tem febre?'), read(S), (S == 1, assert(fact(febre)), perg2); (S \== 1, perg2).
perg2 :- writeln('Tem tosse?'), read(S), (S == 1, assert(fact(tosse)), perg3); (S \== 1, perg3).
perg3 :- writeln('Tem tosse seca?'), read(S), (S == 1, assert(fact(tosse_seca)), perg4); (S \== 1, perg4).
perg4 :- writeln('Tem tosse prolongada?'), read(S), (S == 1, assert(fact(tosse_prolongada)), perg5); (S \== 1, perg5).
perg5 :- writeln('Tem cansaço?'), read(S), (S == 1, assert(fact(cansaco)), perg6); (S \== 1, perg6).
perg6 :- writeln('Tem nervosismo?'), read(S), (S == 1, assert(fact(nervosismo)), perg7); (S \== 1, perg7).
perg7 :- writeln('Tem naúseas?'), read(S), (S == 1, assert(fact(nausea)), perg8); (S \== 1, perg8).
perg8 :- writeln('Tem diarreia?'), read(S), (S == 1, assert(fact(diarreia)), perg9); (S \== 1, perg9).
perg9 :- writeln('Tem vómitos?'), read(S), (S == 1, assert(fact(vomito)), perg10); (S \== 1, perg10).
perg10 :- writeln('Tem coceira?'), read(S), (S == 1, assert(fact(coceira)), perg11); (S \== 1, perg11).
perg11 :- writeln('Tem taquicardia?'), read(S), (S == 1, assert(fact(taquicardia)), perg12); (S \== 1, perg12).
perg12 :- writeln('Tem tonturas?'), read(S), (S == 1, assert(fact(tontura)), perg13); (S \== 1, perg13).
perg13 :- writeln('Tem dor abdominal?'), read(S), (S == 1, assert(fact(dor_abdominal)), perg14); (S \== 1, perg14).
perg14 :- writeln('Tem dor de cabeca?'), read(S), (S == 1, assert(fact(dor_de_cabeca)), perg15); (S \== 1, perg15).
perg15 :- writeln('Tem dor muscular?'), read(S), (S == 1, assert(fact(dor_muscular)), perg16); (S \== 1, perg16).
perg16 :- writeln('Tem dor no peito?'), read(S), (S == 1, assert(fact(dor_no_peito)), perg17); (S \== 1, perg17).
perg17 :- writeln('Tem dor de garganta?'), read(S), (S == 1, assert(fact(dor_de_garganta)), perg18); (S \== 1, perg18).
perg18 :- writeln('Tem dificuldade respiratória?'), read(S), (S == 1, assert(fact(dificuldade_respiratoria)), perg19); (S \== 1, perg19).
perg19 :- writeln('Tem rigidez muscular?'), read(S), (S == 1, assert(fact(rigidez_muscular)), perg20); (S \== 1, perg20).
perg20 :- writeln('Tem perda de apetite?'), read(S), (S == 1, assert(fact(perda_de_apetite)), perg21); (S \== 1, perg21).
perg21 :- writeln('Tem inchaço nos gânglios?'), read(S), (S == 1, assert(fact(inchaco_nos_ganglios)), perg22); (S \== 1, perg22).
perg22 :- writeln('Tem inchaço nas pernas?'), read(S), (S == 1, assert(fact(inchaco_nas_pernas)), perg23); (S \== 1, perg23).
perg23 :- writeln('Tem erupções cutâneas?'), read(S), (S == 1, assert(fact(erupcoes_cutaneas)), perg24); (S \== 1, perg24).
perg24 :- writeln('Tem vermelhidão na pele?'), read(S), (S == 1, assert(fact(vermelhidao_na_pele)), perg25); (S \== 1, perg25).
perg25 :- writeln('Tem sensibilidade à luz?'), read(S), (S == 1, assert(fact(sensibilidade_a_luz)), perg26); (S \== 1, perg26).
perg26 :- writeln('Tem perdido peso?'), read(S), (S == 1, assert(fact(perda_de_peso)), perg27); (S \== 1, perg27).
perg27 :- writeln('Tem ganho peso?'), read(S), (S == 1, assert(fact(aumento_de_peso)), perg28); (S \== 1, perg28).
perg28 :- writeln('Tem intolerância ao frio?'), read(S), (S == 1, assert(fact(intolerancia_ao_frio)), perg29); (S \== 1, perg29).
perg29 :- writeln('Tem intolerância_ao_calor?'), read(S), (S == 1, assert(fact(intolerancia_ao_calor)), perg30); (S \== 1, perg30).
perg30 :- writeln('Tem urinado frequentemente?'), read(S), (S == 1, assert(fact(urinacao_frequente)), perg31); (S \== 1, perg31).
perg31 :- writeln('Tem sede excessiva?'), read(S), (S == 1, assert(fact(sede_excessiva)), perg32); (S \== 1, perg32).
perg32 :- writeln('Tem fome frequente?'), read(S), (S == 1, assert(fact(fome_frequente)), perg33); (S \== 1, perg33).
perg33 :- writeln('Tem presenca de sangue nas fezes?'), read(S), (S == 1, assert(fact(presenca_de_sangue_nas_fezes)), perg34); (S \== 1, perg34).
perg34 :- writeln('Tem suores noturnos?'), read(S), (S == 1, assert(fact(suores_noturnos)), perg35); (S \== 1, perg35).
perg35 :- writeln('Tem falta de ar?'), read(S), ((S == 1, assert(fact(falta_de_ar)), doenca); (S \== 1, doenca)).
%Diagnosting the disease
doenca :-
demo,
writeln('Baseado nos sintomas fornecidos, pode ter:'),
findall(X, fact(X), Doencas),
last_element(Doencas, Doenca),
writeln(Doenca),
tratamento.
last_element(List, Last) :- last(List, Last).
%Providing treatment for the determined disease
tratamento :-
demo, %sistema de inferência forward, para inferir a doença.
fact(Doenca),
tratamento(Doenca, [Tratamentos], Custo, Duracao),
writeln('Tratamento recomendado:'),
write('Para tratar '),
write(Doenca),
write(' recomendamos o seguinte tratamento: '),
writeln([Tratamentos]),
writeln('Este tratamento terá um custo total de: '),
writeln(Custo),
writeln('E uma duração (em dias) de: '),
writeln(Duracao).
您的代码的问题在于它的结构非常糟糕。我建议你按如下方式重组:
:- op(300, xfy, or).
:- op(200, xfy, and).
:- dynamic(symptom/1).
:- dynamic(disease/1).
% USER INTERFACE
init_consult :-
writeln('Bem-vindo ao sistema de diagnóstico médico.'),
writeln('Por favor, responda às perguntas com s ou n.\n'),
check_symptoms,
identify_diseases,
recommend_treatments.
check_symptoms :-
retractall(symptom(_)),
symptoms(Symptoms),
forall(member(Symptom,Symptoms), ask_symptom(Symptom)).
ask_symptom(Symptom) :-
format('Tem ~w? ', [Symptom]),
read_line_to_string(user_input, Answer),
ignore((Answer="s", assertz(symptom(Symptom)))).
identify_diseases :-
retractall(disease(_)),
diseases(Diseases),
forall(member(Disease, Diseases), prove_disease(Disease) ).
recommend_treatments :-
forall(disease(Disease), recommend_treatment(Disease)).
recommend_treatment(Disease) :-
treatment(Disease, Treatment, Cost, Duration),
format('\nBaseado nos sintomas, pode ter: ~w\n', [Disease]),
format('Tratamento recomendado: ~w\n', [Treatment]),
format('Custo total do tratamento: ~w\n', [Cost]),
format('Duração do tratamento (em dias): ~w\n', [Duration]).
% BACKWARD CHAINING
prove_disease(D) :- disease(D), !.
prove_disease(D) :- if(C, D), ignore((prove_symptoms(C), assertz(disease(D)))).
prove_symptoms(Q) :- symptom(Q), !.
prove_symptoms(P and Q) :- prove_symptoms(P), prove_symptoms(Q).
prove_symptoms(P or Q) :- prove_symptoms(P) ; prove_symptoms(Q).
% SYMPTOMS, DISEASES AND TREATMENTS
symptoms([febre, tosse, dor_de_cabeça, cansaço, palidez, dificuldade_respiratória]).
diseases([gripe, anemia, asma]).
if(febre and tosse and dor_de_cabeça and cansaço, gripe).
if(cansaço and palidez, anemia).
if(dificuldade_respiratória and tosse, asma).
treatment(gripe, [repouso, hidratação, paracetamol], 7, 7).
treatment(anemia, [dieta, suplemento_ferro], 15, 15).
treatment(asma, [inalador], 40, 10).
示例:
?- init_consult.
Bem-vindo ao sistema de diagnóstico médico.
Por favor, responda às perguntas com s ou n.
Tem febre? s
Tem tosse? s
Tem dor_de_cabeça? s
Tem cansaço? s
Tem palidez? n
Tem dificuldade_respiratória? s
Baseado nos sintomas, pode ter: gripe
Tratamento recomendado: [repouso,hidratação,paracetamol]
Custo total do tratamento: 7
Duração do tratamento (em dias): 7
Baseado nos sintomas, pode ter: asma
Tratamento recomendado: [inalador]
Custo total do tratamento: 40
Duração do tratamento (em dias): 10
true.