// File: /workspace/github_cpp_makefile_star2_O1/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, %r15
movq %rdi, %r14
leaq 0x7c(%rsp), %rbx
movl $0xffffffff, (%rbx)     # imm = 0xFFFFFFFF
movq (%rdi), %rdi
movq %rbx, %rsi
callq 0x2ab4
cmpl $0x4, (%rbx)
movl $0x0, %eax
ja 0x10f5a
movq (%r14), %rsi
leaq 0x98(%rsp), %rdi
callq 0x29d8
leaq 0x10(%r14), %rax
movq %rax, 0xc0(%rsp)
leaq 0x18(%rsp), %rbx
movq %r15, 0x80(%rsp)
movl 0x98(%rsp), %eax
cmpl $-0x1, %eax
setne %cl
movq %rcx, 0xb8(%rsp)
je 0x10f52
movl %eax, 0x18(%rsp)
movq (%r14), %rdi
movq %rbx, %rsi
callq 0xc98e
cmpl $0x3, %eax
jne 0x10f33
xorps %xmm0, %xmm0
movaps %xmm0, 0xa0(%rsp)
movq $0x0, 0xb0(%rsp)
movq (%r14), %rdi
movl $0xffffffff, 0x60(%rsp) # imm = 0xFFFFFFFF
movq %rbx, %rsi
leaq 0xa0(%rsp), %rdx
xorl %ecx, %ecx
leaq 0x60(%rsp), %r8
callq 0xc714
xorl %ebx, %ebx
xorl %r12d, %r12d
movq 0xa0(%rsp), %rax
movl (%rax,%rbx,4), %ecx
movl %ecx, 0xc(%rsp)
cmpl $0x1, %ebx
je 0x1098a
testl %ebx, %ebx
jne 0x10995
movl 0x4(%rax), %ecx
jmp 0x1098c
movl (%rax), %ecx
movl %ecx, 0x14(%rsp)
movl 0x8(%rax), %eax
jmp 0x1099e
movl (%rax), %ecx
movl %ecx, 0x14(%rsp)
movl 0x4(%rax), %eax
movl %eax, 0x10(%rsp)
cmpl $0x5, (%r15)
jne 0x109bb
movq (%r14), %rdi
leaq 0xc(%rsp), %rsi
callq 0xc98e
cmpl 0x7c(%rsp), %eax
je 0x109eb
movl (%r15), %eax
cmpl $0x3, %eax
je 0x109eb
movb $0x1, %bpl
cmpl $0x4, %eax
jne 0x10ef4
movq (%r14), %rdi
leaq 0xc(%rsp), %rsi
callq 0xc98e
cmpl $0x5, %eax
jb 0x109eb
cmpl $0x3, (%r15)
jne 0x10ef4
movq (%r14), %rdi
leaq 0x14(%rsp), %rsi
leaq 0x10(%rsp), %rdx
callq 0xc5e2
movb $0x1, %bpl
cmpl $-0x1, %eax
je 0x10ef4
xorps %xmm0, %xmm0
movaps %xmm0, 0x60(%rsp)
movq $0x0, 0x70(%rsp)
movq (%r14), %rdi
movl $0xffffffff, 0x20(%rsp) # imm = 0xFFFFFFFF
leaq 0xc(%rsp), %rsi
leaq 0x60(%rsp), %rdx
xorl %ecx, %ecx
leaq 0x20(%rsp), %r8
callq 0xc714
movl (%r15), %ecx
movl %ecx, %eax
xorl $0x5, %eax
movl 0x7c(%rsp), %edx
movl %edx, %esi
xorl $0x3, %esi
orl %eax, %esi
sete %sil
cmpl $0x4, %ecx
movq %r12, 0x90(%rsp)
movq %rbx, 0x88(%rsp)
je 0x10b06
testb %sil, %sil
jne 0x10b06
xorl $0x4, %edx
orl %edx, %eax
jne 0x10b26
xorl %r13d, %r13d
movl %r13d, 0x20(%rsp)
movl %r13d, 0x40(%rsp)
movq 0x60(%rsp), %rbx
movq 0x68(%rsp), %r15
cmpq %r15, %rbx
je 0x10c6f
xorl %r13d, %r13d
movl 0x14(%rsp), %eax
movl %eax, 0x8(%rsp)
movl $0x1, %ebp
leaq 0x20(%rsp), %r12
movq (%r14), %rdi
movq %rbx, %rsi
leaq 0x8(%rsp), %rdx
callq 0xc5e2
cmpl $-0x1, %eax
je 0x10ad8
movl (%r12), %eax
incl %eax
movl %eax, (%r12)
cmpl $0x2, %eax
je 0x10aeb
movl 0x10(%rsp), %eax
movl %eax, 0x8(%rsp)
leaq 0x40(%rsp), %r12
decl %ebp
je 0x10ab4
jmp 0x10aee
movb $0x1, %r13b
testb $0x1, %r13b
jne 0x10c6f
addq $0x4, %rbx
cmpq %r15, %rbx
jne 0x10aa2
jmp 0x10c6f
cmpl $0x4, %ecx
je 0x10bdb
movl $0x1, %eax
cmpl $0x5, %ecx
je 0x10beb
movl 0x1c(%rsp), %eax
jmp 0x10beb
cmpl $0x3, %ecx
jne 0x10c67
movq (%r14), %rdi
leaq 0xc(%rsp), %rsi
callq 0xc98e
movq 0x60(%rsp), %rbx
movq 0x68(%rsp), %r15
cmpq %r15, %rbx
je 0x10c6c
xorl %ebp, %ebp
movb $0x1, %r13b
movl %eax, %r12d
movl (%rbx), %eax
movl $0xf, %ecx
cmpl 0x18(%rsp), %eax
je 0x10bc0
movq (%r14), %rdi
movq %rbx, %rsi
leaq 0x14(%rsp), %rdx
callq 0xc5e2
cmpl $-0x1, %eax
jne 0x10b8a
incl %ebp
cmpl %r12d, %ebp
jbe 0x10b8a
movl $0xe, %ecx
xorl %r13d, %r13d
jmp 0x10bc0
movq (%r14), %rdi
movq %rbx, %rsi
leaq 0x10(%rsp), %rdx
callq 0xc5e2
xorl %ecx, %ecx
cmpl $-0x1, %eax
jne 0x10bc0
incl %ebp
cmpl %r12d, %ebp
movzbl %r13b, %r13d
movl $0x0, %eax
cmoval %eax, %r13d
movl $0x0, %ecx
movl $0xe, %eax
cmoval %eax, %ecx
cmpl $0xf, %ecx
je 0x10bcd
testl %ecx, %ecx
jne 0x10c6f
addq $0x4, %rbx
cmpq %r15, %rbx
jne 0x10b57
jmp 0x10c6f
movq (%r14), %rdi
leaq 0xc(%rsp), %rsi
callq 0xc98e
addl $-0x2, %eax
movq 0x60(%rsp), %rbx
movq 0x68(%rsp), %r15
xorl %r13d, %r13d
cmpq %r15, %rbx
je 0x10c61
movl %eax, 0x1c(%rsp)
movl (%rbx), %ecx
movl $0x8, %eax
cmpl 0x18(%rsp), %ecx
je 0x10c52
movq (%r14), %rdi
movq %rbx, %rsi
leaq 0x14(%rsp), %rdx
callq 0xc5e2
cmpl $-0x1, %eax
jne 0x10c38
movq (%r14), %rdi
movq %rbx, %rsi
leaq 0x10(%rsp), %rdx
callq 0xc5e2
cmpl $-0x1, %eax
je 0x10c50
decl 0x1c(%rsp)
je 0x10c48
movl $0x7, %eax
movb $0x1, %r13b
jmp 0x10c52
movl $0x0, 0x1c(%rsp)
xorl %eax, %eax
testb $0x7, %al
jne 0x10c6f
addq $0x4, %rbx
cmpq %r15, %rbx
jne 0x10c01
jmp 0x10c6f
movl %eax, 0x1c(%rsp)
jmp 0x10c6f
xorl %r13d, %r13d
jmp 0x10c6f
movb $0x1, %r13b
testb $0x1, %r13b
je 0x10ca6
xorps %xmm0, %xmm0
movaps %xmm0, 0x20(%rsp)
movq $0x0, 0x30(%rsp)
movq 0x28(%rsp), %rsi
testq %rsi, %rsi
leaq 0x40(%rsp), %r13
je 0x10cd5
movl 0xc(%rsp), %eax
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x28(%rsp)
jmp 0x10ce4
movq 0x60(%rsp), %rdi
testq %rdi, %rdi
movq 0x80(%rsp), %r15
je 0x10cbd
callq 0x21a0
movq 0x90(%rsp), %r12
movq 0x88(%rsp), %rbx
movb $0x1, %bpl
jmp 0x10ef4
leaq 0x20(%rsp), %rdi
leaq 0xc(%rsp), %rdx
callq 0xdeac
movq 0x28(%rsp), %rsi
cmpq 0x30(%rsp), %rsi
je 0x10d01
movl 0x18(%rsp), %eax
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x28(%rsp)
jmp 0x10d10
leaq 0x20(%rsp), %rdi
leaq 0x18(%rsp), %rdx
callq 0xdeac
movq (%r14), %rdi
xorl %eax, %eax
movb %al, 0x40(%rsp)
movb %al, 0x8(%rsp)
leaq 0x20(%rsp), %rsi
movq 0xc0(%rsp), %rdx
movq %r13, %rcx
xorl %r8d, %r8d
leaq 0x8(%rsp), %r9
callq 0xc16e
movl 0x14(%rsp), %eax
movl %eax, 0x8(%rsp)
xorl %r15d, %r15d
movq 0x20(%rsp), %rax
cmpq %rax, 0x28(%rsp)
je 0x10d56
movq %rax, 0x28(%rsp)
movq 0x60(%rsp), %rbx
movq 0x68(%rsp), %r12
cmpq %r12, %rbx
je 0x10e21
movl (%rbx), %eax
cmpl 0x18(%rsp), %eax
je 0x10e18
movq (%r14), %rdi
movq %rbx, %rsi
leaq 0x8(%rsp), %rdx
callq 0xc5e2
cmpl $-0x1, %eax
jne 0x10e18
movq 0x28(%rsp), %rsi
cmpq 0x30(%rsp), %rsi
je 0x10da9
movl (%rbx), %eax
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x28(%rsp)
jmp 0x10db6
leaq 0x20(%rsp), %rdi
movq %rbx, %rdx
callq 0xdeac
movq (%r14), %r13
movl (%rbx), %ebp
xorps %xmm0, %xmm0
movaps %xmm0, 0x40(%rsp)
movq $0x0, 0x50(%rsp)
movl $0x4, %edi
callq 0x21e0
movq %rax, 0x40(%rsp)
movq %rax, 0x48(%rsp)
movq %rax, %rcx
addq $0x4, %rcx
movq %rcx, 0x50(%rsp)
movl 0x8(%rsp), %edx
movl %edx, (%rax)
movq %rcx, 0x48(%rsp)
movq %r13, %rdi
movl %ebp, %esi
leaq 0x40(%rsp), %r13
movq %r13, %rdx
callq 0x6cde
movq 0x40(%rsp), %rdi
testq %rdi, %rdi
je 0x10e18
callq 0x21a0
addq $0x4, %rbx
jmp 0x10d60
movq (%r14), %rdi
movl 0x8(%rsp), %esi
leaq 0x20(%rsp), %rdx
callq 0x6cde
movl 0x10(%rsp), %eax
movl %eax, 0x8(%rsp)
leal 0x1(%r15), %eax
testl %r15d, %r15d
movl %eax, %r15d
je 0x10d45
movq 0x8(%r14), %rbx
addq $0x50, %rbx
movq 0x60(%rsp), %r15
movq 0x68(%rsp), %r12
cmpq %r12, %r15
je 0x10e86
movl 0x18(%rsp), %eax
cmpl %eax, (%r15)
je 0x10e80
movl (%r15), %ecx
movl %ecx, 0x40(%rsp)
movl %eax, 0x44(%rsp)
movq %rbx, %rdi
movq %r13, %rsi
callq 0xdfc4
addq $0x4, %r15
jmp 0x10e5c
movl 0x14(%rsp), %eax
movl %eax, 0x40(%rsp)
movl 0xc(%rsp), %eax
movl %eax, 0x44(%rsp)
movq %rbx, %rdi
movq %r13, %rsi
callq 0xdfc4
movl 0x10(%rsp), %eax
movl %eax, 0x40(%rsp)
movl 0xc(%rsp), %eax
movl %eax, 0x44(%rsp)
movq %rbx, %rdi
movq %r13, %rsi
callq 0xdfc4
movq 0x80(%rsp), %r15
movq 0x20(%rsp), %rdi
testq %rdi, %rdi
movq 0x90(%rsp), %r12
movq 0x88(%rsp), %rbx
je 0x10ee3
callq 0x21a0
movq 0x60(%rsp), %rdi
testq %rdi, %rdi
je 0x10ef2
callq 0x21a0
xorl %ebp, %ebp
testb %bpl, %bpl
je 0x10f16
cmpq $0x2, %rbx
leaq 0x1(%rbx), %rax
setae %r12b
movq %rax, %rbx
cmpq $0x3, %rax
jne 0x1096d
xorl %ebx, %ebx
jmp 0x10f1b
movl $0x1, %ebx
movq 0xa0(%rsp), %rdi
testq %rdi, %rdi
je 0x10f2d
callq 0x21a0
testb $0x1, %r12b
je 0x10f45
movq (%r14), %rdi
leaq 0x98(%rsp), %rsi
callq 0xc034
xorl %ebx, %ebx
testl %ebx, %ebx
leaq 0x18(%rsp), %rbx
je 0x108fc
movq 0xb8(%rsp), %rax
addq $0xc8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x10f9f
jmp 0x10f7e
jmp 0x10f9f
jmp 0x10fa4
jmp 0x10fa4
jmp 0x10fa4
jmp 0x10fa4
jmp 0x10f9f
jmp 0x10f9f
movq %rax, %rbx
jmp 0x10fc5
jmp 0x10f9f
jmp 0x10fa4
jmp 0x10fa4
movq %rax, %rbx
movq 0x40(%rsp), %rdi
testq %rdi, %rdi
je 0x10fa7
callq 0x21a0
jmp 0x10fa7
jmp 0x10fa4
movq %rax, %rbx
jmp 0x10fb6
movq %rax, %rbx
movq 0x20(%rsp), %rdi
testq %rdi, %rdi
je 0x10fb6
callq 0x21a0
movq 0x60(%rsp), %rdi
testq %rdi, %rdi
je 0x10fc5
callq 0x21a0
movq 0xa0(%rsp), %rdi
testq %rdi, %rdi
je 0x10fd7
callq 0x21a0
movq %rbx, %rdi
callq 0x2320
nop