Está en la página 1de 26

INTRODUCCIN

La lgica de Hoare es una extensin de la lgica de predicados de primer orden, esta


lgica nos es muy til a la hora de pasar a una verificacin formal de los programas.
Esta extensin se obtiene introduciendo un lenguaje de comandos con el que se
construyen los programas y una relacin especial para expresar el comportamiento de
un programa, as como un conjunto de reglas de clculo para la manipulacin de las
expresiones de comportamiento.
La verificacin formal es un mtodo de validacin esttica (se valida a travs del propio
cdigo del programa, a partir de una abstraccin o de una representacin simblica), en
el que partiendo de un conjunto axiomtico, reglas de inferencia y algn lenguaje lgico
(como la lgica de primer orden u otra de preferencia una lgica slida y completa, En
este caso, la lgica de Hoare), se puede encontrar una demostracin o prueba de
correccin de un programa.

DEFINICION:
Desarrollada por C.A.R. Hoare (1969), es una lgica que permite probar la verdad o
falsedad de propiedades de programas imperativos (especialmente correccin y
terminacin) sin concurrencia o paralelismo. Est basada en la idea de diagrama de
flujo anotado.

S es una frase de cdigo en un programa de alto nivel, con una nica entrada y
una nica salida normal.
o Instruccin.
o Bloque de instrucciones consecutivas.
o Un programa o subprograma.
Cada frase S denota una relacin entre dos estados en un espacio de estados
definido por el producto cartesiano de los valores de las variables del programa.
Es decir, al ejecutar una instruccin o secuencia de instrucciones S, se modifica
el valor de una o varias variables, transitando de un estado a otro.
P y Q son anotaciones, formulas de la Lgica de Primer Orden (Lgica de
Predicados).
o P Precondicin (se refiere al estado previo a S)
o Q Postcondicion (se refiere al estado posterior a S)
Notacin: {P }S{Q}
SIGNIFICA:

1. Correccin parcial: si la precondicin P es cierta antes de ejecutar la frase de


programa S, y la ejecucin termina normalmente, la postcondicion Q es cierta.
i. |=par {P }S{Q}
2. Correccin total: si la precondicin P es cierta antes de la ejecucin de la frase de
programa S, esta termina y la postcondicion Q es cierta.
i. |=tot {P }S{Q}

En la correccin parcial, la frase S debe terminar normalmente. Existen dos posibles


fuentes de terminacin anormal:

Bucle infinito.

Error de ejecucin (divisin entre cero, overflow)


Sentencias de correccin parcial En un programa real, aparecen declaraciones de
tipo y declaraciones de variables as como implementaciones de funciones (pueden
ser implementaciones incorporadas al sistema o hechas por el usuario) que
determinan la signatura del programa, adems el segundo argumento de un
comando de asignacin puede ser cualquier expresin del correspondiente tipo s
construida con constantes y funciones implementadas, y el primer argumento de un
comando de seleccin o de iteracin puede ser cualquier expresin del tipo BOOL.
En nuestros programas, aunque no vamos a considerar declaraciones de tipo ni de
variables, supondremos que existe una declaracin de signatura donde aparecen los
tipos y las constantes y funciones necesarias con propiedades conocidas, as como
una asignacin de tipo a cada variable de programa. Para expresar el
comportamiento de un programa normalmente se recurre a una signatura (S, )
ms amplia que la que se deriva del propio programa, incorporando tipos y
funciones auxiliares que no aparecen en el programa (pero que deben estar
debidamente especificados), y a una familia de variables V , tambin ms amplia
que la familia de variables de programa incorporando variables nuevas o variables
lgicas que tampoco aparecen en el programa, y se introduce una relacin especial

REGLAS GENERALES
Si R y S son dos aserciones entonces se dice que R es ms fuerte que S si R S. Si R es ms
fuerte que S entonces se dice que S es ms dbil que R. Ejemplo: i>1 es ms fuerte que i>0 ya
que siempre que i>1 esto implica que i>0. Por tanto i>1 i>0. Si una asercin R es ms fuerte
que una asercin S entonces todos los estados que satisfacen R tambin satisfacen S pero no
viceversa. Un fortalecimiento de la asercin disminuye el nmero de estados que la pueden
satisfacer. Ms fuerte ms selectivo, ms especfico. Ms dbil menos selectivo, ms
general. La asercin ms dbil es { } que recoge todos los estados posibles. Constante lgica V
(true). La asercin ms fuerte ser por tanto F (false), ya que representa que ningn estado
satisface dicha condicin.

