Example #1
0
int32_t choose_unfixed_variable(atom_table_t *atom_table) {
	samp_truth_value_t *assignment = atom_table->assignment;
	int32_t num_vars = atom_table->num_vars;
	int32_t num_unfixed_vars = atom_table->num_unfixed_vars;

	uint32_t var, d, y;

	if (num_unfixed_vars == 0)
		return -1;

	// var = random_uint(num_vars);
	var = genrand_uint(num_vars);
	if (unfixed_tval(assignment[var]))
		return var;
	// d = 1 + random_uint(num_vars - 1);
	d = 1 + genrand_uint(num_vars - 1);
	while (gcd32(d, num_vars) != 1)
		d--;

	y = var;
	do {
		y += d;
		if (y >= num_vars)
			y -= num_vars;
		assert(var != y);
	} while (!unfixed_tval(assignment[y]));
	return y;
}
Example #2
0
int32_t choose_clause_var(samp_table_t *table, samp_clause_t *clause,
		double rvar_probability) {
	rule_inst_table_t *rule_inst_table = &table->rule_inst_table;
	atom_table_t *atom_table = &table->atom_table;
	integer_stack_t *clause_var_stack = &table->clause_var_stack;
	uint32_t i, sidx, vidx;

	if (clause_var_stack->size == 0) {
		init_integer_stack(clause_var_stack, 0);
	} else {
		clear_integer_stack(clause_var_stack);
	}

	double choice = choose();
	if (choice < rvar_probability) { /* flip a random unfixed variable */
		for (i = 0; i < clause->num_lits; i++) {
			if (unfixed_tval(atom_table->assignment[var_of(clause->disjunct[i])]))
				push_integer_stack(i, clause_var_stack);
		} 
		if (unfixed_tval(rule_inst_table->assignment[clause->rule_index]))
			push_integer_stack(clause->num_lits, clause_var_stack);
		/* all unfixed vars are now in clause_var_stack */
	} else {
		int32_t dcost = INT32_MAX, vcost = 0;
		for (i = 0; i < clause->num_lits; i++) {
			if (unfixed_tval(atom_table->assignment[var_of(clause->disjunct[i])])) {
				cost_flip_unfixed_variable(table, var_of(clause->disjunct[i]), &vcost);
				if (dcost >= vcost) {
					if (dcost > vcost) {
						dcost = vcost;
						clear_integer_stack(clause_var_stack);
					}
					push_integer_stack(i, clause_var_stack);
				}
			}
		}
		if (unfixed_tval(rule_inst_table->assignment[clause->rule_index])) {
			cost_flip_unfixed_rule(table, clause->rule_index, &vcost);
			if (dcost > vcost) {
				dcost = vcost;
				clear_integer_stack(clause_var_stack);
				push_integer_stack(clause->num_lits, clause_var_stack);
			}
		}
	}
	//sidx = random_uint(length_integer_stack(clause_var_stack));
	sidx = genrand_uint(length_integer_stack(clause_var_stack));
	vidx = nth_integer_stack(sidx, clause_var_stack);

	return vidx;
}
Example #3
0
/*
 * Pushes a clause to a list depending on its evaluation
 *
 * If it is fixed to be satisfied, push to sat_clauses
 * If it is satisfied, push to the corresponding watched list
 * If it is unsatisified, push to unsat_clauses
 */
