Discussions related to Visual Prolog
Andro
Posts: 2
Joined: 8 Sep 2015 2:46

Need More sample and logic

Unread post by Andro »

Hi All,

I am a programmer in VB but newbie for prolog programming, I had learn LISP and Prolog when I was in University but now already forget.. :roll:
In last few weeks, I downloaded personal edition and start to study from sample and from youtube.

Right now I plan to make my personal project to an automatic identify disease for a Doctor. I already tried coding using VB but it's so complicated with too many "IF Else" and too many possibilities. My VB connect to database MySQL to stored symptoms of disease.

I found some sample, but it's very simple (http://www.dailyfreecode.com/Code/prolo ... -3075.aspx). From that website it's only base on symptoms, no root cause such as bacteria of virus etc.

Maybe anyone in this forum, can help me to share link for any information about doctor using any prolog compiler (it will be great if Visual Prolog). I need to learn deep for the logic before starting to purchase visual prolog.

Thank you very much.

Herewith sample from : http://www.dailyfreecode.com/Code/prolo ... -3075.aspx

Code: Select all

domains     disease,indication = symbol     Patient,name = string     predicates     hypothesis(string,disease)     symptom(name,indication)     response(char)     go clauses     go :-         write("What is the patient's name? "),         readln(Patient),         hypothesis(Patient,Disease),         write(Patient,"probably has ",Disease,"."),nl.             go :-         write("Sorry, I don't seem to be able to"),nl,         write("diagnose the disease."),nl.             symptom(Patient,fever) :-         write("Does ",Patient," have a fever (y/n) ?"),         response(Reply),         Reply='y'.         symptom(Patient,rash) :-         write("Does ",Patient," have a rash (y/n) ?"),         response(Reply),         Reply='y'.         symptom(Patient,headache) :-         write("Does ",Patient," have a headache (y/n) ?"),         response(Reply),         Reply='y'.         symptom(Patient,runny_nose) :-         write("Does ",Patient," have a runny_nose (y/n) ?"),         response(Reply),         Reply='y'.         symptom(Patient,conjunctivitis) :-         write("Does ",Patient," have a conjunctivitis (y/n) ?"),         response(Reply),         Reply='y'.         symptom(Patient,cough) :-         write("Does ",Patient," have a cough (y/n) ?"),         response(Reply),         Reply='y'.         symptom(Patient,body_ache) :-         write("Does ",Patient," have a body_ache (y/n) ?"),         response(Reply),         Reply='y'.         symptom(Patient,chills) :-         write("Does ",Patient," have a chills (y/n) ?"),         response(Reply),         Reply='y'.         symptom(Patient,sore_throat) :-         write("Does ",Patient," have a sore_throat (y/n) ?"),         response(Reply),         Reply='y'.         symptom(Patient,sneezing) :-         write("Does ",Patient," have a sneezing (y/n) ?"),         response(Reply),         Reply='y'.             symptom(Patient,swollen_glands) :-         write("Does ",Patient," have a swollen_glands (y/n) ?"),         response(Reply),         Reply='y'.             hypothesis(Patient,measles) :-         symptom(Patient,fever),         symptom(Patient,cough),         symptom(Patient,conjunctivitis),         symptom(Patient,runny_nose),         symptom(Patient,rash).         hypothesis(Patient,german_measles) :-         symptom(Patient,fever),         symptom(Patient,headache),         symptom(Patient,runny_nose),         symptom(Patient,rash).             hypothesis(Patient,flu) :-         symptom(Patient,fever),         symptom(Patient,headache),         symptom(Patient,body_ache),         symptom(Patient,conjunctivitis),         symptom(Patient,chills),         symptom(Patient,sore_throat),         symptom(Patient,runny_nose),         symptom(Patient,cough).                 hypothesis(Patient,common_cold) :-         symptom(Patient,headache),         symptom(Patient,sneezing),         symptom(Patient,sore_throat),         symptom(Patient,runny_nose),         symptom(Patient,chills).             hypothesis(Patient,mumps) :-         symptom(Patient,fever),         symptom(Patient,swollen_glands).         hypothesis(Patient,chicken_pox) :-         symptom(Patient,fever),         symptom(Patient,chills),         symptom(Patient,body_ache),         symptom(Patient,rash).         hypothesis(Patient,measles) :-         symptom(Patient,cough),         symptom(Patient,sneezing),         symptom(Patient,runny_nose).             response(Reply) :-         readchar(Reply),         write(Reply),nl.
Harrison Pratt
VIP Member
Posts: 439
Joined: 5 Nov 2000 0:01

