예제 #1
0
def qft(a = 11, param = "draw"):
    # Initialisation
    if param == "draw":
        drawing_engine = CircuitDrawer()
        eng = MainEngine(drawing_engine)
    else:
        eng = MainEngine()
    [La, n] = int2bit(a)
    xa = eng.allocate_qureg(n)

    # initialisation de a et b
    for i in range(n):
        if La[i]:
            X | xa[i]

    # On passe de a a phi(a) : QTF
    eng.flush()
    QFT | xa

    eng.flush()

    if param != "draw":
        amp_xa = []
        for i in range(1 << n):
            phase_reel = phase(eng.backend.get_amplitude(adapt_binary(bin(i), n), xa)) / (2 * math.pi)
            amp_xa.append(Fraction(phase_reel).limit_denominator(10))
            print(amp_xa)

    All(Measure) | xa
    eng.flush()

    if param == "draw":
        print(drawing_engine.get_latex())
예제 #2
0
def run_adder(a=11, b=1, param="simulation"):
    # build compilation engine list
    resource_counter = ResourceCounter()
    rule_set = DecompositionRuleSet(
        modules=[projectq.libs.math, projectq.setups.decompositions])
    compilerengines = [
        AutoReplacer(rule_set),
        TagRemover(),
        LocalOptimizer(3),
        AutoReplacer(rule_set),
        TagRemover(),
        LocalOptimizer(3), resource_counter
    ]
    # create a main compiler engine
    if param == "latex":
        drawing_engine = CircuitDrawer()
        eng2 = MainEngine(drawing_engine)
        [xa, xb] = initialisation(eng2, a, b)
        adder(eng2, xa, xb)
        measure(eng2, xa, xb)
        print(drawing_engine.get_latex())
    else:
        eng = MainEngine(Simulator(), compilerengines)
        [xa, xb] = initialisation(eng, a, b)
        adder(eng, xa, xb)
        print(measure(eng, xa, xb))
예제 #3
0
def draw_algorithm(algorithm, num_qubits=None, name="test"):
    """
    Draw circuit of corresponding algorithm.
    
    algorithm: list of strs, gate sequence.
    num_qubits: int, number of qubits for algorithm. Can be None,
                     in which case the algorithm will be run on the minimum
                     number of qubits required.
    name: str, the resulting tex file will be written to name.tex.
    
    return: None.
    """
    #TODO: include drawing of measure gates.
    if num_qubits is None: num_qubits = get_num_qubits(algorithm)
    drawing_engine = CircuitDrawer()
    eng = MainEngine(drawing_engine)
    qureg = eng.allocate_qureg(num_qubits)
    for gate in algorithm:
        if "measure" not in gate.lower(): apply_gate(gate, qureg)
        else:
            _, gate_args = get_gate_info(gate)
            ops.Measure | qureg[gate_args[0]]
    eng.flush()
    with open("%s.tex" % name, "w") as f:
        f.write(drawing_engine.get_latex())
예제 #4
0
def run_inv(a=11, b=1, param="simulation"):
    # build compilation engine list
    resource_counter = ResourceCounter()
    rule_set = DecompositionRuleSet(modules=[projectq.libs.math,
                                             projectq.setups.decompositions])
    compilerengines = [AutoReplacer(rule_set),
                       TagRemover(),
                       LocalOptimizer(3),
                       AutoReplacer(rule_set),
                       TagRemover(),
                       LocalOptimizer(3),
                       resource_counter]

    # create a main compiler engine
    a1 = a
    b1 = b
    if a == 0:
        a1 = 1
    if b == 0:
        b1 = 1
    n = max(int(math.log(a1, 2)), int(math.log(b1, 2))) + 1

    if param == "latex":
        drawing_engine = CircuitDrawer()
        eng2 = MainEngine(drawing_engine)
        xa = initialisation_n(eng2, a, n + 1)
        xb = initialisation_n(eng2, b, n + 1)
        # b --> phi(b)
        QFT | xb
        phi_adder(eng2, xa, xb)
        with Dagger(eng2):
            QFT | xb
        All(Measure) | xa
        All(Measure) | xb
        eng2.flush()
        print(drawing_engine.get_latex())
    else:
        eng = MainEngine(Simulator(), compilerengines)
        xa = initialisation_n(eng, a, n + 1)
        xb = initialisation_n(eng, b, n + 1)
        # b --> phi(b)
        QFT | xb
        with Dagger(eng):
            phi_adder(eng, xa, xb)
        with Dagger(eng):
            QFT | xb
        All(Measure) | xa
        All(Measure) | xb
        eng.flush()
        n = n+1
        measurements_a = [0] * n
        measurements_b = [0] * n
        for k in range(n):
            measurements_a[k] = int(xa[k])
            measurements_b[k] = int(xb[k])

        return [measurements_a, meas2int(measurements_b), measurements_b]
