Apuntes de Tipos Abstractos de Datos

Anuncio
Apuntes de Tipos Abstractos de Datos
Juan M. Molina Bravo
curso 2001-2002
0-2
Capı́tulo 1
Introducción a la Programación
Basada en Tipos Abstractos de
Datos.
1.1
Diseño basado en ttaadd
Los sistemas de software se utilizan para modelar situaciones y resolver problemas que
se presentan en distintos ámbitos (Matemáticas, Fı́sica, Ingenierı́a, Gestión, ...); por
lo que dichos sistemas vienen a ser representaciones de otros sistemas reales o ideales
que pueden alcanzar una gran complejidad. Por ello, la construcción de sistemas de
software se puede considerar una actividad propia de una ingenierı́a, que requiere los
mismos pasos (diseño, implementación, prueba y mantenimiento) que la construcción
de cualquier sistema fı́sico complejo; por lo que para poder construir un sistema de software de una cierta envergadura será necesario aplicar mecanismos de abstracción que
permitan controlar la complejidad desde el momento del diseño para evitar problemas
en las fases posteriores.
Como sabemos, en general, la abstracción de un sistema es una descripción simplificada del mismo en función de unos aspectos que se consideran más relevantes y
en detrimento de otros menos relevantes y, en particular, la abstracción de un sistema
de software supone la aplicación de alguna técnica de abstracción que determina los
aspectos que se deben abstraer (procedimientos de actuación, comportamientos funcionales, organización de los datos, estructura global del sistema) y que conduce a
distintos métodos de diseño.
Las técnicas de abstracción han evolucionado en el sentido de alejar los elementos
que aparecen en los sistemas de software de las nociones propias de las máquinas
sobre las que se implantan dichos sistemas, aproximándolos a las nociones propias de
1-3
1-4
CAPÍTULO 1. PROGRAMACIÓN BASADA EN TTAADD
los dominios en los que se presentan las situaciones que se modelan. Una de estas
técnicas, centrada en las abstracciones de datos, conduce al método de diseño basado
en tipos abstractos. Este método consiste en
• identificar los distintos tipos de datos que interviene en el sistema ası́ como la
función principal de dicho sistema, cuando exista,
• caracterizar cada tipo de datos en función de las operaciones que se puedan
realizar con los objetos de los distintos tipos (haciendo abstracción de sus representaciones concreta),
• componer el sistema utilizando libremente objetos de los tipos definidos junto
con sus operaciones caracterı́sticas y,
• finalmente, implementar cada uno de los tipos utilizados.
Para que esta forma de diseño sea eficaz es necesario controlar la corrección del sistema
durante su construcción, lo que requiere evitar ambigüedades en las caracterizaciones
y errores en las implementaciones.
1.2
Objetivo del curso
El propósito último de esta asignatura será construir programas correctos para tareas
especı́ficas adoptando una disciplina de diseño basada en el uso de tipos abstractos de
datos; es decir, tipos de datos procedentes de los dominios en los que se plantean las
tareas y no necesariamente incorporados a los lenguajes de programación al uso. Para
ello necesitaremos un marco adecuado en el que se pueda expresar una tarea y verificar
si un determinado programa la cumple o no.
Para especificar tareas partiremos de la idea de programa imperativo como transformador de estados, según la cual la actuación de un programa se puede resumir en la
transformación de un estado, dado por unos valores iniciales de sus variables, en otro,
dado por los valores finales de dichas variables. Para verificar que un programa realiza
una tarea correctamente necesitamos disponer de una serie de reglas de comportamiento para las distintas construcciones del lenguaje en el que esté codificado el programa
que nos indiquen cómo afectan estas construcciones al estado de un programa.
Por otro lado, en la programación de alto nivel, próxima a los dominios de los
problemas, las variables que intervienen en un programa generalmente representan objetos abstractos y las tareas se fijan con ayuda de los valores que pueden tomar estas
variables, es decir, valores abstractos. Pensemos en un sencillo programa para calcular
raı́ces cuadradas: su tarea será partir de un número natural N , como valor de una
variable de entrada X, y calcular su raı́z cuadrada positiva, como valor de una variable
1.2. OBJETIVO DEL CURSO
1-5
de salida Y . Esta tarea se puede resumir diciendo que el programa debe transformar
un estado caracterizado por la relación {X = N ∧ N ≥ 0} en otro caracterizado por
√
{Y = + N }. Como vemos, el estado de partida se caracteriza mediante un valor
numérico asignado a una variable X —aunque sabemos que la variable no albergará
tal valor abstracto, sino una representación en código máquina— y el estado final se
caracteriza además con la ayuda de una función abstracta definida en el álgebra de
los números naturales. Según esto necesitaremos disponer de valores abstractos para
todos aquellos tipos con los que pueda trabajar un programa, ası́ como de funciones
definidas sobre ellos y propiedades dadas generalmente mediante ecuaciones.
El marco que buscamos nos lo puede proporcionar la lógica de predicados con varios
universos debidamente extendida para que pueda tratar con sentencias de corrección
de programas. En esta versión de la lógica de predicados se pueden fijar varios universos, ası́ como distintas funciones y predicados relativos a entes de dichos universos. La
idea subyacente es que los universos o dominios sirven para clasificar los términos sobre
los que se va a razonar, las operaciones sirven para construir términos (que representan entes) de los distintos universos mientras que los predicados sirven para expresar
relaciones entre términos que se pueden cumplir o no. Para estudiar la corrección de
un programa
• Se fijará un lenguaje lógico donde los universos representarán los distintos tipos
de datos que intervienen, las funciones servirán para simbolizar operaciones con
los datos y los predicados propiedades de dichas operaciones, siempre a nivel
abstracto.
• Además este lenguaje lógico se ampliará con la introducción de las variables del
programa (cuyos valores abstractos representan los estados de dicho programa)
y con las construcciones propias del lenguaje de programación, para construir
términos de un universo especial: el universo de programas.
• También se introducirá un predicado especial, {P }Π{Q}, para construir sentencias de corrección parcial o tripletas de Hoare, que permite expresar propiedades
o caracterizaciones P y Q de los estados de un programa Π al comienzo y al final
de su ejecución. Estos predicados se utilizan para establecer las “tareas” que
deben realizar los programas, mientras que las caracterizaciones de los estados
se enuncian como relaciones entre los valores abstractos de ciertas variables de
dichos programas.
Del estudio y manipulación de estas sentencias se ocupa la primera parte de la asignatura relativa a la especificación y verificación de programas.
1-6
CAPÍTULO 1. PROGRAMACIÓN BASADA EN TTAADD
De lo que acabamos de decir, se deriva también la necesidad de disponer de descripciones abstractas de los tipos de datos con los que se vaya a operar (pilas, colas,
árboles, ...) con sus propiedades y funciones, tal como ocurre con tipos más conocidos:
los tipos numéricos, cuyas propiedades se establecen mediante ecuaciones algebraicas.
De esto se ocupa la segunda parte de la asignatura relativa a la especificación de
tipos abstractos de datos, donde se estudiarán las propiedades de distintos tipos
abstractos, con cuyas representaciones operan los programas, para poder expresar propiedades de los estados de dichos programas.
Por último, las fórmulas del cálculo de predicados y las fórmulas de corrección
deben interpretarse sobre estructuras algebraicas para darles sentido. De hecho, las
representaciones en máquina de los distintos tipos de datos se puede suponer que
definen una estructura algebraica concreta. Pero para poder razonar a partir de las
especificaciones de tipos abstractos sin tener que recurrir a ningún modelo concreto
necesitaremos un cálculo deductivo consistente que nos permita obtener deducciones
en la seguridad de que se cumplirán en cualquier modelo. De la misma forma para poder
hacer deducciones sobre el comportamiento de los programas tendremos que ampliar el
cálculo deductivo anterior con reglas especializadas para la manipulación de sentencias
de corrección, ligadas a las distintas construcciones del lenguaje de programación, que
son las que permiten la verificación.
Descargar