// File: /workspace/github_cpp_makefile_star2_O2/readmapping[P]alfalfa/src/dp.cpp
// Function: dynProg::dpBasic(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, boundaries&, dp_type const&, outputType const&, dp_output&)
int dynProg::dpBasic( const string& ref, 
        const string&     query,
        boundaries& offset,
        const dp_type&    type,
        const outputType& oType,
        dp_output&  output){
    L1 = offset.refE-offset.refB+1;
    L2 = offset.queryE-offset.queryB+1;
    assert(L1 >=0 && L2 >= 0);
    //build matrices
    updateMatrix(type, false, false);
    M[0][0] = 0;
    for(int i = 1; i <= L2; i++)
        M[i][0] = type.freeQueryB ? 0 : scores.openGap + i*scores.extendGap;
    for(int i = 1; i <= L1; i++)
        M[0][i] = type.freeRefB ? 0 : scores.openGap + i*scores.extendGap;
    //dp
    int        d = 0;
    for(long i = 1L; i <= L2; i++ ){
        for(long j = 1L; j <= L1; j++ ){
            //here insert substitution matrix!
            d = scores.scoreMatrix[size_t(ref[offset.refB+j-1])][size_t(query[offset.queryB+i-1])];
            M[ i ][ j ] = max(M[ i-1 ][ j-1 ] + d, M[ i ][ j-1 ] + scores.extendGap);
            M[ i ][ j ] = max(M[ i ][ j ], M[ i-1 ][ j ] + scores.extendGap);
        }
    }
    //traceback and output
    int        i = L2, j = L1;
    //find beginPosition for traceBack and find dpScore
    int maximum = M[i][j];
    for(int idx = L1; idx >= 0; idx--){
        if(M[i][idx] > maximum){
            maximum = M[i][idx];
            j = idx;
        }
    }
    output.dpScore = M[i][j];
    //Next is for output only
    if(oType>DPSCORE){
        //Alter boundaries to return the new positions when free gaps were introduced.
        if(type.freeRefE && j < L1)
            offset.refE = offset.refB+j-1;
        //traceBack
        std::stringstream ss;
        while( i > 0 ){
            bool equal = false;
            if(j > 0 && i > 0)
                equal = ref[offset.refB+j-1] == query[offset.queryB+i-1];
            if( j > 0 && i > 0 && M[ i ][ j ] == M[ i-1 ][ j-1 ] + scores.match && equal){
                ss << '=';
                i-- ;  j-- ;
            }
            else if(j > 0 && i > 0 && M[ i ][ j ] == M[ i-1 ][ j-1 ] + scores.mismatch){
                ss << 'X';
                output.editDist++;
                i-- ;  j-- ;
            }
            else if(j > 0 && (M[ i ][ j ] == M[ i ][ j-1 ] + scores.extendGap || i==0)){
                ss << 'D';
                output.editDist++;
                j-- ;
            }
            else if(i > 0 && (M[ i ][ j ] == M[ i-1 ][ j ] + scores.extendGap || j==0)){
                ss << 'I';
                output.editDist++;
                i-- ;
            }
            else{
                cerr << "Error in dynamic programming" << endl;
                cerr << "No valid trace position found" << endl;
                cerr << "Position " << i << ", " << j << endl;
                cerr << "Scores: Current " << M[ i ][ j ] << endl;
                if(j > 0 && i > 0){
                    cerr << "Scores: Diag "    << M[ i-1 ][ j-1 ] << endl;
                    cerr << "Characters "    << ref[offset.refB+j-1] << "  " << query[offset.queryB+i-1] << endl; 
                }
                if(j > 0)
                    cerr << "Scores: Left "    << M[ i ][ j-1 ] << endl;
                if(i > 0)
                    cerr << "Scores: Up "    << M[ i-1 ][ j ] << endl;
                exit(1);
            }
        }
        //Edit Dist ouput
        if( i > 0 && !type.freeQueryB)
            output.editDist += i;
        if(j > 0 && !type.freeRefB)
            output.editDist += j;
        //Errorstring output
        if(oType == ERRORSTRING || oType == ALL){
            string errorString = ss.str();
            if(i > 0 && !type.freeQueryB)
                errorString.append(i,'I');
            else if(j > 0 && !type.freeRefB)
                errorString.append(j, 'D');
            reverse( errorString.begin(), errorString.end() );
            //create output: errorString
            int iter = 0;
            int temp;
            int errorStringLength = errorString.length();
            while(iter < errorStringLength){
                temp = iter;
                while(iter+1 < errorStringLength && errorString[iter+1]==errorString[temp])
                    iter++;
                iter++;
                output.cigarChars.push_back(errorString[temp]);
                output.cigarLengths.push_back(iter-temp);
            }
        }
    }
    if(type.freeRefB && j > 0)
        offset.refB = offset.refB+j;

    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1c8, %rsp            # imm = 0x1C8
movq %r9, 0x10(%rsp)
movq %r8, %r12
movq %rcx, %rbx
movq %rdx, (%rsp)
movq %rsi, %r13
movq %rdi, %r15
movl 0x8(%rcx), %eax
subl (%rcx), %eax
incl %eax
movl %eax, 0x20(%rdi)
movl 0x14(%rcx), %eax
subl 0x10(%rcx), %eax
incl %eax
movl %eax, 0x24(%rdi)
movq %r8, %rsi
xorl %edx, %edx
xorl %ecx, %ecx
callq 0x15822
movq (%r15), %rax
movq (%rax), %rcx
andl $0x0, (%rcx)
movb 0x2(%r12), %dl
movq 0x38(%r15), %rsi
pushq $0x1
popq %rdi
movslq 0x24(%r15), %r8
cmpq %r8, %rdi
jg 0x18785
xorl %r8d, %r8d
testb $0x1, %dl
jne 0x18779
movl 0xc(%rsi), %r8d
imull %edi, %r8d
addl 0x8(%rsi), %r8d
movq (%rax,%rdi,8), %r9
movl %r8d, (%r9)
incq %rdi
jmp 0x1875c
movb (%r12), %dl
movq 0x38(%r15), %rsi
pushq $0x1
popq %rdi
movslq 0x20(%r15), %r14
cmpq %r14, %rdi
jg 0x187b6
xorl %r8d, %r8d
testb $0x1, %dl
jne 0x187ad
movl 0xc(%rsi), %r8d
imull %edi, %r8d
addl 0x8(%rsi), %r8d
movl %r8d, (%rcx,%rdi,4)
incq %rdi
jmp 0x18790
movq %r12, 0x8(%rsp)
pushq $0x1
popq %rcx
movq %rcx, %rdx
movl 0x24(%r15), %ebp
movslq %ebp, %rsi
cmpq %rsi, %rdx
jg 0x1885a
movq 0x38(%r15), %rsi
movq (%r13), %rdi
addq (%rbx), %rdi
leaq 0x10(%rsi), %r8
movq (%rsp), %r9
movq (%r9), %r9
addq %rdx, %r9
decq %r9
movq %rcx, %r10
movslq %r14d, %r11
cmpq %r11, %r10
jg 0x18852
movsbq -0x1(%rdi,%r10), %r11
movslq 0x10(%rbx), %r14
movsbq (%r9,%r14), %r14
imulq $0x1fc, %r11, %r11      # imm = 0x1FC
addq %r8, %r11
movq -0x8(%rax,%rdx,8), %r12
movl -0x4(%r12,%r10,4), %ebp
addl (%r11,%r14,4), %ebp
movq (%rax,%rdx,8), %r11
movl 0xc(%rsi), %r14d
addl -0x4(%r11,%r10,4), %r14d
cmpl %r14d, %ebp
cmovgl %ebp, %r14d
movl %r14d, (%r11,%r10,4)
movl 0xc(%rsi), %ebp
addl (%r12,%r10,4), %ebp
cmpl %ebp, %r14d
cmovgl %r14d, %ebp
movl %ebp, (%r11,%r10,4)
incq %r10
movl 0x20(%r15), %r14d
jmp 0x187f0
incq %rdx
jmp 0x187c1
movq (%rax,%rsi,8), %rax
movslq %r14d, %rcx
movl (%rax,%rcx,4), %ecx
movl %r14d, %edx
testl %edx, %edx
js 0x1887d
movl %edx, %esi
movl (%rax,%rsi,4), %esi
cmpl %ecx, %esi
cmovgl %edx, %r14d
cmovgl %esi, %ecx
decl %edx
jmp 0x18867
movslq %r14d, %rcx
movl (%rax,%rcx,4), %eax
movq 0x200(%rsp), %rdx
movl %eax, 0x4(%rdx)
movq 0x10(%rsp), %rax
cmpl $0x0, (%rax)
jle 0x18aa4
movq 0x8(%rsp), %rax
cmpb $0x1, 0x1(%rax)
jne 0x188ba
cmpl 0x20(%r15), %r14d
jge 0x188ba
movq (%rbx), %rax
addq %rcx, %rax
decq %rax
movq %rax, 0x8(%rbx)
leaq 0x40(%rsp), %rdi
callq 0x71e0
movl %ebp, %ebp
movslq %r14d, %r14
movslq %ebp, %r12
testl %ebp, %ebp
jle 0x189c1
movq (%r15), %rcx
testl %r14d, %r14d
jle 0x18955
movl %r14d, %edx
movq -0x8(%rcx,%rbp,8), %rax
movq (%rcx,%rbp,8), %rcx
movl (%rcx,%rdx,4), %esi
movl -0x4(%rax,%rdx,4), %r8d
movq 0x38(%r15), %rdi
movl (%rdi), %r9d
addl %r8d, %r9d
cmpl %r9d, %esi
jne 0x18920
movq (%r13), %r9
addq (%rbx), %r9
movslq 0x10(%rbx), %r10
addq %r12, %r10
movq (%rsp), %r11
movq (%r11), %r11
movb -0x1(%r11,%r10), %r10b
cmpb %r10b, -0x1(%rdx,%r9)
je 0x18991
addl 0x4(%rdi), %r8d
cmpl %r8d, %esi
je 0x189a0
movl 0xc(%rdi), %edi
movl -0x4(%rcx,%rdx,4), %edx
addl %edi, %edx
cmpl %edx, %esi
jne 0x18965
leaq 0x50(%rsp), %rdi
pushq $0x44
popq %rsi
callq 0x7330
movq 0x200(%rsp), %rax
incl (%rax)
decq %r14
jmp 0x188cc
movq -0x8(%rcx,%rbp,8), %rax
movq (%rcx,%rbp,8), %rcx
movq 0x38(%r15), %rdx
movl 0xc(%rdx), %edi
addl (%rax,%r14,4), %edi
cmpl %edi, (%rcx,%r14,4)
je 0x18978
testl %r14d, %r14d
jne 0x18ae9
leaq 0x50(%rsp), %rdi
pushq $0x49
popq %rsi
callq 0x7330
movq 0x200(%rsp), %rax
incl (%rax)
jmp 0x189ba
leaq 0x50(%rsp), %rdi
pushq $0x3d
popq %rsi
callq 0x7330
jmp 0x189b7
leaq 0x50(%rsp), %rdi
pushq $0x58
popq %rsi
callq 0x7330
movq 0x200(%rsp), %rax
incl (%rax)
decl %r14d
decl %ebp
jmp 0x188c4
testl %r14d, %r14d
movq 0x8(%rsp), %r15
jle 0x189dc
cmpb $0x0, (%r15)
jne 0x189dc
movq 0x200(%rsp), %rax
addl %r14d, (%rax)
movq 0x10(%rsp), %rax
movl (%rax), %eax
addl $-0x3, %eax
cmpl $0x1, %eax
ja 0x18aba
leaq 0x58(%rsp), %rsi
leaq 0x20(%rsp), %rdi
callq 0x7540
testl %r14d, %r14d
jle 0x18a19
cmpb $0x0, (%r15)
jne 0x18a19
movl %r14d, %esi
leaq 0x20(%rsp), %rdi
pushq $0x44
popq %rdx
callq 0x7300
movq 0x20(%rsp), %rdi
movq 0x28(%rsp), %rsi
addq %rdi, %rsi
callq 0xa101
movq 0x28(%rsp), %r13
movq 0x200(%rsp), %rax
leaq 0x8(%rax), %rcx
movq %rcx, (%rsp)
addq $0x20, %rax
movq %rax, 0x10(%rsp)
movslq %r13d, %rbp
xorl %r15d, %r15d
cmpl %r13d, %r15d
jge 0x18aab
movq 0x20(%rsp), %rax
movslq %r15d, %rcx
leaq (%rax,%rcx), %rsi
incq %rcx
movl %r15d, %r12d
cmpq %rbp, %rcx
jge 0x18a7a
movb (%rax,%rcx), %dl
incl %r12d
incq %rcx
cmpb (%rsi), %dl
je 0x18a66
jmp 0x18a7d
movl %r13d, %r12d
movq (%rsp), %rdi
callq 0x18cba
movl %r12d, %eax
subl %r15d, %eax
movl %eax, 0x1c(%rsp)
movq 0x10(%rsp), %rdi
leaq 0x1c(%rsp), %rsi
callq 0x18e08
movl %r12d, %r15d
jmp 0x18a4f
movq 0x8(%rsp), %r15
jmp 0x18ac4
leaq 0x20(%rsp), %rdi
callq 0x76a8
movq 0x8(%rsp), %r15
leaq 0x40(%rsp), %rdi
callq 0x7210
cmpb $0x1, (%r15)
jne 0x18ad5
testl %r14d, %r14d
jle 0x18ad5
movl %r14d, %eax
addq %rax, (%rbx)
xorl %eax, %eax
addq $0x1c8, %rsp            # imm = 0x1C8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x314f8(%rip), %rdi     # 0x49fe8
leaq 0x1ddd1(%rip), %rsi     # 0x368c8
callq 0x72b0
movq %rax, %rdi
callq 0x7160
movq 0x314dd(%rip), %rdi     # 0x49fe8
leaq 0x1ddd3(%rip), %rsi     # 0x368e5
callq 0x72b0
movq %rax, %rdi
callq 0x7160
movq 0x314c2(%rip), %rdi     # 0x49fe8
leaq 0x1ddd6(%rip), %rsi     # 0x36903
callq 0x72b0
movq %rax, %rdi
movl %ebp, %esi
callq 0x75c0
leaq 0x1ddca(%rip), %rsi     # 0x3690d
movq %rax, %rdi
callq 0x72b0
movq %rax, %rdi
movl %r14d, %esi
callq 0x75c0
movq %rax, %rdi
callq 0x7160
movq 0x31483(%rip), %rdi     # 0x49fe8
leaq 0x1dda4(%rip), %rsi     # 0x36910
callq 0x72b0
movq (%r15), %rcx
movq (%rcx,%rbp,8), %rcx
movl (%rcx,%r14,4), %esi
movq %rax, %rdi
callq 0x75c0
movq %rax, %rdi
callq 0x7160
testl %r14d, %r14d
jle 0x18c54
movq 0x3144c(%rip), %rdi     # 0x49fe8
leaq 0x1dd7e(%rip), %rsi     # 0x36921
callq 0x72b0
movq (%r15), %rcx
movq -0x8(%rcx,%rbp,8), %rcx
movl %r14d, %r12d
movl -0x4(%rcx,%r12,4), %esi
movq %rax, %rdi
callq 0x75c0
movq %rax, %rdi
callq 0x7160
movq 0x31419(%rip), %rdi     # 0x49fe8
leaq 0x1dd59(%rip), %rsi     # 0x3692f
callq 0x72b0
movq (%rbx), %rcx
addq (%r13), %rcx
movsbl -0x1(%r14,%rcx), %esi
movq %rax, %rdi
callq 0x7330
leaq 0x1dd72(%rip), %rsi     # 0x36969
movq %rax, %rdi
callq 0x72b0
movslq 0x10(%rbx), %rcx
movslq %ebp, %rdx
addq %rcx, %rdx
movq (%rsp), %rcx
movq (%rcx), %rcx
movsbl -0x1(%rcx,%rdx), %esi
movq %rax, %rdi
callq 0x7330
movq %rax, %rdi
callq 0x7160
movq 0x313bc(%rip), %rdi     # 0x49fe8
leaq 0x1dd12(%rip), %rsi     # 0x36945
callq 0x72b0
movq (%r15), %rcx
movq (%rcx,%rbp,8), %rcx
movl -0x4(%rcx,%r12,4), %esi
movq %rax, %rdi
callq 0x75c0
movq %rax, %rdi
callq 0x7160
movq 0x3138d(%rip), %rdi     # 0x49fe8
leaq 0x1dcf1(%rip), %rsi     # 0x36953
callq 0x72b0
movq (%r15), %rcx
movq -0x8(%rcx,%rbp,8), %rcx
movl (%rcx,%r14,4), %esi
movq %rax, %rdi
callq 0x75c0
movq %rax, %rdi
callq 0x7160
pushq $0x1
popq %rdi
callq 0x7390
jmp 0x18ca4
jmp 0x18c95
jmp 0x18ca4
jmp 0x18ca4
jmp 0x18c95
movq %rax, %rbx
leaq 0x20(%rsp), %rdi
callq 0x76a8
jmp 0x18ca7
movq %rax, %rbx
leaq 0x40(%rsp), %rdi
callq 0x7210
movq %rbx, %rdi
callq 0x75e0
nop