// Code ----------------------------------------------------------------------------------------------------------------------------------
disease { // hypothesis for each disease
(tuberculosis, [persistent_cough, constant_fatigue, weight_loss, lack_of_appetite, fever, coughing_blood, night_sweats]);
(pneumonia, [cough, fever, shaking_chills, shortness_of_breath]);
(byssinosis, [chest_tightness, cough, wheezing]);
(pertusis, [runny_nose, mild_fever]);
(pneumoconiosis, [chronic_cough, shortness_of_breath]);
(sarcoidosis, [dry_cough, shortness_of_breath, mild_chest_pain, scaly_rash, fever, red_bumps_on_legs, sore_eyes, swollen_ankles]);
(asbestosis, [chest_tightness, shortness_of_breath, chest_pain, lack_of_appetite]);
(asthma, [wheezing, cough, chest_tightness, shortness_of_breath]);
(bronchiolitis, [wheezing, fever, blue_skin, rapid_breath]);
(influenza, [headache, fever, shaking_chills, nasal_congestion, runny_nose, sore_throat]);
(lung_cancer, [cough, fever, hoarseness, chest_pain, wheezing, weight_loss, lack_of_appetite, coughing_blood, headache, shortness_of_breath]);
}
diagnose.score { // compute a score from the lists matching score
(:l,:s,:o) :- mul(:l,:s,:o); // simply multiply bothe value
}
diagnose { // diagnose the list of symptoms
(:symptoms, :disease) :- lst.length(:symptoms,:symptoms.l), // get the length of the patient's symptoms
#disease(:disease,:list), // query for the disease
lst.length(:list,:list.l), // get the length of the symptoms for the disease's list
#lst.matches(:list,:symptoms,:matches), // get the number of symptoms that matches
div(:matches,:symptoms.l,:symptoms.s), // get % of matches in the patient's symptoms
div(:matches,:list.l,:list.s), // get * of matches in the disease's symptoms
#diagnose.score(:list.s,:symptoms.s,:score),// score the disease
fuzz(:score); // use the score as the value of the inference
}
lst.matches { // count the number of matching items between two lists
(_,[],0)^ :- true;
(:l,[:e?[lst.member(:l)]],1)^ :- true;
(_,[:e],0)^ :- true;
(:l,[:h?[lst.member(:l)]|:r],:c)^ :- #lst.matches(:l,:r,:c1), add(:c1,1,:c);
(:l,[:h?[lst.except(:l)]|:r],:c)^ :- #lst.matches(:l,:r,:c);
}