Sentencias de correccin parcial


En un programa real, aparecen declaraciones de tipo y declaraciones de variables as como
implementaciones de funciones (pueden ser implementaciones incorporadas al sistema o
hechas por el usuario) que determinan la signatura del programa, adems el segundo argumento
de un comando de asignacin puede ser cualquier expresin del correspondiente tipo s
construida con constantes y funciones implementadas, y el primer argumento de un comando
de seleccin o de iteracin puede ser cualquier expresin del tipo BOOL. En nuestros
programas, aunque no vamos a considerar declaraciones de tipo ni de variables, supondremos
que existe una declaracin de signatura donde aparecen los tipos y las constantes y funciones
necesarias con propiedades conocidas, as como una asignacin de tipo a cada variable de
programa.
Para expresar el comportamiento de un programa normalmente se recurre a una signatura (S,
) ms amplia que la que se deriva del propio programa, incorporando tipos y funciones
auxiliares que no aparecen en el programa (pero que deben estar debidamente especificados), y
a una familia de variables V, tambin ms amplia que la familia de variables de programa
incorporando variables nuevas o variables lgicas que tampoco aparecen en el programa, y se
introduce una relacin especial
{} {} : F (V ) P RG F (V )
Con la que se expresan frmulas o sentencias de correccin parcial. Al primer argumento se le
llama precondicin y al tercero postcondicin; estos argumentos estn sujetos a una restriccin
sobre las variables de programa: dichas variables solo deben tener apariciones libres o, dicho de
otro modo, las variables de programa no deben aparecer cuantificadas.
La validez de estas frmulas se define del siguiente modo: { P }{Q} es vlida en una
interpretacin A, para un estado sta , o A |=sta {P }{Q}2 , si y slo si
A |=sta P y sta []A sta 0 implica A |=sta 0
Q

Esto significa que{P }{Q} ser vlida cuando la validez de la precondicin P en el


estado sta y el hecho de que cuando parte del estado sta termina en un cierto estado sta0
implique que la postcondicin Q es vlida para dicho estado final sta . De esta definicin se
deduce que una frmula {P }{Q} puede ser vlida en una interpretacin A, para un
estado sta por alguna de la circunstancias siguientes:
porque A |=sta P y cuando parte del estado sta termina en un estado sta 0
tal que A |=sta 0 Q;
porque A |=sta P , pero cuando parte del estado sta no termina (el
transformador []A no est definido en sta ), o
porque A |=sta P ;
Lo que significa que la validez de una frmula de correccin parcial no implica la
terminacin del correspondiente programa, y, en algunos casos, ni siquiera la validez de la
precondicin para el estado que se considera. {P }{Q} se dice que es vlida en la
interpretacin A cuando lo es para todos los estados definibles sobre A, en cuyo caso se
escribe A |= {P }{Q} y se dice que el programa es parcialmente correcto con
respecto a la especificacin (P, Q). Tambin se dice que (P, Q) es una especificacin parcial
de .

Fortalecimiento de las precondiciones


Si una parte de un cdigo es correcta bajo la precondicin {P}, entonces permanecer correcto
si se refuerza {P}.
Si {P}C{Q} es correcto y adems P1P entonces se puede afirmar que {P1}C{Q} es
correcto. Esto conduce a la siguiente regla de inferencia:
P1 P {P}C{Q}/{P1}C{Q}
Ejemplo: supongamos que la siguiente terna de Hoare es correcta: {y 0} x:=1/y {x=1/y},
demostrar que tambin lo es {y=4} x:=1/y {x=1/y}.
y=4 y 0
( {y 0} x:=1/y {x=1/y} ) / ( {y=4} x:=1/y {x=1/y} )
FORTALECIMIENTO DE LA PRECONDICIN VACA
La asercin vaca puede ser reforzada para producir cualquier precondicin {P} sea cual fuere.
Ejemplo: { } a:=b {a=b} se puede utilizar para justificar {P} a:=b {a=b} donde {P} puede
ser cualquier condicin imaginable.

