// File: /workspace/github_cpp_makefile_star2_O3/iPapatsoris[P]Maximum-Independent-Set/src/Alg.cpp
// Function: Alg::run()
void Alg::run() {
    uint32_t searchNodes = 1;
    uint32_t minCompletedSearchNode = NONE;
    bool down = true;
    uint32_t i = 0;
    while(true) {
        if (down) {
            if (searchTree[i]->theta == 5 && !searchTree[i]->hasCut && searchTree[i]->handleCuts()) {
                ;
            } else {
                searchTree[i]->reductions->run(searchTree[i]->theta);
                //cout << "search node " << searchNodes ;
                searchTree[i]->branchingRule.choose(searchTree[i]->graph, *(searchTree[i]->reductions), searchTree[i]->theta, searchTree[i]);
            }
        } else if (searchTree[i]->rightChild == NONE) {
            down = true;
            assert(searchTree[i]->branchingRule.type != BranchingRule::Type::DONE);
        }
        if (down && searchTree[i]->branchingRule.type == BranchingRule::Type::DONE) {
            searchTree[i]->id = searchNodeID++;
            searchTree[i]->finalMis = new vector<uint32_t>();
            searchTree[i]->mis.unfoldHypernodes(searchTree[i]->graph.zeroDegreeNodes, *searchTree[i]->finalMis);
            i = searchTree[i]->parent;
            if (i == NONE) {
                break;
            }
            down = false;
            continue;
        }
        uint32_t *nextChild;
        if (searchTree[i]->leftChild == NONE) {
            nextChild = &searchTree[i]->leftChild;
        } else if (searchTree[i]->rightChild == NONE) {
            nextChild = &searchTree[i]->rightChild;
        } else if (searchTree[i]->hasCut && !searchTree[i]->cutIsDone) {
            chooseCutBranch(searchTree[i]);
            nextChild = &searchTree[i]->rightChild;
            down = true;
        } else {
            if (i < minCompletedSearchNode) {
                minCompletedSearchNode = i;
                cout << i << endl;
            }
            SearchNode *parent = searchTree[i];
            if (parent->hasCut) {
                assert(parent->cutIsDone);
                concatMis(parent);
                //cout << "concating mis" << endl;
            } else {
                chooseMaxMis(parent);
            }
            i = parent->parent;
            if (searchTree.size() == 1) {
                break;
            }
            continue;
        }
        SearchNode *searchNode = new SearchNode(*searchTree[i], i);
        searchNodes++;
        searchTree.push_back(searchNode);
        *nextChild = searchTree.size() - 1;
        if (nextChild == &searchTree[i]->leftChild) {
            branchLeft(searchTree[i]->branchingRule, searchNode, searchTree[i]->mis);
        }
        else if (nextChild == &searchTree[i]->rightChild) {
            branchRight(searchTree[i]->branchingRule, searchNode, searchTree[i]->mis);
        }
        else {
            assert(false);
        }
        i = *nextChild;
    }
    cout << searchNodes << " search nodes\n";
    searchTree[0]->graph.collectZeroDegreeNodes();
    //cout << "Final id " << searchTree[0]->id;
    Mis::print(*searchTree[0]->finalMis);
    delete searchTree[0]->finalMis;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rdi, %rbx
leaq 0x4(%rsp), %rax
movl $0x0, (%rax)
movl $0x1, 0xc(%rsp)
movl $0xffffffff, 0x8(%rsp)  # imm = 0xFFFFFFFF
movb $0x1, %r14b
xorl %r12d, %r12d
movl %r12d, %r13d
movq (%rbx), %r15
movq (%r15,%r13,8), %rsi
testb $0x1, %r14b
je 0x13943
cmpl $0x5, 0x4(%rsi)
jne 0x13894
cmpb $0x0, 0x128(%rsi)
jne 0x13894
movq %rsi, %rdi
callq 0x13bfe
movq (%rbx), %r15
testb %al, %al
jne 0x138c6
movq (%r15,%r13,8), %rsi
movq 0x108(%rsi), %rdi
addq $0x4, %rsi
callq 0xf680
movq (%rbx), %rax
movq (%rax,%r13,8), %r8
leaq 0x8(%r8), %rdi
leaq 0x30(%r8), %rsi
movq 0x108(%r8), %rdx
leaq 0x4(%r8), %rcx
callq 0x14284
movq (%rbx), %r15
movq (%r15,%r13,8), %rax
cmpl $0xb, 0x8(%rax)
jne 0x13959
movl 0xe8f6(%rip), %ecx      # 0x221d0
leal 0x1(%rcx), %edx
movl %edx, 0xe8ed(%rip)      # 0x221d0
movl %ecx, (%rax)
movl $0x18, %edi
callq 0x21e0
xorps %xmm0, %xmm0
movups %xmm0, (%rax)
movq $0x0, 0x10(%rax)
movq (%r15,%r13,8), %rcx
movq %rax, 0x120(%rcx)
movq (%r15,%r13,8), %rsi
leaq 0x80(%rsi), %rdi
movq 0x120(%rsi), %rdx
addq $0x50, %rsi
callq 0x16e76
movq (%rbx), %rax
movq (%rax,%r13,8), %rax
movl 0x110(%rax), %r12d
xorl %r14d, %r14d
cmpl $-0x1, %r12d
jne 0x1385e
jmp 0x13b12
cmpl $-0x1, 0x118(%rsi)
jne 0x13959
movb $0x1, %r14b
cmpl $0xb, 0x8(%rsi)
je 0x13bac
movl %r12d, 0x4(%rsp)
movq (%r15,%r13,8), %rbp
cmpl $-0x1, 0x114(%rbp)
je 0x139ae
cmpl $-0x1, 0x118(%rbp)
je 0x139b7
movb 0x128(%rbp), %al
cmpb $0x1, %al
jne 0x13a7a
cmpb $0x0, 0x199(%rbp)
jne 0x13a7a
movq %rbx, %rdi
movq %rbp, %rsi
callq 0x146b6
movq (%rbx), %r15
movq (%r15,%r13,8), %rbp
movl $0x118, %eax            # imm = 0x118
addq %rax, %rbp
movb $0x1, %r14b
jmp 0x139be
addq $0x114, %rbp            # imm = 0x114
jmp 0x139be
addq $0x118, %rbp            # imm = 0x118
movl $0x1a0, %edi            # imm = 0x1A0
callq 0x21e0
movq %rax, %r12
movq (%r15,%r13,8), %rsi
movq %rax, %rdi
leaq 0x4(%rsp), %rdx
callq 0x134d6
movq %r12, 0x10(%rsp)
movq 0x8(%rbx), %rsi
cmpq 0x10(%rbx), %rsi
je 0x139fc
movq %r12, (%rsi)
movq 0x8(%rbx), %rax
addq $0x8, %rax
movq %rax, 0x8(%rbx)
jmp 0x13a0d
movq %rbx, %rdi
leaq 0x10(%rsp), %rdx
callq 0x16b42
movq 0x8(%rbx), %rax
movq (%rbx), %rcx
subq %rcx, %rax
shrq $0x3, %rax
decl %eax
movl %eax, (%rbp)
movq (%rcx,%r13,8), %rcx
leaq 0x114(%rcx), %rax
cmpq %rax, %rbp
je 0x13a53
leaq 0x118(%rcx), %rax
cmpq %rax, %rbp
jne 0x13b8d
leaq 0x8(%rcx), %rsi
movq 0x10(%rsp), %rdx
subq $-0x80, %rcx
movq %rbx, %rdi
callq 0x14de6
jmp 0x13a68
leaq 0x8(%rcx), %rsi
movq 0x10(%rsp), %rdx
subq $-0x80, %rcx
movq %rbx, %rdi
callq 0x14a14
incl 0xc(%rsp)
movl (%rbp), %r12d
movl %r12d, 0x4(%rsp)
jmp 0x1385e
cmpl 0x8(%rsp), %r12d
jae 0x13acc
movq 0xe548(%rip), %rdi      # 0x21fd0
movq %r13, %rsi
callq 0x2120
movq %rax, %rbp
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbp, %rdi
movl $0xa, %esi
callq 0x21b0
movsbl %al, %esi
movq %rbp, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x2130
movq (%rbx), %rax
movq (%rax,%r13,8), %rbp
movb 0x128(%rbp), %al
movl %r12d, 0x8(%rsp)
testb $0x1, %al
je 0x13aea
cmpb $0x0, 0x199(%rbp)
je 0x13bcb
movq %rbx, %rdi
movq %rbp, %rsi
callq 0x14786
jmp 0x13af5
movq %rbx, %rdi
movq %rbp, %rsi
callq 0x14902
movl 0x110(%rbp), %r12d
movl %r12d, 0x4(%rsp)
movq 0x8(%rbx), %rax
subq (%rbx), %rax
cmpq $0x8, %rax
jne 0x1385e
movl 0xc(%rsp), %esi
movq 0xe4b3(%rip), %rdi      # 0x21fd0
callq 0x2120
leaq 0x5f61(%rip), %rsi      # 0x19a8a
movl $0xe, %edx
movq %rax, %rdi
callq 0x2200
movq (%rbx), %rax
movq (%rax), %rdi
addq $0x30, %rdi
callq 0x6fa6
movq (%rbx), %rax
movq (%rax), %rax
movq 0x120(%rax), %rdi
callq 0x17014
movq (%rbx), %rax
movq (%rax), %rax
movq 0x120(%rax), %rbx
testq %rbx, %rbx
je 0x13b76
movq (%rbx), %rdi
testq %rdi, %rdi
je 0x13b76
callq 0x21a0
movq %rbx, %rdi
callq 0x21a0
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x5d37(%rip), %rdi      # 0x198cb
leaq 0x5ec1(%rip), %rsi      # 0x19a5c
leaq 0x5ec6(%rip), %rcx      # 0x19a68
movl $0x6f, %edx
callq 0x2110
leaq 0x5e6a(%rip), %rdi      # 0x19a1d
leaq 0x5ea2(%rip), %rsi      # 0x19a5c
leaq 0x5ea7(%rip), %rcx      # 0x19a68
movl $0x3b, %edx
callq 0x2110
leaq 0x5ea6(%rip), %rdi      # 0x19a78
leaq 0x5e83(%rip), %rsi      # 0x19a5c
leaq 0x5e88(%rip), %rcx      # 0x19a68
movl $0x58, %edx
callq 0x2110
movq %rax, %rbx
movq %r12, %rdi
callq 0x21a0
movq %rbx, %rdi
callq 0x2320
nop