void insert_live_clause(samp_clause_t *clause, samp_table_t *table) {
	rule_inst_table_t *rule_inst_table = &table->rule_inst_table;
	atom_table_t *atom_table = &table->atom_table;
	int32_t i, fixable;
	samp_literal_t lit;

	/* See if the clause is fixed-unit propagating */
	fixable = get_fixable_literal(atom_table->assignment, 
			rule_inst_table->assignment, clause);
	if (fixable == -2) { 
		/* fixed unsat */
		mcsat_err("There is a fixed unsat clause, no model exists.");
		return;
	}
	else if (fixable == -1) { /* more than one unfixed lits */
		i = get_true_literal(atom_table->assignment,
				rule_inst_table->assignment, clause);
		if (i < 0) { 
			/* currently unsat, put back to the unsat list */
			clause_list_insert_head(clause, 
					&rule_inst_table->unsat_clauses);
		} else if (i == clause->num_lits) {
			/* currently sat, put to the rule_watched list */
			clause_list_insert_head(clause, 
					&rule_inst_table->rule_watched[clause->rule_index]);
		} else {
			/* currently sat, put to the watched list */
			clause_list_insert_head(clause, 
					&rule_inst_table->watched[clause->disjunct[i]]);
		}
	} else { 
		/* fix a soft rule to unsat, because one of its clauses is fixed unsat */
		if (fixable == clause->num_lits) {
			rule_inst_t *rinst = rule_inst_table->rule_insts[clause->rule_index];
			if (assigned_true(rule_inst_table->assignment[clause->rule_index])) {
				rule_inst_table->unsat_weight += rinst->weight;
			} else {
				rule_inst_table->sat_weight   += rinst->weight;
                        }
			if (get_verbosity_level() >= 3) {
				printf("[insert_live_clause] Fix rule %d: \n", clause->rule_index);
				print_rule_instance(rinst, table);
				printf(" to false\n");
			}
			rule_inst_table->assignment[clause->rule_index] = v_up_false;
		} else {
			/* fixed sat if we fix the 'fixable' literal */
			lit = clause->disjunct[fixable];
			if (unfixed_tval(atom_table->assignment[var_of(lit)])) {
				/* unit propagation */
				fix_lit_true(table, lit);
			} else {
				// already fixed sat
			}
			assert(assigned_fixed_true_lit(atom_table->assignment, lit));
		}
		clause_list_insert_head(clause, &rule_inst_table->sat_clauses);
	}
}
Example #4
0
/*
 * Try to set the value of an atom.
 *
 * If the atom has a non-fixed value and is set to a fixed value, run
 * unit_propagation...;
 * If the atom has a non-fixed value and is set to the opposite non-fixed value,
 * just change the value (and change the state of the relavent clauses?)
 */
static int32_t update_atom_tval(int32_t var, samp_truth_value_t tval, samp_table_t *table) {
	pred_table_t *pred_table = &table->pred_table;
	atom_table_t *atom_table = &table->atom_table;
	samp_atom_t *atom = atom_table->atom[var];
	pred_entry_t *pred_entry = get_pred_entry(pred_table, atom->pred);

	/*
	 * Case 0: If the atom has been fixed, check if consistent: if it is
	 * assigned to the opposite value, return inconsistency; otherwise do
	 * nothing;
	 */
	samp_truth_value_t old_tval = atom_table->assignment[var];
	if (!unfixed_tval(old_tval)) {
		if ((assigned_true(old_tval) && assigned_false(tval))
				|| (assigned_false(old_tval) && assigned_true(tval))) {
			mcsat_err("[update_atom_tval] Assigning a conflict truth value. No model exists.\n");
			return -1;
		} else {
			return 0;
		}
	}

#if USE_PTHREADS
        /* Internally, this is now theoretically protected with a
           mutex, but do we really want a multithreaded mcmc to be
           waiting for mutexes? */
#else
        /* Something's still bad here.  For now, we ignore this code
           block if we are compiled for pthreads */
	char *var_str = var_string(var, table);
	cprintf(3, "[update_atom_tval] Setting the value of %s to %s\n",
			var_str, samp_truth_value_string(tval));
	free(var_str);
#endif

	/* Not case 0: update the value */
	atom_table->assignment[var] = tval;
	if (fixed_tval(tval)) {
          /* If fixed, this can break a later assertion that there are
             no fixed vars. Why? */
		atom_table->num_unfixed_vars--;
	}

	/* Case 1: If the value just gets fixed but not changed, we are done. */
	if (old_tval == unfix_tval(tval)) {
		return 0;
	}

	/* Case 2: the value has changed */
	if (assigned_true(tval)) {
		link_propagate(table, neg_lit(var));
	} else {
		link_propagate(table, pos_lit(var));
	}
	//assert(valid_table(table));

	/* If the atom is inactive AND the value is non-default, activate the atom. */
	if (lazy_mcsat() && !atom_table->active[var]
			&& assigned_false(tval) == pred_default_value(pred_entry)) {
		activate_atom(table, var);
	}
	//assert(valid_table(table));

	samp_truth_value_t new_tval = atom_table->assignment[var];
	assert(new_tval == tval || (fixed_tval(new_tval)
			&& tval == unfix_tval(negate_tval(new_tval))));

	/*
	 * WARNING: in lazy mcsat, when we activate a new clause, it may force the
	 * value of the atom being activated to be the nagation of the value we
	 * intend to assign. E.g., when we want to set p(A) to v_true, and
	 * activated (and kept alive of) the clause ~p(A) or q(B), where q(B) is
	 * fixed to false (either by database or unit propagation), then p(A) has
	 * to change back to v_fixed_false.
	 */
	if (new_tval != tval)
		return -1;
	return 0;
}
Example #5
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;
}