예제 #5
0
def create_eng(path):
    drawing_engine = CircuitDrawer()
    eng = MainEngine(drawing_engine)

    create_circuit(eng, path)

    eng.flush()
    with open('circuit.tex', 'w') as f:
        #print >> f, 'Filename:', filename  # Python 2.x
        #print('Filename:', filename, file=f)  # Python 3.x
        print(drawing_engine.get_latex(), file=f)
예제 #6
0
    def test_print_circuit_diagram(self):
        """
        This function shows how to print LaTeX-based circuit diagrams.
        """
        drawer = CircuitDrawer()
        engine = MainEngine(drawer)
        
        qubits = engine.allocate_qureg(3)
        All(H) | qubits
        X | qubits[2]
        CNOT | (qubits[2], qubits[0])
        for qubit in qubits:
            Measure | qubit

        engine.flush()
        print(drawer.get_latex())
예제 #7
0
def run(args, param="simulation"):
    """
    Be careful the Measure command can take a lot of time to execute as you can create as much as qubit as you want
    :param args: list of int
    :param param: choose between simulation or latex
    :return:
    """
    # build compilation engine list
    resource_counter = ResourceCounter()
    rule_set = DecompositionRuleSet(
        modules=[projectq.libs.math, projectq.setups.decompositions])
    compilerengines = [
        AutoReplacer(rule_set),
        TagRemover(),
        LocalOptimizer(3),
        AutoReplacer(rule_set),
        TagRemover(),
        LocalOptimizer(3), resource_counter
    ]

    # create a main compiler engine
    if param == "latex":
        drawing_engine = CircuitDrawer()
        eng2 = MainEngine(drawing_engine)
        Xreg = initialisation(eng2, args)
        m = len(Xreg)
        All(Measure) | Xreg
        eng2.flush()
        print(drawing_engine.get_latex())
    else:
        eng = MainEngine(Simulator(), compilerengines)
        Xreg = initialisation(eng, args)
        m = len(Xreg)
        n = Xreg[0].__len__()
        for i in range(m):
            All(Measure) | Xreg[i]
        eng.flush()
        measurement = []
        for i in range(m):
            measurement.append([0] * n)
            for k in range(n):
                measurement[i][k] = int(Xreg[i][k])

        return measurement
def run(a=11, b=1, N=12, param="simulation"):
    # build compilation engine list
    resource_counter = ResourceCounter()
    rule_set = DecompositionRuleSet(
        modules=[projectq.libs.math, projectq.setups.decompositions])
    compilerengines = [
        AutoReplacer(rule_set),
        TagRemover(),
        LocalOptimizer(3),
        AutoReplacer(rule_set),
        TagRemover(),
        LocalOptimizer(3), resource_counter
    ]

    # create a main compiler engine
    n = int(math.log(N, 2)) + 1
    if param == "latex":
        drawing_engine = CircuitDrawer()
        eng2 = MainEngine(drawing_engine)

        xN = initialisation_n(eng2, N, n + 1)
        xa = initialisation_n(eng2, a, n + 1)
        xb = initialisation_n(eng2, b, n + 1)
        c1 = initialisation_n(eng2, 1)
        c2 = initialisation_n(eng2, 1)
        aux = initialisation_n(eng2, 0)
        # b --> phi(b)
        QFT | xb
        modularAdder(eng2, xa, xb, xN, c1, c2, aux)
        with Dagger(eng2):
            QFT | xb
        Measure | c1
        Measure | c2
        Measure | aux
        All(Measure) | xa
        All(Measure) | xb
        All(Measure) | xN
        eng2.flush()
        print(drawing_engine.get_latex())
    else:
        eng = MainEngine(Simulator(), compilerengines)
        xN = initialisation_n(eng, N, n + 1)
        xa = initialisation_n(eng, a, n + 1)
        xb = initialisation_n(eng, b, n + 1)
        [c1, c2, aux] = initialisation(eng, [1, 1, 0])
        # b --> phi(b)
        QFT | xb
        modularAdder(eng, xa, xb, xN, c1, c2, aux)
        with Dagger(eng):
            QFT | xb
        Measure | c1
        Measure | c2
        Measure | aux
        All(Measure) | xa
        All(Measure) | xb
        All(Measure) | xN
        eng.flush()

        measurements_a = [0] * n
        measurements_b = [0] * n
        measurements_N = [0] * n
        for k in range(n):
            measurements_a[k] = int(xa[k])
            measurements_b[k] = int(xb[k])
            measurements_N[k] = int(xN[k])

        return [
            measurements_a, measurements_b,
            int(xb[n]), measurements_N,
            int(aux[0]),
            int(c1[0]),
            int(c2[0]),
            meas2int(measurements_b), (a + b) % N
        ]
from projectq import MainEngine
from projectq.backends import CircuitDrawer

import teleport

if __name__ == "__main__":
    # create a main compiler engine with a simulator backend:
    drawing_engine = CircuitDrawer()
    locations = {0: 1, 1: 2, 2: 0}
    drawing_engine.set_qubit_locations(locations)
    eng = MainEngine(drawing_engine)

    # we just want to draw the teleportation circuit
    def create_state(eng, qb):
        pass

    # run the teleport and then, let Bob try to uncompute his qubit:
    teleport.run_teleport(eng, create_state, verbose=False)

    # print latex code to draw the circuit:
    print(drawing_engine.get_latex())
예제 #10
0
def run(a=4, N=7, x=2, param="run"):
    """

    :param a: a<N and must be invertible mod[N]
    :param N:
    :param x:
    :param param:
    :return: |1> --> |(a**x) mod N>
    """
    # build compilation engine list
    resource_counter = ResourceCounter()
    rule_set = DecompositionRuleSet(
        modules=[projectq.libs.math, projectq.setups.decompositions])
    compilerengines = [
        AutoReplacer(rule_set),
        TagRemover(),
        LocalOptimizer(3),
        AutoReplacer(rule_set),
        TagRemover(),
        LocalOptimizer(3), resource_counter
    ]

    # create a main compiler engine
    a = a % N
    b = 0
    n = int(math.log(N, 2)) + 1

    if param == "latex":
        drawing_engine = CircuitDrawer()
        eng = MainEngine(drawing_engine)
    if param == "count":
        eng = MainEngine(resource_counter)
    else:
        eng = MainEngine(Simulator(), compilerengines)

    output = initialisation_n(eng, 1, n + 1)
    xN = initialisation_n(eng, N, n + 1)
    xx = initialisation_n(eng, x, n + 1)
    xb = initialisation_n(eng, b, n + 1)
    aux = initialisation_n(eng, 0, 1)
    expoModN(eng, a, output, xb, xN, aux, xx, N)

    Measure | aux
    All(Measure) | output
    All(Measure) | xx
    All(Measure) | xb
    All(Measure) | xN
    eng.flush()

    if param == "count":
        return resource_counter
    if param == "latex":
        print(drawing_engine.get_latex())

    measurements_b = [0] * n
    measurements_x = [0] * n
    measurements_N = [0] * n
    for k in range(n):
        measurements_b[k] = int(xb[k])
        measurements_N[k] = int(xN[k])
        measurements_x[k] = int(output[k])

    mes_aux = int(aux[0])

    assert int(xb[n]) == 0
    assert int(xN[n]) == 0
    assert int(xx[n]) == 0
    assert meas2int(measurements_b) == 0
    assert meas2int(measurements_N) == N
    assert mes_aux == 0

    return [(a**x) % N, meas2int(measurements_x), measurements_x]
