예제 #1
0
    def calculate_expectation(all_qubits_in_circuit, cirq_circuit, operator_circuits):
        """
        Computes the expectation value according to the formula <psi|O|psi> where O is a Pauli operator
        represented by the state generated from `operator_circuits` for which the expectation is to 
        be calculated over psi where psi is the state generated from `cirq_circuit`

        Parameters
        ---------
        all_qubits_in_circuit   :   (list) list of all qubits in `cirq_circuit`
        cirq_circuit            :   (Circuit) represents the paramterized circuit for the ansatz 
        operator_circuits       :   (list of Circuit objects) represents a circuit generated by 
                                    applying a Pauli operator on a qubit.

        Returns
        -------
        result_overlaps         :   (list) represents the expectation values of each Pauli operator in
                                    `operator_circuits` given the state represented by `cirq_circuit`.
        """
        simulator = Simulator()
        result_overlaps = []
        simulation_result = simulator.simulate(cirq_circuit)
        cirq_circuit_amplitudes = simulation_result.final_state
        for op_circuit in operator_circuits:
            qubits = all_qubits_in_circuit[:]
            if(len(op_circuit._moments) == 0):
                result_overlaps.append(
                    np.conj(cirq_circuit_amplitudes).T.dot(cirq_circuit_amplitudes))
            else:
                if(len(all_qubits_in_circuit) != len(op_circuit.all_qubits())):
                    op_circuit = VQE.modify_operator_circuit(
                        qubits, op_circuit)
                unitary_matrix_op = unitary(op_circuit)
                result_overlaps.append(np.conj(cirq_circuit_amplitudes).T.dot(
                    unitary_matrix_op).dot(cirq_circuit_amplitudes))
        return result_overlaps
예제 #2
0
def qubit_wavefunction_from_vacuum(ops: 'QubitOperator',
                                   qubits: List['LineQubit']) -> numpy.ndarray:
    """Generate a cirq wavefunction from the vacuum given qubit operators and a
    set of qubits that this wavefunction will be represented on

    Args:
        ops (QubitOperators) - a sum of qubit operations with coefficients \
            scheduling the creation of the qubit wavefunction

        qubits (Qid) - the qubits of the quantum computer

    Returns:
        final_state (numpy.array(dtype=numpy.complex64)) - the fully projected \
            wavefunction in the cirq representation
    """
    nqubits = len(qubits)
    vacuum = init_qubit_vacuum(nqubits)
    final_state = numpy.zeros(2**nqubits, dtype=numpy.complex128)
    qpu = Simulator(dtype=numpy.complex128)
    for term in ops.terms:
        circuit = qubit_ops_to_circuit(term, qubits)
        state = vacuum.copy()
        result = qpu.simulate(circuit, qubit_order=qubits, initial_state=state)
        final_state += result.final_state_vector * ops.terms[term]
    return final_state
예제 #3
0
    def test_simulate(self):
        compressed_status = [True, False]

        rad = 0.75
        pauli_word = PauliWord("XZYX")

        for initial_state in range(2**len(pauli_word)):
            results = []
            for is_compressed in compressed_status:
                simulator = Simulator()
                circuit = Circuit()
                qubits = [GridQubit(i, j) for i in range(3) for j in range(3)]
                gate = PauliWordExpGate(rad, pauli_word)
                operation = gate.on(*qubits[0:len(gate.pauli_word)])

                if is_compressed:
                    circuit.append(operation)
                else:
                    circuit.append(cirq.decompose(operation))

                result = simulator.simulate(
                    circuit, initial_state=initial_state
                )  # type: cirq.SimulationTrialResult
                # print(circuit)
                print(result.final_state)
                # print(cirq.unitary(circuit_compressed))

                results.append(result)

            self.assertTrue(
                np.allclose(results[0].final_state,
                            results[1].final_state,
                            rtol=1e-4,
                            atol=1e-5))
