void clause_list_concat(samp_clause_list_t *list_src, samp_clause_list_t *list_dst) { assert(valid_clause_list(list_src)); assert(valid_clause_list(list_dst)); list_dst->tail->link = list_src->head->link; if (!is_empty_clause_list(list_src)) { list_dst->tail = list_src->tail; } list_dst->length += list_src->length; list_src->head->link = NULL; list_src->tail = list_src->head; list_src->length = 0; assert(valid_clause_list(list_src)); assert(valid_clause_list(list_dst)); }
static bool valid_watched_lit(rule_inst_table_t *rule_inst_table, samp_literal_t lit, atom_table_t *atom_table) { valid_clause_list(&rule_inst_table->watched[lit]); bool lit_true = (is_pos(lit) && assigned_true(atom_table->assignment[var_of(lit)])) || (is_neg(lit) && assigned_false(atom_table->assignment[var_of(lit)])); assert(is_empty_clause_list(&rule_inst_table->watched[lit]) || lit_true); if (!is_empty_clause_list(&rule_inst_table->watched[lit]) && !lit_true) { return false; } samp_clause_t *ptr; samp_clause_t *cls; for (ptr = rule_inst_table->watched[lit].head; ptr != rule_inst_table->watched[lit].tail; ptr = next_clause_ptr(ptr)) { cls = ptr->link; assert(clause_contains_lit(cls, lit)); if (!clause_contains_lit(cls, lit)) return false; } return true; }
/* * Propagates a truth assignment on a link of watched clauses for a literal * that has been assigned false. All the literals are assumed to have truth * values. The watched literal points to a true literal if there is one in * the clause. Whenever a watched literal is assigned false, the * propagation must find a new true literal, or retain the existing one. If * a clause is falsified, its weight is added to the delta cost. The * clauses containing the negation of the literal must be reevaluated and * assigned true if previously false. */ static void link_propagate(samp_table_t *table, samp_literal_t lit) { rule_inst_table_t *rule_inst_table = &table->rule_inst_table; #ifndef NDEBUG atom_table_t *atom_table = &table->atom_table; #endif /* the assignment of the lit has just changed to false */ assert(assigned_false_lit(atom_table->assignment, lit)); /* since the assignment of the lit was true, the negate of the lit * should have an empty watched list */ assert(is_empty_clause_list(&rule_inst_table->watched[not(lit)])); /* watched list of lit needs to be rescaned */ clause_list_concat(&rule_inst_table->watched[lit], &rule_inst_table->live_clauses); /* unsat clause list is dirty, need to rescan */ clause_list_concat(&rule_inst_table->unsat_clauses, &rule_inst_table->live_clauses); }