// File: /workspace/github_cpp_makefile_star2_O2/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 $0x10788, %rsp          # imm = 0x10788
movq %rsi, %rbx
cmpl $0x6, %edi
jne 0x4d6f
movq 0x8(%rbx), %rsi
movq 0x10(%rbx), %rdx
leaq 0x8430(%rsp), %rdi
callq 0x5414
movq 0x18(%rbx), %rsi
movq 0x20(%rbx), %rdx
leaq 0xd8(%rsp), %rdi
callq 0x5414
movq 0x28(%rbx), %rsi
leaq 0xb8(%rsp), %rdi
leaq 0x20(%rsp), %rdx
callq 0x5a0c
leaq 0x53e6(%rip), %rsi      # 0xa069
leaq 0x98(%rsp), %rdi
movq %rsp, %rdx
callq 0x5a0c
leaq 0x40(%rsp), %rdi
leaq 0xb8(%rsp), %rsi
leaq 0x98(%rsp), %rdx
callq 0x5a48
leaq 0x80(%rsp), %rdi
leaq 0x40(%rsp), %rsi
xorl %edx, %edx
movl $0x2710, %ecx           # imm = 0x2710
callq 0x7c7e
leaq 0x40(%rsp), %rdi
callq 0x5a7e
leaq 0x98(%rsp), %rdi
callq 0x3100
leaq 0xb8(%rsp), %rdi
callq 0x3100
movl 0xe238(%rsp), %esi
incl %esi
movl 0x5ee0(%rsp), %edx
incl %edx
leaq 0x40(%rsp), %rdi
movl $0x80000000, %ecx       # imm = 0x80000000
callq 0x517e
xorl %eax, %eax
movsd 0x52f3(%rip), %xmm0     # 0xa008
movslq 0xe238(%rsp), %rsi
cmpq %rsi, %rax
jg 0x4da1
imulq $0x18, %rax, %rcx
addq 0x80(%rsp), %rcx
movq 0x48(%rsp), %rdx
xorl %esi, %esi
movslq 0x5ee0(%rsp), %rdi
cmpq %rdi, %rsi
jg 0x4d6a
movq (%rcx), %rdi
movsd (%rdi,%rsi,8), %xmm1
mulsd %xmm0, %xmm1
cvttsd2si %xmm1, %edi
movl 0x44(%rsp), %r8d
imull %eax, %r8d
addl %esi, %r8d
movslq %r8d, %r8
movl %edi, (%rdx,%r8,4)
incq %rsi
jmp 0x4d35
incq %rax
jmp 0x4d15
movq 0xb25a(%rip), %rdi      # 0xffd0
leaq 0x52bb(%rip), %rsi      # 0xa038
callq 0x3210
movq (%rbx), %rsi
movq %rax, %rdi
callq 0x3210
leaq 0x52ac(%rip), %rsi      # 0xa040
movq %rax, %rdi
callq 0x3210
jmp 0x5003
movl 0x5ee0(%rsp), %edx
leaq 0x20(%rsp), %rdi
movl $0x80000000, %ecx       # imm = 0x80000000
callq 0x517e
xorl %eax, %eax
movl 0xe238(%rsp), %ecx
cmpl %ecx, %eax
jge 0x4e29
movq 0x48(%rsp), %rcx
movq 0x28(%rsp), %rdx
movslq %eax, %rsi
xorl %edi, %edi
movl 0x5ee0(%rsp), %r8d
cmpl %r8d, %edi
jge 0x4e25
movslq 0x44(%rsp), %r9
movslq 0xe238(%rsp), %r10
imulq %r9, %r10
imull %eax, %r9d
addl %r9d, %r8d
movslq %r8d, %r8
addq %rdi, %r10
movl (%rcx,%r10,4), %r10d
addl (%rcx,%r8,4), %r10d
movslq %r9d, %r8
addq %rdi, %r8
subl (%rcx,%r8,4), %r10d
movslq 0x24(%rsp), %r8
imulq %rsi, %r8
addq %rdi, %r8
movl %r10d, (%rdx,%r8,4)
incq %rdi
jmp 0x4dd3
incl %eax
jmp 0x4db9
movslq 0x5ee0(%rsp), %rax
movslq 0x44(%rsp), %rsi
xorl %r15d, %r15d
testl %ecx, %ecx
movl $0x0, %edi
cmovgl %ecx, %edi
movq 0x48(%rsp), %rdx
leaq (%rdx,%rax,4), %r8
movq %rsi, %r9
shlq $0x2, %r9
subq $0x1, %rdi
jb 0x4e61
addl (%r8), %r15d
addq %r9, %r8
jmp 0x4e53
imull %esi, %ecx
movslq %ecx, %rdi
xorl %ecx, %ecx
testl %eax, %eax
movl $0x0, %esi
cmovgl %eax, %esi
leaq (%rdx,%rdi,4), %rax
cmpq %rcx, %rsi
je 0x4e85
addl (%rax,%rcx,4), %r15d
incq %rcx
jmp 0x4e77
leaq 0x8430(%rsp), %rdi
leaq 0xd8(%rsp), %rsi
leaq 0x20(%rsp), %rdx
pushq $0x1
popq %rcx
movq %rcx, %r8
callq 0x3c5d
movl %eax, %ebp
xorpd %xmm0, %xmm0
movq %rsp, %rdx
movapd %xmm0, (%rdx)
andq $0x0, 0x10(%rdx)
leaq 0x8430(%rsp), %rdi
leaq 0xd8(%rsp), %rsi
pushq $0x1
popq %rcx
movq %rcx, %r8
callq 0x45d0
movq (%rsp), %rax
movq 0x8(%rsp), %rcx
movl 0x24(%rsp), %edx
xorl %ebx, %ebx
movq 0x28(%rsp), %rsi
cmpq %rcx, %rax
je 0x4f08
movq (%rax), %rdi
movl %edx, %r8d
imull %edi, %r8d
shrq $0x20, %rdi
addl %edi, %r8d
movslq %r8d, %rdi
addl (%rsi,%rdi,4), %ebx
addq $0x8, %rax
jmp 0x4ee6
leaq 0x8430(%rsp), %rdi
leaq 0xd8(%rsp), %rsi
movq %rsp, %rdx
callq 0x49cb
testb %al, %al
je 0x5017
cmpl %ebp, %ebx
jne 0x5036
subl %ebp, %r15d
cvtsi2sd %r15d, %xmm0
divsd 0x50c8(%rip), %xmm0     # 0xa008
movq 0xb061(%rip), %rdi      # 0xffa8
callq 0x3350
movq %rax, %rdi
callq 0x3120
movq (%rsp), %rbx
movq 0x8(%rsp), %r14
movq 0xb06c(%rip), %r15      # 0xffd0
pushq $0x20
popq %rbp
pushq $0xa
popq %r12
cmpq %r14, %rbx
je 0x4fc0
movq (%rbx), %r13
movslq %r13d, %rsi
shlq $0x5, %rsi
addq 0x8460(%rsp), %rsi
movq %r15, %rdi
callq 0x3200
movq %rax, %rdi
movl %ebp, %esi
callq 0x3270
sarq $0x20, %r13
shlq $0x5, %r13
addq 0x108(%rsp), %r13
movq %rax, %rdi
movq %r13, %rsi
callq 0x3200
movq %rax, %rdi
movl %r12d, %esi
callq 0x3270
addq $0x8, %rbx
jmp 0x4f6b
movq %rsp, %rdi
callq 0x79f2
leaq 0x28(%rsp), %rdi
callq 0x65ec
leaq 0x48(%rsp), %rdi
callq 0x65ec
leaq 0x80(%rsp), %rdi
callq 0x5a94
leaq 0xd8(%rsp), %rdi
callq 0x5ab6
leaq 0x8430(%rsp), %rdi
callq 0x5ab6
xorl %eax, %eax
addq $0x10788, %rsp          # imm = 0x10788
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x504d(%rip), %rdi      # 0xa06b
leaq 0x505f(%rip), %rsi      # 0xa084
leaq 0x5066(%rip), %rcx      # 0xa092
movl $0x2c8, %edx            # imm = 0x2C8
callq 0x3190
leaq 0x506c(%rip), %rdi      # 0xa0a9
leaq 0x5040(%rip), %rsi      # 0xa084
leaq 0x5047(%rip), %rcx      # 0xa092
movl $0x2c9, %edx            # imm = 0x2C9
callq 0x3190
jmp 0x50a5
movq %rax, %r15
jmp 0x50b0
movq %rax, %r15
jmp 0x50ba
movq %rax, %r15
jmp 0x50c4
movq %rax, %r15
leaq 0x40(%rsp), %rdi
callq 0x5a7e
jmp 0x5078
movq %rax, %r15
leaq 0x98(%rsp), %rdi
callq 0x3100
jmp 0x508a
movq %rax, %r15
leaq 0xb8(%rsp), %rdi
callq 0x3100
jmp 0x50d1
movq %rax, %r15
jmp 0x50d1
movq %rax, %r15
jmp 0x50de
jmp 0x50a5
movq %rax, %r15
movq %rsp, %rdi
callq 0x79f2
leaq 0x28(%rsp), %rdi
callq 0x65ec
leaq 0x48(%rsp), %rdi
callq 0x65ec
leaq 0x80(%rsp), %rdi
callq 0x5a94
leaq 0xd8(%rsp), %rdi
callq 0x5ab6
leaq 0x8430(%rsp), %rdi
callq 0x5ab6
movq %r15, %rdi
callq 0x33e0
nop