예제 #4
0
def qubit_projection(ops: QubitOperator, qubits: List[LineQubit],
                     state: numpy.ndarray, coeff: numpy.ndarray) -> None:
    """Find the projection of each set of qubit operators on a
    wavefunction.

    Args:
        ops (qubit gates) - A sum of qubit operations which represent the \
            full ci wavefunction in the qubit basis.

        qubits (Qid) - The qubits of a quantum computer.

        state (numpy.array(dtype=numpy.complex64)) - a cirq wavefunction that \
            is being projected

        coeff (numpy.array(dtype=numpy.complex64)) - a coefficient array that \
            will store the result of the projection.
    """
    qpu = Simulator(dtype=numpy.complex128)
    for indx, cluster in enumerate(ops.terms):
        circuit = qubit_ops_to_circuit(cluster, qubits)
        work_state = state.copy()
        result = qpu.simulate(circuit,
                              qubit_order=qubits,
                              initial_state=work_state)
        coeff[indx] = result.final_state_vector[0]
예제 #5
0
def main():
    qft_circuit = generate_2x2_grid()
    print("circuit:")
    print(qft_circuit)
    sim = Simulator()
    res = sim.simulate(qft_circuit)
    print('\nfinal state:')
    print(np.around(res.final_state, 3))
예제 #6
0
    def expectation(all_qubits_in_circuit, cirq_circuit, cirq_pauli_sum):
        """
        Computes the expectation value of `cirq_pauli_sum` over the distribution
        generated from `cirq_circuit`.
        The expectation value is calculated by calculating <psi|O|psi>

        Parameters
        ---------
        all_qubits_in_circuit   :   (list) list of all qubits in `cirq_circuit`
        cirq_circuit            :   (Circuit) represents the paramterized circuit for the ansatz 
        cirq_pauli_sum          :   (CirqPauliSum or ndarray) CirqPauliSum representing the Pauli
                                    operator for which the expectation value is to be calculated
                                    or a numpy matrix representing the Hamiltonian 
                                    tensored up to the appropriate size.

        Returns
        -------
        expectation.real        :   (float) represents the expectation value of cirq_pauli_sum 
                                    given the distribution generated from `cirq_circuit`.
        """
        if isinstance(cirq_pauli_sum, np.ndarray):
            simulator = Simulator()
            simulation_result = simulator.simulate(cirq_circuit)
            cirq_circuit_amplitudes = simulation_result.final_state
            cirq_circuit_amplitudes = np.reshape(
                cirq_circuit_amplitudes, (-1, 1))
            average_exp = np.conj(cirq_circuit_amplitudes).T.dot(
                cirq_pauli_sum.dot(cirq_circuit_amplitudes)).real
            return average_exp
        else:
            operator_circuits = []
            operator_coeffs = []
            for p_string in cirq_pauli_sum.pauli_strings:
                op_circuit = Circuit()
                for qubit, pauli in p_string.items():
                    gate = pauli
                    op_circuit.append(
                        [gate(qubit)], strategy=InsertStrategy.EARLIEST)
                operator_circuits.append(op_circuit)
                operator_coeffs.append(p_string.coefficient)
            result_overlaps = VQE.calculate_expectation(
                all_qubits_in_circuit, cirq_circuit, operator_circuits)
            result_overlaps = list(result_overlaps)
            expectation = sum(
                list(map(lambda x: x[0]*x[1], zip(result_overlaps, operator_coeffs))))
            return expectation.real
예제 #7
0
    def test_symbolic_gate(self):
        sym_circuit = Circuit()
        qubits = [GridQubit(i, j) for i in range(3) for j in range(3)]

        gate = GlobalPhaseGate(sympy.Symbol("rad"))
        sym_circuit.append(gate.on(qubits[0]))

        print(sym_circuit)

        rad_list = np.random.rand(10) * 5
        for rad in rad_list:
            simulator = Simulator()
            circuit = cirq.resolve_parameters(sym_circuit, {"rad": rad})
            result = simulator.simulate(circuit)
            self.assertTrue(
                np.allclose(result.final_state,
                            np.exp(1.0j * rad * np.pi) * np.array([1, 0])))