Debilitamiento de las postcondiciones


Debilitar la postcondicin consiste en exigirnos menos. En su forma ms simple,
el mtodo consiste en sustituir la postcondicin por un debilitamiento suyo,
manteniendo la precondicin. Para debilitar la postcondicin usaremos las tcnicas ya
descritas, y con particular frecuencia las que incorporan nuevas variables en lugar de
subexpresiones.
Las igualdades suprimidas no han de olvidarse. en este caso, nos indicarn las
inicializaciones adecuadas para recuperar la funcin original a partir de la inmersin. En
cuanto a la precondicin, posiblemente sea necesario reforzarla con condiciones de
dominio sobre los nuevos parmetros. A veces, no es fcil predecir cules han de ser
stas, pero, si la verificacin y el diseo se realizan simultneamente, las propias
necesidades de la verificacin nos las proporcionan durante el desarrollo.
EL mtodo para encontrar un debilitamiento de la postcondicin consiste en hacer
aparecer en ella nuevos parmetros, aadiendo las igualdades que sean necesarias, y
debilitarla luego suprimiendo todas o algunas de ellas. La primera fase de adicin de
parmetros puede ser innecesaria cuando ya se tienen conjunciones, y por tanto
clusulas que suprimir.
Al escribir el programa, se ha de incorporar a la cabecera todos los parmetros de
inmersin: tanto los que figuran en el papel de los resultados, como los que hayamos
usado para crear conjunciones a suprimir. Las conjunciones suprimidas, que indican la
diferencia entre postcondicin y precondicin, se convertirn en protecciones del caso
directo, y los casos recursivos presentarn recursividad final.

El principio de debilitamiento de postcondiciones permite concluir que {P}C{Q1} una


vez que {P}C{Q} y Q Q1 hayan sido establecidos formalmente.
Esto conduce a la siguiente regla de inferencia: {P}C{Q} Q Q1 {P}C{Q1} .
Ejemplo: Si { } max:=b {max=b} es correcto.
Demostrar que se cumple: { } max:=b {max b} { } max:=b {max=b} max=b max
b { } max:=b {max b}

REGLAS
Conjuncin
La siguiente regla permite reforzar la precondicin y postcondicin de forma
simultnea.
Definicin: Si C es una parte de un cdigo y se ha establecido que
{P1}C{Q1} y {P 2}C{Q 2} se puede afirmar que {P1 P 2}C{Q1 Q 2}.
Formalmente esto se expresa como:

Como caso particular:

Ejemplo:
Aplicar las ternas { }i:=i+1 {i :=i +1}, {i >0 }i:=i+1 {i >0},
para demostrar que: {i>0 }i:=i+1 {i>1}

De donde: i :=i -1 y puesto que i >0 entonces i >1 por tanto:


{i>0 }i:=i+1 {i>1}

Disyuncin

La siguiente regla permite debilitar la precondicin y postcondicin de forma


simultnea.
Definicin: Si C es una parte de un cdigo y se ha establecido que {P1}C{Q1} y {P
2}C{Q 2} se puede afirmar que {P1 P 2}C{Q1 Q 2}. Formalmente esto se expresa
como:

Como caso particular:

ASIGNACION

Regla de la asignacin: Si C es una sentencia de la forma V:=E con la postcondicin


{Q}, entonces la precondicin de C puede hallarse sustituyendo todos los casos de V en
Q por E. Si Q E V es la expresin que se obtiene mediante esto, entonces:

Ejemplo: Determinar la precondicin para que la terna siguiente sea correcta:


{P} i:=2*i {i<3}

Ejemplo : Determinar la precondicin para que la terna siguiente sea correcta:


{ P} y:= x 2 {y>1}
{Q E V}={y =x *x , y >1} {x 2>1}

SENTENCIA IF (con clusula else)

Si C1 y C 2 son dos partes de un programa y si B es una condicin, entonces la


sentencia if B then C1 else C 2 s e interpreta de la siguiente forma: si B es verdadero
se ejecuta C1 sino C 2.
Si ahora se desea demostrar la correccin de una sentencia if con una precondicin
{P} y una postcondicin {Q} tendremos dos posibilidades: Si el estado inicial
satisface B adems de P entonces se ejecutar C1 y por tanto la verificacin equivaldr
a demostrar que {P B} C1 {Q} es correcto. Si el estado inicial no satisface B
entonces se ejecutar C 2 y por tanto la verificacin equivaldr a demostrar que
{PB} C 2 {Q} es correcto.

