// File: /workspace/github_cpp_makefile_star2_O1/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, %r15d
movq %rsi, %r12
movq %rdi, %rbx
leal (%r15,%r15), %eax
movslq %eax, %rsi
movabsq $-0x100000002, %rax     # imm = 0xFFFFFFFEFFFFFFFE
leaq -0x90(%rbp), %rdx
movq %rax, (%rdx)
leaq -0x58(%rbp), %rdi
leaq -0x2a(%rbp), %rcx
callq 0x4d72
leal (%r15,%r15,2), %r13d
leal 0x1(%r13), %eax
movslq %eax, %rsi
leaq -0x58(%rbp), %rdx
leaq -0x29(%rbp), %rcx
movq %rbx, -0x38(%rbp)
movq %rbx, %rdi
callq 0x4df0
movq -0x58(%rbp), %rdi
testq %rdi, %rdi
je 0x28a7
movq -0x48(%rbp), %rsi
subq %rdi, %rsi
callq 0x2150
testl %r15d, %r15d
js 0x2ac5
xorl %r14d, %r14d
testl %r13d, %r13d
cmovlel %r14d, %r13d
incl %r13d
leaq -0x88(%rbp), %rbx
movq %r15, -0x70(%rbp)
movq %r12, -0x68(%rbp)
movq %r13, -0x60(%rbp)
movq (%r12), %rax
cmpl $-0x2, (%rax,%r14,4)
je 0x2ab9
movq %rbx, %rdi
movq %r12, %rsi
callq 0x4e92
leaq -0x58(%rbp), %rdi
movq %rbx, %rsi
movl %r15d, %edx
movl %r14d, %ecx
callq 0x26d1
movq -0x88(%rbp), %rdi
testq %rdi, %rdi
je 0x2914
movq -0x78(%rbp), %rsi
subq %rdi, %rsi
callq 0x2150
movq -0x58(%rbp), %rax
movq -0x50(%rbp), %rcx
subq %rax, %rcx
je 0x2956
sarq $0x2, %rcx
movq (%r12), %rdx
movq -0x38(%rbp), %rsi
movq (%rsi), %rsi
leaq (%r14,%r14,2), %rdi
movq (%rsi,%rdi,8), %rsi
xorl %edi, %edi
movslq (%rax,%rdi,4), %r8
movl (%rdx,%r8,4), %r9d
movl %r8d, (%rsi,%rdi,8)
movl %r9d, 0x4(%rsi,%rdi,8)
incq %rdi
movl %edi, %r8d
cmpq %r8, %rcx
ja 0x293a
movq %r14, -0x40(%rbp)
testq %r14, %r14
je 0x2a99
movl $0x6, %edx
movq 0x6669(%rip), %rdi      # 0x8fd8
leaq 0x36fd(%rip), %rsi      # 0x6073
callq 0x2170
movq 0x6656(%rip), %rdi      # 0x8fd8
movq -0x40(%rbp), %rsi
callq 0x2210
movq %rax, %r14
movl $0xa, %edx
movq %rax, %rdi
leaq 0x36dd(%rip), %rsi      # 0x607a
callq 0x2170
movq (%r12), %rax
movq -0x40(%rbp), %rcx
movl (%rax,%rcx,4), %esi
movq %r14, %rdi
callq 0x2210
movl $0x3, %edx
movq %rax, %rdi
leaq 0x36c1(%rip), %rsi      # 0x6085
callq 0x2170
movq -0x38(%rbp), %rax
movq %rax, %r12
movq (%rax), %rcx
movq -0x40(%rbp), %rax
leaq (%rax,%rax,2), %r15
movq (%rcx,%r15,8), %rax
cmpq %rax, 0x8(%rcx,%r15,8)
je 0x2a5b
movl $0x1, %r13d
xorl %ebx, %ebx
movl 0x4(%rax,%rbx,8), %esi
movq 0x65df(%rip), %rdi      # 0x8fd8
callq 0x2210
movq %rax, %r14
movl $0x1, %edx
movq %rax, %rdi
leaq 0x3621(%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 0x387e(%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 0x29ee
movq 0x6576(%rip), %rcx      # 0x8fd8
movq (%rcx), %rax
movq -0x18(%rax), %rdi
addq %rcx, %rdi
movl $0xa, %esi
callq 0x2120
movq -0x70(%rbp), %r15
movq -0x68(%rbp), %r12
movq -0x60(%rbp), %r13
movsbl %al, %esi
movq 0x654c(%rip), %rdi      # 0x8fd8
callq 0x2030
movq %rax, %rdi
callq 0x20e0
movq -0x58(%rbp), %rdi
testq %rdi, %rdi
je 0x2aae
movq -0x48(%rbp), %rsi
subq %rdi, %rsi
callq 0x2150
movq -0x40(%rbp), %r14
leaq -0x88(%rbp), %rbx
incq %r14
cmpq %r13, %r14
jne 0x28d0
movq -0x38(%rbp), %rax
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %r14
movq -0x58(%rbp), %rdi
testq %rdi, %rdi
je 0x2b3f
movq -0x48(%rbp), %rsi
subq %rdi, %rsi
callq 0x2150
jmp 0x2b3f
movq %rax, %r14
jmp 0x2b3f
movq %rax, %r14
movq -0x38(%rbp), %r12
jmp 0x2b37
movq -0x38(%rbp), %r12
movq %rax, %r14
movq -0x88(%rbp), %rdi
testq %rdi, %rdi
je 0x2b37
movq -0x78(%rbp), %rsi
jmp 0x2b2f
movq -0x38(%rbp), %r12
jmp 0x2b1f
movq %rax, %r14
movq -0x58(%rbp), %rdi
testq %rdi, %rdi
je 0x2b37
movq -0x48(%rbp), %rsi
subq %rdi, %rsi
callq 0x2150
movq %r12, %rdi
callq 0x4f12
movq %r14, %rdi
callq 0x2220