Articulo de referencia

Teorema de Rice

En la teoría de la computabilidad , el teorema de Rice establece que todas las propiedades semánticas no triviales de los programas son indecidibles . Una propiedad semántica se...

En la teoría de la computabilidad , el teorema de Rice establece que todas las propiedades semánticas no triviales de los programas son indecidibles . Una propiedad semántica se refiere al comportamiento del programa (por ejemplo, "¿el programa finaliza para todas las entradas?"), a diferencia de una propiedad sintáctica (por ejemplo, "¿el programa contiene una instrucción if-then-else ?"). Una propiedad no trivial es aquella que no es verdadera ni falsa para todos los programas.

El teorema generaliza la indecidibilidad del problema de la parada . Tiene implicaciones de gran alcance en la viabilidad del análisis estático de programas. Implica que es imposible, por ejemplo, implementar una herramienta que verifique si un programa dado es correcto , o incluso si se ejecuta sin errores (es posible implementar una herramienta que siempre sobreestime o siempre subestime, por lo que en la práctica hay que decidir qué representa un problema menor).

El teorema recibe su nombre de Henry Gordon Rice , quien lo demostró en su tesis doctoral de 1951 en la Universidad de Syracuse .

Introducción

El teorema de Rice establece un límite teórico para los tipos de análisis estático que pueden realizarse automáticamente. Se puede distinguir entre la sintaxis de un programa y su semántica . La sintaxis describe cómo está escrito el programa, o su "intensión", y la semántica describe cómo se comporta el programa al ejecutarse, o su "extensión". El teorema de Rice afirma que es imposible determinar una propiedad de los programas que dependa únicamente de la semántica y no de la sintaxis, a menos que la propiedad sea trivial (verdadera o falsa para todos los programas).

Según el teorema de Rice, es imposible escribir un programa que verifique automáticamente la ausencia de errores en otros programas, tomando como entrada un programa y una especificación , y comprobando si el programa cumple con la especificación.

Esto no implica la imposibilidad de prevenir ciertos tipos de errores. Por ejemplo, el teorema de Rice implica que en los lenguajes de programación de tipado dinámico que son Turing-completos , es imposible verificar la ausencia de errores de tipo. Por otro lado, los lenguajes de programación de tipado estático cuentan con un sistema de tipos que previene estáticamente los errores de tipo. En esencia, esto debe entenderse como una característica de la sintaxis (en un sentido amplio) de dichos lenguajes. Para verificar el tipo de un programa, es necesario inspeccionar su código fuente; la operación no depende simplemente de la semántica hipotética del programa.

En términos de verificación general de software, esto significa que, si bien no se puede comprobar algorítmicamente si un programa determinado cumple con una especificación dada, se puede exigir que los programas estén anotados con información adicional que demuestre su corrección, o que estén escritos en una forma restringida específica que posibilite la verificación, y solo aceptar programas que se verifiquen de esta manera. En el caso de la seguridad de tipos, lo primero corresponde a las anotaciones de tipo, y lo segundo a la inferencia de tipos . Más allá de la seguridad de tipos, esta idea conduce a pruebas de corrección de programas mediante anotaciones de prueba, como en la lógica de Hoare .

Otra forma de sortear el teorema de Rice es buscar métodos que detecten muchos errores, sin llegar a ser completos. Esta es la teoría de la interpretación abstracta .

Otra vía para la verificación es la comprobación de modelos , que solo se puede aplicar a programas de estados finitos, no a lenguajes Turing-completos.

Declaración formal

Dejarφ{\displaystyle \varphi }Sea una numeración admisible de las funciones computables parciales , y seaPAG{\displaystyle P}ser un subconjunto denorte{\displaystyle \mathbb {N} }Supongamos que:

  1. PAG{\displaystyle P}no es trivial :PAG{\displaystyle P}no está ni vacío ninorte{\displaystyle \mathbb {N} }sí mismo.
  2. PAG{\displaystyle P}es extensional : para todos los enterosmetro{\displaystyle m}ynorte{\displaystyle n}, siφmetro=φnorte{\displaystyle \varphi _{m}=\varphi _{n}}, entoncesmetroPAGnortePAG{\displaystyle m\in P\iff n\in P}.

EntoncesPAG{\displaystyle P}es indecidible .

Se puede hacer una afirmación más concisa en términos de conjuntos de índices : Los únicos conjuntos de índices decidibles son{\displaystyle \varnothing }ynorte{\displaystyle \mathbb {N} }.

Ejemplos

Dado un programa P que toma un número natural n y devuelve un número natural P ( n ), las siguientes preguntas son indecidibles:

  • ¿ Termina P en un n dado ? (Este es el problema de la parada ).
  • ¿ P termina en 0?
  • ¿ P termina en todos los n (es decir, P es total )?
  • ¿ El programa P finaliza y devuelve 0 con cada entrada?
  • ¿La función P finaliza y devuelve 0 con alguna entrada?
  • ¿El algoritmo P finaliza y devuelve el mismo valor para todas las entradas?
  • ¿Es P equivalente a un programa Q dado ?

Demostración mediante el teorema de recursión de Kleene.