예제 #8
0
def solve_maxcut(qubit_pairs, steps=1):
    """
        Solves the maxcut problem on the input graph

        Parameters
        ----------
        qubit_pairs :       (list of GridQubit pairs) represents the graph on which maxcut is to be solved
        steps       :       (int) number of mixing and cost function steps to use. Default=1 
        """
    cirqMaxCutSolver = CirqMaxCutSolver(qubit_pairs=qubit_pairs, steps=steps)
    qaoa_instance = cirqMaxCutSolver.solve_max_cut_qaoa()
    betas, gammas = qaoa_instance.get_angles()
    t = np.hstack((betas, gammas))
    param_circuit = qaoa_instance.get_parameterized_circuit()
    circuit = param_circuit(t)
    sim = Simulator()
    result = sim.simulate(circuit)
    display_maxcut_results(qaoa_instance, result)
q0 = cirq.GridQubit(0, 0)
q1 = cirq.GridQubit(1, 0)


def basic_circuit(meas=True):
    sqrt_x = cirq.X**0.5
    yield sqrt_x(q0), sqrt_x(q1)
    yield cirq.CZ(q0, q1)
    yield sqrt_x(q0), sqrt_x(q1)
    if meas:
        yield cirq.measure(q0, key='q0'), cirq.measure(q1, key='q1')


circuit = cirq.Circuit()
circuit.append(basic_circuit(False))

print(circuit)

result = simulator.simulate(circuit, qubit_order=[q0, q1])

print(np.around(result.final_state, 3))

# Circuit :
# (0, 0): ───X^0.5───@───X^0.5───
#                    │
# (1, 0): ───X^0.5───@───X^0.5───
#

# Result
# [0.5+0.j  0. +0.5j 0. +0.5j 0.5+0.j ]
import cirq
from cirq import Simulator

q_stay = cirq.NamedQubit('q_stay')
q_flip = cirq.NamedQubit('q_flip')
c = cirq.Circuit(cirq.X(q_flip))

simulator = Simulator()

# first qubit in order flipped
result = simulator.simulate(c, qubit_order=[q_flip, q_stay])
print(abs(result.final_state).round(3))
# prints
# [0. 0. 1. 0.]

# second qubit in order flipped
result = simulator.simulate(c, qubit_order=[q_stay, q_flip])
print(abs(result.final_state).round(3))
# prints
# [0. 1. 0. 0.]
n_phiReg.extend([GridQubit(N + n_i + 1, j) for j in range(L)])
w_phiReg.extend([GridQubit(N + n_i + 1, j) for j in range(L, 2 * L - 1)])
n_aReg.extend([GridQubit(N + n_i + 2, j) for j in range(L)])
w_aReg.extend([GridQubit(N + n_i + 2, j) for j in range(L, 2 * L - 1)])
n_bReg.extend([GridQubit(N + n_i + 3, j) for j in range(L)])
w_bReg.extend([GridQubit(N + n_i + 3, j) for j in range(L, 2 * L - 1)])

timeStepList, P_aList, P_bList, P_phiList, Delta_aList, Delta_bList, Delta_phiList = [], [], [], [], [], [], []
cc.populateParameterLists(N, timeStepList, P_aList, P_bList, P_phiList,
                          Delta_aList, Delta_bList, Delta_phiList, g_a, g_b,
                          eps)

cc.U_h(circuit, l, n_i, m, n_phiReg, w_phiReg, n_aReg, w_aReg, n_bReg, w_bReg,
       wReg, eReg, pReg, hReg, w_hReg, P_phiList[0], P_aList[0], P_bList[0])

result = simulator.simulate(circuit)

print(result.final_state_vector)

print(circuit)

pReg2, hReg2, w_hReg2, eReg2, wReg2, n_aReg2, w_aReg2, n_bReg2, w_bReg2, n_phiReg2, w_phiReg2 = qcc.allocateQubits(
    N, n_i, L)