예제 #11
0
from projectq import MainEngine
from projectq.backends import CircuitDrawer
from projectq.ops import All, CNOT, H, Measure, Rz, X, Z


def getBellPair(engine):
    bit1 = engine.allocate_qubit()
    bit2 = engine.allocate_qubit()

    H | bit1
    CNOT | (bit1, bit2)

    return bit1, bit2

circuit_drawer = CircuitDrawer()
engine = MainEngine(circuit_drawer)

getBellPair(engine)

engine.flush()
print(circuit_drawer.get_latex())
def run(a=4, b=6, N=7, x=2, param="count"):
    """
    Last update 19/02 : nb of gate linear in log(N)
    Be careful this algo is a bit long to execute
    |b> --> |b+(ax) mod N> works for
    :param a:
    :param b:
    :param N:
    :param x:
    :param param:
    :return:
    """
    # build compilation engine list
    resource_counter = ResourceCounter()
    rule_set = DecompositionRuleSet(
        modules=[projectq.libs.math, projectq.setups.decompositions])
    compilerengines = [
        AutoReplacer(rule_set),
        TagRemover(),
        LocalOptimizer(3),
        AutoReplacer(rule_set),
        TagRemover(),
        LocalOptimizer(3), resource_counter
    ]

    # create a main compiler engine
    n = int(math.log(N, 2)) + 1

    if param == "latex":
        drawing_engine = CircuitDrawer()
        eng2 = MainEngine(drawing_engine)
        xN = initialisation_n(eng2, N, n + 1)
        xx = initialisation_n(eng2, x, n + 1)
        xb = initialisation_n(eng2, b, n + 1)
        [xc, aux] = initialisation(eng2, [1, 0])
        cMultModN_non_Dagger(eng2, a, xb, xx, xN, aux, xc)
        eng2.flush()
        Measure | aux
        Measure | xc
        All(Measure) | xx
        All(Measure) | xb
        All(Measure) | xN
        eng2.flush()
        print(drawing_engine.get_latex())
    else:
        if param == "count":
            eng = MainEngine(resource_counter)
        else:
            eng = MainEngine(Simulator(), compilerengines)
        xN = initialisation_n(eng, N, n + 1)
        xx = initialisation_n(eng, x, n + 1)
        xb = initialisation_n(eng, b, n + 1)
        [aux, xc] = initialisation(eng, [0, 1])
        cMultModN_non_Dagger(eng, a, xb, xx, xN, aux, xc, N)
        Measure | aux
        Measure | xc
        All(Measure) | xx
        All(Measure) | xb
        All(Measure) | xN
        eng.flush()
        if param == "count":
            return resource_counter

        measurements_b = [0] * n
        measurements_x = [0] * n
        measurements_N = [0] * n
        for k in range(n):
            measurements_b[k] = int(xb[k])
            measurements_N[k] = int(xN[k])
            measurements_x[k] = int(xx[k])

        mes_aux = int(aux[0])
        mes_c = int(aux[0])
        return [
            measurements_b,
            meas2int(measurements_b), (b + a * x) % N, measurements_N,
            measurements_x, mes_aux, mes_c,
            meas2int(measurements_b),
            meas2int(measurements_N),
            meas2int(measurements_x)
        ]
