/**Function******************************************************************** Synopsis [Adds a clause to the solver database.] Description [converts all CNF literals into the internal literals, adds a group id to every clause (if group is not permament) and then add obtained clauses to actual Minisat] SideEffects [] SeeAlso [] ******************************************************************************/ void sat_minisat_add(const SatSolver_ptr solver, const Be_Cnf_ptr cnfProb, SatSolverGroup group) { SatMinisat_ptr self = SAT_MINISAT(solver); int * clause = (int *)NULL; Siter genClause; int* minisatClause; /* just for efficiency */ const int groupIsNotPermanent = SatSolver_get_permanent_group(SAT_SOLVER(self)) != group; SAT_MINISAT_CHECK_INSTANCE(self); minisatClause = sat_minisat_get_minisatClause(self); SLIST_FOREACH (Be_Cnf_GetClausesList(cnfProb), genClause) { clause = (int*) Siter_element(genClause); int literal, i; int clause_size = _get_clause_size(clause); int literalNumber = 0; if (sat_minisat_get_minisatClauseSize(self) - 4 <= clause_size) { sat_minisat_enlarge_minisatClause(self, clause_size + 5); minisatClause = sat_minisat_get_minisatClause(self); } i = 0; while (clause[i] != 0) { literal = clause[i]; minisatClause[literalNumber] = sat_minisat_cnfLiteral2minisatLiteral(self, literal); ++literalNumber; i++; } if (groupIsNotPermanent) { /* add group id to the clause */ minisatClause[literalNumber] = group; ++literalNumber; } #ifdef MINISAT_WITH_PROOF_LOGGING /* add to real minisat */ MiniSat_Add_Clause(self->minisatSolver, minisatClause, literalNumber, SatSolver_curr_itp_group(solver)); #else MiniSat_Add_Clause(self->minisatSolver, minisatClause, literalNumber); #endif /* with the new interface of minisat there is not reason to remember that an unsatisfiable clause has been added to the solver */ } /* while() */
void Be_Cnf_PrintStat(const Be_Cnf_ptr self, FILE* outFile, char* prefix) { /* compute values */ int max_clause_size = 0; float sum_clause_size = 0; Siter cnf; nusmv_assert(self != (Be_Cnf_ptr)NULL); SLIST_FOREACH(Be_Cnf_GetClausesList(self), cnf) { int* clause = (int*)Siter_element(cnf); int clause_size; SLIST_CHECK_INSTANCE(Be_Cnf_GetClausesList(self)); for (clause_size = 0; clause[clause_size] != 0; ++clause_size) { } sum_clause_size += clause_size; if (clause_size > max_clause_size) max_clause_size = clause_size; }
void Be_Cnf_RemoveDuplicateLiterals(Be_Cnf_ptr self) { int i, j; Siter iter; int * clause = (int *)NULL; hash_ptr lits = (hash_ptr)NULL; nusmv_assert(self != NULL); lits = new_assoc(); for (iter = Slist_first(Be_Cnf_GetClausesList(self)); !Siter_is_end(iter); iter = Siter_next(iter)) { clause = (int*) Siter_element(iter); i = 0; while (clause[i] != 0) { if (Nil != find_assoc(lits, NODE_FROM_INT(clause[i]))) { j = i+1; while (clause[j] != 0) { clause[j-1] = clause[j]; j++; } } else { insert_assoc(lits, NODE_FROM_INT(clause[i]), NODE_FROM_INT(1)); } i++; } /* this clear the hash */ clear_assoc(lits); } free_assoc(lits); }
Trace_ptr Bmc_fill_trace_from_cnf_model(const BeEnc_ptr be_enc, const Slist_ptr cnf_model, int k, Trace_ptr trace) { TraceIter first; /* local refs */ const NuSMVEnv_ptr env = EnvObject_get_environment(ENV_OBJECT(be_enc)); const ExprMgr_ptr exprs = EXPR_MGR(NuSMVEnv_get_value(env, ENV_EXPR_MANAGER)); const BoolEnc_ptr bool_enc = \ BoolEncClient_get_bool_enc(BOOL_ENC_CLIENT(be_enc)); const NodeMgr_ptr nodemgr = NODE_MGR(NuSMVEnv_get_value(env, ENV_NODE_MGR)); const Be_Manager_ptr be_mgr = BeEnc_get_be_manager(be_enc); const SymbTable_ptr st = BaseEnc_get_symb_table(BASE_ENC(be_enc)); hash_ptr tvar_2_bval = new_assoc(); hash_ptr time_2_step = new_assoc(); Siter genLiteral; nusmv_ptrint cnfLiteral; nusmv_ptrint beLiteral; int i; TRACE_CHECK_INSTANCE(trace); nusmv_assert(Trace_is_empty(trace)); first = Trace_first_iter(trace); /* phase 0: setup trace iterators for all times */ insert_assoc(time_2_step, NODE_FROM_INT(0), (node_ptr)(first)); for (i = 1; i <= k; ++ i) { TraceIter step = Trace_append_step(trace); insert_assoc(time_2_step, NODE_FROM_INT(i), (node_ptr)(step)); } /* phase 1: we consider only the cnf variables corresponding to BE variables in the range [0, k]. Thus we ignore the cnf variables that are not corresponding to the encoding of the: - model variables; - encoding variables (sub formulas, loop variables, ...) */ SLIST_FOREACH(cnf_model, genLiteral) { int var_idx, ut_index, vtime; node_ptr var, key; cnfLiteral = (nusmv_ptrint) Siter_element(genLiteral); beLiteral = (nusmv_ptrint) Be_CnfLiteral2BeLiteral(be_mgr, cnfLiteral); /* if there is no corresponding rbc variable skip this */ if (0 == beLiteral) continue; /* get timed var */ var_idx = Be_BeLiteral2BeIndex(be_mgr, beLiteral); ut_index = BeEnc_index_to_untimed_index(be_enc, var_idx); vtime = BeEnc_index_to_time(be_enc, var_idx); var = BeEnc_index_to_name(be_enc, ut_index); /* needed to adapt to new trace timing format, input is stored in the next step */ if (SymbTable_is_symbol_input_var(st, var)) { ++ vtime; } if (vtime > k) continue; /* if it's a bit get/create a BitValues structure for the scalar variable which this bit belongs */ if (BoolEnc_is_var_bit(bool_enc, var)) { node_ptr scalar_var = BoolEnc_get_scalar_var_from_bit(bool_enc, var); BitValues_ptr bv; key = find_node(nodemgr, ATTIME, scalar_var, NODE_FROM_INT(vtime)); bv = BIT_VALUES(find_assoc(tvar_2_bval, key)); if (BIT_VALUES(NULL) == bv) { bv = BitValues_create(bool_enc, scalar_var); insert_assoc(tvar_2_bval, key, (node_ptr)(bv)); } /* set the bit value */ BitValues_set(bv, BoolEnc_get_index_from_bit(bool_enc, var), (beLiteral >= 0) ? BIT_VALUE_TRUE : BIT_VALUE_FALSE); } else { /* boolean variables do not require any further processing */ TraceIter timed_step = (-1 != vtime) /* frozenvars */ ? TRACE_ITER(find_assoc(time_2_step, NODE_FROM_INT(vtime))) : first ; nusmv_assert(TRACE_END_ITER != timed_step); Trace_step_put_value(trace, timed_step, var, beLiteral >= 0 ? ExprMgr_true(exprs) : ExprMgr_false(exprs)); } } /* SLIST_FOREACH (phase 1) */