AI-MegaHAL

 view release on metacpan or  search on metacpan

lib/AI/MegaHAL.pm  view on Meta::CPAN

Creates a new AI::MegaHAL object.  The object constructor can optionaly receive the following named parameters:

=over 4

=item B<Path> - The path to MegaHALs brain or training file (megahal.brn and megahal.trn respectively).  If 'Path' is not specified the current working directory is assumed.

=item B<Banner> - A flag which enables/disables the banner which is displayed when MegaHAL starts up.  The default is to disable the banner.

=item B<Prompt> - A flag which enables/disables the prompt. This flag is only useful when MegaHAL is run interactively and is disabled by default.

=item B<Wrap> - A flag which enables/disables word wrapping of MegaHALs responses when the lines exceed 80 characters in length.  The default is to disable word wrapping.

=back

=head1 METHODS

=head2 initial_greeting

$text = $megahal->initial_greeting();

Returns a string containing the initial greeting which is created by MegaHAL at startup.

libmegahal.c  view on Meta::CPAN

#define isspace(x) IsSpace(_AmigaLocale,x)
#endif

#ifndef __mac_os
#undef FALSE
#undef TRUE
typedef enum { FALSE, TRUE } bool;
#endif

typedef struct {
    BYTE1 length;
    char *word;
} STRING;

typedef struct {
    BYTE4 size;
    STRING *entry;
    BYTE2 *index;
} DICTIONARY;

typedef struct {

libmegahal.c  view on Meta::CPAN

     *		Search through the word array.  If a command prefix is found,
     *		then try to match the following word with a command word.  If
     *		a match is found, then return a command identifier.  If the
     *		Following word is a number, then change the judge.  Otherwise,
     *		continue the search.
     */
    for(i=0; i<words->size-1; ++i)
	/*
	 *		The command prefix was found.
	 */
	if(words->entry[i].word[words->entry[i].length - 1] == '#') {
	    /*
	     *		Look for a command word.
	     */
	    for(j = 0; j < COMMAND_SIZE; ++j)
		if(wordcmp(command[j].word, words->entry[i + 1]) == 0) {
		    *position = i + 1;
		    return(command[j].command);
		}
	}

libmegahal.c  view on Meta::CPAN


/*
 *		Function:	Read_Input
 *
 *		Purpose:		Read an input string from the user.
 */
char *read_input(char *prompt)
{
    static char *input=NULL;
    bool finish;
    int length;
    int c;

    /*
     *		Perform some initializations.  The finish boolean variable is used
     *		to detect a double line-feed, while length contains the number of
     *		characters in the input string.
     */
    finish=FALSE;
    length=0;
    if(input==NULL) {
	input=(char *)malloc(sizeof(char));
	if(input==NULL) {
	    error("read_input", "Unable to allocate the input string");
	    return(input);
	}
    }

    /*
     *		Display the prompt to the user.

libmegahal.c  view on Meta::CPAN

	    finish=TRUE;
	    c=32;
	} else {
	    finish=FALSE;
	}

	/*
	 *		Re-allocate the input string so that it can hold one more
	 *		character.
	 */
	++length;
	input=(char *)realloc((char *)input,sizeof(char)*(length+1));
	if(input==NULL) {
	    error("read_input", "Unable to re-allocate the input string");
	    return(NULL);
	}

	/*
	 *		Add the character just read to the input string.
	 */
	input[length-1]=(char)c;
	input[length]='\0';
    }

    while(isspace(input[length-1])) --length;
    input[length]='\0';

    /*
     *		We have finished, so return the input string.
     */
    return(input);
}

/*---------------------------------------------------------------------------*/

