// File: xnevs[P]bullimp/examples/colored_vertices.cpp
// Function: main
int main() { 
    using namespace boost;
    using namespace ullimp;

    graph_type pattern;
    auto u0 = add_vertex(pattern);
    auto u1 = add_vertex(pattern);
    auto u2 = add_vertex(pattern);
    add_edge(u0, u1, pattern);
    add_edge(u1, u2, pattern);
    add_edge(u2, u0, pattern);

    pattern[u0].color = "red";
    pattern[u1].color = "blue";
    pattern[u2].color = "green";

    graph_type graph;
    auto v0 = add_vertex(graph);
    auto v1 = add_vertex(graph);
    auto v2 = add_vertex(graph);
    auto v3 = add_vertex(graph);
    add_edge(v0, v1, graph);
    add_edge(v1, v2, graph);
    add_edge(v2, v0, graph);
    add_edge(v1, v3, graph);
    add_edge(v3, v0, graph);

    graph[v0].color = "red";
    graph[v1].color = "blue";
    graph[v2].color = "green";
    graph[v3].color = "green";

    auto index_map_p = get(vertex_index, pattern);
    auto index_map_g = get(vertex_index, graph);

    int count = 0;

    ullimp_subgraph_iso(pattern,
                        graph,
                        [&count, &pattern, &index_map_p, &index_map_g](auto const & iso, auto const & isoInv) {
                            std::cout << "found isomorphism:" << std::endl;
                            BGL_FORALL_VERTICES(u, pattern, graph_type) {
                                std::cout << "  " << index_map_p[u] << " -> " << index_map_g[iso[u]] << std::endl;
                            }
                            ++count;
                            return true;
                        },
                        get(vertex_index, pattern),
                        get(vertex_index, graph),
                        vertex_order_RDEG_CNC(pattern),
                        always_equivalent(),
                        [&pattern, &graph](auto const & u, auto const & v) {
                            return pattern[u].color == graph[v].color;
                        });

    std::cout << "isomorphism count = " << count << std::endl;
}