Ejm:
Demostrar que: { }if a>b then m:=a else m:=b{(m a) (m b)}
{ a>b}m:=a {(m a) (m b)}
P={m=a, (m a) (m b)} {a a, a b}
{a=a} {a a}, {a=a, a b} {a b}
{ a>b} {a b} {Fortalecimiento PreC.} { a >b}
m: =a {(m a) (m b)}
{ (a>b)}m:=b {(m a) (m b)}
P={m=b,(m a) (m b)} {b a, b b}
{b=b} {b b}, {b a, b=b} {b a}
{ (a>b)} {b a}
{ b a}m:=b {(m a) (m b)}
Con lo que queda demostrado.

SENTENCIA IF( SIN CLAUSULA ELSE)

Si C1 es una parte de un programa y B es una condicin, entonces la sentencia if B


then C1 se interpreta de la siguiente forma: si B es verdadero se ejecuta C1.
Si ahora se desea demostrar la correccin de una sentencia if con una
precondicin {P} y una postcondicin {Q} tendremos dos posibilidades: Si el
estado inicial satisface B adems de P entonces se ejecutar C1 y por tanto la
verificacin equivaldr a demostrar que {P B} C1 {Q} es correcto. Si el estado
inicial no satisface B entonces esto equivaldr a demostrar que {PB} {Q}

Ejm:
Demostrar que:
{ }ifmax<a then max:=a {(maxa)}
{(max<a)}{(maxa)} lo que es obvio.

{ max<a} max:=a {(maxa)}


