210 std::vector<var> vVars;
211 std::vector<var> Var2Level;
212 std::vector<var> Level2Var;
213 std::vector<lit> vObjs;
214 std::vector<bvar> vNexts;
215 std::vector<bool> vMarks;
216 std::vector<ref> vRefs;
217 std::vector<edge> vEdges;
218 std::vector<double> vOneCounts;
219 std::vector<uniq> vUniqueMasks;
220 std::vector<bvar> vUniqueCounts;
221 std::vector<bvar> vUniqueTholds;
222 std::vector<std::vector<bvar> > vvUnique;
250 if(vOneCounts.empty())
251 fatal_error(
"fCountOnes was not set");
253 return std::pow(2.0, nVars) - vOneCounts[
Lit2Bvar(x)];
262 inline bool Mark(
lit x)
const {
return vMarks[
Lit2Bvar(x)]; }
264 inline void SetMark(
lit x) { vMarks[
Lit2Bvar(x)] =
true; }
265 inline void ResetMark(
lit x) { vMarks[
Lit2Bvar(x)] =
false; }
266 inline void IncEdge(
lit x) { vEdges[
Lit2Bvar(x)]++; }
267 inline void DecEdge(
lit x) { vEdges[
Lit2Bvar(x)]--; }
268 inline bool MarkOfBvar(
bvar a)
const {
return vMarks[a]; }
269 inline edge EdgeOfBvar(
bvar a)
const {
return vEdges[a]; }
270 inline void SetVarOfBvar(
bvar a,
var v) { vVars[a] = v; }
272 inline void SetElseOfBvar(
bvar a,
lit x) { vObjs[
Bvar2Lit(a,
true)] = x; }
273 inline void SetMarkOfBvar(
bvar a) { vMarks[a] =
true; }
274 inline void ResetMarkOfBvar(
bvar a) { vMarks[a] =
false; }
275 inline void RemoveBvar(
bvar a) {
277 SetVarOfBvar(a, VarMax());
278 std::vector<bvar>::iterator q = vvUnique[v].begin() + (UniqHash(
ThenOfBvar(a),
ElseOfBvar(a)) & vUniqueMasks[v]);
279 for(; *q; q = vNexts.begin() + *q)
282 bvar next = vNexts[*q];
283 vNexts[*q] = RemovedHead;
290 void SetMark_rec(
lit x) {
294 SetMark_rec(
Then(x));
295 SetMark_rec(
Else(x));
297 void ResetMark_rec(
lit x) {
298 if(x < 2 || !Mark(x))
301 ResetMark_rec(
Then(x));
302 ResetMark_rec(
Else(x));
308 return 1 + CountNodes_rec(
Then(x)) + CountNodes_rec(
Else(x));
310 void CountEdges_rec(
lit x) {
317 CountEdges_rec(
Then(x));
318 CountEdges_rec(
Else(x));
321 vEdges.resize(nObjsAlloc);
322 for(
bvar a = (
bvar)nVars + 1; a < nObjs; a++)
325 for(
bvar a = 1; a <= (
bvar)nVars; a++)
327 for(
bvar a = (
bvar)nVars + 1; a < nObjs; a++)
334 if(nObjsAlloc == nObjsMax)
336 lit nObjsAllocLit = (
lit)nObjsAlloc << 1;
337 if(nObjsAllocLit > (
lit)BvarMax())
338 nObjsAlloc = BvarMax();
340 nObjsAlloc = (
bvar)nObjsAllocLit;
342 std::cout <<
"Reallocating " << nObjsAlloc <<
" nodes" << std::endl;
343 vVars.resize(nObjsAlloc);
344 vObjs.resize((
lit)nObjsAlloc * 2);
345 vNexts.resize(nObjsAlloc);
346 vMarks.resize(nObjsAlloc);
348 vRefs.resize(nObjsAlloc);
350 vEdges.resize(nObjsAlloc);
351 if(!vOneCounts.empty())
352 vOneCounts.resize(nObjsAlloc);
356 uniq nUniqueSize, nUniqueSizeOld;
357 nUniqueSize = nUniqueSizeOld = vvUnique[v].size();
360 vUniqueTholds[v] = BvarMax();
364 std::cout <<
"Reallocating " << nUniqueSize <<
" unique table entries for Var " << v << std::endl;
365 vvUnique[v].resize(nUniqueSize);
366 vUniqueMasks[v] = nUniqueSize - 1;
367 for(
uniq i = 0; i < nUniqueSizeOld; i++) {
368 std::vector<bvar>::iterator q, tail, tail1, tail2;
369 q = tail1 = vvUnique[v].begin() + i;
370 tail2 = q + nUniqueSizeOld;
379 q = vNexts.begin() + *tail;
386 vUniqueTholds[v] <<= 1;
387 if((
lit)vUniqueTholds[v] > (
lit)BvarMax())
388 vUniqueTholds[v] = BvarMax();
392 std::cout <<
"Garbage collect" << std::endl;
393 if(!vEdges.empty()) {
394 for(
bvar a = (
bvar)nVars + 1; a < nObjs; a++)
395 if(!EdgeOfBvar(a) &&
VarOfBvar(a) != VarMax())
398 for(
bvar a = (
bvar)nVars + 1; a < nObjs; a++)
401 for(
bvar a = (
bvar)nVars + 1; a < nObjs; a++)
402 if(!MarkOfBvar(a) &&
VarOfBvar(a) != VarMax())
404 for(
bvar a = (
bvar)nVars + 1; a < nObjs; a++)
414 std::vector<bvar>::iterator
p, q;
415 p = q = vvUnique[v].begin() + (UniqHash(x1, x0) & vUniqueMasks[v]);
416 for(; *q; q = vNexts.begin() + *q)
420 if(nObjs < nObjsAlloc)
423 *
p = RemovedHead, RemovedHead = vNexts[*
p];
427 SetThenOfBvar(*
p, x1);
428 SetElseOfBvar(*
p, x0);
430 if(!vOneCounts.empty())
433 std::cout <<
"Create node " << std::setw(10) << *
p <<
": "
434 <<
"Var = " << std::setw(6) << v <<
", "
435 <<
"Then = " << std::setw(10) << x1 <<
", "
436 <<
"Else = " << std::setw(10) << x0;
437 if(!vOneCounts.empty())
438 std::cout <<
", Ones = " << std::setw(10) << vOneCounts[*q];
439 std::cout << std::endl;
442 if(vUniqueCounts[v] > vUniqueTholds[v]) {
455 x = UniqueCreateInt(v, x1, x0);
459 bool fRemoved =
false;
462 if(!
Resize() && !fRemoved && (nGbc != 1 || !
Gbc()))
463 fatal_error(
"Memout (node)");
475 return (x == y)? x: 0;
478 lit z = cache->Lookup(x, y);
484 v =
Var(x), x1 =
Then(x), x0 =
Else(x), y0 = y1 = y;
486 v =
Var(y), x0 = x1 = x, y1 =
Then(y), y0 =
Else(y);
489 lit z1 = And_rec(x1, y1);
491 lit z0 = And_rec(x0, y0);
493 z = UniqueCreate(v,
z1,
z0);
496 cache->Insert(x, y, z);
502 var v1 = Level2Var[i];
503 var v2 = Level2Var[i + 1];
506 for(std::vector<bvar>::iterator
p = vvUnique[v1].begin();
p != vvUnique[v1].end();
p++) {
507 std::vector<bvar>::iterator q =
p;
509 if(!EdgeOfBvar(*q)) {
510 SetVarOfBvar(*q, VarMax());
511 bvar next = vNexts[*q];
512 vNexts[*q] = RemovedHead;
520 if(
Var(f1) == v2 ||
Var(f0) == v2) {
522 if(
Var(f1) == v2 && !Edge(f1))
523 DecEdge(
Then(f1)), DecEdge(
Else(f1)), diff--;
525 if(
Var(f0) == v2 && !Edge(f0))
526 DecEdge(
Then(f0)), DecEdge(
Else(f0)), diff--;
527 bvar next = vNexts[*q];
534 q = vNexts.begin() + *q;
540 lit f00, f01, f10, f11;
552 f1 = UniqueCreate(v1, f11, f01);
554 IncEdge(f11), IncEdge(f01), diff++;
561 f0 = UniqueCreate(v1, f10, f00);
563 IncEdge(f10), IncEdge(f00), diff++;
568 SetThenOfBvar(f, f1);
569 SetElseOfBvar(f, f0);
570 std::vector<bvar>::iterator q = vvUnique[v2].begin() + (UniqHash(f1, f0) & vUniqueMasks[v2]);
571 lit next = vNexts[f];
577 Var2Level[v1] = i + 1;
580 Level2Var[i + 1] = v1;
585 std::vector<var> sift_order(nVars);
586 for(
var v = 0; v < nVars; v++)
588 for(
var i = 0; i < nVars; i++) {
590 for(
var j = i + 1; j < nVars; j++)
591 if(vUniqueCounts[sift_order[j]] > vUniqueCounts[sift_order[max_j]])
594 std::swap(sift_order[max_j], sift_order[i]);
596 for(
var v = 0; v < nVars; v++) {
597 bvar lev = Var2Level[sift_order[v]];
598 bool UpFirst = lev < (
bvar)(nVars / 2);
602 bvar thold = count * (MaxGrowth - 1);
604 std::cout <<
"Sift " << sift_order[v] <<
" : Level = " << lev <<
" Count = " << count <<
" Thold = " << thold << std::endl;
607 for(; lev >= 0; lev--) {
610 std::cout <<
"\tSwap " << lev <<
" : Diff = " << diff <<
" Thold = " << thold << std::endl;
612 min_lev = lev, min_diff = diff, thold = (count + diff) * (MaxGrowth - 1);
613 else if(diff > thold) {
620 for(; lev < (
bvar)nVars - 1; lev++) {
623 std::cout <<
"\tSwap " << lev <<
" : Diff = " << diff <<
" Thold = " << thold << std::endl;
625 min_lev = lev + 1, min_diff = diff, thold = (count + diff) * (MaxGrowth - 1);
626 else if(diff > thold) {
633 for(; lev >= min_lev; lev--) {
636 std::cout <<
"\tSwap " << lev <<
" : Diff = " << diff <<
" Thold = " << thold << std::endl;
639 for(; lev >= 0; lev--) {
642 std::cout <<
"\tSwap " << lev <<
" : Diff = " << diff <<
" Thold = " << thold << std::endl;
644 min_lev = lev, min_diff = diff, thold = (count + diff) * (MaxGrowth - 1);
645 else if(diff > thold) {
651 for(; lev < min_lev; lev++) {
654 std::cout <<
"\tSwap " << lev <<
" : Diff = " << diff <<
" Thold = " << thold << std::endl;
659 std::cout <<
"Sifted " << sift_order[v] <<
" : Level = " << min_lev <<
" Count = " << count <<
" Thold = " << thold << std::endl;
665 nVerbose =
p.nVerbose;
667 if(
p.nObjsMaxLog <
p.nObjsAllocLog)
668 fatal_error(
"nObjsMax must not be smaller than nObjsAlloc");
669 if(nVars_ >= (
int)VarMax())
670 fatal_error(
"Memout (nVars) in init");
672 lit nObjsMaxLit = (
lit)1 <<
p.nObjsMaxLog;
674 fatal_error(
"Memout (nObjsMax) in init");
675 if(nObjsMaxLit > (
lit)BvarMax())
676 nObjsMax = BvarMax();
678 nObjsMax = (
bvar)nObjsMaxLit;
679 lit nObjsAllocLit = (
lit)1 <<
p.nObjsAllocLog;
681 fatal_error(
"Memout (nObjsAlloc) in init");
682 if(nObjsAllocLit > (
lit)BvarMax())
683 nObjsAlloc = BvarMax();
685 nObjsAlloc = (
bvar)nObjsAllocLit;
686 if(nObjsAlloc <= (
bvar)nVars)
687 fatal_error(
"nObjsAlloc must be larger than nVars");
688 uniq nUniqueSize = (
uniq)1 <<
p.nUniqueSizeLog;
690 fatal_error(
"Memout (nUniqueSize) in init");
693 std::cout <<
"Allocating " << nObjsAlloc <<
" nodes and " << nVars <<
" x " << nUniqueSize <<
" unique table entries" << std::endl;
694 vVars.resize(nObjsAlloc);
695 vObjs.resize((
lit)nObjsAlloc * 2);
696 vNexts.resize(nObjsAlloc);
697 vMarks.resize(nObjsAlloc);
698 vvUnique.resize(nVars);
699 vUniqueMasks.resize(nVars);
700 vUniqueCounts.resize(nVars);
701 vUniqueTholds.resize(nVars);
702 for(
var v = 0; v < nVars; v++) {
703 vvUnique[v].resize(nUniqueSize);
704 vUniqueMasks[v] = nUniqueSize - 1;
705 if((
lit)(nUniqueSize *
p.UniqueDensity) > (
lit)BvarMax())
706 vUniqueTholds[v] = BvarMax();
708 vUniqueTholds[v] = (
bvar)(nUniqueSize *
p.UniqueDensity);
712 fatal_error(
"nVars must be less than 1024 to count ones");
713 vOneCounts.resize(nObjsAlloc);
716 cache =
new Cache(
p.nCacheSizeLog,
p.nCacheMaxLog,
p.nCacheVerbose);
720 for(
var v = 0; v < nVars; v++)
721 UniqueCreateInt(v, 1, 0);
723 Var2Level.resize(nVars);
724 Level2Var.resize(nVars);
725 for(
var v = 0; v < nVars; v++) {
727 Var2Level[v] = (*
p.pVar2Level)[v];
730 Level2Var[Var2Level[v]] = v;
736 MaxGrowth =
p.MaxGrowth;
737 fReoVerbose =
p.fReoVerbose;
738 if(nGbc || nReo != BvarMax())
739 vRefs.resize(nObjsAlloc);
743 std::cout <<
"Free " << nObjsAlloc <<
" nodes (" << nObjs <<
" live nodes)" << std::endl;
744 std::cout <<
"Free {";
746 for(
var v = 0; v < nVars; v++) {
747 std::cout << delim << vvUnique[v].size();
750 std::cout <<
"} unique table entries" << std::endl;
752 std::cout <<
"Free " << vRefs.size() <<
" refs" << std::endl;
758 std::cout <<
"Reorder" << std::endl;
770 while(nReo < nObjs) {
772 if((
lit)nReo > (
lit)BvarMax())
776 return And_rec(x, y);
783 void SetRef(std::vector<lit>
const &vLits) {
785 vRefs.resize(nObjsAlloc);
786 for(
size_t i = 0; i < vLits.size(); i++)
790 if(!nGbc && nReo == BvarMax())
793 void TurnOnReo(
int nReo_ = 0, std::vector<lit>
const *vLits = NULL) {
798 if((
lit)nReo > (
lit)BvarMax())
804 vRefs.resize(nObjsAlloc);
814 Var2Level_.resize(nVars);
815 for(
var v = 0; v < nVars; v++)
816 Var2Level_[v] = Var2Level[v];
820 if(!vEdges.empty()) {
821 for(
bvar a = 1; a < nObjs; a++)
826 for(
bvar a = 1; a <= (
bvar)nVars; a++) {
830 for(
bvar a = (
bvar)nVars + 1; a < nObjs; a++)
832 count += CountNodes_rec(
Bvar2Lit(a));
833 for(
bvar a = 1; a <= (
bvar)nVars; a++)
835 for(
bvar a = (
bvar)nVars + 1; a < nObjs; a++)
842 for(
size_t i = 0; i < vLits.size(); i++)
843 count += CountNodes_rec(vLits[i]);
844 for(
size_t i = 0; i < vLits.size(); i++)
845 ResetMark_rec(vLits[i]);
850 bvar a = RemovedHead;
852 a = vNexts[a], nRemoved++;
854 for(
var v = 0; v < nVars; v++)
855 nLive += vUniqueCounts[v];
856 std::cout <<
"ref: " << std::setw(10) << (vRefs.empty()? 0:
CountNodes()) <<
", "
857 <<
"used: " << std::setw(10) << nObjs <<
", "
858 <<
"live: " << std::setw(10) << nLive <<
", "
859 <<
"dead: " << std::setw(10) << nRemoved <<
", "
860 <<
"alloc: " << std::setw(10) << nObjsAlloc