⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 megahal.c

📁 megahal is the conversation simulators conversing with a user in natural language. The program will
💻 C
📖 第 1 页 / 共 5 页
字号:
/*===========================================================================*//* *  Copyright (C) 1998 Jason Hutchens * *  This program is free software; you can redistribute it and/or modify it *  under the terms of the GNU General Public License as published by the Free *  Software Foundation; either version 2 of the license or (at your option) *  any later version. * *  This program is distributed in the hope that it will be useful, but *  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *  or FITNESS FOR A PARTICULAR PURPOSE.  See the Gnu Public License for more *  details. * *  You should have received a copy of the GNU General Public License along *  with this program; if not, write to the Free Software Foundation, Inc., *  675 Mass Ave, Cambridge, MA 02139, USA. *//*===========================================================================*//* *		$Id: megahal.c,v 1.2 2004/02/25 20:19:40 lfousse Exp $ * *		File:			megahal.c * *		Program:		MegaHAL * *		Purpose:		To simulate a natural language conversation with a psychotic *						computer.  This is achieved by learning from the user's *						input using a third-order Markov model on the word level. *						Words are considered to be sequences of characters separated *						by whitespace and punctuation.  Replies are generated *						randomly based on a keyword, and they are scored using *						measures of surprise. * *		Author:		Mr. Jason L. Hutchens (http://www.amristar.com.au/~hutch/) * *		WWW:		http://megahal.sourceforge.net * *		Compilation Notes *		================= * *		When compiling, be sure to link with the maths library so that the *		log() function can be found. * *		On the Macintosh, add the library SpeechLib to your project.  It is *		very important that you set the attributes to Import Weak.  You can *		do this by selecting the lib and then use Project Inspector from the *		Window menu. * *		CREDITS *		======= * *		Amiga (AmigaOS) *		--------------- *		Dag Agren (dagren@ra.abo.fi) * *		DEC (OSF) *		--------- *		Jason Hutchens (hutch@ciips.ee.uwa.edu.au) * *		Macintosh *		--------- *		Paul Baxter (pbaxter@assistivetech.com) *		Doug Turner (dturner@best.com) * *		PC (Linux) *		---------- *		Jason Hutchens (hutch@ciips.ee.uwa.edu.au) * *		PC (OS/2) *		--------- *		Bjorn Karlowsky (?) * *		PC (Windows 3.11) *		----------------- *		Jim Crawford (pfister_@hotmail.com) * *		PC (Windows '95) *		---------------- *		Jason Hutchens (hutch@ciips.ee.uwa.edu.au) * *		PPC (Linux) *		----------- *		Lucas Vergnettes (Lucasv@sdf.lonestar.org) * *		SGI (Irix) *		---------- *		Jason Hutchens (hutch@ciips.ee.uwa.edu.au) * *		Sun (SunOS) *		----------- *		Jason Hutchens (hutch@ciips.ee.uwa.edu.au) *//*===========================================================================*/#include <stdio.h>#include <stdlib.h>#include <stdarg.h>#include <unistd.h>#include <getopt.h>#if !defined(AMIGA) && !defined(__mac_os)#include <malloc.h>#endif#include <string.h>#include <signal.h>#include <math.h>#include <time.h>#include <ctype.h>#if defined(__mac_os)#include <types.h>#include <Speech.h>#else#include <sys/types.h>#endif#include "megahal.h"#if defined(DEBUG)#include "debug.h"#endif#define P_THINK 40#define D_KEY 100000#define V_KEY 50000#define D_THINK 500000#define V_THINK 250000#define MIN(a,b) ((a)<(b))?(a):(b)#define COOKIE "MegaHALv8"#define TIMEOUT 1#define DEFAULT "."#define COMMAND_SIZE (sizeof(command)/sizeof(command[0]))#define BYTE1 unsigned char#define BYTE2 unsigned short#define BYTE4 unsigned long#ifdef __mac_os#define bool Boolean#endif#ifdef DOS#define SEP "\\"#else#define SEP "/"#endif#ifdef AMIGA#undef toupper#define toupper(x) ToUpper(x)#undef tolower#define tolower(x) ToLower(x)#undef isalpha#define isalpha(x) IsAlpha(_AmigaLocale,x)#undef isalnum#define isalnum(x) IsAlNum(_AmigaLocale,x)#undef isdigit#define isdigit(x) IsDigit(_AmigaLocale,x)#undef isspace#define isspace(x) IsSpace(_AmigaLocale,x)#endif#ifndef __mac_os#undef FALSE#undef TRUEtypedef enum { FALSE, TRUE } bool;#endiftypedef struct {    BYTE1 length;    char *word;} STRING;typedef struct {    BYTE4 size;    STRING *entry;    BYTE2 *index;} DICTIONARY;typedef struct {    BYTE2 size;    STRING *from;    STRING *to;} SWAP;typedef struct NODE {    BYTE2 symbol;    BYTE4 usage;    BYTE2 count;    BYTE2 branch;    struct NODE **tree;} TREE;typedef struct {    BYTE1 order;    TREE *forward;    TREE *backward;    TREE **context;    DICTIONARY *dictionary;} MODEL;typedef enum { UNKNOWN, QUIT, EXIT, SAVE, DELAY, HELP, SPEECH, VOICELIST, VOICE, BRAIN, QUIET} COMMAND_WORDS;typedef struct {    STRING word;    char *helpstring;    COMMAND_WORDS command;} COMMAND;/*===========================================================================*/static int width=75;static int order=5;static bool typing_delay=FALSE;static bool noprompt=FALSE;static bool speech=FALSE;static bool quiet=FALSE;static bool nowrap=FALSE;static bool nobanner=FALSE;static char *errorfilename = "megahal.log";static char *statusfilename = "megahal.txt";static DICTIONARY *words=NULL;static DICTIONARY *greets=NULL;static MODEL *model=NULL;static FILE *errorfp;static FILE *statusfp;static DICTIONARY *ban=NULL;static DICTIONARY *aux=NULL;/*static DICTIONARY *fin=NULL; not used */static DICTIONARY *grt=NULL;static SWAP *swp=NULL;static bool used_key;static char *directory=NULL;static char *last=NULL;static COMMAND command[] = {    { { 4, "QUIT" }, "quits the program and saves MegaHAL's brain", QUIT },    { { 4, "EXIT" }, "exits the program *without* saving MegaHAL's brain", EXIT },    { { 4, "SAVE" }, "saves the current MegaHAL brain", SAVE },    { { 5, "DELAY" }, "toggles MegaHAL's typing delay (off by default)", DELAY },    { { 6, "SPEECH" }, "toggles MegaHAL's speech (off by default)", SPEECH },    { { 6, "VOICES" }, "list available voices for speech", VOICELIST },    { { 5, "VOICE" }, "switches to voice specified", VOICE },    { { 5, "BRAIN" }, "change to another MegaHAL personality", BRAIN },    { { 4, "HELP" }, "displays this message", HELP },    { { 5, "QUIET" }, "toggles MegaHAL's responses (on by default)",QUIET},    /*      { { 5, "STATS" }, "Display stats", STATS},      { { 5, "STATS-SESSION" }, "Display stats for this session only",STATS_SESSION},      { { 5, "STATS-ALL" },"Display stats for the whole lifetime",STATS-ALL},    */};#ifdef AMIGAstruct Locale *_AmigaLocale;#endif#ifdef __mac_osBoolean gSpeechExists = false;SpeechChannel gSpeechChannel = nil;#endif/* FIXME - these need to be static  */static void add_aux(MODEL *, DICTIONARY *, STRING);static void add_key(MODEL *, DICTIONARY *, STRING);static void add_node(TREE *, TREE *, int);static void add_swap(SWAP *, char *, char *);static TREE *add_symbol(TREE *, BYTE2);static BYTE2 add_word(DICTIONARY *, STRING);static int babble(MODEL *, DICTIONARY *, DICTIONARY *);static bool boundary(char *, int);static void capitalize(char *);static void changevoice(DICTIONARY *, int);static void change_personality(DICTIONARY *, unsigned int, MODEL **);static void delay(char *);static void die(int);static bool dissimilar(DICTIONARY *, DICTIONARY *);static void error(char *, char *, ...);static float evaluate_reply(MODEL *, DICTIONARY *, DICTIONARY *);static COMMAND_WORDS execute_command(DICTIONARY *, int *);static void exithal(void);static TREE *find_symbol(TREE *, int);static TREE *find_symbol_add(TREE *, int);static BYTE2 find_word(DICTIONARY *, STRING);static char *generate_reply(MODEL *, DICTIONARY *);static void help(void);static void ignore(int);static bool initialize_error(char *);#ifdef __mac_osstatic bool initialize_speech(void);#endifstatic bool initialize_status(char *);static void learn(MODEL *, DICTIONARY *);static void listvoices(void);static void make_greeting(DICTIONARY *);static void make_words(char *, DICTIONARY *);static DICTIONARY *new_dictionary(void);static char *read_input(char *);static void save_model(char *, MODEL *);#ifdef __mac_osstatic char *strdup(const char *);#endifstatic void upper(char *);static void write_input(char *);static void write_output(char *);#if defined(DOS) || defined(__mac_os)static void usleep(int);#endifstatic char *format_output(char *);static void free_dictionary(DICTIONARY *);static void free_model(MODEL *);static void free_tree(TREE *);static void free_word(STRING);static void free_words(DICTIONARY *);static void initialize_context(MODEL *);static void initialize_dictionary(DICTIONARY *);static DICTIONARY *initialize_list(char *);static SWAP *initialize_swap(char *);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 *);static bool status(char *, ...);static void train(MODEL *, char *);static void typein(char);static void update_context(MODEL *, int);static void update_model(MODEL *, int);static bool warn(char *, char *, ...);static int wordcmp(STRING, STRING);static bool word_exists(DICTIONARY *, STRING);static int rnd(int);/* Function: setnoprompt   Purpose: Set noprompt variable. */void megahal_setnoprompt(void){    noprompt = TRUE;}void megahal_setnowrap (void){    nowrap = TRUE;}void megahal_setnobanner (void){    nobanner = TRUE;}void megahal_seterrorfile(char *filename){    errorfilename = filename;}void megahal_setstatusfile(char *filename){    statusfilename = filename;}void megahal_setdirectory (char *dir){    directory = dir;}/*   megahal_initialize --   Initialize various brains and files.   Results:   None.*/void megahal_initialize(void){    errorfp = stderr;    statusfp = stdout;    initialize_error(errorfilename);    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"		"+------------------------------------------------------------------------+\n"		);    words = new_dictionary();    greets = new_dictionary();    change_personality(NULL, 0, &model);}/*   megahal_do_reply --   Take string as input, and return allocated string as output.  The   user is responsible for freeing this memory.  */char *megahal_do_reply(char *input, int log){    char *output = NULL;    if (log != 0)	write_input(input);  /* log input if so desired */    upper(input);    make_words(input, words);    learn(model, words);    output = generate_reply(model, words);    capitalize(output);    return output;}/*   megahal_learn_no_reply --   Take string as input, update model but don't generate reply.  */void megahal_learn_no_reply(char *input, int log){    if (log != 0)	write_input(input);  /* log input if so desired */    upper(input);    make_words(input, words);    learn(model, words);}/*   megahal_initial_greeting --   This function returns an initial greeting.  It can be used to start   Megahal conversations, but it isn't necessary.  */char *megahal_initial_greeting(void){    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);}/*   megahal_input --   Get a string from stdin, using a prompt.  */char *megahal_input(char *prompt){    if (noprompt)	return read_input("");    else	return read_input(prompt);}/*   megahal_command --   Check to see if input is a megahal command, and if so, act upon it.   Returns 1 if it is a command, 0 if it is not.  */int megahal_command(char *input){    int position = 0;    char *output;    make_words(input,words);    switch(execute_command(words, &position)) {    case EXIT:	exithal();	break;    case QUIT:	save_model("megahal.brn", model);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -