Articulo de referencia

semántica de transformadores de predicados

La semántica de transformadores de predicados fue introducida por Edsger Dijkstra en su artículo fundamental " Guarded commands, nondeterminacy and formal derivation of programs...

La semántica de transformadores de predicados fue introducida por Edsger Dijkstra en su artículo fundamental " Guarded commands, nondeterminacy and formal derivation of programs ". Define la semántica de un paradigma de programación imperativa asignando a cada instrucción de este lenguaje un transformador de predicados correspondiente : una función total entre dos predicados en el espacio de estados de la instrucción. En este sentido, la semántica de transformadores de predicados es una especie de semántica denotacional . De hecho, en "Guarded commands" , Dijkstra utiliza solo un tipo de transformador de predicados: las conocidas precondiciones más débiles (véase más adelante).

Además, la semántica de transformadores de predicados es una reformulación de la lógica de Floyd-Hoare . Mientras que la lógica de Hoare se presenta como un sistema deductivo , la semántica de transformadores de predicados (ya sea mediante precondiciones más débiles o postcondiciones más fuertes , véase más adelante) ofrece estrategias completas para construir deducciones válidas de la lógica de Hoare. En otras palabras, proporciona un algoritmo eficaz para reducir el problema de verificar una tripleta de Hoare al problema de demostrar una fórmula de primer orden . Técnicamente, la semántica de transformadores de predicados realiza una especie de ejecución simbólica de enunciados en predicados: la ejecución se realiza hacia atrás en el caso de precondiciones más débiles, o hacia adelante en el caso de postcondiciones más fuertes.

precondiciones más débiles

Definición

