view release on metacpan or search on metacpan
libmegahal.c view on Meta::CPAN
static void load_dictionary(FILE *, DICTIONARY *);
static bool load_model(char *, MODEL *);
static void load_personality(MODEL **);
static void load_tree(FILE *, TREE *);
static void load_word(FILE *, DICTIONARY *);
static DICTIONARY *make_keywords(MODEL *, DICTIONARY *);
static char *make_output(DICTIONARY *);
static MODEL *new_model(int);
static TREE *new_node(void);
static SWAP *new_swap(void);
static bool print_header(FILE *);
static bool progress(char *, int, int);
static DICTIONARY *reply(MODEL *, DICTIONARY *);
static void save_dictionary(FILE *, DICTIONARY *);
static void save_tree(FILE *, TREE *);
static void save_word(FILE *, STRING);
static int search_dictionary(DICTIONARY *, STRING, bool *);
static int search_node(TREE *, int, bool *);
static int seed(MODEL *, DICTIONARY *);
static void show_dictionary(DICTIONARY *);
static void speak(char *);
libmegahal.c view on Meta::CPAN
// initialize_status(statusfilename);
ignore(0);
#ifdef AMIGA
_AmigaLocale=OpenLocale(NULL);
#endif
#ifdef __mac_os
gSpeechExists = initialize_speech();
#endif
if(!nobanner)
fprintf(stdout,
"+------------------------------------------------------------------------+\n"
"| |\n"
"| # # ###### #### ## # # ## # |\n"
"| ## ## # # # # # # # # # # ### |\n"
"| # ## # ##### # # # ###### # # # # # |\n"
"| # # # # ### ###### # # ###### # # # ### |\n"
"| # # # # # # # # # # # # # # # # |\n"
"| # # ###### #### # # # # # # ###### # ###r6 |\n"
"| |\n"
"| Copyright(C) 1998 Jason Hutchens |\n"
libmegahal.c view on Meta::CPAN
char *output;
make_greeting(greets);
output = generate_reply(model, greets);
return output;
}
/*
megahal_output --
This function pretty prints output.
Wrapper function to have things in the right namespace.
*/
void megahal_output(char *output)
{
if(!quiet)
write_output(output);
}
libmegahal.c view on Meta::CPAN
break;
case QUIT:
save_model("megahal.brn", model);
exithal();
break;
case SAVE:
save_model("megahal.brn", model);
break;
case DELAY:
typing_delay=!typing_delay;
printf("MegaHAL typing is now %s.\n", typing_delay?"on":"off");
return 1;
case SPEECH:
speech=!speech;
printf("MegaHAL speech is now %s.\n", speech?"on":"off");
return 1;
case HELP:
help();
return 1;
case VOICELIST:
listvoices();
return 1;
case VOICE:
changevoice(words, position);
return 1;
libmegahal.c view on Meta::CPAN
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.
*/
fprintf(stdout, prompt);
fflush(stdout);
/*
* Loop forever, reading characters and putting them into the input
* string.
*/
while(TRUE) {
/*
* Read a single character from stdin.
libmegahal.c view on Meta::CPAN
/*
* If the character is a line-feed, then set the finish variable
* to TRUE. If it already is TRUE, then this is a double line-feed,
* in which case we should exit. After a line-feed, display the
* prompt again, and set the character to the space character, as
* we don't permit linefeeds to appear in the input.
*/
if((char)(c)=='\n') {
if(finish==TRUE) break;
fprintf(stdout, prompt);
fflush(stdout);
finish=TRUE;
c=32;
} else {
finish=FALSE;
}
/*
* Re-allocate the input string so that it can hold one more
* character.
libmegahal.c view on Meta::CPAN
{
if(errorfp!=stderr) fclose(errorfp);
if(filename==NULL) return(TRUE);
errorfp = fopen(filename, "a");
if(errorfp==NULL) {
errorfp=stderr;
return(FALSE);
}
return(print_header(errorfp));
}
/*---------------------------------------------------------------------------*/
/*
* Function: Error
*
* Purpose: Print the specified message to the error file.
*/
void error(char *title, char *fmt, ...)
{
va_list argp;
fprintf(errorfp, "%s: ", title);
va_start(argp, fmt);
vfprintf(errorfp, fmt, argp);
va_end(argp);
fprintf(errorfp, ".\n");
fflush(errorfp);
// fprintf(stderr, "MegaHAL died for some reason; check the error log.\n");
exit(1);
}
/*---------------------------------------------------------------------------*/
bool warn(char *title, char *fmt, ...)
{
va_list argp;
fprintf(errorfp, "%s: ", title);
va_start(argp, fmt);
vfprintf(errorfp, fmt, argp);
va_end(argp);
fprintf(errorfp, ".\n");
fflush(errorfp);
// fprintf(stderr, "MegaHAL emitted a warning; check the error log.\n");
return(TRUE);
}
/*---------------------------------------------------------------------------*/
/*
* Function: Initialize_Status
*
* Purpose: Close the current status file pointer, and open a new one.
*/
bool initialize_status(char *filename)
{
if(statusfp!=stdout) fclose(statusfp);
if(filename==NULL) return(FALSE);
statusfp=fopen(filename, "a");
if(statusfp==NULL) {
statusfp=stdout;
return(FALSE);
}
return(print_header(statusfp));
}
/*---------------------------------------------------------------------------*/
/*
* Function: Status
*
* Purpose: Print the specified message to the status file.
*/
bool status(char *fmt, ...)
{
va_list argp;
va_start(argp, fmt);
vfprintf(statusfp, fmt, argp);
va_end(argp);
fflush(statusfp);
return(TRUE);
}
/*---------------------------------------------------------------------------*/
/*
* Function: Print_Header
*
* Purpose: Display a copyright message and timestamp.
*/
bool print_header(FILE *file)
{
time_t clock;
char timestamp[1024];
struct tm *local;
clock=time(NULL);
local=localtime(&clock);
strftime(timestamp, 1024, "Start at: [%Y/%m/%d %H:%M:%S]\n", local);
fprintf(file, "MegaHALv8\n");
fprintf(file, "Copyright (C) 1998 Jason Hutchens\n");
fprintf(file, timestamp);
fflush(file);
return(TRUE);
}
/*---------------------------------------------------------------------------*/
/*
* Function: Write_Output
*
libmegahal.c view on Meta::CPAN
{
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);
libmegahal.c view on Meta::CPAN
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);
}
/*---------------------------------------------------------------------------*/
/*
* Function: Save_Model
*
libmegahal.c view on Meta::CPAN
/*
* Allocate memory for the filename
*/
filename=(char *)realloc(filename,
sizeof(char)*(strlen(directory)+strlen(SEP)+12));
if(filename==NULL) error("save_model","Unable to allocate filename");
show_dictionary(model->dictionary);
if(filename==NULL) return;
sprintf(filename, "%s%smegahal.brn", directory, SEP);
file=fopen(filename, "wb");
if(file==NULL) {
warn("save_model", "Unable to open file `%s'", filename);
return;
}
fwrite(COOKIE, sizeof(char), strlen(COOKIE), file);
fwrite(&(model->order), sizeof(BYTE1), 1, file);
save_tree(file, model->forward);
save_tree(file, model->backward);
libmegahal.c view on Meta::CPAN
* Purpose: Display the string to stdout as if it was typed by a human.
*/
void delay(char *string)
{
register int i;
/*
* Don't simulate typing if the feature is turned off
*/
if(typing_delay==FALSE) {
fprintf(stdout, string);
return;
}
/*
* Display the entire string, one character at a time
*/
for(i=0; i<(int)strlen(string)-1; ++i) typein(string[i]);
usleep((D_THINK+rnd(V_THINK)-rnd(V_THINK))/2);
typein(string[i]);
}
libmegahal.c view on Meta::CPAN
* Function: Typein
*
* Purpose: Display a character to stdout as if it was typed by a human.
*/
void typein(char c)
{
/*
* Standard keyboard delay
*/
usleep(D_KEY+rnd(V_KEY)-rnd(V_KEY));
fprintf(stdout, "%c", c);
fflush(stdout);
/*
* A random thinking delay
*/
if((!isalnum(c))&&((rnd(100))<P_THINK))
usleep(D_THINK+rnd(V_THINK)-rnd(V_THINK));
}
/*---------------------------------------------------------------------------*/
libmegahal.c view on Meta::CPAN
// compare ignoring case
if (EqualString((StringPtr)buffer, info.name, false, false)) {
if (gSpeechChannel) {
StopSpeech(gSpeechChannel);
DisposeSpeechChannel(gSpeechChannel);
gSpeechChannel = nil;
}
err = NewSpeechChannel(&voiceSpec, &gSpeechChannel);
if (!err) {
p2cstr((StringPtr)buffer);
printf("Now using %s voice\n", buffer);
c2pstr(buffer);
err = SpeakText(gSpeechChannel, &buffer[1], buffer[0]);
}
}
}
}
}
#endif
}
libmegahal.c view on Meta::CPAN
if (err) continue;
err = GetVoiceDescription(&voiceSpec, &info,
sizeof(VoiceDescription));
if (err) continue;
p2cstr(info.name);
for (temp= info.name; *temp; temp++)
if (*temp == ' ')
*temp = '_';
printf("%s\n",info.name);
}
}
}
#endif
}
/*---------------------------------------------------------------------------*/
/*
* Function: Speak
libmegahal.c view on Meta::CPAN
* Function: Progress
*
* Purpose: Display a progress indicator as a percentage.
*/
bool progress(char *message, int done, int total)
{
static int last=0;
static bool first=FALSE;
/*
* We have already hit 100%, and a newline has been printed, so nothing
* needs to be done.
*/
if((done*100/total==100)&&(first==FALSE)) return(TRUE);
/*
* Nothing has changed since the last time this function was called,
* so do nothing, unless it's the first time!
*/
if(done*100/total==last) {
if((done==0)&&(first==FALSE)) {
// fprintf(stderr, "%s: %3d%%", message, done*100/total);
first=TRUE;
}
return(TRUE);
}
/*
* Erase what we printed last time, and print the new percentage.
*/
last=done*100/total;
//if(done>0) fprintf(stderr, "%c%c%c%c", 8, 8, 8, 8);
//fprintf(stderr, "%3d%%", done*100/total);
/*
* We have hit 100%, so reset static variables and print a newline.
*/
if(last==100) {
first=FALSE;
last=0;
//fprintf(stderr, "\n");
}
return(TRUE);
}
/*---------------------------------------------------------------------------*/
void help(void)
{
int j;
for(j=0; j<COMMAND_SIZE; ++j) {
printf("#%-7s: %s\n", command[j].word.word, command[j].helpstring);
}
}
/*---------------------------------------------------------------------------*/
void load_personality(MODEL **model)
{
FILE *file;
static char *filename=NULL;
libmegahal.c view on Meta::CPAN
*/
filename=(char *)realloc(filename,
sizeof(char)*(strlen(directory)+strlen(SEP)+12));
if(filename==NULL) error("load_personality","Unable to allocate filename");
/*
* Check to see if the brain exists
*/
if(strcmp(directory, DEFAULT)!=0) {
sprintf(filename, "%s%smegahal.brn", directory, SEP);
file=fopen(filename, "r");
if(file==NULL) {
sprintf(filename, "%s%smegahal.trn", directory, SEP);
file=fopen(filename, "r");
if(file==NULL) {
fprintf(stdout, "Unable to change MegaHAL personality to \"%s\".\n"
"Reverting to MegaHAL personality \"%s\".\n", directory, last);
free(directory);
directory=strdup(last);
return;
}
}
fclose(file);
fprintf(stdout, "Changing to MegaHAL personality \"%s\".\n", directory);
}
/*
* Free the current personality
*/
free_model(*model);
free_words(ban);
free_dictionary(ban);
free_words(aux);
free_dictionary(aux);
libmegahal.c view on Meta::CPAN
/*
* Create a language model.
*/
*model=new_model(order);
/*
* Train the model on a text if one exists
*/
sprintf(filename, "%s%smegahal.brn", directory, SEP);
if(load_model(filename, *model)==FALSE) {
sprintf(filename, "%s%smegahal.trn", directory, SEP);
train(*model, filename);
}
/*
* Read a dictionary containing banned keywords, auxiliary keywords,
* greeting keywords and swap keywords
*/
sprintf(filename, "%s%smegahal.ban", directory, SEP);
ban=initialize_list(filename);
sprintf(filename, "%s%smegahal.aux", directory, SEP);
aux=initialize_list(filename);
sprintf(filename, "%s%smegahal.grt", directory, SEP);
grt=initialize_list(filename);
sprintf(filename, "%s%smegahal.swp", directory, SEP);
swp=initialize_swap(filename);
}
/*---------------------------------------------------------------------------*/
void change_personality(DICTIONARY *command, int position, MODEL **model)
{
if(directory == NULL) {
directory = (char *)malloc(sizeof(char)*(strlen(DEFAULT)+1));
# Before `make install' is performed this script should be runnable with
# `make test'. After `make install' it should work as `perl test.pl'
#########################
# change 'tests => 1' to 'tests => last_test_to_print';
use Test;
BEGIN { plan tests => 6 };
use AI::MegaHAL;
ok(1); # If we made it this far, we're ok.
#########################
# Insert your test code below, the Test module is use()ed here so read
# its man page ( perldoc Test ) for help writing this test script.
print("Creating new AI::MegaHAL\n");
my $megahal = AI::MegaHAL->new(AutoSave => 1);
ok(ref($megahal) ne "", 1);
print("#Testing AI::MegaHAL->do_reply method\n");
my $query = "#We are the knights who say NI!";
print("# * Sending: $query\n");
my $reply = $megahal->do_reply($query);
print("# * Replied: $reply\n");
ok($reply ne "", 1);
print("#Destroying MegaHAL - should autosave brain and dictionary files\n");
$megahal = undef;
ok(1);
print("#Checking for brain file: megahal.brn\n");
ok(-f 'megahal.brn', 1);
print("#Checking for dictionary file: megahal.dic\n");
ok(-f 'megahal.dic', 1);