Los oráculos son operaciones abstractas que generalmente son definidas utilizando la notación de funciones binarias clásicas:
f:{0,1}n→{0,1}m
Los oráculos actúan como cajas negras y abstraen su implementación, que varía segun el contexto. Notar que si no se pueden encontrar circuitos reales (con puertas) para representar la funcionalidad el oráculo carece de uso práctico.
Los oráculos se utilizan, por ejemplo, en los algoritmos Deutsch-Jozsa y Grover. En el primero se usa para abstraer la función a determinar si es constante o balanceada, y en el segundo caso se utiliza para abstraer el suscinto sobre el cual buscar.
Estos se definen de forma general de la siguiente manera:
Uf(∣x⟩⊗∣y⟩)=∣x⟩⊗∣y⊕f(x)⟩
Donde \(x\) es la entrada e \(y\) un registro que se utilizará como salida. La razon de la creación de un nuevo registro para salida es para permitir que la operación sea reversible, es decir que a partir de la salida se pueda saber cuál fue la entrada.
Vale por construcción que \(U_f=U_f^\dag\), permitiendo que para obtener el valor de entrada solo se deba aplicar nuevamente la operación.
En (1) se aplica normalmente el oráculo, en (2) se vuelve a aplicar el oráculo al resultado de (1), y en (3) se obtiene la misma entrada de (1). Por lo tanto \(U_f=U_f^\dag\).
Los oráculos son utilizados para verificar el resultado de una entrada, o para poder distinguir (aplicando una fase) aquellos valores que pertenecen a la solución del problema. Utilizando la definicion matemática de oráculo, se puede verificar que la entrada x sea una solución de f reemplazando y con "0" de la siguiente manera:
Uf(∣x⟩⊗∣0⟩)==∣x⟩⊗∣0⊕f(x)⟩∣x⟩⊗∣f(x)⟩
Al leer el segundo cubit se puede verificar si x es solución o no de f.
De forma análoga, si se reemplaza y con "1" se obtiene el complemento de f(x) en el segundo cubit:
Se suele utilizar el valor "−" en lugar de y para distinguir aquellos valores que pertenecen a la solución del problema, con la precondición m=1, es decir que haya un solo bit de solución:
Este oráculo es conocido como oráculo de fase. El último cubit no cambia nunca por lo que ciertas bibliografías simplifican enunciándolo de la siguiente manera:
Pf∣x⟩=(−1)f(x)∣x⟩
Detalles adicionales
La siguiente fórmula funciona para todas las combinaciones de bits b,c∈Σ.
∣b⊕c⟩=Xc∣b⟩
Esto puede comprobarse verificando para los dos posibles valores c=0 y c=1:
∣b⊕0⟩=∣b⟩=1∣b⟩=X0∣b⟩∣b⊕1⟩=¬∣b⟩=X∣b⟩=X1∣b⟩
Utilizando dicha fórmula sobre el oráculo de fase,
Uf(∣b⟩∣a⟩)=∣b⊕f(a)⟩∣a⟩=(Xf(a)∣b⟩)∣a⟩
para toda combinación de bits a,b∈Σ. Dado que la fórmula se mantiene verdadera para b=0 y b=1, por linealidad se llega a que
Uf(∣ψ⟩∣a⟩)=(Xf(a)∣ψ⟩)∣a⟩
para todo estado posible ∣ψ⟩, y en consecuencia
Uf(∣−⟩∣a⟩)=(Xf(a)∣−⟩)∣a⟩=(−1)f(a)∣−⟩∣a⟩
La clave que permite que esto funcione está en que X∣−⟩=−∣−⟩. En términos matemáticos, el vector ∣−⟩ es un autovector de la matriz X con autovalor −1.
En ciertas ocasiones se utiliza combinado con el operador de difusión (por ejemplo el Operador de Grover), ya que permite seleccionar la solución al problema (cuando f(x)=1) invirtiendo su fase, para luego amplificar su amplitud.
Por otra parte, en el algoritmo de Deutsch-Jozsa se utiliza para identificar si la función es balanceada o constante.