Search code examples
listprologrulesfact

Prolog: facts and rules


I have the following situation, I have to make a predicate that represents a doctor attending a patient, but it does not work.

doctor(adele).
doctor(inez).
doctor(elin).

patient(aurora).
patient(mandy).
patient(roan).

doctor_attends_patient(doc,pat):-doctor(doc),patient(pat).

When making the query returns false.

doctor_attends_patient(adele,roan).
false

Solution

  • As was said before, predicates can be read as

    to_prove(This) :- need_to_prove(This) , and_also(That).
    

    so

    doctor_attends_patient(doc, pat) :- doctor(doc), patient(pat).
    

    means that to prove

    doctor_attends_patient(doc, pat)
    

    Prolog needs to prove

                                        doctor(doc), patient(pat).
    

    Both of these sub-goals are ground, do not contain any logical Variables, so to be proven they must match some fact(s) in our knowledge base. But we only have

    doctor(adele).
    doctor(inez).
    doctor(elin).
    
    patient(aurora).
    patient(mandy).
    patient(roan).
    

    We do not have doctor(doc) nor patient(pat) as stated facts.

    doctor(Doc) on the other hand, would match any of the stated doctor/1 facts, because Doc is a logical variable able to assume any value.

    As Daniel Lyons points in the comments, variable names are Capitalized, in Prolog.

    You can now fix your predicate definition.


    As to your query,

    doctor_attends_patient(adele,roan)
    

    also does not match any facts nor rule heads in your knowledge base. The only rule with remotely matching head you have is

    doctor_attends_patient(doc, pat) :- doctor(doc), patient(pat).
    

    but the compound term

    doctor_attends_patient( adele, roan)
    

    does not match the compound term

    doctor_attends_patient( doc  , pat )
    

    because though the functors of both terms, doctor_attends_patient, do match, and their arities, 2, match also, none of the arguments inside the parentheses match. In particular,

        adele = doc
    

    fails, and also

        roan = pat
    

    would also fail, if tried.

    But if you were using variables, then

        adele = Doc , roan = Pat
    

    would instead succeed, resulting in a substitution Doc = adele , Pat = roan. Since the rule's head would then match too, as a whole,

    doctor_attends_patient(adele,roan)
    doctor_attends_patient( Doc , Pat)
    

    the rule's body would be entered, and Prolog would try to prove the resulting sub-goals after substituting any variables therein with their values in the successful substitution.

    You can now fix your predicate definition.