Example #1
0
/*
 * [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;
}
Example #2
0
/* 
 * 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;
}