# circuit = QuantumCircuit(pReg, hReg, w_hReg, eReg, wReg, n_aReg, w_aReg, n_bReg, w_bReg, n_phiReg, w_phiReg)
circuit2 = QuantumCircuit(pReg2, hReg2, w_hReg2, eReg2, wReg2, n_aReg2,
                          w_aReg2, n_bReg2, w_bReg2, n_phiReg2)

simulator2 = Aer.get_backend('statevector_simulator')

timeStepList2, P_aList2, P_bList2, P_phiList2, Delta_aList2, Delta_bList2, Delta_phiList2 = [], [], [], [], [], [], []
예제 #12
0
def run(formula_original, truth_table):
	atomics = 0
	operations = 0
	negations = 0
	repetitions = []
	formula_original = formula_original.replace(' ', '')
	formula_original = formula_original.replace('∨', '|')
	formula_original = formula_original.replace('→', '>')
	formula_original = formula_original.replace('∧', '&')
	formula_original = formula_original.replace('¬', '~')
	formula = list(formula_original)
	table = list(truth_table)
	print(formula)

	#tranforma x > y em ~x | y #ERRO ESTÁ AQUI. A associação é a esquerda, mas o caso (x | y) -> z está vendo traduzido
	#como x | ~y | z, quando na verdade deve ser ~(x | y) | z
	# O(n)

	"""
	for i in range(len(formula)):
		if formula[i] == '>':
			formula[i] = '|'
			formula.insert(i - 1, '~')
	"""
	print(formula)
	parenteses = 0

	# lê a formula, contando cada coisa
	# O(n)
	for element in formula:
		if element == '~':
			#lidando apenas com a negação de clausulas atomicas. Qualquer negação maior devem ser aplicadas as De Morgan Laws
			negations = negations + 1
		elif element == '|' or element == '&' or element == '>': #aqui deve entrar qualquer uma das operações
   			operations = operations + 1
		elif element == '(' or element == ')':
			parenteses = parenteses + 1
		else:
   			atomics = atomics + 1
   			repetitions.append(element)

	print("Atomicos: ", end = '')
	print(atomics)
	print("operations: ", end = '')
	print(operations)
	
	#print(repetitions)
   	
	full_size = negations + operations + atomics + parenteses
	size = operations + atomics + parenteses
	# cria o numero de qubits adequado
	qubits = cirq.LineQubit.range(size)
	circuit = cirq.Circuit()
	size2 = len(formula)
	#print(len(formula))
	#print(full_size)
	if full_size != size2:
		print("Erro nos tamanhos!")
		exit()

	


	# entrelaça os qubits necessários
	# ignora as negations, que serão lidadas com mais para frente
	uniques = 0
	formula_use = remove_values(formula, '~')
	#O(n), maximo de ligações é N
	for i in range(size):
		if not str(formula_use[i]).isalnum():
			#print(formula_use[i])
			continue
		uniques = uniques + 1
		circuit.append(cirq.H(qubits[i]))
		for j in range(i + 1, size):
			if (formula_use[i] == formula_use[j]):
				circuit.append([cirq.CNOT(qubits[i], qubits[j])])
				formula_use[j] = "_"
		formula_use[i] = "_" 

	#Cuida das negations
	#O(n)
	neg_count = 0
	for i in range(full_size):
		if formula[i] == '~':
			circuit.append(cirq.X(qubits[i - neg_count]))
			neg_count = neg_count + 1
	indexator = list(range(size))

	#faz as operações lógicas
	#associação a esquerda, não aceita parênteses por enquanto
	print(formula_use)
	print(formula)

	#passada inicial, lidando com os parenteses:
	print(indexator)
	print("ENTRANDO -------------")

	has_parenteses = 1
	i = 0
	while len(indexator) > 1 and has_parenteses == 1:
		has_parenteses = 0
		for i in range(len(indexator)):
			if formula_use[indexator[i]] == '(': #achou o abre parenteses
				print(" ABRIU -------------")
				has_parenteses = 1
				start = i
				while formula_use[indexator[i]]  != ')': #procura o fecha parênteses
					i = i + 1
					if formula_use[indexator[i]] == '(':# achou outro abre parênteses, atualiza o start
						start = i	
				print("FECHOU ---------")			
				#quando saiu do while, está no primeiro ')' - assumindo que a afirmação está bem formada (numero equilibrado de parenteses)
				#destruir os parenteses antes
				internal_count = i - start - 1
				print(indexator)
				del indexator[start]
				del indexator[i - 1]
				print(indexator)
				create_circuit(formula_use, circuit, qubits, indexator, start, start + internal_count)
				print("CHECK----------")
				print(i)
				print(indexator)
				break
		#if i >= len(indexator):
		#	i = 0
	print("SAINDO ------------------------")
	print(formula_use)
	print(indexator)
	create_circuit(formula_use, circuit, qubits, indexator, 0, len(indexator) - 1)

	print(indexator)

	print(circuit)
	simulator = Simulator()	
	result = simulator.simulate(circuit, initial_state=000000000000000)
	print(result.dirac_notation())
	string_result = str(result.dirac_notation())
	original_ones = 0
	original_zeros = 0
	for i in range(len(table)):
		if table[i] == 0:
			original_zeros = original_zeros + 1
		else:
			original_ones = original_ones + 1
	ones = 0
	zeros = 0
	temp_parenteses = 0
	for i in range(indexator[0]):
		if formula_use[i] == ')' or formula_use[i] == '(':
			temp_parenteses = temp_parenteses + 1
	for i in range(len(string_result)):
		if string_result[i] == "|":
			if int(string_result[i + indexator[0] + 1 - temp_parenteses]) == 0:
				zeros = zeros + 1
			else:
				ones = ones + 1

	print("Truth Table Ones/Zeros:", end = ' ')
	print(original_ones, end = '/')
	print(original_zeros)
	print("Circuit Result:")
	print("Ones:", end = '')
	print(ones)
	print("Zeros:", end='')
	print(zeros)