P={max=a, (maxa)}{aa}
{aa{ },
Y puesto que {max<a} { }
Con lo que queda demostrado.

CONCATENACION DE CDIGO

La concatenacin significa que las partes del programa se ejecutan secuencialmente de


tal forma que el estado final de la primera parte de un cdigo se convierte en el estado
inicial de la segunda parte del programa.
Regla de la concatenacin: Sean C1 y C 2 dos partes de un cdigo y sea C1;C 2 su
concatenacin. Si {P}C1{R} y {R}C 2{Q} Son ternas de Hoare correctas entonces se
puede afirmar que

Ejemplo:
Demostrar que el siguiente cdigo es correcto:
{ }c:=a+b; c:=c/2 {c=(a+b)/2}
{ P}c:=c/ 2 {c=(a+b)/2}
P={c =c/2,c =(a+b)/2} {c/2=(a+b)/2}
{ c/2=(a+b)/2}c:=c/2 {c=(a+b)/2}

{P} c:= a+b { c/2= (a+b)/2}


P={c =a+b,c /2 =(a+b)/2} {(a+b)/2=(a+b)/2} { }
{ }c:=a+b {c/2=(a+b)/2}
Con lo que queda demostrado.

INVARIANTE DE UN CDIGO

Cualquier asercin que es a la vez precondicin y postcondicin de una parte del cdigo
se denomina invariante.
Ejemplo: Demostrar que r=2i es un invariante del siguiente cdigo:
i:=i+1; r:=r*2.
{ P}r:=r* 2 {r=2i }
P={r=r*2, r=2i } {r*2=2i } {r=2i-1 }
{r=2i-1} r:=r*2 {r=2i }
{P} i:=i+1 {r=2i-1 }
P={i=i+1, r=2i-1 } {r=2i+1-1} {r=2i }
{r=2i}i:=i+1 {r=2i-1 }
Con lo que queda demostrado

BUCLES

Mientras que todos los programas sin bucles terminan, no se puede decir lo mismo de
aquellos que si lo poseen o son recursivos. Por ahora slo nos preocupar la correccin
parcial.
El invariante del bucle es un aserto que captura las caractersticas que no varan al
ejecutarse un bucle.
El variante de un bucle es una expresin que mide el progreso realizado por el bucle
hasta satisfacer la condicin de salida.
Las estructuras iterativas elegidas para establecer su correccin son:
o while B do C, donde B es la condicin de entrada y C es el cdigo contenido
dentro del bucle.
o repeat C until B, donde B es la condicin de salida y C es el cdigo contenido
dentro del bucle.
Como podremos comprobar en cada iteracin el bucle debe progresar hacia la
postcondicin final, que debe derivarse del invariante cuando la condicin de entrada no
se cumple (condicin de salida).

CONCEPTO DE CORRECCIN
Si {P}C{Q} es un cdigo con la precondicin {P} y la postcondicin {Q}, entonces {P}C{Q}
es correcto si cada estado inicial posible que satisfaga {P} da como resultado un estado final
que satisface {Q}.
Dentro de este concepto debemos distinguir entre correccin total y parcial.
CORRECION PARCIAL
Se dice que {P}C{Q} es parcialmente correcto si el estado final de C, cuando termina el
programa (aunque no se le exige esta premisa), satisface {Q} siempre que el estado inicial
satisface {P}.
En un programa real, aparecen declaraciones de tipo y declaraciones de variables as como
implementaciones de funciones (pueden ser implementaciones incorporadas al sistema o hechas
por el usuario) que determinan la signatura del programa, adems el segundo argumento de un
comando de asignacin puede ser cualquier expresin del correspondiente tipo s construida con
constantes y funciones implementadas, y el primer argumento de un comando de seleccin o de
iteracin puede ser cualquier expresin del tipo BOOL. En nuestros programas, aunque no
vamos a considerar declaraciones de tipo ni de variables, supondremos que existe una
declaracin de signatura donde aparecen los tipos y las constantes y funciones necesarias con
propiedades conocidas, as como una asignacin de tipo a cada variable de programa.
EJEMPLO
Probar la correccin del siguiente algoritmo respecto de su especificacin:
P {x > 1}
xx+1
Q {x > 2}
sp(x x + 1, x > 1)
(y) x = (x + 1)[x : y] (x > 1)[x : y]
(y) x = y + 1 y > 1
x>2

CORRECIN TOTAL
Correccin total implica correccin parcial. Sin embargo, en muchas ocasiones se demuestra
primero la segunda y, a partir de ella la primera.

En Lgica de Hoare se utilizan dos lenguajes formales:


Un lenguaje de programacin imperativo (LP) para S.
Un lenguaje de frmula (LF) para P y Q. En LF se usan los tipos (enteros,
booleanos, reales, . . . ), funciones (suma de enteros, suma de reales...) y
predicados(<, >, , . . . ) usados en el LP, incluidos los definidos por el usuario.
Como hemos visto, la validez de una sentencia de correccin parcial no implica que el
transformador de estados correspondiente al programa que aparece en la sentencia est
definido para todos los estados denotados por la precondicin. Esta indefinicin, a nivel
terico, slo puede deberse a la aparicin de ciclos tales que la aplicacin reiterada del
transformador asociado al cuerpo del ciclo a estados en los que es vlida la condicin de
control nunca alcanza un estado en el que no se cumpla dicha condicin. En estos casos

se dice que el programa no termina. El lenguaje de la lgica de Hoare se podra ampliar


con formulas de correccin total de la forma [P][Q] cuya validez en una interpretacin
A, para un estado sta, se puede establecer de la forma siguiente: A |=sta [P][Q], si y
slo si

A |=sta P implica sta[]Asta0 y A |=sta0 Q

VERIFICACIN DE LOS ALGORITMOS


RECURSIVOS
Cuestin previa:

Teorema de la Recursin
El siguiente teorema, llamado el teorema de la recursin, formaliza la existencia de una
funcin definida de manera recursiva.
Teorema 1 (Teorema de la recursin) Dados el conjunto A, el elemento
a A y la funcion h : A A, existe una unica funcion f : N A tal que
1. f(0) = a, y
2. para todo n N, f(n + 1) = h(f(n))
Prueba. Usamos [0, n] para denotar el conjunto {0, 1, 2, . . . , n}. Primero
probamos por induccion sobre n que existe una funcion unica fn : [0, n] A tal
que
(1) fn(0) = a, y
(2) para todo m [0, n 1], fn(m + 1) = h(fn(m))
Para el caso base, note que f0 debe ser {(0, a)}. Ahora nos ocupamos del paso
inductivo de n a n + 1. Definimos fn+1 : [0, n + 1] A de la siguiente manera
(a) para m [0, n] se tiene fn+1(m) = fn(m)
(b) fn+1(n + 1) = h(fn(n))
Veamos que fn+1 satisface (1) y (2): para (1) tenemos fn+1(0) = fn(0) = a
por definicion de fn+1(0) e hipotesis de induccion (fn satisface (1)); para (2)
tenemos para todo m [0, n 1] que
fn+1(m + 1) = fn(m + 1) = h(fn(m)) = h(fn+1(m))
usando la definicin de fn+1 (caso (a)) y la hiptesis de induccin (fn satisface (2));
y finalmente
fn+1(n + 1) = h(fn(n)) = h(fn+1(n))
usando la definicion de fn+1 (caso (b), y caso (a) para m = n). La funcion
definida fn+1 es unica en [0, n] con condiciones (1) y (2) porque es identica a
fn
en [0, n] la cual es unica, y el valor de fn+1(n + 1) esta entonces determinado por el
caso (b) de la definicion.
Ahora con las funciones fn consideradas como relaciones (son conjuntos
de pares (n, x) donde n N y x A) definimos
f = U fn
n N

Esta relacion f es una funcion porque si (m, x), (m, y) f, entonces (m, x)
fn1 y (m, y) fn1 para algunos n1 y n2. Si n1 = n2 = n entonces debe ser
x = y porque n es una funcion. De los contrario supongamos n1 < n2. Entonces por la
unicidad de las fn, la restriccion de fn2 a [0, n1] debe ser igual a fn1 y por
lo tanto x = y. Es claro que el dominio de f es N (porque n dom(fn)) y que f
satisface necesariamente (1) y (2) del enunciado. Finalmente, f es unica: si f y f t son dos
tales funciones diferentes, sea n tal que f(n) = ft(n); pero entonces f y f t
restringidas a [1, n] resulta en dos funciones diferentes
que tienen las mismas propiedades (1) y (2) de fn arriba, lo que es una
contradiccion.
No todos los ejemplos que hemos visto se adaptan a la forma simple de recursion
del anterior teorema. El siguiente ejemplo muestra como este teorema se puede usar para
justificar la existencia para definiciones recursivas ms complicadas.
Ahora veamos la verificacin del algoritmo o sub-problema recursivo:
Sabemos que la ejecucin de los algoritmos o subprograma recursivo hacen, en general, que
ste sea llamado varias veces. Para asegurar que este proceso termina es necesario que el
subprograma recursivo definido cumpla las siguientes condiciones:
1) Hay al menos una posible llamada al subprograma que produce un resultado sin
provocar una nueva llamada recursiva. A esto se le llama caso base de la recursin. En
el caso de la funcin Factorial el caso base es n=0.
La siguiente definicin de la funcin Factorial no es correcta ya que no posee caso
base:
PROCEDURE Factorial (n : CARDINAL) : CARDINAL;
BEGIN
RETURN n * Factorial(n-1)
END Factorial;
2) Todas las llamadas recursivas se refieren a un caso que es ms cercano al caso base. En
el caso de la funcin Factorial, cada llamada disminuye en uno el valor del argumento,
por lo que ste se va acercando a cero, que es el caso base.
A partir de la expresin n!= (n 1)! n , y la sustitucin n = m + 1 se obtiene que (m
+1)!= m! (m +1) , de donde despejando se deduce m!= (m + 1)! / (m + 1). Con esta
expresin podemos construir el siguiente subprograma recursivo:
PROCEDURE Factorial (m : CARDINAL) : CARDINAL;
BEGIN
IF m = 0 THEN
RETURN 1