예제 #13
0
def run(a=4, N=7, x=2, param="count"):
    """
    |b> --> |b+(ax) mod N>
    nb of gate ~454*log2(N)
    :param a: a<N and must be invertible mod[N]
    :param N:
    :param x:
    :param param:
    :return:
    """
    # build compilation engine list
    resource_counter = ResourceCounter()
    rule_set = DecompositionRuleSet(
        modules=[projectq.libs.math, projectq.setups.decompositions])
    compilerengines = [
        AutoReplacer(rule_set),
        TagRemover(),
        LocalOptimizer(3),
        AutoReplacer(rule_set),
        TagRemover(),
        LocalOptimizer(3), resource_counter
    ]

    # create a main compiler engine
    a = a % N
    inv_a = mod_inv(a, N)
    b = 0
    n = int(math.log(N, 2)) + 1

    if param == "latex":
        drawing_engine = CircuitDrawer()
        eng2 = MainEngine(drawing_engine)
        xN = initialisation_n(eng2, N, n + 1)
        xx = initialisation_n(eng2, x, n + 1)
        xb = initialisation_n(eng2, b, n + 1)
        [xc, aux] = initialisation(eng2, [1, 0])
        gateUa(eng2, a, inv_a, xx, xb, xN, aux, xc, N)
        eng2.flush()
        Measure | aux
        Measure | xc
        All(Measure) | xx
        All(Measure) | xb
        All(Measure) | xN
        eng2.flush()
        print(drawing_engine.get_latex())
    else:
        if param == "count":
            eng = MainEngine(resource_counter)
        else:
            eng = MainEngine(Simulator(), compilerengines)
        xN = initialisation_n(eng, N, n + 1)
        xx = initialisation_n(eng, x, n + 1)
        xb = initialisation_n(eng, b, n + 1)
        [xc, aux] = initialisation(eng, [1, 0])
        gateUa(eng, a, inv_a, xx, xb, xN, aux, xc, N)
        Measure | aux
        Measure | xc
        All(Measure) | xx
        All(Measure) | xb
        All(Measure) | xN
        eng.flush()
        if param == "count":
            return resource_counter
        measurements_b = [0] * n
        measurements_x = [0] * n
        measurements_N = [0] * n
        for k in range(n):
            measurements_b[k] = int(xb[k])
            measurements_N[k] = int(xN[k])
            measurements_x[k] = int(xx[k])

        mes_aux = int(aux[0])
        mes_c = int(aux[0])

        assert int(xb[n]) == 0
        assert int(xN[n]) == 0
        assert int(xx[n]) == 0
        assert meas2int(measurements_b) == 0
        assert meas2int(measurements_N) == N
        assert mes_aux == 0

        return [(a * x) % N, meas2int(measurements_x), measurements_x, mes_c]
예제 #14
0
from projectq import MainEngine  # import the main compiler engine
from projectq.ops import C, X, H, Measure  # import the operations we want to perform (Hadamard and measurement)
from projectq.backends import CircuitDrawer

circuit_backend = CircuitDrawer()
eng = MainEngine(
    circuit_backend)  # create a default compiler (the back-end is a simulator)
qubit = eng.allocate_qubit()  # allocate a quantum register with 1 qubit
qureg = eng.allocate_qureg(5)

# how about a list of qubits?
lq = (qureg[0], qureg[1], qureg[3], qureg[4])

H | qubit  # apply a Hadamard gate
Measure | qubit  # measure the qubit
C(X, 3) | (qureg[0], qureg[1], qureg[2], qureg[3])
C(X, 3) | lq

