// File: grame-cncm[P]digraph/./dglib/digraphop.hh
// Function: digraph<digraph<char, std::pair<std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, int, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, int>>>, int>>, std::pair<std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, int, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, int>>>, int>> partitionGraph<char, std::pair<std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, int, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, int>>>, int>>(digraph<char, std::pair<std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, int, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, int>>>, int>> const&, std::set<std::set<char, std::less<char>, std::allocator<char>>, std::less<std::set<char, std::less<char>, std::allocator<char>>>, std::allocator<std::set<char, std::less<char>, std::allocator<char>>>> const&)
inline digraph<digraph<N, A>, A> partitionGraph(const digraph<N, A>& g, const std::set<std::set<N>>& partition)
{
    std::map<N, digraph<N, A>> M;   // std::mapping between nodes and supernodes
    digraph<digraph<N, A>, A>  sg;  // the resulting supergraph

    // build the graph of supernodes

    // For each std::set s of the partition, create the corresponding graph sn
    // create also a std::mapping in order to retrieve the supernode a node
    /// belongs to.
    for (const auto& s : partition) {
        digraph<N, A> sn;                     // the supernode graph
        for (const N& n : s) {                // for each node of a cycle
            M.insert(std::make_pair(n, sn));  // remember its supernode
            sn.add(n);                        // and add it to the super node
        }
        sg.add(sn);  // and add the super node to the super graph
    }

    // compute the connections between the supernodes
    for (const auto& n1 : g.nodes()) {
        digraph<N, A> sn1(M[n1]);
        for (const auto& c : g.connections(n1)) {
            digraph<N, A> sn2(M[c.first]);
            if (sn1 == sn2) {
                // the connection is inside the same supernode
                sn1.add(n1, c.first, c.second);
            } else {
                // the connection is between supernodes
                sg.add(sn1, sn2, c.second);  // exploit the fact that add will keep the mini
            }
        }
    }

    return sg;
}