ELSE
RETURN Factorial(m+1) DIV (m+1)
END
END Factorial;
Este subprograma presenta un caso base, sin embargo no es correcto ya que no
cumple la condicin 2). Cada llamada recursiva incrementa en uno el valor del
argumento por lo que ste se va alejando del caso base y la recursin nunca termina.
3) El caso base debe acabar alcanzndose.
El siguiente subprograma cumple las condiciones 1) y 2), pero no es correcto. Si lo
llamamos con un argumento cuyo valor sea impar, el caso base nunca se alcanza.
PROCEDURE Factorial (n : CARDINAL) : CARDINAL;
BEGIN
IF n = 0 THEN
RETURN 1
ELSE
RETURN n * (n-1) * Factorial(n-2)
END
END Factorial;
Para algunos algoritmos recursivos el caso base puede ser mltiple. Un ejemplo es la sucesin
de Fibonacci, que se define del siguiente modo: el primer nmero de Fibonacci es 0, el segundo
es 1 y cualquier otro nmero de Fibonacci se obtiene sumando los dos nmeros de Fibonacci
que le preceden:
0
,si n = 1

Fibonacci(n) =
si n = 2
1,

Fibonacci(n 1)

+ Fibonacci(n 2),
caso

en otro

Los casos bases en este ejemplo son n = 1 y n = 2. Una funcin en Modula-2 que calcule el nsimo nmero de Fibonacci segn esta definicin es:

