// File: aalto-speech[P]ftk/src/Unigrams.cc
// Function: Unigrams::rank_candidates(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>&, std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, double, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, double>>> const&, std::set<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>> const&, std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, double, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, double>>>&, std::vector<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, double>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, double>>>&)
flt_type
Unigrams::rank_candidates(std::vector<std::string> &sents,
                          const map<string, flt_type> &vocab,
                          const set<string> &candidates,
                          map<string, flt_type> &new_freqs,
                          vector<pair<string, flt_type> > &removal_scores)
{
    new_freqs.clear();
    removal_scores.clear();

    StringSet ss_vocab(vocab);
    map<string, flt_type> ll_diffs;
    map<string, flt_type> token_diffs;
    set<string> problem_hypos;

    flt_type curr_ll = 0.0;
    flt_type token_count = 0.0;

    for (auto sentiter = sents.cbegin(); sentiter != sents.cend(); ++sentiter) {

        map<string, flt_type> stats;
        flt_type orig_score = segf(ss_vocab, *sentiter, stats, this->utf8);

        if (stats.size() == 0) {
            cerr << "warning, no segmentation for sentence: " << *sentiter << endl;
            continue;
        }

        curr_ll += orig_score;
        token_count += stats.size();

        // Update statistics
        for (auto it = stats.cbegin(); it != stats.cend(); ++it)
            new_freqs[it->first] += it->second;

        for (auto hypoiter = stats.cbegin(); hypoiter != stats.cend(); ++hypoiter) {

            if (candidates.find(hypoiter->first) != candidates.end()) {

                flt_type stored_value = ss_vocab.remove(hypoiter->first);

                map<string, flt_type> hypo_stats;
                flt_type hypo_score = segf(ss_vocab, *sentiter, hypo_stats, this->utf8);

                if (hypo_stats.size() > 0) {
                    ll_diffs[hypoiter->first] += (hypo_score-orig_score);
                    token_diffs[hypoiter->first] += (flt_type)(hypo_stats.size())-(flt_type)(stats.size());
                }
                else
                    problem_hypos.insert(hypoiter->first);

                ss_vocab.add(hypoiter->first, stored_value);
            }
        }
    }

    for (auto iter = ll_diffs.begin(); iter != ll_diffs.end(); ++iter) {
        if (problem_hypos.find(iter->first) != problem_hypos.end()) continue;
        flt_type renormalizer = sub_log_domain_probs(0, vocab.at(iter->first));
        flt_type hypo_token_count = (token_count + token_diffs[iter->first]);
        flt_type normalizer_ll_diff = hypo_token_count * -renormalizer;
        pair<string, flt_type> removal_score = make_pair(iter->first, iter->second + normalizer_ll_diff);
        removal_scores.push_back(removal_score);
    }

    sort(removal_scores.begin(), removal_scores.end(), descending_sort);

    return curr_ll;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x470, %rsp            # imm = 0x470
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
movq %r9, -0x30(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x348(%rbp)
movq -0x28(%rbp), %rdi
callq 0x47d90
movq -0x30(%rbp), %rdi
callq 0x588b0
movq -0x18(%rbp), %rsi
leaq -0x150(%rbp), %rdi
callq 0x19e70
leaq -0x180(%rbp), %rdi
callq 0x5fb0
leaq -0x1b0(%rbp), %rdi
callq 0x5fb0
leaq -0x1e0(%rbp), %rdi
callq 0x6050
xorps %xmm0, %xmm0
movsd %xmm0, -0x1e8(%rbp)
xorps %xmm0, %xmm0
movsd %xmm0, -0x1f0(%rbp)
movq -0x10(%rbp), %rdi
callq 0x4ee70
movq %rax, -0x1f8(%rbp)
movq -0x10(%rbp), %rdi
callq 0x58e50
movq %rax, -0x200(%rbp)
leaq -0x1f8(%rbp), %rdi
leaq -0x200(%rbp), %rsi
callq 0x2c520
testb $0x1, %al
jne 0x57d16
jmp 0x582ac
leaq -0x230(%rbp), %rdi
movq %rdi, -0x360(%rbp)
callq 0x5fb0
movq -0x348(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x358(%rbp)
leaq -0x1f8(%rbp), %rdi
callq 0x2c590
movq -0x348(%rbp), %rcx
movq -0x360(%rbp), %rdx
movq %rax, %rsi
movq -0x358(%rbp), %rax
movzbl 0x8(%rcx), %ecx
andl $0x1, %ecx
leaq -0x150(%rbp), %rdi
callq *%rax
movsd %xmm0, -0x350(%rbp)
jmp 0x57d78
movsd -0x350(%rbp), %xmm0
movsd %xmm0, -0x238(%rbp)
leaq -0x230(%rbp), %rdi
callq 0x5fd0
cmpq $0x0, %rax
jne 0x57e15
movq 0x3c247(%rip), %rdi     # 0x93fe8
leaq 0xeabc(%rip), %rsi      # 0x66864
callq 0x43c0
movq %rax, -0x368(%rbp)
jmp 0x57db6
leaq -0x1f8(%rbp), %rdi
callq 0x2c590
movq -0x368(%rbp), %rdi
movq %rax, %rsi
callq 0x4380
movq %rax, -0x370(%rbp)
jmp 0x57dda
movq -0x370(%rbp), %rdi
movq 0x3c1b0(%rip), %rsi     # 0x93f98
callq 0x4400
jmp 0x57def
movl $0x4, -0x248(%rbp)
jmp 0x5826e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x240(%rbp)
movl %eax, -0x244(%rbp)
jmp 0x5829b
movsd -0x238(%rbp), %xmm1
movsd -0x1e8(%rbp), %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x1e8(%rbp)
leaq -0x230(%rbp), %rdi
callq 0x5fd0
movq %rax, %xmm0
movaps 0xe9d7(%rip), %xmm1     # 0x66820
punpckldq %xmm1, %xmm0    # xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
movapd 0xe9db(%rip), %xmm1     # 0x66830
subpd %xmm1, %xmm0
movaps %xmm0, %xmm1
unpckhpd %xmm0, %xmm0            # xmm0 = xmm0[1,1]
addsd %xmm1, %xmm0
addsd -0x1f0(%rbp), %xmm0
movsd %xmm0, -0x1f0(%rbp)
leaq -0x230(%rbp), %rdi
callq 0x1b260
movq %rax, -0x250(%rbp)
leaq -0x230(%rbp), %rdi
callq 0x1b2c0
movq %rax, -0x258(%rbp)
leaq -0x250(%rbp), %rdi
leaq -0x258(%rbp), %rsi
callq 0x1b290
testb $0x1, %al
jne 0x57eb3
jmp 0x57f2a
leaq -0x250(%rbp), %rdi
movq %rdi, -0x390(%rbp)
callq 0x1b2f0
movq -0x390(%rbp), %rdi
movsd 0x20(%rax), %xmm0
movsd %xmm0, -0x388(%rbp)
movq -0x28(%rbp), %rax
movq %rax, -0x380(%rbp)
callq 0x1b2f0
movq -0x380(%rbp), %rdi
movq %rax, %rsi
callq 0x47db0
movq %rax, -0x378(%rbp)
jmp 0x57f02
movq -0x378(%rbp), %rax
movsd -0x388(%rbp), %xmm0
addsd (%rax), %xmm0
movsd %xmm0, (%rax)
leaq -0x250(%rbp), %rdi
callq 0x1b320
jmp 0x57e87
leaq -0x230(%rbp), %rdi
callq 0x1b260
movq %rax, -0x260(%rbp)
leaq -0x230(%rbp), %rdi
callq 0x1b2c0
movq %rax, -0x268(%rbp)
leaq -0x260(%rbp), %rdi
leaq -0x268(%rbp), %rsi
callq 0x1b290
testb $0x1, %al
jne 0x57f6c
jmp 0x58264
movq -0x20(%rbp), %rax
movq %rax, -0x3a0(%rbp)
leaq -0x260(%rbp), %rdi
callq 0x1b2f0
movq -0x3a0(%rbp), %rdi
movq %rax, %rsi
callq 0x235e0
movq %rax, -0x398(%rbp)
jmp 0x57f9b
movq -0x398(%rbp), %rax
movq %rax, -0x270(%rbp)
movq -0x20(%rbp), %rdi
callq 0x23610
movq %rax, -0x278(%rbp)
leaq -0x270(%rbp), %rdi
leaq -0x278(%rbp), %rsi
callq 0x235b0
testb $0x1, %al
jne 0x57fd5
jmp 0x58251
leaq -0x260(%rbp), %rdi
callq 0x1b2f0
movq %rax, %rsi
leaq -0x150(%rbp), %rdi
callq 0x1aa80
movsd %xmm0, -0x3a8(%rbp)
jmp 0x57ffa
movsd -0x3a8(%rbp), %xmm0
movsd %xmm0, -0x280(%rbp)
leaq -0x2b0(%rbp), %rdi
movq %rdi, -0x3c0(%rbp)
callq 0x5fb0
movq -0x348(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x3b8(%rbp)
leaq -0x1f8(%rbp), %rdi
callq 0x2c590
movq -0x348(%rbp), %rcx
movq -0x3c0(%rbp), %rdx
movq %rax, %rsi
movq -0x3b8(%rbp), %rax
movzbl 0x8(%rcx), %ecx
andl $0x1, %ecx
leaq -0x150(%rbp), %rdi
callq *%rax
movsd %xmm0, -0x3b0(%rbp)
jmp 0x5806c
movsd -0x3b0(%rbp), %xmm0
movsd %xmm0, -0x2b8(%rbp)
leaq -0x2b0(%rbp), %rdi
callq 0x5fd0
cmpq $0x0, %rax
jbe 0x581dc
movsd -0x2b8(%rbp), %xmm0
movsd -0x238(%rbp), %xmm1
subsd %xmm1, %xmm0
movsd %xmm0, -0x3d0(%rbp)
leaq -0x260(%rbp), %rdi
callq 0x1b2f0
movq %rax, %rsi
leaq -0x180(%rbp), %rdi
callq 0x47db0
movq %rax, -0x3c8(%rbp)
jmp 0x580d2
movq -0x3c8(%rbp), %rax
movsd -0x3d0(%rbp), %xmm1
movsd (%rax), %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, (%rax)
leaq -0x2b0(%rbp), %rdi
callq 0x5fd0
movq %rax, %xmm0
movaps 0xe71b(%rip), %xmm1     # 0x66820
movaps %xmm1, -0x410(%rbp)
punpckldq %xmm1, %xmm0    # xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
movapd 0xe718(%rip), %xmm1     # 0x66830
movaps %xmm1, -0x400(%rbp)
subpd %xmm1, %xmm0
movaps %xmm0, %xmm1
unpckhpd %xmm0, %xmm0            # xmm0 = xmm0[1,1]
addsd %xmm1, %xmm0
movsd %xmm0, -0x3e8(%rbp)
leaq -0x230(%rbp), %rdi
callq 0x5fd0
movaps -0x410(%rbp), %xmm3
movaps -0x400(%rbp), %xmm2
movsd -0x3e8(%rbp), %xmm0
movq %rax, %xmm1
punpckldq %xmm3, %xmm1    # xmm1 = xmm1[0],xmm3[0],xmm1[1],xmm3[1]
subpd %xmm2, %xmm1
movaps %xmm1, %xmm2
unpckhpd %xmm1, %xmm1            # xmm1 = xmm1[1,1]
addsd %xmm2, %xmm1
subsd %xmm1, %xmm0
movsd %xmm0, -0x3e0(%rbp)
leaq -0x260(%rbp), %rdi
callq 0x1b2f0
movq %rax, %rsi
leaq -0x1b0(%rbp), %rdi
callq 0x47db0
movq %rax, -0x3d8(%rbp)
jmp 0x581a0
movq -0x3d8(%rbp), %rax
movsd -0x3e0(%rbp), %xmm0
addsd (%rax), %xmm0
movsd %xmm0, (%rax)
jmp 0x58220
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x240(%rbp)
movl %eax, -0x244(%rbp)
leaq -0x2b0(%rbp), %rdi
callq 0x6090
jmp 0x5829b
leaq -0x260(%rbp), %rdi
callq 0x1b2f0
movq %rax, %rsi
leaq -0x1e0(%rbp), %rdi
callq 0x31820
movb %dl, -0x419(%rbp)
movq %rax, -0x418(%rbp)
jmp 0x58206
movb -0x419(%rbp), %al
movq -0x418(%rbp), %rcx
movq %rcx, -0x2c8(%rbp)
movb %al, -0x2c0(%rbp)
leaq -0x260(%rbp), %rdi
callq 0x1b2f0
movq %rax, %rsi
movsd -0x280(%rbp), %xmm0
leaq -0x150(%rbp), %rdi
callq 0x1a2a0
jmp 0x58245
leaq -0x2b0(%rbp), %rdi
callq 0x6090
jmp 0x58253
leaq -0x260(%rbp), %rdi
callq 0x1b320
jmp 0x57f3d
movl $0x0, -0x248(%rbp)
leaq -0x230(%rbp), %rdi
callq 0x6090
movl -0x248(%rbp), %eax
testl %eax, %eax
je 0x58288
jmp 0x58286
jmp 0x5828a
jmp 0x5828a
leaq -0x1f8(%rbp), %rdi
callq 0x2c5b0
jmp 0x57cea
leaq -0x230(%rbp), %rdi
callq 0x6090
jmp 0x58582
leaq -0x180(%rbp), %rdi
callq 0x58790
movq %rax, -0x2d0(%rbp)
leaq -0x180(%rbp), %rdi
callq 0x48c90
movq %rax, -0x2d8(%rbp)
leaq -0x2d0(%rbp), %rdi
leaq -0x2d8(%rbp), %rsi
callq 0x48c30
testb $0x1, %al
jne 0x582ee
jmp 0x584eb
leaq -0x2d0(%rbp), %rdi
callq 0x587c0
movq %rax, %rsi
leaq -0x1e0(%rbp), %rdi
callq 0x58b10
movq %rax, -0x428(%rbp)
jmp 0x58312
movq -0x428(%rbp), %rax
movq %rax, -0x2e0(%rbp)
leaq -0x1e0(%rbp), %rdi
callq 0x23610
movq %rax, -0x2e8(%rbp)
leaq -0x2e0(%rbp), %rdi
leaq -0x2e8(%rbp), %rsi
callq 0x235b0
testb $0x1, %al
jne 0x5834c
jmp 0x58368
jmp 0x584b7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x240(%rbp)
movl %eax, -0x244(%rbp)
jmp 0x58582
movq -0x18(%rbp), %rax
movq %rax, -0x438(%rbp)
leaq -0x2d0(%rbp), %rdi
callq 0x587c0
movq -0x438(%rbp), %rdi
movq %rax, %rsi
callq 0x48880
movq %rax, -0x430(%rbp)
jmp 0x58397
movq -0x430(%rbp), %rax
movsd (%rax), %xmm1
xorps %xmm0, %xmm0
callq 0x57bb0
movsd %xmm0, -0x440(%rbp)
jmp 0x583b4
movsd -0x440(%rbp), %xmm0
movsd %xmm0, -0x2f0(%rbp)
movsd -0x1f0(%rbp), %xmm0
movsd %xmm0, -0x450(%rbp)
leaq -0x2d0(%rbp), %rdi
callq 0x587c0
movq %rax, %rsi
leaq -0x1b0(%rbp), %rdi
callq 0x47db0
movq %rax, -0x448(%rbp)
jmp 0x583f8
movsd -0x450(%rbp), %xmm0
movq -0x448(%rbp), %rax
movsd (%rax), %xmm1
addsd %xmm1, %xmm0
movsd %xmm0, -0x2f8(%rbp)
movsd -0x2f8(%rbp), %xmm0
movaps 0xe36a(%rip), %xmm2     # 0x66790
movsd -0x2f0(%rbp), %xmm1
pxor %xmm2, %xmm1
mulsd %xmm1, %xmm0
movsd %xmm0, -0x300(%rbp)
leaq -0x2d0(%rbp), %rdi
movq %rdi, -0x460(%rbp)
callq 0x587c0
movq -0x460(%rbp), %rdi
movq %rax, -0x458(%rbp)
callq 0x587c0
movq -0x458(%rbp), %rsi
movsd 0x20(%rax), %xmm0
movsd -0x300(%rbp), %xmm1
addsd %xmm1, %xmm0
movsd %xmm0, -0x330(%rbp)
leaq -0x328(%rbp), %rdi
leaq -0x330(%rbp), %rdx
callq 0x58e10
jmp 0x58499
movq -0x30(%rbp), %rdi
leaq -0x328(%rbp), %rsi
callq 0x58910
jmp 0x584ab
leaq -0x328(%rbp), %rdi
callq 0x58980
leaq -0x2d0(%rbp), %rdi
callq 0x4bba0
jmp 0x582bf
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x240(%rbp)
movl %eax, -0x244(%rbp)
leaq -0x328(%rbp), %rdi
callq 0x58980
jmp 0x58582
movq -0x30(%rbp), %rdi
callq 0x58a30
movq %rax, -0x338(%rbp)
movq -0x30(%rbp), %rdi
callq 0x58a60
movq %rax, -0x340(%rbp)
movq -0x338(%rbp), %rdi
movq -0x340(%rbp), %rsi
leaq -0x39f0(%rip), %rdx     # 0x54b30
callq 0x589e0
jmp 0x58527
movsd -0x1e8(%rbp), %xmm0
movsd %xmm0, -0x468(%rbp)
movl $0x1, -0x248(%rbp)
leaq -0x1e0(%rbp), %rdi
callq 0x6070
leaq -0x1b0(%rbp), %rdi
callq 0x6090
leaq -0x180(%rbp), %rdi
callq 0x6090
leaq -0x150(%rbp), %rdi
callq 0x1a3e0
movsd -0x468(%rbp), %xmm0
addq $0x470, %rsp            # imm = 0x470
popq %rbp
retq
leaq -0x1e0(%rbp), %rdi
callq 0x6070
leaq -0x1b0(%rbp), %rdi
callq 0x6090
leaq -0x180(%rbp), %rdi
callq 0x6090
leaq -0x150(%rbp), %rdi
callq 0x1a3e0
movq -0x240(%rbp), %rdi
callq 0x46e0
nop