Unread post by Harrison Pratt »

As a first step, think carefully about how you will model the facts (collections of observations) which permit diagnosis of various diseases with XX% probability.

Then, figure out how you can represent these in a form that is easy to maintain, perhaps in a text file that you can parse into prolog facts in your expert system shell. Consider whether you want to embed the questions and possible answers for the user interface in this database. You could, as an example, use an INI type data structure for hypotheses and symptom queries:

Code: Select all

[measles] cough=1 sneezing=1 runny_nose=1 rash=0   [body_ache] question="Does <patient> have a body ache (y/n)?" responses=Y,N,UNKNOWN
A disease fact could look something like this:

Code: Select all

hypothesis(measles,[cough,sneezing,runny_nose],[rash]).
and a question fact could look like this:

Code: Select all

question("Does <patient> have a body ache (y/n",[yes,no,unknown]).

The structure of the facts for disease definition will both determine and be determined by the inference logic you create in the program.

Embedding the knowledge in the program source code is one of the worse ways to attack this problem, except for small "toy" projects.
Andro
Posts: 2
Joined: 8 Sep 2015 2:46

Unread post by Andro »

Dear Harrison,

Thank you for your explanation. It give me an inspiration.
yes you're right, Embedding the knowledge in the program source code it make not flexible for development.
Anyway that sample is very simple. The program should more complex, since it connect to database.
but since in personal edition not available for OdbcDemo, I still get difficulties to learn and not so many information I get from internet

Thank you
Harrison Pratt
VIP Member
Posts: 439
Joined: 5 Nov 2000 0:01

Unread post by Harrison Pratt »

Andro,
You can use text files and VIP databases you process with file::consult and file::save predicates to store your diagnostic criteria. These can be large enough to support your project with no significant performance loss. Don't let lack of access to ODBC stymie you.

As a side question, what medical domain are you planning to attack with your application?
Martin Meyer
VIP Member
Posts: 328
Joined: 14 Nov 2002 0:01

Unread post by Martin Meyer »

Hello Andro (and Harrison),

Visual Prolog does not follow standard Prolog but has its own dialect. You have probably noticed already, that the example code from your link does not compile in Visual Prolog.

Below is a translation of the example into Visual Prolog. I improved the logic a little to output all possible diseases omitting double questions and double output lines.

Many ways exist in Visual Prolog to expand the example's functionality and user interface to a full blown windows application. Maybe the translated code gives you a point to start from.

To run the translated example in Visual Prolog (build 7501), create a new project of style "console application", replace the contents of file "main.pro" by the below code and type Alt+F5.

Code: Select all

