// File: /workspace/github_cpp_makefile_star2_O2/JameyWoo[P]re2graph/algorithms.cpp
// Function: dfa2dot(DFA, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>)
void dfa2dot(DFA dfa, string dot_file) {
    // 合并起点终点相同的边, 用一个矩阵来存储
    vector<vector<vector<char>>> merge_jump(dfa.state_cnt, vector<vector<char>>(dfa.state_cnt, vector<char>()));
    for (int i = 0; i < dfa.state_cnt; ++i) {
        auto sm = dfa.jump_map[i];
        for (auto m : sm) {
            merge_jump[i][m.second].push_back(m.first);
        }
    }
    ofstream write;
    write.open(dot_file, ios::out | ios::trunc);
    // 写入文件开始
    write << "digraph {" << endl;
    // 写入状态
    for (int i = 0; i < dfa.state_cnt; ++i) {
        write << "\t" + to_string(i) + " [label=\"" + to_string(i) + "\"";
        if (count(dfa.end_states.begin(), dfa.end_states.end(), i)) {
            write << " color=red shape=doublecircle";  // 如果是终止状态, 那么结点为红色, 且为双圆型
        }
        write << "]" << endl;
    }
    // * 可以合并的边, 检测到连续3个或以上的 +1递增 的条件就合并, 用 - 连接
    for (int i = 0; i < dfa.state_cnt; ++i) {
        for (int j = 0; j < dfa.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), %r15
movq %r15, %rdi
callq 0x321a
leaq 0x160(%rsp), %r13
xorl %ebp, %ebp
movq %rbx, 0x8(%rsp)
movslq 0x4(%rbx), %rax
cmpq %rax, %rbp
jge 0x7150
imulq $0x30, %rbp, %rsi
addq 0x58(%rbx), %rsi
movq %r14, %rdi
callq 0x38b2
movq 0x170(%rsp), %r12
imulq $0x18, %rbp, %rbx
cmpq %r13, %r12
je 0x713e
movq 0x20(%r12), %rax
movq %rax, 0x30(%rsp)
movq 0x18(%rsp), %rcx
sarq $0x20, %rax
imulq $0x18, %rax, %rdi
addq (%rcx,%rbx), %rdi
movq %r15, %rsi
callq 0x8b80
movq %r12, %rdi
callq 0x2170
movq %rax, %r12
jmp 0x7109
movq %r14, %rdi
callq 0x3af6
incq %rbp
movq 0x8(%rsp), %rbx
jmp 0x70e4
leaq 0x158(%rsp), %rdi
callq 0x2350
leaq 0x158(%rsp), %rdi
pushq $0x30
popq %rdx
movq 0x10(%rsp), %rsi
callq 0x20e0
leaq 0x8072(%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 0x8(%rsp), %rax
movl 0x4(%rax), %eax
cmpl %eax, %esi
jge 0x72bd
movq %rbx, %rdi
callq 0x9591
movq %r15, %rdi
leaq 0x8015(%rip), %rsi      # 0xf1f5
movq %rbx, %rdx
callq 0x9883
movq %r13, %rdi
movq %r15, %rsi
leaq 0x8002(%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 0x7fde(%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 0x8(%rsp), %rax
movq 0x40(%rax), %rdi
movq 0x48(%rax), %rsi
leaq 0x58(%rsp), %rdx
callq 0xcd59
testq %rax, %rax
je 0x7296
leaq 0x158(%rsp), %rdi
leaq 0x7f70(%rip), %rsi      # 0xf201
callq 0x21f0
leaq 0x158(%rsp), %rdi
leaq 0x7fb7(%rip), %rsi      # 0xf25c
callq 0x21f0
movq %rax, %rdi
callq 0x20f0
movl 0x58(%rsp), %esi
incl %esi
jmp 0x71ba
xorl %ebx, %ebx
leaq 0x30(%rsp), %r12
leaq 0xb8(%rsp), %r14
pushq $0x2c
popq %rbp
movslq %eax, %rcx
cmpq %rcx, %rbx
jge 0x75c5
imulq $0x18, %rbx, %r13
xorl %edx, %edx
movq %rbx, 0x50(%rsp)
movslq %eax, %rcx
cmpq %rcx, %rdx
jge 0x75bd
movq 0x18(%rsp), %rcx
movq (%rcx,%r13), %rcx
movq %rdx, 0x10(%rsp)
imulq $0x18, %rdx, %r15
movq 0x8(%rcx,%r15), %rdx
cmpq (%rcx,%r15), %rdx
je 0x75b0
movq %r12, %rdi
leaq 0x7ee2(%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 0x7402
movsbl (%rcx,%rbx), %eax
movsbl -0x1(%rcx,%rbx), %ecx
incl %ecx
cmpl %eax, %ecx
jne 0x7382
incl %r14d
jmp 0x73e5
cmpl $0x3, %r14d
jl 0x73e5
leal -0x1(,%r14,2), %r14d
subl $0x1, %r14d
jb 0x73a0
movq %r12, %rdi
callq 0x2280
jmp 0x7390
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 0x7350
cmpl $0x3, %r14d
jl 0x744e
leal -0x1(,%r14,2), %ebx
subl $0x1, %ebx
jb 0x741f
movq %r12, %rdi
callq 0x2280
jmp 0x7410
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 0x50(%rsp), %rbx
movl %ebx, %esi
callq 0x9591
leaq 0x58(%rsp), %r15
movq %r15, %rdi
leaq 0x7d5d(%rip), %rsi      # 0xf1f5
movq %r14, %rdx
callq 0x9883
leaq 0x78(%rsp), %rdi
movq %r15, %rsi
leaq 0x7d70(%rip), %rdx      # 0xf21f
callq 0x9371
leaq 0x118(%rsp), %r14
movq %r14, %rdi
movq 0x10(%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 0x7d2e(%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 0x7d36(%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 0x8(%rsp), %rax
movl 0x4(%rax), %eax
movq 0x10(%rsp), %rdx
incq %rdx
jmp 0x72e6
incq %rbx
jmp 0x72cf
leaq 0x7c1d(%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 0x7696
movq %rax, %rbx
leaq 0x158(%rsp), %rdi
callq 0x9862
jmp 0x761c
movq %rax, %rbx
leaq 0x30(%rsp), %rdi
callq 0x321a
jmp 0x777c
jmp 0x76d0
movq %rax, %rbx
leaq 0x30(%rsp), %rdi
callq 0x20d0
jmp 0x7642
movq %rax, %rbx
leaq 0xb8(%rsp), %rdi
callq 0x20d0
jmp 0x7654
movq %rax, %rbx
leaq 0x78(%rsp), %rdi
callq 0x20d0
jmp 0x7663
movq %rax, %rbx
leaq 0x98(%rsp), %rdi
callq 0x20d0
leaq 0xf8(%rsp), %rdi
callq 0x20d0
leaq 0xd8(%rsp), %rdi
jmp 0x7760
movq %rax, %rbx
jmp 0x7670
movq %rax, %rbx
jmp 0x767d
jmp 0x76d0
movq %rax, %rbx
jmp 0x7772
jmp 0x76d0
jmp 0x7758
movq %rax, %rbx
jmp 0x76fd
movq %rax, %rbx
jmp 0x7717
movq %rax, %rbx
jmp 0x770a
movq %rax, %rbx
jmp 0x7724
movq %rax, %rbx
jmp 0x7745
movq %rax, %rbx
jmp 0x7731
movq %rax, %rbx
jmp 0x773b
jmp 0x7758
movq %rax, %rbx
jmp 0x7765
movq %rax, %rbx
leaq 0x158(%rsp), %rdi
callq 0x3af6
jmp 0x7772
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 0x775b
jmp 0x7758
jmp 0x7758
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