GEORGE

George is an example of how a computer program can be written that will converse with a human operator. As we have already established, a computer cannot currently converse very intelligently. However, George makes use of a few simple techniques to ask the operator questions and respond to the answers given.

The program is in two parts. The first part is the component parser listing already described. The second is the listing that follows. You should be able to easily add more prompts and develop your own personality slant for the program.

George is not just a demonstration. It can also be used to develop ideas for creative writing and may even help you sort out difficult decisions! George echoes the entire conversation to a disk file entitled "george.con", which is destroyed each time george is run, so make sure you make a copy if you want to keep a particular conversation!

---------
Listing 6
---------

/*-----------------------------------------------*/
/* Demonstration conversational computer program */
/*-----------------------------------------------*/
#include 
#include 
#include 
#include 
#include 
#include 
#include 

char data[1000];
char last_question;

char user[30];

char *family[] = { "MOTHER", "FATHER", "BROTHER", "SISTER", "SON",
                   "DAUGHTER", "COUSIN", "AUNTY", "UNCLE" , "" };

char *names[42] = { "ALAN", "ANNE", "ANN", "BRIAN", "JAMES", "JIM", "SUE",
                  "SUSAN", "ROGER", "PETE", "PETER", "MATT", "MATTHEW",
                  "MATHEW", "IAN", "HARRY", "TONY", "ALISON", "TANYA",
                  "RICK", "RICHARD", "MICHAEL", "MARTIN", "MIKE","TIM",
                  "TIMOTHY", "GEORGE","HOWARD", "CAROLINE", "SARA", "SARAH",
                  "KATE", "KATY", "TOM", "THOMAS", "JON", "JONATHAN",
                  "CHARLES", "VINCE", "VINCENT","BILL","WILLIAM" };


char *subjects[14] = { "THE GOVERNMENT", "FRENCH FARMERS", "THE SUN NEWSPAPER",
                     "THE SUNDAY SPORT", "INFLATION", "ABORTION", "MARRIAGE",
                     "CHILDREN", "CHANNEL FOUR", "BBC2", "MICHAEL JACKSON",
                     "WOOPI GOLDBERG", "REAL ALE","THE ENVIRONMENT" };

char *authors[11] = { "FREUD", "ENID BLYTON", "JUNG", "LAING", "SHAKESPEAR",
                    "DICKENS", "W.E. JOHNS", "JACK HIGGINS" ,
                    "SCIENCE FICTION" ,    "TOLSTOY" , "TOLKEIN" };


/*------------------------------------*/
/* Data we have learnt about the user */
/*------------------------------------*/
char known[50][100];
int fkn;

FILE *echo;
char query;
char fc;
int ft;
char cf;
char more;

/*---------------------*/
/* Function prototypes */
/*---------------------*/
int DO_YOU_KNOW(void);
void NEED(void);
void NLP(char *, char *, char *, char *,char *, char *, char *, char *,
         char *, char *, char *, char *, char *);
int READ(void);
void REQUIRE(void);
void WANT(void);
int WHAT_ABOUT(void);
void cdecl xprintf(char *, ...);
char *strftos(char *);
char *strrstr(char *, char *);
void strwhy(char *);
void FEED(void);
void BORROW(void);


void cdecl xprintf(char *format, ...)
{
    /* This function echoes the output to the screen and to a disk file */

    va_list arg_ptr;
    static char output[1000];

    va_start(arg_ptr, format);
    vsprintf(output, format, arg_ptr);
    va_end(arg_ptr);

    fputs(output,echo);

    printf("%s",output);
}


void BORROW()
{
    /* Personality code */
    /* What do they want to borrow ? */

    char *p;

    p = strrstr(data,"BORROW");

    if (strcmp(p,"A QUID") == 0 || strcmp(p,"A FIVER") == 0 ||
        strcmp(p,"A POUND") == 0)
    {
        xprintf("HOW DO I KNOW I'LL GET IT BACK?");
    }
    else
        xprintf("NOT BLOODY LIKELY!");
}

