bool context::check_clauses(clause_vector const & v) const { clause_vector::const_iterator it = v.begin(); clause_vector::const_iterator end = v.end(); for (; it != end; ++it) { clause * cls = *it; if (!cls->deleted()) check_clause(cls); } return true; }
//applies unit resolution to the cnf of sat state //returns 1 if unit resolution succeeds, 0 if it finds a contradiction BOOLEAN sat_unit_resolution(SatState* sat_state) { Lit* ret_lit; Var* var; c2dLiteral tmp_value; Clause* conflict_clause = NULL; c2dSize f = 0, r = 0; Lit** tmp_lit_list = sat_state->tmp_lit_list; // Push the new decided literal if (sat_state->unit_resolution_s == UNIT_RESOLUTION_AFTER_DECIDING_LITERAL) { if (sat_state->num_decided_literals > 0) { tmp_lit_list[++r] = sat_state->decided_literals[sat_state->num_decided_literals-1]; } if (sat_state->num_implied_literals > 0) { c2dSize i = sat_state->num_implied_literals - 1; while (sat_state->implied_literals[i]->decision_level == sat_state->cur_level) { tmp_lit_list[++r] = sat_state->implied_literals[i]; if (i == 0) break; i--; } } } // Check whether has unit clause c2dSize start_clauses = 1; if (sat_state->unit_resolution_s == UNIT_RESOLUTION_AFTER_ASSERTING_CLAUSE) start_clauses = sat_state->num_cnf_clauses + sat_state->num_learned_clauses; if (sat_state->unit_resolution_s == UNIT_RESOLUTION_AFTER_DECIDING_LITERAL) start_clauses = sat_state->num_cnf_clauses + sat_state->num_learned_clauses + 1; for (c2dSize i = start_clauses; i <= sat_state->num_cnf_clauses + sat_state->num_learned_clauses; i++) { Clause* clause = sat_index2clause(i, sat_state); tmp_value = check_clause(clause, &ret_lit); if (tmp_value == -1) { conflict_clause = clause; break; } if (tmp_value == 2) { instantiate_literal(ret_lit, sat_state->cur_level, clause); sat_state->implied_literals[sat_state->num_implied_literals++] = ret_lit; tmp_lit_list[++r] = ret_lit; } } if (conflict_clause == NULL) { // BFS, expands the implied literals while (f < r) { var = sat_literal_var(tmp_lit_list[++f]); for (c2dSize i = 0; i < var->num_clauses; i++) { tmp_value = check_clause(var->clauses[i], &ret_lit); if (tmp_value == -1) { conflict_clause = var->clauses[i]; break; } if (tmp_value == 2) { instantiate_literal(ret_lit, sat_state->cur_level, var->clauses[i]); sat_state->implied_literals[sat_state->num_implied_literals++] = ret_lit; tmp_lit_list[++r] = ret_lit; } } } } if (conflict_clause == NULL) { // No conflict sat_state->asserted_clause = NULL; return 1; } // Has conflict, derives asserted clause // // It follows the algorithm: // // In implication graph, if the contradition happended at node n. // then // { {n} if n is root // C(n) = { // { ePa(n) \union \union_{m \in Pa(n)} C(m) // where Pa(n) are the parents of node n which are set at the same level as n // ePa(n) are the parents of ndoe n set at earlier levels // BOOLEAN* seen = sat_state->seen; for (c2dSize i = 1; i <= sat_state->num_vars; i++) seen[i] = 0; Lit** lit_list = sat_state->lit_list; c2dSize lit_list_sz = 0; f = 0, r = 0; for (c2dSize i = 0; i < conflict_clause->size; i++) { if (!seen[conflict_clause->literals[i]->var->index]) { tmp_lit_list[++r] = conflict_clause->literals[i]->op_lit; seen[conflict_clause->literals[i]->var->index] = 1; } } c2dSize assertion_level = 1; c2dSize dl; while (f < r) { Lit* lit = tmp_lit_list[++f]; if (lit->decision_level < sat_state->cur_level || lit->decision_clause == NULL) { lit_list[lit_list_sz++] = lit->op_lit; dl = lit->decision_level; if (dl < sat_state->cur_level && dl > assertion_level) { assertion_level = dl; } } else { for (c2dSize i = 0; i < lit->decision_clause->size; i++) { if (!seen[lit->decision_clause->literals[i]->var->index]) { tmp_lit_list[++r] = lit->decision_clause->literals[i]->op_lit; seen[lit->decision_clause->literals[i]->var->index] = 1; } } } } sat_state->asserted_clause = new_clause(0, lit_list_sz, lit_list); sat_state->asserted_clause->assertion_level = assertion_level; return 0; }