You are on page 1of 3

A Simple Expert System in Prolog

Recently, I had to write an "intelligent" tourist advisor in Prolog. It was only supposed to be very simple and basically help me learn the basics of Prolog beyond the typical family tree-type programs. In this article we will look at slightly more complicated rules and comparisons. What I am aiming at is to allow you to write programs with an integrated "database" that will allow some relatively powerful queries. Note that since this article was originally published as the Prolog Tutorial Part II, it is assumed that your knowledge of Prolog is very limited. If you have never worked with Prolog before, please read the first installment of the Prolog tutorials first.

The Facts
Obviously, the first part of the program consisted of all the facts. Now the registerEvent fact was quite long, since it consisted of a name, place, the starting month, the starting date, the end date (assuming same month), a rough classification and an event genre. I only created a 16 places in the database. /******************************************************* * registerEvent(Name, Place, Start-Month, Start-Date, * * End-Date, Classification, Genre) * *******************************************************/ registerEvent(grungefest2000, bradford, 9, 12, 14, adolescent, music). registerEvent(moti-curry-house, bradford, -1, -1, -1, cheap, restaurant). registerEvent(the-national-russian-jazz-ensemble, bradford, 1, 1, 1, family, music). registerEvent(horrorfest-2000, leeds, 6, 4, 6, adult, cinema). registerEvent(kiddyland-gokarting-championships, leeds, 10, 4, 4, family, sport). registerEvent(dust, leeds, -1, -1, -1, adult, nightclub). registerEvent(the-old-bar, leeds, -1, -1, -1, cheap, restaurant). registerEvent(est-est-est, leeds, -1, -1, -1, expensive, restaurant). registerEvent(corn-exchange-mall, leeds, -1, -1, -1, family, shopping). registerEvent(manchester-city-zoo, manchester, -1, -1, -1, family, animal). registerEvent(art-erotica-exhibition, manchester, 4, 10, 14, adult, art). registerEvent(bbc-radio-5-live, manchester, 6, 7, 8, family, music). registerEvent(steak-house, manchester, -1, -1, -1, medium, restaurant). registerEvent(york-equine-festival, york, 5, 7, 14, family, sport). registerEvent(york-science-museum, york, -1, -1, -1, family, science). registerEvent(the-flying-horse-pub, york, -1, -1, -1, medium, restaurant). Obviously, the first thing that you'll notice is that all the place names look horrible. This is an unfortunate byproduct of Prolog's syntax, since anything with a capital letter is a variable. While they could have been encompassed in quotation marks, I decided to keep things simple. foodAvailableAt(grungefest2000, cheap). foodAvailableAt(corn-exchange-mall, medium). foodAvailableAt(manchester-city-zoo, expensive). foodAvailableAt(york-equine-festival, medium). foodAvailableAt(york-science-museum, medium). distance(york, leeds, 50). distance(york, manchester, 100). distance(leeds, manchester, 75). distance(leeds, bradford, 25). distance(manchester, bradford, 90). distance(york, bradford, 60).

In Prolog. A simple example of this will be shown soon.._. One thing to note at this juncture is that the distance fact is not reflective. D =< 50).family.G) :. I know.registerEvent(E.M.) so far. The suitableForKids rules basically aids readability of the program further down. partyEvents(E. Notice the semicolon (OR).Ds._. and Prolog is no exception. D =< 50) ._.P. but they tend to differ slightly from most languages: Comparision Greater than Less than Greater than or equal to Less than or equal to Equal Not equal Now we can look at our first rule: /************************************* * U T I L I T Y F U N C T I O N S * *************************************/ near(X. These rules are relatively easy. if you typed "distance(leeds. X)". it is rather confusing.). allYearEvent(E) :. The Rules We now have to introduce some new things. Firstly. What do we do if we want the rules to be exclusive (OR)? We use a semicolon (.registerEvent(E.G). (distance(Y. then the event is an all-year event.registerEvent(E.X = Y ._). SWIProlog would answer "No"._._).M.D). we check whether the two cities we are checking for are in fact the same city (leeds is close to leeds!).registerEvent(E.Y.D). moving swiftly on.X.-1.C.M.family. the cities are close. G \= shopping._. near will return 'Yes' if two cities are close. (distance(X. now we want to check whether the distance between the two cities is close. suitableForKids(E) :.-1._.Ep. getDates(E.G). when designing this program is have to create two facts for every distance between each city._.De) :. but not before I introduce one more thing. In that.P) :. Note that if all the date information is set at -1.-1._. Don't ask me why we have to use the standard equal sign for constants. Note that the underscore tells the Prolog system that we don't care about that information. Comparisions are an intrinsic part of any programming language.._.De. Prolog has all the standard comparisions.C.Ds.Ep). when you separate rules we've used the comma (. york.The other facts are pretty self explanatory._. If the distance between X and Y OR Y and X is less than or equal to 50._._).getEvent(E. We check both for X and Y and Y and X because of that non-reflective property I discussed above. What I didn't want to have to do. though. This makes the rules inclusive (AND).P. near(P.D.Y) :. Prolog Syntax > < >= <= =:= =\= . /************************************* * E N D U S E R F U N C T I O N S * *************************************/ getEvent(E. So.

.T) :. (getEvent(E.. G = restaurant).. Finally.york). Now. .and that's a wrap. foodAvailable(E.T) ._..foodAvailableAt(E.adult.De).10. so we retrieve the necessary dates. Firstly. you may do so here! So now you should be able to create relatively useful programs that can use inclusive and exclusive rules and comparisions .leeds).Ds. De >= D._). The partyEvents rule is fairly complicated. ? nearEvents(E. we need to check the dates. kids hate shopping as a party exercise._). the event either needs to be an allYearEvent or we need to make sure the date passed resides between the dates of the event. getEvent(E. we get a family event (assuming E is passed as a variable). so make sure the genre is "shopping". Then. P).leeds. Get all adult events in Leeds ? getEvents(E. if so how expensive is it? ? foodAvailable(york-science-museum.X).G). Example Queries Here are some examples of how you would use the program: • Is there anything suitable for a party for someone whose birthday is on the 4th October in or near Leeds. Is there food available at the York Science Museum. then we check whether it is near the place P that was passed. and the month passed is equal to the event month. nearEvents(E.getDates(E.Em. Em =:= M))._.4.X. • • • Conclusion If you would like to download the program in its entirety. (allYearEvent(E) . (Ds =< D.near(P. List all events in or near York. ? partyEvents(X. Phew.T.P) :.