13 de marzo de 2017

Tipos de datos abstractos (ADT).

   Desde el punto de vista de la programación, es importante que los programadores puedan definir sus propias abstracciones de datos, de tal forma que dichas abstracciones trabajen de manera parecida a las abstracciones o a las primitivas de datos proporcionadas por el sistema subyacente.

   Un tipo de dato abstracto o ADT (Abstract Data Type) es definido por una especificación abstracta, es decir, permite especificar las propiedades lógicas y funcionales de un tipo de dato.

   Desde el punto de vista de los ADT, un tipo de dato es un conjunto de valores y un grupo de operaciones definidas sobre dichos valores. El conjunto de valores y el de las operaciones forman una estructura matemática que se implementa usando una estructura de datos particular de hardware o de software.

   El concepto de ADT está relacionado con la concepción matemática que define al tipo de datos por lo que, al definir un ADT como concepto matemático, no interesa la eficiencia del espacio o del tiempo (los cuales son aspectos relacionados con la implementación del ADT), sino las propiedades y características inherentes a él. La definición de un ADT no se relaciona en lo absoluto con los detalles de la implementación; de hecho, tal vez ni siquiera sea posible implementar un ADT particular en ningún tipo de hardware o software (piense por ejemplo en los números reales y en la propiedad de la densidad de los números reales por ejemplo).

   Un ADT consta de dos partes: una definición de valor y una definición de operador, mismas que se describen a continuación:
  1. La definición del valor establece el conjunto de valores para el ADT y consta a su vez de dos partes:
    1. Una cláusula de definición.
    2. Una cláusula de condición. Para la definición de un ADT racional por ejemplo, una cláusula de condición estaría relacionada con la restricción de que el denominador de un número racional no puede ser cero.
  2. En la definición del operador cada operador está definido como una operación abstracta con condiciones previas opcionales, y las condiciones posteriores o postcondiciones.
   Por otro lado, para la implementación de un ADT, es necesario tomar en cuenta los siguientes aspectos:
  • Hacer disponible (pública) la definición del nuevo tipo.
  • Hacer disponibles un conjunto de operaciones que puedan ser utilizadas para manipular las instancias del tipo definido (métodos públicos de servicios).
  • Proteger los datos asociados con el tipo de dato que está siendo definido (atributos privados), de tal forma que dichos datos sólo puedan ser accedidos por medio de los métodos proporcionados para ello.
  • Poder generar múltiples instancias del tipo definido, preferentemente, con más de una opción de inicialización, siempre que ésto no entre en contradicción con la definición o restricciones del tipo.
   Es importante resaltar que, asociado con un ADT particular, puede haber una o más implementaciones distintas.

   En resumen, los ADT son un mecanismo de abstracción sumamente importante y, dado que la programación orientada a objetos (POO) se fundamenta en la abstracción, es posible decir que constituye uno de los pilares de la orientación a objetos.

Especificación del ADT racional.
   Existen varios métodos para especificar un ADT, desde notaciones matemáticas hasta descripciones detalladas hechas en lenguaje natural. Lo importante de la especificación es que sea clara y no ambigüa.

   Esta sección, debido a las limitaciones de formato inherentes al blog, hará uso de algo parecido a una notación matemática apoyándose del lenguaje natural para la especificación del ADT racional.

   Sea r un número racional (Q). Se define r como el cociente de dos números enteros, es decir:


r = p / q

donde p, q son números enteros (Z) y q distinto de cero (!=0).

   Las operaciones aritméticas de suma, resta, multiplicación y división de dos números racionales se especifican a continuación.

   Sean r1 y r2 son dos números racionales (Q) definidos como:

r1 = p1 / q1 con p1, q1 números enteros (Z) y  q1 != 0

r2 = p2 / q2 con p2, q2 números enteros (Z) y  q2 != 0
entonces:
  1. r1 + r2 = (p1 / q1) + (p2 / q2) = [ (p1 * q2) + (p2 * q1) ] / (q1 * q2).
  2. r1 - r2 = (p1 / q1) - (p2 / q2) = [ (p1 * q2) - (p2 * q1) ] / (q1 * q2).
  3. r1 * r2 = (p1 / q1) * (p2 / q2) = (p1 * p2) / (q1 * q2).
  4. r1 / r2 = (p1 / q1) / (p2 / q2) = (p1 * q2) / (q1 * p2).

   Observe la especificación de los valores para el ADT racional, y la restricción que existe sobre el valor del denominador representado por q1 y q2 respectivamente.

   Finalmente, note que se ha proporcionado también la especificación de las operaciones aritméticas asociadas al ADT.