system_doradzwa_medycznego_.../medical_adviser.pl

348 lines
10 KiB
Prolog

% Ten program ekspercki ma za zadanie pomoc ustalic jakie choroby moga dolegac pacjentowi.
% Choroby posiadaja objawy obowiazkowe i objawy nieobowiazkowe.
% Program jest w stanie rozpoznawac choroby w dwoch stopniach pewnosci.
% Jesli pacjent ma wszystkie obowiazkowe objawy dla choroby (wyzszy stopien pewnosci) sa to
% program wypisze:
% "The patients disease is almost certainly NAZWA_CHOROBY.".
% Jesli pacjent ma przynajmniej jeden (lecz nie wszystkie obowiazkowe) objaw z danej
% choroby (nizszy stopien pewnosci) to zostanie ona tak wypisana:
% "The patients disease might be NAZWA_CHOROBY.".
% Program moze listowac wiele chorob naraz jesli podane objawy pasuja do wiecej niz jednej
% choroby.
% Choroby dla ktorych nie pasuje (nie istnieje w obowiazkowych ani opcjonalnych objawach)
% przynajmniej jeden z podanych przez uzytkownika objawow nie zostana wylistowane.
% Glowna procedura jest: diagnose(Sentences, Answer).
% Jesli wiecej niz jedna choroba pasuje do podanych objawow to mozna podgladac kolejne
% wciskajac klawisz ";".
% Zdania jakie mozna tworzyc to:
% Patient has OBJAW1, OBJAW2, etc. (np. runny nose, spleen enlargment)
% Patients MIEJSCE_BOLU1, MIEJSCE_BOLU2, etc hurts. [hurts, nie hurt!] (np. throat, head)
% Patient OBJAW1, OBJAW2, etc. (np. coughs, faints)
% Patients temperature is CZ_CALKOWITA,CZ_DZIESIETNA. (np. 36,6) [przecinek obowiazkowo miedzy czesc calkowita i dziesietna!]
% Patients erythrocyte level is CZ_CALKOWITA,CZ_DZIESIETNA. (np. 5,5) [przecinek obowiazkowo miedzy czesc calkowita i dziesietna!]
% Wszystkie zdania koncza sie kropka. Mozna zapisac wiele zdan na raz w taki sposob:
% diagnose("Zdanie1 Zdanie2 Zdanie3", Answer).
% np:
% diagnose( "Patient has general weakness, chills. Patients throat hurts. Patients temperature is 39,0. Patients erythrocyte level is 5,0.", Answer).
% Istnieja trzy poziomy goraczki - (-INF ; 37,0]: 0, (37,0 ; 38,0]: 1, (38,0 ; INF): 2.
% Poziom erytrocytow we krwii rowniez jest pogrupowany w poziomy -
% (-INF ; 4,2]: 0, (4,2 ; 5,4]: 1, (5,4 ; INF): 2.
% Choroby wraz z nazwa, objawami obowiazkowymi (pierwsza lista) i opcjonalnymi (druga lista) sa ponizej.
% | ======================= |
% | == disease data base == |
% | ======================= |
disease(
"flu",
[
("pain",["throat"]),
("runny nose"),
("general weakness"),
("coughs")
],
[
("pain",["muscles"]),
("fever",0), ("fever",1), ("fever",2),
("erythrocyte",-1), ("erythrocyte",0), ("erythrocyte",1)
]
).
disease(
"malaria",
[
("fever",2),
("general weakness")
],
[
("pain",["head"]),
("chills"),
("erythrocyte",-1)
]
).
disease(
"angina",
[
("fever",2),
("coughs"),
("general weakness"),
("magnifying lymph nodes"),
("pain",["throat"])
],
[
("cannot swallow"),
("pain",["head"]),
("chills"),
("erythrocyte",-1), ("erythrocyte",0), ("erythrocyte",1)
]
).
disease(
"diphtheria",
[
("fever",1),
("general weakness"),
("dyspnea")
],
[
("unclear speech"),
("cannot swallow"),
("erythrocyte",-1), ("erythrocyte",0), ("erythrocyte",1)
]
).
disease(
"typhoid",
[
("fever",0),
("pain",["stomach"]),
("spleen enlargement")
],
[
"tire symptoms",
("erythrocyte",-1), ("erythrocyte",0), ("erythrocyte",1)
]
).
disease(
"plague",
[
("fever",2),
("general weakness"),
("magnifying lymph nodes"),
("liver enlargement"),
("spleen enlargement")
],
[
("cloded rash"),
("erythrocyte",-1), ("erythrocyte",0), ("erythrocyte",1)
]
).
disease(
"haemophilia",
[
("epistaxis"),
("impaired blood clotting"),
("spleen enlargement")
],
[
("fever",0), ("fever",1), ("fever",2),
("erythrocyte",-1), ("erythrocyte",0), ("erythrocyte",1)
]
).
disease(
"whooping cough",
[
("fever",1),
("pain",["throat"]),
("paroxysmal cough")
],
[
("conjunctivitis"),
("vomits"),
("erythrocyte",-1), ("erythrocyte",0), ("erythrocyte",1)
]
).
disease(
"myasthenia",
[
("excessive fatigue")
],
[
("muscle weakness"),
("double vision"),
("fever",0), ("fever",1), ("fever",2),
("erythrocyte",-1), ("erythrocyte",0), ("erythrocyte",1)
]
).
disease(
"atrial fibrillation",
[
("dizziness"),
("faints"),
("excessive fatigue")
],
[
("coughs"),
("fever",0), ("fever",1), ("fever",2),
("erythrocyte",-1), ("erythrocyte",0), ("erythrocyte",1)
]
).
% | ===================== |
% | == main procedures == |
% | ===================== |
diagnose(Sentences, Answer) :-
interpret(Sentences, Symptoms),
suggest(Symptoms, Answer).
% | ============================= |
% | == data parsing procedures == |
% | ============================= |
% | = interprete input = |
interpret(Input, Symptoms) :-
split_string(Input, ".", " ", Splited),
iterate(Splited,A),
flatten(A, Symptoms).
% | = auxiliary procedures = |
envelop([X], [Z]):-
Z=(X).
envelop([X|Xs], [Z|Zs]) :-
Z=(X),
envelop(Xs,Zs).
envelopPain([X], [Z]):-
Z=("pain",[X]).
envelopPain([X|Xs], [Z|Zs]) :-
Z=("pain",[X]),
envelopPain(Xs,Zs).
iterate([_], []).
iterate([X|Xs], [Z|WithoutLast]) :-
(sub_string(X,_,_,_,"Patient has ")->string_length(X,AA),L is AA-12, sub_string(X,12,L,_,AAA), split_string(AAA, ",", " ", AAAA),envelop(AAAA,Z);
(sub_string(X,_,_,_,"Patient ")->string_length(X,AA),L is AA-8, sub_string(X,8,L,_,AAA), split_string(AAA, ",", " ", AAAA),envelop(AAAA,Z);
(sub_string(X,_,_,_,"Patients erythrocyte level is ")->string_length(X,AA),L is AA-30, sub_string(X,30,L,_,AAA), re_replace(",",".",AAA,AAAA), number_string(VAL,AAAA), (VAL>4.2->(VAL>5.4->Z=("erythrocyte",1);Z=("erythrocyte",0));Z=[("erythrocyte",-1)]);
(sub_string(X,_,_,_,"Patients temperature is ")->string_length(X,AA), sub_string(X,24,4,_,AAA), re_replace(",",".",AAA,AAAA), number_string(VAL,AAAA), (VAL>37.0->(VAL>38.0->Z=("fever",2);Z=("fever",1));Z=[("fever",0)]);
(sub_string(X,_,_,_,"Patients ")->string_length(X,AA),L is AA-15, sub_string(X,9,L,_,AAA), split_string(AAA, ",", " ", AAAA), envelopPain(AAAA,Z);Z="cannot interprete"))))),
iterate(Xs, WithoutLast).
% | ==================================== |
% | == disease recognizing procedures == |
% | ==================================== |
% | = auxiliary procedures = |
includesAll(_, []) :- true, !.
includesAll(List, [Inhd|Intl]) :- member(Inhd, List), includesAll(List, Intl), !.
includesAny(_, []) :- false, !.
includesAny(List, [Inhd|Intl]) :- member(Inhd, List); includesAny(List, Intl), !.
checkForDiseaseStrong(Symptoms, Disease) :-
disease(Disease, ObligatorySymptoms, AdditionalSymptoms),
append(ObligatorySymptoms, AdditionalSymptoms, ExpectedSymptoms),
includesAll(Symptoms, ObligatorySymptoms),
includesAll(ExpectedSymptoms, Symptoms),
!.
checkForDiseaseWeak(Symptoms, Disease) :-
disease(Disease, ObligatorySymptoms, AdditionalSymptoms),
append(ObligatorySymptoms, AdditionalSymptoms, ExpectedSymptoms),
not(checkForDiseaseStrong(Symptoms, Disease)),
includesAny(Symptoms, ExpectedSymptoms),
includesAll(ExpectedSymptoms, Symptoms),
!.
% | = suggest procedure = |
% flu
suggest(Symptoms, Answer) :-
checkForDiseaseStrong(Symptoms, "flu"),
Answer = "The patients disease is almost certainly flu.".
suggest(Symptoms, Answer) :-
checkForDiseaseWeak(Symptoms, "flu"),
Answer = "The patients disease might be flu.".
% malaria
suggest(Symptoms, Answer) :-
checkForDiseaseStrong(Symptoms, "malaria"),
Answer = "The patients disease is almost certainly malaria.".
suggest(Symptoms, Answer) :-
checkForDiseaseWeak(Symptoms, "malaria"),
Answer = "The patients disease might be malaria.".
% angina
suggest(Symptoms, Answer) :-
checkForDiseaseStrong(Symptoms, "angina"),
Answer = "The patients disease is almost certainly angina.".
suggest(Symptoms, Answer) :-
checkForDiseaseWeak(Symptoms, "angina"),
Answer = "The patients disease might be angina.".
% diphtheria
suggest(Symptoms, Answer) :-
checkForDiseaseStrong(Symptoms, "diphtheria"),
Answer = "The patients disease is almost certainly diphtheria.".
suggest(Symptoms, Answer) :-
checkForDiseaseWeak(Symptoms, "diphtheria"),
Answer = "The patients disease might be diphtheria.".
% typhoid
suggest(Symptoms, Answer) :-
checkForDiseaseStrong(Symptoms, "typhoid"),
Answer = "The patients disease is almost certainly typhoid.".
suggest(Symptoms, Answer) :-
checkForDiseaseWeak(Symptoms, "typhoid"),
Answer = "The patients disease might be typhoid.".
% plague
suggest(Symptoms, Answer) :-
checkForDiseaseStrong(Symptoms, "plague"),
Answer = "The patients disease is almost certainly plague.".
suggest(Symptoms, Answer) :-
checkForDiseaseWeak(Symptoms, "plague"),
Answer = "The patients disease might be plague.".
% haemophilia
suggest(Symptoms, Answer) :-
checkForDiseaseStrong(Symptoms, "haemophilia"),
Answer = "The patients disease is almost certainly haemophilia.".
suggest(Symptoms, Answer) :-
checkForDiseaseWeak(Symptoms, "haemophilia"),
Answer = "The patients disease might be haemophilia.".
% whooping cough
suggest(Symptoms, Answer) :-
checkForDiseaseStrong(Symptoms, "whooping cough"),
Answer = "The patients disease is almost certainly whooping cough.".
suggest(Symptoms, Answer) :-
checkForDiseaseWeak(Symptoms, "whooping cough"),
Answer = "The patients disease might be whooping cough.".
% myasthenia
suggest(Symptoms, Answer) :-
checkForDiseaseStrong(Symptoms, "myasthenia"),
Answer = "The patients disease is almost certainly myasthenia.".
suggest(Symptoms, Answer) :-
checkForDiseaseWeak(Symptoms, "myasthenia"),
Answer = "The patients disease might be myasthenia.".
% atrial fibrillation
suggest(Symptoms, Answer) :-
checkForDiseaseStrong(Symptoms, "atrial fibrillation"),
Answer = "The patients disease is almost certainly atrial fibrillation.".
suggest(Symptoms, Answer) :-
checkForDiseaseWeak(Symptoms, "atrial fibrillation"),
Answer = "The patients disease might be atrial fibrillation.".