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 + -
显示快捷键?