AI-MegaHAL
view release on metacpan or search on metacpan
libmegahal.c view on Meta::CPAN
initialize_dictionary(model->dictionary);
return(model);
fail:
return(NULL);
}
/*---------------------------------------------------------------------------*/
/*
* Function: Update_Model
*
* Purpose: Update the model with the specified symbol.
*/
void update_model(MODEL *model, int symbol)
{
unsigned int i;
/*
* Update all of the models in the current context with the specified
* symbol.
*/
for(i=(model->order+1); i>0; --i)
if(model->context[i-1]!=NULL)
model->context[i]=add_symbol(model->context[i-1], (BYTE2)symbol);
return;
}
/*---------------------------------------------------------------------------*/
/*
* Function: Update_Context
*
* Purpose: Update the context of the model without adding the symbol.
*/
void update_context(MODEL *model, int symbol)
{
unsigned int i;
for(i=(model->order+1); i>0; --i)
if(model->context[i-1]!=NULL)
model->context[i]=find_symbol(model->context[i-1], symbol);
}
/*---------------------------------------------------------------------------*/
/*
* Function: Add_Symbol
*
* Purpose: Update the statistics of the specified tree with the
* specified symbol, which may mean growing the tree if the
* symbol hasn't been seen in this context before.
*/
TREE *add_symbol(TREE *tree, BYTE2 symbol)
{
TREE *node=NULL;
/*
* Search for the symbol in the subtree of the tree node.
*/
node=find_symbol_add(tree, symbol);
/*
* Increment the symbol counts
*/
if((node->count<65535)) {
node->count+=1;
tree->usage+=1;
}
return(node);
}
/*---------------------------------------------------------------------------*/
/*
* Function: Find_Symbol
*
* Purpose: Return a pointer to the child node, if one exists, which
* contains the specified symbol.
*/
TREE *find_symbol(TREE *node, int symbol)
{
register int i;
TREE *found=NULL;
bool found_symbol=FALSE;
/*
* Perform a binary search for the symbol.
*/
i=search_node(node, symbol, &found_symbol);
if(found_symbol==TRUE) found=node->tree[i];
return(found);
}
/*---------------------------------------------------------------------------*/
/*
* Function: Find_Symbol_Add
*
* Purpose: This function is conceptually similar to find_symbol,
* apart from the fact that if the symbol is not found,
* a new node is automatically allocated and added to the
* tree.
*/
TREE *find_symbol_add(TREE *node, int symbol)
{
register int i;
TREE *found=NULL;
bool found_symbol=FALSE;
/*
* Perform a binary search for the symbol. If the symbol isn't found,
* attach a new sub-node to the tree node so that it remains sorted.
*/
i=search_node(node, symbol, &found_symbol);
if(found_symbol==TRUE) {
found=node->tree[i];
} else {
found=new_node();
found->symbol=symbol;
add_node(node, found, i);
}
return(found);
}
/*---------------------------------------------------------------------------*/
/*
* Function: Add_Node
*
* Purpose: Attach a new child node to the sub-tree of the tree
* specified.
*/
void add_node(TREE *tree, TREE *node, int position)
{
register int i;
/*
* Allocate room for one more child node, which may mean allocating
* the sub-tree from scratch.
*/
if(tree->tree==NULL) {
tree->tree=(TREE **)malloc(sizeof(TREE *)*(tree->branch+1));
} else {
tree->tree=(TREE **)realloc((TREE **)(tree->tree),sizeof(TREE *)*
(tree->branch+1));
}
if(tree->tree==NULL) {
error("add_node", "Unable to reallocate subtree.");
return;
}
/*
* Shuffle the nodes down so that we can insert the new node at the
* subtree index given by position.
*/
for(i=tree->branch; i>position; --i)
tree->tree[i]=tree->tree[i-1];
/*
* Add the new node to the sub-tree.
*/
tree->tree[position]=node;
tree->branch+=1;
}
/*---------------------------------------------------------------------------*/
/*
* Function: Search_Node
*
* Purpose: Perform a binary search for the specified symbol on the
* subtree of the given node. Return the position of the
* child node in the subtree if the symbol was found, or the
* position where it should be inserted to keep the subtree
* sorted if it wasn't.
*/
int search_node(TREE *node, int symbol, bool *found_symbol)
{
register int position;
int min;
int max;
int middle;
int compar;
/*
* Handle the special case where the subtree is empty.
*/
if(node->branch==0) {
position=0;
goto notfound;
}
/*
* Perform a binary search on the subtree.
*/
min=0;
max=node->branch-1;
while(TRUE) {
middle=(min+max)/2;
compar=symbol-node->tree[middle]->symbol;
if(compar==0) {
position=middle;
goto found;
} else if(compar>0) {
if(max==middle) {
position=middle+1;
goto notfound;
}
min=middle+1;
} else {
if(min==middle) {
position=middle;
goto notfound;
}
max=middle-1;
}
}
found:
*found_symbol=TRUE;
return(position);
notfound:
*found_symbol=FALSE;
return(position);
}
/*---------------------------------------------------------------------------*/
/*
* Function: Initialize_Context
*
* Purpose: Set the context of the model to a default value.
*/
void initialize_context(MODEL *model)
{
register int i;
for(i=0; i<=model->order; ++i) model->context[i]=NULL;
}
/*---------------------------------------------------------------------------*/
/*
* Function: Learn
*
* Purpose: Learn from the user's input.
*/
void learn(MODEL *model, DICTIONARY *words)
{
register int i;
BYTE2 symbol;
/*
libmegahal.c view on Meta::CPAN
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);
save_dictionary(file, model->dictionary);
fclose(file);
}
/*---------------------------------------------------------------------------*/
/*
* Function: Save_Tree
*
* Purpose: Save a tree structure to the specified file.
*/
void save_tree(FILE *file, TREE *node)
{
static int level=0;
register int i;
fwrite(&(node->symbol), sizeof(BYTE2), 1, file);
fwrite(&(node->usage), sizeof(BYTE4), 1, file);
fwrite(&(node->count), sizeof(BYTE2), 1, file);
fwrite(&(node->branch), sizeof(BYTE2), 1, file);
if(level==0) progress("Saving tree", 0, 1);
for(i=0; i<node->branch; ++i) {
++level;
save_tree(file, node->tree[i]);
--level;
if(level==0) progress(NULL, i, node->branch);
}
if(level==0) progress(NULL, 1, 1);
}
/*---------------------------------------------------------------------------*/
/*
* Function: Load_Tree
*
* Purpose: Load a tree structure from the specified file.
*/
void load_tree(FILE *file, TREE *node)
{
static int level=0;
register int i;
fread(&(node->symbol), sizeof(BYTE2), 1, file);
fread(&(node->usage), sizeof(BYTE4), 1, file);
fread(&(node->count), sizeof(BYTE2), 1, file);
fread(&(node->branch), sizeof(BYTE2), 1, file);
if(node->branch==0) return;
node->tree=(TREE **)malloc(sizeof(TREE *)*(node->branch));
if(node->tree==NULL) {
error("load_tree", "Unable to allocate subtree");
return;
}
if(level==0) progress("Loading tree", 0, 1);
for(i=0; i<node->branch; ++i) {
node->tree[i]=new_node();
++level;
load_tree(file, node->tree[i]);
--level;
if(level==0) progress(NULL, i, node->branch);
}
if(level==0) progress(NULL, 1, 1);
}
/*---------------------------------------------------------------------------*/
/*
* Function: Load_Model
*
* Purpose: Load a model into memory.
*/
bool load_model(char *filename, MODEL *model)
{
FILE *file;
char cookie[16];
if(filename==NULL) return(FALSE);
file=fopen(filename, "rb");
if(file==NULL) {
warn("load_model", "Unable to open file `%s'", filename);
return(FALSE);
}
fread(cookie, sizeof(char), strlen(COOKIE), file);
if(strncmp(cookie, COOKIE, strlen(COOKIE))!=0) {
warn("load_model", "File `%s' is not a MegaHAL brain", filename);
goto fail;
}
fread(&(model->order), sizeof(BYTE1), 1, file);
load_tree(file, model->forward);
load_tree(file, model->backward);
load_dictionary(file, model->dictionary);
return(TRUE);
fail:
fclose(file);
return(FALSE);
}
/*---------------------------------------------------------------------------*/
/*
* Function: Make_Words
*
( run in 3.400 seconds using v1.01-cache-2.11-cpan-75ffa21a3d4 )