eng.flush()  # flush all gates (and execute measurements)
print(
    "Measured {}".format(int(qubit))
)  # converting a qubit to int or bool gives access to the measurement result
print(circuit_backend.get_latex())
예제 #15
0
def zoo_profile():
    """Generate and display the zoo of quantum gates."""
    # create a main compiler engine with a drawing backend
    drawing_engine = CircuitDrawer()
    locations = {0: 1, 1: 2, 2: 0, 3: 3}
    drawing_engine.set_qubit_locations(locations)
    main_eng = MainEngine(drawing_engine)
    qureg = main_eng.allocate_qureg(4)

    # define a zoo of gates
    te_gate = TimeEvolution(0.5, 0.1 * QubitOperator('X0 Y2'))

    def add(x, y):
        return x, y + 1

    zoo = [
        (X, 3),
        (Y, 2),
        (Z, 0),
        (Rx(0.5), 2),
        (Ry(0.5), 1),
        (Rz(0.5), 1),
        (Ph(0.5), 0),
        (S, 3),
        (T, 2),
        (H, 1),
        (Toffoli, (0, 1, 2)),
        (Barrier, None),
        (Swap, (0, 3)),
        (SqrtSwap, (0, 1)),
        (get_inverse(SqrtSwap), (2, 3)),
        (SqrtX, 2),
        (C(get_inverse(SqrtX)), (0, 2)),
        (C(Ry(0.5)), (2, 3)),
        (CNOT, (2, 1)),
        (Entangle, None),
        (te_gate, None),
        (QFT, None),
        (Tensor(H), None),
        (BasicMathGate(add), (2, 3)),
        (All(Measure), None),
    ]

    # apply them
    for gate, pos in zoo:
        if pos is None:
            gate | qureg
        elif isinstance(pos, tuple):
            gate | tuple(qureg[i] for i in pos)
        else:
            gate | qureg[pos]

    main_eng.flush()

    # generate latex code to draw the circuit
    s = drawing_engine.get_latex()
    prefix = 'zoo'
    with open('{}.tex'.format(prefix), 'w') as f:
        f.write(s)

    # compile latex source code and open pdf file
    os.system('pdflatex {}.tex'.format(prefix))
    openfile('{}.pdf'.format(prefix))
예제 #16
0
from Bell_States_Generator import bell_state
from Quantum_Teleportation import quantum_teleportation
from projectq import MainEngine
from projectq.backends import CircuitDrawer
from projectq.ops import H,Rz
import os

drawer=CircuitDrawer()
eng=MainEngine(drawer)
qubit_psi=eng.allocate_qubit()
H|qubit_psi
Rz(1.32)|qubit_psi
quantum_teleportation(eng,qubit_psi)
eng.flush()

with open("./circuit_plot/quantum_teleportation.tex","w") as f:
    f.write(drawer.get_latex())
예제 #17
0
class DHAOracle:
    def __init__(self, delta, numBits, ancillaBit=None):
        self.C = C
        self.X = X
        self.H = H
        self.Barrier = Barrier
        
        self.delta = delta
        self.numBits = numBits
        self.delta_bin = np.binary_repr(delta, numBits)
        self.delta_bin = [int(i) for i in self.delta_bin]
        self.gatesList = []
        self.reverseGatesList = []
        
        self.circuit_drawer = CircuitDrawer()
        self.diag_eng = MainEngine(self.circuit_drawer)
        
        self.valreg = self.diag_eng.allocate_qureg(self.numBits)
        self.refreg = self.diag_eng.allocate_qureg(self.numBits)

        if (ancillaBit is None):
            self.ancilla = self.diag_eng.allocate_qureg(1)
        else:
            self.ancilla = ancillaBit

        # old qiskit ver
