Пример #1
0
/*
 * FIXME in lazy version, we need to consider the clauses that would be
 * activated and becoming unsat if the variable is flipped. The dcost computed
 * by the current code is an underestimate
 */
void cost_flip_unfixed_variable(samp_table_t *table, int32_t var, 
		int32_t *dcost) {
	rule_inst_table_t *rule_inst_table = &table->rule_inst_table;
	atom_table_t *atom_table = &table->atom_table;
	samp_literal_t plit, nlit;
	uint32_t i;

	if (assigned_true(atom_table->assignment[var])) {
		nlit = neg_lit(var);
		plit = pos_lit(var);
	} else {
		nlit = pos_lit(var);
		plit = neg_lit(var);
	}

	*dcost = 0;
	samp_clause_t *ptr;
	samp_clause_t *cls;

	/* add the number of the watched clauses that will be flipped */
	for (ptr = rule_inst_table->watched[plit].head;
			ptr != rule_inst_table->watched[plit].tail;
			ptr = next_clause_ptr(ptr)) {
		cls = ptr->link;
		i = 0;
		while (i < cls->num_lits
				&& (cls->disjunct[i] == plit
				|| assigned_false_lit(atom_table->assignment, cls->disjunct[i]))) {
			i++;
		}
		if (i == cls->num_lits) {
			*dcost += 1;
		}
	}

	/* subtract the number of the unsatisfied clauses that can be flipped */
	for (ptr = rule_inst_table->unsat_clauses.head;
			ptr != rule_inst_table->unsat_clauses.tail;
			ptr = next_clause_ptr(ptr)) {
		cls = ptr->link;
		i = 0;
		while (i < cls->num_lits && cls->disjunct[i] != nlit) {
			assert(cls->disjunct[i] != plit);
			i++;
		}
		if (i < cls->num_lits) {
			*dcost -= 1;
		}
	}
}
Пример #2
0
void init_live_clauses(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, j;
	for (i = 0; i < atom_table->num_vars; i++) {
		empty_clause_list(&rule_inst_table->watched[pos_lit(i)]);
		empty_clause_list(&rule_inst_table->watched[neg_lit(i)]);
	}
	for (i = 0; i < rule_inst_table->num_rule_insts; i++)
		empty_clause_list(&rule_inst_table->rule_watched[i]);
	empty_clause_list(&rule_inst_table->sat_clauses);
	empty_clause_list(&rule_inst_table->unsat_clauses);
	empty_clause_list(&rule_inst_table->live_clauses);

	for (i = 0; i < rule_inst_table->num_rule_insts; i++) {
		if (assigned_true(rule_inst_table->assignment[i])) {
			rule_inst_t *rinst = rule_inst_table->rule_insts[i];
			for (j = 0; j < rinst->num_clauses; j++) {
				clause_list_insert_tail(rinst->conjunct[j], &rule_inst_table->live_clauses);
			}
		}
	}
}
Пример #3
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;
}
Пример #4
0
/*
 * Validate all the lists in the clause table
 */
bool valid_rule_inst_table(rule_inst_table_t *rule_inst_table, atom_table_t *atom_table){
	samp_clause_t *ptr;
	samp_clause_t *cls;
	int32_t lit, i;
	assert(rule_inst_table->size >= 0);
	assert(rule_inst_table->num_rule_insts >= 0);
	assert(rule_inst_table->num_rule_insts <= rule_inst_table->size);
	if (rule_inst_table->size < 0) return false;
	if (rule_inst_table->num_rule_insts < 0 
			|| rule_inst_table->num_rule_insts > rule_inst_table->size)
		return false;

	/* check that every clause in the unsat list is unsat */
	valid_clause_list(&rule_inst_table->unsat_clauses);
	for (ptr = rule_inst_table->unsat_clauses.head;
			ptr != rule_inst_table->unsat_clauses.tail;
			ptr = next_clause_ptr(ptr)) {
		cls = ptr->link;
		assert(eval_clause(atom_table->assignment, cls) == -1);
		if (eval_clause(atom_table->assignment, cls) != -1)
			return false;
	}

	///* check negative_or_unit_clauses */
	//valid_clause_list(&rule_inst_table->negative_or_unit_clauses);
	//for (ptr = rule_inst_table->negative_or_unit_clauses.head;
	//		ptr != rule_inst_table->negative_or_unit_clauses.tail;
	//		ptr = next_clause_ptr(ptr)) {
	//	cls = ptr->link;
	//	assert(cls->weight < 0 || cls->numlits == 1);
	//	if (cls->weight >= 0 && cls->numlits != 1) 
	//		return false;
	//}

	///* check dead_negative_or_unit_clauses */
	//valid_clause_list(&rule_inst_table->dead_negative_or_unit_clauses);
	//for (ptr = rule_inst_table->dead_negative_or_unit_clauses.head;
	//		ptr != rule_inst_table->dead_negative_or_unit_clauses.tail;
	//		ptr = next_clause_ptr(ptr)) {
	//	cls = ptr->link;
	//	assert(cls->weight < 0 || cls->numlits == 1);
	//	if (cls->weight >= 0 && cls->numlits != 1) 
	//		return false;
	//}

	/* check that every watched clause is satisfied */
	for (i = 0; i < atom_table->num_vars; i++) {
		lit = pos_lit(i);
		valid_watched_lit(rule_inst_table, lit, atom_table);

		lit = neg_lit(i);
		valid_watched_lit(rule_inst_table, lit, atom_table);
	}

	/* check the sat_clauses to see if the first disjunct is fixed true */
	valid_clause_list(&rule_inst_table->sat_clauses);
	for (ptr = rule_inst_table->sat_clauses.head;
			ptr != rule_inst_table->sat_clauses.tail;
			ptr = next_clause_ptr(ptr)) {
		cls = ptr->link;
		assert(clause_contains_fixed_true_lit(cls, atom_table->assignment));
		if (!clause_contains_fixed_true_lit(cls, atom_table->assignment))
			return false;
	}
	
	/* check the live_clauses */
	valid_clause_list(&rule_inst_table->sat_clauses);

	/* check all the clauses to see if they are properly indexed */
	rule_inst_t *rinst;
	for (i = 0; i < rule_inst_table->num_rule_insts; i++){
		rinst = rule_inst_table->rule_insts[i];
		assert(rinst->num_clauses >= 0);
		if (rinst->num_clauses < 0) 
			return false;
		//for (j = 0; j < clause->numlits; j++){
		//	assert(var_of(clause->disjunct[j]) >= 0);
		//	assert(var_of(clause->disjunct[j]) < atom_table->num_vars);
		//	if (var_of(clause->disjunct[j]) < 0 ||
		//			var_of(clause->disjunct[j]) >= atom_table->num_vars)
		//		return false;
		//}
	}
	return true;
}