Prior to the computation of each clause, we will need to set up the logic to compute that clause. For example, prior to computing , we will need to negate the qubit corresponding to c, the third qubit. To do that succinctly in our Qiskit code, we create a function called setup_or_teardown_logic, which takes in a quantum register and quantum circuit object, as well as a truth value for each variable in the clause, set to False if the variable is negated in the clause, and set to True if it is left alone. The function is defined as follows:
def setup_or_teardown_logic(qr,qc,is_a,is_b,is_c):
"""
is_a,is_b,and is_c: False indicates the variable should be negated, True left as is.
Negation is done with the X gate.
"""
if not is_a:
qc.x(qr[0])
if not is_b:
qc.x(qr[1])
if not is_c:
qc.x(qr[2])
For the computation, the setup would then be setup_or_teardown_logic(qr,qc,True,True,False). After the setup, the three-qubit quantum OR is computed with the quantumor_3 function and the final result is stored in the temporary register of our choice. This will be repeated for each clause, so prior to setting up the next clause, we will need to tear down the logic for this clause.
Since the X gate reverses itself, this can be done by calling the setup_or_teardown_logic function with exactly the same arguments as in setup; thus the name of the function, which implies that it can be used to either set up or to tear down the logic of a clause. In the case of , that means we will call setup_or_teardown_logic(qr,qc,True,True,False) before and after the call to the quantumor_3 function.