Suppose you have a disease diagnosis Prolog program that starts with many relations between diseases and symptons:
causes_of(symptom1, Disease) :-
Disease = disease1;
Disease = disease2.
causes_of(symptom2, Disease) :-
Disease = disease2;
Disease = disease3.
causes_of(symptom3, Disease) :-
Disease = disease4.
has_symptom(person1, symptom1).
has_symptom(person1, symptom2).
How can I create a rule with the head ‘has_disease(Person, Disease)’ that will return true if the person has all the symptoms from that disease? Using the example above the following would a sample output:
has_disease(person1, Disease).
Disease = disease2.
Well, there is probably a much simpler way to do this, as my Prolog skills are minor at best.
To be called as follows:
The
findall/3predicate is used first to find all symptoms a person has, then again to find all symptoms a disease has, then a quick check to see if the disease’s symptoms are a subset of the person’s.The way I have written the
has_disease/2predicate prevents it from giving a list of diseases. So I createdhas_diseases/2, which performs anotherfindallon any disease it can find, usinghas_disease/2as the check. Asetof/3call is used last to get unique results on the disease list and order it for convenience.NB. The
atom/1on thehas_disease/2primitive is just to ensure a variable is not passed in forDisease, as it does not work in that case, at least not for me.