CHAPTER 16    Example Prolog Programs

 

In this final tutorial chapter, we present some small example programs intended to stimulate your own ideas and to further illustrate the topics covered in the earlier tutorial chapters. Nearly all of the examples offer plenty of room for expansion; your own ideas can grow into full-blown programs using one of these programs as a starting point.

Building a Small Expert System

In this first example, we show you how to construct a small expert system expert system, sample that figures out which of seven animals (if any) the system's user has in mind. The expert system will figure out the animal by asking questions then making deductions from the replies given. This example demonstrates back­tracking--using facts--and how to use not effectively.

A typical user dialogue with this expert system might be:

    has it hair?

    yes

    does it eat meat?

    yes

    has it a fawn color?

    yes

    has it dark spots?

    yes

Your animal may be a cheetah!

Visual Prolog's ability to check facts and rules will provide your program with the reasoning capabilities germane to an expert system. The first step is to provide the knowledge with which the system can reason; this is known as the inference engine and is shown in ch16e01.pro.

/* Program ch16e01.pro */

 

PREDICATES

    nondeterm animal_is(symbol)

    nondeterm it_is(symbol)

    ask(symbol,symbol,symbol)

    remember(symbol,symbol,symbol)

    positive(symbol,symbol)

    negative(symbol,symbol)

    clear_facts

    run

 

CLAUSES

    animal_is(cheetah):-

        it_is(mammal),

        it_is(carnivore),

        positive(has,tawny_color),

        positive(has,dark_spots).

 

    animal_is(tiger):-

        it_is(mammal),

        it_is(carnivore),

        positive(has, tawny_color),

        positive(has, black_stripes).

 

    animal_is(giraffe):-

        it_is(ungulate),

        positive(has,long_neck),

        positive(has,long_legs),

        positive(has, dark_spots).

 

    animal_is(zebra):-

        it_is(ungulate),

        positive(has,black_stripes).

 

    animal_is(ostrich):-

        it_is(bird),

        negative(does,fly),

        positive(has,long_neck),

        positive(has,long_legs),

        positive(has, black_and_white_color).

 

    animal_is(penguin):-

        it_is(bird),

        negative(does,fly),

        positive(does,swim),

        positive(has,black_and_white_color).

 

    animal_is(albatross):-

        it_is(bird),positive(does,fly_well).

        

    it_is(mammal):-

        positive(has,hair).

    it_is(mammal):-

        positive(does,give_milk).

 

    it_is(bird):-

        positive(has,feathers).

    it_is(bird):-

        positive(does,fly),

        positive(does,lay_eggs).

 

    it_is(carnivore):-

        positive(does,eat_meat).

 

    it_is(carnivore):-

        positive(has,pointed_teeth),

        positive(has, claws),

        positive(has,forward_eyes).

 

    it_is(ungulate):-

        it_is(mammal),

        positive(has,hooves).

 

    it_is(ungulate):-

        it_is(mammal),

        positive(does,chew_cud).

 

    positive(X,Y):-

        xpositive(X,Y),!.

    positive(X,Y):-

        not(xnegative(X,Y)),

        ask(X,Y,yes).

 

    negative(X,Y):-

        xnegative(X,Y),!.

    negative(X,Y):-

        not(xpositive(X,Y)),

        ask(X,Y,no).

 

    ask(X,Y,yes):-

        !,

        write(X," it ",Y,'¡¬n'),

        readln(Reply),nl,

        frontchar(Reply,'y',_),

        remember(X,Y,yes).

        

    ask(X,Y,no):-

        !,

        write(X," it ",Y,'¡¬n'),

        readln(Reply),nl,

        frontchar(Reply,'n',_),

        remember(X,Y,no).

 

    remember(X,Y,yes):-

        assertz(xpositive(X,Y)).

    remember(X,Y,no):-

        assertz(xnegative(X,Y)).

 

    clear_facts:-

        write("¡¬n¡¬nPlease press the space bar to exit¡¬n"),

        retractall(_,dbasedom),readchar(_).

 

    run:-

        animal_is(X),!,

        write("¡¬nYour animal may be a (an) ",X),

        nl,nl,clear_facts.

    run :-

        write("¡¬nUnable to determine what"),

        write("your animal is.¡¬n¡¬n"),

        clear_facts.

 

GOAL

    run.

Each animal is described by a number of attributes that it has (or has not). Those questions that the user is to reply to are the positive(X,Y) and negative(X,Y) ones. The system, therefore, might ask something like this:

    Does it have hair?

Having received a reply to such a question, you want to be able to add the answer to the database, so the system will be able to use the previously gathered information when reasoning.*

For simplicity, this example program will only consider positive and negative replies, so it uses a database containing two predicates:

    DATABASE
        xpositive(symbol, symbol)
        xnegative(symbol, symbol)

The fact that the animal doesn't have hair is represented by

    xnegative(has,hair).

The rules of positive and negative then check to see if the answer is already known, before asking the user. askable

 

negative(X,Y) :-

    xnegative(X,Y), !.

negative(X,Y) :-

    not(xpositive(X,Y)),

    ask(X,Y,no).

Notice that the second rule for both positive and negative ensures that a contradiction won't arise before asking the user.

The ask predicate asks the questions and organizes the remembered replies. If a reply begins with the letter y, the system assumes the answer is Yes; if it begins with n, the answer is No.

/* Asking Questions and Remembering Answers */

 

ask(X, Y, no)  :-  !, write(X, " it ", Y, '¡¬n'),

    readln(Reply),

    frontchar(Reply, 'n', _),

    remember(X, Y, no).

 

remember(X, Y, yes) :- assertz(xpositive(X, Y)).

remember(X, Y, no)  :- assertz(xnegative(X, Y)).

 

/* Clearing Out Old Facts */

clear_facts :- write("¡¬n¡¬nPlease press the space bar to exit¡¬n"),

    retractall(_,dbasedom), readchar(_).

For practice, type in the preceding inference engine and knowledge clauses. Add appropriate declarations to make a complete program, and then try out the result. The completed animal expert system is provided as ch16e01.pro.

An example expert systems shell (GENI.PRO) is also provided with Visual Prolog in the PROGRAMS directory; this shell is based on the same techniques introduced in this example, with the added feature that it allows you to dynamically change the rules.