// File: /workspace/github_cpp_makefile_star2_O2/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 $0x408, %rsp            # imm = 0x408
movq %rsi, %rbx
movq %rdi, %r12
leaq -0x428(%rbp), %rdi
pushq $0x8
popq %rdx
callq 0x4540
leaq 0x1a0f6(%rip), %rsi     # 0x23462
leaq -0x60(%rbp), %rdi
leaq -0x220(%rbp), %rdx
callq 0x4140
movq -0x428(%rbp), %rax
movq -0x18(%rax), %rax
testb $0x5, -0x408(%rbp,%rax)
jne 0x97f0
leaq -0x30(%rbp), %rdx
andl $0x0, (%rdx)
leaq -0x80(%rbp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
movb $0x0, (%rax)
leaq -0x428(%rbp), %rdi
leaq -0x90(%rbp), %rsi
callq 0x9294
leaq -0x428(%rbp), %rbx
leaq -0x90(%rbp), %r14
leaq -0x30(%rbp), %r15
cmpq $0x0, -0x88(%rbp)
jne 0x93eb
movq %rbx, %rdi
movq %r14, %rsi
movq %r15, %rdx
callq 0x9294
jmp 0x93d1
leaq 0x1a0a0(%rip), %rsi     # 0x23492
leaq -0x90(%rbp), %rdi
xorl %edx, %edx
callq 0x4680
cmpq $-0x1, %rax
je 0x9828
leaq -0x428(%rbp), %rdi
leaq -0x90(%rbp), %rsi
leaq -0x30(%rbp), %rdx
callq 0x9294
leaq -0x2c(%rbp), %rax
movl $0x1, (%rax)
movq %r12, -0x40(%rbp)
leaq 0xc0(%r12), %rax
movq %rax, -0x98(%rbp)
xorl %r14d, %r14d
leaq -0x90(%rbp), %r12
leaq -0x220(%rbp), %r13
pushq $0x3d
popq %r15
cmpq $0x0, -0x88(%rbp)
je 0x94ed
movq %r12, %rdi
leaq 0x1a02e(%rip), %rsi     # 0x23499
xorl %edx, %edx
callq 0x4680
cmpq $-0x1, %rax
je 0x96d1
movq %r13, %rdi
movq %r12, %rsi
pushq $0x18
popq %rdx
callq 0x4520
movq %r13, %rdi
movq %r12, %rsi
movl %r15d, %edx
callq 0x4610
movq %r13, %rdi
movq %r12, %rsi
movl %r15d, %edx
callq 0x4610
movq %r12, %rdi
xorl %esi, %esi
pushq $0xa
popq %rdx
callq 0x9f02
movl %eax, %ebx
movq -0x98(%rbp), %rdi
leaq -0x2c(%rbp), %rsi
callq 0x9f24
movl %ebx, (%rax)
incl -0x2c(%rbp)
leaq -0x428(%rbp), %rdi
movq %r12, %rsi
leaq -0x30(%rbp), %rdx
callq 0x9294
addl %ebx, %r14d
movq %r13, %rdi
callq 0x42b0
jmp 0x9453
movl -0x2c(%rbp), %eax
movl %eax, -0x64(%rbp)
movl $0x1, -0x2c(%rbp)
movq -0x40(%rbp), %r15
leaq 0x78(%r15), %rdi
leal 0x1(%r14), %eax
movslq %eax, %rsi
callq 0x9f76
leaq 0x90(%r15), %rdi
movslq %r14d, %rbx
movq %rbx, %rsi
callq 0x9fbc
leaq 0xa8(%r15), %rdi
movq %rbx, %rsi
callq 0x9fbc
leaq -0x68(%rbp), %rax
andl $0x0, (%rax)
leaq -0x6c(%rbp), %rax
movl $0x1, (%rax)
leaq -0x428(%rbp), %r13
leaq -0x90(%rbp), %r15
leaq -0x30(%rbp), %r12
leaq -0x220(%rbp), %r14
movl -0x64(%rbp), %eax
cmpl %eax, -0x2c(%rbp)
jge 0x9672
cmpq $0x0, -0x88(%rbp)
jne 0x957f
movq %r13, %rdi
movq %r15, %rsi
movq %r12, %rdx
callq 0x9294
jmp 0x9565
movq %r15, %rdi
leaq 0x1a030(%rip), %rsi     # 0x235b9
xorl %edx, %edx
callq 0x4680
cmpq $-0x1, %rax
je 0x96fc
movq %r13, %rdi
movq %r15, %rsi
movq %r12, %rdx
callq 0x9294
xorps %xmm0, %xmm0
movaps %xmm0, -0x220(%rbp)
andq $0x0, -0x210(%rbp)
movl -0x2c(%rbp), %r8d
movq -0x40(%rbp), %rdi
movq %r13, %rsi
movq %r14, %rdx
movq %r15, %rcx
movq %r12, %r9
callq 0x994e
movl %eax, %ebx
movq 0x2ba0c(%rip), %rdi     # 0x34fe8
leaq 0x19ebd(%rip), %rsi     # 0x234a0
callq 0x4340
movl -0x2c(%rbp), %esi
movq %rax, %rdi
callq 0x45d0
movq %rax, %rdi
leaq 0x1a115(%rip), %rsi     # 0x23712
callq 0x4340
movq %rax, %rdi
movl %ebx, %esi
callq 0x45d0
movq %rax, %rdi
callq 0x4180
movq -0x98(%rbp), %rdi
leaq -0x2c(%rbp), %rsi
callq 0x9f24
cmpl (%rax), %ebx
jne 0x973a
movq -0x220(%rbp), %rdi
movq -0x218(%rbp), %rsi
callq 0xa96b
movq -0x40(%rbp), %rdi
movq %r14, %rsi
leaq -0x6c(%rbp), %rdx
leaq -0x68(%rbp), %rcx
callq 0x9c80
movl -0x2c(%rbp), %eax
movq -0x40(%rbp), %rcx
movl %eax, 0xf0(%rcx)
incl %eax
movl %eax, -0x2c(%rbp)
movq %r14, %rdi
callq 0x9ff4
jmp 0x9559
movq -0x40(%rbp), %rbx
leaq 0x48(%rbx), %rdi
leaq 0x10(%rbx), %rsi
callq 0x705c
movl (%rax), %edx
movl %edx, 0x8(%rbx)
movl (%rbx), %esi
movq %rbx, %rdi
callq 0x9194
movl %eax, 0x4(%rbx)
cmpl $-0x1, %eax
je 0x984c
leaq -0x90(%rbp), %rdi
callq 0x46b8
leaq -0x60(%rbp), %rdi
callq 0x46b8
leaq -0x428(%rbp), %rdi
callq 0x40d0
addq $0x408, %rsp            # imm = 0x408
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
pushq $0x20
popq %rdi
callq 0x4190
leaq 0x10(%rax), %rdx
movq %rdx, (%rax)
leaq -0x50(%rbp), %rcx
movq -0x10(%rcx), %rsi
cmpq %rcx, %rsi
jne 0x977a
movups (%rcx), %xmm0
movups %xmm0, (%rdx)
jmp 0x9785
movq 0x2b8e5(%rip), %rdi     # 0x34fe8
leaq -0x90(%rbp), %rsi
callq 0x4300
pushq $0x20
popq %rdi
callq 0x4190
leaq 0x10(%rax), %rdx
movq %rdx, (%rax)
leaq -0x50(%rbp), %rcx
movq -0x10(%rcx), %rsi
cmpq %rcx, %rsi
jne 0x97b5
movups (%rcx), %xmm0
movups %xmm0, (%rdx)
jmp 0x97c0
pushq $0x20
popq %rdi
callq 0x4190
movq %rax, %r14
movslq -0x2c(%rbp), %rax
leaq 0x19d63(%rip), %rsi     # 0x234b3
addq %rax, %rsi
leaq -0x31(%rbp), %rdx
movq %r14, %rdi
callq 0x4140
leaq 0x2b5f2(%rip), %rsi     # 0x34d58
movq 0x2b833(%rip), %rdx     # 0x34fa0
movq %r14, %rdi
callq 0x45c0
jmp 0x98bb
movq %rsi, (%rax)
movq -0x50(%rbp), %rdx
movq %rdx, 0x10(%rax)
movq -0x58(%rbp), %rdx
movq %rdx, 0x8(%rax)
movq %rcx, -0x60(%rbp)
andq $0x0, -0x58(%rbp)
movb $0x0, -0x50(%rbp)
leaq 0x2b5b7(%rip), %rsi     # 0x34d58
movq 0x2b7f8(%rip), %rdx     # 0x34fa0
movq %rax, %rdi
callq 0x45c0
jmp 0x98bb
movq %rsi, (%rax)
movq -0x50(%rbp), %rdx
movq %rdx, 0x10(%rax)
movq -0x58(%rbp), %rdx
movq %rdx, 0x8(%rax)
movq %rcx, -0x60(%rbp)
andq $0x0, -0x58(%rbp)
movb $0x0, -0x50(%rbp)
leaq 0x2b57c(%rip), %rsi     # 0x34d58
movq 0x2b7bd(%rip), %rdx     # 0x34fa0
movq %rax, %rdi
callq 0x45c0
jmp 0x98bb
pushq $0x20
popq %rdi
callq 0x4190
movq %rax, %r14
leaq 0x19c74(%rip), %rsi     # 0x23476
movq %rax, %rdi
movq %rbx, %rdx
callq 0x9e8c
leaq 0x2b544(%rip), %rsi     # 0x34d58
movq 0x2b785(%rip), %rdx     # 0x34fa0
movq %r14, %rdi
callq 0x45c0
jmp 0x98bb
pushq $0x20
popq %rdi
callq 0x4190
leaq 0x10(%rax), %rdx
movq %rdx, (%rax)
leaq -0x50(%rbp), %rcx
movq -0x10(%rcx), %rsi
cmpq %rcx, %rsi
jne 0x9885
movups (%rcx), %xmm0
movups %xmm0, (%rdx)
jmp 0x9890
pushq $0x20
popq %rdi
callq 0x4190
movq %rax, %r14
leaq 0x19c7b(%rip), %rsi     # 0x234d9
leaq -0x220(%rbp), %rdx
movq %rax, %rdi
callq 0x4140
leaq 0x2b4e4(%rip), %rsi     # 0x34d58
movq 0x2b725(%rip), %rdx     # 0x34fa0
movq %r14, %rdi
callq 0x45c0
jmp 0x98bb
movq %rsi, (%rax)
movq -0x50(%rbp), %rdx
movq %rdx, 0x10(%rax)
movq -0x58(%rbp), %rdx
movq %rdx, 0x8(%rax)
movq %rcx, -0x60(%rbp)
andq $0x0, -0x58(%rbp)
movb $0x0, -0x50(%rbp)
leaq 0x2b4ac(%rip), %rsi     # 0x34d58
movq 0x2b6ed(%rip), %rdx     # 0x34fa0
movq %rax, %rdi
callq 0x45c0
jmp 0x9922
movq %rax, %rbx
movq %r14, %rdi
callq 0x4290
jmp 0x9925
movq %rax, %rbx
jmp 0x9931
movq %rax, %rbx
movq %r14, %rdi
callq 0x4290
jmp 0x9931
movq %rax, %rbx
jmp 0x993a
jmp 0x9922
jmp 0x9922
jmp 0x9911
movq %rax, %rbx
movq %r14, %rdi
callq 0x4290
jmp 0x9914
jmp 0x9922
jmp 0x9922
jmp 0x9922
jmp 0x9922
jmp 0x9922
jmp 0x9900
movq %rax, %rbx
leaq -0x220(%rbp), %rdi
callq 0x42b0
jmp 0x9925
movq %rax, %rbx
leaq -0x220(%rbp), %rdi
callq 0x9ff4
jmp 0x9925
movq %rax, %rbx
leaq -0x90(%rbp), %rdi
callq 0x46b8
leaq -0x60(%rbp), %rdi
callq 0x46b8
leaq -0x428(%rbp), %rdi
callq 0x40d0
movq %rbx, %rdi
callq 0x45f0