PROCEDURE Fibonacci (n : CARDINAL) : CARDINAL;


BEGIN
IF n = 0 THEN
WrStr (Error: Fibonacci(0) no est definido);
HALT
ELSIF n = 1 THEN
RETURN 0
ELSIF n = 2 THEN
RETURN 1
ELSE
RETURN Fibonacci(n-1) + Fibonacci(n-2)
END
END Factorial;

CORRECCIN PARCIAL TAMBIN APLICABLE A UN ALGORITMO RECURSIVO.


Partiendo de una especificacion (una postcondicion y posiblemente
alguna precondicion), se trata de demostrar, utilizando las reglas anteriores (y
algunas otras que no hemos visto) que el programa verifica dicha
especificacin.
Generalmente, tras unas pocas lneas de codigo, la prueba se hace
demasiado compleja para poder representarla en forma de inferencias
encadenadas. Para resolver este problema se intercalan las anotaciones del
LF entre las lneas del LP.
Dado S S1; S2; . . . ; Sn, si queremos demostrar que {P0}S{Pn}, basta
demostrar que:
{P0}S1{P1} {P1}S2{P2}

. . . {Pn1}Sn{Pn}

y usar la regla de la composicion n 1 veces.


De este modo, podemos representar la prueba de {P0}S{Pn} como:
{P0 }
S1

anotacion

{P1 }
S2

anotacion

...
{Pn1 } anotacion
Sn

{Pn }

anotacion

Las formulas P1 , . . . , Pn1 seran condiciones intermedias y cada paso


{Pi1}
Si
{Pi}
sera obtenido a traves de alguna de las reglas anteriores.
El proceso de prueba para un bloque o programa S S1; S2; . . . ; Sn se
produce de abajo a arriba (desde el fin hacia el principio del bloque o
programa) debido a la naturaleza de la regla de la asignacion. En
general, comenzamos con la postcondicion Pn y se utiliza Sn para obtener
Pn1 .
Obtener Pi1 a partir de Pi y Si es mecanico para las asignaciones
y las instrucciones if. La Pi1 obtenida de esa manera se denomina la
precondicion mas debil para Si y Pi , lo que quiere decir que que Pi1
es la formula logica mas debil que siendo verdadera al principio de la
ejecucion de Si garantiza la veracidad de la postcondicion Pi .

al principio de la secuencia,
0 P
Al final del proceso, obtenemos una formula
que garantiza que al ejecutar S se verifica la postcondicion Pn . Debemos
chequear
si P puede obtenerse a partir de la precondicion P0 mediante la regla
de reforzamiento de la precondicion.

0 P , usando cualquiera
En este caso, deberamos demostrar que P0
de los sistemas deductivos de logica de predicados. En general, ese
tipo de demostraciones, que aparecen al usar las dos reglas de la
implicacion, suelen omitirse en la secuencia de anotaciones e instrucciones.
Si se demuestra que P R, la practica habitual es simplemente escribir
la segunda condicion debajo de la primera.
{P }
{R}
S
{Q}

Para la calcular la precondicion mas debil P para un if a partir de


una prostcondicion Q
{P } if B then S1 else S2 {Q}
suele precederse del siguiente modo:

1. Se obtiene la precondicion P1 a partir de Q y S1 .


2. Se obtiene la precondicion P2 a partir de Q y S2 . 3. P
(B P1 ) (B P2 )
Recordemos el while parcial:

{P B}S{P }
{P }while B do S{P B}
Si tenemos una precondicion R y una postcondicion Q, y queremos demostrar:
|=par {R}while B do S{Q}
Debemos encontrar una formula P del LF que verifique:

