#Extending Grover's Algorithm to cover the Satisfiability Problem
#Satifiability Problem Ex
#Ordering food
# Satisfiability Constraints
# Open, Nearby, Deliver, Thai Food

#For a reasonable # of resturants, classical comp is fine
#However for big datasets, we can use a quantum speedup
#recast problem into search problem

#Grover's Dinner Party
#Invite as many friends over as possible while everyone gets along
#Grover's search can be used for boolean satisfiability problems
#((Olivia & Abe) | (Jin & Amira)) & ~(Abe & Amira)
#((A & B) | (C & D)) & ~(A & D)

from qiskit import BasicAer
#Deprecation of Aqua
#from qiskit.aqua.algorithms import Grover
#from qiskit.aqua.components.oracles import LogicalExpressionOracle
from qiskit.circuit.library import PhaseOracle
from qiskit.algorithms import Grover, AmplificationProblem
from qiskit.utils import QuantumInstance
from qiskit.tools.visualization import plot_histogram

log_expr = '((Olivia & Abe) | (Jin & Amira)) & ~(Abe & Amira)'
oracle = PhaseOracle(log_expr)
problem = AmplificationProblem(oracle=oracle)

backend = BasicAer.get_backend('qasm_simulator')
qinstance = QuantumInstance(backend, shots = 1000)
grover = Grover(quantum_instance = qinstance)
#algorithm = Grover(oracle)


result = grover.amplify(problem)
print('Top measurement:', result.top_measurement)