implement main   domains     symptom = symbol.     disease = symbol.   clauses     run() :-         stdIo::write("What is the patient's name? "),         Patient = stdIo::readLine(),         checkAllHypothesis(Patient),         if not(patientDisease(Patient, _)) then             stdIo::write("Sorry, I don't seem to be able to"),             stdIo::nl,             stdIo::write("diagnose the disease.")         else             foreach patientDisease(Patient, Disease) do                 stdIo::write(Patient, " possibly has ", Disease, "."),                 stdIo::nl             end foreach         end if,         stdIo::nl,         stdIo::write("Run again ? "),         if response() = true then             run()         end if.   class facts     hypothesis : (         symptom* SymptomList,         disease Disease)         nondeterm. clauses     hypothesis(["fever", "cough", "conjunctivitis", "runny nose", "rash"], "measles").     hypothesis(["fever", "headache", "runny nose", "rash"], "german measles").     hypothesis(["fever", "headache", "body ache", "conjunctivitis", "chills", "sore throat", "runny nose", "cough"], "flu").     hypothesis(["headache", "sneezing", "sore throat", "runny nose", "chills"], "common cold").     hypothesis(["fever", "swollen glands"], "mumps").     hypothesis(["fever", "chills", "body ache", "rash"], "chicken pox").     hypothesis(["cough", "sneezing", "runny nose"], "measles").   class facts     patientSymptom : (         string Patient,         symptom Symptom,         boolean Reply)         nondeterm.   class facts     patientDisease : (         string Patient,         disease Disease)         nondeterm.   class predicates      checkAllHypothesis : (string Patient). clauses      checkAllHypothesis(Patient) :-         hypothesis(SymptomList, Disease),  % For any hypothesis, i.e. for any SymptomList of a Disease:             not(patientDisease(Patient, Disease)),  % It's yet unknown, whether Patient has Disease.             not  % There is no solution for:                 ((                     Symptom in SymptomList,  % For any Symtom of the Disease:                         patientSymptom(Patient, Symptom, false)  % It's already known, that Patient doesn't have Symptom.                 )),             not  % There is no solution for:                 ((                     Symptom in SymptomList,  % For any Symtom of the Disease:                         not(patientSymptom(Patient, Symptom, true)),  % It's yet unknown, whether Patient has Symptom.                         not(checkSymptom(Patient, Symptom))  % Checking Patient shows, that Patient does not have Symptom.                 )),             assert(patientDisease(Patient, Disease)),  % Add the knowledge, that Patient has Disease.             fail.      checkAllHypothesis(_).   class predicates      checkSymptom : (         string Patient,         symptom Symptom)         determ. clauses      checkSymptom(Patient, Symptom) :-         stdIo::write("Does ", Patient, " have ", Symptom, " (y/n)? "),         Reply = response(),         assert(patientSymptom(Patient, Symptom, Reply)),         Reply = true.   class predicates     response : ()         -> boolean Reply. clauses     response() = Reply :-         ReplyString = stdIo::readLine(),         if ReplyString = "n" then             Reply = false         elseif ReplyString = "y" then             Reply = true         else             stdIo::write(" please answer with 'y' or 'n': "),             Reply = response()         end if.   end implement main   goal     console::runUtf8(main::run).
Regards
Martin
Martin Meyer
VIP Member
Posts: 328
Joined: 14 Nov 2002 0:01

Unread post by Martin Meyer »

One of my comments in the code is not accurate. The line

Code: Select all

not(patientSymptom(Patient, Symptom, true)),  % It's yet unknown, whether Patient has Symptom.
should better be

Code: Select all

not(patientSymptom(Patient, Symptom, true)),  % It's not already known, that Patient has Symptom.
The original comment wasn't really wrong, because the case, that patientSymptom(Patient, Symptom, false) holds, is filtered out before; but it did not reflect, for what the line alone is standing for.

Regards
Martin
Peter Muraya
VIP Member
Posts: 147
Joined: 5 Dec 2012 7:29

Unread post by Peter Muraya »

Hi Andro,
I agree with Harrison that:-
As a first step, think carefully about how you will model the facts (collections of observations) which permit diagnosis of various diseases
Martin has done an excellent job of translating the code you provided to the correct visual prolog dialect. The data is embedded in the code -- which -- as Harrison says, is not very good for large cases; but it does greatly clarify the data model (as well as the necessary logic). (I used the personal edition for more than a year to just get this data modelling done satisfactorily. I called prototyping). The resulting model will guide you in structuring the actual (ODBC-compliant) database that you will finally use for building the real project; then you will need the commercial version.
Mutall Data Management Technical Support
Post Reply