// File: /workspace/github_cpp_makefile_star2_O2/JameyWoo[P]re2graph/algorithms.cpp
// Function: nfa2dot(NFA, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>)
void nfa2dot(NFA nfa, string dot_file) {
    // 合并起点终点相同的边, 用一个矩阵来存储
    vector<vector<vector<char>>> merge_jump(nfa.state_cnt, vector<vector<char>>(nfa.state_cnt, vector<char>()));
    for (int i = 0; i < nfa.state_cnt; ++i) {
        auto sm = nfa.jump[i];
        for (auto m : sm) {
            for (auto v : m.second) {
                merge_jump[i][v].push_back(m.first);
            }
        }
    }
    // cout << "dot_file: " << dot_file << endl;
    ofstream write;
    write.open(dot_file, ios::out | ios::trunc);
    // 写入文件开始
    write << "digraph {" << endl;
    // 写入状态
    for (int i = 0; i < nfa.state_cnt; ++i) {
        write << "\t" + to_string(i) + " [label=\"" + to_string(i) + "\"";
        if (count(nfa.end_states.begin(), nfa.end_states.end(), i)) {
            write << " color=red shape=doublecircle";  // 如果是终止状态, 那么结点为红色, 且为双圆型
        }
        write << "]" << endl;
    }
    // * 可以合并的边, 检测到连续3个或以上的 +1递增 的条件就合并, 用 - 连接
    for (int i = 0; i < nfa.state_cnt; ++i) {
        for (int j = 0; j < nfa.state_cnt; ++j) {
            if (merge_jump[i][j].size()) {
                string cond = "\"";
                cond += merge_jump[i][j][0];
                cond += ',';
                int ins = 1;
                for (int k = 1; k < merge_jump[i][j].size(); ++k) {
                    if (merge_jump[i][j][k] == merge_jump[i][j][k - 1] + 1) {
                        ins += 1;
                    } else {
                        if (ins >= 3) {
                            for (int l = 0; l < 2 * ins - 1; ++l) {
                                cond.pop_back();
                            }
                            cond += '-';
                            cond += merge_jump[i][j][k - 1];
                            cond += ',';
                            ins = 1;
                        }
                    }
                    cond += merge_jump[i][j][k];
                    cond += ',';
                    // cout << "cond: " << cond << endl;
                }
                if (ins >= 3) {
                    for (int l = 0; l < 2 * ins - 1; ++l) {
                        cond.pop_back();
                    }
                    cond += '-';
                    cond += merge_jump[i][j].back();
                    cond.push_back(',');
                    ins = 1;
                }
                cond.erase(cond.end() - 1);
                cond += '"';
                // cout << "cond = " << cond << endl;
                write << "\t" + to_string(i) + " -> " + to_string(j) + " [label=" + cond + "]" << endl;
            }
        }
    }
    write << "}";
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x358, %rsp            # imm = 0x358
movq %rsi, %r15
movq %rdi, %rbx
movslq 0x4(%rdi), %r14
xorps %xmm0, %xmm0
leaq 0x30(%rsp), %rdx
movaps %xmm0, (%rdx)
andq $0x0, 0x10(%rdx)
leaq 0x158(%rsp), %rdi
leaq 0xb8(%rsp), %rcx
movq %r14, %rsi
callq 0x97b6
movq %r15, 0x10(%rsp)
leaq 0x18(%rsp), %rdi
leaq 0x158(%rsp), %rdx
leaq 0x98(%rsp), %rcx
movq %r14, %rsi
callq 0x980c
leaq 0x158(%rsp), %r14
movq %r14, %rdi
callq 0x9862
leaq 0x30(%rsp), %r12
movq %r12, %rdi
callq 0x321a
leaq 0x160(%rsp), %rbp
xorl %ecx, %ecx
movq %rbx, (%rsp)
movslq 0x4(%rbx), %rax
cmpq %rax, %rcx
jge 0x67e1
imulq $0x30, %rcx, %rsi
addq 0x58(%rbx), %rsi
movq %r14, %rdi
movq %rcx, %rbx
callq 0x343a
movq 0x170(%rsp), %r13
movq %rbx, 0x8(%rsp)
imulq $0x18, %rbx, %r14
cmpq %rbp, %r13
je 0x67c0
leaq 0x20(%r13), %rsi
movq %r12, %rdi
callq 0x3698
movq 0x38(%rsp), %rbx
movq 0x40(%rsp), %r15
cmpq %r15, %rbx
je 0x67a9
movslq (%rbx), %rax
movq 0x18(%rsp), %rcx
imulq $0x18, %rax, %rdi
addq (%rcx,%r14), %rdi
movq %r12, %rsi
callq 0x8b80
addq $0x4, %rbx
jmp 0x6786
leaq 0x38(%rsp), %rdi
callq 0x329e
movq %r13, %rdi
callq 0x2170
movq %rax, %r13
jmp 0x676b
leaq 0x158(%rsp), %r14
movq %r14, %rdi
callq 0x3706
movq 0x8(%rsp), %rcx
incq %rcx
movq (%rsp), %rbx
jmp 0x673a
leaq 0x158(%rsp), %rdi
callq 0x2350
leaq 0x158(%rsp), %rdi
pushq $0x30
popq %rdx
movq 0x10(%rsp), %rsi
callq 0x20e0
leaq 0x89e1(%rip), %rsi      # 0xf1eb
leaq 0x158(%rsp), %rdi
callq 0x21f0
movq %rax, %rdi
callq 0x20f0
xorl %esi, %esi
leaq 0xd8(%rsp), %rbx
leaq 0xf8(%rsp), %r15
leaq 0x98(%rsp), %r13
leaq 0x78(%rsp), %rbp
leaq 0xb8(%rsp), %r14
leaq 0x30(%rsp), %r12
movl %esi, 0x58(%rsp)
movq (%rsp), %rax
movl 0x4(%rax), %eax
cmpl %eax, %esi
jge 0x694c
movq %rbx, %rdi
callq 0x9591
movq %r15, %rdi
leaq 0x8985(%rip), %rsi      # 0xf1f5
movq %rbx, %rdx
callq 0x9883
movq %r13, %rdi
movq %r15, %rsi
leaq 0x8972(%rip), %rdx      # 0xf1f7
callq 0x9371
movl 0x58(%rsp), %esi
movq %rbp, %rdi
callq 0x9591
movq %r14, %rdi
movq %r13, %rsi
movq %rbp, %rdx
callq 0x9508
movq %r12, %rdi
movq %r14, %rsi
leaq 0x894e(%rip), %rdx      # 0xf1ff
callq 0x9371
leaq 0x158(%rsp), %rdi
movq %r12, %rsi
callq 0x21e0
movq %r12, %rdi
callq 0x20d0
movq %r14, %rdi
callq 0x20d0
movq %rbp, %rdi
callq 0x20d0
movq %r13, %rdi
callq 0x20d0
movq %r15, %rdi
callq 0x20d0
movq %rbx, %rdi
callq 0x20d0
movq (%rsp), %rax
movq 0x40(%rax), %rdi
movq 0x48(%rax), %rsi
leaq 0x58(%rsp), %rdx
callq 0xcd59
testq %rax, %rax
je 0x6925
leaq 0x158(%rsp), %rdi
leaq 0x88e1(%rip), %rsi      # 0xf201
callq 0x21f0
leaq 0x158(%rsp), %rdi
leaq 0x8928(%rip), %rsi      # 0xf25c
callq 0x21f0
movq %rax, %rdi
callq 0x20f0
movl 0x58(%rsp), %esi
incl %esi
jmp 0x684b
xorl %ebx, %ebx
leaq 0x30(%rsp), %r12
leaq 0xb8(%rsp), %r14
pushq $0x2c
popq %rbp
movslq %eax, %rcx
cmpq %rcx, %rbx
jge 0x6c53
imulq $0x18, %rbx, %r13
xorl %edx, %edx
movq %rbx, 0x10(%rsp)
movslq %eax, %rcx
cmpq %rcx, %rdx
jge 0x6c4b
movq 0x18(%rsp), %rcx
movq (%rcx,%r13), %rcx
movq %rdx, 0x8(%rsp)
imulq $0x18, %rdx, %r15
movq 0x8(%rcx,%r15), %rdx
cmpq (%rcx,%r15), %rdx
je 0x6c3e
movq %r12, %rdi
leaq 0x8853(%rip), %rsi      # 0xf1ff
movq %r14, %rdx
callq 0x2f70
movq 0x18(%rsp), %rax
movq (%rax,%r13), %rax
movq (%rax,%r15), %rax
movsbl (%rax), %esi
movq %r12, %rdi
callq 0x21c0
movq %r12, %rdi
movl %ebp, %esi
callq 0x21c0
pushq $0x1
popq %rbx
pushq $0x1
popq %rax
movl %eax, %r14d
movq 0x18(%rsp), %rax
movq (%rax,%r13), %rax
movq (%rax,%r15), %rcx
movq 0x8(%rax,%r15), %rax
subq %rcx, %rax
cmpq %rbx, %rax
jbe 0x6a91
movsbl (%rcx,%rbx), %eax
movsbl -0x1(%rcx,%rbx), %ecx
incl %ecx
cmpl %eax, %ecx
jne 0x6a11
incl %r14d
jmp 0x6a74
cmpl $0x3, %r14d
jl 0x6a74
leal -0x1(,%r14,2), %r14d
subl $0x1, %r14d
jb 0x6a2f
movq %r12, %rdi
callq 0x2280
jmp 0x6a1f
movq %r12, %rdi
pushq $0x2d
popq %rsi
callq 0x21c0
movq 0x18(%rsp), %rax
movq (%rax,%r13), %rax
movq (%rax,%r15), %rax
movsbl -0x1(%rax,%rbx), %esi
movq %r12, %rdi
callq 0x21c0
movq %r12, %rdi
movl %ebp, %esi
callq 0x21c0
movq 0x18(%rsp), %rax
movq (%rax,%r13), %rax
movq (%rax,%r15), %rax
movb (%rax,%rbx), %al
pushq $0x1
popq %rcx
movl %ecx, %r14d
movsbl %al, %esi
movq %r12, %rdi
callq 0x21c0
movq %r12, %rdi
movl %ebp, %esi
callq 0x21c0
incq %rbx
jmp 0x69df
cmpl $0x3, %r14d
jl 0x6add
leal -0x1(,%r14,2), %ebx
subl $0x1, %ebx
jb 0x6aae
movq %r12, %rdi
callq 0x2280
jmp 0x6a9f
movq %r12, %rdi
pushq $0x2d
popq %rsi
callq 0x21c0
movq 0x18(%rsp), %rax
movq (%rax,%r13), %rax
movq 0x8(%rax,%r15), %rax
movsbl -0x1(%rax), %esi
movq %r12, %rdi
callq 0x21c0
movq %r12, %rdi
movl %ebp, %esi
callq 0x21c0
movq 0x30(%rsp), %rax
movq 0x38(%rsp), %rcx
leaq (%rax,%rcx), %rsi
decq %rsi
movq %r12, %rdi
callq 0x22a0
movq %r12, %rdi
pushq $0x22
popq %rsi
callq 0x21c0
leaq 0x138(%rsp), %r14
movq %r14, %rdi
movq 0x10(%rsp), %rbx
movl %ebx, %esi
callq 0x9591
leaq 0x58(%rsp), %r15
movq %r15, %rdi
leaq 0x86ce(%rip), %rsi      # 0xf1f5
movq %r14, %rdx
callq 0x9883
leaq 0x78(%rsp), %rdi
movq %r15, %rsi
leaq 0x86e1(%rip), %rdx      # 0xf21f
callq 0x9371
leaq 0x118(%rsp), %r14
movq %r14, %rdi
movq 0x8(%rsp), %rsi
callq 0x9591
leaq 0xd8(%rsp), %r15
movq %r15, %rdi
leaq 0x78(%rsp), %rsi
movq %r14, %rdx
callq 0x9508
leaq 0xf8(%rsp), %r14
movq %r14, %rdi
movq %r15, %rsi
leaq 0x869f(%rip), %rdx      # 0xf224
callq 0x9371
leaq 0x98(%rsp), %r15
movq %r15, %rdi
movq %r14, %rsi
movq %r12, %rdx
callq 0x9390
leaq 0xb8(%rsp), %r14
movq %r14, %rdi
movq %r15, %rsi
leaq 0x86a7(%rip), %rdx      # 0xf25c
callq 0x9371
leaq 0x158(%rsp), %rdi
movq %r14, %rsi
callq 0x21e0
movq %rax, %rdi
callq 0x20f0
movq %r14, %rdi
callq 0x20d0
leaq 0x98(%rsp), %rdi
callq 0x20d0
leaq 0xf8(%rsp), %rdi
callq 0x20d0
leaq 0xd8(%rsp), %rdi
callq 0x20d0
leaq 0x118(%rsp), %rdi
callq 0x20d0
leaq 0x78(%rsp), %rdi
callq 0x20d0
leaq 0x58(%rsp), %rdi
callq 0x20d0
leaq 0x138(%rsp), %rdi
callq 0x20d0
movq %r12, %rdi
callq 0x20d0
movq (%rsp), %rax
movl 0x4(%rax), %eax
movq 0x8(%rsp), %rdx
incq %rdx
jmp 0x6975
incq %rbx
jmp 0x695e
leaq 0x858f(%rip), %rsi      # 0xf1e9
leaq 0x158(%rsp), %rdi
callq 0x21f0
leaq 0x158(%rsp), %rdi
callq 0x22f0
leaq 0x18(%rsp), %rdi
callq 0x98a8
addq $0x358, %rsp            # imm = 0x358
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x6d24
movq %rax, %rbx
leaq 0x158(%rsp), %rdi
callq 0x9862
jmp 0x6caa
movq %rax, %rbx
leaq 0x30(%rsp), %rdi
callq 0x321a
jmp 0x6e13
jmp 0x6d5b
movq %rax, %rbx
leaq 0x30(%rsp), %rdi
callq 0x20d0
jmp 0x6cd0
movq %rax, %rbx
leaq 0xb8(%rsp), %rdi
callq 0x20d0
jmp 0x6ce2
movq %rax, %rbx
leaq 0x78(%rsp), %rdi
callq 0x20d0
jmp 0x6cf1
movq %rax, %rbx
leaq 0x98(%rsp), %rdi
callq 0x20d0
leaq 0xf8(%rsp), %rdi
callq 0x20d0
leaq 0xd8(%rsp), %rdi
jmp 0x6df7
movq %rax, %rbx
jmp 0x6cfe
movq %rax, %rbx
jmp 0x6d0b
jmp 0x6d5b
movq %rax, %rbx
jmp 0x6e09
jmp 0x6d5b
jmp 0x6def
movq %rax, %rbx
jmp 0x6d78
movq %rax, %rbx
jmp 0x6d92
movq %rax, %rbx
jmp 0x6d85
movq %rax, %rbx
jmp 0x6d9f
movq %rax, %rbx
jmp 0x6dc0
movq %rax, %rbx
jmp 0x6dac
movq %rax, %rbx
jmp 0x6db6
jmp 0x6def
movq %rax, %rbx
jmp 0x6dfc
movq %rax, %rbx
jmp 0x6de0
movq %rax, %rbx
leaq 0xb8(%rsp), %rdi
callq 0x20d0
leaq 0x98(%rsp), %rdi
callq 0x20d0
leaq 0xf8(%rsp), %rdi
callq 0x20d0
leaq 0xd8(%rsp), %rdi
callq 0x20d0
leaq 0x118(%rsp), %rdi
callq 0x20d0
leaq 0x78(%rsp), %rdi
callq 0x20d0
leaq 0x58(%rsp), %rdi
callq 0x20d0
leaq 0x138(%rsp), %rdi
callq 0x20d0
jmp 0x6df2
jmp 0x6def
jmp 0x6def
movq %rax, %rbx
leaq 0x38(%rsp), %rdi
callq 0x329e
leaq 0x158(%rsp), %rdi
callq 0x3706
jmp 0x6e09
movq %rax, %rbx
leaq 0x30(%rsp), %rdi
callq 0x20d0
leaq 0x158(%rsp), %rdi
callq 0x22f0
leaq 0x18(%rsp), %rdi
callq 0x98a8
movq %rbx, %rdi
callq 0x2370