// File: /workspace/github_cpp_makefile_star2_O2/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 $0xb8, %rsp
movq %rsi, %r15
movq %rdi, %r14
leaq 0x1c(%rsp), %rbx
orl $-0x1, (%rbx)
movq (%rdi), %rdi
movq %rbx, %rsi
callq 0x27cc
cmpl $0x4, (%rbx)
jbe 0xe96c
xorl %eax, %eax
jmp 0xee71
movq (%r14), %rsi
leaq 0x88(%rsp), %rdi
callq 0x270e
leaq 0x10(%r14), %rax
movq %rax, 0xb0(%rsp)
leaq 0x90(%rsp), %r12
leaq 0x20(%rsp), %r13
leaq 0x40(%rsp), %rbp
movq %r15, 0x80(%rsp)
movl 0x88(%rsp), %eax
cmpl $-0x1, %eax
setne %cl
movl %ecx, 0x78(%rsp)
je 0xee6d
movl %eax, 0x14(%rsp)
movq (%r14), %rdi
leaq 0x14(%rsp), %rsi
callq 0xa5ce
cmpl $0x3, %eax
jne 0xee53
xorps %xmm0, %xmm0
movaps %xmm0, 0x90(%rsp)
andq $0x0, 0xa0(%rsp)
movq (%r14), %rdi
orl $-0x1, 0x20(%rsp)
leaq 0x14(%rsp), %rsi
movq %r12, %rdx
xorl %ecx, %ecx
movq %r13, %r8
callq 0xa3c8
xorl %r12d, %r12d
cmpq $0x3, %r12
je 0xee35
movq 0x90(%rsp), %rax
movl (%rax,%r12,4), %ecx
movl %ecx, 0x10(%rsp)
cmpl $0x1, %r12d
je 0xea2e
testl %r12d, %r12d
jne 0xea39
movl 0x4(%rax), %ecx
jmp 0xea30
movl (%rax), %ecx
movl %ecx, 0xc(%rsp)
movl 0x8(%rax), %eax
jmp 0xea42
movl (%rax), %ecx
movl %ecx, 0xc(%rsp)
movl 0x4(%rax), %eax
movl %eax, 0x8(%rsp)
movl (%r15), %eax
cmpl $0x5, %eax
jne 0xea64
movq (%r14), %rdi
leaq 0x10(%rsp), %rsi
callq 0xa5ce
cmpl 0x1c(%rsp), %eax
je 0xea8e
movl (%r15), %eax
cmpl $0x3, %eax
je 0xea8e
cmpl $0x4, %eax
jne 0xec68
movq (%r14), %rdi
leaq 0x10(%rsp), %rsi
callq 0xa5ce
cmpl $0x5, %eax
jb 0xea8e
cmpl $0x3, (%r15)
jne 0xec68
movq (%r14), %rdi
leaq 0xc(%rsp), %rsi
leaq 0x8(%rsp), %rdx
callq 0x9e3a
testb %al, %al
je 0xec68
xorps %xmm0, %xmm0
movaps %xmm0, 0x20(%rsp)
andq $0x0, 0x30(%rsp)
movq (%r14), %rdi
orl $-0x1, 0x40(%rsp)
leaq 0x10(%rsp), %rsi
movq %r13, %rdx
xorl %ecx, %ecx
movq %rbp, %r8
callq 0xa3c8
movl (%r15), %eax
movl %eax, %ecx
xorl $0x5, %ecx
movl 0x1c(%rsp), %edx
movl %edx, %esi
xorl $0x3, %esi
orl %ecx, %esi
sete %sil
cmpl $0x4, %eax
je 0xeb6a
testb %sil, %sil
jne 0xeb6a
xorl $0x4, %edx
orl %edx, %ecx
jne 0xebdb
andl $0x0, 0x40(%rsp)
andl $0x0, 0x60(%rsp)
movq 0x20(%rsp), %rbx
movq 0x28(%rsp), %r15
cmpq %r15, %rbx
je 0xec4e
movl 0xc(%rsp), %eax
movl %eax, 0x4(%rsp)
pushq $0x2
popq %rbp
leaq 0x40(%rsp), %r13
subl $0x1, %ebp
jb 0xeb64
movq (%r14), %rdi
movq %rbx, %rsi
leaq 0x4(%rsp), %rdx
callq 0x9e3a
testb %al, %al
je 0xeb55
movl (%r13), %eax
incl %eax
movl %eax, (%r13)
cmpl $0x2, %eax
je 0xec49
movl 0x8(%rsp), %eax
movl %eax, 0x4(%rsp)
leaq 0x60(%rsp), %r13
jmp 0xeb29
addq $0x4, %rbx
jmp 0xeb10
pushq $0x1
popq %rbp
cmpl $0x5, %eax
je 0xeb84
movq (%r14), %rdi
leaq 0x10(%rsp), %rsi
callq 0xa5ce
movl %eax, %ebp
addl $-0x2, %ebp
movq 0x20(%rsp), %rbx
movq 0x28(%rsp), %r15
cmpq %r15, %rbx
je 0xec4e
movl (%rbx), %eax
cmpl 0x14(%rsp), %eax
je 0xebd5
movq (%r14), %rdi
movq %rbx, %rsi
leaq 0xc(%rsp), %rdx
callq 0x9e3a
testb %al, %al
jne 0xebc7
movq (%r14), %rdi
movq %rbx, %rsi
leaq 0x8(%rsp), %rdx
callq 0x9e3a
testb %al, %al
je 0xebd5
cmpl $0x1, %ebp
movl $0x0, %ebp
jne 0xec70
addq $0x4, %rbx
jmp 0xeb8e
cmpl $0x3, %eax
jne 0xec4e
movq (%r14), %rdi
leaq 0x10(%rsp), %rsi
callq 0xa5ce
movl %eax, %r15d
movq 0x20(%rsp), %rbp
movq 0x28(%rsp), %rbx
xorl %r13d, %r13d
cmpq %rbx, %rbp
je 0xec70
movl (%rbp), %eax
cmpl 0x14(%rsp), %eax
je 0xec43
movq (%r14), %rdi
movq %rbp, %rsi
leaq 0xc(%rsp), %rdx
callq 0x9e3a
testb %al, %al
jne 0xec27
incl %r13d
cmpl %r15d, %r13d
ja 0xec4e
movq (%r14), %rdi
movq %rbp, %rsi
leaq 0x8(%rsp), %rdx
callq 0x9e3a
testb %al, %al
jne 0xec43
incl %r13d
cmpl %r15d, %r13d
ja 0xec4e
addq $0x4, %rbp
jmp 0xebfd
cmpq %r15, %rbx
jne 0xec70
leaq 0x20(%rsp), %r13
movq %r13, %rdi
callq 0xb872
movq 0x80(%rsp), %r15
leaq 0x40(%rsp), %rbp
incq %r12
jmp 0xea04
cmpq $0x3, %r12
setae 0x3(%rsp)
xorps %xmm0, %xmm0
movaps %xmm0, 0x40(%rsp)
andq $0x0, 0x50(%rsp)
leaq 0x40(%rsp), %rbp
movq %rbp, %rdi
leaq 0x10(%rsp), %rsi
callq 0xa1ac
movq %rbp, %rdi
leaq 0x14(%rsp), %rsi
callq 0xa1ac
movq (%r14), %rdi
xorl %eax, %eax
movb %al, 0x60(%rsp)
movb %al, 0x4(%rsp)
movq %rbp, %rsi
movq 0xb0(%rsp), %rdx
leaq 0x60(%rsp), %r12
movq %r12, %rcx
xorl %r8d, %r8d
leaq 0x4(%rsp), %r9
callq 0x9e48
movl 0xc(%rsp), %eax
movl %eax, 0x4(%rsp)
xorl %eax, %eax
cmpl $0x2, %eax
je 0xed93
movl %eax, 0x7c(%rsp)
movq 0x40(%rsp), %rax
cmpq %rax, 0x48(%rsp)
je 0xecfb
movq %rax, 0x48(%rsp)
movq 0x20(%rsp), %rbp
movq 0x28(%rsp), %r15
cmpq %r15, %rbp
je 0xed6c
movl (%rbp), %eax
cmpl 0x14(%rsp), %eax
je 0xed66
movq (%r14), %rdi
movq %rbp, %rsi
leaq 0x4(%rsp), %rdx
callq 0x9e3a
testb %al, %al
jne 0xed66
leaq 0x40(%rsp), %rdi
movq %rbp, %rsi
callq 0xa1ac
movq (%r14), %rbx
movl (%rbp), %r13d
movq %r12, %rdi
pushq $0x1
popq %rsi
leaq 0x4(%rsp), %rdx
leaq 0x1b(%rsp), %rcx
callq 0xa016
movq %rbx, %rdi
movl %r13d, %esi
movq %r12, %rdx
callq 0x5e38
movq %r12, %rdi
callq 0xb872
addq $0x4, %rbp
jmp 0xed05
movq (%r14), %rdi
movl 0x4(%rsp), %esi
leaq 0x40(%rsp), %rbp
movq %rbp, %rdx
callq 0x5e38
movl 0x8(%rsp), %eax
movl %eax, 0x4(%rsp)
movl 0x7c(%rsp), %eax
incl %eax
jmp 0xecdd
movq 0x8(%r14), %rbx
addq $0x50, %rbx
movq 0x20(%rsp), %r15
movq 0x28(%rsp), %r12
leaq 0x20(%rsp), %r13
cmpq %r12, %r15
je 0xedd5
movl (%r15), %eax
movl 0x14(%rsp), %ecx
cmpl %ecx, %eax
je 0xedcf
movl %eax, 0x60(%rsp)
movl %ecx, 0x64(%rsp)
movq %rbx, %rdi
leaq 0x60(%rsp), %rsi
callq 0xbfd8
addq $0x4, %r15
jmp 0xedaa
movl 0xc(%rsp), %eax
movl %eax, 0x60(%rsp)
movl 0x10(%rsp), %eax
movl %eax, 0x64(%rsp)
movq %rbx, %rdi
leaq 0x60(%rsp), %r15
movq %r15, %rsi
callq 0xbfd8
movl 0x8(%rsp), %eax
movl %eax, 0x60(%rsp)
movl 0x10(%rsp), %eax
movl %eax, 0x64(%rsp)
movq %rbx, %rdi
movq %r15, %rsi
callq 0xbfd8
movq 0x80(%rsp), %r15
leaq 0x90(%rsp), %r12
movq %rbp, %rdi
callq 0xb872
movq %r13, %rdi
callq 0xb872
pushq $0x1
popq %rbx
jmp 0xee44
xorl %ebx, %ebx
movb $0x1, 0x3(%rsp)
leaq 0x90(%rsp), %r12
movq %r12, %rdi
callq 0xb872
cmpb $0x0, 0x3(%rsp)
je 0xee65
movq (%r14), %rdi
leaq 0x88(%rsp), %rsi
callq 0x9cf8
xorl %ebx, %ebx
testl %ebx, %ebx
je 0xe9a2
movl 0x78(%rsp), %eax
addq $0xb8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0xeea0
jmp 0xeeb6
jmp 0xeeb6
jmp 0xeeb6
jmp 0xeea0
jmp 0xee97
jmp 0xeeb6
jmp 0xeea0
jmp 0xeea0
jmp 0xeeb6
movq %rax, %rbx
jmp 0xeecd
jmp 0xeeb6
jmp 0xeea0
movq %rax, %rbx
jmp 0xeec3
movq %rax, %rbx
leaq 0x60(%rsp), %rdi
callq 0xb872
jmp 0xeeb9
jmp 0xeeb6
movq %rax, %rbx
leaq 0x40(%rsp), %rdi
callq 0xb872
leaq 0x20(%rsp), %rdi
callq 0xb872
leaq 0x90(%rsp), %rdi
callq 0xb872
movq %rbx, %rdi
callq 0x22c0