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.
has_disease(Person, Disease) :- atom(Disease),
findall(Symptom, has_symptom(Person, Symptom), PersonSymptoms),
findall(DSymptom, causes_of(DSymptom, Disease), DiseaseSymptoms),
subset(DiseaseSymptoms, PersonSymptoms).
has_diseases(Person, Diseases) :-
findall(Disease, (causes_of(_, Disease), has_disease(Person, Disease)), DiseaseList),
setof(Disease, member(Disease, DiseaseList), Diseases).
To be called as follows:
?- has_diseases(person1, D).
D = [disease1, disease2, disease3].
The findall/3
predicate 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/2
predicate prevents it from giving a list of diseases. So I created has_diseases/2
, which performs another findall
on any disease it can find, using has_disease/2
as the check. A setof/3
call is used last to get unique results on the disease list and order it for convenience.
NB. The atom/1
on the has_disease/2
primitive is just to ensure a variable is not passed in for Disease
, as it does not work in that case, at least not for me.
You will need a way to query all symptoms, e.g. with findall(S,cause_of(S,disease),SS)
, where SS
will be the list of symptoms for this disease.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With