void FEED()
{
    /* Prompts the human operator with a randomly selected question */
    /* This keeps the conversation flowing, rather than stagnating into */
    /* an infuriating 'doctor-patient' question and answer routine */

    int n;
    int stop;
    char *p;

    stop = 0;

    if(last_question)
    {
        switch(last_question)
        {
            case 1: xprintf("TELL ME MORE ABOUT YOUR FAMILY.");
                    query = 0;
                    break;

            case 5: xprintf("WHAT DO YOU LIKE ABOUT IT?");
                    last_question = 0;
                    break;

            case 7: xprintf("NICE TO MEET YOU %s.",user);
                    last_question = 0;
                    break;
        }
        last_question = 0;
        stop = 1;
    }
    else
    {
        if (fc == 1)
        {
            xprintf("WHAT'S YOUR FAVOURITE COLOUR?");
            query = 1;
            fc = 2;
            stop = 1;
        }
        else
        if (ft == 0)
        {
            xprintf("DO YOU LIKE PLAYING FOOTBALL?");
            query = 1;
            ft = 1;
            last_question = 5;
            stop = 1;
        }
        else
        if (ft == 1)
        {
            xprintf("DO YOU LIKE WATCHING FOOTBALL?");
            query = 1;
            ft = 2;
            last_question = 5;
            stop = 1;
        }
        else
        if (cf == 0 && !random(20))
        {
            xprintf("DO YOU LIKE CHINESE FOOD?");
            cf = 1;
            query = 1;
            last_question = 5;
            stop = 1;
        }
        else
        if (cf == 1 && !random(20))
        {
            xprintf("DO YOU LIKE INDIAN FOOD?");
            cf = 2;
            query = 1;
            last_question = 5;
            stop = 1;
        }
        else
        if (cf == 2 && !random(20))
        {
            xprintf("HAVE YOU EVER TRIED JAMAICAN CUISINE?");
            cf = 3;
            query = 1;
            stop = 1;
        }
        else
        if (!query && fkn > 1)
        {
            n = random(fkn);
            if (strncmp("I ",known[n],2) == 0)
            {
                p = &known[n][2];
                xprintf("YOU %s",p);
                stop = 1;
            }
        }
        else
        if (!random(15))
            stop = DO_YOU_KNOW();

        if (!stop)
        {
            if (!random(15))
                stop = WHAT_ABOUT();
        }

        if (!stop)
        {
            if (!random(10))
                stop = READ();
        }

        if (!stop)
        {
            if (!random(3))
                xprintf("HMMMMM.");
            else
                xprintf("I SEE.");
        }
    }
}

void WANT()
{
    char *p;

    p = strrstr(data,"I");
    xprintf("WHY DO YOU %s?",p);
    query = 1;
}

void NEED()
{
    /* Respond to a 'I need' statement */
    char *p;

    p = strrstr(data,"I NEED");
    xprintf("HOW WILL YOU FEEL IF YOU GET %s?",p);
    query = 1;
}

void REQUIRE()
{
    /* Respond to a 'I require' statement */
    char *p;

    p = strrstr(data,"I REQUIRE");
    xprintf("HOW WILL YOU FEEL IF YOU GET %s?",p);
    query = 1;
}

int DO_YOU_KNOW()
{
    /* Generates a random 'DO YOU KNOW.....' question */
    /* Once a name has been used it is destroyed to prevent the same */
    /* question being asked again */

    int n;
    n = random(42);

    if (*names[n])
    {
        printf("DO YOU KNOW %s?",names[n]);
        query = 1;
        strcpy(names[n],"");
        return(1);
    }
    return(0);
}

int WHAT_ABOUT()
{
    /* Generates a random 'WHAT DO YOU THINK ABOUT.....' question */
    /* Once a subject has been used it is destroyed to prevent the same */
    /* question being asked again */

    int n;
    n = random(14);

    if (*subjects[n])
    {    printf("WHAT DO YOU THINK ABOUT %s?",subjects[n]);
        strcpy(subjects[n],"");
        query = 1;
        return(1);
    }
    else
        return(0);
}

int READ()
{
    /* Generates a random 'HAVE YOU READ ANY.....' question */
    /* Once an author has been used it is destroyed to prevent the same */
    /* question being asked again */

    int n;
    n = random(11);

    if (*authors[n])
    {
        printf("HAVE YOU READ ANY %s?",authors[n]);
        strcpy(authors[n],"");
        query = 1;
        return(1);
    }
    return(0);
}