// Assembly:
subq $0x1a8, %rsp            # imm = 0x1A8
movq %rdi, 0x58(%rsp)
movq %rdi, %rax
movq %rax, 0x50(%rsp)
movq %rdi, 0x1a0(%rsp)
movq %rsi, 0x198(%rsp)
movq %rdx, 0x190(%rsp)
leaq 0x160(%rsp), %rdi
callq 0x16bc0
movq 0x58(%rsp), %rdi
movb $0x0, 0x15f(%rsp)
callq 0x16bd0
jmp 0x166ad
movq 0x190(%rsp), %rax
movq %rax, 0x140(%rsp)
movq 0x140(%rsp), %rdi
callq 0xad10
movq %rax, 0x138(%rsp)
movq 0x140(%rsp), %rdi
callq 0xad40
movq %rax, 0x130(%rsp)
leaq 0x138(%rsp), %rdi
leaq 0x130(%rsp), %rsi
callq 0xad70
testb $0x1, %al
jne 0x16705
jmp 0x16920
leaq 0x138(%rsp), %rdi
callq 0xad90
movq %rax, 0x128(%rsp)
leaq 0x118(%rsp), %rdi
callq 0x29c0
jmp 0x16729
movq 0x128(%rsp), %rax
movq %rax, 0x110(%rsp)
movq 0x110(%rsp), %rdi
callq 0xa150
movq %rax, 0x108(%rsp)
movq 0x110(%rsp), %rdi
callq 0xa180
movq %rax, 0x100(%rsp)
leaq 0x108(%rsp), %rdi
leaq 0x100(%rsp), %rsi
callq 0xa1b0
testb $0x1, %al
jne 0x16781
jmp 0x16896
leaq 0x108(%rsp), %rdi
callq 0xa1d0
movq %rax, 0xf8(%rsp)
movq 0xf8(%rsp), %rsi
leaq 0xe0(%rsp), %rdi
leaq 0x118(%rsp), %rdx
callq 0x16c60
jmp 0x167b5
leaq 0x160(%rsp), %rdi
leaq 0xe0(%rsp), %rsi
callq 0x16c10
movb %dl, 0x47(%rsp)
movq %rax, 0x48(%rsp)
jmp 0x167d5
movb 0x47(%rsp), %al
movq 0x48(%rsp), %rcx
movq %rcx, 0xd0(%rsp)
movb %al, 0xd8(%rsp)
leaq 0xe0(%rsp), %rdi
callq 0x16ca0
movq 0xf8(%rsp), %rax
movsbl (%rax), %esi
leaq 0x118(%rsp), %rdi
callq 0x16cc0
jmp 0x16814
jmp 0x16816
leaq 0x108(%rsp), %rdi
callq 0xa350
jmp 0x16763
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x150(%rsp)
movl %eax, 0x14c(%rsp)
jmp 0x16ba1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x150(%rsp)
movl %eax, 0x14c(%rsp)
jmp 0x16b97
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x150(%rsp)
movl %eax, 0x14c(%rsp)
jmp 0x1690e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x150(%rsp)
movl %eax, 0x14c(%rsp)
leaq 0xe0(%rsp), %rdi
callq 0x16ca0
jmp 0x1690e
leaq 0xc0(%rsp), %rdi
movq %rdi, 0x38(%rsp)
leaq 0x118(%rsp), %rsi
callq 0x16d90
movq 0x58(%rsp), %rdi
movq 0x38(%rsp), %rsi
callq 0x16d00
jmp 0x168c1
leaq 0xc0(%rsp), %rdi
callq 0x3780
leaq 0x118(%rsp), %rdi
callq 0x3780
leaq 0x138(%rsp), %rdi
callq 0xadb0
jmp 0x166e7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x150(%rsp)
movl %eax, 0x14c(%rsp)
leaq 0xc0(%rsp), %rdi
callq 0x3780
leaq 0x118(%rsp), %rdi
callq 0x3780
jmp 0x16b97
movq 0x198(%rsp), %rdi
callq 0xa130
movq %rax, 0x30(%rsp)
jmp 0x16934
movq 0x30(%rsp), %rax
movq %rax, 0xb8(%rsp)
movq 0xb8(%rsp), %rdi
callq 0xa150
movq %rax, 0xb0(%rsp)
movq 0xb8(%rsp), %rdi
callq 0xa180
movq %rax, 0xa8(%rsp)
leaq 0xb0(%rsp), %rdi
leaq 0xa8(%rsp), %rsi
callq 0xa1b0
testb $0x1, %al
jne 0x16989
jmp 0x16b61
leaq 0xb0(%rsp), %rdi
callq 0xa1d0
movq %rax, 0xa0(%rsp)
movq 0xa0(%rsp), %rsi
leaq 0x160(%rsp), %rdi
callq 0x16dc0
movq %rax, 0x28(%rsp)
jmp 0x169ba
movq 0x28(%rsp), %rsi
leaq 0x90(%rsp), %rdi
callq 0x16d90
movq 0x198(%rsp), %rdi
movq 0xa0(%rsp), %rsi
callq 0xa1f0
movq %rax, 0x20(%rsp)
jmp 0x169e8
movq 0x20(%rsp), %rax
movq %rax, 0x88(%rsp)
movq 0x88(%rsp), %rdi
callq 0xa220
movq %rax, 0x80(%rsp)
movq 0x88(%rsp), %rdi
callq 0xa250
movq %rax, 0x78(%rsp)
leaq 0x80(%rsp), %rdi
leaq 0x78(%rsp), %rsi
callq 0xa280
testb $0x1, %al
jne 0x16a37
jmp 0x16b33
leaq 0x80(%rsp), %rdi
callq 0xa2a0
movq %rax, 0x70(%rsp)
movq 0x70(%rsp), %rsi
leaq 0x160(%rsp), %rdi
callq 0x16dc0
movq %rax, 0x18(%rsp)
jmp 0x16a62
movq 0x18(%rsp), %rsi
leaq 0x60(%rsp), %rdi
movq %rdi, 0x8(%rsp)
callq 0x16d90
movq 0x8(%rsp), %rsi
leaq 0x90(%rsp), %rdi
callq 0x16eb0
movb %al, 0x17(%rsp)
jmp 0x16a8e
movb 0x17(%rsp), %al
testb $0x1, %al
jne 0x16a98
jmp 0x16af3
movq 0xa0(%rsp), %rsi
movq 0x70(%rsp), %rdx
movq %rdx, %rcx
addq $0x8, %rcx
leaq 0x90(%rsp), %rdi
callq 0x2a00
jmp 0x16abb
jmp 0x16b17
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x150(%rsp)
movl %eax, 0x14c(%rsp)
jmp 0x16b52
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x150(%rsp)
movl %eax, 0x14c(%rsp)
leaq 0x60(%rsp), %rdi
callq 0x3780
jmp 0x16b52
movq 0x58(%rsp), %rdi
movq 0x70(%rsp), %rcx
addq $0x8, %rcx
leaq 0x90(%rsp), %rsi
leaq 0x60(%rsp), %rdx
callq 0x16ee0
jmp 0x16b15
jmp 0x16b17
leaq 0x60(%rsp), %rdi
callq 0x3780
leaq 0x80(%rsp), %rdi
callq 0xa320
jmp 0x16a1c
leaq 0x90(%rsp), %rdi
callq 0x3780
leaq 0xb0(%rsp), %rdi
callq 0xa350
jmp 0x1696b
leaq 0x90(%rsp), %rdi
callq 0x3780
jmp 0x16b97
movb $0x1, 0x15f(%rsp)
testb $0x1, 0x15f(%rsp)
jne 0x16b7d
movq 0x58(%rsp), %rdi
callq 0x160a0
leaq 0x160(%rsp), %rdi
callq 0x16f30
movq 0x50(%rsp), %rax
addq $0x1a8, %rsp            # imm = 0x1A8
retq
movq 0x58(%rsp), %rdi
callq 0x160a0
leaq 0x160(%rsp), %rdi
callq 0x16f30
movq 0x150(%rsp), %rdi
callq 0x2290
nopl (%rax,%rax)