/* * [lazy only] Choose a random atom for simulated annealing step in sample SAT. * The lazy version of choose_unfixed_variable. First choose a random atom, * regardless whether its value is fixed or not (because we can calculate the * total number of atoms and it is convenient to randomly choose one from * them). If its value is fixed, we skip this flip using the following * statement (return 0). */ int32_t choose_random_atom(samp_table_t *table) { uint32_t i, atom_num, anum; int32_t card, all_card, acard, pcard, predicate; pred_tbl_t *pred_tbl = &table->pred_table.pred_tbl; // Indirect preds atom_table_t *atom_table = &table->atom_table; sort_table_t *sort_table = &table->sort_table; pred_entry_t *pred_entry; assert(valid_table(table)); /* Get the number of possible indirect atoms */ all_card = all_atoms_cardinality(pred_tbl, sort_table); //atom_num = random_uint(all_card); atom_num = genrand_uint(all_card); predicate = 1; /* Skip past true */ acard = 0; while (true) { /* determine the predicate */ assert(predicate <= pred_tbl->num_preds); pcard = pred_cardinality(pred_tbl, sort_table, predicate); if (acard + pcard > atom_num) { break; } acard += pcard; predicate++; } assert(pred_cardinality(pred_tbl, sort_table, predicate) != 0); /* gives the position of atom within predicate */ anum = atom_num - acard; /* * Now calculate the arguments. We represent the arguments in * little-endian form */ pred_entry = &pred_tbl->entries[predicate]; int32_t *signature = pred_entry->signature; int32_t arity = pred_entry->arity; atom_buffer_resize(arity); int32_t constant; samp_atom_t *atom = (samp_atom_t *) atom_buffer.data; /* Build atom from atom_num by successive division */ atom->pred = predicate; for (i = 0; i < arity; i++) { card = sort_table->entries[signature[i]].cardinality; constant = anum % card; anum = anum / card; sort_entry_t *sort_entry = &sort_table->entries[signature[i]]; if (sort_entry->constants == NULL) { /* Must be an integer */ if (sort_entry->ints == NULL) { atom->args[i] = sort_entry->lower_bound + constant; } else { atom->args[i] = sort_entry->ints[constant]; } } else { atom->args[i] = sort_entry->constants[constant]; /* Quick typecheck */ assert(const_sort_index(atom->args[i], &table->const_table) == signature[i]); } } assert(valid_table(table)); array_hmap_pair_t *atom_map; atom_map = array_size_hmap_find(&atom_table->atom_var_hash, arity + 1, (int32_t *) atom); int32_t atom_index; if (atom_map == NULL) { /* need to activate atom */ atom_index = add_internal_atom(table, atom, false); atom_map = array_size_hmap_find(&atom_table->atom_var_hash, arity + 1, (int32_t *) atom); assert(atom_map != NULL); activate_atom(table, atom_index); } else { atom_index = atom_map->val; } return atom_index; }
/* * Checks that each atom is well-formed. */ bool valid_atom_table(atom_table_t *atom_table, pred_table_t *pred_table, const_table_t *const_table, sort_table_t *sort_table){ assert(atom_table->size >= 0); assert(atom_table->num_vars <= atom_table->size); if (atom_table->size < 0 || atom_table->num_vars > atom_table->size) { printf("Invalid atom table size\n"); return false; } uint32_t i, j, k; int32_t pred, arity; int32_t num_unfixed = 0; int32_t *sig; sort_entry_t *sort_entry; int32_t arg; bool int_exists; for (i = 0; i < atom_table->num_vars; i++) { pred = atom_table->atom[i]->pred; arity = pred_arity(pred, pred_table); sig = pred_signature(pred, pred_table); if (unfixed_tval(atom_table->assignment[i])){ num_unfixed++; } for (j = 0; j < arity; j++){ sort_entry = &sort_table->entries[sig[j]]; arg = atom_table->atom[i]->args[j]; if (sort_entry->constants == NULL) { if (sort_entry->ints == NULL) { assert(arg >= sort_entry->lower_bound); assert(arg <= sort_entry->upper_bound); if (arg < sort_entry->lower_bound || arg > sort_entry->upper_bound) { printf("Integer out of boundary\n"); } } else { /* Enumerate integers, check if in the set */ int_exists = false; for (k = 0; k < sort_entry->cardinality; k++) { if (arg == sort_entry->ints[k]) int_exists = true; } assert(int_exists); if (!int_exists) { printf("Enumerate integer not in set\n"); } } } else { /* constants have unique sorts, lookup directly */ assert(const_table->entries[arg].sort_index == sig[j]); if (const_table->entries[arg].sort_index != sig[j]) { printf("Invalid atom sort\n"); return false; } } } array_hmap_pair_t *hmap_pair; hmap_pair = array_size_hmap_find(&(atom_table->atom_var_hash), arity+1, (int32_t *) atom_table->atom[i]); assert(hmap_pair != NULL); assert(hmap_pair->val == i); if (hmap_pair == NULL || hmap_pair->val != i) { printf("Invalid atom hmap_pair\n"); return false; } } assert(num_unfixed == atom_table->num_unfixed_vars); if (num_unfixed != atom_table->num_unfixed_vars) { printf("Invalid atom num unfixed vars\n"); return false; } return true; }