/* * 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); } }
/* * Returns if a clause contains a literal that is fixed to true */ static bool clause_contains_fixed_true_lit(samp_clause_t *clause, samp_truth_value_t *assignment) { int32_t i; for (i = 0; i < clause->num_lits; i++) { if (assigned_fixed_true_lit(assignment, clause->disjunct[i])) return true; } return false; }
/* * Checks the satisfiability of a clause * * if fixable, i.e., a fixed true literal or a unique non-fixed literal exists, * returns the index of the literal; * if unfixable, i.e., has at least two unfixed literals, returns -1; * if fixed unsat, returns -2. */ static int32_t get_fixable_literal( samp_truth_value_t *atom_assignment, samp_truth_value_t *rule_assignment, samp_clause_t *clause) { samp_literal_t *disjunct = clause->disjunct; int32_t num_lits = clause->num_lits; int32_t i, j; /* case 0: fixed sat */ /* if a rule is fixed false, its clauses should not be in the clause lists */ assert(!assigned_fixed_false(rule_assignment[clause->rule_index])); for (i = 0; i < num_lits; i++) { if (assigned_fixed_true_lit(atom_assignment, disjunct[i])) return i; } for (i = 0; i < num_lits; i++) { if (!assigned_fixed_false_lit(atom_assignment, disjunct[i])) break; } if (i == num_lits) { if (assigned_fixed_true(rule_assignment[clause->rule_index])) return -2; /* case 4: fixed unsat */ else return num_lits; /* the rule delegate literal is fixable */ } /* i is the first unfixed literal, now check if there is a second one */ for (j = i + 1; j < num_lits; j++) { if (!assigned_fixed_false_lit(atom_assignment, disjunct[j])) break; } /* there are at least two unfixed literals */ if (j < num_lits) { return -1; } else if (!fixed_tval(rule_assignment[clause->rule_index])) { return -1; } else { /* i is uniquely fixable */ return i; } }