# How do these alternative Q# algorithms produce the same set of Bell states?

In the "Superposition" Microsoft quantum katas (https://github.com/microsoft/QuantumKatas/blob/master/Superposition/ReferenceImplementation.qs) the solution for Task 7 looks like this:

// ------------------------------------------------------
// Task 7. All Bell states
// Inputs:
//      1) two qubits in |00⟩ state (stored in an array of length 2)
//      2) an integer index
// Goal: create one of the Bell states based on the value of index:
//       0: |Φ⁺⟩ = (|00⟩ + |11⟩) / sqrt(2)
//       1: |Φ⁻⟩ = (|00⟩ - |11⟩) / sqrt(2)
//       2: |Ψ⁺⟩ = (|01⟩ + |10⟩) / sqrt(2)
//       3: |Ψ⁻⟩ = (|01⟩ - |10⟩) / sqrt(2)

operation AllBellStates_Reference (qs : Qubit[], index : Int) : Unit is Adj {
H(qs[0]);
CNOT(qs[0], qs[1]);

// now we have |00⟩ + |11⟩ - modify it based on index arg
if (index % 2 == 1) {
// negative phase
Z(qs[1]);
}
if (index / 2 == 1) {
X(qs[1]);
}


}

And my alternative solution looks like this:

// Task 7. All Bell states
// Inputs:
//      1) two qubits in |00⟩ state (stored in an array of length 2)
//      2) an integer index
// Goal: create one of the Bell states based on the value of index:
//    0: |Φ⁺⟩ = (|00⟩ + |11⟩) / sqrt(2)
//    1: |Φ⁻⟩ = (|00⟩ - |11⟩) / sqrt(2)
//    2: |Ψ⁺⟩ = (|01⟩ + |10⟩) / sqrt(2)
//    3: |Ψ⁻⟩ = (|01⟩ - |10⟩) / sqrt(2)

operation AllBellStates (qs : Qubit[], index : Int) : Unit
{
H(qs[0]);
CNOT(qs[0], qs[1]);

if (index == 0){
} elif(index == 1) {
Z(qs[0]);
} elif(index == 2){
X(qs[0]);
} elif(index == 3){
X(qs[0]);
Z(qs[1]);
}


}

Yet BOTH solutions pass the unit tests. How is that possible, since the X-gate and Z-gate operators are being applied to the other qubit in the pair? Could the unit test logic be incorrect?

The unit test logic is correct, no worries there! One of the really neat things about the four Bell states is that you can transform between each using single-qubit operations. For example, consider the Bell state $$\left|\Phi^{+}\right\rangle = \frac{1}{\sqrt{2}} \left(\left|00\right\rangle + \left|11\right\rangle\right)$$. Flipping the first qubit with an X instruction transforms the state of your qubits to $$\frac{1}{\sqrt{2}} \left(\left|10\right\rangle + \left|01\right\rangle\right)$$, while flipping the second qubit with X(qs[1]) transforms your qubits into the state $$\frac{1}{\sqrt{2}} \left(\left|01\right\rangle + \left|10\right\rangle\right)$$. Since addition is commutative (that is, $$a + b = b + a$$), these two states are equal.
Thus, even though X(qs[0]) and X(qs[1]) are very different instructions, they do the same thing in the special case of the Bell state $$\left|\Phi^{+}\right\rangle$$. In the same way, Z(qs[0]) and Z(qs[1]) do the same thing to $$\left|\Phi^{+}\right\rangle$$. Another way of thinking of why this is is that the quantum programs ApplyToEach(X, qs) and ApplyToEach(Z, qs) do nothing to qubits in the state $$\left|\Phi^{+}\right\rangle$$, similarly to how Z(q) does nothing when q is in the state |0⟩. If you're interested, there's a beautiful mathematical framework known as the stabilizer formalism for helping to track these kinds of symmetries of quantum states.