//frees the SatState void sat_state_free(SatState* sat_state) { for (c2dSize i = 1; i <= sat_var_count(sat_state); i++) { Var* var = sat_index2var(i, sat_state); vector_free(&var->mentions); vector_free(&var->mentions_lc); free(var); free(sat_index2literal(i, sat_state)); free(sat_index2literal(-i, sat_state)); } for (c2dSize i = 1; i <= sat_clause_count(sat_state); i++) { Clause* clause = sat_index2clause(i, sat_state); vector_free(&clause->lits); free(clause); } vector_free(&sat_state->vars); vector_free(&sat_state->plits); vector_free(&sat_state->nlits); vector_free(&sat_state->kb); vector_free(&sat_state->lc); vector_free(&sat_state->ds); vector_free(&sat_state->il); vector_free(&sat_state->q); vector_free(&sat_state->s); free(sat_state); }
//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) { BOOLEAN more = 1; while (more) { more = 0; for (c2dSize i = vector_size(&sat_state->q); i >= 1; i--) { Clause* clause = vector_get(&sat_state->q, i - 1); clause->subsumed = sat_check_subsumed_clause(clause); if (sat_subsumed_clause(clause)) { vector_erase(&sat_state->q, i - 1); continue; } BOOLEAN flag = 0; c2dSize pos; for (c2dSize j = 0; j < sat_clause_size(clause); j++) { Lit* lit = vector_get(&clause->lits, j); if (!sat_implied_literal(sat_opp_literal(lit))) { flag++; pos = j; if (flag == 2) break; } } if (flag == 0) { sat_state->ac = malloc(sizeof(Clause)); vector_init(&sat_state->ac->lits); sat_state->ac->subsumed = 0; sat_state->ac->mark = 0; if (vector_size(&sat_state->ds) > 0) { for (c2dSize j = 0; j < sat_var_count(sat_state); j++) { Var* var = vector_get(&sat_state->vars, j); var->u = var->level <= 1; } sat_get_assert_clause(sat_state, sat_state->ac, clause->index - 1, 0, vector_size(&sat_state->s) - 1); } return 0; } if (flag == 1) { Lit* lit = vector_get(&clause->lits, pos); lit->implied = 1; lit->locate = clause->index - 1; lit->var->level = vector_size(&sat_state->ds) + 1; vector_push(&sat_state->il, lit); vector_push(&sat_state->s, lit); clause->subsumed = 1; vector_erase(&sat_state->q, i - 1); more = 1; } } } return 1; }
//returns a variable structure for the corresponding index Var* sat_index2var(c2dSize index, const SatState* sat_state) { ASSERT_TEST(index>=1 && index<=sat_var_count(sat_state)); //index range test return sat_state->variables[index-1]; }
//constructs a SatState from an input cnf file SatState* sat_state_new(const char* file_name) { FILE *file; if (!(file = fopen(file_name, "r"))) return NULL; SatState *sat_state = malloc(sizeof(SatState)); while (!feof(file)) { if (fgetc(file) == 'p') break; while (fgetc(file) != '\n') continue; } fscanf(file, " cnf %lu %lu", &sat_state->varnum, &sat_state->clausenum); vector_init(&sat_state->vars); vector_init(&sat_state->plits); vector_init(&sat_state->nlits); vector_init(&sat_state->kb); vector_init(&sat_state->lc); vector_init(&sat_state->ds); vector_init(&sat_state->il); vector_init(&sat_state->q); vector_init(&sat_state->s); sat_state->ac = NULL; for (c2dSize i = 1; i <= sat_var_count(sat_state); i++) { Var* var = malloc(sizeof(Var)); var->index = i; var->mark = 0; vector_init(&var->mentions); vector_init(&var->mentions_lc); Lit* plit = malloc(sizeof(Lit)); plit->index = i; plit->implied = 0; plit->var = var; Lit* nlit = malloc(sizeof(Lit)); nlit->index = -i; nlit->implied = 0; nlit->var = var; vector_push(&sat_state->plits, plit); vector_push(&sat_state->nlits, nlit); var->plit = plit; var->nlit = nlit; vector_push(&sat_state->vars, var); } for (c2dSize i = 1; i <= sat_clause_count(sat_state); i++) { Clause* clause = malloc(sizeof(Clause)); clause->index = i; clause->subsumed = 0; clause->mark = 0; vector_init(&clause->lits); while (1) { c2dLiteral index; while (!fscanf(file, "%ld", &index) || (index == 0 && vector_size(&clause->lits) == 0)) { while (fgetc(file) != '\n') continue; } if (index == 0) break; vector_push(&clause->lits, sat_index2literal(index, sat_state)); } vector_push(&sat_state->kb, clause); vector_push(&sat_state->q, clause); } for (c2dSize i = 1; i <= sat_clause_count(sat_state); i++) { Clause* clause = sat_index2clause(i, sat_state); for (c2dSize j = 0; j < sat_clause_size(clause); j++) { Lit* lit = vector_get(&clause->lits, j); Var* var = sat_literal_var(lit); if (vector_size(&var->mentions) == 0 || vector_top(&var->mentions) != clause) vector_push(&var->mentions, clause); } } fclose(file); return sat_state; }