3 TEMA 3: LA VERIFICACIÓN FORMAL

Anuncio
3 TEMA 3: LA VERIFICACIÓN FORMAL
3.1
El código y la especificación: la comprobación formal de la
implementación.
Hasta ahora se ha visto como realizar una especificación formal de los requerimientos
de un sistema utilizando el lenguaje Z. Sobre esta especificación pueden realizarse
diversas pruebas formales que permiten garantizar la corrección de la especificación
realizada.
También se estudió en la introducción al lenguaje Z, mediante un ejemplo, la
posibilidad de ir refinando la especificación hasta acercarla al modo en que podría ser
implementada en un lenguaje de programación. Aunque este aspecto no se ha tratado en
mayor profundidad a lo largo del presente curso.
El enfoque que ahora se propone sería un paso más en la garantía de calidad de un
producto software. Una vez realizada una especificación que representa el
comportamiento deseado de una componente software, el siguiente paso consistiría en
su implementación, su realización en un lenguaje de programación concreto.
Una vez concluida la implementación, habríamos de verificar la corrección de dicha
implementación, garantizando que el programa construido cumple con el significado de
la especificación. Este planteamiento tiene un problema y es la dependencia del
lenguaje de programación elegido para realizar la verificación, lo que resulta demasiado
complicado, puesto que nos obligaría a desarrollar un método de verificación para cada
lenguaje concreto.
Esto puede ser evitado introduciendo un paso intermedio entre la especificación y la
implementación de algoritmos que denominaremos Diseño. El diseño de un programa
nos permite obtener una caracterización algorítmica del mismo lo bastante abstracta
como para:
 Ser independiente del lenguaje de programación
 Permitirnos razonar acerca del programa
 Poder realizar una traducción a los lenguajes imperativos comunes
La notación empleada se denomina Lenguaje Algorítmico, un lenguaje de programación
imperativo genérico, con un repertorio de instrucciones reducido pero que permiten
representar todas las construcciones existentes en los lenguajes imperativos
estructurados.
3.2
Especificación de algoritmos mediante la lógica de Hoare
MFES: TEMA 3: Verificación Formal
1/4
El método de verificación formal más conocido describe la especificación utilizando la
lógica de Hoare, basada en fórmulas de lógica de primer orden. Sin embargo, esta
aproximación no está demasiado alejada de las especificaciones formales que hemos
estudiado, utilizando el lenguaje Z como vemos en el ejemplo que aparece a
continuación.
Ordenar
matriz, matriz’: seq
i, j:
#matriz = # matriz’
i: 1..#matriz’, j:1..#matriz  matriz’ i = matriz j
i: 1..#matriz-1  matriz’ i  matriz’ i+1
El programa, en la lógica de Hoare, se especifica mediante formulas denominadas
aserciones que relacionan las entradas y salidas del programa. Se garantiza que si la
entrada actual satisface las restricciones de entrada (precondiciones) la salida satisface
las restricciones de salida (postcondiciones).
Se utiliza una expresión del tipo P{programa}Q, siendo P y Q aserciones de la lógica,
para indicar que si P es cierto antes de la ejecución del programa y dicho programa
termina, entonces Q es cierto tras la ejecución de dicho programa. Esta notación permite
que se pueda verificar la corrección parcial del programa, o sea, siempre que el
programa termine. Por otro lado, la expresión {P}programa{Q} indica corrección total de
dicho programa, esto es, además de garantizar el cumplimento de postcondiciones, el
programa termina.
La especificación en esta lógica, que como ya se indicó utiliza el formato
pre/postcondición, del programa de ordenación que figura como ejemplo, sería la
siguiente:
{n >0 and a(1..n): integers}
P
{i: (1  i  n) | a(i)  a(i+1)}
Las aserciones de entrada o precondiciones nos indican que la cardinalidad de la matriz
tiene que ser mayor que 0 y que todos los elementos de la matriz son enteros. Las
aserciones para los valores de salida o postcondiciones afirman que la matriz al final
debe estar ordenada de modo incremental.
Como se puede ver, la postcondición no es más que la definición en Z de los efectos de
la operación sobre las variables del esquema. Por otro lado, las precondiciones se
corresponden con las definiciones de variables que se han hecho en el esquema, más las
que se podrían obtener utilizando pre Ordenar, o sea, el cálculo de precondiciones de
dicho esquema.
MFES: TEMA 3: Verificación Formal
2/4
3.3
Verificación de algoritmos
3.3.1 Precondición más débil
Conceptualmente todo el proceso de verificación se basa en la definición de la
precondición más débil: pmd (weakest precondition: wp). Supongamos que nos
encontramos con una acción algorítmica A y queremos comprobar si cumple la
especificación formada por P y Q como precondición y postcondición respectivamente,
esto es, {P} A {Q}.
La idea de la verificación es proceder de atrás hacia delante. Esto es, vamos a intentar
definir cuales son los estados tales que desde ellos y ejecutando A se llega a Q. Estos
estados se pueden caracterizar por una serie de condiciones, o sea, por una aserción R
que cumplirá {R} A {Q}. En este punto, si la precondición (P) es más fuerte que R, o
sea si P  R, se obtiene que el algoritmo es correcto.
Para poder usar este método de razonamiento hacia atrás se necesita poder calcular la
aserción R para cada posible acción A De este modo, se define la precondición más
débil y se denota por pmd (A, Q) como el conjunto de todos los estados tales que una
ejecución de A que comience en uno de ellos se garantiza que termina en el estado Q en
un tiempo finito.
Veremos este concepto mediante la utilización de algunos ejemplos:
 Sea A, el comando de asignación i:=i+1 y Q, i  1, entonces pmd (A, Q) = (i  0).
 Sea A, if x y then z:=x else z:=y y Q, z = max(x,y). La ejecución de la sentencia
siempre hace que z sea el máximo de dichos valroes, por lo tanto pmd (A,Q) = true.
O sea, se cumplirá para cualquier estado previo.
 Sea A la misma que en el ejemplo anterior y Q z = y. Entonces pmd(A,Q) = (y  x).
Puesto que la ejecución de A con conjuntos de valores que cumplen y  x, hará que
z tome el valor y, mientras que para conjuntos de valores con y <x, pondrá a z el
valor x, que es distinto de y.
El cálculo de la precondición más débil se ha realizado en los ejemplos de modo
intuitivo, pero están definidas una serie de reglas para su cálculo de modo sistemático.
3.3.2 Verificación de un programa
Para probar la corrección parcial del un programa B (o sea, de un conjunto de
operaciones o instrucciones), con respecto a un predicado de entrada P y un predicado
de salida Q, lo que se hace es intentar deducir la aserción {P}B{Q}utilizando una serie
de reglas de verificación.
MFES: TEMA 3: Verificación Formal
3/4
Las reglas de verificación expresan la semántica de las distintas operaciones, ya que nos
indican las condiciones que cumple el estado antes y después de la ejecución de cada
instrucción. Existirá al menos una regla de verificación para cada instrucción, que será
empleada para la verificación a posteriori del programa construido.
De este modo se intentará para verificar un programa obtener su pmd dadas las
postcondiciones y el propio programa. Una vez obtenida ésta, si las precondiciones
iniciales son más fuertes que dicha pmd tenemos garantía de que el programa cumple
las especificaciones iniciales.
MFES: TEMA 3: Verificación Formal
4/4
Descargar