/*

libmegahal.c  view on Meta::CPAN

					    sizeof(STRING)*(dictionary->size));
    }
    if(dictionary->entry==NULL) {
	error("add_word", "Unable to reallocate the dictionary to %d elements.", dictionary->size);
	goto fail;
    }

    /*
     *		Copy the new word into the word array
     */
    dictionary->entry[dictionary->size-1].length=word.length;
    dictionary->entry[dictionary->size-1].word=(char *)malloc(sizeof(char)*
							      (word.length));
    if(dictionary->entry[dictionary->size-1].word==NULL) {
	error("add_word", "Unable to allocate the word.");
	goto fail;
    }
    for(i=0; i<word.length; ++i)
	dictionary->entry[dictionary->size-1].word[i]=word.word[i];

    /*
     *		Shuffle the word index to keep it sorted alphabetically
     */
    for(i=(dictionary->size-1); i>position; --i)
	dictionary->index[i]=dictionary->index[i-1];

    /*
     *		Copy the new symbol identifier into the word index

libmegahal.c  view on Meta::CPAN

 *
 *		Purpose:		Compare two words, and return an integer indicating whether
 *						the first word is less than, equal to or greater than the
 *						second word.
 */
int wordcmp(STRING word1, STRING word2)
{
    unsigned int i;
    unsigned int bound;

    bound=MIN(word1.length,word2.length);

    for(i=0; i<bound; ++i)
	if(toupper(word1.word[i])!=toupper(word2.word[i]))
	    return((int)(toupper(word1.word[i])-toupper(word2.word[i])));

    if(word1.length<word2.length) return(-1);
    if(word1.length>word2.length) return(1);

    return(0);
}

/*---------------------------------------------------------------------------*/

/*
 *		Function:	Free_Dictionary
 *
 *		Purpose:		Release the memory consumed by the dictionary.

libmegahal.c  view on Meta::CPAN


/*
 *		Function:	Save_Word
 *
 *		Purpose:		Save a dictionary word to a file.
 */
void save_word(FILE *file, STRING word)
{
    unsigned int i;

    fwrite(&(word.length), sizeof(BYTE1), 1, file);
    for(i=0; i<word.length; ++i)
	fwrite(&(word.word[i]), sizeof(char), 1, file);
}

/*---------------------------------------------------------------------------*/

/*
 *		Function:	Load_Word
 *
 *		Purpose:		Load a dictionary word from a file.
 */
void load_word(FILE *file, DICTIONARY *dictionary)
{
    unsigned int i;
    STRING word;

    fread(&(word.length), sizeof(BYTE1), 1, file);
    word.word=(char *)malloc(sizeof(char)*word.length);
    if(word.word==NULL) {
	error("load_word", "Unable to allocate word");
	return;
    }
    for(i=0; i<word.length; ++i)
	fread(&(word.word[i]), sizeof(char), 1, file);
    add_word(dictionary, word);
    free(word.word);
}

/*---------------------------------------------------------------------------*/

/*
 *		Function:	New_Node
 *

libmegahal.c  view on Meta::CPAN

/*
 *		Function:	Train
 *
 *		Purpose:	 	Infer a MegaHAL brain from the contents of a text file.
 */
void train(MODEL *model, char *filename)
{
    FILE *file;
    char buffer[1024];
    DICTIONARY *words=NULL;
    int length;

    if(filename==NULL) return;

    file=fopen(filename, "r");
    if(file==NULL) {
	printf("Unable to find the personality %s\n", filename);
	return;
    }

    fseek(file, 0, 2);
    length=ftell(file);
    rewind(file);

    words=new_dictionary();

    progress("Training from file", 0, 1);
    while(!feof(file)) {

	if(fgets(buffer, 1024, file)==NULL) break;
	if(buffer[0]=='#') continue;

	buffer[strlen(buffer)-1]='\0';

	upper(buffer);
	make_words(buffer, words);
	learn(model, words);

	progress(NULL, ftell(file), length);

    }
    progress(NULL, 1, 1);

    free_dictionary(words);
    fclose(file);
}

/*---------------------------------------------------------------------------*/

libmegahal.c  view on Meta::CPAN

    register int j;
    FILE *file;

    file=fopen("megahal.dic", "w");
    if(file==NULL) {
	warn("show_dictionary", "Unable to open file");
	return;
    }

    for(i=0; i<dictionary->size; ++i) {
	for(j=0; j<dictionary->entry[i].length; ++j)
	    fprintf(file, "%c", dictionary->entry[i].word[j]);
	fprintf(file, "\n");
    }

    fclose(file);
}