Para una proposición S y una postcondición R , una precondición más débil es un predicado Q tal que para cualquier precondición P ,{PAG}S{R}{\displaystyle \{P\}S\{R\}}si y solo siPAGQ{\displaystyle P\Rightarrow Q}En otras palabras, es el requisito "más laxo" o menos restrictivo necesario para garantizar que R se cumpla después de S. La unicidad se deduce fácilmente de la definición: si tanto Q como Q' son precondiciones más débiles, entonces por definición{Q}S{R}{\displaystyle \{Q'\}S\{R\}}entoncesQQ{\displaystyle Q'\Rightarrow Q}y{Q}S{R}{\displaystyle \{Q\}S\{R\}}entoncesQQ{\displaystyle Q\Rightarrow Q'}y por lo tantoQ=Q{\displaystyle Q=Q'}A menudo usamoswpag(S,R){\displaystyle wp(S,R)}para denotar la precondición más débil para la afirmación S con respecto a una postcondición R.

Convenciones

Usamos T para denotar el predicado que es verdadero en todas partes y F para denotar el que es falso en todas partes. No deberíamos confundirnos, al menos conceptualmente, con una expresión booleana definida por la sintaxis de algún lenguaje, que también podría contener verdadero y falso como escalares booleanos. Para tales escalares, necesitamos realizar una conversión de tipo tal que tengamos T = predicado(verdadero) y F = predicado(falso). Esta conversión se realiza a menudo de forma informal, por lo que la gente tiende a considerar T como verdadero y F como falso.

Saltar

Abortar

Asignación

A continuación, presentamos dos precondiciones más débiles equivalentes para la declaración de asignación. En estas fórmulas,R[incógnitami]{\displaystyle R[x\leftarrow E]}es una copia de R donde las ocurrencias libres de x se reemplazan por E. Por lo tanto, aquí, la expresión E se convierte implícitamente en un término válido de la lógica subyacente: es, por lo tanto, una expresión pura , totalmente definida, terminante y sin efectos secundarios.

  • versión 1:
  • versión 2:

Siempre que E esté bien definido, aplicamos la llamada regla de un punto a la versión 1. Entonces

La primera versión evita una posible duplicación de x en R , mientras que la segunda versión es más simple cuando hay como máximo una sola aparición de x en R. La primera versión también revela una profunda dualidad entre la precondición más débil y la postcondición más fuerte (véase más abajo).

Un ejemplo de cálculo válido de wp (usando la versión 2) para asignaciones con la variable x de valor entero es:

wpag(incógnita:=incógnita5,incógnita>10)=incógnita5>10incógnita>15{\displaystyle {\begin{array}{rcl}wp(x:=x-5,x>10)&=&x-5>10\\&\Leftrightarrow &x>15\end{array}}}

Esto significa que, para que la postcondición x > 10 sea verdadera después de la asignación, la precondición x > 15 debe ser verdadera antes de la asignación. Esta es también la "precondición más débil", ya que es la restricción "más débil" sobre el valor de x que hace que x > 10 sea verdadera después de la asignación.

Secuencia

Por ejemplo,

wpag(incógnita:=incógnita5;incógnita:=incógnita2 , incógnita>20)=wpag(incógnita:=incógnita5,wpag(incógnita:=incógnita2,incógnita>20))=wpag(incógnita:=incógnita5,incógnita2>20)=(incógnita5)2>20=incógnita>15{\displaystyle {\begin{array}{rcl}wp(x:=x-5;x:=x*2\ ,\ x>20)&=&wp(x:=x-5,wp(x:=x*2,x>20))\\&=&wp(x:=x-5,x*2>20)\\&=&(x-5)*2>20\\&=&x>15\end{array}}}

Condicional

Por ejemplo:

wpag(si incógnita<y entonces incógnita:=y demássaltarfin, incógnitay)=(incógnita<ywpag(incógnita:=y,incógnitay))  (¬(incógnita<y)wpag(saltar,incógnitay))=(incógnita<yyy)  (¬(incógnita<y)incógnitay)verdadero{\displaystyle {\begin{array}{rcl}wp({\texttt {if}}\ x<y\ {\texttt {entonces}}\ x:=y\ {\texttt {else}}\;\;{\texttt {skip}}\;\;{\texttt {end}},\ x\geq y)&=&(x<y\Rightarrow wp(x:=y,x\geq y))\ \wedge \ (\neg (x<y)\Rightarrow wp({\texttt {skip}},x\geq y))\\&=&(x<y\Rightarrow y\geq y)\ \wedge \ (\neg (x<y)\Rightarrow x\geq y)\\&\Leftrightarrow &{\texttt {true}}\end{array}}}

Bucle while

Corrección parcial

Ignorando la terminación por un momento, podemos definir la regla para la precondición liberal más débil , denotada wlp , utilizando un predicado INV , llamado ariant INV de bucle , normalmente proporcionado por un programador:

Corrección total

Para demostrar la corrección total, también debemos demostrar que el bucle termina. Para ello, definimos una relación bien fundamentada en el espacio de estados, denotada como ( wfs , <), y definimos una función variante vf , de tal manera que tenemos:

De manera informal, en la combinación anterior de tres fórmulas:

  • La primera significa que la variante debe ser parte de la relación bien fundamentada antes de entrar en el bucle;
  • La segunda significa que el cuerpo del bucle (es decir, la instrucción S ) debe preservar el invariante y reducir el variante;
  • La última significa que la postcondición del bucle R debe establecerse cuando el bucle finaliza.

Sin embargo, la conjunción de esos tres no es una condición necesaria. Exactamente, tenemos

Comandos protegidos no deterministas

En realidad, el lenguaje de comandos protegidos (GCL) de Dijkstra es una extensión del lenguaje imperativo simple presentado hasta ahora con enunciados no deterministas. De hecho, GCL pretende ser una notación formal para definir algoritmos. Los enunciados no deterministas representan opciones que quedan a la implementación real (en un lenguaje de programación efectivo): las propiedades demostradas en los enunciados no deterministas se garantizan para todas las posibles opciones de implementación. En otras palabras, las precondiciones más débiles de los enunciados no deterministas garantizan

  • que existe una ejecución que termina (por ejemplo, existe una implementación),
  • y que el estado final de toda ejecución que termina satisface la postcondición.

Las definiciones de precondición más débil dadas anteriormente (en particular para el bucle while ) preservan esta propiedad.

Selección

La selección es una generalización de la instrucción if :

Aquí, cuando dos guardiasmii{\displaystyle E_{i}}ymij{\displaystyle E_{j}}Si ambas condiciones son verdaderas simultáneamente, entonces la ejecución de esta instrucción puede ejecutar cualquiera de las instrucciones asociadas.Si{\displaystyle S_{i}}oSj{\displaystyle S_{j}}.

Repetición

La repetición es una generalización de la instrucción while de manera similar.

Declaración de especificaciones

El cálculo de refinamiento extiende GCL con la noción de declaración de especificación . Sintácticamente, preferimos escribir una declaración de especificación como

incógnita:l[pagrmi,pagost]{\displaystyle x:l[pre,post]}

que especifica un cálculo que comienza en un estado que satisface pre y está garantizado que terminará en un estado que satisface post cambiando solo x . Lo llamamosl{\displaystyle l}una constante lógica empleada para ayudar en una especificación. Por ejemplo, podemos especificar un cálculo que incremente x en 1 como

incógnita:l[incógnita=l,incógnita=l+1]{\displaystyle x:l[x=l,x=l+1]}

Otro ejemplo es el cálculo de la raíz cuadrada de un número entero.

incógnita:l[incógnita=l2,incógnita=l]{\displaystyle x:l[x=l^{2},x=l]}

La declaración de especificación se presenta como una instrucción primitiva en el sentido de que no contiene otras instrucciones. Sin embargo, es muy expresiva, ya que pre y post son predicados arbitrarios. Su precondición más débil es la siguiente.

Combina la idea sintáctica de Morgan con la idea de nitidez de Bijlsma, Matthews y Wiltink. [ 1 ] La principal ventaja de esto es su capacidad para definir wp de goto L y otras sentencias de salto. [ 2 ]

Ir a la instrucción

La formalización de sentencias de salto como goto L requiere un proceso largo y accidentado. Una creencia común parece indicar que la sentencia goto solo podría argumentarse operacionalmente. Esto probablemente se deba a la falta de reconocimiento de que goto L es en realidad milagroso (es decir, no estricto) y no sigue la Ley de Exclusión de Milagros acuñada por Dijkstra, tal como se presenta en sí misma. Pero goza de una visión operacional extremadamente simple desde la perspectiva de la precondición más débil, lo cual fue inesperado. Definimos

Para la ejecución goto L, el control se transfiere a la etiqueta L en la que debe cumplirse la precondición más débil. La forma en que se hace referencia a wpL en la regla no debería ser una gran sorpresa. Es solo wpag(L:S,Q){\displaystyle wp(L:S,Q)}para alguna Q calculada hasta ese punto. Esto es como cualquier regla wp, que utiliza sentencias constituyentes para dar definiciones wp, aunque goto L parezca una primitiva. La regla no requiere la unicidad para las ubicaciones donde wpL se cumple dentro de un programa, por lo que teóricamente permite que la misma etiqueta aparezca en múltiples ubicaciones siempre que la precondición más débil en cada ubicación sea la misma wpL. La sentencia goto puede saltar a cualquiera de dichas ubicaciones. Esto justifica que podríamos colocar las mismas etiquetas en la misma ubicación varias veces, ya queS(L:L:S1){\displaystyle S(L:L:S1)} , que es lo mismo queS(L:S1){\displaystyle S(L:S1)}Además , no implica ninguna regla de ámbito, lo que permite, por ejemplo, un salto dentro del cuerpo de un bucle. Calculemos wp del siguiente programa S, que tiene un salto dentro del cuerpo del bucle.

 wp(do x > 0 → L: x := x-1 od; if x < 0 → x := -x; goto L ⫿ x ≥ 0 → skip fi, post) = { reglas de composición y alternancia secuenciales } wp(do x > 0 → L: x := x-1 od, (x<0 ∧ wp(x := -x; goto L, post)) ∨ (x ≥ 0 ∧ post) = { composición secuencial, ir a, reglas de asignación } wp(do x > 0 → L: x := x-1 od, x<0 ∧ wpL(x ← -x) ∨ x≥0 ∧ post) = { regla de repetición } la solución más fuerte de Z: [ Z ≡ x > 0 ∧ wp(L: x := x-1, Z) ∨ x < 0 ∧ wpL(x ← -x) ∨ x=0 ∧ post ] = { regla de asignación, encontrado wpL = Z(x ← x-1) } la solución más fuerte de Z: [ Z ≡ x > 0 ∧ Z(x ← x-1) ∨ x < 0 ∧ Z(x ← x-1) (x ← -x) ∨ x=0 ∧ post] = { sustitución } la solución más fuerte de Z:[ Z ≡ x > 0 ∧ Z(x ← x-1) ∨ x < 0 ∧ Z(x ← -x-1) ∨ x=0 ∧ post ] = { resolver la ecuación por aproximación } post(x ← 0)

Por lo tanto,

wp(S, post) = post(x ← 0).

Otros transformadores de predicados

Precondición liberal más débil

Una variante importante de la condición previa más débil es la condición previa liberal más débil.wlpag(S,R){\displaystyle wlp(S,R)}, que produce la condición más débil bajo la cual S no termina o establece R. Por lo tanto, difiere de wp en que no garantiza la terminación. De ahí que corresponda a la lógica de Hoare en corrección parcial: para el lenguaje de sentencias dado anteriormente, wlp difiere de wp solo en el bucle while , en que no requiere una variante (ver más arriba).

Postacondicionamiento más fuerte

Dado S una proposición y R una precondición (un predicado sobre el estado inicial), entonces spag(S,R){\displaystyle sp(S,R)}es su postcondición más fuerte : implica cualquier postcondición satisfecha por el estado final de cualquier ejecución de S, para cualquier estado inicial que satisfaga R. En otras palabras, una tripleta de Hoare{PAG}S{Q}{\displaystyle \{P\}S\{Q\}}es demostrable en lógica de Hoare si y solo si se cumple el predicado siguiente:

incógnita,spag(S,PAG)Q{\displaystyle \forall x,sp(S,P)\Rightarrow Q}

Por lo general, las postcondiciones más fuertes se utilizan en la corrección parcial. Por lo tanto, tenemos la siguiente relación entre las precondiciones liberales más débiles y las postcondiciones más fuertes:

(incógnita,PAGwlpag(S,Q))  (incógnita,spag(S,PAG)Q){\displaystyle (\forall x,P\Rightarrow wlp(S,Q))\ \Leftrightarrow \ (\forall x,sp(S,P)\Rightarrow Q)}

Por ejemplo, en la tarea tenemos:

Arriba, la variable lógica y representa el valor inicial de la variable x . Por lo tanto,

spag(incógnita:=incógnita5,incógnita>15) = y,incógnita=y5y>15  incógnita>10{\displaystyle sp(x:=x-5,x>15)\ =\ \exists y,x=y-5\wedge y>15\ \Leftrightarrow \ x>10}

En la secuencia, parece que sp avanza (mientras que wp retrocede):

transformadores de predicados de victoria y pecado

Leslie Lamport ha sugerido win y sin como transformadores de predicados para la programación concurrente . [ 3 ]

Propiedades de los transformadores de predicados

Esta sección presenta algunas propiedades características de los transformadores de predicados. [ 4 ] A continuación, S denota un transformador de predicados (una función entre dos predicados en el espacio de estados) y P un predicado. Por ejemplo, S(P) puede denotar wp(S,P) o sp(S,P) . Mantenemos x como la variable del espacio de estados.

Monótono

Los transformadores de predicados de interés ( wp , wlp y sp ) son monótonos . Un transformador de predicados S es monótono si y solo si:

(incógnita:PAG:Q)(incógnita:S(PAG):S(Q)){\displaystyle (\forall x:P:Q)\Rightarrow (\forall x:S(P):S(Q))}

Esta propiedad está relacionada con la regla de consecuencia de la lógica de Hoare .

Estricto

Un transformador de predicados S es estricto si y solo si:

S(F)  F{\displaystyle S({\texttt {F}})\ \Leftrightarrow \ {\texttt {F}}}

Por ejemplo, wp se hace artificialmente estricto, mientras que wlp generalmente no lo es. En particular, si la instrucción S no puede terminar entonces wlpag(S,F){\displaystyle wlp(S,{\texttt {F}})}es satisfactorio. Tenemos

wlpag(mientras verdadero hacer saltar hecho,F) T{\displaystyle wlp({\texttt {while}}\ {\texttt {true}}\ {\texttt {do}}\ {\texttt {skip}}\ {\texttt {done}},{\texttt {F}})\ \Leftrightarrow {\texttt {T}}}

En efecto, T es un invariante válido de ese bucle.

Los transformadores de predicados no estrictos pero monótonos o conjuntivos se denominan milagrosos y también pueden usarse para definir una clase de construcciones de programación, en particular, las sentencias de salto, que a Dijkstra le importaban menos. Estas sentencias de salto incluyen goto L directo, break y continue en un bucle y sentencias return en el cuerpo de un procedimiento, manejo de excepciones, etc. Resulta que todas las sentencias de salto son milagrosos ejecutables, [ 5 ] es decir, pueden implementarse pero no son estrictas.

Terminando

Un transformador de predicados S termina si:

S(T)  T{\displaystyle S({\texttt {T}})\ \Leftrightarrow \ {\texttt {T}}}

En realidad, esta terminología solo tiene sentido para los transformadores de predicados estrictos: de hecho,wpag(S,T){\displaystyle wp(S,{\texttt {T}})}es la condición previa más débil que garantiza la terminación de S.

Parece más apropiado denominar a esta propiedad "no abortiva" : en su corrección total, la no terminación es aborto, mientras que en su corrección parcial, no lo es.

Conjuntivo

Un transformador de predicados S es conjuntivo si y solo si:

S(PAGQ)  S(PAG)S(Q){\displaystyle S(P\wedge Q)\ \Leftrightarrow \ S(P)\wedge S(Q)}

Este es el caso dewpag(S,.){\displaystyle wp(S,.)}, incluso si la declaración S no es determinista como una declaración de selección o una declaración de especificación.

Disyuntivo

Un transformador de predicados S es disyuntivo si y solo si:

S(PAGQ)  S(PAG)S(Q){\displaystyle S(P\vee Q)\ \Leftrightarrow \ S(P)\vee S(Q)}

Este no suele ser el caso dewpag(S,.){\displaystyle wp(S,.)}cuando S no es determinista. De hecho, consideremos una proposición no determinista S que elige un valor booleano arbitrario. Esta proposición se presenta aquí como la siguiente proposición de selección :

S = si verdaderoincógnita:=0 [] verdaderoincógnita:=1 fi{\displaystyle S\ =\ {\texttt {if}}\ {\texttt {true}}\rightarrow x:=0\ [\!]\ {\texttt {true}}\rightarrow x:=1\ {\texttt {fi}}}

Entonces,wpag(S,R){\displaystyle wp(S,R)}se reduce a la fórmulaR[incógnita0]R[incógnita1]{\displaystyle R[x\leftarrow 0]\wedge R[x\leftarrow 1]}.

Por eso,wpag(S, incógnita=0incógnita=1){\displaystyle wp(S,\ x=0\vee x=1)}se reduce a la tautología(0=00=1)(1=01=1){\displaystyle (0=0\vee 0=1)\wedge (1=0\vee 1=1)}

Mientras que la fórmulawpag(S,incógnita=0)wpag(S,incógnita=1){\displaystyle wp(S,x=0)\vee wp(S,x=1)} reduce a la proposición errónea(0=01=0)(1=01=1){\displaystyle (0=0\wedge 1=0)\vee (1=0\wedge 1=1)}.

Aplicaciones

Más allá de los transformadores de predicados

Precondiciones más débiles y postcondiciones más fuertes de las expresiones imperativas

En la semántica de transformadores de predicados, las expresiones se restringen a los términos de la lógica (véase más arriba). Sin embargo, esta restricción parece demasiado fuerte para la mayoría de los lenguajes de programación existentes, donde las expresiones pueden tener efectos secundarios (llamada a una función con efecto secundario), pueden no terminar o abortar (como la división por cero ). Existen muchas propuestas para extender las precondiciones más débiles o las postcondiciones más fuertes para lenguajes de expresiones imperativas y, en particular, para mónadas .

Entre ellas, la teoría de tipos de Hoare combina la lógica de Hoare para un lenguaje similar a Haskell , la lógica de separación y la teoría de tipos . [ 9 ] Este sistema se implementa como una biblioteca Rocq llamada Ynot . [ 10 ] En este lenguaje, la evaluación de expresiones corresponde a cálculos de postcondiciones más fuertes .

transformadores de predicados probabilísticos

Los transformadores de predicados probabilísticos son una extensión de los transformadores de predicados para programas probabilísticos . Dichos programas tienen muchos usos en criptografía (ocultar información mediante ruido aleatorio) y computación distribuida (ruptura de simetría). [ 11 ]

Véase también

Notas

  1. Chen, Wei y Udding, Jan Tijmen, "The Specification Statement Refined" WUCS-89-37 (1989). https://openscholarship.wustl.edu/cse_research/749
  2. Chen, Wei, "Una caracterización wp de las sentencias de salto", Simposio Internacional de 2021 sobre Aspectos Teóricos de la Ingeniería de Software (TASE), 2021, pp. 15-22. doi: 10.1109/TASE52547.2021.00019.
  3. Lamport, Leslie (julio de 1990). " win and sin : Predicate Transformers for Concurrency" . ACM Transactions on Programming Languages ​​and Systems . 12 (3): 396–428 . CiteSeerX 10.1.1.33.90 . doi : 10.1145/78969.78970 . S2CID 209901 .  
  4. Back, Ralph-Johan; Wright, Joakim (2012) [1978]. Cálculo de refinamiento: una introducción sistemática . Textos en informática. Springer. ISBN 978-1-4612-1674-2.
  5. Chen, Wei, "Las sentencias de salida son milagros ejecutables" WUCS-91-53 (1991). https://openscholarship.wustl.edu/cse_research/671
  6. Dijkstra, Edsger W. (1968). "Un enfoque constructivo al problema de la corrección de programas". BIT Numerical Mathematics . 8 (3): 174– 186. doi : 10.1007/bf01933419 . S2CID 62224342 . 
  7. Wirth, N. (abril de 1971). "Desarrollo de programas mediante refinamiento por etapas" (PDF) . Comm. ACM . 14 (4): 221– 7. doi : 10.1145/362575.362577 . hdl : 20.500.11850/80846 . S2CID 13214445 . 
  8. Un tutorial sobre cómo reflejar en Coq la generación de obligaciones de prueba de Hoare (tutorial sobre lógica de Hoare) : una biblioteca de Rocq (computación) , que proporciona una prueba simple pero formal de que la lógica de Hoare es sólida y completa con respecto a una semántica operacional .
  9. Nanevski, Aleksandar; Morrisett, Greg; Birkedal, Lars (septiembre de 2008). "Hoare Type Theory, Polymorphism and Separation" (PDF) . Journal of Functional Programming . 18 ( 5–6 ): 865–911 . doi : 10.1017/S0956796808006953 . S2CID 6956622 . 
  10. Ynot es una biblioteca de Rocq que implementa la teoría de tipos de Hoare.
  11. Morgan, Carroll; McIver, Annabelle ; Seidel, Karen (mayo de 1996). "Probabilistic Predicate Transformers" (PDF) . ACM Transactions on Programming Languages ​​and Systems . 18 (3): 325–353 . CiteSeerX 10.1.1.41.9219 . doi : 10.1145/229542.229547 . S2CID 5812195 .  

Referencias

  • de Bakker, JW (1980). Teoría matemática de la corrección de programas . Prentice-Hall. ISBN 978-0-13-562132-5.
  • Bonsangue, Marcello M.; Kok, Joost N. (noviembre de 1994). "El cálculo de precondiciones más débiles: recursión y dualidad". Aspectos formales de la computación . 6 (6): 788– 800. CiteSeerX 10.1.1.27.8491 . doi : 10.1007/BF01213603 . S2CID 40323488 .  
  • Dijkstra, Edsger W. (agosto de 1975). "Comandos protegidos, indeterminación y derivación formal de programas" . Comm. ACM . 18 (8): 453–7 . doi : 10.1145/360933.360975 . S2CID 1679242 . 
  • Dijkstra, Edsger W. (1976). Una disciplina de programación . Prentice Hall. ISBN 978-0-613-92411-5.– Una introducción sistemática a una versión del lenguaje de comandos protegidos con muchos ejemplos resueltos.
  • Dijkstra, Edsger W.; Scholten, Carel S. (1990). Cálculo de predicados y semántica de programas . Textos y Monografías en Informática. Springer-Verlag. ISBN 978-0-387-96957-2.– Un tratamiento más abstracto, formal y definitivo
  • Gries, David (1981). La ciencia de la programación . Springer-Verlag. ISBN 978-0-387-96480-5.

!-- Categorías ocultas a continuación -->