184 unsigned long long nCreatedTotal;
191 std::vector<var> vVars;
192 std::vector<var> Var2Level;
193 std::vector<var> Level2Var;
194 std::vector<lit> vObjs;
195 std::vector<bvar> vNexts;
196 std::vector<bool> vMarks;
197 std::vector<ref> vRefs;
198 std::vector<edge> vEdges;
199 std::vector<double> vOneCounts;
200 std::vector<uniq> vUniqueMasks;
201 std::vector<bvar> vUniqueCounts;
202 std::vector<bvar> vUniqueTholds;
203 std::vector<std::vector<bvar> > vvUnique;
231 if(vOneCounts.empty())
232 fatal_error(
"fCountOnes was not set");
234 return std::pow(2.0, nVars) - vOneCounts[
Lit2Bvar(x)];
243 inline bool Mark(
lit x)
const {
return vMarks[
Lit2Bvar(x)]; }
245 inline void SetMark(
lit x) { vMarks[
Lit2Bvar(x)] =
true; }
246 inline void ResetMark(
lit x) { vMarks[
Lit2Bvar(x)] =
false; }
247 inline void IncEdge(
lit x) { vEdges[
Lit2Bvar(x)]++; }
248 inline void DecEdge(
lit x) { vEdges[
Lit2Bvar(x)]--; }
249 inline bool MarkOfBvar(
bvar a)
const {
return vMarks[a]; }
250 inline edge EdgeOfBvar(
bvar a)
const {
return vEdges[a]; }
251 inline void SetVarOfBvar(
bvar a,
var v) { vVars[a] = v; }
253 inline void SetElseOfBvar(
bvar a,
lit x) { vObjs[
Bvar2Lit(a,
true)] = x; }
254 inline void SetMarkOfBvar(
bvar a) { vMarks[a] =
true; }
255 inline void ResetMarkOfBvar(
bvar a) { vMarks[a] =
false; }
256 inline void RemoveBvar(
bvar a) {
258 SetVarOfBvar(a, VarMax());
259 std::vector<bvar>::iterator q = vvUnique[v].begin() + (UniqHash(
ThenOfBvar(a),
ElseOfBvar(a)) & vUniqueMasks[v]);
260 for(; *q; q = vNexts.begin() + *q)
263 bvar next = vNexts[*q];
264 vNexts[*q] = RemovedHead;
271 void SetMark_rec(
lit x) {
275 SetMark_rec(
Then(x));
276 SetMark_rec(
Else(x));
278 void ResetMark_rec(
lit x) {
279 if(x < 2 || !Mark(x))
282 ResetMark_rec(
Then(x));
283 ResetMark_rec(
Else(x));
289 return 1 + CountNodes_rec(
Then(x)) + CountNodes_rec(
Else(x));
291 void CountEdges_rec(
lit x) {
298 CountEdges_rec(
Then(x));
299 CountEdges_rec(
Else(x));
302 vEdges.resize(nObjsAlloc);
303 for(
bvar a = (
bvar)nVars + 1; a < nObjs; a++)
306 for(
bvar a = 1; a <= (
bvar)nVars; a++)
308 for(
bvar a = (
bvar)nVars + 1; a < nObjs; a++)
315 if(nObjsAlloc == nObjsMax)
317 lit nObjsAllocLit = (
lit)nObjsAlloc << 1;
318 if(nObjsAllocLit > (
lit)BvarMax())
319 nObjsAlloc = BvarMax();
321 nObjsAlloc = (
bvar)nObjsAllocLit;
323 std::cout <<
"Reallocating " << nObjsAlloc <<
" nodes" << std::endl;
324 vVars.resize(nObjsAlloc);
325 vObjs.resize((
lit)nObjsAlloc * 2);
326 vNexts.resize(nObjsAlloc);
327 vMarks.resize(nObjsAlloc);
329 vRefs.resize(nObjsAlloc);
331 vEdges.resize(nObjsAlloc);
332 if(!vOneCounts.empty())
333 vOneCounts.resize(nObjsAlloc);
337 uniq nUniqueSize, nUniqueSizeOld;
338 nUniqueSize = nUniqueSizeOld = vvUnique[v].size();
341 vUniqueTholds[v] = BvarMax();
345 std::cout <<
"Reallocating " << nUniqueSize <<
" unique table entries for Var " << v << std::endl;
346 vvUnique[v].resize(nUniqueSize);
347 vUniqueMasks[v] = nUniqueSize - 1;
348 for(
uniq i = 0; i < nUniqueSizeOld; i++) {
349 std::vector<bvar>::iterator q, tail, tail1, tail2;
350 q = tail1 = vvUnique[v].begin() + i;
351 tail2 = q + nUniqueSizeOld;
360 q = vNexts.begin() + *tail;
367 vUniqueTholds[v] <<= 1;
368 if((
lit)vUniqueTholds[v] > (
lit)BvarMax())
369 vUniqueTholds[v] = BvarMax();
373 std::cout <<
"Garbage collect" << std::endl;
374 if(!vEdges.empty()) {
375 for(
bvar a = (
bvar)nVars + 1; a < nObjs; a++)
376 if(!EdgeOfBvar(a) &&
VarOfBvar(a) != VarMax())
379 for(
bvar a = (
bvar)nVars + 1; a < nObjs; a++)
382 for(
bvar a = (
bvar)nVars + 1; a < nObjs; a++)
383 if(!MarkOfBvar(a) &&
VarOfBvar(a) != VarMax())
385 for(
bvar a = (
bvar)nVars + 1; a < nObjs; a++)
395 std::vector<bvar>::iterator
p, q;
396 p = q = vvUnique[v].begin() + (UniqHash(x1, x0) & vUniqueMasks[v]);
397 for(; *q; q = vNexts.begin() + *q)
402 if(nObjs < nObjsAlloc)
405 *
p = RemovedHead, RemovedHead = vNexts[*
p];
409 SetThenOfBvar(*
p, x1);
410 SetElseOfBvar(*
p, x0);
412 if(!vOneCounts.empty())
415 std::cout <<
"Create node " << std::setw(10) << *
p <<
": "
416 <<
"Var = " << std::setw(6) << v <<
", "
417 <<
"Then = " << std::setw(10) << x1 <<
", "
418 <<
"Else = " << std::setw(10) << x0;
419 if(!vOneCounts.empty())
420 std::cout <<
", Ones = " << std::setw(10) << vOneCounts[*q];
421 std::cout << std::endl;
424 if(vUniqueCounts[v] > vUniqueTholds[v]) {
437 x = UniqueCreateInt(v, x1, x0);
441 bool fRemoved =
false;
444 if(!
Resize() && !fRemoved && (nGbc != 1 || !
Gbc()))
445 fatal_error(
"Memout (node)");
457 return (x == y)? x: 0;
460 lit z = cache->Lookup(x, y);
466 v =
Var(x), x1 =
Then(x), x0 =
Else(x), y0 = y1 = y;
468 v =
Var(y), x0 = x1 = x, y1 =
Then(y), y0 =
Else(y);
471 lit z1 = And_rec(x1, y1);
473 lit z0 = And_rec(x0, y0);
475 z = UniqueCreate(v,
z1,
z0);
478 cache->Insert(x, y, z);
484 var v1 = Level2Var[i];
485 var v2 = Level2Var[i + 1];
488 for(std::vector<bvar>::iterator
p = vvUnique[v1].begin();
p != vvUnique[v1].end();
p++) {
489 std::vector<bvar>::iterator q =
p;
491 if(!EdgeOfBvar(*q)) {
492 SetVarOfBvar(*q, VarMax());
493 bvar next = vNexts[*q];
494 vNexts[*q] = RemovedHead;
502 if(
Var(f1) == v2 ||
Var(f0) == v2) {
504 if(
Var(f1) == v2 && !Edge(f1))
505 DecEdge(
Then(f1)), DecEdge(
Else(f1)), diff--;
507 if(
Var(f0) == v2 && !Edge(f0))
508 DecEdge(
Then(f0)), DecEdge(
Else(f0)), diff--;
509 bvar next = vNexts[*q];
516 q = vNexts.begin() + *q;
522 lit f00, f01, f10, f11;
534 f1 = UniqueCreate(v1, f11, f01);
536 IncEdge(f11), IncEdge(f01), diff++;
543 f0 = UniqueCreate(v1, f10, f00);
545 IncEdge(f10), IncEdge(f00), diff++;
550 SetThenOfBvar(f, f1);
551 SetElseOfBvar(f, f0);
552 std::vector<bvar>::iterator q = vvUnique[v2].begin() + (UniqHash(f1, f0) & vUniqueMasks[v2]);
553 lit next = vNexts[f];
559 Var2Level[v1] = i + 1;
562 Level2Var[i + 1] = v1;
567 std::vector<var> sift_order(nVars);
568 for(
var v = 0; v < nVars; v++)
570 for(
var i = 0; i < nVars; i++) {
572 for(
var j = i + 1; j < nVars; j++)
573 if(vUniqueCounts[sift_order[j]] > vUniqueCounts[sift_order[max_j]])
576 std::swap(sift_order[max_j], sift_order[i]);
578 for(
var v = 0; v < nVars; v++) {
579 bvar lev = Var2Level[sift_order[v]];
580 bool UpFirst = lev < (
bvar)(nVars / 2);
584 bvar thold = count * (MaxGrowth - 1);
586 std::cout <<
"Sift " << sift_order[v] <<
" : Level = " << lev <<
" Count = " << count <<
" Thold = " << thold << std::endl;
589 for(; lev >= 0; lev--) {
592 std::cout <<
"\tSwap " << lev <<
" : Diff = " << diff <<
" Thold = " << thold << std::endl;
594 min_lev = lev, min_diff = diff, thold = (count + diff) * (MaxGrowth - 1);
595 else if(diff > thold) {
602 for(; lev < (
bvar)nVars - 1; lev++) {
605 std::cout <<
"\tSwap " << lev <<
" : Diff = " << diff <<
" Thold = " << thold << std::endl;
607 min_lev = lev + 1, min_diff = diff, thold = (count + diff) * (MaxGrowth - 1);
608 else if(diff > thold) {
615 for(; lev >= min_lev; lev--) {
618 std::cout <<
"\tSwap " << lev <<
" : Diff = " << diff <<
" Thold = " << thold << std::endl;
621 for(; lev >= 0; lev--) {
624 std::cout <<
"\tSwap " << lev <<
" : Diff = " << diff <<
" Thold = " << thold << std::endl;
626 min_lev = lev, min_diff = diff, thold = (count + diff) * (MaxGrowth - 1);
627 else if(diff > thold) {
633 for(; lev < min_lev; lev++) {
636 std::cout <<
"\tSwap " << lev <<
" : Diff = " << diff <<
" Thold = " << thold << std::endl;
641 std::cout <<
"Sifted " << sift_order[v] <<
" : Level = " << min_lev <<
" Count = " << count <<
" Thold = " << thold << std::endl;
648 nVerbose =
p.nVerbose;
650 if(
p.nObjsMaxLog <
p.nObjsAllocLog)
651 fatal_error(
"nObjsMax must not be smaller than nObjsAlloc");
652 if(nVars_ >= (
int)VarMax())
653 fatal_error(
"Memout (nVars) in init");
655 lit nObjsMaxLit = (
lit)1 <<
p.nObjsMaxLog;
657 fatal_error(
"Memout (nObjsMax) in init");
658 if(nObjsMaxLit > (
lit)BvarMax())
659 nObjsMax = BvarMax();
661 nObjsMax = (
bvar)nObjsMaxLit;
662 lit nObjsAllocLit = (
lit)1 <<
p.nObjsAllocLog;
664 fatal_error(
"Memout (nObjsAlloc) in init");
665 if(nObjsAllocLit > (
lit)BvarMax())
666 nObjsAlloc = BvarMax();
668 nObjsAlloc = (
bvar)nObjsAllocLit;
669 if(nObjsAlloc <= (
bvar)nVars)
670 fatal_error(
"nObjsAlloc must be larger than nVars");
671 uniq nUniqueSize = (
uniq)1 <<
p.nUniqueSizeLog;
673 fatal_error(
"Memout (nUniqueSize) in init");
676 std::cout <<
"Allocating " << nObjsAlloc <<
" nodes and " << nVars <<
" x " << nUniqueSize <<
" unique table entries" << std::endl;
677 vVars.resize(nObjsAlloc);
678 vObjs.resize((
lit)nObjsAlloc * 2);
679 vNexts.resize(nObjsAlloc);
680 vMarks.resize(nObjsAlloc);
681 vvUnique.resize(nVars);
682 vUniqueMasks.resize(nVars);
683 vUniqueCounts.resize(nVars);
684 vUniqueTholds.resize(nVars);
685 for(
var v = 0; v < nVars; v++) {
686 vvUnique[v].resize(nUniqueSize);
687 vUniqueMasks[v] = nUniqueSize - 1;
688 if((
lit)(nUniqueSize *
p.UniqueDensity) > (
lit)BvarMax())
689 vUniqueTholds[v] = BvarMax();
691 vUniqueTholds[v] = (
bvar)(nUniqueSize *
p.UniqueDensity);
695 fatal_error(
"nVars must be less than 1024 to count ones");
696 vOneCounts.resize(nObjsAlloc);
699 cache =
new Cache(
p.nCacheSizeLog,
p.nCacheMaxLog,
p.nCacheVerbose);
703 for(
var v = 0; v < nVars; v++)
704 UniqueCreateInt(v, 1, 0);
706 Var2Level.resize(nVars);
707 Level2Var.resize(nVars);
708 for(
var v = 0; v < nVars; v++) {
710 Var2Level[v] = (*
p.pVar2Level)[v];
713 Level2Var[Var2Level[v]] = v;
719 MaxGrowth =
p.MaxGrowth;
720 fReoVerbose =
p.fReoVerbose;
721 if(nGbc || nReo != BvarMax())
722 vRefs.resize(nObjsAlloc);
726 std::cout <<
"Free " << nObjsAlloc <<
" nodes (" << nObjs <<
" live nodes)" << std::endl;
727 std::cout <<
"Free {";
729 for(
var v = 0; v < nVars; v++) {
730 std::cout << delim << vvUnique[v].size();
733 std::cout <<
"} unique table entries" << std::endl;
735 std::cout <<
"Free " << vRefs.size() <<
" refs" << std::endl;
741 std::cout <<
"Reorder" << std::endl;
753 while(nReo < nObjs) {
755 if((
lit)nReo > (
lit)BvarMax())
759 return And_rec(x, y);
766 void SetRef(std::vector<lit>
const &vLits) {
768 vRefs.resize(nObjsAlloc);
769 for(
size_t i = 0; i < vLits.size(); i++)
773 if(!nGbc && nReo == BvarMax())
776 void TurnOnReo(
int nReo_ = 0, std::vector<lit>
const *vLits = NULL) {
781 if((
lit)nReo > (
lit)BvarMax())
787 vRefs.resize(nObjsAlloc);
797 Var2Level_.resize(nVars);
798 for(
var v = 0; v < nVars; v++)
799 Var2Level_[v] = Var2Level[v];
803 if(!vEdges.empty()) {
804 for(
bvar a = 1; a < nObjs; a++)
809 for(
bvar a = 1; a <= (
bvar)nVars; a++) {
813 for(
bvar a = (
bvar)nVars + 1; a < nObjs; a++)
815 count += CountNodes_rec(
Bvar2Lit(a));
816 for(
bvar a = 1; a <= (
bvar)nVars; a++)
818 for(
bvar a = (
bvar)nVars + 1; a < nObjs; a++)
825 for(
size_t i = 0; i < vLits.size(); i++)
826 count += CountNodes_rec(vLits[i]);
827 for(
size_t i = 0; i < vLits.size(); i++)
828 ResetMark_rec(vLits[i]);
833 bvar a = RemovedHead;
835 a = vNexts[a], nRemoved++;
837 for(
var v = 0; v < nVars; v++)
838 nLive += vUniqueCounts[v];
839 std::cout <<
"ref: " << std::setw(10) << (vRefs.empty()? 0:
CountNodes()) <<
", "
840 <<
"used: " << std::setw(10) << nObjs <<
", "
841 <<
"live: " << std::setw(10) << nLive <<
", "
842 <<
"dead: " << std::setw(10) << nRemoved <<
", "
843 <<
"alloc: " << std::setw(10) << nObjsAlloc
847 return nCreatedTotal;