Supongamos por contradicción quePAG{\displaystyle P}es un conjunto no trivial, extensional y computable de números naturales. Dado quePAG{\displaystyle P}no es trivial, hay un número naturalaPAG{\displaystyle a\in P}y un número naturalbPAG{\displaystyle b\notin P}. Defina la función computable totalQ{\displaystyle Q}demi{\displaystyle e}yincógnita{\displaystyle x}porQmi(incógnita)=φb(incógnita){\displaystyle Q_{e}(x)=\varphi _{b}(x)}cuandomiPAG{\displaystyle e\in P}yQmi(incógnita)=φa(incógnita){\displaystyle Q_{e}(x)=\varphi _ {a}(x)}cuandomiPAG{\displaystyle e\notin P}. Por el teorema de recursión de Kleene , existemi{\displaystyle e}de tal manera queφmi=Qmi{\displaystyle \varphi _ {e} = Q_ {e}}. Entonces, simiPAG{\displaystyle e\in P}, tenemosφmi=φb{\displaystyle \varphi _{e}=\varphi _{b}}, contradiciendo la extensionalidad dePAG{\displaystyle P}desdebPAG{\displaystyle b\notin P}y a la inversa, simiPAG{\displaystyle e\notin P}, tenemosφmi=φa{\displaystyle \varphi _ {e} = \varphi _ {a}}, lo cual contradice nuevamente la extensionalidad ya queaPAG{\displaystyle a\in P}.

Demostración por reducción a partir del problema de la parada.

Boceto de prueba

Supongamos, a modo de ejemplo, que disponemos de un algoritmo para examinar un programa p y determinar infaliblemente si p es una implementación de la función de elevación al cuadrado, que toma un número entero d y devuelve . La demostración funciona igual de bien si disponemos de un algoritmo para determinar cualquier otra propiedad no trivial del comportamiento de un programa (es decir, una propiedad semántica y no trivial), y se presenta de forma general a continuación.

La afirmación es que podemos convertir nuestro algoritmo para identificar programas de elevación al cuadrado en uno que identifique funciones que se detienen. Describiremos un algoritmo que toma como entradas a e i y determina si el programa a se detiene cuando se le da la entrada i .

El algoritmo para decidir esto es conceptualmente simple: construye (la descripción de) un nuevo programa t que toma un argumento n , el cual (1) primero ejecuta el programa a sobre la entrada i (tanto a como i están codificados en la definición de t ), y (2) luego devuelve el cuadrado de n . Si a ( i ) se ejecuta indefinidamente, entonces t nunca llega al paso (2), independientemente de n . Entonces, claramente, t es una función para calcular cuadrados si y solo si el paso (1) termina. Dado que hemos asumido que podemos identificar infaliblemente programas para calcular cuadrados, podemos determinar si t , que depende de a e i , es tal programa; por lo tanto, hemos obtenido un programa que decide si el programa a se detiene sobre la entrada i . Nótese que nuestro algoritmo de decisión de parada nunca ejecuta t , sino que solo pasa su descripción al programa de identificación de cuadrados, que por supuesto siempre termina; puesto que la construcción de la descripción de t también se puede hacer de una manera que siempre termina, la decisión de parada tampoco puede dejar de detenerse.

paradas (a,i) { define t(n) { ai) devolver n×n } devolver es_una_función_de_cuadrado(t) }

Este método no depende específicamente de poder reconocer funciones que calculen cuadrados; siempre que algún programa pueda hacer lo que estamos tratando de reconocer, podemos agregar una llamada a para obtener nuestro t . Podríamos haber tenido un método para reconocer programas para calcular raíces cuadradas, o programas para calcular la nómina mensual, o programas que se detienen cuando se les da la entrada "Abraxas"; en cada caso, podríamos resolver el problema de la parada de manera similar.

Prueba formal

Si disponemos de un algoritmo que determine una propiedad no trivial, podemos construir una máquina de Turing que resuelva el problema de la parada.

Para la demostración formal, se supone que los algoritmos definen funciones parciales sobre cadenas y que están representados por cadenas. La función parcial calculada por el algoritmo representado por una cadena a se denota F a . Esta demostración procede por reducción al absurdo : suponemos que existe una propiedad no trivial que es decidida por un algoritmo, y luego mostramos que de ello se deduce que podemos resolver el problema de la parada , lo cual no es posible y, por lo tanto, es una contradicción.

Supongamos ahora que P ( a ) es un algoritmo que decide alguna propiedad no trivial de F( a) . Sin pérdida de generalidad, podemos suponer que P ( no-halt ) = "no", donde " no-halt" representa un algoritmo que nunca se detiene. Si esto no es cierto, entonces esto se cumple para el algoritmo P que calcula la negación de la propiedad P. Ahora bien, dado que P decide una propiedad no trivial, se deduce que existe una cadena b que representa un algoritmo F( b) y P ( b ) = "sí". Entonces podemos definir un algoritmo H ( a , i ) de la siguiente manera:

1. Construir una cadena t que represente un algoritmo T ( j ) tal que
  • T primero simula el cálculo de F a ( i ),
  • Luego, T simula el cálculo de F b ( j ) y devuelve su resultado.
2. devolver P ( t ).

Ahora podemos demostrar que H decide el problema de la parada:

  • Supongamos que el algoritmo representado por a se detiene en la entrada i . En este caso, F t = F b y, dado que P ( b ) = "sí" y la salida de P ( x ) depende solo de F x , se deduce que P ( t ) = "sí" y, por lo tanto, H ( a , i ) = "sí".
  • Supongamos que el algoritmo representado por a no se detiene en la entrada i . En este caso, F t = F no-halt , es decir, la función parcial que nunca se define. Dado que P ( no-halt ) = "no" y la salida de P ( x ) depende solo de F x , se deduce que P ( t ) = "no" y, por lo tanto, H ( a , i ) = "no".

Dado que se sabe que el problema de la parada es indecidible, esto es una contradicción y la suposición de que existe un algoritmo P ( a ) que decide una propiedad no trivial para la función representada por a debe ser falsa.

Véase también

Referencias