// File: /workspace/github_cpp_makefile_star2_O3/iPapatsoris[P]Maximum-Independent-Set/src/Reductions.cpp
// Function: Reductions::removeShortFunnels(unsigned int const&)
bool Reductions::removeShortFunnels(const uint32_t &theta) {
    //cout << "\n**Performing short funnels reduction**" << endl;
    uint32_t minDegree = NONE;
    graph.getMinDegree(minDegree);
    if (minDegree > 4) {
        return false;
    }
    Graph::GraphTraversal graphTraversal(graph);
    while (graphTraversal.curNode != NONE) {
        uint32_t nodeV = graphTraversal.curNode;
        if (graph.getNodeDegree(nodeV) == 3) {
            //cout << "nodeV " << nodeV << endl;
            vector<uint32_t> neighborsV;
            graph.gatherNeighbors(nodeV, neighborsV);
            for (uint32_t i = 0 ; i < 3 ; i++) {
                uint32_t nodeA = neighborsV[i];
                uint32_t nodeB, nodeC;
                if (i == 0) {
                    nodeB = neighborsV[1];
                    nodeC = neighborsV[2];
                } else if (i == 1) {
                    nodeB = neighborsV[0];
                    nodeC = neighborsV[2];
                } else {
                    nodeB = neighborsV[0];
                    nodeC = neighborsV[1];
                }
                if ((theta == 5 && graph.getNodeDegree(nodeA) == minDegree || theta == 4 && graph.getNodeDegree(nodeA) <= 4 || theta == 3) && graph.edgeExists(nodeB, nodeC)) {
                    bool shortFunnel = false;
                    vector<uint32_t> neighborsA;
                    graph.gatherNeighbors(nodeA, neighborsA);
                    if (theta == 5 && minDegree == 3 || theta == 4) {
                        uint32_t edges;
                        if (theta == 5) {
                            edges = 1;
                        } else if (theta == 4) {
                            edges = graph.getNodeDegree(nodeA) - 2;
                        }
                        for (auto &neighbor: neighborsA) {
                            if (neighbor == nodeV) {
                                continue;
                            }
                            if (graph.edgeExists(neighbor, nodeB) || graph.edgeExists(neighbor, nodeC)) {
                                if (--edges) {
                                    shortFunnel = true;
                                    break;
                                }
                            }
                        }
                    } else if (theta == 5 && minDegree == 4) {
                        uint32_t countB = 0;
                        uint32_t countC = 0;
                        uint32_t *count;
                        uint32_t target;
                        for (auto &neighbor: neighborsA) {
                            count = &countB;
                            target = nodeB;
                            for (uint32_t i = 0 ; i < 2 ; i++) {
                                if (graph.edgeExists(neighbor, target)) {
                                    (*count)++;
                                    if ((*count) == 2) {
                                        shortFunnel = true;
                                        break;
                                    }
                                }
                                count = &countC;
                                target = nodeC;
                            }
                            if (shortFunnel) {
                                break;
                            }
                        }
                    } else if (theta == 3) {
                        uint32_t count = 0;
                        uint32_t atmost = graph.getNodeDegree(nodeA);
                        shortFunnel = true;
                        for (auto &neighbor: neighborsA) {
                            if (neighbor == nodeV) {
                                continue;
                            }
                            if (!graph.edgeExists(neighbor, nodeB)) {
                                if (++count > atmost) {
                                    shortFunnel = false;
                                    break;
                                }
                            }
                            if (!graph.edgeExists(neighbor, nodeC)) {
                                if (++count > atmost) {
                                    shortFunnel = false;
                                    break;
                                }
                            }
                        }
                    }
                    if (shortFunnel) {
                        //cout << "short funnel " << nodeA << "-" << nodeV << "-{" << nodeB << "," << nodeC << "}" << endl;
                        vector<uint32_t> container;
                        container.push_back(nodeA);
                        container.push_back(nodeV);
                        graph.remove(container, reduceInfo);
                        uint32_t target = nodeB;
                        for (uint32_t i = 0 ; i < 2 ; i++) {
                            container.clear();
                            for (auto &neighbor: neighborsA) {
                                if (neighbor == nodeV) {
                                    continue;
                                }
                                if (!graph.edgeExists(neighbor, target)) {
                                    container.push_back(neighbor);
                                    graph.addEdges(neighbor, vector<uint32_t>(1, target));
                                }
                            }
                            graph.addEdges(target, container);
                            target = nodeC;
                        }
                        auto &subsequentNodes = mis.getSubsequentNodes();
                        for (auto &neighbor: neighborsA) {
                            if (neighbor == nodeV) {
                                continue;
                            }
                            subsequentNodes.insert({neighbor, nodeV});
                        }
                        subsequentNodes.insert({nodeB, nodeA});
                        subsequentNodes.insert({nodeC, nodeA});
                        return true;
                    }
                }
            }
        }
        graph.getNextNode(graphTraversal);
    }
    return false;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xc8, %rsp
movq %rsi, %r12
movq %rdi, %r14
leaq 0x7c(%rsp), %rbx
movl $0xffffffff, (%rbx)     # imm = 0xFFFFFFFF
movq (%rdi), %rdi
movq %rbx, %rsi
callq 0x2ac6
cmpl $0x4, (%rbx)
movl $0x0, %r15d
ja 0x107dc
movq (%r14), %rsi
leaq 0x98(%rsp), %rdi
callq 0x29d8
leaq 0x10(%r14), %rax
movq %rax, 0xc0(%rsp)
leaq 0x1c(%rsp), %r13
movq %r12, 0x88(%rsp)
movl 0x98(%rsp), %eax
cmpl $-0x1, %eax
setne %r15b
je 0x107dc
movl %eax, 0x18(%rsp)
movq (%r14), %rdi
leaq 0x18(%rsp), %rsi
callq 0xc2d2
cmpl $0x3, %eax
jne 0x107c2
movq %r15, 0x80(%rsp)
xorps %xmm0, %xmm0
movaps %xmm0, 0xa0(%rsp)
movq $0x0, 0xb0(%rsp)
movq (%r14), %rdi
movl $0xffffffff, 0x60(%rsp) # imm = 0xFFFFFFFF
leaq 0x18(%rsp), %rsi
leaq 0xa0(%rsp), %rdx
xorl %ecx, %ecx
leaq 0x60(%rsp), %r8
callq 0xc092
xorl %r15d, %r15d
xorl %ebx, %ebx
movq 0xa0(%rsp), %rax
movl (%rax,%r15,4), %ecx
movl %ecx, 0x1c(%rsp)
cmpl $0x1, %r15d
je 0x102c9
testl %r15d, %r15d
jne 0x102d4
movl 0x4(%rax), %ecx
jmp 0x102cb
movl (%rax), %ecx
movl %ecx, 0x14(%rsp)
movl 0x8(%rax), %eax
jmp 0x102dd
movl (%rax), %ecx
movl %ecx, 0x14(%rsp)
movl 0x4(%rax), %eax
movl %eax, 0x10(%rsp)
movl (%r12), %eax
cmpl $0x5, %eax
jne 0x102ff
movq (%r14), %rdi
movq %r13, %rsi
callq 0xc2d2
cmpl 0x7c(%rsp), %eax
je 0x10328
movl (%r12), %eax
cmpl $0x3, %eax
je 0x10328
cmpl $0x4, %eax
jne 0x1052d
movq (%r14), %rdi
movq %r13, %rsi
callq 0xc2d2
cmpl $0x5, %eax
jb 0x10328
cmpl $0x3, (%r12)
jne 0x1052d
movq (%r14), %rdi
leaq 0x14(%rsp), %rsi
leaq 0x10(%rsp), %rdx
callq 0xbf3a
cmpl $-0x1, %eax
je 0x1052d
xorps %xmm0, %xmm0
movaps %xmm0, 0x60(%rsp)
movq $0x0, 0x70(%rsp)
movq (%r14), %rdi
movl $0xffffffff, 0x20(%rsp) # imm = 0xFFFFFFFF
movq %r13, %rsi
leaq 0x60(%rsp), %rdx
xorl %ecx, %ecx
leaq 0x20(%rsp), %r8
callq 0xc092
movl (%r12), %eax
movl %eax, %ecx
xorl $0x5, %ecx
movl 0x7c(%rsp), %edx
movl %edx, %esi
xorl $0x3, %esi
orl %ecx, %esi
sete %sil
cmpl $0x4, %eax
movq %rbx, 0x90(%rsp)
je 0x1041f
testb %sil, %sil
jne 0x1041f
xorl $0x4, %edx
orl %edx, %ecx
jne 0x10499
xorl %eax, %eax
movl %eax, 0x20(%rsp)
movl %eax, 0x40(%rsp)
movq 0x60(%rsp), %rbx
movq 0x68(%rsp), %r12
cmpq %r12, %rbx
je 0x1050e
movl 0x14(%rsp), %eax
movl %eax, 0xc(%rsp)
movb $0x1, %bpl
leaq 0x20(%rsp), %r13
movq (%r14), %rdi
movq %rbx, %rsi
leaq 0xc(%rsp), %rdx
callq 0xbf3a
cmpl $-0x1, %eax
je 0x10401
movl (%r13), %eax
incl %eax
movl %eax, (%r13)
cmpl $0x2, %eax
je 0x1055e
movl 0x10(%rsp), %eax
movl %eax, 0xc(%rsp)
leaq 0x40(%rsp), %r13
testb $0x1, %bpl
movl $0x0, %ebp
jne 0x103d9
addq $0x4, %rbx
jmp 0x103c0
movl $0x1, %ebx
cmpl $0x5, %eax
je 0x10439
movq (%r14), %rdi
movq %r13, %rsi
callq 0xc2d2
movl %eax, %ebx
addl $-0x2, %ebx
movq 0x60(%rsp), %r12
movq 0x68(%rsp), %r13
cmpq %r13, %r12
je 0x10513
movl (%r12), %eax
cmpl 0x18(%rsp), %eax
je 0x1048e
movq (%r14), %rdi
movq %r12, %rsi
leaq 0x14(%rsp), %rdx
callq 0xbf3a
cmpl $-0x1, %eax
jne 0x10480
movq (%r14), %rdi
movq %r12, %rsi
leaq 0x10(%rsp), %rdx
callq 0xbf3a
cmpl $-0x1, %eax
je 0x1048e
cmpl $0x1, %ebx
movl $0x0, %ebx
jne 0x1055e
addq $0x4, %r12
cmpq %r13, %r12
jne 0x1044c
jmp 0x1050e
cmpl $0x3, %eax
jne 0x1050e
movq (%r14), %rdi
leaq 0x1c(%rsp), %rsi
callq 0xc2d2
movq 0x60(%rsp), %rbx
movq 0x68(%rsp), %r13
cmpq %r13, %rbx
je 0x1055e
movl %eax, %r12d
xorl %ebp, %ebp
movl (%rbx), %eax
cmpl 0x18(%rsp), %eax
je 0x10503
movq (%r14), %rdi
movq %rbx, %rsi
leaq 0x14(%rsp), %rdx
callq 0xbf3a
cmpl $-0x1, %eax
jne 0x104e7
incl %ebp
cmpl %r12d, %ebp
ja 0x1050e
movq (%r14), %rdi
movq %rbx, %rsi
leaq 0x10(%rsp), %rdx
callq 0xbf3a
cmpl $-0x1, %eax
jne 0x10503
incl %ebp
cmpl %r12d, %ebp
ja 0x1050e
addq $0x4, %rbx
cmpq %r13, %rbx
jne 0x104c3
jmp 0x1055e
movq 0x60(%rsp), %r12
testq %r12, %r12
je 0x10520
movq %r12, %rdi
callq 0x21a0
movq 0x88(%rsp), %r12
leaq 0x1c(%rsp), %r13
cmpq $0x2, %r15
leaq 0x1(%r15), %rax
setae %bl
movq %rax, %r15
cmpq $0x3, %rax
jne 0x102a9
xorl %ebx, %ebx
movb $0x1, %al
movq %rax, 0x90(%rsp)
movq 0x80(%rsp), %r15
jmp 0x107a6
xorps %xmm0, %xmm0
movaps %xmm0, 0x20(%rsp)
movq $0x0, 0x30(%rsp)
leaq 0x20(%rsp), %rdi
xorl %esi, %esi
leaq 0x1c(%rsp), %rdx
callq 0xd7b4
leaq 0x40(%rsp), %rbx
movq 0x28(%rsp), %rsi
cmpq 0x30(%rsp), %rsi
je 0x105a2
movl 0x18(%rsp), %eax
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x28(%rsp)
jmp 0x105b1
leaq 0x20(%rsp), %rdi
leaq 0x18(%rsp), %rdx
callq 0xd7b4
movq (%r14), %rdi
xorl %eax, %eax
movb %al, 0x40(%rsp)
movb %al, 0xc(%rsp)
leaq 0x20(%rsp), %rsi
movq 0xc0(%rsp), %rdx
movq %rbx, %rcx
xorl %r8d, %r8d
leaq 0xc(%rsp), %rbx
movq %rbx, %r9
callq 0xbaa6
movl 0x14(%rsp), %esi
movl %esi, 0xc(%rsp)
movb $0x1, %r13b
movq 0x20(%rsp), %rax
cmpq %rax, 0x28(%rsp)
je 0x105fa
movq %rax, 0x28(%rsp)
movq 0x60(%rsp), %r12
movq 0x68(%rsp), %rbp
cmpq %rbp, %r12
je 0x106ce
movl (%r12), %eax
cmpl 0x18(%rsp), %eax
je 0x106bd
movq (%r14), %rdi
movq %r12, %rsi
movq %rbx, %rdx
callq 0xbf3a
cmpl $-0x1, %eax
jne 0x106bd
movq 0x28(%rsp), %rsi
cmpq 0x30(%rsp), %rsi
je 0x1064f
movl (%r12), %ebx
movl %ebx, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x28(%rsp)
jmp 0x10660
leaq 0x20(%rsp), %rdi
movq %r12, %rdx
callq 0xd7b4
movl (%r12), %ebx
movq (%r14), %r15
xorps %xmm0, %xmm0
movaps %xmm0, 0x40(%rsp)
movq $0x0, 0x50(%rsp)
movl $0x4, %edi
callq 0x21e0
movq %rax, 0x40(%rsp)
movq %rax, %rcx
addq $0x4, %rcx
movq %rcx, 0x50(%rsp)
movl 0xc(%rsp), %edx
movl %edx, (%rax)
movq %rcx, 0x48(%rsp)
movq %r15, %rdi
movl %ebx, %esi
leaq 0x40(%rsp), %rdx
callq 0x6c96
movq 0x40(%rsp), %rdi
testq %rdi, %rdi
je 0x106b8
callq 0x21a0
leaq 0xc(%rsp), %rbx
addq $0x4, %r12
cmpq %rbp, %r12
jne 0x1060d
movl 0xc(%rsp), %esi
movq (%r14), %rdi
leaq 0x20(%rsp), %rdx
callq 0x6c96
movl 0x10(%rsp), %esi
movl %esi, 0xc(%rsp)
testb $0x1, %r13b
movl $0x0, %r13d
jne 0x105e9
movq 0x8(%r14), %rbx
addq $0x50, %rbx
movq 0x60(%rsp), %r15
movq 0x68(%rsp), %r12
cmpq %r12, %r15
leaq 0x1c(%rsp), %r13
je 0x10738
movl (%r15), %eax
movl 0x18(%rsp), %ecx
cmpl %ecx, %eax
je 0x1072f
movl %eax, 0x40(%rsp)
movl %ecx, 0x44(%rsp)
movq %rbx, %rdi
leaq 0x40(%rsp), %rsi
callq 0xd8cc
addq $0x4, %r15
cmpq %r12, %r15
jne 0x1070f
movl 0x14(%rsp), %eax
movl %eax, 0x40(%rsp)
movl 0x1c(%rsp), %eax
movl %eax, 0x44(%rsp)
movq %rbx, %rdi
leaq 0x40(%rsp), %r15
movq %r15, %rsi
callq 0xd8cc
movl 0x10(%rsp), %eax
movl %eax, 0x40(%rsp)
movl 0x1c(%rsp), %eax
movl %eax, 0x44(%rsp)
movq %rbx, %rdi
movq %r15, %rsi
callq 0xd8cc
movq 0x88(%rsp), %r12
movq 0x80(%rsp), %r15
movq 0x20(%rsp), %rdi
testq %rdi, %rdi
je 0x10792
callq 0x21a0
movq 0x60(%rsp), %rdi
testq %rdi, %rdi
je 0x107a1
callq 0x21a0
movl $0x1, %ebx
movq 0xa0(%rsp), %rdi
testq %rdi, %rdi
je 0x107b8
callq 0x21a0
testb $0x1, 0x90(%rsp)
je 0x107d4
movq (%r14), %rdi
leaq 0x98(%rsp), %rsi
callq 0xb94a
xorl %ebx, %ebx
testl %ebx, %ebx
je 0x10233
movl %r15d, %eax
addq $0xc8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x1080c
jmp 0x1080c
jmp 0x10829
jmp 0x10829
jmp 0x10829
jmp 0x10805
jmp 0x10829
jmp 0x1080c
jmp 0x1080c
jmp 0x10829
movq %rax, %rbx
jmp 0x1084a
jmp 0x1080c
movq %rax, %rbx
jmp 0x1083b
jmp 0x10829
movq %rax, %rbx
movq 0x40(%rsp), %rdi
testq %rdi, %rdi
je 0x1082c
callq 0x21a0
jmp 0x1082c
jmp 0x10829
movq %rax, %rbx
movq 0x20(%rsp), %rdi
testq %rdi, %rdi
je 0x1083b
callq 0x21a0
movq 0x60(%rsp), %rdi
testq %rdi, %rdi
je 0x1084a
callq 0x21a0
movq 0xa0(%rsp), %rdi
testq %rdi, %rdi
je 0x1085c
callq 0x21a0
movq %rbx, %rdi
callq 0x2320