// File: xnevs[P]bullimp/examples/colored_edges.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);

    auto e01 = add_edge(u0, u1, pattern).first;
    auto e12 = add_edge(u1, u2, pattern).first;
    auto e20 = add_edge(u2, u0, pattern).first;

    pattern[e01].color = "red";
    pattern[e12].color = "black";
    pattern[e20].color = "black";

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

    auto f01 = add_edge(v0, v1, graph).first;
    auto f12 = add_edge(v1, v2, graph).first;
    auto f20 = add_edge(v2, v0, graph).first;
    auto f13 = add_edge(v1, v3, graph).first;
    auto f30 = add_edge(v3, v0, graph).first;

    graph[f01].color = "red";
    graph[f12].color = "black";
    graph[f20].color = "black";
    graph[f13].color = "black";
    graph[f30].color = "black";

    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),
                        [&pattern, &graph](auto const & e, auto const & f) {
                            return pattern[e].color == graph[f].color;
                        },
                        always_equivalent());

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

// Assembly:
subq $0x4e8, %rsp            # imm = 0x4E8
leaq 0x4b0(%rsp), %rdi
movq %rdi, 0xb0(%rsp)
leaq 0x4af(%rsp), %rsi
callq 0x6340
movq 0xb0(%rsp), %rdi
callq 0x63b0
movq %rax, 0xb8(%rsp)
jmp 0x246b
movq 0xb8(%rsp), %rax
movq %rax, 0x4a0(%rsp)
leaq 0x4b0(%rsp), %rdi
callq 0x63b0
movq %rax, 0xa8(%rsp)
jmp 0x2492
movq 0xa8(%rsp), %rax
movq %rax, 0x488(%rsp)
leaq 0x4b0(%rsp), %rdi
callq 0x63b0
movq %rax, 0xa0(%rsp)
jmp 0x24b9
movq 0xa0(%rsp), %rax
movq %rax, 0x480(%rsp)
movq 0x4a0(%rsp), %rsi
movq 0x488(%rsp), %rdx
leaq 0x440(%rsp), %rdi
leaq 0x4b0(%rsp), %rcx
callq 0x6430
jmp 0x24f0
movq 0x450(%rsp), %rax
movq %rax, 0x470(%rsp)
vmovdqu 0x440(%rsp), %xmm0
vmovdqa %xmm0, 0x460(%rsp)
movq 0x488(%rsp), %rsi
movq 0x480(%rsp), %rdx
leaq 0x400(%rsp), %rdi
leaq 0x4b0(%rsp), %rcx
callq 0x6430
jmp 0x2539
movq 0x410(%rsp), %rax
movq %rax, 0x430(%rsp)
vmovdqu 0x400(%rsp), %xmm0
vmovdqa %xmm0, 0x420(%rsp)
movq 0x480(%rsp), %rsi
movq 0x4a0(%rsp), %rdx
leaq 0x3c0(%rsp), %rdi
leaq 0x4b0(%rsp), %rcx
callq 0x6430
jmp 0x2582
movq 0x3d0(%rsp), %rax
movq %rax, 0x3f0(%rsp)
vmovdqu 0x3c0(%rsp), %xmm0
vmovdqa %xmm0, 0x3e0(%rsp)
movq 0x470(%rsp), %rax
movq %rax, 0x3b0(%rsp)
vmovdqa 0x460(%rsp), %xmm0
vmovdqa %xmm0, 0x3a0(%rsp)
movq 0x3b0(%rsp), %rcx
movq %rsp, %rax
movq %rcx, 0x10(%rax)
vmovdqa 0x3a0(%rsp), %xmm0
vmovdqu %xmm0, (%rax)
leaq 0x4b0(%rsp), %rdi
callq 0x64c0
movq %rax, 0x98(%rsp)
jmp 0x25f9
movq 0x98(%rsp), %rdi
leaq 0x109fc(%rip), %rsi     # 0x13004
callq 0x21e0
jmp 0x260f
movq 0x430(%rsp), %rax
movq %rax, 0x390(%rsp)
vmovdqa 0x420(%rsp), %xmm0
vmovdqa %xmm0, 0x380(%rsp)
movq 0x390(%rsp), %rcx
movq %rsp, %rax
movq %rcx, 0x10(%rax)
vmovdqa 0x380(%rsp), %xmm0
vmovdqu %xmm0, (%rax)
leaq 0x4b0(%rsp), %rdi
callq 0x64c0
movq %rax, 0x90(%rsp)
jmp 0x2664
movq 0x90(%rsp), %rdi
leaq 0x10995(%rip), %rsi     # 0x13008
callq 0x21e0
jmp 0x267a
movq 0x3f0(%rsp), %rax
movq %rax, 0x370(%rsp)
vmovdqa 0x3e0(%rsp), %xmm0
vmovdqa %xmm0, 0x360(%rsp)
movq 0x370(%rsp), %rcx
movq %rsp, %rax
movq %rcx, 0x10(%rax)
vmovdqa 0x360(%rsp), %xmm0
vmovdqu %xmm0, (%rax)
leaq 0x4b0(%rsp), %rdi
callq 0x64c0
movq %rax, 0x88(%rsp)
jmp 0x26cf
movq 0x88(%rsp), %rdi
leaq 0x1092a(%rip), %rsi     # 0x13008
callq 0x21e0
jmp 0x26e5
leaq 0x328(%rsp), %rdi
leaq 0x327(%rsp), %rsi
callq 0x6340
jmp 0x26fc
leaq 0x328(%rsp), %rdi
callq 0x63b0
movq %rax, 0x80(%rsp)
jmp 0x2713
movq 0x80(%rsp), %rax
movq %rax, 0x318(%rsp)
leaq 0x328(%rsp), %rdi
callq 0x63b0
movq %rax, 0x78(%rsp)
jmp 0x2737
movq 0x78(%rsp), %rax
movq %rax, 0x310(%rsp)
leaq 0x328(%rsp), %rdi
callq 0x63b0
movq %rax, 0x70(%rsp)
jmp 0x2758
movq 0x70(%rsp), %rax
movq %rax, 0x308(%rsp)
leaq 0x328(%rsp), %rdi
callq 0x63b0
movq %rax, 0x68(%rsp)
jmp 0x2779
movq 0x68(%rsp), %rax
movq %rax, 0x300(%rsp)
movq 0x318(%rsp), %rsi
movq 0x310(%rsp), %rdx
leaq 0x2c0(%rsp), %rdi
leaq 0x328(%rsp), %rcx
callq 0x6430
jmp 0x27ad
movq 0x2d0(%rsp), %rax
movq %rax, 0x2f0(%rsp)
vmovdqu 0x2c0(%rsp), %xmm0
vmovdqa %xmm0, 0x2e0(%rsp)
movq 0x310(%rsp), %rsi
movq 0x308(%rsp), %rdx
leaq 0x280(%rsp), %rdi
leaq 0x328(%rsp), %rcx
callq 0x6430
jmp 0x27f6
movq 0x290(%rsp), %rax
movq %rax, 0x2b0(%rsp)
vmovdqu 0x280(%rsp), %xmm0
vmovdqa %xmm0, 0x2a0(%rsp)
movq 0x308(%rsp), %rsi
movq 0x318(%rsp), %rdx
leaq 0x240(%rsp), %rdi
leaq 0x328(%rsp), %rcx
callq 0x6430
jmp 0x283f
movq 0x250(%rsp), %rax
movq %rax, 0x270(%rsp)
vmovdqu 0x240(%rsp), %xmm0
vmovdqa %xmm0, 0x260(%rsp)
movq 0x310(%rsp), %rsi
movq 0x300(%rsp), %rdx
leaq 0x200(%rsp), %rdi
leaq 0x328(%rsp), %rcx
callq 0x6430
jmp 0x2888
movq 0x210(%rsp), %rax
movq %rax, 0x230(%rsp)
vmovdqu 0x200(%rsp), %xmm0
vmovdqa %xmm0, 0x220(%rsp)
movq 0x300(%rsp), %rsi
movq 0x318(%rsp), %rdx
leaq 0x1c0(%rsp), %rdi
leaq 0x328(%rsp), %rcx
callq 0x6430
jmp 0x28d1
movq 0x1d0(%rsp), %rax
movq %rax, 0x1f0(%rsp)
vmovdqu 0x1c0(%rsp), %xmm0
vmovdqa %xmm0, 0x1e0(%rsp)
movq 0x2f0(%rsp), %rax
movq %rax, 0x1b0(%rsp)
vmovdqa 0x2e0(%rsp), %xmm0
vmovdqa %xmm0, 0x1a0(%rsp)
movq 0x1b0(%rsp), %rcx
movq %rsp, %rax
movq %rcx, 0x10(%rax)
vmovdqa 0x1a0(%rsp), %xmm0
vmovdqu %xmm0, (%rax)
leaq 0x328(%rsp), %rdi
callq 0x64c0
movq %rax, 0x60(%rsp)
jmp 0x2945
movq 0x60(%rsp), %rdi
leaq 0x106b3(%rip), %rsi     # 0x13004
callq 0x21e0
jmp 0x2958
movq 0x2b0(%rsp), %rax
movq %rax, 0x190(%rsp)
vmovdqa 0x2a0(%rsp), %xmm0
vmovdqa %xmm0, 0x180(%rsp)
movq 0x190(%rsp), %rcx
movq %rsp, %rax
movq %rcx, 0x10(%rax)
vmovdqa 0x180(%rsp), %xmm0
vmovdqu %xmm0, (%rax)
leaq 0x328(%rsp), %rdi
callq 0x64c0
movq %rax, 0x58(%rsp)
jmp 0x29aa
movq 0x58(%rsp), %rdi
leaq 0x10652(%rip), %rsi     # 0x13008
callq 0x21e0
jmp 0x29bd
movq 0x270(%rsp), %rax
movq %rax, 0x170(%rsp)
vmovdqa 0x260(%rsp), %xmm0
vmovdqa %xmm0, 0x160(%rsp)
movq 0x170(%rsp), %rcx
movq %rsp, %rax
movq %rcx, 0x10(%rax)
vmovdqa 0x160(%rsp), %xmm0
vmovdqu %xmm0, (%rax)
leaq 0x328(%rsp), %rdi
callq 0x64c0
movq %rax, 0x50(%rsp)
jmp 0x2a0f
movq 0x50(%rsp), %rdi
leaq 0x105ed(%rip), %rsi     # 0x13008
callq 0x21e0
jmp 0x2a22
movq 0x230(%rsp), %rax
movq %rax, 0x150(%rsp)
vmovdqa 0x220(%rsp), %xmm0
vmovdqa %xmm0, 0x140(%rsp)
movq 0x150(%rsp), %rcx
movq %rsp, %rax
movq %rcx, 0x10(%rax)
vmovdqa 0x140(%rsp), %xmm0
vmovdqu %xmm0, (%rax)
leaq 0x328(%rsp), %rdi
callq 0x64c0
movq %rax, 0x48(%rsp)
jmp 0x2a74
movq 0x48(%rsp), %rdi
leaq 0x10588(%rip), %rsi     # 0x13008
callq 0x21e0
jmp 0x2a87
movq 0x1f0(%rsp), %rax
movq %rax, 0x130(%rsp)
vmovdqa 0x1e0(%rsp), %xmm0
vmovdqa %xmm0, 0x120(%rsp)
movq 0x130(%rsp), %rcx
movq %rsp, %rax
movq %rcx, 0x10(%rax)
vmovdqa 0x120(%rsp), %xmm0
vmovdqu %xmm0, (%rax)
leaq 0x328(%rsp), %rdi
callq 0x64c0
movq %rax, 0x40(%rsp)
jmp 0x2ad9
movq 0x40(%rsp), %rdi
leaq 0x10523(%rip), %rsi     # 0x13008
callq 0x21e0
jmp 0x2aec
xorl %edi, %edi
leaq 0x4b0(%rsp), %rsi
callq 0x6540
jmp 0x2afd
xorl %edi, %edi
leaq 0x328(%rsp), %rsi
callq 0x6540
jmp 0x2b0e
movl $0x0, 0x118(%rsp)
leaq 0x118(%rsp), %rax
movq %rax, 0xf8(%rsp)
leaq 0x4b0(%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 0x6540
jmp 0x2b62
xorl %edi, %edi
leaq 0x328(%rsp), %rsi
callq 0x6540
jmp 0x2b73
leaq 0xd8(%rsp), %rdi
leaq 0x4b0(%rsp), %rsi
callq 0x6560
jmp 0x2b8a
leaq 0x4b0(%rsp), %rdi
movq %rdi, 0xc8(%rsp)
leaq 0x328(%rsp), %rsi
movq %rsi, 0xd0(%rsp)
vmovdqu 0xc8(%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 0x2ce0
jmp 0x2bea
leaq 0xd8(%rsp), %rdi
callq 0x65b0
movq 0x183da(%rip), %rdi     # 0x1afd8
leaq 0x10409(%rip), %rsi     # 0x1300e
callq 0x2150
movq %rax, 0x38(%rsp)
jmp 0x2c11
movq 0x38(%rsp), %rdi
movl 0x118(%rsp), %esi
callq 0x2260
movq %rax, 0x30(%rsp)
jmp 0x2c29
movq 0x30(%rsp), %rdi
movq 0x18393(%rip), %rsi     # 0x1afc8
callq 0x2190
jmp 0x2c3c
leaq 0x328(%rsp), %rdi
callq 0x6610
leaq 0x4b0(%rsp), %rdi
callq 0x6610
xorl %eax, %eax
addq $0x4e8, %rsp            # imm = 0x4E8
retq
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x498(%rsp)
movl %eax, 0x494(%rsp)
jmp 0x2cba
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x498(%rsp)
movl %eax, 0x494(%rsp)
jmp 0x2cad
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x498(%rsp)
movl %eax, 0x494(%rsp)
leaq 0xd8(%rsp), %rdi
callq 0x65b0
leaq 0x328(%rsp), %rdi
callq 0x6610
leaq 0x4b0(%rsp), %rdi
callq 0x6610
movq 0x498(%rsp), %rdi
callq 0x2270
nopw %cs:(%rax,%rax)