예제 #13
0
# cooling
if not cooling_out_exists:
    print('\nRunning cooling simulation')
    stopwatch = time.time()

    norm_samples = []
    energy_samples = []
    gsf_samples = []
    for _ in range(n_samples):
        # initialize random computational-basis system state (this emulates the
        # maximally-mixed system state) tensored with fridge |0>
        init_state = np.zeros(2**(L + 1), dtype=np.complex64)
        init_state[np.random.randint(L)] = 1

        res = simulator.simulate(
            circuit,
            initial_state=init_state,
            qubit_order=[*system.get_qubits(), qdccirq.FRIDGE])
        final_state = res.final_state[::2]  # discard fridge

        # Compute the norm to normalize sampled results:
        #    The numerical error produces a non-normalized final state.
        #    This seems to be the dominant error in the final result.
        #    To keep this under check, we store the resulting state norms.
        norm = np.sqrt(np.sum(np.abs(final_state)**2))
        norm_samples.append(
            np.float64(norm)
        )  # conversion to np.float64 needed for compatibility with json.
        energy_samples.append(system.energy_expval(final_state) / norm**2)
        gsf_samples.append(system.ground_space_fidelity(final_state) / norm**2)

    out_dict = dict(L=L,
예제 #14
0
#monte carlo noise
q = cirq.NamedQubit('a')
circuit = cirq.Circuit.from_ops(cirq.bit_flip(p=0.2)(q),
                                cirq.measure(q))  #PauliXGate
simq = cirq.Simulator()
result = simq.run(circuit, repetitions=100)
print(result.histogram(key='a'))
"""Paramatarized values for setting up Studies"""
import sympy
rot_w_gate = cirq.X**sympy.Symbol('x')
circuit = cirq.Circuit()
circuit.append([rot_w_gate(q0), rot_w_gate(q1)])
for y in range(5):
    resolver = cirq.ParamResolver({'x': y / 4.0})
    result = simq.simulate(circuit, resolver)
    print(np.round(result.final_state, 2))

resolvers = [cirq.ParamResolver({'x': y / 2.0}) for y in range(3)]
circuit = cirq.Circuit()
circuit.append([rot_w_gate(q0), rot_w_gate(q1)])
circuit.append([cirq.measure(q0, key='q0'), cirq.measure(q1, key='q1')])
results = simq.run_sweep(program=circuit, params=resolvers, repetitions=2)
for result in results:
    print(result)

#The mixed state simulator """__magic__"""

q = cirq.NamedQubit('a')
circuit = cirq.Circuit.from_ops(cirq.H(q),
                                cirq.amplitude_damp(0.2)(q), cirq.measure(q))
예제 #15
0
import tensorflow as tf
import tensorflow_quantum as tfq

import cirq
from cirq.ops import CCX
from cirq import Simulator
import sympy
import numpy as np

# visualization tools
import matplotlib.pyplot as plt
from cirq.contrib.svg import SVGCircuit

simulator = Simulator()
q0 = cirq.GridQubit(0, 0)
q1 = cirq.GridQubit(1, 0)
q2 = cirq.GridQubit(2, 0)
q3 = cirq.GridQubit(3, 0)
rot_w_gate = cirq.X**sympy.Symbol('x')
circuit = cirq.Circuit()
circuit.append([rot_w_gate(q0), rot_w_gate(q1)])
for y in range(5):
    resolver = cirq.ParamResolver({'x': y / 4.0})
    result = simulator.simulate(circuit, resolver)
    print(np.round(result.final_state, 2))
예제 #16
0
            'o': 1 / 5,
            'u': 1 / 5,
        }, 8)

    print(uniform_vowel)
    vowel_aog = AOG(uniform_vowel)

    vowel_dist = get_dist(Simulator(), vowel_aog.as_circuit(), 8)
    print(vowel_dist.print_strs())

    print(vowel_aog.pprint())
    quantum_vowel = vowel_aog.as_circuit()
    print(quantum_vowel)
    exit(0)

    vowel_sim = Simulator()
    vowel_res = vowel_sim.simulate(quantum_vowel)
    print(vowel_res)

    exit(0)

    dist = {0b0011: 1 / 2, 0b1011: 1 / 4, 0b0101: 1 / 8, 0b1110: 1 / 8}
    d = Distribution(dist, 4)
    aog = AOG(d)
    aog_circuit, _, _ = aog.to_circuit()
    print(aog_circuit)

    simulator = Simulator()
    result = simulator.simulate(aog_circuit)
    print(result)
