%matplotlib inline

from qiskit import *
from qiskit.visualization import *
from qiskit.tools.monitor import *
from qiskit.aqua import *
from qiskit.aqua.components.oracles import *
from qiskit.aqua.algorithms import *

oracle = TruthTableOracle("0101")
oracle.construct_circuit().draw(output='mpl')

dj = DeutschJozsa(oracle)
dj.construct_circuit(measurement=True).draw(output='mpl')

backend = Aer.get_backend('qasm_simulator')
quantum_instance = QuantumInstance(backend)
result = dj.run(quantum_instance)
print(result)

oracle2 = TruthTableOracle('00000000')
dj2 = DeutschJozsa(oracle2)
result = dj2.run(quantum_instance)
print("The function is",result['result'])

backend = Aer.get_backend('qasm_simulator')
oracle3 = TruthTableOracle('0001')
g = Grover(oracle3, iterations=1)

result = g.run(quantum_instance)
print(result)

expression = '(x | y) & (~y | z) & (~x | ~z | w) & (~x | y | z | ~w)'
oracle4 = LogicalExpressionOracle(expression)
g2 = Grover(oracle4, iterations = 3)
result = g2.run(quantum_instance)
print(result)

backend = Aer.get_backend('qasm_simulator')
expression2 = '(x & y & z & w) | (~x & ~y & ~z & ~w)'
#expression2 = '(x & y) | (~x & ~y)'
oracle5 = LogicalExpressionOracle(expression2, optimization = True)
g3 = Grover(oracle5, incremental = True)
result = g3.run(quantum_instance)
print(result)