/* * Returns the total number of groundings of all non-evidence predicate */ static int32_t all_atoms_cardinality(pred_tbl_t *pred_tbl, sort_table_t *sort_table) { int32_t i; int32_t card = 0; for (i = 1; i < pred_tbl->num_preds; i++) { card += pred_cardinality(pred_tbl, sort_table, i); } return card; }
void gen_assert_discr_fun_two_clones(z3_wrapper *z3, const clone *clone1_basis, const clone *clone1, const clone *clone2, int fun_arity) { /* select any predicate discriminating two clones */ clone diff; clone_diff(clone2, clone1, &diff); assert(!clone_is_empty(&diff)); /* heuristically, find a predicate from `diff` with the smallest extensional * size */ uint64_t min_card = -1; pred min_pred; for(clone_iterator it = clone_iterator_begin(&diff); !clone_iterator_end(&diff, &it); clone_iterator_next(&it)) { pred pred = clone_iterator_deref(&it); int64_t card = pred_cardinality(&pred); if(card < min_card) { min_card = card; min_pred = pred; } } gen_assert_discr_fun(z3, clone1_basis, &min_pred, fun_arity); }
/* * [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; }