#        self.valreg = QuantumRegister(self.numBits, 'val')
#        self.refreg = QuantumRegister(self.numBits, 'reg')
#        self.qc = QuantumCircuit(self.valreg, self.refreg)
#        self.circdrawer = circuit_drawer(self.qc)

    def makeGates(self, delta_bin=None):
        if delta_bin is None:
            delta_bin = self.delta_bin
        
        idx = 0 # current bit
        cidx = 0 # current control bit
        prefix = [] # initialize with no prefixes
        
        while (idx<len(delta_bin)):
            # debug
            print (idx)
            
            # Condition 0. For each 0 at the start, place a simple CNOT.
            if delta_bin[idx] == 0:
                print('Condition 0')
                self.gatesList.append(tuple([self.valreg[prefix[i]] for i in range(len(prefix))]) + tuple([self.valreg[idx]]) + tuple([self.refreg[cidx]]))
                idx = idx+1 # move to next bit/next iteration
                cidx = cidx+1
                
            # Condition 1. All remaining bits are 1. E.g. 11111, 01111 etc.
            elif np.all(delta_bin[idx:]):
                print('Condition 1')
                self.gatesList.append(tuple([self.valreg[prefix[i]] for i in range(len(prefix))]) + tuple([self.valreg[i] for i in range(idx, len(delta_bin))]) + tuple([self.refreg[cidx]]))
                
                print('Exited at idx ' + str(idx)) # DEBUG
                
                idx = len(delta_bin) # end the loop, early stopping
            
            # Condition 2a. Current bit is 1, rest are 0. E.g. 01000 etc.
            elif np.all(np.logical_not(delta_bin[idx+1:])) and delta_bin[idx] == 1:
                print('Condition 2a')
                self.gatesList.append(tuple([self.valreg[prefix[i]] for i in range(len(prefix))]) + tuple([self.valreg[idx]]) + tuple([self.refreg[cidx]]))
                
                print('Exited at idx ' + str(idx)) # DEBUG
                
                idx = len(delta_bin) # early stopping
            
            # Condition 2b. Current bit is 1. End of sequence.
            elif (idx == len(delta_bin)-1) and delta_bin[idx] == 1:
                print('Condition 2b')
                self.gatesList.append(tuple([self.valreg[prefix[i]] for i in range(len(prefix))]) + tuple([self.valreg[idx]]) + tuple([self.refreg[cidx]]))
                
                print('Exited at idx ' + str(idx)) # DEBUG
                
                idx = len(delta_bin) # early stopping
                
            # Condition 3. Current bit is 1. All special cases failed.
            elif (delta_bin[idx] == 1):
                print('Condition 3')
                prefix.append(idx)
                idx = idx + 1
                # but we don't need to move cidx
                
            # Condition 4. Current bit is 0. All special cases failed.
            elif (delta_bin[idx] == 0):
                print('Condition 4')
                # attach all existing prefixes, and write a toffoli with a node at the 0
                self.gatesList.append(tuple([self.valreg[prefix[i]] for i in range(len(prefix))]) + tuple([self.valreg[idx]]) + tuple([self.refreg[cidx]]))
                idx = idx + 1
                
            else:
                print('Unknown conditions')

        # implement the gates
        for i in range(len(self.gatesList)):
            print(self.gatesList[i])
            
            # implement the gate
            self.C(X,len(self.gatesList[i])-1) | self.gatesList[i]
            
        # Barrier for neatness?
        self.Barrier | (self.valreg, self.refreg, self.ancilla)   
            
        # implement X gates on 0 bits
        for i in range(len(delta_bin)):
            if (delta_bin[i] == 0):
                self.X | self.refreg[i]
                
        
                
        # implement Hadamard on ancilla
        self.H | self.ancilla
            
        # implement centre Toffoli
        self.C(X,len(delta_bin)) | (self.refreg, self.ancilla)
        
        # == and then implement all the reverses ==
        # implement Hadamard on ancilla
        self.H | self.ancilla
        
        
        
        # implement X gates on 0 bits
        for i in range(len(delta_bin)):
            if (delta_bin[i] == 0):
                self.X | self.refreg[i]
                
        # Barrier for neatness?
        self.Barrier | (self.valreg, self.refreg, self.ancilla)
        
        # implement the gates
        for i in range(len(self.gatesList)-1, -1, -1):
            print(self.gatesList[i])
            
            # implement the gate
            self.C(X,len(self.gatesList[i])-1) | self.gatesList[i]
        
        
            
        # flush gates
        self.diag_eng.flush()
        
    def showGates(self, adjustBarrier=False):
        text2print = self.circuit_drawer.get_latex()
        
        if adjustBarrier:
            # fix the barrier text to be vertical
            text2print = text2print.replace("Barrier", "\\rotatebox{90}{Barrier}")
            
        print('\n')
        print(text2print)
        
        return text2print