CS. de la COMPUTACION II 1 VERIFICACION DE PROGRAMAS Uo de los efoques para determiar si u programa es correcto es establecer ua actividad de testig. Esta cosiste e seleccioar u cojuto de datos de etrada para determiar si los resultados producidos por el programa co esos datos coicide o o co los valores esperados. Para asegurar que el programa es correcto se debería aalizar el mismo co todos los valores posibles de los datos de etrada. Pero esto es imposible cuado este cojuto es ifiito. Por eso, el testig sólo puede mostrar la presecia de errores y o su ausecia. Otro efoque, la prueba formal de programas, es ua técica que se basa e el cálculo de predicados. Primero, se debe describir el comportamieto de cada istrucció del leguaje formalmete. Es decir, se debe defiir la semática de u leguaje de programació e térmios de fórmulas lógicas. Para probar u programa, se debe expresar su semática e térmios de fórmulas lógicas y luego probar que el programa sigifica lo mismo que su especificació. Ua prueba formal de u programa asegura que el programa es correcto co respecto a ua especificació para todas las etradas. Hay dos problemas importates co la prueba formal de programas: 1) la maipulació lógica puede ser tediosa y propesa a errores; 2) la prueba solamete muestra que el programa implemeta la especificació correctamete. No hay certeza de que la especificació describe lo que el usuario realmete desea. Defiició: Si u programa usa variables (x 1, x 2,..., x ) el estado s es ua tupla de valores (X 1, X 2,..., X ) dode X i es el valor de la variable x i. Ejemplo: Dado el estado s = (x, y) = (7, 8), el resultado de ejecutar la setecia de asigació x := 2*y+1 es el estado s = (x, y) = (17, 8) Ua variable se usa e u programa para describir ua posició de memoria que puede coteer valores diferetes e diferetes estados. Ua maera de describir u cojuto de estados es utilizado fórmulas del cálculo de predicados. Defiició: Sea U el cojuto de todos los posibles estados del programa y sea S U. Se defie P S, el predicado característico de S, tal que S = { s S / P S (s ) }. Es decir, es el predicado que solamete es satisfecho por los estados que perteece al cojuto S. Por ejemplo, e vez de decir que la setecia x:= 2*y+1 trasforma el estado s = (x, y) e el estado s = (2*y+1, y), defiiremos predicados P(x, y) y P (x, y ) tal que si P(x, y) es verdadero e el estado s etoces P (x, y ) será verdadero después de ejecutar la setecia x := 2*y+1. Ejemplo: Se quiere probar x 7 después de ejecutar x := 2*y+1. Esto es verdadero si 2*y+1 7 ates de ejecutar la setecia, es decir y 3. { y 3 } x := 2*y+1 { x 7 } {y 3} y {x 7} se deomia asercioes. Defiició: Ua aserció es ua fórmula del cálculo de predicados ubicada e u programa, que es verdadera cada vez que el programa pasa por ese puto. Defiició: {P} S {Q}, dode P y Q so asercioes llamadas pre-codició y post-codició respectivamete y S es u fragmeto de programa, se iterpreta como sigue: si la ejecució de S empieza e u estado caracterizado por P y S termia, etoces termiará e u estado caracterizado por Q. S se dice parcialmete correcto co respecto a P y Q. Si además se garatiza que S termia, S es totalmete correcto co respecto a P y Q. {P} S {Q} se deomia especificació formal de S.
CS. de la COMPUTACION II 2 Ejemplos: Los siguietes so ejemplos de programas especificados e térmios de pre y post codicioes. 1) Dados dos úmeros aturales a y b, b 0, ecotrar el cociete etre a y b. P: { a, b N b > 0} Q: { a = b*c + r 0 r < b c 0 } 2) Dado u arreglo de úmeros eteros, ordearlo e forma ascedete. P: { i: 1 i : (iteger(a[i]) a[i] = A[i]) } A referecia el valor de los elemetos del arreglo a ates de iiciar la ejecució Q: { i: 1 i < : a[i] a[i+1] permutació(a, A)} El predicado permutació(a, A) se defie como: permutació(a, A) = { i: 1 i : (Nj: 1 j : a[i] = a[j]) = (Nk: 1 k : a[i] = A[k])} 3) Ecotrar el valor máximo de u arreglo de úmeros eteros. P: { i: 1 i : (iteger(a[i]) a[i] = A[i]) } A referecia el valor de los elemetos del arreglo a ates de iiciar la ejecució Q: { i: 1 i : (max = a[i] j: 1 j : (a[j] max a[j] = A[j] ))} Volviedo al ejemplo { y 3 } x := 2*y+1 { x 7 }, { y 3 } o es la úica pre-codició que hace verdadera la post-codició después de la ejecució de la setecia de asigació. Otra precodició podría ser { y = 1 y = 3}. Pero esta última es meos iteresate porque o caracteriza todos los estados desde los cuales se puede alcazar u estado caracterizado por la post-codició. Se desea determiar como pre-codicioes aquellas fórmulas que describa tatos estados como sea posible. Esto se hace eligiedo el predicado meos restrictivo posible. Defiició: Ua fórmula A es más débil que ua fórmula B si B A (B es más fuerte que A). Como A es más débil que B, A describe más estados que B. Ua aserció es ua fórmula del cálculo de predicados; como casos especiales se puede distiguir las fórmulas T (true) y F(false). Como T es verdadero e todo estado, es la más débil etre las fórmulas. F es más fuerte que toda fórmula. Por ejemplo, y 3 es más débil que (y = 1 y =3) porque (y = 1 y =3) y 3 Defiició: Para todo fragmeto de programa S y fórmula Q, se defie la pre-codició más débil R = wp(s, Q) tal que {R} S {Q} es verdadero. Es decir, wp(s, Q) represeta todos los estados tal que la ejecució de S que comezó e cualquiera de ellos, si termia, termia e u estado que satisface Q. La otació {P} S {Q} (defiida ateriormete) es otra otació para P wp(s, Q). wp se deomia tambié predicado trasformador, ya que para cualquier fragmeto de programa defie ua trasformació de u predicado post-codició e u predicado pre-codició. Es decir, e vez de describir cómo u programa trasforma u cojuto de estados iiciales e u cojuto de estados fiales, describe cómo u programa trasforma u predicado post-codició, que caracteriza el cojuto de estados fiales, e u predicado pre-codició que caracteriza el cojuto de estados iiciales. Esto sigifica que para probar formalmete u programa se comezará desde la post-codició y se trabajará hacia atrás para verificar cada ua de las setecias idividuales del programa.
CS. de la COMPUTACION II 3 Se defie a cotiuació el predicado wp para u leguaje de programació co setecias de asigació, codicioal (if B S 1 else S 2 ) e iteració (while B S). Defiició: wp(x = e, Q) = Q {x/e} e es ua expresió Por ejemplo wp(y = b, y 0} = (y 0) {y/b} = b 0 wp(x = x+1, x = 5) = (x = 5) {x/x+1} = (x+1 = 5) = (x = 4) Defiició: wp(s 1 ; S 2, Q) = wp(s 1, wp(s 2, Q)) Por ejemplo se desea calcular la pre-codició más débil del siguiete fragmeto de programa: x = x+1; y = y+2 {x < y} wp(x = x+1; y = y+2, x < y) = wp(x = x+1, wp(y = y+2, x < y)) = wp(x = x+1, x < y+2) = x < y+1 Esto se puede escribir tambié como sigue { x < y+1 } x = x+1; { x < y+2 } y = y+2 { x < y } Defiició: wp(if B S 1 else S 2, Q) = (B wp(s 1, Q)) ( B wp(s 2, Q)) Ejemplo: Calcular la pre-codició más débil del siguiete fragmeto de programa: if y = 0 x = 0 else x = y 1 { x = y } wp(if y = 0 x = 0 else x = y-1, x = y) = = ( y = 0 wp(x = 0, x = y)) ( (y = 0) wp(x = y-1, x = y)) = ( y = 0 y = 0) (y 0 y-1 = y) = T (y 0 F) = (y 0 F) = ( (y 0) F) = (y 0) = (y = 0) Por lo tato la pre-codició más débil es P: { y = 0 } Defiició: U predicado I se llama ivariate de ua setecia S si wp(s, I) = I Defiició: Para probar la correcció de ua setecia while B S, co post-codició Q se deberá: 1) Calcular el predicado ivariate I.
CS. de la COMPUTACION II 4 2) Probar que I B wp(s, I) 3) Probar que I vale ates de iterar 4) Probar que I B Q (Q es la post-codició de la setecia while B S) Ejemplo: Para el siguiete fragmeto de programa y sus pre y post codicioes, probar si es o o correcto co respecto a las especificacioes dadas. pre: { >0} (6) i = 1; (5) suma = 0; (4) while (i <= ) (3) { suma = suma + i; (2) i++; (1) } post: {suma = Σ j } j = 1 El predicado ivariate es I: { 1 i +1 suma = Σ j } (1) = I ( es decir, después de ejecutar i++ es verdadero el predicado ivariate) (2) = (1) {i/i+1} = {1 i+1 +1 suma = Σ j } = {0 i suma = Σ j } i (3) = (2){suma/suma+i} = {0 i suma+i = Σ j } = {0 i suma+i = Σ j + i} (3) = {0 i suma = Σ j } I {i <= } (3) {1 i +1 suma = Σ j } {i <= } (3) i+1-1 {1 i suma = Σ j } {0 i suma = Σ j } i I {i > } post {1 i +1 suma = Σ j } {i > } post
CS. de la COMPUTACION II 5 {i = +1 suma = Σ j } { suma = Σ j } {suma = Σ j } { suma = Σ j } (4) = I (5) = (4){suma/0} = { 1 i +1 0 = Σ j } 1-1 (6) = (5){i/1} = { 1 1 +1 0 = Σ j } = { 0 0 = 0 } = { 0 } La aserció (6) es la pre-codició más débil del programa. Se debe comprobar además si la pre-codició del programa es más fuerte que la pre-codició más débil del programa, esto es { > 0 } { 0 } Es imediato que se cumple. Por lo tato, se ha probado formalmete que el fragmeto de programa dado es parcialmete correcto. Para probar que es totalmete correcto se debería probar que el programa termia y para probar esto se debería probar que el úico ciclo que tiee el programa termia.