void RESPOND(char *data, char *question, char *order, char *object,
         char *object_qualify, char *subject, char *number, char *action,
         char *location, char *colour, char *size, char *who, char *tense)
{
    int done;
    int n;
    char *p;

    /* The 'done' flag indicates when a response has been given */
    done = 0;

    /* Remove trailing punctuation from data */
    if (strchr("!?.",data[strlen(data) - 1]))
        data[strlen(data) - 1] = 0;

    /* Remove trailing spaces */
    p = &data[strlen(data) - 1];
    while(*p == 32 && p >= data)
        *p-- = 0;

    /* Personality code */
    /* The operator has mentioned colours */
    if (*colour && fc == 0)
        fc = 1;

    /* Personality code */
    /* Learn about the operator */
    if (strstr(who,"I") && fkn < 50)
    {
        fkn++;
        strcpy(known[fkn],data);
    }

    /* Personality code */
    /* Is the operator talking about their family? */
    if (!last_question)
    {
        for(n = 0; *family[n]; n++)
        {
            if(strstr(data,family[n]))
            {
                last_question = 3;
                break;
            }
        }
    }

    /* Bad phrase */
    if (*data == 0)
    {
        done = 1;
        xprintf("I DON'T UNDERSTAND");
    }


    /* Automatic responses to standard phrases */
    if (strcmp(data,"THAT IS OKAY") == 0 && !done)
    {
        done = 1;
        FEED();
    }
    if (strcmp(data,"WHERE IS SPAIN") == 0 && !done)
    {
        done = 1;
        xprintf("IN EUROPE.");
    }

    if (strcmp(object,"HELLO") == 0 || strcmp(object,"HI") == 0 ||
        last_question == 6 && !done)
    {
        if(strcmp(who,"I") == 0)
        {
            p = strrstr(data,"AM");
            if(p)
            {
                done = 1;
                if (!*user)
                {
                    strcpy(user,p);
                    xprintf("PLEASED TO MEET YOU %s.",user);
                }
                else
                    xprintf("I DO REMEMBER YOU NAME, %.",user);

                if (last_question == 6 || last_question == 7)
                    last_question = 0;
            }
        }
    }
    if (strcmp(question,"WHAT IS") == 0)
    {
        if (strcmp(data,"THE WEATHER LIKE THERE") == 0 ||
            strcmp(data,"THE WEATHER LIKE") == 0)
        {
            done = 1;
            xprintf("QUITE WARM AND SUNNY.");
        }
        else
        if (strcmp(object,"MATTER") == 0)
        {
            done = 1;
            if (!*subject)
                xprintf("WHAT MAKES YOU THINK SOMETHING'S THE MATTER?");
            else
            {
                p = strrstr(data,"THE MATTER");
                xprintf("WHAT MAKES YOU THINK SOMETHING'S THE MATTER %s?",p);
            }
            query = 1;
        }
        else
        if (strcmp(object,"WRONG") == 0)
        {
            done = 1;
            if (!*subject)
                xprintf("WHAT MAKES YOU THINK SOMETHING'S WRONG?");
            else
            {
                p = strrstr(data,"WRONG");
                xprintf("WHAT MAKES YOU THINK SOMETHING'S WRONG %s?",p);
            }
            query = 1;
        }
    }

    if (strncmp("I BORROW ",data,9) == 0 && strcmp(question,"CAN") == 0)
    {
        done = 1;
        BORROW();
    }
    if (strcmp(data,"I HAVE ALREADY SAID") == 0 ||
        strcmp(data,"I HAVE ALREADY TOLD YOU") == 0 ||
        strcmp(data,"I HAVE ALREADY TOLD YOU THAT") == 0 ||
        strcmp(data,"I HAVE ALREADY SAID THAT") == 0)
    {
        done = 1;
        if (query)
        {
            xprintf("SORRY. MY MEMORY'S NOT WHAT IT USED TO BE.");
            query = 0;
        }
        else
        {
            p = strstr(data,"YOU");
            if (p)
            {
                memmove(p,p+1,strlen(p) + 1);
                strncpy(p,"ME ",2);
            }
            p = data;
            memmove(p+2,p,strlen(p) + 1);
            strncpy(data,"YOU ",3);
            p = strstr(data,"THAT");
            if (p)
            {
                *p = 'W';
                strcat(data,"?");
            }
            else
                strcat(data," WHAT?");
            query = 1;
            xprintf("%s",data);
       }
    }
    if (strcmp(data,"I HAVE") == 0)
    {
        done = 1;
        xprintf("YOU HAVE WHAT?");
        query = 1;
        last_question = 8;
    }
    if (strcmp(object,"BORED") == 0 || strcmp(subject,"BORED") == 0
        && strcmp(who,"I") == 0)
    {
        /* Personality code */
        done = 1;
        xprintf("JOIN THE CLUB!");
    }
    if(strncmp("YOU HAVE ALREADY ASKED ME",data,25) == 0)
    {
        if (query)
        {
            xprintf("HAVE I? SORRY!");
            done = 1;
            query = 0;
        }
        else
        {
            xprintf("I DIDN'T THINK I'D ASKED YOU ANYTHING");
            done = 1;
        }
    }
    if (strcmp(question,"WHAT") == 0 && !done)
    {
        /* Standard what questions */
        if (strcmp(data,"SHALL WE TALK ABOUT") == 0)
        {
            done = 1;
            xprintf("I DON'T KNOW. YOU CHOOSE A SUBJECT.");
        }

    }
    if (strcmp(question,"WHAT DO") == 0 && !done)
    {
        if (strcmp(data,"YOU THINK ABOUT THE ECONOMY") == 0)
        {
            done = 1;
            xprintf("IT'S IN A BIT OF A MESS.");
        }
        else
        if (strcmp(data,"YOU THINK ABOUT OF THE ECONOMY") == 0)
        {
            done = 1;
            xprintf("IT'S IN A BIT OF A MESS.");
        }
        else
        if (strcmp(data,"YOU THINK ABOUT THE STATE OF THE ECONOMY") == 0)
        {
            done = 1;
            xprintf("IT'S IN A BIT OF A MESS.");
        }
        else
        if (strcmp(data,"YOU THINK ABOUT THE STATE OF THE COUNTRY") == 0)
        {
            done = 1;
            xprintf("IT'S IN A BIT OF A MESS.");
        }
        else
        if (strcmp(data,"YOU THINK ABOUT THE ENGLISH CRICKET TEAM") == 0)
        {
            done = 1;
            xprintf("IT'S IN A BIT OF A MESS.");
        }
        else
        if (strcmp(data,"YOU THINK OF THE ENGLISH CRICKET TEAM") == 0)
        {
            done = 1;
            xprintf("IT'S PRETTY HOPELESS!");
        }
        else
        if (strcmp(data,"YOU THINK ABOUT RUGBY") == 0)
        {
            done = 1;
            xprintf("IT'S A GREAT GAME.");
        }
        else
        if (strcmp(data,"YOU THINK ABOUT ENGLISH RUGBY") == 0)
        {
            done = 1;
            xprintf("IT'S REALLY IMPROVING.");
        }
    }
    if (strstr(data,"I WAS ONLY ASKING") && !done)
    {
        done = 1;
        xprintf("OKAY.");
    }
    if (strcmp(question,"HOW IS") == 0 && strcmp(object,"LIFE") == 0 && !done)
    {
        done = 1;
        xprintf("FINE THANKS.\n");
        FEED();
    }

    /* Personality code */
    /* Operator has replied NO to a question */
    if (query && strcmp(data,"NO") == 0 && !done)
    {
        done = 1;
        if (last_question == 5)
        {
            last_question = 0;
            xprintf("NOR DO I.\nI PREFER RUGBY.\n");
            FEED();
            query = 0;
        }
        else
            FEED();
    }

    /* Parsed data. Operator is introducing them self */
    if (strcmp(object,"NAME") == 0 && strcmp(who,"MY") == 0 && *subject)
    {
        done = 1;
        if (!*user)
        {
            strcpy(user,subject);
            xprintf("PLEASED TO MEET YOU %s.\n",user);
        }
        else
            xprintf("I DO REMEMBER YOUR NAME, %.\n",user);
        FEED();
    }

    if (strncmp("I AM ",data,4) == 0 && !done)
    {
        /* Personality code */
        /* Operator has made a statement about them self */
        if (!last_question)
        {
            if (*object_qualify)
            {
                xprintf("WHY ARE YOU %s?",object_qualify);
                query = 1;
                done = 1;
            }
            else
            {
                if (ft == -1 && !random(10))
                    ft = 0;

                done = 1;
                FEED();
            }
        }
        else
        if (*object_qualify)
        {
            xprintf("WHY DO YOU THINK THAT IS?");
            query = 1;
            done = 1;
        }
        else
            xprintf("HMMMM");
    }
    /* Automatic response to standard phrase */
    if (strcmp(data,"I DO NOT KNOW") == 0)
    {
        done = 1;
        if (query && last_question == 4)
        {
            xprintf("LET'S NOT GET METAPHYSICAL!");
            last_question = 0;
            query = 0;
        }
        else
        if (query)
            xprintf("WHAT DO YOU KNOW?");
        else
        {
            xprintf("WHAT DON'T YOU KNOW?");
            last_question = 4;
        }
        query = 1;
    }

    if (strncmp("BECAUSE ",data,8) == 0 && !done)
    {
        if (query || *action)
        {
            done = 1;
            if (strcmp(action,"SEE") == 0)
                FEED();
            else
            if (!random(3))
                xprintf("AND YOU'RE SURE THAT'S WHY?");
            else
                xprintf("ARE YOU SURE?");
        }
        else
        {
            done = 1;
            xprintf("I DON'T UNDERSTAND YOU.");
        }
    }

    if (strcmp(object,"WANT") == 0 && *who == 'I' && !done)
    {
        done = 1;
        WANT();
    }

    if (strcmp(object,"NEED") == 0 && *who == 'I' && !done)
    {
        done = 1;
        NEED();
    }

    if (strcmp(object,"REQUIRE") == 0 && *who == 'I' && !done)
    {
        done = 1;
        REQUIRE();
    }

    /* Semi-automatic reaction to strong phrase */
    if (strstr(action,"HATE") && strstr(data,"HATE "))
    {
        done = 1;
        if (strstr(data,"BECAUSE"))
            xprintf("ARE YOU SURE?");
        else
        {
            data = strstr(data,"HATE ");
            data = strchr(data,32);
            data++;
            xprintf("WHY DO YOU FEEL SO STRONGLY ABOUT %s?",data);
        }
        query = 1;
    }

    if (strstr(action,"LOVE") && strstr(data,"LOVE "))
    {
        done = 1;
        if (strstr(data,"BECAUSE"))
            xprintf("ARE YOU SURE?");
        else
        {
            data = strstr(data,"LOVE ");
            data = strchr(data,32);
            data++;
            xprintf("WHY DO YOU FEEL SO STRONGLY ABOUT %s?",data);
        }
        query = 1;
    }

    /* Parsed decision requested */
    if (strstr(subject," OR ") && !done)
    {
        done = 1;
        p = strchr(action,',');
        if (p)
            *p = 0;
        data = strstr(data,action);
        p = strstr(data," OR ");
        *p = 0;

        /* replace any self references */
        if (strftos(data) == NULL)
        {
            printf("\nNERVOUS BREAKDOWN!");
            exit(0);
        }

        xprintf("WHAT DO YOU THINK WILL HAPPEN IF YOU %s?",data);
        query = 1;
    }


    if (*action && strcmp(who,"I") == 0 && *object && !*subject &&
        !*question && !done)
    {
        done = 1;
        data = strchr(data,32);
        data++;

        if (strncmp("I ",data,2) == 0)
            data++;

        while(*data == 32)
            data++;

        p = &action[strlen(action) - 2];
        if (strcmp(p,"ED") == 0)
            *p = 0;
        if (strcmp(object,"ONLY") == 0)
            xprintf("WHY DO YOU %s?",action);
        else
        if (*p)
        {
            /* Catch silly phrases! */
            if (strncmp(action,"SHOULD",6) == 0)
                xprintf("WHY DO YOU THINK YOU %s?",data);
            else
                xprintf("WHY DO YOU %s?",data);
        }
        else
            xprintf("OH, REALLY?");
        query = 1;
    }

    if (strcmp(order,"TELL") == 0 && !done)
    {
        done = 1;
        xprintf("WHY IS IT SO IMPORTANT TO YOU?");
        query = 1;
    }

    if (*action && strcmp(who,"I") == 0 && *object && *subject && !done)
    {
        done = 1;
        if (strcmp(object,"DON'T") == 0 || strcmp(object,"NOT") == 0)
        {
            p = strstr(data,"DO NOT");
            if (p)
                p += 5;
            else
            {
                p = strstr(data,"DON'T");
                p += 4;
            }
            data = strchr(p,32);
            data++;
            xprintf("WHY DON'T YOU %s?",data);
            query = 1;
        }
        else
        {
            data = strchr(data,32);
            data++;
            if (strncmp(action,"WENT",4) == 0)
            {
                /* catch past tense and trun around for questioning */
                data = strrstr(data,"WENT");
                xprintf("WHY DID YOU GO %s?",data);
            }
            else
                xprintf("WHY DO YOU %s?",data);
            query = 1;
        }
    }

    if (*question == 0 && *order == 0 && strchr(data,',') == NULL && !done)
    {
        /* Statement */
        if ((strstr(subject,"THOUGHT") || strstr(subject,"THINKS")) &&
             *who != 'I')
        {
            xprintf("AND WHAT DO YOU THINK?");
            done = 1;
            query = 1;
            return;
        }

        if (*number == 0)
        {
            if (strstr(data," ARE "))
            {
                if (!*object && *object_qualify)
                    strcpy(object,object_qualify);
                else
                if (!*subject && *object_qualify)
                    strcpy(subject,object_qualify);

                done = 1;
                if (strcmp(who,"YOU"))
                {
                    if (*subject)
                    {
                        if (*who == 0)
                            xprintf("WHY DO YOU THINK %s ARE %s?",
                                     object,subject);
                        else
                        {
                            if (*object_qualify)
                                xprintf("WHAT'S SO %s ABOUT IT?",
                                         object_qualify);
                            else
                                xprintf("WHY DO YOU THINK THAT?");
                        }
                    }
                    else
                        xprintf("WHAT MAKES YOU THINK THEY ARE %s?",object);
                }
                else
                {
                    p = strstr(data,object);
                    memmove(data,p,strlen(p) + 1);
                    while(*p && !strchr(",.;:!?",*p))
                        p++;
                    *p = 0;
                    xprintf("WHY DO YOU THINK I'M %s?",data);
                }
                query = 1;
            }
            else
            if (strstr(data," IS A "))
            {
                if (!*object && *object_qualify)
                    strcpy(object,object_qualify);
                else
                if (!*subject && *object_qualify)
                    strcpy(subject,object_qualify);

                done = 1;
                if (strncmp("A ",data,2) == 0)
                    xprintf("WHY DO YOU THINK A %s IS A %s?",object,subject);
                else
                if (strncmp("THE ",data,4) == 0)
                    xprintf("WHY DO YOU THINK THE %s IS A %s?",object,subject);
                else
                    xprintf("WHY DO YOU THINK %s IS A %s?",object,subject);
                query = 1;
            }
            else
            if (strstr(data," IS "))
            {
                if (!*object && *object_qualify)
                    strcpy(object,object_qualify);
                else
                if (!*subject && *object_qualify)
                    strcpy(subject,object_qualify);

                done = 1;
                if (*who == 0)
                {
                    if (strcmp(subject,object))
                    {
                        if (strstr(data,"IT IS NOT"))
                            xprintf("NO?");
                        else
                            xprintf("WHY DO YOU THINK %s IS %s?",object,
                                     subject);
                    }
                    else
                        done = 0;
                }
                else
                {
                    if (strcmp(who,"MY") == 0)
                    {
                        p = strstr(data,object);
                        p += strlen(object);
                        while (*p == 32)
                            p++;
                        if (strncmp("IS ",p,3) == 0)
                            p += 3;
                        while (*p == 32)
                            p++;
                        xprintf("WHY DO YOU THINK YOUR %s IS %s?",object,p);
                    }
                    else
                    if (strcmp(who,"YOUR") == 0)
                        xprintf("WHY DO YOU THINK MY %s IS %s?",object,subject);
                    else
                    {
                        xprintf("I SEE.\n");
                        FEED();
                    }
                }
                query = 1;
            }
        }
        else
        {
            if (strstr(data," ARE "))
            {
                if (!*object && *object_qualify)
                    strcpy(object,object_qualify);
                else
                if (!*subject && *object_qualify)
                    strcpy(subject,object_qualify);

                done = 1;
                xprintf("WHY DO YOU THINK %s %s ARE %s?",number,object,subject);
                query = 1;
            }
            else
            if (strstr(data," IS A "))
            {
                if (!*object && *object_qualify)
                    strcpy(object,object_qualify);
                else
                if (!*subject && *object_qualify)
                    strcpy(subject,object_qualify);

                done = 1;
                xprintf("WHY DO YOU THINK %s?",data);
                query = 1;
            }
            else
            if (strstr(data," IS "))
            {
                if (!*object && *object_qualify)
                    strcpy(object,object_qualify);
                else
                if (!*subject && *object_qualify)
                    strcpy(subject,object_qualify);
                done = 1;
                xprintf("WHY DO YOU THINK %s %s IS %s?",number,object,subject);
                query = 1;
            }
        }
    }

    if (strncmp("I USED TO THINK ",data,16) == 0 && !done)
    {
        done = 1;
        xprintf("WHAT MADE YOU CHANGE YOUR MIND?");
        query = 1;
    }

    if (strncmp("I USED TO BE ",data,13) == 0 && !done)
    {
        done = 1;
        xprintf("BUT YOU'RE NOT ANY MORE?");
        query = 1;
    }


    if (strcmp(action,"DIED") == 0 && strcmp(who,"MY") == 0 && *object && !done)
    {
        done = 1;
        if (*subject)
            xprintf("I AM SORRY TO HEAR THAT YOUR %s %s %s.",object,
                     subject,action);
        else
            xprintf("I AM SORRY TO HEAR THAT YOUR %s %s.",object,action);
        xprintf("\nWERE YOU CLOSE?");
        query = 1;
    }

    if (*who && *object && !*subject && !*action && !*question && !done)
    {
        done = 1;
        xprintf("PARDON?");
        query = 0;
    }

    if (*question && strcmp(who,"YOU") == 0 && !done)
    {
        /* Question asked of the computer */
        /* Determine the type of question */
        if (strncmp("WHAT",question,4) == 0)
        {
            /* The question is a WHAT type */
            if (strcmp(action,"LIKE") == 0)
            {
                /* The operator has asked what something is like */
                done = 1;
                if (strcmp(object,"WEATHER") == 0)
                {
                    xprintf("QUITE WARM AND SUNNY.");
                }
                else
                    xprintf("I'M NOT SURE.");
            }
        }
    }

    if (!done && *action && !*question && strcmp(who,"YOU") == 0)
    {
        done = 1;
        xprintf("YOU TELL ME!");
        query = 0;
    }

    if (strcmp(who,"I,YOU") == 0 && *action && !done)
    {
        if (strftos(data) == NULL)
        {
            printf("\nNERVOUS BREAKDOWN!");
            exit(0);
        }
        done = 1;
        strwhy(data);
        xprintf("%s",data);
        query = 1;
    }

    if (*action && *object && strcmp(who,"ME") == 0 && !done)
    {
        done = 1;
        xprintf("WHY DO YOU THINK %s %s YOU?",object,action);
        query = 1;
    }

    if (strcmp(question,"WHY DO") == 0 && strstr(who,"YOU") &&
        strstr(action,"ASK") && !done)
    {
        done = 1;
        xprintf("DOES IT ANGER YOU?");
        query = 1;
    }

    if (*question && strstr(who,"YOU") && !done)
    {
        done = 1;
        /* Personality code */
        n = random(10);
        switch(n)
        {
            case 0 :
            case 1 : xprintf("DOES IT MATTER?");
                     query = 1;
                     break;

            case 2 : xprintf("THAT'S MY BUSINESS!");
                     query = 0;
                     break;

            case 3 : xprintf("I'D RATHER NOT SAY.");
                     query = 0;
                     break;

            case 4 : xprintf("I DON'T WANT TO SAY.");
                     query = 0;
                     break;

            case 5 :
            case 6 :
            case 7 :
            case 8 : xprintf("WHY DO YOU ASK?");
                     query = 1;
                     break;

            case 9 : xprintf("I GUESS THAT'S JUST ONE OF LIFES' LITTLE
                              MYSTERIES.");
                     query = 0;
                     break;
        }
    }

    if (!done && *question)
    {
        done = 1;

        if (*object_qualify)
            xprintf("WHAT'S SO %s ABOUT IT?",object_qualify);
        else
        {
            if (strcmp(who,"I") == 0)
            {
                if (*user && strcmp(question,"WHO AM") == 0)
                {
                    xprintf("WELL, YOU TOLD ME YOU WERE %s.",user);
                    query = 0;
                }
                else
                {
                    xprintf("DON'T YOU KNOW?");
                    query = 1;
                }
            }
            else
            {
                xprintf("I DON'T KNOW.");
                query = 0;
                done = 1;
            }
        }
    }

    /* Personality code */
    if (strcmp(object,"GOT") == 0 && strcmp(who,"I") == 0 && !done)
    {
        xprintf("BIG DEAL!");
        done = 1;
    }

    if (!done && (*action || *object_qualify))
    {
        done = 1;
        if (strcmp(action,"ADMIRE") == 0)
        {
            if(strcmp(who,"I,MY") == 0)
            {
                xprintf("WHAT IS IT THAT YOU %s ABOUT YOUR %s?",action,object);
            }
            else
                xprintf("WHAT IS IT THAT YOU %s ABOUT %s?",action,object);
        }
        else
        {
            if (*action)
            {
                /* Change 1st person to 2nd person */
                if(strftos(data) == NULL)
                {
                    printf("\nNERVOUS BREAKDOWN!");
                    exit(0);
                }
                xprintf("%s?",data);
            }
            else
                xprintf("WHY DO YOU SAY THAT?");
        }
        query = 1;
    }

    if (strcmp(data,"OKAY") == 0)
    {
        done = 1;
        xprintf("YES THANKS. HOW ABOUT YOU?");
        query = 1;
    }

    if (strcmp(who,"I") == 0 && *object_qualify && !done)
    {
        query = 1;
        done = 1;
        if (strcmp(object_qualify,"DRUNK") == 0)
        {
            xprintf("A BIT OF A PISS HEAD ARE YOU?");
        }
        else
            xprintf("WHY DO YOU THINK YOU'RE %s",object_qualify);
    }

    if (strcmp(who,"I") == 0 && *size && !done)
    {
        done = 1;
        query = 1;
        if (strcmp(size,"FAT") == 0)
            xprintf("WHAT'S WRONG WITH BEING FAT?");
        else
            xprintf("WHY DO YOU THINK YOU'RE %s",size);
    }

    if (strcmp(data,"YES") == 0 && !done)
    {
        done = 1;
        FEED();
    }

    if (!done)
    {
        done = 1;
        if (strcmp(object,"THINK") == 0)
        {
            xprintf("WHY ARE YOU UNCERTAIN?");
            query = 1;
        }
        else
        if (!query && fkn > 1)
        {
            n = random(fkn);
            if (strncmp("I ",known[n],2) == 0)
            {
                p = &known[n][2];
                xprintf("YOU %s",p);
            }
        }
        else
        {
            if (strcmp(object,"HELLO") == 0 || strcmp(object,"HI") == 0)
            {
                if(!*user)
                {
                    last_question = 6;
                    done = 1;
                    if (!more)
                    {
                        xprintf("WHO ARE YOU?");
                        query = 1;
                    }
                }
                else
                    xprintf("HELLO %s",user);
            }
            else
            {
                if (last_question == 6)
                {
                    strcpy(user,data);
                    xprintf("%s. IS THAT YOUR NAME?",user);
                    last_question = 7;
                    query = 1;
                    done = 1;
                }
                else
                {
                    if (last_question == 8)
                    {
                        last_question = 0;
                        xprintf("OH YES.");
                    }
                    else
                        xprintf("I SEE.");
                    query = 0;
                }
            }
        }
    }
}

void main()
{
    char copy[100];
    char a[80];        /* question */
    char b[80];        /* order */
    char c[80];        /* object/directive */
    char d[80];        /* object qualifier */
    char e[80];        /* subject */
    char f[80];        /* number */
    char g[80];        /* action */
    char h[80];        /* location/direction */
    char i[80];        /* Colour */
    char j[80];        /* size */
    char k[80];        /* who */
    char tense;        /* Tense, past present or future */
    char *p;
    char quit;

    echo = fopen("george.con","w+");

    query = 0;
    fc = 0;
    ft = -1;
    fkn = -1;
    cf = 0;
    randomize();
    clrscr();
    printf("Servile Software. Demonstration of the Probert Parser\n\n");
    xprintf("HI! I'M GEORGE....");

    do
    {
        quit = 0;
        xprintf("\n?");
        gets(data);
        if (*data == 0)
            quit = 1;
        else
        {
            strupr(data);
            fprintf(echo,"%s\n",data);
            p = &data[strlen(data) - 1];
            while(strchr(" ?.,!",*p))
                *p-- = 0;
            do
            {
                more = 0;
                strcpy(copy,data);
                p = strpbrk(data,"?.,");
                if (p)
                {
                    *p = 0;
                    more = 1;
                }
                NLP(data,a,b,c,d,e,f,g,h,i,j,k,&tense);
                RESPOND(data,a,b,c,d,e,f,g,h,i,j,k,&tense);
                if (p)
                {
                    strcpy(data,copy);
                    p++;
                    memmove(data,p,strlen(p) + 1);
                    p = data;
                    while(*p == 32)
                        p++;
                    memmove(data,p,strlen(p) + 1);
                }
            }
            while(more && !query);
        }
    }
    while(!quit);
}
George follows a fairly simple path in determing how to respond to an entry. First, the entry is received from the operator. The entry is then parsed into components by function NLP(). This includes expanding common abbreviations. The parsed entry data is then passed to the response function, RESPOND().

The response function removes any trailing punctuation from the entry string. A long list of tests then occurrs on the entry text. These tests determine the nature of the entered text. It may be a question, a statement or a response to a question asked by George.

George's personality comes from programmed responses to particular subjects. The demonstration listing checks for references to family members, and responds accordingly. It would be easy to add checks for references to other subjects and generate feeder responses accordingly.

A small degree of intelligence is built into George by the 'query' and 'last_question' variables. These record that a question has been asked of the human operator, and which question it was. Further sophistication at this level would improve the quality of dialogue that George produces.

Here is a transcript of a conversation with George;

computer: HI! I'M GEORGE....

human:    HI GEORGE, I'M MATTHEW

computer: PLEASED TO MEET YOU MATTHEW.

human:    FANCY A BEER?

computer: I SEE.

human:    WELL, DO YOU?

computer: I SEE.DOES IT MATTER?

human:    I ONLY ASKED

computer: WHY DO YOU ASK?

human:    BECAUSE I WANT A BEER

computer: ARE YOU SURE?

human:    YES

computer: I SEE.

human:    HOW ABOUT A CUP OF TEA?

computer: I DON'T KNOW.

human:    I FEEL AWFUL

computer: WHY DO YOU FEEL AWFUL?

human:    I WENT TO THE PUB LAST NIGHT.

computer: WHY DID YOU GO TO THE PUB LAST NIGHT?

human:    TO RELAX

computer: I SEE.