Académique Documents
Professionnel Documents
Culture Documents
Especicacin de problemas
1.1 Introduccin
El diseo formal de algoritmos utiliza mtodos formales para abordar sus tres fases fundamentales: especicacin, derivacin y vericacin. La especicacin formal de algoritmos es una tcnica que permite especicar la semntica intencional de un algoritmo de forma breve y precisa. A partir de una especicacin formal se pueden deducir formalmente (derivar) las instrucciones que debe contener el algoritmo y, una vez escrito, vericar formalmente su correccin. La vericacin formal de algoritmos tiene una gran importancia ya que permite vericar la correccin de un algoritmo antes de ser escrito en un lenguaje concreto (lenguaje de implementacin). Es lo que se conoce como vericacin a priori. Tradicionalmente los algoritmos se prueban, una vez escritos, con la ayuda de herramientas de depuracin, es lo que se conoce como vericacin a posteriori. Esto quiere decir que, hasta que no se prueba el programa no aparecen los errores. Al igual que en otra muchas actividades, cuanto ms pronto aore un error menos esfuerzo costar el corregirlo, lo que da un gran valor a las tcnicas formales de especicacin, derivacin y vericacin. La vericacin formal tambin se puede aplicar a algoritmos que no hayan sido derivados formalmente.
CAPTULO 1.
ESPECIFICACIN DE PROBLEMAS
Fijndose en la especicacin del ejemplo se ve que tiene dos destinatarios: 1. El usuario que vaya a utilizar el algoritmo. En el ejemplo el usuario se tiene que cerciorar de que b tiene que ser distinto de cero. 2. El programador que tendr que desarrollar el algoritmo suponiendo que el usuario llamar al algoritmo con los parmetros adecuados. En el ejemplo, desarrollar el algoritmo suponiendo que b es distinto de cero. La tcnica de especicacin formal que se va a utilizar es la conocida como tcnica pre/post. Un algoritmo se especica siguiendo el siguiente esquema {Q}S {R}, que se leer de la forma siguiente: "Si S comienza su ejecucin en un estado que satisface Q, termina, y lo hace en un estado que satisface R" El signicado de los tres componente es el siguiente: que cumplir los parmetros de entrada para que el algoritmo produzca el resultado deseado. Es donde se expresan las obligaciones que debe cumplir el usuario. S es la interfaz del algoritmo. Donde se especica el nombre del algoritmo y sus parmetros formales de entrada y de salida. R es la postcondicin. Donde se especica la relacin que deben cumplir los parmetros de entrada y los de salida para que el algorimo produzca el resultado deseado. Es donde se expresan las obligaciones del programador. Tanto la precondicin como la postcondicin se especican mediante predicados lgicos. Un predicado lgico es una frmula cuya evaluacin solo puede dar dos resultados: Cierto o F also. En cuanto a la interfaz, la notacin que se utilizar ser
Q es la precondicin. Donde se especican las restricciones que tienen
fun f (x : Tx ) dev (y : Ty )
donde:
f representa al nombre de la funcin. x : Tx representa a los parmetros de entrada y sus correspondientes tipos. y : Ty representa a los parmetros de salida y sus correspondientes tipos.
Cuando se quiera especicar una accin, la especicacin de la interfaz se har mediante la siguiente notacin
1.3.
LGICA DE PREDICADOS
accion f (x cf : Tx )
donde cf se concretar en:
E, para los parmetros de solo de entrada. S, para los parmetros de solo de salida. nada o E/S, para los parmetros de entrada y salida.
1.3
Lgica de predicados
Es predicado Una constante booleana Una variable de tipo booleano Una expresin relacional Una funcin booleana Ejemplo
Un predicado lgico puede ser atmico o construirse utilizando operadores. Un predicado atmico puede ser:
verdadero,f also x,y x y, x + y > 0 esP ar(x), estaOrdenado(x)
Denotando por las letras P y Q a predicados y por D a un dominio de valores, adems de los predicados atmicos, son igualmente predicados los siguientes: Es predicado La negacin de un predicado Una conjuncin de predicados Una disyuncin de predicados Un condicional de predicados Un bicondicional de predicados Una cuanticacin universal de un predicado Una cuanticacin existencial de un predicado Ejemplo
P P Q P Q P Q P Q D.P () D.P ()
Los cuanticadores sirven para escribir de forma abreviada una operacin sobre todos los valores de un dominio. El universal para la conjuncin y el existencial para la disyuncin, de tal manera que: El predicado
D.P () D.P () P (d1 ) P (d2 ) ... P (dn ) P (d1 ) P (d2 ) ... P (dn )
siendo "" el operador para denotar la equivalencia de predicados y d1 , d2 ,....dn los n valores del dominio D.
CAPTULO 1.
ESPECIFICACIN DE PROBLEMAS
Adems de estos cuanticadores, se utilizarn otros para representar de forma abreviada operaciones aritmticas sobre todos los valores de un dominio. Estos cuanticadores son:
P (d1 ) + P (d2 ) + ... + P (dn ) P (d1 ) P (d2 ) ... P (dn ) Nu mero(P (d1 ), P (d2 ), ..., P (dn ))
siendo la funcin Nmero igual al nmero de sus argumentos que se evalan a Cierto. Obsrvese que, en los dos primeros P () debe ser una frmula aritmtica y en el tercero una frmula lgica. Los cuanticadores podrn ser denotados por la notacin anterior o por, la utilizada tradicionalmente para los cuanticadores aritmticos:
Las leyes de equivalencia que facilitan el clculo con predicados son las siguientes:
1.3.
LGICA DE PREDICADOS
Ley Conmutativa Conmutativa Asociativa Asociativa Idempotencia Idempotencia Distributiva Distributiva Absorcin Absorcin Elemento neutro Elemento neutro Elemento neutro Elemento neutro Negacin Negacin Negacin De Morgan De Morgan de de de de de de de ( y ) de de
Predicados equivalentes
P Q P Q P (Q R) P (Q R) P P P P P (Q R) P (Q R) P (P Q) P (P Q) P F also P F also P Cierto P Cierto P P P P P (P Q) (P Q) P Q P Q ( Di .P ) ( Di .P ) ( D.P ) ( D.P ) ( D.P ) D1 . D2 .P D1 . D2 .P QP QP (P Q) R (P Q) R P P (P Q) (P R) (P Q) (P R) P P F also P P Cierto P F also Cierto P Q P Q P Q (P Q) (Q P ) Cierto, si Di = F also, si Di = ( Di .P ) ( Di .P ) ( D.P [/]), siempre que / variables(P ) D2 . D1 .P D2 . D1 .P
CAPTULO 1.
ESPECIFICACIN DE PROBLEMAS
en D1.(f ()) D2.(g ()) la variable ligada toma los valores del dominio D1 en el primer subpredicado y de D2 en el segundo.
Estado de una variable Es el valor que tiene la variable en un momento determinado de la ejecucin de un algoritmo. Estado de un algoritmo Es el valor que tienen todas sus variables libres en un momento determinado de su ejecucin. Aserto asercin Es un predicado que expresa la relacin que tienen que cumplir los valores de ciertas variables en un momento determinado de la ejecucin de un algoritmo. Los asertos los escribiremos como comentarios del algoritmo, por tanto el predicado deber escribirse entre los signos "{" y "}". La precondicin y la postcondicin son los asertos que se tienen que cumplir al inicio y a la nalizacin, respectivamente, del algoritmo. Podremos escribir tantos asertos entre las sentencias de un algoritmo como se considere conveniente y constituyen comentarios valiosos para la comprensin del algoritmo. Evaluacin de un predicado Para evaluar un aserto, ste tiene que estar bien denido. Se dice que el aserto {P } est bien denido si se puede evaluar para todos los posibles valores de las variables libres que aparecen en P y, adems, todas las funciones que aparecen en P estn bien denidas. Sustitucin e Se denota por Px al resultado de sustituir en la frmula de P todas las apariciones libres de la variable x por la expresin e. Esta expresin debe cumplir las siguientes restricciones: (1) no puede contener variables ligadas de P y (2) ha <e1 ,..,en > e se generaliza a P<x de ser del mismo tipo de dato que x. La notacin Px 1 ,..,xn > para representar al predicado resultado de sustituir en P simultneamente, las apariciones de x1 , .., xn por las expresiones e1 , .., en .
Ejemplo: Sea P (z ) z.((1 < z < d x mod z = 0) d < x), entonces z 5 z.((1 < z < d 5 mod z = 0) d < 5), sin embargo Px x no es Px una sustitucin vlida, ya que z es una variable ligada.
Predicados ms fuertes y ms dbiles Un predicado P dene un conjunto de estados, aquellos estados en que el predicado se evale como Cierto. Se dice que un predicado P es ms fuerte (ms restrictivo) que otro Q, si el conjunto de estados representados por P es un subconjunto de los estados representados por Q. Formalmente, si se denota por estados(X ) el conjunto de estados que satisfacen el predicado X , se dice que P es ms fuerte que Q si estados(P )
1.3.
LGICA DE PREDICADOS
estados(Q). De igual forma se dice que P es ms dbil que Q si estados(P ) estados(Q). La notacin P Q expresa que P es ms fuerte que Q y, viceversa, que Q es ms dbil que P . Tambin diremos que Q es una deduccin lgica de P .
Reforzamiento de un predicado Consiste en aadirle una conjuncin con otro predicado ( P Q P ). El predicado ms fuerte es F also ya que por mucho que se refuerce sigue siendo F also, (F also P F also) Debilitamiento de un predicado Consiste en aadirle una disyuncin con otro predicado. ( P P Q. Obviamente, si el predicado P es una conjuncin de predicados, cualquier predicado resultante de eliminar alguna de las conjunciones ser un debilitamiento de P . El predicado ms dbil es Cierto ya que por mucho que se debilite sigue siendo Cierto, (Cierto P Cierto). Otra forma de debilitar un predicado es realizar una sustitucin en el predicado de una constante por una variable, sta con un dominio de valores, donde la constante sea uno de los valores del dominio. En una especicacin pre/post se deben especicar la precondicin ms dbil y la postcondicin ms fuerte posibles. Axioma Es una propiedad que no necesita ser demostrada (a = a). Regla de inferencia Es una forma de deducir unas propiedades de otras que se suponen ciertas. La notacin que se emplear para enunciar una regla de inferencia es la sigu1 ,E2 ,...,En iente E F1 ,F2 ,...Fm , que se leer "si se cumplen (evalan a Cierto) E1 , E2 , ..., En , tambin se cumplirn F1 , F2 , ...Fm . Clculo de predicados Consiste en el razonamiento sobre predicados partiendo de la leyes de equivalencia (los axiomas) y de dos reglas de inferencia bsicas:
P2 ,P2 P3 Regla de transitividad. P1 P 1 P3
1 P2 Regla de sustitucin. Q(PP , siendo Q(P ) un predicado Q que 1 )Q(P2 ) tiene un subpredicado P .
Demostracin de la correccin de una deduccin lgica La demostracin de la correccin de una deduccin lgica P Q la podemos hacer, indistintamente, de tres formas bsicas:
1. Haciendo ver que el antecedente es ms fuerte que el consecuente. 2. Como cierto es el predicado ms dbil, evaluando el consecuente a cierto, aprovechando o no el cumplimiento de los predicados del antecedente.
CAPTULO 1.
ESPECIFICACIN DE PROBLEMAS
3. Realizando equivalencias y deducciones lgicas, partiendo del antecedente o parte de l, hasta llegar a un predicado que sea el mismo que el consecuente. Vamos a ver la aplicacin de las tres formas bsicas a un ejemplo sencillo,
x > 0 x < 100 x > 0
1. x > 0 x < 100 x > 0 es una deduccin (lgica) correcta, ya que el consecuente es un debilitamiento del antecedente. 2. Para que se cumpla el antecedente se tiene que cumplir x > 0, por tanto el consecuente se evala a cierto lo que hace que la deduccin sea correcta por ser cierto el predicado ms dbil. 3. Partiendo del predicado x > 0 del antecedente realizamos la siguiente deduccin lgica trivial x > 0 x > 0. La utilizacin de una u otra forma depender de la forma deduccin y de las preferencias particulares de cada uno.
El nombre de la funcin o de la accin. Sus parmetros formales. Especicar la precondicin. Especicar la postcondicin.
La especicacin se har utilizando la notacin {Q}S {R} 2. Derivar el algoritmo. 3. Vericar la correccin del algoritmo derivado.
1.4.1 Deniciones
En lo siguiente se denotar por C tanto una instruccin, como una secuencia de instrucciones , incluso, todo un algoritmo.
Correccin parcial Se dice que un cdigo C es parcialmente correcto con una precondicin Q y una postcondicin R, que se denota por {Q}C {R}, si comienza en un estado que satisface Q, en caso de que termine, lo hace en un estado que satisface R.
1.4.
Correccin total Cuando C , adems de ser correcto parcialmente, termina. Relacin entre correccin parcial y total Si C no contiene bucles ni tiene recursividad y es correcto parcialmente, tambin lo es totalmente. En caso contrario, para demostrar la correccin total de C , adems de demostrar su correccin parcial, habr que demostrar que termina. Invariante de un bucle La derivacin y la vericacin de las instrucciones de un bucle se apoya en el concepto de invariante. Se llama invariante de un bucle a un aserto P que describe todos los estados por los que atraviesan las variables del bucle, observados justo antes de evaluar la condicin B de terminacin del bucle. Concretamente, el invariante se tiene que cumplir antes y despus de cada iteracin, en particular, antes de la primera y despus de la ltima. Por tanto, el invariante es, a la vez, precondicin y postcondicin del bucle.
Si por ejemplo, se tiene el siguiente segmento de cdigo
i := 0; q := 0; p := 1 mientras i < n hacer i := i + 1; q := q + p; p := p + 2 fmientras
si se listan los estados del algoritmo antes de cada iteracin se tendran los siguiente valores: estado
P0 P1 P2
. . .
0 1 2 . . .
0 1 4 . . .
1 3 5 . . .
se ver una forma de obtener el invariante de un bucle sin tener que listar los valores que iran tomando las variables.
10
CAPTULO 1.
ESPECIFICACIN DE PROBLEMAS
Captulo 2
Sirven para introducir asertos ms fuertes/dbiles. La primera de estas reglas dice que siempre se puede fortalecer la precondicin y la segunda que siempre se puede debilitar la postcondicin.
Esta regla dice que siempre se pueden componer las precondiciones y las postcondiciones si se hacen ambas con el mismo operador o . 11
12
CAPTULO 2.
Este regla dice que At x es precondicin para que la ejecucin de la instruccin x := t lleve a un estado que cumpla su postcondicin A. Dicho de otra forma, despus de ejecutarse una instruccin x := t, x satisface la misma propiedad que t satisfaca antes de la asignacin. Esta regla proporciona la forma de obtener la precondicin ms dbil de un segmento de cdigo. Se denotar por pmd(C, A), a la precondicin ms dbil que garantice que la ejecucin de C lleve a un estado que satisfaga A. Los siguientes son ejemplos de precondiciones ms dbiles.
{x + y = 10}x := x + y {x = 10} {j.(x = 2j )}z := x{j.(z = 2j )}. x+y En efecto, en el primero {x = 10}x x + y = 10 x y en el segundo {j.(z = 2j )}z j.(x = 2j )
t Q Rx {Q}x := t{R}
Adems, de esta regla y de la de reforzamiento de la precondicin se deduce la siguiente regla: que da la forma de demostrar la correccin de {A}C {B }, que consiste en demostrar la correccin de A pmd(C, B ).
Esta regla sirve para razonar con secuencias de instrucciones. La regla dice que dos instrucciones S1 y S2 , en este orden, satisfacen una especicacin con precondicion Q y postcondicin R, si existe un aserto intermedio P , que sea postcondicin de la primera y precondicin de la segunda.
Instruccin de seleccin
{Q B }S1 {R}, {Q B }S2 {R} {Q Dom(B )}Si B entonces S1 si_no S2 fsi{R}
donde Dom(B ) es la expresin que dene el conjunto de estados en los que se puede evaluar la expresin B . Esta regla dice que para demostrar que la instruccin Si B entonces S1 si_no S2 fsi, satisface una especicacin con precondicion Q y postcondicin R, si se demuestra que son correctas
2.1.
13
La regla particularizada para una instruccin de seleccin con una rama vaca es:
{Q B }S {R}, Q B R {Q Dom(B )}Si B entonces S fsi{R}
Funcin cota o limitadora de un bucle Las dos condiciones anteriores no garantizan que el bucle termine. Por tanto, adems, habr que asegurarse de la terminacin del bucle. Para ello, se tiene que encontrar una expresin del no de iteraciones que realiza el bucle, en funcin de algn estado de cmputo, y demostrar que:
1. Esa expresin se evala a un nmero entero positivo y, por tanto, tiene una cota inferior. 2. El valor de la expresin decrece estrictamente en cada iteracin. La bsqueda de esa expresin se basa en el concepto de f uncinlimitadora. Una funcin limitadora t : estado Z
es una funcin que a cada estado del algoritmo da un nmero entero, se mantiene no negativa en cada iteracin y decrece en cada iteracin.
Instruccin Mientras
14
CAPTULO 2.
Las reglas para los bucles Repetir hasta y Desde hasta Hacer no se formulan ya que ambos bucles se pueden transformar en un bucle Mientras.
2.2.
15
{x = X y = Y AB = u + xy }I {x = X div 2 y = 2 Y AB = u + xy } siguiendo un planteamiento similar al del punto anterior. Se plantea la deduccin x = X y = Y AB = u + xy pmd(I, x = X div 2 y = 2 Y AB = u + xy ), si se propone I < x, y >:=< X div 2, 2 Y >, la deduccin queda x = X y = Y AB = u + xy pmd(< x, y >:=< X div 2, 2 Y >, x = X div 2 y = 2 Y AB = u + xy ),
es decir,
x = X y = Y AB = u + xy div {x = X div 2 y = 2 Y AB = u + xy }<X <x,y>
2 ,2 Y >
, operando queda
simplicando queda
x = X y = Y AB = u + xy X div 2 = X div 2 2 Y = 2 Y AB = u + (X div 2) 2 Y , que x = X y = Y AB = u + xy AB = u + (X div 2) 2 Y , y operando AB = u + XY AB = u + (X div 2) 2 Y , es decir se tendra que cumplir
XY = (X div 2) 2 Y
Al ser div la divisin entera esa igualdad solo se cumple cuando X es par. Cuando X es impar se sabe que (X div 2) 2 = X 1. Es decir, en caso de ser impar, se cumplir que XY = (X div 2) 2 Y + Y . Luego, si se suma Y a la variable u se cumplira que: u + XY = (u + Y ) + (X div 2) 2 Y , que es la igualdad que quedara para demostrar que la instruccin I necesaria, en caso de que X fuese impar, es < x, y, u >:=< X div 2, 2 Y, u + Y > Es decir, la conclusin de este razonamiento es que la instruccin I necesaria se concretara en:
Si X es par entonces <x,y>:= <X div 2,2* Y> si no <x,y,u>:= <X div 2,2* Y,u+Y> fsi.
Esta instruccin se puede simplicar en la siguiente:
Si X es impar entonces
16
CAPTULO 2.
donde:
Q es la precondicin de las sentencias anteriores al bucle, que se denotan
por Inic . R es la postcondicin del bucle. P es el invariante del bucle. B es la condicin de entrada en el cuerpo del bucle. El cuerpo del bucle est constituido por las instrucciones denotadas por:
Avanzar que representa a las instrucciones que hacen que las variables que intervienen en la expresin B avancen hacia la condicin de salida del bucle, es decir hacia B . Restablecer que representa a las instrucciones que modican las variables libres del invariante no modicadas por Avanzar.
T es un aserto intermedio, que habr que calcular una vez concretada Avanzar, cuya utilidad es facilitar el clculo de Restablecer.
Para no repetir la escritura del invariante P , en los puntos donde se debe cumplir: 1,2,3 y 4, ste se escribir una sola vez a continuacin de la palabra clave hacer. Adems del invariante, en los siguientes puntos se deber cumplir:
En el 2, B , es decir P B .
2.2.
17
En el 4, B , es decir P B .
Si P B T , entonces no es necesaria Restablecer. Si no, proponer que el resto de la variables libres de P se modiquen asignndoles unas expresiones que habr que calcular. Para ello se plantea la deduccin P B pmd(Restablecer, T ) y se ve cmo tienen que ser esas expresiones para que la deduccin sea correcta. Derivacin de bucles en secuencia y anidados
Si se necesitan varios bucles, se deriva cada uno por separado. Si se necesitan bucles anidados, se deriva cada uno por separado em-
Heurstica para obtener invariantes a partir de la postcondicin Se basa en las propiedades que se deben cumplir:
Cuando termina el bucle, se cumplir P B y tambin R, por tanto P B R. Mientras se itera, algunos estados de P no pertenecern a R. Por lo que la idea es que debilitando R se puede llegar a P .
Se toma como P el operando, R1 R2 , en el que sea ms fcil dar valores a sus variables libres que hagan que se cumpla, y el otro como B .
18
CAPTULO 2.
Construir R1 , sustituyendo en R expresiones (suelen ser constantes) por nuevas variables w. Si se hace que R2 sea la ecuacin de sustitucin w = (x), se cumplir que R R1 R2 . Se toma R2 como B y R1 Dom(w) como P .
El siguiente ejemplo ilustra la derivacin de algoritmos iterativos.
Qn0
1. Postcondicin en forma conjuntiva Como, en este caso, R no est en forma conjuntiva, se sustituye en ella la constante n por la variable x. Por tanto R r = x =0 x = n. El dominio de x ser 0 x n. Con lo hecho hasta ahora:
el invariante ser P r = x =0 0 x n y la condicin de salida del bucle B x = n.
2. Obtencin de la condicin del bucle B (B ) (x = n) x = n, pero teniendo en cuenta el dominio de x se puede dejar como x<n. 3. Obtencin de Inic Inic debe hacer correcta {n 0}Inic{r = x =0 }. Se ve que los valores de las variables libres de P (x y r ) que hacen que ste se cumpla son 0, en ambas. Por tanto se propone que Inic se concrete x:=0;r:=0. Es obvio que: <0,0> n 0 {r = x =0 0 x n}<x,r> , ya que al evaluarse la parte derecha como Cierto, n 0 Cierto es una deduccin correcta. 4. Obtencin de Avanzar Como el bucle termina cuando x = n y x se inicializa a 0, parece razonable suponer que en cada iteracin se incremente el valor de x en 1. Por lo que se propone x:= x+1. 5. Obtencin de Restablecer Previamente se calcula T .
x+1 T pmd(Avanzar, P ) pmd(x := x + 1, P ) Px +1 x+1 r = x r = x =0 0 x n}x =0 0 x + 1 n.
2.2.
19
Ya que Avanzar modica x, parece razonable suponer que Restablecer modique la otra variable, r, asignndole un valor que se expresa por Er , es decir, tendr la forma r := Er .
Er pmd(Restablecer, T ) pmd(r := Er , T ) Tr +1 Er = x =0 0 x + 1 n. Er Luego debe ser correcta P B Tr , es decir, x+1 r = x =0 0 x n x < n Er = =0 0 x + 1 n.
e introduciendo x + 1 en el sumatorio
+1 x+1 x =0 = =0 0 x + 1 n,
Cierto 0 x + 1 n Cierto ya que la expresin 0 x + 1 n es Cierta porque en el antecedente de la deduccin se tiene que 0 x n x < n 0 x < n, y es evidente que 0 x < n 0 x + 1 n es una deduccin correcta.
Con lo que Restablecer se concreta en la instruccin r:=r+x+1. Con todo lo anterior el algoritmo obtenido ser el siguiente:
{Q n 0}
fmientras un
{R r = n =0 }
20
CAPTULO 2.
mientras B hacer{P }
Restablecer {T } Avanzar
fmientras
{R } F in {R }
y se vericarn por separado, si tuviese bucles anidados, se vericara el ms interior y se tratara como una caja negra en el bucle externo superior.
Un aspecto crucial para la vericacin es encontrar el invariante del bucle, si ste no viene ya dado. Las ideas bsicas que guan esta bsqueda son las siguientes:
Debe ser sucientemente fuerte para que junto con B lleve a R . Debe ser sucientemente dbil para que Inic haga que se cumpla y despus de la ejecucin de S se mantenga la invarianza.
Los pasos para vericar un algoritmo iterativo son los siguientes: 1. Obtencin de la postcondicin del bucle El punto de partida es R.
Si F in no tiene contenido entonces R R. Si lo tiene, R pmd(F in, R).
2. Proponer el invariante y la funcin de cota del bucle En el caso de que no vengan dados. Para ello se utilizan las mismas heursticas presentadas en derivacin.
2.3.
21
3. Satisfaccin de la postcondicin del bucle Comprobar que cuando se sale del bucle se llega a un estado que satisface R ,(P B R ). 4. Satisfaccin inicial del invariante Comprobar el cumplimiento del invariante a la llegada al bucle ({Q}Inic{P }). 5. Mantenimiento de la invarianza en cada iteracin Comprobar de que despus de cada iteracin se mantiene la invarianza ({P B }S {P }). 6. Cota inferior positiva Comprobar que la funcin cota tiene una cota inferior (P B t 0). 7. Decrecimiento del nmero de iteraciones Comprobar que el bucle termina ({P B t = T }S {t < T }). Aunque los pasos 3, 4, 5, 6 y 7 se pueden realizar en cualquier orden, conviene probar primero los pasos 3 y 4 (los lmites del bucle). Si falla la vericacin de los pasos 3 y 4, suele ser porque el invariante no es el apropiado. Ejemplo: Vericar el siguiente algoritmo que resuelve el problema de la suma de los n primeros nmeros naturales.
{Q n 0}
fmientras un
{R r = n =0 }
1. Obtencin de la postcondicin del bucle Como F in no tiene contenido R R . 2. Proponer el invariante La obtencin de la funcin limitadora t se pospone hasta la vericacin de los puntos 6 y 7. Teniendo en cuenta que, al ser B x < n e incrementarse en 1 x en cada iteracin, la condicin de salida del bucle B ser x = n, por lo que se propone que:
P r = x i=0 i 0 x n
22
CAPTULO 2.
Operando en el antecedente,
n r = x =0 0 x n x = n r = =0 0 n n,
donde se ve que el antecedente es ms fuerte que el consecuente; por tanto, la deduccin es correcta. 4. Satisfaccin inicial del invariante
{Q}Inic{P }). En este caso,
0 = 0 =0 0 0 n 0 = 0 0 0 n cierto 0 0 n 00n0n
2.3.
23
x+1 r = x =0 0 x n x < n r + x + 1 = =0 0 x + 1 n,
introduciendo x + 1 en el sumatorio,
x+1 x+1 r = x =0 0 x n x < n =0 = =0 0 x + 1 n,
operando sucesivamente
r = x =0 0 x n x < n cierto 0 x + 1 n r = x =0 0 x n x < n 0 x + 1 n.
Esta deduccin es correcta, ya que, al cumplirse el operando subrayado es correcta la siguiente deduccin: 0 x n x < n 0 x + 1 n. 6. Cota inferior positiva (P B t 0). Primero, se realiza el clculo pospuesto de la funcin limitadora. Aplicando la heurstica indicada anteriormente se propone como funcin limitadora t n x. Luego en este caso:
r = x =0 0 x n x < n n x 0.
Es evidente que si x < n entonces n x 0, luego la deduccin es correcta. 7. Decrecimiento del nmero de iteraciones Para que {P B t = T }S {t < T } sea correcta, deber ser correcta
P B t = T pmd(S, t < T )
+1 r +x+1 pmd(S, t < T ) {{n x < T }x }r x
24
CAPTULO 2.
n (x + 1) < T . n x 1 < T,
Captulo 3
{Q(x)}
{R(x, y )}
donde, adems de la precondicin, postcondicin y especicacin de la interfaz, los elementos del lenguaje algortmico recursivo que se utilizan son los siguientes:
Bt (x) es la condicin del caso trivial. triv (x) es la solucin del caso trivial. Bnt (x) es la condicin del caso no trivial. s(x) denota al conjunto de parmetros con los que se llama a la funcin
desde el propio algoritmo. A estos parmetros se les llamar parmetros sucesores de los actuales. c(x, f (s(x)) es la solucin del caso no trivial, siendo c 1 la funcin de combinacin de los parmetros actuales x con los resultados de la llamada a la funcin con los parmetros sucesores de los actuales f (s(x)) .
1 La funcin de combinacin que en la forma abstracta se ha escrito en notacin preja, se puede escribir igualmente en las notaciones postja e inja, esta ltima es la que se utilizar normalmente para las funciones artmeticas
25
26
CAPTULO 3.
[] es el separador de los casos. Adems, aunque no aparece explcitamente en la notacin, con (y ) se de-
Entendiendo que puede haber tantas estructuras de casos triviales y no triviales como necesite el algoritmo. Con esta notacin, el seudocdigo de la funcin factorial de un nmero n dado, se escribira de la forma siguiente:
{Q n 0}
{R r =
En el caso de una accin, es obvio que no tiene sentido hablar de funcin de combinacin El siguiente ejemplo muestra el seudocdigo del algoritmo recursivo para calcular el factorial de un nmero mediante una accin:
3.1.
27
{Q n 0}
fcaso
{R r =
n =1
Adems el lenguaje permite utilizar variables locales mediante la siguiente clusula Sea q =expresiones 1 en expresin 2 : donde:
q es una lista de una o ms variables locales, separadas por comas. expresiones 1 es una lista de una o ms expresiones, separadas por comas, cuya evaluacin es la asignacin inicial a cada una de las variables q . expresin 2 es una expresin donde aparecen cada una de las variables locales q .
fun suma(a : vector[1..n] de entero; i, j : entero) dev(s : entero) caso i > j a[i] [] i < j Sea m = (i + j ) div 2 en suma(a, i, m) + suma(a, m + 1, j ) fcaso un
28
CAPTULO 3.
{Q n 0}
No se tiene otra forma de partir el problema en problemas ms pequeos que la de partir el vector en vectores ms pequeos, pero eso signicara que cambiara el tipo del vector por lo que no se podra llamar recursivamente a sumaV. Pero si se piensa en una funcin con un parmetro adicional i,
{Q(x)}
3.2.
INMERSIN DE ESPECIFICACIONES
29
y adems calcular los valores wini , que hagan que f (x) = g (x, wini ), es decir, que f sea un caso particular de g . Vamos a ver dos tcnicas. La primera de ellas, inmersin no nal, lleva generalmente lleva al diseo de una funcin g recursiva no nal y la segunda, inmersin nal, siempre lleva al diseo de una funcin g recursiva nal. El punto de partida de ambas es la postocondicin R(x, y ). El convenio que se seguir para dar nombre a la funcin inmersora es preceder el nombre de la sumergida de una i cuando se haga una inmersin no nal y dos ies cuando se haga una inmersin nal.
{Q n 0 1 i n}
30
CAPTULO 3.
la solucin del caso trivial. Si R ya est en forma conjuntiva, es decir R R1 (x, w1 ) R2 (x, w1 ):
Elegir, entre R1 y R2 , aqul predicado en el que sea ms fcil dar valores a los parmetros w1 que hagan que se cumpla el predicado. Ese predicado reforzar la precondicin de la sumergida. El otro ser la condicin del caso trivial.
Si R no est o no se puede poner en forma conjuntiva:
Obtener R (x, w1 , w2 ), realizando una sustitucin w2 = (x, w1 ), de forma anloga a como se haca en el mtodo de inmersin no nal. R reforzar la precondicin de la sumergida. La ecuacin de sustitucin w2 = (x, w1 ) ser la condicin del caso trivial.
La precondicin ser el reforzamiento obtenido, junto a las condiciones de dominio que sea necesario poner a los nuevos parmetros w Los valores iniciales wini , que hacen que f (x) = g (x, wini ), sern aquellos
Se va a ilustrar la aplicacin de esta tcnica con el mismo ejemplo utilizado en la inmersin nal.
Se renombra enR s por ss, obteniendo R ss = n =1 v []. Como R no est en forma conjuntiva, se realiza la sustitucin i = n, obteniendo R ss = i =1 v []. La precondicicin de iiSumaV ser n 0 ss = i =1 v [] 1 i n
3.3.
31
Los valores iniciales ss = 0 e i = 0 cumpliran la precondicin si se admitiese que el dominio de valores de i, incluya el valor 0, por lo que se
Siendo la llamada inicial sumaV (v ) = iiSumaV (v, 0, 0). Adems se tiene ya un caso con condicin i = n y solucin trivial ss
3 obviamente, si se encontrase una solucin trivial, tambin se habra acabado, pero el algoritmo obtenido no sera recursivo
32
CAPTULO 3.
Habr veces que la tabla tendr que ser ms compleja para reejar situaciones de condiciones encadenadas. La siguiente podra la tabla de una situacin con dos casos, uno de ellos con dos subcasos.
Obtencin de casos triviales Una forma bsica de conseguir un caso trivial es ver qu valores deben tener alguno de los parmetros de entrada para anular el dominio de algn cuanticador que aparezca en la postcondicin, lo que, automticamente, llevar a la solucin trivial del caso. Tomando como ejemplo la especicacin de la funcin iSumaV (resultado del ejemplo de inmersin no nal), se puede ver que hay un caso trivial cuando i = n + 1, cuya solucin, al anularse el rango del , ser el elemento neutro de la suma, es decir 0. Como el valor n + 1 no pertenece al dominio de i que se deni en el paso 2, por conveniencia, habr que modicar el dominio para que i pueda valer n + 1.
Si se estuviese haciendo el anlisis por casos de la especicacin de la funcin iiSumaV (resultado del ejemplo de inmersin nal), se partira de que ya se tiene un caso trivial i = n con solucin ss.
Obtencin de casos no triviales La obtencin de una solucin no trivial consiste en obtener la ley de recurrencia, es decir la funcin de combinacin y los parmetros sucesores. Cuando se haga el planteamiento para calcular la ley de recurrencia, cada uno de los parmetros sucesores se podr: expresar que permanezca constante, proponer una expresin (si se tienen argumentos para hacer una propuesta) o expresarlo como una incgnita. Bsicamente, habr dos situaciones:
Cuando en la postcondicin aparezcan parmetros de entrada que puedan
variarse. Una buena estrategia es comparar el predicado de la postcondicin con el de la misma, pero cambiando en ella los parmetros de entrada por sus parmetros sucesores y los parmetros de salida por nuevos parmetros de salida, y ver si se pueden poner los parmetros de salida en funcin de los parmetros actuales y los nuevos de salida. Formalmente sera plantear R(x, y ), R(s(x), y ) y ver si se puede conseguir una funcin c tal que y = c(x, y ) Siguiendo con el ejemplo de la funcin iSumaV , la condicin del caso no trivial ser i = n + 1, pero, teniendo en cuenta las condiciones de dominio, se podr dejar como i < n + 1. Dado que, i empieza valiendo 1 y termina
3.3.
33
valiendo n + 1, parece lgico proponer como sucesor de i a la expresin i +1. El sucesor del parmetro a, no puede ser otro que l mismo. Al nuevo resultado se le llamar s . Comparando la postcondicin s = n =i v [] con la misma para los parmetros sucesores y la nueva salida s = n =i+1 v [], se puede deducir que s = s + v [i]. Dado que se ha encontrado la ley de recurrencia para el caso i < n +1 se da por terminado el anlisis por casos.
Cuando en la postcondicn slo aparezcan parmetros de entrada que no
puedan modicarse.
Esa es una situacin con postcondicin constante, por tanto, no habr funcin de combinacin y lo nico que habr que calcular son las expresiones de los parmetros sucesores, de los de entrada que no aparezcan en la postcondicin. Para ello se utilizar la propiedad de que la precondicin se debe cumplir tanto en la llamada externa como en las internas. Formalmente eso signica que deber ser correcta la deduccin
Q(x) Bnt (x) Q(s(x))
En el ejemplo de la funcin iiSumaV , se plantea un caso no trivial cuya condicin, teniendo en cuenta las condiciones de dominio de i, ser i < n. Como la postcondicin es constante, ya que n es el lmite superior del ndice del vector, se plantea la siguiente deduccin:
n 0 ss = i =1 v [] 0 i n i < n
+1 n 0 suc(ss) = i =1 v [] 0 i + 1 n
(Se ha propuesto que el sucesor de i sea i + 1, ya que su valor inicial es 0 y su valor nal es n; el de ss se ha dejado como incgnita y el de n debe ser l mismo). Si se desarrolla el del consecuente, ste queda por su valor en el antecedente, el consecuente queda del consecuente.
n 0 suc(ss) = i =1 v [] + v [i + 1] 0 i + 1 n, sustituyendo el
n 0 suc(ss) = ss + v [i + 1] 0 i + 1 n, que directamente da la expresin de suc(ss) para que se evale a cierto el segundo conjuntando
Se deja como ejercicio para el lector la demostracin de que los otros dos conjuntandos del consecuente tambin se evalan a cierto. La tabla resultante para el anlisis por casos de la funcin iSumaV sera la siguiente
Condicin
i=n+1 i<n+1
Solucin 0
v [i] + iSumaV (v, i + 1)
34
CAPTULO 3.
Condicin
i=n i<n
Solucin
ss iiSumaV (v, ss + v [i + 1], i + 1)
Aunque, una vez hecha la composicin algortmica, habr que vericar formalmente el algoritmo derivado, hay tres comprobaciones importantes que es conveniente realizar informalmente en este paso:
Comprobar informalmente que los parmetros sucesores en las soluciones
Comprobar que entre todos los casos cubren todos los estados previstos Comprobar que los casos sean mutuamente excluyentes.
Se deja como ejercicio para el lector la realizacin de las comprobaciones para la tabla de la funcin iiSumaV .
fun iSumaV (v : vector[1..n] de entero; i : entero) dev(s : entero) caso i = n + 1 0 fcaso un
[] i < n + 1 v [i] + iSumaV (v, i + 1)
{Q n 0 1 i n }
{R s = n =i v []}.
3.4.
VERIFICACIN FORMAL
35
fun iiSumaV (v : vector[1..n] de entero; ss, i : entero) dev(s : entero) caso i = n ss fcaso un
[] i < n iiSumaV (v, ss + v [i + 1], i + 1)
{R s = n =1 v []}.
Declaracin de variables locales En algunas situaciones ser conveniente introducir declaraciones de variables locales para evitar clculos repetidos. Tomando como ejemplo la siguiente tabla, que resume el anlisis por casos de una funcin potEf cte para calcular la potencia n -sima de un nmero a, de una forma ms eciente que la bsica Condiciones
n=0 n>0 n mod 2 = 0 n mod 2 = 1
Solucin 1
(an div 2 ) (an div 2 ) a (an div 2 ) (an div 2 )
caso n = 0 1 [] n > 0 caso n mod 2 = 0 potEf cte(a, n div 2)potEf cte(a, n div 2) [] n mod 2 = 1 apotEf cte(a, n div 2)potEf cte(a, n div 2) fcaso fcaso
Donde se ve que se puede ahorrar el llamar dos veces a la funcin y, adems, calcular en cada llamada el resultado de la expresin n div 2, si se hace una declaracin de una variable local p que recoja el resultado de potEf cte(a, n div 2), quedando la siguiente expresin del algoritmo:
caso n = 0 1 [] n > 0 sea p = potEf cte(a, n div 2) en caso n mod 2 = 0 p p [] n mod 2 = 1 a p p fcaso fcaso
36
CAPTULO 3.
La tcnica bien conocida de demostracin basada en el principio de induccin sobre los nmeros naturales se puede expresar mediante la siguiente regla de inferencia:
P (0), N.(P () P ( + 1)) N.P ()
Es decir para demostrar la propiedad P (n) basta con demostrar la propiedad para n = 0, P (0) (base de la induccin), y que el cumplimiento de P para cualquier nmero natural implica el cumplimiento para el nmero siguiente + 1 (recurrencia). La regla anterior se puede generalizar a la siguiente:
P (0), N.(( [0, 1].P ( )) P ()) N.P ())
Dado que P (0) est incluido en el predicado N.(( [0, 1].P ( )) P ()), la regla se puede simplicar a la la siguiente:
N.( [0, 1].P ( )) P ()) N.P ()
El principio de induccin sobre el conjunto de los nmeros naturales se puede generalizar sobre otras estructuras de datos que sean prerdenes bien fundados (pbf ). Si se tiene un conjunto D sobre el que se dene una relacin binaria , se dice que (D, ) es un preorden si los elementos de D cumplen las propiedades reexiva ( D. ) y transitiva (, , D.( ) ( ) ( )). Los siguientes son ejemplos de preordenes:
Los nmeros naturales con la relacin (N, ). Los nmeros enteros con la relacin (Z, ). El conjunto de las cadenas de caracteres con la relacin de orden alfabtico (orden_alf abetico ) denida como c1 orden_alf abetico c2 si y solo si la cadena c1 es igual o precede alfabticamente a la cadena c2
Se dice que en un preorden (D, ) x precede estrictamente a y (x y ), cuando se cumple que (x y ) (y x). Una sucesin de elementos x1 , x2 , x3 , . . . de un preorden (D, ) es estrictamente decreciente, si para todo par xi , xi+1 de elementos consecutivos de la sucesin se tiene que xi+1 xi . Un preorden (D, ) es noetheriano si no existen sucesiones innitas estrictamente decrecientes en D. Dado un preorden (D, ), se dice que x D es un minimal si no hay otro elemento en D que preceda estrictamente a x. Un preorden (D, ) es un pbf si en D hay al menos un minimal. Todo pbf es noetheriano y viceversa.
3.4.
VERIFICACIN FORMAL
37
pbf, ya que todo nmero entero tiene otro que le precede estrictamente. S es un pbf el conjunto de los enteros en el intervalo [0, ] con la relacin . El principio de induccin es vlido en un pbf (D, ), es decir, si P es una propiedad sobre los elementos de D, se cumple que:
D.( D. < P ( )) P () D.P ()
Cuando se est analizando un algoritmo no es inmediato encontrar un pbf para poder aplicar el principio de induccin. Sin embargo, s se podr denir induciendo un pbf sobre un conjunto D a partir de otro preorden (D, ) conocido, como puede ser el preorden (N, ). Sea D un conjunto cualquiera, (D , c ) un pbf y f una funcin de D en D (f : D D ). Entonces (D, c ) ser un pbf si se se dene de la siguiente forma:
x, y D.(x c y f (x) c f (y ))
A continuacin se presentan algunos ejemplos de denicin de un pbf sobre el conjunto N N , deniendo diversas funciones f : N N N :
(x , y 1 (x, y ) x x) (x , y 2 (x, y ) y y ) (x , y 3 (x, y ) (x + y ) (x + y ))
En cambio (x , y 4 (x, y ) (x y ) (x y )) no es un pbf, ya que la resta de dos naturales puede que no sea otro natural. Otro ejemplo es el siguiente: siendo Csec el conjunto de las secuencias de datos de un determinado tipo de dato y s1 , s2 dos secuencias cualesquiera de dicho conjunto, (Csec , lsec ) es un pbf, deniendo la relacin binaria lsec de la forma:
s1 , s2 Csec .(s1 lsec s2 longitud(s1 ) longitud(s2 )
Las funciones de cota que se utilizan para demostrar la terminacin tanto de bucles como de secuencias de llamadas recursivas son una aplicacin de esta forma de inducir pbf s. Al igual que en los algoritmos iterativos, para vericar la correccin total de un algoritmo recursivo habr que demostrar que:
Es correcto parcialmente. Termina.
38
CAPTULO 3.
Ntese que si solo hay dos casos Bnt (x) Bt (x) 2. Satisfaccin de la precondicin en la llamada interna Una solucin no trivial realiza una llamada al algoritmo con unos parmetros que cumplen la precondicin.
Q(x) Bnt (x) Q(s(x))
(En este punto se deben realizar tantas demostraciones como casos no triviales haya) 3. Hiptesis de la induccin Una solucin trivial cumple la postcondicin.
Q(x) Bt (x) R(x, triv (x))
(En este punto se deben realizar tantas demostraciones como casos triviales haya) 4. Paso de induccin Una solucin no trivial cumple la postcondicin, supuesto conocida la solucin a la llamada recursiva.
Q(x) Bnt (x) R(s(x), y ) R(x, c(x, y ))
(En este punto se deben realizar tantas demostraciones como casos no triviales haya) Con esto quedara demostrado que el algoritmo es correcto parcialmente.
Vericacin de la terminacin del algoritmo Para vericar que un algoritmo recursivo no pueda entrar en una sucesin innita de llamadas recursivas, se tendr que encontrar una funcin cota t que cumpla unas propiedades similares a las exigidas para algoritmos iterativos. Es decir:
Se debe mantener positiva en todas y cada una de las llamadas al algoritmo
recursivo. Cada vez que se hace una llamada recursiva el valor de la funcin decrece estrictamente. La heurstica para encontrarla es la misma que la utilizada para algoritmos iterativos. La funcin cota t deber cumplir que:
3.4.
VERIFICACIN FORMAL
39
2. Decrece estrictamente en cada llamada interna (Decrecimiento del tamao del problema).
Q(x) Bnt (x) t(x) > t(s(x))
Lo que hace un total de 6 propiedades a demostrar. A continuacin se ilustra la demostracin de estas seis propiedades con el ejemplo de la funcin factorial de la seccin ??. En cada unos de los puntos se van identicando las expresiones necesarias an no identicadas. La demostracin de la correccin de una deduccin, se puede hacer de tres formas distintas:
Identicar predicados en el antecedente y en el consecuente donde se vea
claramente que el antecedente es ms fuerte que el consecuente. Sustituir expresiones del antecedente en el consecuente y evaluar el consecuente como cierto, que al ser el predicado ms dbil har que la deduccin sea correcta. Partiendo de todo o parte del antecedente, realizar deducciones lgicas hasta llegar a una que sea el consecuente
Q(x) Bt (x) Bnt (x)) Q(x) n 0 Bt (x) n = 0 Bnt (x)) n > 0
=0 n>0
Como en ambos lados aparece el mismo predicado, se puede decir que el antecedente es ms fuerte que el consecuente. Por tanto, esta deduccin es correcta. 2. Satisfaccin de la precondicin en la llamada interna
Q(x) Bnt (x) Q(s(x))
40
CAPTULO 3.
s(x) n 1 Q(s(x)) (n 1) 0
? n 0 n > 0 (n 1) 0
cin es correcta por ser el predicado del antecedente ms fuerte que el del consecuente. 3. Hiptesis de la induccin
Q(x) Bt (x) R(x, triv (x)) triv (x) 1 R(x, triv (x)) 1 =
? n 0 n = 0 1 = n =1
valor en el antecedente:
1=
0 =1
n =1
ms dbil.
4. Paso de induccin
Q(x) Bnt (x) R(s(x), y ) R(x, c(x, y )) y r R(s(x), y ) r = c c(x, y ) n r R(x, c(x, y )) n r =
n =1 n1 =1
3.5.
INMERSIN DE ALGORITMOS
41
n
n1
n 0n > 0r =
Q(x) Bnt (x) =1
? nr = =1 R(x,c(x,y ))
R(s(x),y )
n =1
n =1
n =1
Cierto. La deduccin es correcta por ser Cierto el predicado ms dbil. 5. Estructura de preorden bien fundado Se propone como funcin cota t n, con lo que: Q(x) t(x) 0
? n 0 n 0 (trivial)
42
CAPTULO 3.
La tcnica tiene tres pasos: 1. Generalizacin. Se dene la funcin inmersora de f (x) de la siguiente manera: g (x, w) = c(f (x), w), siendo c la funcin de combinacin de la solucin no trivial de f . Es evidente que, si c tiene elemento neutro w0 , g (x, w0 ) = c(f (x), w0 ) = f (x). Por tanto, w0 sern los valores iniciales de los nuevos parmetros w que hacen que la funcin inmersora simule a la sumergida. 2. Desplegado. Se despliega el algoritmo de f (x) en la denicin de g (x, w). Es decir, g (x, w) = c(f (x), w) = c( caso Bt (x) triv (x)
[] Bnt (x) c(f (s(x), x))
fcaso
3. Plegado. Se pliega el algoritmo de acuerdo a la denicin de g (x, w) = caso Bt (x) c(triv (x), w)
[] Bnt (x) g (s(x), c(x, w))
fcaso
La precondicin de la funcin inmersora ser la de la sumergida en conjuncin con las condiciones de dominio de los nuevos parmetros, es decir Q (x, w) Q(x Dom(w). En cuanto a su postcondicin, sta viene dada por la denicin de la funcin, es decir, R (x, w, y ) y = c(f (x), w) Se va a ilustrar la aplicacin de sta tcnica al algoritmo de la funcin factorial
3.5.
INMERSIN DE ALGORITMOS
43
1. Generalizacin. Se dene iiF actorial(n, w) = w F actorial(n), como 1 es el elemento neutro de la multiplicacin, iiF actorial(n, 1) = F actorial(n). Es decir 1 ser el valor inicial de w que hace iiF actorial(n, w) simule a
F actorial(n)
2. Desplegado. Se despliega el algoritmo de F actorial en la denicin de iiF actorial. Es decir, iiF actorial(n, w) = w F actorial(n) = w (caso n = 0 1
[] n > 0 n F actorial(n 1)
fcaso)
= caso n = 0 w 1
[] n > 0 w (n F actorial(n 1))
fcaso
3. Plegado. Se pliega el algoritmo de acuerdo a la denicin de iiF actorial(n, w)) = caso n = 0 w
[] n > 0 iiF actorial(n 1), w n)
fcaso
La postcondicin R w F actorial(n), que no tiene la caracterstica de postcondicin constante. La precondicin de la funcin ser la de F actorial, ya que no tenemos forma de imponer condiciones de dominio a w. Aunque se puede ver que en w se va acumulando el producto de los enteros entre el valor de n con el que se llame externamente a la funcin y el valor actual de n + 1, no hay forma de expresar esto, porque el algoritmo no recuerda el valor n inicial.
44
CAPTULO 3.
{Q n 0}
{R r = w
Si se aplicase sta tcnica al algoritmo recursivo no nal de iSumaV (n, i) para obtener iiSuma2 V (v, ss, i) (ejercicio que se deja para el lector) si se llamase ss al nuevo parmetro de inmersin, la postcondicin resultante sera
R r = ss + n =i v [] iiSuma2 V [v, 0, 1], podramos dejarla como R r = n =1 v [], y adems como
n r = ss + n =i v [] = =1 v [], si despejamos ss i1 n ss = n =1 v [] =i v [] = =1 v []. Condicin que imponemos en la
Cuando los algoritmos no son tan sencillos como el del ejemplo, ser de bastante ayuda, para la obtencin de la denicin de la funcin inmersora, construir el rbol sintctico de la solucin no trivial y realizar ciertas operaciones sobre. Vamos a ilustrar la obtencin de la denicin de iiF actorial con la ayuda del arbol sintctico de F actorial. 1. Se construye el rbol sintctico de la solucin no trivial
/ * \
Q n 0 1 i n + 1 ss = n =i+1 v []
/ n
\ Factorial | n - 1
3.5.
INMERSIN DE ALGORITMOS
45
El resultado sera
/ * \
\ Factorial |
\ Factorial | n
4. Escribir la denicin de la nueva funcin leyendo el rbol resultante. En este caso, iiF actorial(n, w) = w F actorial(n) Habr situaciones donde haya ms de una solucin no trivial. En ese caso habr que operar sobre el algoritmo para conseguir que haya un solo caso y que el nombre de la funcin solo aparezca una vez. Para ello, podemos ayudarnos de funciones auxiliares que no habr que implementar. Vamos a ilustrar estas situaciones con el algoritmo de la funcin potEf cte escrito al nal de la seccin 3.3. Como el nombre de la funcin no aparece explcitamente en ninguna de las dos ramas nos quedamos con la versin que no tiene declarada p , que reescribimos como sigue:
potEf cte(a, n) = caso n = 0 1 [] n > 0 caso n mod 2 = 0 [potEf cte(a, n div 2)]2 [] n mod 2 = 1 a [potEf cte(a, n div 2)]2
fcaso
fcaso
Si nos jamos vemos que la nica diferencia entre las dos soluciones no triviales es que la segunda es igual a la primera multiplicada por a, por lo que podemos pensar en una funcin auxiliar cond(a, n) =
46
CAPTULO 3.
fcaso que ya est en la forma que nos interesa. A continuacin se ilustra de forma resumida la denicin de iiP otEf cte
1. Construccin del rbol
*
/ cond / \ / \ a n
/ \ / \ potEfcte 2 / \ / \ a n div 2
\ ^
2. Poda
*
/ \ / \ potEfcte / \ / \
\ ^
3. Relleno
3.5.
INMERSIN DE ALGORITMOS
47
/ \ / \ potEfcte w / \ / \ a n
\ ^
4. La denicin de la funcin que sale de la lectura del rbol sera: establecer la siguiente igualdad
iiP otEf cte(a, n, u, w) = u [potEf cte(a, n)]w , donde se ve que se puede
En este caso, iiF actorial(n, w) = w F actorial(n) Se deja como ejercicio para el lector la aplicacin del resto de la tcnica, cuya solucin es la siguiente caso n = 0 u [] n > 0 caso n mod 2 = 0 iipotEf cte(a, n div 2, u, 2 w) [] n mod 2 = 1 iipotEf cte(a, n div 2, u aw , 2 w) fcaso fcaso
tintos a ellos mismos. Estos nuevos parmetros permanecern constantes a lo largo de todas las llamadas internas. con duplicado por su duplicado.
48
CAPTULO 3.
cin sobre los parmetros que varan implica la pstcondicin sobre los parmetros duplicados
Aplicando el mtodo al algoritmo de iiF actorial, resultante de aplicar la tcnica de desplegado y plegado al de F actorial:
Como los dos parmetros, n y w, varan, incorporamos dos nuevos parmetros N y W para recibir los valores iniciales de n y w, respectivamente. La postcondicin ser, por tanto, r = N ! W . El aserto para reforzar la precondicin ser r = n! w r = N ! W , es decir, n! w = N ! W
Como sabemos que el valor inicial de w y, por tanto, el de W es 1, podemos prescindir del duplicado. El algoritmo resultante ser el siguiente:
fun iiF actorial2 (n, w, N : entero) dev (r : entero) caso n = 0 w fcaso un
[] n > 0 iiF actorial(n 1, n w)
{Q n 0 n! w = N !}
{R r = N !}