%run init.ipynb

from qiskit import *
nshots = 8192
IBMQ.load_account()
provider = IBMQ.get_provider(hub = 'ibm-q-research-2', group = 'federal-uni-sant-1', project = 'main')
device = provider.get_backend('ibm_nairobi')
simulator = Aer.get_backend('qasm_simulator')
from qiskit.tools.monitor import job_monitor, backend_overview, backend_monitor
from qiskit.tools.visualization import plot_histogram

q0 = QuantumRegister(1); q1 = QuantumRegister(1); q2 = QuantumRegister(1); q3 = QuantumRegister(1)
c0 = ClassicalRegister(1); c1 = ClassicalRegister(1); c2 = ClassicalRegister(1); c3 = ClassicalRegister(1)
qc = QuantumCircuit(q0,q1,q2,q3,c0,c1,c2,c3)
# q0 e q1 estao com Alice, q2 com Charlies e q3 com Bob
qc.h(q1); qc.cx(q1,q2); qc.cx(q2,q3) # prepara o estado GHZ
qc.barrier()
#qc.sdg(q0); qc.h(q0) # prepara o estado a ser teletransportado (y+)
# prepara o estado |0>
qc.barrier()
qc.cx(q0,q1); qc.h(q0); qc.measure(q0,c0); qc.measure(q1,c1) # Medida de Alice na base de Bell
qc.h(q2); qc.measure(q2,c2) # medida de Charlie na base +,-
qc.barrier()
qc.z(q3).c_if(c0, 1) # acao de Bob condicionada no 1º cbit enviado por Alice
qc.x(q3).c_if(c1, 1) # acao de Bob condicionada no 2º cbit enviado por Alice
qc.z(q3).c_if(c2, 1) # acao de Bob condicionada no cbit enviado por Charlie
qc.barrier()
#qc.sdg(q3); qc.h(q3); qc.measure(q3,c3) # passa da base circular pra computacional
qc.measure(q3,c3) # mede na base computacional
qc.draw(output='mpl')

jobS = execute(qc, backend = simulator, shots = nshots)

plot_histogram(jobS.result().get_counts(qc))

jobE = execute(qc, backend = device, shots = nshots)
job_monitor(jobE)

tqc = transpile(qc, device)
jobE = device.run(tqc)
job_monitor(jobE)

plot_histogram([jobS.result().get_counts(0), jobE.result().get_counts(0)], 
               bar_labels = False, legend = ['sim', 'exp'])