1. R P (para el reforzamiento de la precondicion)


2. P B Q (para el debilitamiento de la postcondicion)
3. |=par {P }while B do S{P B} (regla while parcial)
A la formula P verificando lo anterior se le denomina invariante.
Encontrar invariantes requiere cierto ingenio (puede haber muchas diferentes
para un mismo bucle), aunque hay reglas heursticas:

1. Comenzar

modificando la postcondicion del while para hacerla


dependiente del ndice del bucle (la variable que crece o decrece en cada iteraci
on).

2. Si la invariante P aun no verifica P B Q, debemos reforzar P para que se


cumpla.

CORRECCIN TOTAL TAMBIN APLICABLE A UN ALGORITMO RECURSIVO.


Lo anterior solo prueba la correccion parcial de las triplas {P }S{Q}, es decir, s
olo es cierto cuando S termina normalmente.
Habamos visto dos posibles razones para la no terminacion: error de ejecucion y
bucle infinito. La primera esta cubierta por el sistema de calculo que ya hemos
descrito.
Por lo tanto, asegurar la correccion total implica asegurar la correccion parcial
y la terminacion de los bucles while.
Podemos obtener la prueba de terminacion si podemos, a partir de las variables de los
estados del bucle, encontrar una expresion entera que disminuya en cada iteracion
del bucle manteniendose no negativa (0 o positiva).
Si tal expresion existe, en bucle termina despues de un numero finito de
iteraciones, ya que no hay cadenas descendentes infinitas de enteros positivos
(algebra basica).
A la expresion entera mencionada se le denomina variante. De
este modo obtenemos una regla del while total:
{P B (0 E = E0)} S {P (0 E < E0)}
{P (0 E)} while B do S {P B}

E es la variante, que decrece en cada iteracion. Si E = E0 antes de cada iteraci


on del bucle, es estrictamente menor despues. Si existen instrucciones antes del bucle
y queremos calcular sus anotaciones a partir de la precondicion del while, debemos
utilizar la precondicion del while.
La aplicacion de esta regla es equivalente a la utilizacion de la regla del while parcial
y la demostracion de las siguientes formulas:
PBE>0

{P B E = E0}S{E < E0}

Conclusion

Los mtodos formales permiten que un ingeniero de software especifique,


desarrolle y verifique un sistema basado en computadora aplicando una notacin
rigorosa y matemtica; utilizando est mtodo descubre y corrige ambigedades,
inconsistencias y errores.

Tenemos que tomar en cuenta que los mtodos formales estn presentes en
bastantes campos y no solo los referidos a la ingeniera y la informtica, los
mtodos formales tienen un amplio recorrido y su utilidad y eficiencia en
desarrollo crticos estn demostradas. Sus herramientas proporcionan el soporte
automatizado necesario para la integridad, trazabilidad, verificabilidad,
reutilizacin y para apoyar la evolucin de los requisitos, los puntos de vista
diversos
y
la
gestin
de
las
inconsistencias.
Los mtodos formales pueden ser aplicados en las empresas para mejorar sus
procedimientos y productos.

La decisin de utilizar mtodos formales debe considerar los costes de arranque,


as como los cambios puntuales asociados a una tecnologa radicalmente
distinta. En la mayora de los casos, los mtodos formales ofrecen los mayores
beneficios para los sistemas de seguridad y para los sistemas crticos para los
negocios.

Lo que se ha pretendido plantear en este trabajo es cmo nos enfrentamos al reto


de determinar si el software que construimos realmente har lo que esperamos
de l. Para ello hemos partido del entorno acadmico (donde lo que prima es la
formalidad y la teora) y hemos llegado hasta el entorno industrial guiado
principalmente por metodologas de desarrollo bien definidas.

BIBLIOGRAFA
VERIFICACIN FORMAL DE ALGORITMOS - J.V.Alvarez(Departamento de Informtica
Universidad de Valladolid Campus de Segovia)
Programming with TopSpeed Modula-2. Barry Cornelius. Addison-Wesley.
Pascal y estructuras de datos. Nell Dale y Susan C. Lilly. McGraw-Hill.
Fundamentos de programacin . L. Joyanes. McGraw-Hill.

También podría gustarte