// File: /workspace/github_cpp_makefile_star2_O3/NeoResearch[P]dbft3-spork-detect/main.cpp
// Function: selections(std::vector<int, std::allocator<int>>, int)
vector<vector<pair<int, int>>> selections(vector<int> choices, int f)
{
    int N = 3 * f + 1;
    vector<vector<pair<int, int>>> sel(N, vector<pair<int, int>>(2 * f, make_pair(-2, -2)));
    // for each i in N, select possible 2f responses, in order
    for (int i = 0; i < N; i++)
    {
        if (choices[i] == -2) // faulty node
            continue;
        vector<int> choicesi = make2f(choices, f, i); // 2f responses for replica i
        for (unsigned j = 0; j < choicesi.size(); j++)
            sel[i][j] = make_pair(choicesi[j], choices[choicesi[j]]);
        // may have bug here
        // R_3 | 1(1) |    1(3)    0(0)    | Cancel 1
        // we must prefer response over request, if double response being made
        // I think this only applies to non-prepare nodes
        if (i > 0) // only backups (or primary 1) ... not primary zero
        {
            int prepZero = -1;
            int respZero = -1;
            int prepOne = -1;
            int respOne = -1;
            for (unsigned k = 0; k < sel[i].size(); k++)
            {
                if ((sel[i][k].second == 0) && (sel[i][k].first == 0)) // prepareZero
                    prepZero = k;
                if ((sel[i][k].second == 1) && (sel[i][k].first == 1)) // prepareOne
                    prepOne = k;
                if ((sel[i][k].second == 0) && (sel[i][k].first == i)) // respZero
                    respZero = k;
                if ((sel[i][k].second == 1) && (sel[i][k].first == i)) // respOne
                    respOne = k;
            }
            cout << "*** i=" << i << " | choice=" << choices[i] << " | ";
            for (unsigned k = 0; k < sel[i].size(); k++)
                cout << sel[i][k].second << "(" << sel[i][k].first << ") ";
            cout << endl;

            // disabling multiple response
            /*
            if (choices[i] == 0) // assert that my prepare and response is going out
            {
                //assert(prepZero>-1); // this is my choice, not in this vector (TODO: improve)
                assert(respZero > -1);
                // if re-proposing, must prioritize reply
                if ((prepOne > -1) && (respOne == -1))
                {
                    // propose but no reply, let's change
                    //sel[i][prepOne].first = i; // now I'm responding, not sending proposal only
                    sel[i].push_back(make_pair(i, 1)); // My response
                    //assert(respOne > -1); // THIS must be valid
                }
            }
            if (choices[i] == 1) // assert that my prepare and response is going out
            {
                //assert(prepOne>-1); // this is my choice, not in this vector (TODO: improve)
                if(i != 1) // 'one' does not respond to itself
                    assert(respOne > -1);
                // if re-proposing, must prioritize reply
                if ((prepZero > -1) && (respZero == -1))
                {
                    // propose but no reply, let's change
                    //sel[i][prepZero].first = i; // now I'm responding, not sending proposal only
                    sel[i].push_back(make_pair(i, 0)); // My response
                    //assert(respZero > -1); // THIS must be valid
                }
            }
            */
            // DISABLED: this generates forks

        } // backups
    }

    return sel;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x68, %rsp
movl %edx, %r14d
movq %rsi, %r15
movq %rdi, %rbx
leal (%r14,%r14), %eax
movslq %eax, %rsi
movabsq $-0x100000002, %rax     # imm = 0xFFFFFFFEFFFFFFFE
leaq -0x90(%rbp), %rdx
movq %rax, (%rdx)
leaq -0x50(%rbp), %rdi
leaq -0x2a(%rbp), %rcx
callq 0x4d98
leal (%r14,%r14,2), %r12d
leal 0x1(%r12), %eax
movslq %eax, %rsi
leaq -0x50(%rbp), %rdx
leaq -0x29(%rbp), %rcx
movq %rbx, %rdi
callq 0x4e24
movq %rbx, -0x38(%rbp)
movq -0x50(%rbp), %rdi
testq %rdi, %rdi
je 0x28e2
movq -0x40(%rbp), %rsi
subq %rdi, %rsi
callq 0x2150
testl %r14d, %r14d
js 0x2b03
xorl %r13d, %r13d
testl %r12d, %r12d
cmovlel %r13d, %r12d
incl %r12d
leaq -0x88(%rbp), %rbx
movq %r14, -0x60(%rbp)
movq %r15, -0x68(%rbp)
movq %r12, -0x58(%rbp)
movq (%r15), %rax
cmpl $-0x2, (%rax,%r13,4)
je 0x2af7
movq %rbx, %rdi
movq %r15, %rsi
callq 0x4ec6
leaq -0x50(%rbp), %rdi
movq %rbx, %rsi
movl %r14d, %edx
movl %r13d, %ecx
callq 0x26c7
movq -0x88(%rbp), %rdi
testq %rdi, %rdi
je 0x294e
movq -0x78(%rbp), %rsi
subq %rdi, %rsi
callq 0x2150
movq -0x50(%rbp), %rdi
movq -0x48(%rbp), %rax
subq %rdi, %rax
je 0x2996
sarq $0x2, %rax
movq (%r15), %rcx
movq -0x38(%rbp), %rdx
movq (%rdx), %rdx
leaq (,%r13,2), %rsi
addq %r13, %rsi
movq (%rdx,%rsi,8), %rdx
xorl %esi, %esi
movslq (%rdi,%rsi,4), %r8
movl (%rcx,%r8,4), %r9d
movl %r8d, (%rdx,%rsi,8)
movl %r9d, 0x4(%rdx,%rsi,8)
incq %rsi
movl %esi, %r8d
cmpq %r8, %rax
ja 0x297a
testq %r13, %r13
je 0x2adf
movl $0x6, %edx
movq 0x662d(%rip), %rdi      # 0x8fd8
leaq 0x36c1(%rip), %rsi      # 0x6073
callq 0x2170
movq 0x661a(%rip), %rdi      # 0x8fd8
movl %r13d, %esi
callq 0x2210
movq %rax, %r14
movl $0xa, %edx
movq %rax, %rdi
leaq 0x36a2(%rip), %rsi      # 0x607a
callq 0x2170
movq (%r15), %rax
movl (%rax,%r13,4), %esi
movq %r14, %rdi
callq 0x2210
movl $0x3, %edx
movq %rax, %rdi
leaq 0x368a(%rip), %rsi      # 0x6085
callq 0x2170
movq -0x38(%rbp), %rax
movq %rax, %r12
movq (%rax), %rcx
movq %r13, -0x70(%rbp)
leaq (,%r13,2), %r15
addq %r13, %r15
movq (%rcx,%r15,8), %rax
cmpq %rax, 0x8(%rcx,%r15,8)
je 0x2a99
movl $0x1, %r13d
xorl %ebx, %ebx
movl 0x4(%rax,%rbx,8), %esi
movq 0x65a1(%rip), %rdi      # 0x8fd8
callq 0x2210
movq %rax, %r14
movl $0x1, %edx
movq %rax, %rdi
leaq 0x35e3(%rip), %rsi      # 0x6031
callq 0x2170
movq (%r12), %rax
movq (%rax,%r15,8), %rax
movl (%rax,%rbx,8), %esi
movq %r14, %rdi
callq 0x2210
movl $0x2, %edx
movq %rax, %rdi
leaq 0x3840(%rip), %rsi      # 0x62b5
callq 0x2170
movl %r13d, %ebx
movq (%r12), %rcx
movq (%rcx,%r15,8), %rax
movq 0x8(%rcx,%r15,8), %rcx
subq %rax, %rcx
sarq $0x3, %rcx
incl %r13d
cmpq %rbx, %rcx
ja 0x2a2c
movq 0x6538(%rip), %rcx      # 0x8fd8
movq (%rcx), %rax
movq -0x18(%rax), %rdi
addq %rcx, %rdi
movl $0xa, %esi
callq 0x2120
movq -0x68(%rbp), %r15
movq -0x70(%rbp), %r13
movsbl %al, %esi
movq 0x6512(%rip), %rdi      # 0x8fd8
callq 0x2030
movq %rax, %rdi
callq 0x20e0
movq -0x50(%rbp), %rdi
movq -0x60(%rbp), %r14
movq -0x58(%rbp), %r12
testq %rdi, %rdi
je 0x2af0
movq -0x40(%rbp), %rsi
subq %rdi, %rsi
callq 0x2150
leaq -0x88(%rbp), %rbx
incq %r13
cmpq %r12, %r13
jne 0x290b
movq -0x38(%rbp), %rax
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %r14
movq -0x50(%rbp), %rdi
testq %rdi, %rdi
je 0x2b7d
movq -0x40(%rbp), %rsi
subq %rdi, %rsi
callq 0x2150
jmp 0x2b7d
movq %rax, %r14
jmp 0x2b7d
movq %rax, %r14
movq -0x38(%rbp), %r12
jmp 0x2b75
movq -0x38(%rbp), %r12
movq %rax, %r14
movq -0x88(%rbp), %rdi
testq %rdi, %rdi
je 0x2b75
movq -0x78(%rbp), %rsi
jmp 0x2b6d
movq -0x38(%rbp), %r12
jmp 0x2b5d
movq %rax, %r14
movq -0x50(%rbp), %rdi
testq %rdi, %rdi
je 0x2b75
movq -0x40(%rbp), %rsi
subq %rdi, %rsi
callq 0x2150
movq %r12, %rdi
callq 0x4f46
movq %r14, %rdi
callq 0x2220