// Assembly:
subq $0x2e8, %rsp            # imm = 0x2E8
leaq 0x2b0(%rsp), %rdi
movq %rdi, 0xb0(%rsp)
leaq 0x2af(%rsp), %rsi
callq 0x5fe0
movq 0xb0(%rsp), %rdi
callq 0x6050
movq %rax, 0xb8(%rsp)
jmp 0x246b
movq 0xb8(%rsp), %rax
movq %rax, 0x2a0(%rsp)
leaq 0x2b0(%rsp), %rdi
callq 0x6050
movq %rax, 0xa8(%rsp)
jmp 0x2492
movq 0xa8(%rsp), %rax
movq %rax, 0x288(%rsp)
leaq 0x2b0(%rsp), %rdi
callq 0x6050
movq %rax, 0xa0(%rsp)
jmp 0x24b9
movq 0xa0(%rsp), %rax
movq %rax, 0x280(%rsp)
movq 0x2a0(%rsp), %rsi
movq 0x288(%rsp), %rdx
leaq 0x260(%rsp), %rdi
leaq 0x2b0(%rsp), %rcx
callq 0x60d0
jmp 0x24f0
movq 0x288(%rsp), %rsi
movq 0x280(%rsp), %rdx
leaq 0x240(%rsp), %rdi
leaq 0x2b0(%rsp), %rcx
callq 0x60d0
jmp 0x2517
movq 0x280(%rsp), %rsi
movq 0x2a0(%rsp), %rdx
leaq 0x220(%rsp), %rdi
leaq 0x2b0(%rsp), %rcx
callq 0x60d0
jmp 0x253e
movq 0x2a0(%rsp), %rsi
leaq 0x2b0(%rsp), %rdi
callq 0x6110
movq %rax, 0x98(%rsp)
jmp 0x255d
movq 0x98(%rsp), %rdi
leaq 0x10a98(%rip), %rsi     # 0x13004
callq 0x21e0
jmp 0x2573
movq 0x288(%rsp), %rsi
leaq 0x2b0(%rsp), %rdi
callq 0x6110
movq %rax, 0x90(%rsp)
jmp 0x2592
movq 0x90(%rsp), %rdi
leaq 0x10a67(%rip), %rsi     # 0x13008
callq 0x21e0
jmp 0x25a8
movq 0x280(%rsp), %rsi
leaq 0x2b0(%rsp), %rdi
callq 0x6110
movq %rax, 0x88(%rsp)
jmp 0x25c7
movq 0x88(%rsp), %rdi
leaq 0x10a37(%rip), %rsi     # 0x1300d
callq 0x21e0
jmp 0x25dd
leaq 0x1e8(%rsp), %rdi
leaq 0x1e7(%rsp), %rsi
callq 0x5fe0
jmp 0x25f4
leaq 0x1e8(%rsp), %rdi
callq 0x6050
movq %rax, 0x80(%rsp)
jmp 0x260b
movq 0x80(%rsp), %rax
movq %rax, 0x1d8(%rsp)
leaq 0x1e8(%rsp), %rdi
callq 0x6050
movq %rax, 0x78(%rsp)
jmp 0x262f
movq 0x78(%rsp), %rax
movq %rax, 0x1d0(%rsp)
leaq 0x1e8(%rsp), %rdi
callq 0x6050
movq %rax, 0x70(%rsp)
jmp 0x2650
movq 0x70(%rsp), %rax
movq %rax, 0x1c8(%rsp)
leaq 0x1e8(%rsp), %rdi
callq 0x6050
movq %rax, 0x68(%rsp)
jmp 0x2671
movq 0x68(%rsp), %rax
movq %rax, 0x1c0(%rsp)
movq 0x1d8(%rsp), %rsi
movq 0x1d0(%rsp), %rdx
leaq 0x1a0(%rsp), %rdi
leaq 0x1e8(%rsp), %rcx
callq 0x60d0
jmp 0x26a5
movq 0x1d0(%rsp), %rsi
movq 0x1c8(%rsp), %rdx
leaq 0x180(%rsp), %rdi
leaq 0x1e8(%rsp), %rcx
callq 0x60d0
jmp 0x26cc
movq 0x1c8(%rsp), %rsi
movq 0x1d8(%rsp), %rdx
leaq 0x160(%rsp), %rdi
leaq 0x1e8(%rsp), %rcx
callq 0x60d0
jmp 0x26f3
movq 0x1d0(%rsp), %rsi
movq 0x1c0(%rsp), %rdx
leaq 0x140(%rsp), %rdi
leaq 0x1e8(%rsp), %rcx
callq 0x60d0
jmp 0x271a
movq 0x1c0(%rsp), %rsi
movq 0x1d8(%rsp), %rdx
leaq 0x120(%rsp), %rdi
leaq 0x1e8(%rsp), %rcx
callq 0x60d0
jmp 0x2741
movq 0x1d8(%rsp), %rsi
leaq 0x1e8(%rsp), %rdi
callq 0x6110
movq %rax, 0x60(%rsp)
jmp 0x275d
movq 0x60(%rsp), %rdi
leaq 0x1089b(%rip), %rsi     # 0x13004
callq 0x21e0
jmp 0x2770
movq 0x1d0(%rsp), %rsi
leaq 0x1e8(%rsp), %rdi
callq 0x6110
movq %rax, 0x58(%rsp)
jmp 0x278c
movq 0x58(%rsp), %rdi
leaq 0x10870(%rip), %rsi     # 0x13008
callq 0x21e0
jmp 0x279f
movq 0x1c8(%rsp), %rsi
leaq 0x1e8(%rsp), %rdi
callq 0x6110
movq %rax, 0x50(%rsp)
jmp 0x27bb
movq 0x50(%rsp), %rdi
leaq 0x10846(%rip), %rsi     # 0x1300d
callq 0x21e0
jmp 0x27ce
movq 0x1c0(%rsp), %rsi
leaq 0x1e8(%rsp), %rdi
callq 0x6110
movq %rax, 0x48(%rsp)
jmp 0x27ea
movq 0x48(%rsp), %rdi
leaq 0x10817(%rip), %rsi     # 0x1300d
callq 0x21e0
jmp 0x27fd
xorl %edi, %edi
leaq 0x2b0(%rsp), %rsi
callq 0x6160
jmp 0x280e
xorl %edi, %edi
leaq 0x1e8(%rsp), %rsi
callq 0x6160
jmp 0x281f
movl $0x0, 0x118(%rsp)
leaq 0x118(%rsp), %rax
movq %rax, 0xf8(%rsp)
leaq 0x2b0(%rsp), %rsi
movq %rsi, 0x100(%rsp)
leaq 0x11f(%rsp), %rax
movq %rax, 0x108(%rsp)
leaq 0x11d(%rsp), %rax
movq %rax, 0x110(%rsp)
xorl %edi, %edi
callq 0x6160
jmp 0x2873
xorl %edi, %edi
leaq 0x1e8(%rsp), %rsi
callq 0x6160
jmp 0x2884
leaq 0xd8(%rsp), %rdi
leaq 0x2b0(%rsp), %rsi
callq 0x6180
jmp 0x289b
leaq 0x2b0(%rsp), %rdi
movq %rdi, 0xc0(%rsp)
leaq 0x1e8(%rsp), %rsi
movq %rsi, 0xc8(%rsp)
vmovdqu 0xc0(%rsp), %xmm0
movq %rsp, %rax
vmovdqu %xmm0, 0x20(%rax)
vmovdqu 0xf8(%rsp), %ymm0
vmovdqu %ymm0, (%rax)
leaq 0xf7(%rsp), %rdx
leaq 0xf5(%rsp), %rcx
leaq 0xd8(%rsp), %r8
vzeroupper
callq 0x29f0
jmp 0x28fb
leaq 0xd8(%rsp), %rdi
callq 0x61d0
movq 0x186c9(%rip), %rdi     # 0x1afd8
leaq 0x106fd(%rip), %rsi     # 0x13013
callq 0x2150
movq %rax, 0x40(%rsp)
jmp 0x2922
movq 0x40(%rsp), %rdi
movl 0x118(%rsp), %esi
callq 0x2260
movq %rax, 0x38(%rsp)
jmp 0x293a
movq 0x38(%rsp), %rdi
movq 0x18682(%rip), %rsi     # 0x1afc8
callq 0x2190
jmp 0x294d
leaq 0x1e8(%rsp), %rdi
callq 0x6230
leaq 0x2b0(%rsp), %rdi
callq 0x6230
xorl %eax, %eax
addq $0x2e8, %rsp            # imm = 0x2E8
retq
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x298(%rsp)
movl %eax, 0x294(%rsp)
jmp 0x29cb
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x298(%rsp)
movl %eax, 0x294(%rsp)
jmp 0x29be
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x298(%rsp)
movl %eax, 0x294(%rsp)
leaq 0xd8(%rsp), %rdi
callq 0x61d0
leaq 0x1e8(%rsp), %rdi
callq 0x6230
leaq 0x2b0(%rsp), %rdi
callq 0x6230
movq 0x298(%rsp), %rdi
callq 0x2270
nopw %cs:(%rax,%rax)