// File: canzarlab[P]Trajan/src/BnG.cpp
// Function: GenericBnBSolver::Solve(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>)
void GenericBnBSolver::Solve(string filename, string outScoreFile)
{
    this->filename = filename;
    
#if DEBUG == 1    
    if (debug_file == "")
        debug_log = ofstream(filename + ".log");
    else
        debug_log = ofstream(debug_file + ".log");
    debug_nodecnt  = 0;
    debug_genocnt  = 0;
    debug_genotime = 0;
    debug_genomin  = 1e20;
    debug_genomax  = 0;
#endif

#if DEBUG == 1    
    Timer T; T.start();
#endif

    sys_sol.conservativeResizeLike(Vector::Zero(nr_cols));
    OnSolverInit();

    PushNode(InitNodeFrom(nullptr));
    while (!OpenEmpty())
    {
        for (auto& it : EvalOpen())
        {
            vector<BnBNode*>* V = EvalBranch(it);
#if DEBUG == 1
            if (V != nullptr)
                debug_log << "fixed: " << V->front()->debug_varid << " (" << V->front()->debug_varval << " <- " << it->sol(V->front()->debug_varid) << ") in node " << it->debug_nodeid << endl << endl;
#endif

            if (V != nullptr)
                PushAll(V);
            else if (sys_ub > it->obj)
            {
                sys_sol = it->sol;
                sys_ub  = it->obj;         
#if DEBUG == 1    
                debug_log << "BOUND " << sys_ub << " (" << it->debug_nodeid << ")" << endl << endl;
#endif            
                OnSolverUpdate();
            }
            delete it;
            
        }         
    }
#if DEBUG == 1    
    T.stop();
#endif

    if (OnSolverFinish())
    {
        x = sys_sol;
        for (size_t i = 0; i < x.size(); ++i)
            x(i) = round(x(i));    
        if (filename != "") 
            WriteSolution(filename);     
        // write the objective function 
        ofstream score(outScoreFile);
        score << moptVal << endl;
        cout << "my score: "  << moptVal << endl;
        score.close();
    }

#if DEBUG == 1    
    debug_log << "total time: " << T.secs() << endl;
    debug_log << "total nodes: " << debug_nodecnt << endl;
    debug_log << "total geno calls: " << debug_genocnt << endl;
    debug_log << "total geno time: " << debug_genotime << " (" << debug_genomin << ", " << debug_genotime / debug_genocnt << "," << debug_genomax << ")" << endl;
    debug_log << "best: " << -sys_ub << endl << endl;
#endif
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x310, %rsp            # imm = 0x310
movq %rsi, -0x2c8(%rbp)
movq %rdx, -0x2c0(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0x2b0(%rbp)
addq $0x130, %rdi            # imm = 0x130
callq 0xa060
movq -0x2b0(%rbp), %rax
movq %rax, %rcx
addq $0x120, %rcx            # imm = 0x120
movq %rcx, -0x2b8(%rbp)
movslq 0x10c(%rax), %rsi
leaq -0x30(%rbp), %rdi
callq 0x13c30
movq -0x2b8(%rbp), %rdi
leaq -0x30(%rbp), %rsi
callq 0xcec20
movq -0x2b0(%rbp), %rdi
movq (%rdi), %rax
callq *0x80(%rax)
movq -0x2b0(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0xd34e0
movq -0x2b0(%rbp), %rdi
movq %rax, %rsi
movq (%rdi), %rax
callq *0x30(%rax)
movq -0x2b0(%rbp), %rdi
movq (%rdi), %rax
callq *0x38(%rax)
xorb $-0x1, %al
testb $0x1, %al
jne 0xd312c
jmp 0xd329e
movq -0x2b0(%rbp), %rsi
movq (%rsi), %rax
leaq -0x50(%rbp), %rdi
callq *0x40(%rax)
leaq -0x50(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rdi
callq 0xd9170
movq %rax, -0x58(%rbp)
movq -0x38(%rbp), %rdi
callq 0xd91a0
movq %rax, -0x60(%rbp)
leaq -0x58(%rbp), %rdi
leaq -0x60(%rbp), %rsi
callq 0xd91d0
testb $0x1, %al
jne 0xd317e
leaq -0x50(%rbp), %rdi
callq 0xd9250
jmp 0xd3299
leaq -0x58(%rbp), %rdi
callq 0xd9210
movq -0x2b0(%rbp), %rdi
movq %rax, -0x68(%rbp)
movq -0x68(%rbp), %rax
movq (%rax), %rsi
movq (%rdi), %rax
movq 0x48(%rax), %rax
callq *%rax
movq %rax, -0x2d0(%rbp)
jmp 0xd31ab
movq -0x2d0(%rbp), %rax
movq %rax, -0x70(%rbp)
cmpq $0x0, -0x70(%rbp)
je 0xd31ee
movq -0x2b0(%rbp), %rdi
movq -0x70(%rbp), %rsi
callq 0xd3610
jmp 0xd31cf
jmp 0xd3258
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
leaq -0x50(%rbp), %rdi
callq 0xd9250
jmp 0xd34d4
movq -0x2b0(%rbp), %rax
movsd 0x118(%rax), %xmm0
movq -0x68(%rbp), %rax
movq (%rax), %rax
ucomisd 0x60(%rax), %xmm0
jbe 0xd3256
movq -0x2b0(%rbp), %rdi
movq -0x68(%rbp), %rax
movq (%rax), %rsi
addq $0x50, %rsi
addq $0x120, %rdi            # imm = 0x120
callq 0x145a0
jmp 0xd322b
movq -0x2b0(%rbp), %rdi
movq -0x68(%rbp), %rax
movq (%rax), %rax
movsd 0x60(%rax), %xmm0
movsd %xmm0, 0x118(%rdi)
movq (%rdi), %rax
movq 0x88(%rax), %rax
callq *%rax
jmp 0xd3254
jmp 0xd3256
jmp 0xd3258
movq -0x68(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x2d8(%rbp)
cmpq $0x0, %rax
je 0xd3289
movq -0x2d8(%rbp), %rdi
callq 0xd2e10
movq -0x2d8(%rbp), %rdi
movl $0x68, %esi
callq 0xa460
jmp 0xd328b
leaq -0x58(%rbp), %rdi
callq 0xd9230
jmp 0xd315f
jmp 0xd3114
movq -0x2b0(%rbp), %rdi
movq (%rdi), %rax
callq *0x90(%rax)
testb $0x1, %al
jne 0xd32b7
jmp 0xd34cb
movq -0x2b0(%rbp), %rdi
movq %rdi, %rsi
addq $0x120, %rsi            # imm = 0x120
addq $0xc0, %rdi
callq 0x145a0
movq $0x0, -0x88(%rbp)
movq -0x2b0(%rbp), %rdi
movq -0x88(%rbp), %rax
movq %rax, -0x2e0(%rbp)
addq $0xc0, %rdi
callq 0x14700
movq %rax, %rcx
movq -0x2e0(%rbp), %rax
cmpq %rcx, %rax
jae 0xd3377
movq -0x2b0(%rbp), %rdi
addq $0xc0, %rdi
movq -0x88(%rbp), %rsi
callq 0x145f0
movsd (%rax), %xmm0
callq 0xa180
movq -0x2b0(%rbp), %rdi
movsd %xmm0, -0x2e8(%rbp)
addq $0xc0, %rdi
movq -0x88(%rbp), %rsi
callq 0x145f0
movsd -0x2e8(%rbp), %xmm0
movsd %xmm0, (%rax)
movq -0x88(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x88(%rbp)
jmp 0xd32df
movq -0x2c8(%rbp), %rdi
leaq 0x56e55(%rip), %rsi     # 0x12a1da
callq 0xa91e0
testb $0x1, %al
jne 0xd3390
jmp 0xd33ee
movq -0x2c8(%rbp), %rsi
leaq -0xa8(%rbp), %rdi
movq %rdi, -0x2f0(%rbp)
callq 0xa190
movq -0x2b0(%rbp), %rdi
movq -0x2f0(%rbp), %rsi
movq (%rdi), %rax
movq 0x18(%rax), %rax
callq *%rax
jmp 0xd33c3
leaq -0xa8(%rbp), %rdi
callq 0xa8d8
jmp 0xd33ee
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
leaq -0xa8(%rbp), %rdi
callq 0xa8d8
jmp 0xd34d4
movq -0x2c0(%rbp), %rsi
leaq -0x2a8(%rbp), %rdi
movq %rdi, -0x300(%rbp)
movl $0x10, %edx
callq 0xa890
movq -0x2b0(%rbp), %rax
movq -0x300(%rbp), %rdi
movsd 0x20(%rax), %xmm0
callq 0xa870
movq %rax, -0x2f8(%rbp)
jmp 0xd342e
movq -0x2f8(%rbp), %rdi
movq 0xcdb24(%rip), %rsi     # 0x1a0f60
callq 0xa4a0
jmp 0xd3443
movq 0xcdb66(%rip), %rdi     # 0x1a0fb0
leaq 0x589ff(%rip), %rsi     # 0x12be50
callq 0xa440
movq %rax, -0x308(%rbp)
jmp 0xd345f
movq -0x308(%rbp), %rdi
movq -0x2b0(%rbp), %rax
movsd 0x20(%rax), %xmm0
callq 0xa870
movq %rax, -0x310(%rbp)
jmp 0xd3480
movq -0x310(%rbp), %rdi
movq 0xcdad2(%rip), %rsi     # 0x1a0f60
callq 0xa4a0
jmp 0xd3495
leaq -0x2a8(%rbp), %rdi
callq 0xa620
jmp 0xd34a3
leaq -0x2a8(%rbp), %rdi
callq 0xa670
jmp 0xd34cb
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
leaq -0x2a8(%rbp), %rdi
callq 0xa670
jmp 0xd34d4
addq $0x310, %rsp            # imm = 0x310
popq %rbp
retq
movq -0x78(%rbp), %rdi
callq 0xa7c0
nopl (%rax)