// File: /workspace/github_cpp_makefile_star2_O3/aalto-speech[P]ftk/util/Ngram.cc
// Function: Ngram::read_arpa(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>)
void
Ngram::read_arpa(string arpafname) {

    ifstream arpafile(arpafname);
    string header_error("Invalid ARPA header");
    if (!arpafile) throw string("Problem opening ARPA file: " + arpafname);

    int linei = 0;
    string line;
    _getline(arpafile, line, linei);
    while (line.length() == 0)
        _getline(arpafile, line, linei);

    if (line.find("\\data\\") == string::npos) throw header_error;
    _getline(arpafile, line, linei);

    int curr_ngram_order = 1;
    int total_ngram_count = 0;
    while (line.length() > 0) {
        if (line.find("ngram ") == string::npos) throw header_error;
        stringstream vals(line);
        getline(vals, line, '=');
        getline(vals, line, '=');
        int count = stoi(line);
        ngram_counts_per_order[curr_ngram_order] = count;
        total_ngram_count += count;
        curr_ngram_order++;
        _getline(arpafile, line, linei);
    }

    int max_ngram_order = curr_ngram_order-1;
    int total_ngrams_read = 0;
    curr_ngram_order = 1;
    nodes.resize(total_ngram_count+1);
    arc_words.resize(total_ngram_count);
    arc_target_nodes.resize(total_ngram_count);
    int curr_node_idx = 1;
    int curr_arc_idx = 0;

    while (curr_ngram_order <= max_ngram_order) {

        while (line.length() == 0)
            _getline(arpafile, line, linei);
        if (line.find("-grams") == string::npos) {
            cerr << line;
            throw header_error;
        }

        _getline(arpafile, line, linei);
        vector<NgramInfo> order_ngrams;
        int ngrams_read = read_arpa_read_order(arpafile, order_ngrams, line, curr_ngram_order, linei);

        cerr << "n-grams for order " << curr_ngram_order << ": " << ngrams_read << endl;
        if (ngrams_read != ngram_counts_per_order[curr_ngram_order])
            throw string("Invalid number of n-grams for order: " + curr_ngram_order);

        sort(order_ngrams.begin(), order_ngrams.end());

        read_arpa_insert_order_to_tree(order_ngrams, curr_node_idx, curr_arc_idx, curr_ngram_order);

        max_order = curr_ngram_order;
        curr_ngram_order++;
        total_ngrams_read += ngrams_read;
    }

    sentence_start_symbol_idx = vocabulary_lookup[sentence_start_symbol];
    sentence_start_node = find_node(root_node, sentence_start_symbol_idx);
    if (sentence_start_node == -1) throw string("Sentence start symbol not found.");
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x418, %rsp            # imm = 0x418
movq %rsi, %rbx
movq %rdi, %r12
leaq -0x438(%rbp), %rdi
movl $0x8, %edx
callq 0x45a0
leaq -0x40(%rbp), %rax
movq %rax, -0x10(%rax)
leaq 0x1c35e(%rip), %rsi     # 0x264d2
leaq 0x1c36a(%rip), %rdx     # 0x264e5
leaq -0x50(%rbp), %rdi
callq 0x5fac
movq -0x438(%rbp), %rax
movq -0x18(%rax), %rax
testb $0x5, -0x418(%rbp,%rax)
jne 0xa792
leaq -0x30(%rbp), %rdx
movl $0x0, (%rdx)
leaq -0x78(%rbp), %rax
movq %rax, -0x10(%rax)
movq $0x0, -0x8(%rax)
movb $0x0, (%rax)
leaq -0x438(%rbp), %rdi
leaq -0x88(%rbp), %rsi
callq 0xa051
leaq -0x438(%rbp), %rbx
leaq -0x88(%rbp), %r14
leaq -0x30(%rbp), %r15
cmpq $0x0, -0x80(%rbp)
jne 0xa1f6
movq %rbx, %rdi
movq %r14, %rsi
movq %r15, %rdx
callq 0xa051
jmp 0xa1df
leaq 0x1c305(%rip), %rsi     # 0x26502
leaq -0x88(%rbp), %rdi
movl $0x6, %ecx
xorl %edx, %edx
callq 0x4630
cmpq $-0x1, %rax
je 0xa7cc
leaq -0x438(%rbp), %rdi
leaq -0x88(%rbp), %rsi
leaq -0x30(%rbp), %rdx
callq 0xa051
movl $0x1, -0x2c(%rbp)
cmpq $0x0, -0x80(%rbp)
movq %r12, -0x58(%rbp)
je 0xa387
leaq 0xc0(%r12), %rax
movq %rax, -0xa0(%rbp)
xorl %ebx, %ebx
leaq -0x88(%rbp), %r15
leaq -0x230(%rbp), %r13
movl $0x6, %ecx
movq %r15, %rdi
leaq 0x1c294(%rip), %rsi     # 0x26509
xorl %edx, %edx
callq 0x4630
cmpq $-0x1, %rax
je 0xa635
movq %r13, %rdi
movq %r15, %rsi
movl $0x18, %edx
callq 0x4580
movq %rbx, -0x60(%rbp)
movq %r13, %rdi
movq %r15, %rsi
movl $0x3d, %edx
callq 0x4680
movq %r13, %rdi
movq %r15, %rsi
movl $0x3d, %edx
callq 0x4680
movq %r15, %r14
movq -0x88(%rbp), %r15
callq 0x4050
movq %rax, %r12
movl (%rax), %eax
movl %eax, -0x68(%rbp)
movl $0x0, (%r12)
movq %r15, %rdi
leaq -0x90(%rbp), %rsi
movl $0xa, %edx
callq 0x44b0
cmpq %r15, -0x90(%rbp)
je 0xa666
movq %rax, %rbx
movslq %ebx, %rax
cmpq %rbx, %rax
jne 0xa629
movl (%r12), %eax
cmpl $0x22, %eax
je 0xa629
testl %eax, %eax
movq %r14, %r15
jne 0xa324
movl -0x68(%rbp), %eax
movl %eax, (%r12)
movq -0xa0(%rbp), %rdi
leaq -0x2c(%rbp), %rsi
callq 0xb0d8
movl %ebx, (%rax)
incl -0x2c(%rbp)
leaq -0x438(%rbp), %rdi
movq %r15, %rsi
leaq -0x30(%rbp), %rdx
callq 0xa051
movq -0x60(%rbp), %rax
addl %ebx, %eax
movq %rax, %rbx
movq %r13, %rdi
movq 0x29c31(%rip), %rsi     # 0x33f90
callq 0x42c0
leaq -0x1b0(%rbp), %rdi
callq 0x4110
cmpq $0x0, -0x80(%rbp)
movq -0x58(%rbp), %r12
jne 0xa266
movl -0x2c(%rbp), %eax
movl %eax, -0x60(%rbp)
jmp 0xa390
xorl %ebx, %ebx
movl $0x1, -0x60(%rbp)
movl $0x1, -0x2c(%rbp)
leaq 0x78(%r12), %rdi
leal 0x1(%rbx), %eax
movslq %eax, %rsi
callq 0xb140
leaq 0x90(%r12), %rdi
movslq %ebx, %rbx
movq %rbx, %rsi
callq 0xb18a
leaq 0xa8(%r12), %rdi
movq %rbx, %rsi
callq 0xb18a
movl $0x1, -0x90(%rbp)
movl $0x0, -0x94(%rbp)
movl -0x60(%rbp), %eax
cmpl %eax, -0x2c(%rbp)
jge 0xa5b8
movq -0x58(%rbp), %rax
addq $0xc0, %rax
movq %rax, -0x68(%rbp)
leaq -0x438(%rbp), %rbx
leaq -0x88(%rbp), %r12
leaq -0x30(%rbp), %r15
cmpq $0x0, -0x80(%rbp)
je 0xa5a5
movl $0x6, %ecx
movq %r12, %rdi
leaq 0x1c205(%rip), %rsi     # 0x26629
xorl %edx, %edx
callq 0x4630
cmpq $-0x1, %rax
je 0xa672
movq %rbx, %rdi
movq %r12, %rsi
movq %r15, %rdx
callq 0xa051
xorps %xmm0, %xmm0
movaps %xmm0, -0x230(%rbp)
movq $0x0, -0x220(%rbp)
movl -0x2c(%rbp), %r8d
movq -0x58(%rbp), %rdi
movq %rbx, %r13
movq %rbx, %rsi
leaq -0x230(%rbp), %rdx
movq %r12, %rcx
movq %r15, %r14
movq %r15, %r9
callq 0xa94c
movl %eax, %r15d
movl $0x12, %edx
movq 0x29b5e(%rip), %rdi     # 0x33fe8
leaq 0x1c07f(%rip), %rsi     # 0x26510
callq 0x4400
movl -0x2c(%rbp), %esi
movq 0x29b48(%rip), %rdi     # 0x33fe8
callq 0x4620
movq %rax, %rbx
movl $0x2, %edx
movq %rax, %rdi
leaq 0x1c2cb(%rip), %rsi     # 0x26782
callq 0x4400
movq %rbx, %rdi
movl %r15d, %esi
callq 0x4620
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x4370
movsbl %al, %esi
movq %rbx, %rdi
callq 0x4030
movq %rax, %rdi
callq 0x4260
movq -0x68(%rbp), %rdi
leaq -0x2c(%rbp), %rsi
callq 0xb0d8
cmpl (%rax), %r15d
jne 0xa6ba
movq -0x230(%rbp), %rbx
movq -0x228(%rbp), %r15
cmpq %r15, %rbx
je 0xa555
movq %r15, %rax
subq %rbx, %rax
sarq $0x3, %rax
movabsq $-0x3333333333333333, %rcx # imm = 0xCCCCCCCCCCCCCCCD
imulq %rcx, %rax
bsrq %rax, %rdx
xorl $0x3f, %edx
addl %edx, %edx
xorq $0x7e, %rdx
movq %rbx, %rdi
movq %r15, %rsi
callq 0xb874
movq %rbx, %rdi
movq %r15, %rsi
callq 0xb934
movq -0x58(%rbp), %rdi
leaq -0x230(%rbp), %rsi
leaq -0x90(%rbp), %rdx
leaq -0x94(%rbp), %rcx
callq 0xadf4
movl -0x2c(%rbp), %eax
movq -0x58(%rbp), %rcx
movl %eax, 0xf0(%rcx)
incl %eax
movl %eax, -0x2c(%rbp)
leaq -0x230(%rbp), %rdi
callq 0xb1c2
movl -0x60(%rbp), %eax
cmpl %eax, -0x2c(%rbp)
movq %r13, %rbx
movq %r14, %r15
jl 0xa40a
jmp 0xa5b8
movq %rbx, %rdi
movq %r12, %rsi
movq %r15, %rdx
callq 0xa051
jmp 0xa40a
movq -0x58(%rbp), %rbx
leaq 0x48(%rbx), %rdi
leaq 0x10(%rbx), %rsi
callq 0x7dac
movl (%rax), %edx
movl %edx, 0x8(%rbx)
movl (%rbx), %esi
movq %rbx, %rdi
callq 0x9f1c
movl %eax, 0x4(%rbx)
cmpl $-0x1, %eax
je 0xa7f6
movq -0x88(%rbp), %rdi
leaq -0x78(%rbp), %rax
cmpq %rax, %rdi
je 0xa5f9
callq 0x4350
movq -0x50(%rbp), %rdi
leaq -0x40(%rbp), %rax
cmpq %rax, %rdi
je 0xa60b
callq 0x4350
leaq -0x438(%rbp), %rdi
callq 0x40c0
addq $0x418, %rsp            # imm = 0x418
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x1bf9d(%rip), %rdi     # 0x265cd
callq 0x44e0
movl $0x20, %edi
callq 0x4190
leaq 0x10(%rax), %rcx
movq %rcx, (%rax)
movq -0x50(%rbp), %rdx
leaq -0x40(%rbp), %rsi
cmpq %rsi, %rdx
jne 0xa70e
leaq -0x40(%rbp), %rdx
movups (%rdx), %xmm0
movups %xmm0, (%rcx)
jmp 0xa719
leaq 0x1bf60(%rip), %rdi     # 0x265cd
callq 0x4200
movq -0x88(%rbp), %rsi
movq -0x80(%rbp), %rdx
movq 0x29964(%rip), %rdi     # 0x33fe8
callq 0x4400
movl $0x20, %edi
callq 0x4190
leaq 0x10(%rax), %rcx
movq %rcx, (%rax)
movq -0x50(%rbp), %rdx
leaq -0x40(%rbp), %rsi
cmpq %rsi, %rdx
jne 0xa750
leaq -0x40(%rbp), %rdx
movups (%rdx), %xmm0
movups %xmm0, (%rcx)
jmp 0xa75b
movl $0x20, %edi
callq 0x4190
movq %rax, %r14
movslq -0x2c(%rbp), %rax
leaq 0x1be51(%rip), %rbx     # 0x26523
addq %rax, %rbx
leaq 0x10(%r14), %rax
movq %rax, (%r14)
movq %rbx, %rdi
callq 0x4170
leaq (%rax,%rbx), %rdx
movq %r14, %rdi
movq %rbx, %rsi
callq 0x5fac
leaq 0x29656(%rip), %rsi     # 0x33d50
movq 0x2989f(%rip), %rdx     # 0x33fa0
movq %r14, %rdi
callq 0x4610
jmp 0xa875
movq %rdx, (%rax)
movq -0x40(%rbp), %rcx
movq %rcx, 0x10(%rax)
movq -0x48(%rbp), %rcx
movq %rcx, 0x8(%rax)
leaq -0x40(%rbp), %rcx
movq %rcx, -0x50(%rbp)
movq $0x0, -0x48(%rbp)
movb $0x0, -0x40(%rbp)
leaq 0x29614(%rip), %rsi     # 0x33d50
movq 0x2985d(%rip), %rdx     # 0x33fa0
movq %rax, %rdi
callq 0x4610
jmp 0xa875
movq %rdx, (%rax)
movq -0x40(%rbp), %rcx
movq %rcx, 0x10(%rax)
movq -0x48(%rbp), %rcx
movq %rcx, 0x8(%rax)
leaq -0x40(%rbp), %rcx
movq %rcx, -0x50(%rbp)
movq $0x0, -0x48(%rbp)
movb $0x0, -0x40(%rbp)
leaq 0x295d2(%rip), %rsi     # 0x33d50
movq 0x2981b(%rip), %rdx     # 0x33fa0
movq %rax, %rdi
callq 0x4610
jmp 0xa875
movl $0x20, %edi
callq 0x4190
movq %rax, %r14
leaq 0x1bd40(%rip), %rsi     # 0x264e6
movq %rax, %rdi
movq %rbx, %rdx
callq 0xb04d
leaq 0x29598(%rip), %rsi     # 0x33d50
movq 0x297e1(%rip), %rdx     # 0x33fa0
movq %r14, %rdi
callq 0x4610
jmp 0xa875
movl $0x20, %edi
callq 0x4190
leaq 0x10(%rax), %rcx
movq %rcx, (%rax)
movq -0x50(%rbp), %rdx
leaq -0x40(%rbp), %rsi
cmpq %rsi, %rdx
jne 0xa838
leaq -0x40(%rbp), %rdx
movups (%rdx), %xmm0
movups %xmm0, (%rcx)
jmp 0xa843
movl $0x20, %edi
callq 0x4190
movq %rax, %r14
addq $0x10, %rax
movq %rax, (%r14)
leaq 0x1bd38(%rip), %rsi     # 0x26549
leaq 0x1bd51(%rip), %rdx     # 0x26569
movq %r14, %rdi
callq 0x5fac
leaq 0x29529(%rip), %rsi     # 0x33d50
movq 0x29772(%rip), %rdx     # 0x33fa0
movq %r14, %rdi
callq 0x4610
jmp 0xa875
movq %rdx, (%rax)
movq -0x40(%rbp), %rcx
movq %rcx, 0x10(%rax)
movq -0x48(%rbp), %rcx
movq %rcx, 0x8(%rax)
leaq -0x40(%rbp), %rcx
movq %rcx, -0x50(%rbp)
movq $0x0, -0x48(%rbp)
movb $0x0, -0x40(%rbp)
leaq 0x294ea(%rip), %rsi     # 0x33d50
movq 0x29733(%rip), %rdx     # 0x33fa0
movq %rax, %rdi
callq 0x4610
jmp 0xa8c4
movq %rax, %rbx
movq %r14, %rdi
callq 0x42b0
jmp 0xa911
movq %rax, %rbx
jmp 0xa926
movq %rax, %rbx
movq %r14, %rdi
callq 0x42b0
jmp 0xa926
movq %rax, %rbx
jmp 0xa938
jmp 0xa8c4
jmp 0xa8c4
jmp 0xa902
movq %rax, %rbx
movq %r14, %rdi
callq 0x42b0
jmp 0xa905
jmp 0xa8c4
jmp 0xa8c4
jmp 0xa8c4
jmp 0xa8c4
jmp 0xa8c4
movq %rax, %rbx
jmp 0xa911
jmp 0xa8cb
movq %rax, %rbx
jmp 0xa8e1
movq %rax, %rbx
cmpl $0x0, (%r12)
jne 0xa8e1
movl -0x68(%rbp), %eax
movl %eax, (%r12)
movq 0x296a8(%rip), %rsi     # 0x33f90
leaq -0x230(%rbp), %rdi
callq 0x42c0
leaq -0x1b0(%rbp), %rdi
callq 0x4110
jmp 0xa911
movq %rax, %rbx
leaq -0x230(%rbp), %rdi
callq 0xb1c2
movq -0x88(%rbp), %rdi
leaq -0x78(%rbp), %rax
cmpq %rax, %rdi
je 0xa926
callq 0x4350
movq -0x50(%rbp), %rdi
leaq -0x40(%rbp), %rax
cmpq %rax, %rdi
je 0xa938
callq 0x4350
leaq -0x438(%rbp), %rdi
callq 0x40c0
movq %rbx, %rdi
callq 0x4650