예제 #17
0
def run(formula_original, truth_table = ""):


	# Troca simbolos logicos comuns pelos equivalentes esperados
	formula_original = formula_original.replace(' ', '')
	formula_original = formula_original.replace('∨', '|')
	formula_original = formula_original.replace('→', '>')
	formula_original = formula_original.replace('∧', '&')
	formula_original = formula_original.replace('¬', '~')
	formula = list(formula_original)
	table = list(truth_table)

	parenteses = 0
	atomics = 0
	operations = 0
	negations = 0

	# lê a formula, contando cada elemento
	# O(n)
	for element in formula:
		if element == '~':
			negations = negations + 1
		elif element == '|' or element == '&' or element == '>': #aqui deve entrar qualquer uma das operações
   			operations = operations + 1
		elif element == '(' or element == ')':
			parenteses = parenteses + 1
		else:
   			atomics = atomics + 1
	
   	
	full_size = negations + operations + atomics + parenteses
	size = operations + atomics + parenteses

	# cria o numero de qubits adequado e o circuito
	qubits = cirq.LineQubit.range(size)
	circuit = cirq.Circuit()

	size2 = len(formula)

	# checa se há alguma inconsistência na contagem
	if full_size != size2:
		print("Erro nos tamanhos")
		exit()


	# entrelaça os qubits necessários
	# ignora as negações, que serão lidadas com mais para frente
	formula_use = remove_values(formula, '~')
	#O(n), maximo de ligações é n
	for i in range(size):
		if not str(formula_use[i]).isalnum(): # se não for alfanumérico, ignora
			continue
		circuit.append(cirq.H(qubits[i])) # aplica o Hadamard no primeiro qubit encontrado para cada clausula atomica 
		for j in range(i + 1, size): # procura no resto da formula outras instâncias da clausula atomica
			if (formula_use[i] == formula_use[j]):
				circuit.append([cirq.CNOT(qubits[i], qubits[j])]) # entrelaça as que encontrar com a primeira
				formula_use[j] = "_"
		formula_use[i] = "_" 

	# verifica as clausulas que estão negadas, e faz o bit flip
	#O(n)
	neg_count = 0
	for i in range(full_size):
		if formula[i] == '~':
			if formula[i + 1] == '(': #negações aparecem antes de ( ou antes de uma clausula atomica
				formula_use[i - neg_count] = '[' #troca a representação do parenteses negado
				neg_count = neg_count + 1 
			else:
				circuit.append(cirq.X(qubits[i - neg_count]))
				neg_count = neg_count + 1


	# cria uma lista de inteiros para servir de referência a quais qubits ainda estão com informação importante
	indexator = list(range(size))

	# procura os parenteses mais internos, e chama a função de criar circuito

	has_parenteses = 1
	i = 0
	print(formula_use)
	#O(n^2)
	while len(indexator) > 1 and has_parenteses == 1: # quando o tamanho de indexador é 1, o algoritmo terminou, e o resultado está no qubit com o indice restante
		has_parenteses = 0
		for i in range(len(indexator)):
			negated = 0
			if formula_use[indexator[i]] == '(' or formula_use[indexator[i]] == '[': #achou o abre parenteses
				if formula_use[indexator[i]] == '[':
					negated = 1
				has_parenteses = 1
				start = i
				while formula_use[indexator[i]]  != ')': #procura o fecha parênteses
					i = i + 1
					if formula_use[indexator[i]] == '(' or formula_use[indexator[i]] == '[':# achou outro abre parênteses, atualiza o start
						start = i
						negated = 0
						if formula_use[indexator[i]] == '[':
							negated = 1	
				#quando saiu do while, está no primeiro ')' - assumindo que a afirmação está bem formada (numero equilibrado de parenteses)
				internal_count = i - start - 1
				#remove os parenteses
				del indexator[start]
				del indexator[i - 1]
				create_circuit(formula_use, circuit, qubits, indexator, start, start + internal_count, negated)
				break

	#chama a funçao uma ultima vez, quando nao houver mais nenhum parenteses
	create_circuit(formula_use, circuit, qubits, indexator, 0, len(indexator) - 1, 0)

	# a resposta esta no qubit[indexador[0]]
	print(indexator)
	print(circuit)

	simulator = Simulator()	
	result = simulator.simulate(circuit, initial_state=000000000000000)
	print(result.dirac_notation())
	string_result = str(result.dirac_notation())

	# conta os 0s e 1s do resultado da simulação e compara com os da truth table
	original_ones = 0
	original_zeros = 0
	for i in range(len(table)):
		if int(table[i]) == 0:
			original_zeros = original_zeros + 1
		elif int(table[i]) == 1:
			original_ones = original_ones + 1
	ones = 0
	zeros = 0
	temp_parenteses = 0
	for i in range(indexator[0]):
		if formula_use[i] == ')' or formula_use[i] == '(' or formula_use[i] == '[':
			temp_parenteses = temp_parenteses + 1
	for i in range(len(string_result)):
		if string_result[i] == "|":
			if int(string_result[i + indexator[0] + 1 - temp_parenteses]) == 0:
				zeros = zeros + 1
			else:
				ones = ones + 1

	print("Truth Table Ones/Zeros:", end = ' ')
	print(original_ones, end = '/')
	print(original_zeros)
	print("Circuit Result:")
	print("Ones:", end = '')
	print(ones)
	print("Zeros:", end='')
	print(zeros)