libdb.c

Go to the documentation of this file.
00001 /****************************************************************************
00002  *   File    : libdb.c
00003  *   Author  : Adam Cheyer
00004  *   Purpose : Contains C version of Prolog database
00005  *   Updated : 3/1/98
00006  */
00007 /*
00008  * Copyright (C) 2006  SRI International
00009  *
00010  * This library is free software; you can redistribute it and/or
00011  * modify it under the terms of the GNU Lesser General Public
00012  * License as published by the Free Software Foundation; either
00013  * version 2.1 of the License, or (at your option) any later version.
00014  *
00015  * This library is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018  * Lesser General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU Lesser General Public
00021  * License along with this library; if not, write to the Free Software
00022  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00023  *
00024  * SRI International: 333 Ravenswood Ave, Menlo Park, CA 94025
00025  */
00026 
00027 #define EXPORT_BORLAND
00028 
00029 #ifdef IS_DLL
00030 #define EXPORT_MSCPP __declspec(dllexport)
00031 #else
00032 #define EXPORT_MSCPP
00033 #endif
00034 
00035 /****************************************************************************
00036  * RCS Header
00037  ****************************************************************************/
00038 #ifndef lint
00039 /*static char *rcsid= "$Header: /home/zuma1/OAA/CVSRepository/oaa2/src/oaalib/c/src/libdb.c,v 1.22 2006/10/29 22:36:50 agno Exp $";*/
00040 #endif
00041 
00042 
00043 #define DB_MAGIC_COOKIE 123456
00044 
00045 /****************************************************************************
00046  *Include files
00047  ****************************************************************************/
00048 
00049 #include <stdio.h>
00050 //#include <malloc.h>
00051 #include "libdb.h"
00052 #include "libicl_private.h"
00053 
00057 int OAA_hash_function(char *str)
00058 {
00059   int i = 0;
00060 
00061   while (str && *str) {
00062     i = i + *str;
00063     str = str + 1;
00064   }
00065 
00066   return(i % DB_HASH_TABLE_SIZE);
00067 }
00068 
00069 
00073 int
00074 db_IsValid(ICLDatabase *db)
00075 {
00076   if (db && (db->magic_cookie == DB_MAGIC_COOKIE))
00077     return TRUE;
00078   else {
00079     /* DEBUG */
00080     /*
00081       printf("Warning!  Trying to perform operation on uninitialized DB.\n");
00082     */
00083     return FALSE;
00084   }
00085 }
00086 
00087 
00091 EXPORT_MSCPP
00092 ICLDatabase *  EXPORT_BORLAND
00093 db_NewDB()
00094 {
00095   int i;
00096   ICLDatabase *db = malloc(sizeof(ICLDatabase));
00097 
00098   db->magic_cookie = DB_MAGIC_COOKIE;
00099   for (i = 0; i < DB_HASH_TABLE_SIZE; i++)
00100     db->row[i] = NULL;
00101   return db;
00102 }
00103 
00104 
00105 
00110 EXPORT_MSCPP
00111 int EXPORT_BORLAND
00112 db_FreeDB(ICLDatabase *db)
00113 {
00114   int i;
00115 
00116   if (db) {
00117     for (i = 0; i < DB_HASH_TABLE_SIZE; i++) {
00118       ICLListType *list = db->row[i];
00119       ICLListType *next;
00120       while (list) {
00121   next = list->next;
00122   icl_Free(list->elt);
00123   free(list);
00124   list = next;
00125       }
00126       db->row[i] = NULL;
00127     }
00128     free(db);
00129     return TRUE;
00130   }
00131   else return FALSE;
00132 }
00133 
00134 
00135 
00141 EXPORT_MSCPP
00142 int EXPORT_BORLAND
00143 db_Assert(ICLDatabase *db, ICLTerm *term, ICLTerm *params)
00144 {
00145   if (icl_IsStruct(term) && db_IsValid(db)) {
00146     int index;
00147 
00148     index = OAA_hash_function(icl_Functor(term));
00149 
00150     /* If first element added to row */
00151     if (db->row[index] == NULL) {
00152       ICLTerm* copy = icl_CopyTerm(term);
00153       db->row[index] = icl_NewCons(copy, NULL);
00154       /*db_PrintDB(db);*/
00155       CHECK_LEAKS();
00156     }
00157     else {
00158       /* if adding at beginning of row */
00159       if (icl_ParamValue("at_beginning", ICL_TRUE, params, NULL)) {
00160         db->row[index] = icl_NewCons(icl_CopyTerm(term), db->row[index]);
00161       }
00162       else {
00163   ICLListType *p = db->row[index];
00164         /* Loop to end of current row */
00165   while (p->next)
00166     p = p->next;
00167   p->next = icl_NewCons(icl_CopyTerm(term), NULL);
00168       }
00169     }
00170 
00171     return TRUE;
00172   }
00173   else return FALSE;
00174 }
00175 
00176 
00182 EXPORT_MSCPP
00183 int EXPORT_BORLAND
00184 db_Retract(ICLDatabase *db, ICLTerm *term, ICLTerm *params)
00185 {
00186   if (icl_IsStruct(term) && db_IsValid(db)) {
00187     int index = OAA_hash_function(icl_Functor(term));
00188     ICLListType *prev = NULL, *list;
00189     int found;
00190     int doAll = icl_ParamValue("do_all", ICL_TRUE, params, NULL);
00191 
00192     list = db->row[index];
00193 
00194     do {
00195       found = icl_Unify(list->elt, term, NULL);
00196 
00197       if (found) {
00198   /* first element of list */
00199   if (prev == NULL) {
00200     db->row[index] = list->next;
00201   }
00202   else {
00203     prev->next = list->next;
00204   }
00205 
00206   /*
00207           icl_Free(list);
00208   */
00209   icl_Free(list->elt);
00210   free(list);
00211   list = db->row[index];
00212       }
00213       else {
00214   prev = list;
00215   list = list->next;
00216       }
00217 
00218     } while ((!found || doAll) && list);
00219 
00220     return found;
00221   }
00222   else return FALSE;
00223 }
00224 
00225 
00226 
00232 EXPORT_MSCPP
00233 int EXPORT_BORLAND
00234 db_Solve(ICLDatabase *db, ICLTerm *term, ICLTerm *params, ICLTerm **answers)
00235 {
00236   if (icl_IsStruct(term) && db_IsValid(db)) {
00237     int index = OAA_hash_function(icl_Functor(term));
00238     ICLListType *list, *p = (ICLListType *)NULL;
00239     int found;
00240     gint64 solutionLimit = 0;
00241     int n = 0;
00242 
00243     list = db->row[index];
00244 
00245     /* No information */
00246     if (!list)
00247       return FALSE;
00248 
00249     if (!icl_ParamValueAsInt("solution_limit", params, &solutionLimit))
00250       solutionLimit = 30000;
00251 
00252     if (answers)
00253       *answers = icl_NewList(NULL);
00254 
00255     do {
00256       found = icl_Unify(list->elt, term, NULL);
00257 
00258       if (found) {
00259 
00260         /* If first addition, connect to *answers */
00261         if (!p) {
00262           if (answers) {
00263             p = icl_NewCons(icl_CopyTerm(list->elt), NULL);
00264             (*answers)->p = p;
00265           }
00266           n = n + 1;
00267         }
00268         /* for other additions, add to last element (p) */
00269         else {
00270           if(answers) {
00271             p->next = icl_NewCons(icl_CopyTerm(list->elt), NULL);
00272             p = p->next;
00273           }
00274         }
00275       }
00276       list = list->next;
00277 
00278     } while ((n < solutionLimit) && list);
00279 
00280     return TRUE;
00281   }
00282   else return FALSE;
00283 }
00284 
00285 
00290 EXPORT_MSCPP
00291 int EXPORT_BORLAND
00292 db_PrintDB(ICLDatabase *db)
00293 {
00294   if (db_IsValid(db)) {
00295     ICLListType *p;
00296     int i;
00297 
00298     printf("******* Print DB *********\n");
00299 
00300     for (i = 0; i < DB_HASH_TABLE_SIZE; i++) {
00301       p = db->row[i];
00302       while (p != NULL) {
00303   printf("p: %p p->elt: %p ", p, p->elt);
00304   icl_WriteTerm(p->elt);
00305   printf("\n");
00306   p = p->next;
00307       }
00308     }
00309 
00310     return TRUE;
00311   }
00312   else return FALSE;
00313 }
00314 

Generated on Wed May 23 17:20:11 2007 using doxygen 1.5.2