00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
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
00037
00038 #ifndef lint
00039
00040 #endif
00041
00042
00043 #define DB_MAGIC_COOKIE 123456
00044
00045
00046
00047
00048
00049 #include <stdio.h>
00050
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
00080
00081
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
00151 if (db->row[index] == NULL) {
00152 ICLTerm* copy = icl_CopyTerm(term);
00153 db->row[index] = icl_NewCons(copy, NULL);
00154
00155 CHECK_LEAKS();
00156 }
00157 else {
00158
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
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
00199 if (prev == NULL) {
00200 db->row[index] = list->next;
00201 }
00202 else {
00203 prev->next = list->next;
00204 }
00205
00206
00207
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
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
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
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