// File: /workspace/github_cpp_makefile_star2_O3/szmer[P]brill/./src/corpus.cpp
// Function: Corpus::tag_all_unigram(bool)
Corpus Corpus::tag_all_unigram(bool leave_table) {

	Corpus child;
	child.sentences.reserve(sentences.size());

	// Compute frequency distribution for each tag for each word token (in this Corpus instance).
	map< string, map<string,int> > tag_freqs; // word => <tag => frequency>

	for(vector< vector<TaggedWord> >::iterator stc = sentences.begin(); stc != sentences.end(); stc++) { 

		child.sentences.push_back( vector<TaggedWord>() );
		child.sentences.rbegin()->reserve( stc->size() );	// reserve space in the last sentence
									// vector of the child

		for(vector<TaggedWord>::iterator tword = stc->begin(); tword != stc->end(); tword ++) {

			if(tag_freqs[tword->word].count(tword->tag) == 0) // (entry for this tag doesn't exist yet)
				tag_freqs[tword->word][tword->tag] = 1;
			else
				tag_freqs[tword->word][tword->tag] ++;
	
			// Copy the word to the last sentence of the child Corpus (with an empty tag).
			child.sentences.rbegin()->push_back( TaggedWord(tword->word, string("")) );

		}
	}

	// Go through the words in the child Corpus and tag each with the most frequent tag.
	for(vector< vector<TaggedWord> >::iterator stc = child.sentences.begin(); stc != child.sentences.end()
						; stc++) 
		for(unsigned int wi = 0; wi < stc->size(); wi ++) {

			TaggedWord * tword = & stc->at(wi);
	
			// Now, each word will receive its only known interpretation. IF there is more than one 
			// possible tag for given word, wipe all entries in tag_freqs except for the tag with
			// the highest frequency.
			if(tag_freqs[tword->word].size() > 1) {

				string max_label = "";
				int max_val = 0;

				for(map<string,int>::iterator tag_entry = tag_freqs[tword->word].begin()
						; tag_entry != tag_freqs[tword->word].end(); tag_entry ++)
					if(tag_entry->second > max_val) {
						max_label = tag_entry->first;
						max_val = tag_entry->second;
					}

				tag_freqs[tword->word].clear();
				tag_freqs[tword->word][max_label]; // create entry, don't care about value
			}
	
			// (there is only one intepretation)
			// Extract tag label of this lone entry.
			tword->tag = tag_freqs[tword->word].begin()->first;
	
		}

	// Fill unigram_table if it is requested.
	if(leave_table)
		for(map<string, map<string,int> >::iterator i = tag_freqs.begin(); i != tag_freqs.end(); i ++)
			unigram_table[ i->first ] = i->second.begin()->first;

	return child;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xd8, %rsp
movq %rsi, %rbx
xorl %eax, %eax
movq %rax, 0x10(%rdi)
xorps %xmm0, %xmm0
movups %xmm0, (%rdi)
leaq 0x20(%rdi), %rcx
movl $0x0, 0x20(%rdi)
movq %rax, 0x28(%rdi)
movq %rcx, 0x30(%rdi)
movq %rcx, 0x38(%rdi)
movq %rax, 0x40(%rdi)
movq 0x8(%rsi), %rax
subq (%rsi), %rax
movl %edx, -0x3c(%rbp)
sarq $0x3, %rax
movabsq $-0x5555555555555555, %rsi # imm = 0xAAAAAAAAAAAAAAAB
imulq %rax, %rsi
movq %rdi, -0x30(%rbp)
callq 0x629e
leaq -0xf0(%rbp), %rcx
movl $0x0, (%rcx)
xorl %eax, %eax
movq %rax, 0x8(%rcx)
movq %rcx, 0x10(%rcx)
movq %rcx, 0x18(%rcx)
movq %rax, 0x20(%rcx)
movq %rbx, %rax
movq (%rbx), %rbx
movq %rax, -0x38(%rbp)
cmpq 0x8(%rax), %rbx
je 0x2f8b
leaq -0x80(%rbp), %r12
xorps %xmm0, %xmm0
movaps %xmm0, -0x80(%rbp)
movq $0x0, -0x70(%rbp)
movq -0x30(%rbp), %r14
movq %r14, %rdi
movq %r12, %rsi
callq 0x6faa
movq %r12, %rdi
callq 0x603a
movq 0x8(%r14), %rdi
addq $-0x18, %rdi
movq 0x8(%rbx), %rsi
subq (%rbx), %rsi
sarq $0x6, %rsi
callq 0x63bc
movq (%rbx), %r13
cmpq 0x8(%rbx), %r13
je 0x2f79
leaq -0xf8(%rbp), %rdi
movq %r13, %rsi
callq 0x6450
movq %rax, %r14
leaq 0x20(%r13), %r15
movq %rax, %rdi
movq %r15, %rsi
callq 0x7a92
addq $0x8, %r14
cmpq %r14, %rax
je 0x2e65
leaq -0xf8(%rbp), %rdi
movq %r13, %rsi
callq 0x6450
movq %rax, %rdi
movq %r15, %rsi
callq 0x64d0
incl (%rax)
jmp 0x2e85
leaq -0xf8(%rbp), %rdi
movq %r13, %rsi
callq 0x6450
movq %rax, %rdi
movq %r15, %rsi
callq 0x64d0
movl $0x1, (%rax)
movq -0x30(%rbp), %rax
movq 0x8(%rax), %r15
leaq -0x90(%rbp), %rax
movq %rax, -0xa0(%rbp)
movq (%r13), %rsi
movq 0x8(%r13), %rdx
addq %rsi, %rdx
leaq -0xa0(%rbp), %rdi
callq 0x6e16
leaq -0xb0(%rbp), %rax
movq %rax, -0xc0(%rbp)
leaq -0xc0(%rbp), %r14
movq %r14, %rdi
leaq 0x629d(%rip), %rdx      # 0x916e
movq %rdx, %rsi
callq 0x6eb4
movq %r12, %rdi
leaq -0xa0(%rbp), %rsi
movq %r14, %rdx
callq 0x6168
addq $-0x18, %r15
movq %r15, %rdi
movq %r12, %rsi
callq 0x71d6
movq -0x60(%rbp), %rdi
leaq -0x50(%rbp), %rax
cmpq %rax, %rdi
je 0x2f13
movq -0x50(%rbp), %rsi
incq %rsi
callq 0x21c0
movq -0x80(%rbp), %rdi
leaq -0x70(%rbp), %rax
cmpq %rax, %rdi
je 0x2f2c
movq -0x70(%rbp), %rsi
incq %rsi
callq 0x21c0
movq -0xc0(%rbp), %rdi
leaq -0xb0(%rbp), %rax
cmpq %rax, %rdi
je 0x2f4e
movq -0xb0(%rbp), %rsi
incq %rsi
callq 0x21c0
movq -0xa0(%rbp), %rdi
leaq -0x90(%rbp), %rax
cmpq %rax, %rdi
je 0x2f70
movq -0x90(%rbp), %rsi
incq %rsi
callq 0x21c0
addq $0x40, %r13
jmp 0x2e13
addq $0x18, %rbx
movq -0x38(%rbp), %rax
cmpq 0x8(%rax), %rbx
jne 0x2dd2
movq -0x30(%rbp), %rax
movq (%rax), %r15
movq 0x8(%rax), %rcx
cmpq %rcx, %r15
je 0x30dd
leaq -0xf8(%rbp), %rbx
movq (%r15), %rax
cmpq %rax, 0x8(%r15)
je 0x30d0
xorl %r12d, %r12d
xorl %r14d, %r14d
movq %r15, -0xc8(%rbp)
shlq $0x6, %r12
addq %rax, %r12
movq %rbx, %rdi
movq %r12, %rsi
callq 0x6450
cmpq $0x2, 0x28(%rax)
jb 0x308c
leaq -0x70(%rbp), %rax
movq %rax, -0x80(%rbp)
leaq -0x80(%rbp), %rdi
leaq 0x617e(%rip), %rdx      # 0x916e
movq %rdx, %rsi
callq 0x6eb4
movq %rbx, %rdi
movq %r12, %rsi
callq 0x6450
movq 0x18(%rax), %r13
xorl %r15d, %r15d
movq %rbx, %rdi
movq %r12, %rsi
callq 0x6450
addq $0x8, %rax
cmpq %rax, %r13
je 0x3042
cmpl %r15d, 0x40(%r13)
jle 0x3035
leaq 0x20(%r13), %rsi
leaq -0x80(%rbp), %rdi
callq 0x2110
movl 0x40(%r13), %r15d
movq %r13, %rdi
callq 0x2130
movq %rax, %r13
jmp 0x300a
movq %rbx, %rdi
movq %r12, %rsi
callq 0x6450
movq %rax, %rdi
callq 0x7e9e
movq %rbx, %rdi
movq %r12, %rsi
callq 0x6450
movq %rax, %rdi
leaq -0x80(%rbp), %rsi
callq 0x64d0
movq -0x80(%rbp), %rdi
leaq -0x70(%rbp), %rax
cmpq %rax, %rdi
je 0x3085
movq -0x70(%rbp), %rsi
incq %rsi
callq 0x21c0
movq -0xc8(%rbp), %r15
movq %rbx, %rdi
movq %r12, %rsi
callq 0x6450
movq 0x18(%rax), %rsi
addq $0x20, %rsi
addq $0x20, %r12
movq %r12, %rdi
callq 0x2110
incl %r14d
movq (%r15), %rax
movq 0x8(%r15), %rcx
subq %rax, %rcx
sarq $0x6, %rcx
movq %r14, %r12
cmpq %r14, %rcx
ja 0x2fc0
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rcx
addq $0x18, %r15
cmpq %rcx, %r15
jne 0x2fa6
cmpb $0x0, -0x3c(%rbp)
leaq -0xf0(%rbp), %r15
je 0x312b
movq -0xe0(%rbp), %rbx
cmpq %r15, %rbx
je 0x312b
addq $0x18, -0x38(%rbp)
leaq 0x20(%rbx), %rsi
movq 0x58(%rbx), %r14
movq -0x38(%rbp), %rdi
callq 0x6550
addq $0x20, %r14
movq %rax, %rdi
movq %r14, %rsi
callq 0x2110
movq %rbx, %rdi
callq 0x2130
movq %rax, %rbx
cmpq %r15, %rax
jne 0x30fb
leaq -0xf8(%rbp), %rdi
callq 0x6830
movq -0x30(%rbp), %rax
addq $0xd8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
jmp 0x31f9
jmp 0x31ca
movq %rax, %rbx
leaq -0x80(%rbp), %rdi
callq 0x603a
jmp 0x31ed
jmp 0x31ca
jmp 0x31d1
jmp 0x31ca
jmp 0x31ca
movq %rax, %rbx
jmp 0x3181
movq %rax, %rbx
leaq -0x80(%rbp), %rdi
callq 0x61ea
movq -0xc0(%rbp), %rdi
leaq -0xb0(%rbp), %rax
cmpq %rax, %rdi
je 0x31aa
movq -0xb0(%rbp), %rsi
incq %rsi
callq 0x21c0
jmp 0x31aa
jmp 0x31ca
movq %rax, %rbx
movq -0xa0(%rbp), %rdi
leaq -0x90(%rbp), %rax
cmpq %rax, %rdi
je 0x31ed
movq -0x90(%rbp), %rsi
jmp 0x31e5
jmp 0x31d1
jmp 0x31ca
movq %rax, %rbx
jmp 0x31ed
jmp 0x31d1
movq %rax, %rbx
movq -0x80(%rbp), %rdi
leaq -0x70(%rbp), %rax
cmpq %rax, %rdi
je 0x31ed
movq -0x70(%rbp), %rsi
incq %rsi
callq 0x21c0
leaq -0xf8(%rbp), %rdi
callq 0x6830
movq -0x30(%rbp), %r14
leaq 0x18(%r14), %rdi
callq 0x6960
movq %r14, %rdi
callq 0x67cc
movq %rbx, %rdi
callq 0x2320