12 template <
typename Ntk>
26 std::vector<int> vVars;
27 std::vector<int> vLits;
28 std::vector<VarValue> vValues;
35 double durationRedundancy;
36 double durationFeasibility;
39 void ActionCallback(
Action const &action);
42 void EncodeNode(
sat_solver *
p, std::vector<int>
const &v,
int id,
int to_negate = -1)
const;
43 void EncodeMiter(
sat_solver *
p, std::vector<int> &v,
int id);
44 void SetTarget(
int id);
57 std::vector<VarValue>
GetCex();
67 template <
typename Ntk>
68 void SatSolver<Ntk>::ActionCallback(
Action const &action) {
74 if(action.
id != target) {
82 if(action.
id == target) {
87 if(action.
id != target) {
119 template <
typename Ntk>
120 void SatSolver<Ntk>::EncodeNode(
sat_solver *
p, std::vector<int>
const &v,
int id,
int to_negate)
const {
123 bool cx =
false, cy =
false;
127 std::cout <<
"node " << std::setw(3) <<
id <<
": ";
129 pNtk->ForEachFanin(
id, [&](
int fi,
bool c) {
132 cx = c ^ (fi == to_negate);
135 cy = c ^ (fi == to_negate);
139 std::cout << delim << z <<
" = " << (cx?
"!":
"") << x <<
" & " << (cy?
"!":
"") << y << std::endl;
140 delim = std::string(10,
' ');
147 cy = c ^ (fi == to_negate);
152 std::cout << delim << v[id] <<
" = !0" << std::endl;
154 RetValue = sat_solver_add_const(
p, v[
id], 0);
158 std::cout << delim << v[id] <<
" = " << (cx?
"!":
"") << x << std::endl;
160 RetValue = sat_solver_add_buffer(
p, v[
id], x, cx);
164 std::cout << delim << v[id] <<
" = " << (cx?
"!":
"") << x <<
" & " << (cy?
"!":
"") << y << std::endl;
171 template <
typename Ntk>
172 void SatSolver<Ntk>::EncodeMiter(
sat_solver *
p, std::vector<int> &v,
int id) {
179 int nNodes = pNtk->GetNumNodes();
182 for(
int i = 0; i < nNodes; i++) {
186 RetValue = sat_solver_add_const(
p, v[0], 1);
190 std::cout <<
"encoding network" << std::endl;
192 pNtk->ForEachInt([&](
int id) {
193 EncodeNode(
p, v,
id);
196 if(pNtk->IsPoDriver(
id)) {
201 pNtk->ForEachPoDriver([&](
int fi) {
202 vLits.push_back(v[fi]);
206 std::cout <<
"encoding an inverted copy" << std::endl;
208 pNtk->ForEachTfo(
id,
false, [&](
int fo) {
210 EncodeNode(
p, v, fo,
id);
214 std::cout <<
"encoding miter xors" << std::endl;
218 pNtk->ForEachPoDriver([&](
int fi) {
220 if(v[fi] != vLits[idx]) {
223 std::cout << x <<
" = " << v[fi] <<
" ^ " << vLits[idx] << std::endl;
227 vLits[n] = toLitCond(x, 0);
235 std::cout <<
"adding miter output clause" << std::endl;
237 std::string delim =
"";
238 for(
int iLit: vLits) {
239 std::cout << delim << (lit_sign(iLit)?
"!":
"") << lit_var(iLit);
242 std::cout <<
")" << std::endl;
252 template <
typename Ntk>
253 void SatSolver<Ntk>::SetTarget(
int id) {
254 if(!fUpdate &&
id == target) {
259 EncodeMiter(pSat, vVars, target);
266 template <
typename Ntk>
269 nVerbose(pPar->nSatSolverVerbose),
270 nConflictLimit(pPar->nConflictLimit),
278 template <
typename Ntk>
284 template <
typename Ntk>
291 pNtk->AddCallback(std::bind(&SatSolver<Ntk>::ActionCallback,
this, std::placeholders::_1));
298 template <
typename Ntk>
304 std::cout <<
"trivially UNSATISFIABLE" << std::endl;
306 durationRedundancy += Duration(timeStart, GetCurrentTime());
311 pNtk->ForEachFaninIdx(
id, [&](
int idx2,
int fi,
bool c) {
313 vLits.push_back(toLitCond(vVars[fi], !c));
315 vLits.push_back(toLitCond(vVars[fi], c));
319 std::cout <<
"solving with assumptions: ";
320 std::string delim =
"";
321 for(
int iLit: vLits) {
322 std::cout << delim << (lit_sign(iLit)?
"!":
"") << lit_var(iLit);
325 std::cout << std::endl;
328 int res =
sat_solver_solve(pSat, vLits.data(), vLits.data() + vLits.size(), nConflictLimit, 0 , 0 , 0 );
331 std::cout <<
"UNSATISFIABLE" << std::endl;
334 durationRedundancy += Duration(timeStart, GetCurrentTime());
339 std::cout <<
"UNDETERMINED" << std::endl;
341 durationRedundancy += Duration(timeStart, GetCurrentTime());
346 std::cout <<
"SATISFIABLE" << std::endl;
350 vValues.resize(pNtk->GetNumNodes());
351 pNtk->ForEachPi([&](
int id) {
352 if(sat_solver_var_value(pSat, vVars[
id])) {
358 pNtk->ForEachInt([&](
int id) {
359 if(sat_solver_var_value(pSat, vVars[
id])) {
366 pNtk->ForEachFaninIdx(
id, [&](
int idx2,
int fi,
bool c) {
368 vValues[fi] = DecideVarValue(vValues[fi]);
370 durationRedundancy += Duration(timeStart, GetCurrentTime());
374 template <
typename Ntk>
380 std::cout <<
"trivially UNSATISFIABLE" << std::endl;
382 durationFeasibility += Duration(timeStart, GetCurrentTime());
387 vLits.push_back(toLit(vVars[
id]));
388 vLits.push_back(toLitCond(vVars[fi], !c));
390 std::cout <<
"solving with assumptions: ";
391 std::string delim =
"";
392 for(
int iLit: vLits) {
393 std::cout << delim << (lit_sign(iLit)?
"!":
"") << lit_var(iLit);
396 std::cout << std::endl;
399 int res =
sat_solver_solve(pSat, vLits.data(), vLits.data() + vLits.size(), nConflictLimit, 0 , 0 , 0 );
402 std::cout <<
"UNSATISFIABLE" << std::endl;
405 durationFeasibility += Duration(timeStart, GetCurrentTime());
410 std::cout <<
"UNDETERMINED" << std::endl;
412 durationFeasibility += Duration(timeStart, GetCurrentTime());
417 std::cout <<
"SATISFIABLE" << std::endl;
421 vValues.resize(pNtk->GetNumNodes());
422 pNtk->ForEachPi([&](
int id) {
423 if(sat_solver_var_value(pSat, vVars[
id])) {
429 pNtk->ForEachInt([&](
int id) {
430 if(sat_solver_var_value(pSat, vVars[
id])) {
438 vValues[id] = DecideVarValue(vValues[
id]);
440 vValues[fi] = DecideVarValue(vValues[fi]);
441 durationFeasibility += Duration(timeStart, GetCurrentTime());
449 template <
typename Ntk>
452 std::cout <<
"cex: ";
453 pNtk->ForEachPi([&](
int id) {
454 std::cout << GetVarValueChar(vValues[
id]);
456 std::cout << std::endl;
459 pNtk->ForEachIntReverse([&](
int id) {
460 switch(pNtk->GetNodeType(
id)) {
462 if(vValues[
id] ==
TRUE) {
463 pNtk->ForEachFanin(
id, [&](
int fi,
bool c) {
465 vValues[fi] = DecideVarValue(vValues[fi]);
467 }
else if(vValues[
id] ==
FALSE) {
469 pNtk->ForEachFanin(
id, [&](
int fi,
bool c) {
474 if(vValues[fi] ==
TRUE) {
478 if(vValues[fi] ==
FALSE) {
484 pNtk->ForEachFanin(
id, [&](
int fi,
bool c) {
491 vValues[fi] = DecideVarValue(vValues[fi]);
496 vValues[fi] = DecideVarValue(vValues[fi]);
508 std::cout <<
"pex: ";
509 pNtk->ForEachPi([&](
int id) {
510 std::cout << GetVarValueChar(vValues[
id]);
512 std::cout << std::endl;
515 pNtk->ForEachInt([&](
int id) {
516 switch(pNtk->GetNodeType(
id)) {
518 if(vValues[
id] ==
TRUE) {
519 pNtk->ForEachFanin(
id, [&](
int fi,
bool c) {
523 }
else if(vValues[
id] ==
FALSE) {
525 pNtk->ForEachFanin(
id, [&](
int fi,
bool c) {
530 if(vValues[fi] ==
TRUE) {
534 if(vValues[fi] ==
FALSE) {
547 std::vector<VarValue> vPartialCex;
548 pNtk->ForEachPi([&](
int id) {
549 if(vValues[
id] ==
TRUE || vValues[
id] ==
FALSE) {
550 vPartialCex.push_back(vValues[
id]);
552 vPartialCex.push_back(
UNDEF);
562 template <
typename Ntk>
567 durationRedundancy = 0;
568 durationFeasibility = 0;
571 template <
typename Ntk>
574 v.emplace_back(
"sat call", nCalls);
575 v.emplace_back(
"sat satisfiable", nSats);
576 v.emplace_back(
"sat unsatisfiable", nUnsats);
580 template <
typename Ntk>
583 v.emplace_back(
"sat redundancy", durationRedundancy);
584 v.emplace_back(
"sat feasibility", durationFeasibility);
#define ABC_NAMESPACE_CXX_HEADER_START
#define ABC_NAMESPACE_CXX_HEADER_END
#define sat_solver_addclause
#define sat_solver_addvar
#define sat_solver_add_and
#define sat_solver_add_xor
summary< int > GetStatsSummary() const
std::vector< VarValue > GetCex()
SatSolver(Parameter const *pPar)
SatResult CheckFeasibility(int id, int fi, bool c)
void AssignNetwork(Ntk *pNtk_, bool fReuse)
summary< double > GetTimesSummary() const
SatResult CheckRedundancy(int id, int idx)
std::vector< std::pair< std::string, T > > summary
std::chrono::time_point< clock_type > time_point
sat_solver * sat_solver_new(void)
void sat_solver_restart(sat_solver *s)
void sat_solver_setnvars(sat_solver *s, int n)
void sat_solver_delete(sat_solver *s)