/*---------------------------------------------------------------------------*/

/*

libmegahal.c  view on Meta::CPAN

	    if(words->entry==NULL)
		words->entry=(STRING *)malloc((words->size+1)*sizeof(STRING));
	    else
		words->entry=(STRING *)realloc(words->entry, (words->size+1)*sizeof(STRING));

	    if(words->entry==NULL) {
		error("make_words", "Unable to reallocate dictionary");
		return;
	    }

	    words->entry[words->size].length=offset;
	    words->entry[words->size].word=input;
	    words->size+=1;

	    if(offset==(int)strlen(input)) break;
	    input+=offset;
	    offset=0;
	} else {
	    ++offset;
	}
    }

libmegahal.c  view on Meta::CPAN

    if(isalnum(words->entry[words->size-1].word[0])) {
	if(words->entry==NULL)
	    words->entry=(STRING *)malloc((words->size+1)*sizeof(STRING));
	else
	    words->entry=(STRING *)realloc(words->entry, (words->size+1)*sizeof(STRING));
	if(words->entry==NULL) {
	    error("make_words", "Unable to reallocate dictionary");
	    return;
	}

	words->entry[words->size].length=1;
	words->entry[words->size].word=".";
	++words->size;
    }
    else if(strchr("!.?", words->entry[words->size-1].word[words->entry[words->size-1].length-1])==NULL) {
	words->entry[words->size-1].length=1;
	words->entry[words->size-1].word=".";
    }

    return;
}

/*---------------------------------------------------------------------------*/
/*
 *		Function:	Boundary
 *

libmegahal.c  view on Meta::CPAN

	 */
	if(replies->entry==NULL)
	    replies->entry=(STRING *)malloc((replies->size+1)*sizeof(STRING));
	else
	    replies->entry=(STRING *)realloc(replies->entry, (replies->size+1)*sizeof(STRING));
	if(replies->entry==NULL) {
	    error("reply", "Unable to reallocate dictionary");
	    return(NULL);
	}

	replies->entry[replies->size].length=
	    model->dictionary->entry[symbol].length;
	replies->entry[replies->size].word=
	    model->dictionary->entry[symbol].word;
	replies->size+=1;

	/*
	 *		Extend the current context of the model with the current symbol.
	 */
	update_context(model, symbol);
    }

libmegahal.c  view on Meta::CPAN

	    replies->entry=(STRING *)realloc(replies->entry, (replies->size+1)*sizeof(STRING));
	if(replies->entry==NULL) {
	    error("reply", "Unable to reallocate dictionary");
	    return(NULL);
	}

	/*
	 *		Shuffle everything up for the prepend.
	 */
	for(i=replies->size; i>0; --i) {
	    replies->entry[i].length=replies->entry[i-1].length;
	    replies->entry[i].word=replies->entry[i-1].word;
	}

	replies->entry[0].length=model->dictionary->entry[symbol].length;
	replies->entry[0].word=model->dictionary->entry[symbol].word;
	replies->size+=1;

	/*
	 *		Extend the current context of the model with the current symbol.
	 */
	update_context(model, symbol);
    }

    return(replies);

libmegahal.c  view on Meta::CPAN

/*
 *		Function:	Make_Output
 *
 *		Purpose:		Generate a string from the dictionary of reply words.
 */
