libdb.c
来自「SRI international 发布的OAA框架软件」· C语言 代码 · 共 327 行
C
327 行
/****************************************************************************
* File : libdb.c
* Author : Adam Cheyer
* Purpose : Contains C version of Prolog database
* Updated : 3/1/98
*
* -------------------------------------------------------------------------
* Unpublished-rights reserved under the copyright laws of the United States.
*
* This data and information is proprietary to, and a valuable trade
* secret of, SRI International. It is given in confidence by SRI
* International. Its use, duplication, or disclosure is subject to the
* restrictions set forth in the License Agreement under which it has
* been distributed.
*
* Unpublished Copyright (c) 1993-98, SRI International.
* -------------------------------------------------------------------------
*
*****************************************************************************/
#define EXPORT_BORLAND
#ifdef IS_DLL
#define EXPORT_MSCPP __declspec(dllexport)
#else
#define EXPORT_MSCPP
#endif
/****************************************************************************
* RCS Header
****************************************************************************/
#ifndef lint
/*static char *rcsid= "$Header: /home/zuma1/OAA/CVSRepository/oaa2/src/oaalib/c/src/libdb.c,v 1.20 2004/10/12 17:58:44 agno Exp $";*/
#endif
#define DB_MAGIC_COOKIE 123456
/****************************************************************************
*Include files
****************************************************************************/
#include <stdio.h>
//#include <malloc.h>
#include "libdb.h"
#include "libicl_private.h"
/**
* Hash function: simple sum of characters modulo hash table size
*/
int OAA_hash_function(char *str)
{
int i = 0;
while (str && *str) {
i = i + *str;
str = str + 1;
}
return(i % DB_HASH_TABLE_SIZE);
}
/**
* Returns TRUE if Database has been properly initialized.
*/
int
db_IsValid(ICLDatabase *db)
{
if (db && (db->magic_cookie == DB_MAGIC_COOKIE))
return TRUE;
else {
/* DEBUG */
/*
printf("Warning! Trying to perform operation on uninitialized DB.\n");
*/
return FALSE;
}
}
/**
* Returns a pointer to a new database structure.
*/
EXPORT_MSCPP
ICLDatabase * EXPORT_BORLAND
db_NewDB()
{
int i;
ICLDatabase *db = malloc(sizeof(ICLDatabase));
db->magic_cookie = DB_MAGIC_COOKIE;
for (i = 0; i < DB_HASH_TABLE_SIZE; i++)
db->row[i] = NULL;
return db;
}
/**
* Frees all space used by a database.
* @return TRUE if success
*/
EXPORT_MSCPP
int EXPORT_BORLAND
db_FreeDB(ICLDatabase *db)
{
int i;
if (db) {
for (i = 0; i < DB_HASH_TABLE_SIZE; i++) {
ICLListType *list = db->row[i];
ICLListType *next;
while (list) {
next = list->next;
icl_Free(list->elt);
free(list);
list = next;
}
db->row[i] = NULL;
}
free(db);
return TRUE;
}
else return FALSE;
}
/**
* Adds a copy of an ICL term to the database.
* Parameters may include "at_beginning" (boolean parameter).
* @return TRUE if success
*/
EXPORT_MSCPP
int EXPORT_BORLAND
db_Assert(ICLDatabase *db, ICLTerm *term, ICLTerm *params)
{
if (icl_IsStruct(term) && db_IsValid(db)) {
int index;
index = OAA_hash_function(icl_Functor(term));
/* If first element added to row */
if (db->row[index] == NULL) {
ICLTerm* copy = icl_CopyTerm(term);
db->row[index] = icl_NewCons(copy, NULL);
/*db_PrintDB(db);*/
CHECK_LEAKS();
}
else {
/* if adding at beginning of row */
if (icl_ParamValue("at_beginning", ICL_TRUE, params, NULL)) {
db->row[index] = icl_NewCons(icl_CopyTerm(term), db->row[index]);
}
else {
ICLListType *p = db->row[index];
/* Loop to end of current row */
while (p->next)
p = p->next;
p->next = icl_NewCons(icl_CopyTerm(term), NULL);
}
}
return TRUE;
}
else return FALSE;
}
/**
* Removes an ICL term from the database.
* Parameters may include "do_all" (boolean parameter).
* @return TRUE if success
*/
EXPORT_MSCPP
int EXPORT_BORLAND
db_Retract(ICLDatabase *db, ICLTerm *term, ICLTerm *params)
{
if (icl_IsStruct(term) && db_IsValid(db)) {
int index = OAA_hash_function(icl_Functor(term));
ICLListType *prev = NULL, *list;
int found;
int doAll = icl_ParamValue("do_all", ICL_TRUE, params, NULL);
list = db->row[index];
do {
found = icl_Unify(list->elt, term, NULL);
if (found) {
/* first element of list */
if (prev == NULL) {
db->row[index] = list->next;
}
else {
prev->next = list->next;
}
/*
icl_Free(list);
*/
icl_Free(list->elt);
free(list);
list = db->row[index];
}
else {
prev = list;
list = list->next;
}
} while ((!found || doAll) && list);
return found;
}
else return FALSE;
}
/**
* Searches the database for matches to term.
* Parameters may include "solution_limit" (integer parameter).
* @return TRUE if success
*/
EXPORT_MSCPP
int EXPORT_BORLAND
db_Solve(ICLDatabase *db, ICLTerm *term, ICLTerm *params, ICLTerm **answers)
{
if (icl_IsStruct(term) && db_IsValid(db)) {
int index = OAA_hash_function(icl_Functor(term));
ICLListType *list, *p = (ICLListType *)NULL;
int found;
gint64 solutionLimit = 0;
int n = 0;
list = db->row[index];
/* No information */
if (!list)
return FALSE;
if (!icl_ParamValueAsInt("solution_limit", params, &solutionLimit))
solutionLimit = 30000;
if (answers)
*answers = icl_NewList(NULL);
do {
found = icl_Unify(list->elt, term, NULL);
if (found) {
/* If first addition, connect to *answers */
if (!p) {
if (answers) {
p = icl_NewCons(icl_CopyTerm(list->elt), NULL);
(*answers)->p = p;
}
n = n + 1;
}
/* for other additions, add to last element (p) */
else {
if(answers) {
p->next = icl_NewCons(icl_CopyTerm(list->elt), NULL);
p = p->next;
}
}
}
list = list->next;
} while ((n < solutionLimit) && list);
return TRUE;
}
else return FALSE;
}
/**
* Writes out the entire database.
* @return TRUE if success
*/
EXPORT_MSCPP
int EXPORT_BORLAND
db_PrintDB(ICLDatabase *db)
{
if (db_IsValid(db)) {
ICLListType *p;
int i;
printf("******* Print DB *********\n");
for (i = 0; i < DB_HASH_TABLE_SIZE; i++) {
p = db->row[i];
while (p != NULL) {
printf("p: %p p->elt: %p ", p, p->elt);
icl_WriteTerm(p->elt);
printf("\n");
p = p->next;
}
}
return TRUE;
}
else return FALSE;
}
/**
* @defgroup DB Database
*
* Contains the C version of the Prolog database.
*
* @{
*/
/**
* @file libdb.h
*/
/**
* @file libdb.c
* Contains the C version of the Prolog database.
*/
/** @} */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?