// File: /workspace/github_cpp_makefile_star2_O3/canzarlab[P]Trajan/src/match.cpp
// Function: main
int main(int argc, char** argv)
{
    if (argc != 6)
    {
        cout << "usage: " << argv[0] << " <tree1> <map1> <tree2> <map2> <matrix>\n";
        return 0;
    }
    // load the data
    tree t1(argv[1], argv[2]);
    tree t2(argv[3], argv[4]);
    vector<vector<double>> cost_matrix = CSVReader(argv[5]).getDoubleData();

    // last row/column is deletion cost
    array2d minmatrix(t1.n + 1, t2.n + 1);

    // convert scores to integers
    const double scale = 1000;
    for (int i = 0; i < t1.n + 1; ++i)
        for (int j = 0; j < t2.n + 1; ++j)
            minmatrix(i, j) = scale * cost_matrix[i][j];

    // convert into maximization problem
    array2d maxmatrix(t1.n, t2.n);
    for (int i = 0; i < t1.n; ++i)
        for (int j = 0; j < t2.n; ++j)
            maxmatrix(i, j) = minmatrix(i, t2.n) + minmatrix(t1.n, j) - minmatrix(i, j);

    // minimization score of empty matching
    int null_score = 0;
    for (int i = 0; i < t1.n; ++i)
        null_score += minmatrix(i, t2.n);
    for (int i = 0; i < t2.n; ++i)
        null_score += minmatrix(t1.n, i);

    // compute optimal tree to tree matching
    // note: first node in topological ordering is the root
    int weight = forest_forest(t1, t2, maxmatrix, 1, 1);

    // recover the matching
    vector<pair<int, int>> matching;
    recover_matching(t1, t2, matching, 1, 1);

    // weight of recovered matching (for sanity check)
    int mweight = 0;
    for (auto [x, y] : matching)
        mweight += maxmatrix(x, y);

    // convert to minimization score
    weight = null_score - weight;
    mweight = null_score - mweight;

    // verify the matching
    assert(verify(t1, t2, matching));
    assert(weight == mweight);

    // scale back the score
    clog << weight / scale << endl;

    // print the matching
    for (auto [x, y] : matching)
        cout << t1.rm[x] << ' ' << t2.rm[y] << '\n';
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x10798, %rsp          # imm = 0x10798
movq %rsi, %rbx
cmpl $0x6, %edi
jne 0x5478
movq 0x8(%rbx), %rsi
movq 0x10(%rbx), %rdx
leaq 0xe8(%rsp), %rdi
callq 0x5d12
movq 0x18(%rbx), %rsi
movq 0x20(%rbx), %rdx
leaq 0x8440(%rsp), %rdi
callq 0x5d12
movq 0x28(%rbx), %rsi
leaq 0xb0(%rsp), %rdi
leaq 0x30(%rsp), %rdx
callq 0x651c
leaq 0xa0(%rsp), %r14
movq %r14, -0x10(%r14)
leaq 0x6e5d(%rip), %rsi      # 0xc0b1
leaq 0x6e57(%rip), %rdx      # 0xc0b2
leaq 0x90(%rsp), %rdi
callq 0x7318
leaq 0x50(%rsp), %rdi
leaq 0xb0(%rsp), %rsi
leaq 0x90(%rsp), %rdx
callq 0x655a
leaq 0xd0(%rsp), %rdi
leaq 0x50(%rsp), %rsi
xorl %edx, %edx
movl $0x2710, %ecx           # imm = 0x2710
callq 0x88e0
leaq 0x80(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x52bc
movq 0x80(%rsp), %rsi
incq %rsi
callq 0x3230
leaq 0x60(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x52d7
movq 0x60(%rsp), %rsi
incq %rsi
callq 0x3230
movq 0x90(%rsp), %rdi
cmpq %r14, %rdi
je 0x52f4
movq 0xa0(%rsp), %rsi
incq %rsi
callq 0x3230
leaq 0xc0(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x5315
movq 0xc0(%rsp), %rsi
incq %rsi
callq 0x3230
movl 0x5ef0(%rsp), %esi
incl %esi
movl 0xe248(%rsp), %edx
incl %edx
leaq 0x50(%rsp), %rdi
movl $0x80000000, %ecx       # imm = 0x80000000
callq 0x5968
movl 0x5ef0(%rsp), %esi
movl 0xe248(%rsp), %edx
testl %esi, %esi
js 0x53b9
movq 0xd0(%rsp), %rax
movq 0x58(%rsp), %rcx
xorl %edi, %edi
movsd 0x6cf1(%rip), %xmm0     # 0xc050
testl %edx, %edx
js 0x53aa
leaq (%rdi,%rdi,2), %rdx
movq (%rax,%rdx,8), %rsi
movslq %edi, %r8
xorl %r9d, %r9d
movsd (%rsi,%r9,8), %xmm1
mulsd %xmm0, %xmm1
cvttsd2si %xmm1, %edx
movslq 0x54(%rsp), %r10
imulq %r8, %r10
addq %r9, %r10
movl %edx, (%rcx,%r10,4)
leaq 0x1(%r9), %r10
movslq 0xe248(%rsp), %rdx
cmpq %rdx, %r9
movq %r10, %r9
jl 0x5371
movl 0x5ef0(%rsp), %esi
leaq 0x1(%rdi), %r8
movslq %esi, %r9
cmpq %r9, %rdi
movq %r8, %rdi
jl 0x535f
leaq 0x30(%rsp), %rdi
movl $0x80000000, %ecx       # imm = 0x80000000
callq 0x5968
movl 0x5ef0(%rsp), %ecx
movl 0xe248(%rsp), %eax
testl %ecx, %ecx
jle 0x54be
movq 0x58(%rsp), %rdx
xorl %esi, %esi
movq 0x38(%rsp), %rdi
testl %eax, %eax
jle 0x5449
movslq %esi, %rcx
xorl %r8d, %r8d
movslq 0x54(%rsp), %r9
movslq 0x5ef0(%rsp), %r10
imulq %r9, %r10
imull %esi, %r9d
addl %r9d, %eax
cltq
addq %r8, %r10
movl (%rdx,%r10,4), %r10d
addl (%rdx,%rax,4), %r10d
movslq %r9d, %rax
addq %r8, %rax
subl (%rdx,%rax,4), %r10d
movslq 0x34(%rsp), %rax
imulq %rcx, %rax
addq %r8, %rax
movl %r10d, (%rdi,%rax,4)
movl 0xe248(%rsp), %eax
incq %r8
cmpl %eax, %r8d
jl 0x53f4
movl 0x5ef0(%rsp), %ecx
incl %esi
cmpl %ecx, %esi
jl 0x53ea
testl %ecx, %ecx
jle 0x54be
movslq 0x54(%rsp), %rdx
movslq %eax, %rsi
movl %ecx, %edi
shlq $0x2, %rsi
addq 0x58(%rsp), %rsi
shlq $0x2, %rdx
xorl %ebp, %ebp
addl (%rsi), %ebp
addq %rdx, %rsi
decq %rdi
jne 0x546c
jmp 0x54c0
movq 0xbb51(%rip), %r14      # 0x10fd0
leaq 0x6bfa(%rip), %rsi      # 0xc080
movl $0x7, %edx
movq %r14, %rdi
callq 0x3270
movq (%rbx), %rbx
testq %rbx, %rbx
je 0x5582
movq %rbx, %rdi
callq 0x3100
movq 0xbb22(%rip), %rdi      # 0x10fd0
movq %rbx, %rsi
movq %rax, %rdx
callq 0x3270
jmp 0x559a
xorl %ebp, %ebp
testl %eax, %eax
jle 0x54e8
movslq 0x54(%rsp), %rdx
movslq %ecx, %rcx
imulq %rdx, %rcx
movl %eax, %eax
shlq $0x2, %rcx
addq 0x58(%rsp), %rcx
xorl %edx, %edx
addl (%rcx,%rdx,4), %ebp
incq %rdx
cmpq %rdx, %rax
jne 0x54dd
leaq 0xe8(%rsp), %rdi
leaq 0x8440(%rsp), %rsi
leaq 0x30(%rsp), %rdx
movl $0x1, %ecx
movl $0x1, %r8d
callq 0x3d84
movl %eax, %ebx
xorpd %xmm0, %xmm0
leaq 0x10(%rsp), %rdx
movapd %xmm0, (%rdx)
movq $0x0, 0x10(%rdx)
leaq 0xe8(%rsp), %rdi
leaq 0x8440(%rsp), %rsi
movl $0x1, %ecx
movl $0x1, %r8d
callq 0x4a4f
movq 0x10(%rsp), %rax
movq 0x18(%rsp), %rcx
cmpq %rcx, %rax
je 0x55b7
movl 0x34(%rsp), %edx
xorl %r14d, %r14d
movq 0x38(%rsp), %rsi
movq (%rax), %rdi
movl %edx, %r8d
imull %edi, %r8d
shrq $0x20, %rdi
addl %edi, %r8d
movslq %r8d, %rdi
addl (%rsi,%rdi,4), %r14d
addq $0x8, %rax
cmpq %rcx, %rax
jne 0x555f
jmp 0x55ba
movq (%r14), %rax
movq -0x18(%rax), %rax
leaq (%r14,%rax), %rdi
movl 0x20(%r14,%rax), %esi
orl $0x1, %esi
callq 0x33b0
movq 0xba2f(%rip), %rdi      # 0x10fd0
leaq 0x6ae0(%rip), %rsi      # 0xc088
movl $0x28, %edx
callq 0x3270
jmp 0x57a3
xorl %r14d, %r14d
leaq 0xe8(%rsp), %rdi
leaq 0x8440(%rsp), %rsi
leaq 0x10(%rsp), %rdx
callq 0x4e63
testb %al, %al
je 0x57b7
cmpl %ebx, %r14d
jne 0x57d6
subl %ebx, %ebp
xorps %xmm0, %xmm0
cvtsi2sd %ebp, %xmm0
divsd 0x6a5a(%rip), %xmm0     # 0xc050
movq 0xb9ab(%rip), %rdi      # 0x10fa8
callq 0x3340
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x3210
movsbl %al, %esi
movq %rbx, %rdi
callq 0x3040
movq %rax, %rdi
callq 0x3190
movq 0x10(%rsp), %rbx
movq 0x18(%rsp), %r12
cmpq %r12, %rbx
je 0x56c7
movq 0xb98a(%rip), %r14      # 0x10fd0
leaq 0xf(%rsp), %r15
movq (%rbx), %r13
movq 0x118(%rsp), %rax
movslq %r13d, %rcx
shlq $0x5, %rcx
movq (%rax,%rcx), %rsi
movq 0x8(%rax,%rcx), %rdx
movq %r14, %rdi
callq 0x3270
movb $0x20, 0xf(%rsp)
movl $0x1, %edx
movq %rax, %rdi
movq %r15, %rsi
callq 0x3270
sarq $0x20, %r13
movq 0x8470(%rsp), %rcx
shlq $0x5, %r13
movq (%rcx,%r13), %rsi
movq 0x8(%rcx,%r13), %rdx
movq %rax, %rdi
callq 0x3270
movb $0xa, 0xf(%rsp)
movl $0x1, %edx
movq %rax, %rdi
movq %r15, %rsi
callq 0x3270
addq $0x8, %rbx
cmpq %r12, %rbx
jne 0x564b
movq 0x10(%rsp), %rbx
testq %rbx, %rbx
je 0x56dc
movq 0x20(%rsp), %rsi
subq %rbx, %rsi
movq %rbx, %rdi
callq 0x3230
movq 0x38(%rsp), %rdi
testq %rdi, %rdi
je 0x56f3
movq 0x48(%rsp), %rsi
subq %rdi, %rsi
callq 0x3230
movq 0x58(%rsp), %rdi
testq %rdi, %rdi
je 0x570a
movq 0x68(%rsp), %rsi
subq %rdi, %rsi
callq 0x3230
leaq 0xd0(%rsp), %rdi
callq 0x65f4
movl $0x5e00, %ebx           # imm = 0x5E00
movq 0x8430(%rsp,%rbx), %rdi
testq %rdi, %rdi
je 0x5739
movq 0x8440(%rsp,%rbx), %rsi
subq %rdi, %rsi
callq 0x3230
addq $-0x18, %rbx
cmpq $0x40, %rbx
jne 0x571c
leaq 0x8470(%rsp), %rdi
callq 0x69f8
leaq 0x8440(%rsp), %rdi
callq 0x72ca
movl $0x5e00, %ebx           # imm = 0x5E00
movq 0xd8(%rsp,%rbx), %rdi
testq %rdi, %rdi
je 0x577f
movq 0xe8(%rsp,%rbx), %rsi
subq %rdi, %rsi
callq 0x3230
addq $-0x18, %rbx
cmpq $0x40, %rbx
jne 0x5762
leaq 0x118(%rsp), %rdi
callq 0x69f8
leaq 0xe8(%rsp), %rdi
callq 0x72ca
xorl %eax, %eax
addq $0x10798, %rsp          # imm = 0x10798
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x68f5(%rip), %rdi      # 0xc0b3
leaq 0x6907(%rip), %rsi      # 0xc0cc
leaq 0x690e(%rip), %rcx      # 0xc0da
movl $0x2c8, %edx            # imm = 0x2C8
callq 0x3180
leaq 0x6914(%rip), %rdi      # 0xc0f1
leaq 0x68e8(%rip), %rsi      # 0xc0cc
leaq 0x68ef(%rip), %rcx      # 0xc0da
movl $0x2c9, %edx            # imm = 0x2C9
callq 0x3180
jmp 0x5872
movq %rax, %rbx
jmp 0x588c
movq %rax, %rbx
jmp 0x58a3
movq %rax, %rbx
jmp 0x58ba
movq %rax, %rbx
leaq 0x50(%rsp), %rdi
callq 0x65be
jmp 0x5821
movq %rax, %rbx
movq 0x90(%rsp), %rdi
cmpq %r14, %rdi
je 0x5843
movq 0xa0(%rsp), %rsi
incq %rsi
callq 0x3230
jmp 0x5843
movq %rax, %rbx
leaq 0xc0(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x58c7
movq 0xc0(%rsp), %rsi
incq %rsi
callq 0x3230
jmp 0x58c7
movq %rax, %rbx
jmp 0x58c7
movq %rax, %rbx
jmp 0x58d4
jmp 0x5872
movq %rax, %rbx
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x588c
movq 0x20(%rsp), %rsi
subq %rdi, %rsi
callq 0x3230
movq 0x38(%rsp), %rdi
testq %rdi, %rdi
je 0x58a3
movq 0x48(%rsp), %rsi
subq %rdi, %rsi
callq 0x3230
movq 0x58(%rsp), %rdi
testq %rdi, %rdi
je 0x58ba
movq 0x68(%rsp), %rsi
subq %rdi, %rsi
callq 0x3230
leaq 0xd0(%rsp), %rdi
callq 0x65f4
leaq 0x8440(%rsp), %rdi
callq 0x6648
leaq 0xe8(%rsp), %rdi
callq 0x6648
movq %rbx, %rdi
callq 0x33e0
nop