char *make_output(DICTIONARY *words)
{
    static char *output=NULL;
    register int i;
    register int j;
    int length;
    static char *output_none=NULL;

    if(output_none==NULL) output_none=malloc(40);

    if(output==NULL) {
	output=(char *)malloc(sizeof(char));
	if(output==NULL) {
	    error("make_output", "Unable to allocate output");
	    return(output_none);
	}
    }

    if(words->size==0) {
	if(output_none!=NULL)
	    strcpy(output_none, "I am utterly speechless!");
	return(output_none);
    }

    length=1;
    for(i=0; i<words->size; ++i) length+=words->entry[i].length;

    output=(char *)realloc(output, sizeof(char)*length);
    if(output==NULL) {
	error("make_output", "Unable to reallocate output.");
	if(output_none!=NULL)
	    strcpy(output_none, "I forgot what I was going to say!");
	return(output_none);
    }

    length=0;
    for(i=0; i<words->size; ++i)
	for(j=0; j<words->entry[i].length; ++j)
	    output[length++]=words->entry[i].word[j];

    output[length]='\0';

    return(output);
}

/*---------------------------------------------------------------------------*/

/*
 *		Function:	Babble
 *
 *		Purpose:		Return a random symbol from the current context, or a

libmegahal.c  view on Meta::CPAN

	error("add_swap", "Unable to reallocate from");
	return;
    }

    list->to=(STRING *)realloc(list->to, sizeof(STRING)*(list->size));
    if(list->to==NULL) {
	error("add_swap", "Unable to reallocate to");
	return;
    }

    list->from[list->size-1].length=strlen(s);
    list->from[list->size-1].word=strdup(s);
    list->to[list->size-1].length=strlen(d);
    list->to[list->size-1].word=strdup(d);
}

/*---------------------------------------------------------------------------*/

/*
 *		Function:	Initialize_Swap
 *
 *		Purpose:		Read a swap structure from a file.
 */

libmegahal.c  view on Meta::CPAN

    file=fopen(filename, "r");
    if(file==NULL) return(list);

    while(!feof(file)) {

	if(fgets(buffer, 1024, file)==NULL) break;
	if(buffer[0]=='#') continue;
	string=strtok(buffer, "\t \n#");

	if((string!=NULL)&&(strlen(string)>0)) {
	    word.length=strlen(string);
	    word.word=strdup(buffer);
	    add_word(list, word);
	}
    }

    fclose(file);
    return(list);
}

/*---------------------------------------------------------------------------*/

libmegahal.c  view on Meta::CPAN

    }

    if(last == NULL) {
	last = strdup(directory);
    }

    if((command == NULL)||((position+2)>=command->size)) {
	/* no dir set, so we leave it to whatever was set above */
    } else {
        directory=(char *)realloc(directory,
                                  sizeof(char)*(command->entry[position+2].length+1));
        if(directory == NULL)
            error("change_personality", "Unable to allocate directory");
        strncpy(directory, command->entry[position+2].word,
                command->entry[position+2].length);
        directory[command->entry[position+2].length]='\0';
    }

    load_personality(model);
}

/*---------------------------------------------------------------------------*/

void free_words(DICTIONARY *words)
{
    unsigned int i;

megahal.trn  view on Meta::CPAN

A chromosome is a chemical found in all cells which determines how the cell will act.
The cranium is the skeleton enclosing the brain.
The dingo is wild dog found in Australia.
The dinosaurs were a family of reptiles which lived on the earth millions of years ago.
A dog is a domesticated mammal descended from the wolf.
Donkey is another name for ass.
Ecology is a study of the relationship between an organism and its environment.
The emu is a large, ostrich-like flightless bird found in Australia.
Eucalyptus is a tree native to Australia where it is called the gum tree.
Excretion is the process of getting rid of unwanted substances from within the body.
Genes are hereditary information material arranged in a single row along the length of each chromosome.
Gum tree is another name for Eucalyptus.
A herbivore is an animal that eats plants.
The kangaroo is a marsupial mammal found in Australia.
The kiwi is a group of three species of bird only found in New Zealand.
The koala is a marsupial found only in east Australia.
Locomotion is the idea of movement from one place to another.
Milk is a secretion of modified skin glands of female mammals.
A monkey is a small, usually tree dwelling, primate.
The mule is a hybrid animal, the result of an ass and a mare breeding.
A neurone is a cell which receives and transmits electrical impulses.



( run in 0.908 second using v1.01-cache-2.11-cpan-65fba6d93b7 )