int32_t add_var(var_table_t *var_table, char *name, sort_table_t *sort_table, char * sort_name){ int32_t sort_index = sort_name_index(sort_name, sort_table); if (sort_index == -1){ printf("\nSort name %s has not been declared.", sort_name); return -1; } int32_t index = stbl_find(&(var_table->var_name_index), name); if (index == -1){//var is not in the symbol table int32_t n = var_table->num_vars; if (n >= var_table->size){ var_table_resize(var_table, n + (n/2)); } name = str_copy(name); var_table->entries[n].name = name; var_table->entries[n].sort_index = sort_index; var_table->num_vars++; stbl_add(&(var_table->var_name_index), name, n); return 0; } else { printf("\nVariable %s already exists", name); return -1; } }
int32_t add_pred(pred_table_t *pred_table, char *name, bool evidence, int32_t arity, sort_table_t *sort_table, char **in_signature){ int32_t * signature = sort_signature(in_signature, arity, sort_table); if (signature == NULL && in_signature != NULL){ printf("\nInput signature contains undeclared sort."); return -1; } int32_t index = stbl_find(&(pred_table->pred_name_index), name); pred_tbl_t *pred_tbl; if (strlen(name) == 0){ printf("\nEmpty predicate name is not allowed."); return -1; } if (index == -1) { //pred is not in the symbol table (Change to stbl_rec_t *) if (evidence) { pred_tbl = &(pred_table->evpred_tbl); index = 2 * pred_tbl->num_preds; } else { pred_tbl = &(pred_table->pred_tbl); index = (2 * pred_tbl->num_preds) + 1; } pred_tbl_resize(pred_tbl); int32_t n = pred_tbl->num_preds; name = str_copy(name); pred_tbl->entries[n].name = name; pred_tbl->entries[n].signature = signature; pred_tbl->entries[n].arity = arity; pred_tbl->entries[n].size_atoms = 0; pred_tbl->entries[n].num_atoms = 0; pred_tbl->entries[n].atoms = NULL; pred_tbl->entries[n].size_rules = 0; pred_tbl->entries[n].num_rules = 0; pred_tbl->entries[n].rules = NULL; pred_tbl->num_preds++; stbl_add(&(pred_table->pred_name_index), name, index); //note index is never -1 //printf("\nAdded predicate index %"PRId32" with name %s, hashindex %"PRId32", arity %"PRId32", and signature:", // n, name, index, arity); //printf("\nhashindex[%s] = %"PRId32"", // pred_tbl->entries[n].name, // pred_index(pred_tbl->entries[n].name, pred_table)); //printf("\n("); //int32_t i; //for (i=0; i < arity; i++){ //printf("%"PRId32"", signature[i]); //} //printf(")"); return 0; } else { return -1; } }
/* * Checks the validity of the table for assertions within other functions. * valid_sort_table checks that the sort size is nonnegative, num_sorts is * at most size, and each sort name is hashed to the right index. */ bool valid_sort_table(sort_table_t *sort_table){ assert(sort_table->size >= 0); assert(sort_table->num_sorts <= sort_table->size); if (sort_table->size < 0 || sort_table->num_sorts > sort_table->size) return false; uint32_t i = 0; while (i < sort_table->num_sorts && i == stbl_find(&(sort_table->sort_name_index), sort_table->entries[i].name)) i++; assert(i >= sort_table->num_sorts); if (i < sort_table->num_sorts) return false; return true; }
/* Checks that the const names are hashed to the right index. */ bool valid_const_table(const_table_t *const_table, sort_table_t *sort_table){ assert(const_table->size >= 0); assert(const_table->num_consts <= const_table->size); if (const_table->size < 0 || const_table->num_consts > const_table->size) return false; uint32_t i = 0; while (i < const_table->num_consts && i == stbl_find(&(const_table->const_name_index), const_table->entries[i].name) && const_table->entries[i].sort_index < sort_table->num_sorts) i++; assert(i >= const_table->num_consts); if (i < const_table->num_consts) return false; return true; }
void add_sort(sort_table_t *sort_table, char *name) { int32_t index = stbl_find(&(sort_table->sort_name_index), name); if (index == -1){ /* sort is not in the symbol table */ int32_t n = sort_table->num_sorts; if (n >= sort_table->size){ sort_table_resize(sort_table, n + (n/2)); } name = str_copy(name); sort_table->entries[n].name = name; sort_table->entries[n].size = INIT_SORT_CONST_SIZE; sort_table->entries[n].cardinality = 0; sort_table->entries[n].constants = (int32_t *) safe_malloc(INIT_SORT_CONST_SIZE * sizeof(int32_t)); sort_table->entries[n].subsorts = NULL; sort_table->entries[n].supersorts = NULL; sort_table->num_sorts++; stbl_add(&(sort_table->sort_name_index), name, n); } }
/* * Check the state: * - if scope[i] > 0, then symbol[i] shoulld be mapped to scope[i] * - is scope[i] = 0, then symbol[i] should not be mapped */ static void check(void) { uint32_t i; int32_t k; for (i=0; i<NSYMBOLS; i++) { k = stbl_find(&sym_table, name[i]); if (k < 0) { if (scope[i] != 0) { printf("*** BUG: %s is not mapped. Should be mapped to %"PRIu32" ***\n", name[i], scope[i]); fflush(stdout); exit(1); } } else { if (k != scope[i]) { printf("*** BUG: %s is mapped to %"PRId32". It should be mapped to %"PRIu32" ***\n", name[i], k, scope[i]); fflush(stdout); exit(1); } } } }
/* * Internal form of add_const, checks if const already exists, and verifies * its sort if it does. Returns 0 if it is newly added, 1 if it is already * there, and -1 if there is an error (e.g., sort mismatch). */ int32_t add_const_internal (char *name, int32_t sort_index, samp_table_t *table) { const_table_t *const_table = &(table->const_table); sort_table_t *sort_table = &(table->sort_table); int32_t const_index, num_consts; if (sort_index < 0 || sort_index >= sort_table->num_sorts) { printf("Invalid sort_index"); return -1; } const_index = stbl_find(&(const_table->const_name_index), name); if (const_index == -1){ //const is not in the symbol table num_consts = const_table->num_consts; if (num_consts >= const_table->size) { const_table_resize(const_table, num_consts + (num_consts/2)); } name = str_copy(name); const_table->entries[num_consts].name = name; const_table->entries[num_consts].sort_index = sort_index; add_const_to_sort(num_consts, sort_index, sort_table); const_table->num_consts++; stbl_add(&(const_table->const_name_index), name, num_consts); return 0; } else { // const is in the symbol table - check the sorts if (sort_index == const_table->entries[const_index].sort_index) { return 1; } else { printf("Const %s of sort %s may not be redeclared to sort %s\n", name, sort_table->entries[const_table->entries[const_index].sort_index].name, sort_table->entries[sort_index].name); return -1; } } }
int main(int argc, char *argv[]) { uint32_t i, j, n; double runtime, memused; int32_t x, *val; if (argc != 2) { fprintf(stderr, "Usage: %s filename\n", argv[0]); fprintf(stderr, " filename must contain a set of strings, one per line, less than 100 char long\n"); fflush(stderr); exit(1); } words_from_file(argv[1]); init_stbl(&sym_table, 0); val = (int32_t *) malloc(n_words * sizeof(int32_t)); if (val == NULL) { fprintf(stderr, "Failed to allocate array val\n"); exit(1); } for (i=0; i<n_words; i++) { x = stbl_find(&sym_table, words[i]); if (x < 0) { stbl_add(&sym_table, words[i], i); val[i] = i; } else { val[i] = x; } } printf("\n--- checking ---\n"); for (i=0; i<n_words; i++) { x = stbl_find(&sym_table, words[i]); if (x != val[i]) { printf("*** Error: %s, val = %"PRId32", should be %"PRId32" ***\n", words[i], x, val[i]); fflush(stdout); exit(1); } } printf("\n*** Added %"PRIu32" words from %s ***\n", n_words, argv[1]); // repeated additions of the same symbols with multiple lookups // warning: this code does not work (may give a false alarm) // if the input file contains duplicates. n = (n_words < 200) ? n_words : 200; printf("\n*** Repeated symbol addition ***\n"); runtime = get_cpu_time(); for (i=0; i<10000; i++) { for (j=0; j<n; j++) { stbl_add(&sym_table, words[j], new_val(i, j)); } for (j=0; j<n; j++) { x = stbl_find(&sym_table, words[j]); if (x != new_val(i, j)) { printf("*** Error: %s, val = %"PRId32", should be %"PRId32" ***\n", words[j], x, new_val(i, j)); fflush(stdout); exit(1); } } for (j=0; j<n; j++) { x = stbl_find(&sym_table, words[j]); if (x != new_val(i, j)) { printf("*** Error: %s, val = %"PRId32", should be %"PRId32" ***\n", words[j], x, new_val(i, j)); fflush(stdout); exit(1); } } for (j=0; j<n_words; j++) { x = stbl_find(&sym_table, words[j]); } for (j=0; j<n; j++) { x = stbl_find(&sym_table, words[j]); if (x != new_val(i, j)) { printf("*** Error: %s, val = %"PRId32", should be %"PRId32" ***\n", words[j], x, new_val(i, j)); fflush(stdout); exit(1); } } for (j=0; j<n_words; j++) { x = stbl_find(&sym_table, words[j]); } } runtime = get_cpu_time() - runtime; memused = mem_size() / (1024 * 1024); printf("Adding 10000 times the same %"PRIu32" words + repeated lookups\n", n); printf("Runtime: %.4f s\n", runtime); printf("Table size: %"PRIu32" (nelems = %"PRIu32", ndeleted = %"PRIu32")\n", sym_table.size, sym_table.nelems, sym_table.ndeleted); if (memused > 0) { printf("Memory used: %.2f MB\n", memused); } clear_words(); free(val); delete_stbl(&sym_table); return 0; }
int32_t pred_index(char * predicate, pred_table_t *pred_table){ return stbl_find(&(pred_table->pred_name_index), predicate); }
int32_t sort_name_index(char *name, sort_table_t *sort_table){ return stbl_find(&(sort_table->sort_name_index), name); }
int32_t var_index(char *name, var_table_t *var_table){ return stbl_find(&(var_table->var_name_index), name); }
int32_t const_index(char *name, const_table_t *const_table){ return stbl_find(&(const_table->const_name_index), name); }
void add_subsort(sort_table_t *sort_table, char *subsort, char *supersort) { int32_t i, j, subidx, supidx; sort_entry_t *subentry, *supentry; bool foundit; add_sort(sort_table, subsort); // Does nothing if already there add_sort(sort_table, supersort); subidx = stbl_find(&(sort_table->sort_name_index), subsort); supidx = stbl_find(&(sort_table->sort_name_index), supersort); subentry = &sort_table->entries[subidx]; supentry = &sort_table->entries[supidx]; // Check if this is unnecessary if (subidx == supidx) { printf("Declaring %s as a subsort of itself has no effect\n", subsort); return; } // Note that we only need to test one direction if (supentry->subsorts != NULL) { for (i = 0; supentry->subsorts[i] != -1; i++) { if (supentry->subsorts[i] == subidx) { printf("%s is already a subsort of %s; this delaration has no effect\n", subsort, supersort); return; } } } // Now check for cirularities if (supentry->supersorts != NULL) { for (i = 0; supentry->supersorts[i] != -1; i++) { if (supentry->supersorts[i] == subidx) { printf("%s is a already supersort of %s; cannot be made a subsort\n", subsort, supersort); return; } } } // Need to check both ways if (subentry->subsorts != NULL) { for (i = 0; subentry->subsorts[i] != -1; i++) { if (subentry->subsorts[i] == supidx) { printf("%s is a already subsort of %s; cannot be made a supersort\n", supersort, subsort); return; } } } // Everything's OK, update the subentry supersorts and the supentry subsorts if (supentry->supersorts != NULL) { for (i = 0; supentry->supersorts[i] != -1; i++) { foundit = false; if (subentry->supersorts != NULL) { for (j = 0; subentry->supersorts[j] != -1; j++) { if (supentry->supersorts[i] == subentry->supersorts[j]) { foundit = true; break; } } } if (!foundit) { add_new_supersort(subentry, supentry->supersorts[i]); } } } add_new_supersort(subentry, supidx); if (subentry->subsorts != NULL) { for (i = 0; subentry->subsorts[i] != -1; i++) { foundit = false; if (supentry->subsorts != NULL) { for (j = 0; supentry->subsorts[j] != -1; j++) { if (subentry->subsorts[i] == supentry->subsorts[j]) { foundit = true; break; } } } if (!foundit) { add_new_subsort(supentry, subentry->subsorts[i]); } } } add_new_subsort(supentry, subidx); assert(supentry->subsorts != NULL); assert(subentry->supersorts != NULL); // Finally, add constants of the subsort to the supersort add_subsort_consts_to_supersort(subidx, supidx, sort_table); }