Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Introducción
Los métodos formales surgieron como puntos de vista analíticos con lo que es posible verificar el
desarrollo de sistemas mediante la lógica y las matemáticas, lo que aporta grandes ventajas para
mejorar la calidad de los programas y por tanto la ingeniería del software, sabiendo que el
principal objetivo de la ingeniería de software es desarrollar sistemas de alta calidad, garantizando
así su correcto funcionamiento.
Los métodos formales presentan una alternativa práctica para solucionar problemas, ya que es
una de las más importantes fases del ciclo de vida, garantiza que tanto el funcionamiento como el
desempeño del programa sean correctos. Bajo cualquier situación, esté construye un enfoque
analítico para la especificación, diseño y verificación de sistemas de hardware y software; teniendo
como característica principal es la rigurosidad en la que sus modelos se encuentran basados, con
fundamentos en solidos principios matemáticos que permitan definir con precisión y sin temor a
ambigüedades las necesidades de un sistema; el propósito de los métodos formales es
sistematizar e introducir rigor en todas las fases de desarrollo de software, con lo que es posible
evitar que se pasen por alto cuestiones críticas.
Métodos formales
Un método formal es un camino a la construcción y análisis de modelos matemáticos que
permitan una automatización del desarrollo de sistemas informáticos. Se caracterizan por emplear
técnicas y herramientas matemáticas para lograr una facilitación a la hora de encarar la
construcción o el análisis de un modelo matemático de un sistema. Los métodos formales se
refieren entonces al uso de técnicas de la lógica y de la matemática discreta para especificar,
diseñar, verificar, desarrollar y validar programas.
En la lógica formal como en los métodos formales el objetivo es el mismo, “reducir la dependencia
de la institución y el juicio humano para evaluar argumentos”. Los métodos menos rigurosos
enfatizan en la formalización y renuncian a la computación, definición que implica un amplio
espectro de técnicas, y una gama igualmente amplias de estrategias. La interacción de las técnicas
y estrategias de muchos métodos formales, en determinados proyectos, se limita por el papel que
interpretan y por los recursos disponibles para su aplicación.
Se puede decir también que un método formal es una técnica basada en matemáticas, usada para
describir sistemas de hardware o software. Los métodos formales permiten representar la
especificación del software, verificación y diseño de componentes mediante notaciones
matemáticas. El uso de métodos formales permite plantear de manera clara la especificación de
un sistema, generando modelos que definen el comportamiento en términos de “qué debe hacer”
y no en “cómo lo hace”. Gracias al correcto proceso de especificación, se pueden verificar
propiedades derivadas de cada módulo mediante técnicas de razonamiento asociadas a los
modelos formales, como probadores de teoremas y verificadores de modelos. Para los procesos
de especificación se reconoce las siguientes clasificaciones:
3. Especificación de comportamiento:
• Métodos basados en álgebra de procesos: Modelan la interacción entre procesos concurrentes.
Esto ha potenciado se difusión en la especificación de sistemas de comunicación y de sistemas
distribuidos y concurrentes. Algunos ejemplos son: CCS, CSP, Pi Calculus y LOTOS.
• Métodos basados en Redes de Petri: Una red de Petri es un formalismo basado en autómatas,
es decir, un modelo formal basado en flujos de información. Permiten expresar eventos
concurrentes. Los formalismos basados en redes de Petri establecen la noción de estado de un
sistema mediante lugares que pueden contener marcas. Un conjunto de transiciones (con pre y
post condiciones) describe la evolución del sistema entendida como la producción y consumo de
marcas en vario puntos de la red.
• Precondición más débil: Básicamente, consiste en dada una poscondición POST, encontrar,
operando hacia atrás, un programa S tal que wp(S, POST) (la precondición) se satisfaga en un
lOMoARcPSD|6095641
entrada para que el programa pueda cumplir su tarea mientras que la postcondición indica las
condiciones de salida que son aceptables como soluciones correctas del problema en cuestión. Por
ejemplo, para un programa simple que calcule el inverso de un número podríamos tener como
precondición que el argumento de entrada sea distinto de cero y como postcondición el inverso de
ese argumento. De esta forma representaríamos la terna de Hoare como {y≠0} x:=1/y {x=1/y}. En
algunas ocasiones puede ocurrir que no exista precondición, representándose con unas llaves
vacías. En estos casos siempre se obtienen estados que satisfacen la postcondición,
independientemente de la precondición. Un ejemplo de este caso podría ser la terna de Hoare { }
a:=b {a=b}, en la que el programa siempre asignará el valor de b a la variable a.
Para demostrar la corrección de un programa o de parte de una mismo haciendo uso de la
verificación formal debemos partir de la postcondición final del código, es decir de las condiciones
que deben satisfacer los resultados esperados como salida válida del programa. A partir de ahí
debemos ir deduciendo “hacia atrás” hasta llegar a la precondición inicial. Es decir, el código se
verifica en sentido contrario a como se ejecutaría.
A continuación se enumeran una serie de nociones que se deben tener en cuenta para
comprender con mayor claridad ciertos conceptos necesarios para llevar a cabo la verificación
formal de un programa dado:
• Los programas hacen uso de variables para describir posiciones de memoria que puede
contener valores diferentes en diferentes estados.
• Vamos a entender la idea de programa como una secuencia ordenada de sentencias que parte
de un estado inicial (anterior a la ejecución) y lo transforman en un estado final (posterior a la
ejecución).
• El estado del programa en un momento determinado viene especificado por una tupla
S=(X1,X2,…, Xn) donde Xi es el valor de la variable xi (suponiendo que el programa usa el conjunto
de variables (x1, x2,…, xn)).
Ejemplo: Dado el estado s=(x,y)=(7,8), el resultado de ejecutar la sentencia de asignación x:=2*y+1
es el estado s’=(x,y)=(17,8)
• Si U es el conjunto de todos los posibles estados un programa y S es un subconjunto de U
podemos definir Ps como el predicado característico de S, tal que S = { s’ S / Ps(s’) }. Es decir, es el
predicado que solamente es satisfecho por los estados que pertenecen al conjunto S.
Ejemplo: Queremos probar que x<7 después de ejecutar la sentencia x:=2*y+1. Esto sería
verdadero si 2*y+1<7 antes de ejecutar la sentencia, es decir y < 3. Por tanto, { y < 3 } x := 2*y+1 { x
< 7 }.
• Vamos a definir la notación para P -> wp(S, Q) como una alternativa a la notación {P} S {Q}. La
función wp se denomina también predicado transformador, ya que para cualquier fragmento de
programa define una transformación de un predicado post-condición en un predicado pre-
condición. Esto quiere decir que, como ya anticipamos en un párrafo anterior, en vez de describir
cómo un programa transforma un conjunto de estados iniciales en un conjunto de estados finales,
describe cómo un programa transforma un predicado post-condición, que caracteriza el conjunto
de estados finales, en un predicado pre-condición que caracteriza el conjunto de estados iniciales.
Hemos descrito en que consiste la verificación formal de un programa mediante el empleo de
precondiciones y postcondiciones. Este enfoque es denominado por algunos autores como
“diseño por contrato” ya que podemos ver las precondiciones como lo que el usuario se
compromete a suministrar y las postcondiciones como lo que el programa entregará a cambio. El
lOMoARcPSD|6095641
primer paso que debemos realizar para llevar a cabo la verificación de un programa debe ser
anotar el programa. Vamos a entender anotar un programa o un fragmento de código como la
acción de añadir al código o pseudocódigo de las mismas aserciones en aquellos puntos del código
que la persona encargada de realizar la anotación considere oportuno. El número de aserciones
que se debe introducir es variable siendo el requisito principal que éstas sean suficientes para
construir la demostración de la corrección del programa a verificar. Además estas aserciones
suelen servir a posteriori como una documentación precisa, compacta y no ambigua del software
desarrollado. Vamos a exponer las tres posibles estrategias que podemos seguir a la hora de
verificar un programa desde el punto de vista de la corrección del mismo. En las tres se parte de
un programa correctamente anotado, es decir, con las aserciones mínimas necesarias cuya
demostración formal asegura el correcto funcionamiento del programa:
• Verificación estática completa: Generalmente se lleva a cabo a mano aunque en ocasiones se
hace uso de herramientas tales como probadores de teoremas, etc.
Ventaja: Esta estrategia es que es el único método que permite tener la certeza de la corrección
del software ya que está basado en su verificación matemática.
Inconveniente: Requiere conocimientos profundos de Lógica y manipulación simbólica, además de
ser excesivamente costosa en tiempo (y consecuentemente en dinero).
• Verificación estática parcial: En esta estrategia, también incluida dentro de un enfoque
estático, se hace uso de entornos capaces de detectar algunas propiedades relativas a la
corrección de un programa dado, aunque sin poder llegar a probar la corrección total del software.
Estos entornos de desarrollo contienen, además del compilador del lenguaje de programación
utilizado, herramientas que son capaces de procesar las aserciones insertas en el código,
informando al programador de problemas encontrados o causas de posibles problemas. Dado que
se trata de un análisis estático, la información dada gira en torno a dependencias entre los datos, a
uso de variables no inicializadas, a declaración de variables que no se utilizan, a guardas de bucle
cuyo valor es constante, etc. Este tipo de entornos no suelen adoptar esta opción como única, sino
que suelen ir acompañados de probadores de teoremas para adoptar complementariamente el
enfoque anterior.
Ventaja: Respecto a la opción anterior, presentan la ventaja de que las comprobaciones se llevan a
cabo de manera automática.
Inconveniente: Sólo se analizan algunos aspectos de la corrección del programa.
• Verificación dinámica: Esta última estrategia se basa en que las aserciones insertas en el
código pueden, con un compilador adecuado, ser transformadas en código ejecutable, de manera
que en tiempo de ejecución se convierten en un mecanismo para asegurar la corrección de la
ejecución.
Ventaja: La ventaja fundamental de este enfoque reside en su simplicidad, ya que, con un lenguaje
de aserciones adecuado, permite que cualquier programador especializado pueda adoptarla.
Inconveniente: Como las aserciones se chequean en tiempo de ejecución con los datos
correspondientes a dicha ejecución no se prueba que el programa en si sea correcto (al igual que
ocurre con el testing) sino que simplemente se asegura que la ejecución no viola ninguna de las
propiedades descritas en las aserciones. Además, si el lenguaje usado es muy potente puede
ocurrir que sea demasiado costoso ejecutar el código que las aserciones generen. Esto se suele
paliar estableciendo niveles de severidad en las aserciones, de manera que algunas aserciones que
han sido utilizadas en las etapas de desarrollo del software no generen código para la versión de
lOMoARcPSD|6095641
partes de la especificación, pero confían en el usuario para probar las propiedades complicadas.
• Verificación: Para asegurar la calidad de los sistemas es necesario probarlos, y para asegurar
que se desarrollan pruebas rigurosas se requiere una precisa y completa descripción de sus
funciones, incluso cuando en la especificación se utilicen métodos formales. Una de las
aplicaciones más interesantes de éstos es el desarrollo de herramientas, que pueden generar
casos de prueba completos desde la especificación formal.
Aunque gran número de herramientas para automatizar pruebas se encuentran disponibles en el
mercado, la mayoría automatiza sólo sus aspectos más simples: generan los datos de prueba,
ingresan esos datos al sistema y reportan resultados. Definir la respuesta correcta del sistema,
para un determinado conjunto de datos de entrada, es una tarea ardua, que la mayoría de
herramientas no puede lograr cuando el comportamiento del mismo se especifica en lenguaje
natural. Debido a que la respuesta esperada del sistema se puede determinar únicamente
mediante la lectura de la especificación, los ingenieros esperan que a las pruebas automatizadas
se les adicione este faltante y crítico componente (Dan & Aichernig, 2002). La gran ventaja de las
herramientas, que generan pruebas con base en los métodos formales, es que la especificación
formal describe matemáticamente el comportamiento del sistema, desde la que se puede generar
la respuesta a un dato de entrada en particular, es decir, la herramienta puede generar casos de
prueba completos.
Las técnicas de verificación formal dependen de especificaciones matemáticamente precisas y,
desde un punto de vista costo-beneficio, generar pruebas desde la especificación puede ser uno
de los usos más productivos de los métodos formales. Aproximadamente la mitad del tiempo del
equipo de trabajo, en un desarrollo típico de software comercial, se invierte en esfuerzo para
desarrollar pruebas, e “incluso con este nivel de esfuerzo sólo se eliminan los errores más
evidentes” (Saiedian & Hinchey, 1996). Algunas mediciones empíricas demuestran que las
pruebas, generadas con herramientas automatizadas, ofrecen una cobertura tan buena o mejor
que la alcanzada por las manuales, por lo que los ingenieros pueden elegir entre producir más
pruebas en el mismo tiempo, o reducir el número de horas necesarias para hacerlas (Gabbar,
2006).
• Validación: Mientras que la verificación se puede realizar semiautomáticamente y las pruebas
mecánicamente, la validación es un problema diferente. Una diferencia específica entre
verificación y validación es que la primera responde a si “se está construyendo el producto
correctamente”, y la segunda a si “se está construyendo el producto correcto” (Dasso & Funes,
2007). En otras palabras, la verificación es el conjunto de actividades que aseguran que el software
implementa correctamente una función específica, y la validación es un conjunto de actividades
diferentes que aseguran que el software construido corresponde con los requisitos del cliente
(Amman & Offutt, 2008).
Desde el conjunto de requisitos es posible verificar, formal o informalmente, si el sistema los
implementa; sin embargo, la validación es necesariamente un proceso informal. Sólo el juicio
humano puede determinar si el sistema que se especificó y desarrolló es el adecuado para el
trabajo. A pesar de la necesidad de utilizar este juicio en el proceso de validación, los métodos
formales tienen su lugar, especialmente en grandes y complejas aplicaciones, como en modelado y
simulación. Una de sus aplicaciones más prometedoras es en el modelado de requisitos, ya que, al
diseñarlos formalmente, el teorema provisto en la herramienta de prueba se puede utilizar para
explorar sus propiedades, y a menudo detectar los conflictos entre ellos. Este método no sustituye
lOMoARcPSD|6095641
al juicio humano, pero puede ayudar a determinar si se especificó el “sistema correcto”, por lo que
es más fácil determinar si las propiedades deseadas se mantienen (Flynn & Hamlet, 2006).
Una diferencia significativa entre validar sistemas de modelado y simulación, y los de control o
cálculo, es que los primeros tienen dos tipos de requisitos de validación: deben modelar y predecir
el comportamiento de alguna entidad del mundo real, problema que se conoce como “validación
operacional”, y deben “validar el modelo conceptual”, para asegurar que la hipótesis en la que se
sustenta es correcta, y que su lógica y estructura son adecuadas para el modelo que se propone
(Sargent, 1999). Debido a que el modelo conceptual describe lo que debe representar la
simulación, es necesario incluir supuestos acerca del sistema, su entorno, las ecuaciones, los
algoritmos, los datos, y de las relaciones entre las entidades del modelo. Aunque los algoritmos y
las ecuaciones son declaraciones necesariamente formales, los supuestos y las relaciones se
describen normalmente en lenguaje natural, lo que introduce potenciales ambigüedades e
incomprensiones entre ingenieros y usuarios.
Una tendencia relativamente reciente en los métodos formales, conocida como “métodos
formales ligeros” (Jackson, 2001), demuestra tener potencial para detectar errores importantes en
la declaración de requisitos, sin el costo de una verificación diseñada formalmente. La premisa
básica de este enfoque es el uso de técnicas formales en el análisis de los supuestos, las relaciones
y las propiedades de los requisitos, indicadas en su declaración o en el modelo conceptual. Se
puede aplicar a especificaciones parciales o a un segmento de la especificación completa, proceso
que se realiza en tres fases: 1) reafirmar los requisitos y el modelo conceptual en una notación
formal o semiformal, típicamente en una tabla de descripción de estados; 2) identificar y corregir
las ambigüedades, conflictos e inconsistencias; y 3) utilizar un verificador de modelos o un
probador de teoremas para estudiar el comportamiento del sistema, demostrar sus propiedades y
graficar su comportamiento. Los ingenieros y usuarios pueden utilizar estos resultados para
mejorar el modelo conceptual (Davis, 2005).
Un aspecto particularmente interesante de este enfoque es que se ha utilizado para modelar y
analizar el comportamiento del software, del hardware y de las acciones humanas en los sistemas
(Mazzola et al, 2006). Agerholm y Larsen (1997) describen su aplicación en un sistema de actividad
extra-vehicular de la NASA; y Lutz (1997) describe la validación de requisitos de los monitores de
errores a bordo de una nave espacial. Un detalle importante de este proyecto es que los
ingenieros utilizaron el modelo de requisitos para un segundo proyecto, que se desarrolló a partir
del primero, como una construcción en serie. Janssen et al (1999) describen la aplicación de un
verificador de modelos para analizar procesos de negocios automatizados, como el procesamiento
de reclamaciones de seguros.
Podemos resumir de una manera más exacta que las ventajas de los métodos formales son:
• La comunicación con el cliente mejora ya que se dispone de una descripción clara y no ambigua
de los requisitos del usuario.
• Se comprende mejor el sistema.
• El sistema se describe de una manera más precisa.
• El sistema se asegura matemáticamente que es correcto según las especificaciones.
• Mayor calidad software respecto al cumplimiento de las especificaciones.
• Mayor productividad.
en cuenta cuando se esté considerando el beneficio obtenido frente a esa inversión asociada a los
métodos formales.
4. Poseerás un experto en métodos formales a tu disposición: El entrenamiento de expertos y la
asesoría continua son esenciales para el éxito cuando se utilizan los métodos formales por primera
vez.
5. No abandonarás tus métodos formales de desarrollo: Es posible, y en muchos casos resulta
deseable, integrar los métodos formales con los métodos convencionales y/o con métodos
orientados a objetos. Cada uno de estos métodos posee sus ventajas y sus inconvenientes. Una
combinación de ambos, aplicada de forma adecuada, puede producir excelentes resultados.
6. Documentarás suficientemente: Los métodos formales proporcionan un método conciso, sin
ambigüedades y consistente para documentar los requisitos del sistema. Sin embargo, se
recomienda que se adjunte un comentario en lenguaje natural a la especificación formal, para que
sirva como mecanismo para reforzar la comprensión del sistema por parte de los lectores.
7. No comprometerás los estándares de calidad: Los métodos formales no tienen nada de
mágico, y por esta razón, las demás actividades de SQA deben de seguir aplicándose cuando se
desarrollen sistemas.
8. No serás dogmático: El ingeniero de software debe reconocer que los métodos formales no
son una garantía de corrección. Es posible (o como algunos probablemente dirían) que el sistema
final, aun cuando se haya desarrollado empleando métodos formales, siga conteniendo pequeñas
omisiones, errores de menor importancia y otros atributos que no satisfagan nuestras
expectativas.
9. Comprobarás, comprobarás y volverás a comprobar: Los métodos formales no absuelven al
ingeniero del software de la necesidad de llevar a cabo unas comprobaciones exhaustivas y bien
planeadas.
10. Reutilizarás cuanto puedas: A la larga, la única forma racional de reducir los costes del
software y de incrementar la calidad del software pasa por la reutilización. Los métodos formales
no modifican esta realidad. De hecho, quizás suceda que los métodos formales sean un enfoque
adecuado cuando es preciso crear componentes para bibliotecas reutilizables.
los ingenieros de software. Este mito, a su vez, se basa en la percepción de que las matemáticas
son intrínsecamente difíciles.
5. Los métodos formales aumentan el costo del desarrollo: Se acostumbraba decir que a pesar
que el costo que significaba usar métodos formales era muy alto, de todas formas era conveniente
porque resultaba en menores costos de mantenimiento del software.
6. Los métodos formales son incomprensibles para los usuarios: Una especificación formal esta
llena de símbolos matemáticos que resultan incomprensibles para cualquiera que no este
familiarizado con la notación. De ahí que se suponga que son inútiles para clientes no
matemáticos.
7. Los métodos formales no se usan en grandes proyectos reales: Los métodos formales se
asocian comúnmente con departamentos académicos y organizaciones de investigación. Se piensa
que solo estas organizaciones tienen la capacidad necesaria para usar métodos formales y que
estos solo son apropiados para las aplicaciones idealizadas que estos grupos desarrollan.
años setenta, pero hasta fines de los ochenta comenzaron a tener cierta madurez e impacto fuera
de los laboratorios de investigación.
Una de las notaciones más utilizadas es Z (diseñada por un equipo en la Universidad de Oxford), la
cual está basada en la teoría de conjuntos con tipos y el cálculo de predicados. Existe otra notación
como es VDM (Vienna Development Method), está basada para sistemas secuenciales.
Se ha experimentado con los métodos formales en varios proyectos para lograr el desarrollo de
sistemas reales con calidad:
• Para automatizar la verificación tanto como sea posible (Wunram, 1990).
• En requisitos y diseños de alto nivel, en los que la mayor parte de los detalles se abstraen de
diversas formas (Rushby, 1993).
• Sólo a los componentes más críticos (Lutz & Ampo, 1994).
• Para analizar modelos de software y hardware, en los que las variables se discretizan y los
rangos se reducen drásticamente (McDermid, 1995).
• En el análisis de los modelos de sistemas de manera jerárquica, de tal forma que se aplique el
“divide y vencerás” (Zhang, 1999).
Aunque el uso de la lógica matemática sea un tema de unificación en los métodos formales, no es
posible indicar que un método sea mejor que otro; cada dominio de aplicación requiere métodos
de modelado diferentes, lo mismo que el acercamiento a las pruebas. Además, en cada dominio
en particular, las diferentes fases del ciclo de vida se pueden lograr mejor con la aplicación
combinada de diferentes técnicas y herramientas formales (Pressman, 2004).
CONCLUSIÓN
Los métodos formales permiten que un ingeniero de software especifique, desarrolle y verifique
un sistema basado en computadora aplicando una notación rigorosa y matemática; utilizando esté
método descubre y corrige ambigüedades, inconsistencias y errores.
Tenemos que tomar en cuenta que los métodos formales están presentes en bastantes campos y
no solo los referidos a la ingeniería y la informática, los métodos formales tienen un amplio
recorrido y su utilidad y eficiencia en desarrollo críticos están demostradas. Sus herramientas
proporcionan el soporte automatizado necesario para la integridad, trazabilidad, verificabilidad,
reutilización y para apoyar la evolución de los requisitos, los puntos de vista diversos y la gestión
de las inconsistencias.
Los métodos formales pueden ser aplicados en las empresas para mejorar sus procedimientos y
productos.
La decisión de utilizar métodos formales debe considerar los costes de arranque, así como los
cambios puntuales asociados a una tecnología radicalmente distinta. En la mayoría de los casos,
los métodos formales ofrecen los mayores beneficios para los sistemas de seguridad y para los
sistemas críticos para los negocios.
Lo que se ha pretendido plantear en este trabajo es cómo nos enfrentamos al reto de determinar
si el software que construimos realmente hará lo que esperamos de él. Para ello hemos partido
del entorno académico (donde lo que prima es la formalidad y la teoría) y hemos llegado hasta el
entorno industrial guiado principalmente por metodologías de desarrollo bien definidas.