No es un bug, es una característica no documentada

Mostrando entradas con la etiqueta ADA. Mostrar todas las entradas
Mostrando entradas con la etiqueta ADA. Mostrar todas las entradas

12/6/15

Programación. Manual completo del módulo

0:57 Posted by Inazio , , , No comments
Por fin puedo decirlo. Ha sido un año trabajando duro, pero he conseguido aprobar el módulo (bueno, el curso completo, que coño) de programación, y lo que es aún más importante, aprender y no poco.

Durante todo el curso he estado realizando un manual exclusivamente de este módulo, tanto teoríco como práctico. Si quieres descargartelo puedes visitar la sección de descargas de este blog (pulsa aquí o navega por el menú habilitado para ello).

Cualquier duda, mejora, consulta, corrección, etc. agradecería un comentario en la propia entrada de la descarga.

Espero que le podaís sacar partido. Saludos


14/3/15

Programación. ADA. Tipos abstractos de datos (II)

17:56 Posted by Inazio , No comments

Árbol binario

·         Implementación estática. Un vector con componentes con cuatro campos (información, índice del hijo izquierdo – 0 si no hay hijo izquierdo -, índice del hijo derecho – lo mismo -, y si hay algo en esa componente o no. La raíz se almacena en la primera componente del vector.
·         Implementación dinámica. La que ya conocemos, nodos con información y dos punteros a los hijos.

Árbol n-ario

En general un árbol no tiene por qué tener sólo dos hijos como máximo. Hay problemas que pueden llevar a que un nodo pueda tener un número de hijos mayor, 3, 4, 5 o incluso puede ocurrir que no quede fijado a priori el número de hijos máximo que pueda tener un nodo.

Vamos a ver una posible representación estática para un árbol n-ario general, que sólo es razonable si el árbol es completo o caso completo. En este caso el valor de n puede ser cualquiera pero tiene que estar fijado a priori.

Vamos a ver una representación dinámica, que es lo más razonable que suele emplearse cuando se trabaja con árboles n-arios

·         Implementación estática.
Se utiliza un vector de 0 a máx-1 componentes para almacenar los elementos.
La raíz  se almacena en la componente 0.

Si un nodo es el hijo k-ésimo de padre en un árbol n-ario, será almacenado en la componente n*indice(padre)+k

El número de componentes necesario para almacenar un árbol n-ario arbitrario de altura h es


       Consideraciones para la implementación estática:
·         Conocido el índice que le corresponde a un elemento e en el vector, es fácil calcular el índice que le corresponde a su padre, hermanos e hijos:
·         Elemento, índice, condición
·         e, i
·         Hijo k-ésimo de e, n*i+k, si n*i+k<max
·         Padre de e, (i-1) div n, si n<>0
·         Hermano siguiente a e, i+1, si i mod n <> 0

·         Número de orden entre sus hermanos, ((i-1) mod n)+1, si i<>0


·         Implementación estática
Lo primero que se nos puede ocurrir es adaptar la que ya utilizamos para los árboles binarios: nodos con información y una lista de punteros a los hijos

Lo que se suele utilizar es precisamente eso mismo, pero “visto desde otra perspectiva”: la representación primogénito-siguiente-hermano.

Cada nodo tiene además de la información dos punteros, uno que apunta al primogénito (es decir, al primero de los hijos) y otro que apunta al siguiente hermano.

Árboles de búsqueda

Una de las más importantes aplicaciones que tienen los árboles es la de permitir realizar en ellos búsquedas con costes temporales logarítmicos (es decir, mucha mayor eficiencia que en estructuras lineales recorridas secuencialmente).

Para poder realizar búsquedas eficientes en árboles, logarítmicamente éstos deben estar ordenados.

Hay una gran variedad de tipos de árboles de búsqueda en función de su grado y restricciones.

Clasificación de árboles de búsqueda
·         Árboles binarios de búsqueda
·         Árboles AVL (binarios equilibrados)
·         Árboles m-arios de búsqueda (también llamados árboles de búsqueda múltiple o multicamino)
·         Árboles m-arios de búsqueda equilibrados
·         Árboles B de grado m
·         Árboles 2-3
·         Árboles B* de grado m
·         Árboles B+
·        

Árboles m-arios de búsqueda

Los nodos almacenan m-1 elementos ordenados de menor a mayor.

El subarbol 1 el nodo es menor que el menor de los elementos del nodo del que cuelga.
El subarbol 2, mayor que el primero y menor que el segundo, y así sucesivamente.

Ejemplo: Árbol 3-ario de búsqueda


Árboles B

Un árbol B de orden m tiene las siguientes propiedades
·         Es un árbol m-ario de búsqueda
·         La raíz es una hoja o tiene al menos dos hijos
·         Cada nodo, excepto la raíz y las hojas, tienen al menos m/2 hijos
·         Todas las hojas están en el mismo nivel

Un árbol 2-3 es un árbol B de orden 3. Cada nodo excepto las hojas, tiene dos o tres hijos.

Un árbol B* se caracteriza porque todos los nodos (excepto la raíz, y lógicamente las hojas), están por lo menos a 2/3 de ocupación en vez de a 1/2 , como el caso general de los árboles B.

Un árbol B+ es un árbol B que tiene todas las hojas enlazadas (formando una lista, para aumentar la eficiencia de ciertas operaciones). En un árbol B+ toda la información se guarda en las hojas y los nodos intermedios sólo guardan información de claves.

Grafos

Conceptos básicos

Un grado es una relación arbitraria entre objetos de un mismo tipo.

Puede definirse formando como un par G = (V,A) donde V es un conjunto de objetos llamados vértices o nodos y A es un conjunto de aristas o arcos. Una arista es un par (u,v) de vértices de V.

El grafo se llama dirigido, si sus aristas son pares ordenados. Es decir, si la aristas (u,v) se considera distinta a la arista (v,u). En caso contrario es no dirigido.

En muchas ocasiones es útil asociar información a cada arista de un grafo. En ese caso el grafo se dice etiquetado y se llama etiqueta de una arista a su información asociada. En ocasiones las etiquetas son valores numéricos que representan valores o costes asociados a las aristas, y se denominan pesos.

Por ejemplo, los vértices de un grafo no dirigido pueden representar ciudades con aeropuerto, las aristas servicios de vuelo de ida y vuelta entre las ciudades, y el peso asociado a cada arista, la duración del vuelo entre las dos ciudades correspondientes.

El grafo del ejemplo anterior podría ser dirigido si quisiésemos contemplar la posibilidad de que sólo hay vuelos en un sentido entre dos ciudades.

Caminos en grafos

Un camino en un grado G = (V,A) es una secuencia de vértices v1,…,vn tal que existen las aristas (vi, vi+1) para i = 1,…,n-1

La longitud de un camino es su número de vértices menos uno.

Un camino es simple si todos sus vértices, excepto tal vez el primero y el último, son distintos.

Un ciclo es un camino simple de longitud no nula que empieza y termina en el mismo vértice. Un grado es acíclico si no tiene ningún ciclo.

Los árboles son grafos

Un subgrafo de un grafo G es otro grafo G cuyos vértices y aristas son un subconjunto de los vértices y aristas de G.

Un grafo no dirigido se dice conexo si existe un camino entre cada par de vértices.

Un árbol libre es un grafo no dirigido, conexo y acíclico. Si en un árbol libre se destaca un vértice, denominado raíz, el grafo se denomina árbol.

Spanning tree

Un subárbol de recubrimiento de un grafo no dirigido (spanning tree) es un árbol libre que es subgrafo del grafo original y que incluye todos sus vértices.

En un grafo no dirigido y con pesos, el cálculo del árbol de recubrimiento de peso mínimo (árbol de recubrimiento cuya suma de pesos es mínima) es un problema de especial interés.

Si, por ejemplo, los vértices representan ciudades, las aristas las posibles líneas de comunicación entre ellas y el peso de una arista el coste de seleccionar esa línea de comunicación, un árbol de recubrimiento de peso mínimo representa una red de comunicaciones entre todas las ciudades que minimiza el coste.

Operaciones para grafos

è Crear grafo vacío
è Añadir vértice al grafo
è Añadir arista entre dos vértices
è Averiguar si existe el vértice en el grafo
è Averiguar si existe arista entre dos vértices en el grafo
è Averiguar con qué vértices existe comunicación directa desde un vértice
è

Implementación estática. Matriz de adyacencia

Si el grafo tiene n vértices, la matriz de adyacencia para el grafo es una matriz A de dimensiones nxn de elementos booleanos en la que A[i,j] es verdad, si y sólo si existe una arista en el grado que va del vértice i al vértice j.

En el caso de un grafo no dirigido, la matriz de adyacencia tiene la particularidad de ser simétrica y los elementos de su diagonal son todos igual a falso.

La representación de la matriz de adyacencia es útil para aquellos algoritmos que precisas saber si existe o no una arista entre dos vértices dados.

En el caso de grados etiquetados con pesos, los elementos de la matriz pueden ser enteros o reales (en lugar de booleanos) y representar el peso de la arista. Si no existe una arista de i a j debe emplearse un valor que no pueda ser una etiqueta válida para almacenarse en A[i,j].

Implementación dinámica. Lista de adyacencia

Consiste en una lista de listas, de forma que la lista i-ésima contiene los vértices adyacentes al vértice i.

En el caso de un grafo no dirigido, si tengo la arista (u,v), el vértice v estará en la lista de adyacencia de vértice u, y el vértice u lo estará a su vez en la del v.

Para representar un grafo etiquetado con pesos, basta con añadir otro campo al tipo nodo que almacene el peso correspondiente.

22/2/15

Programación. ADA. Tipos abstractos de datos

13:57 Posted by Inazio , No comments

Concepto de abstracción


El concepto de abstracción en el proceso de compresión de un problema, lleva consigo el destacar los detalles importantes e ignorar los irrelevantes.

La abstracción es usada constantemente a la hora de programar.

Un claro ejemplo de ello es el uso de funciones y procedimientos. Ambos, ocultan los detalles sobre como se consigue el resultado que ofrecen y desde fuera son vistos como lo que hacen y no el cómo lo consiguen hacer.

La abstracción siempre lleva asociada la ocultación de información.

Se separa el QUÉ del CÓMO.

O dicho de otra manera, se separa la especificación (el qué) de la implementación (el cómo).

Abstracción de acciones


El uso de procedimientos y funciones nos permite abstraernos de las instrucciones que realmente se están ejecutando para conseguir los resultados que obtenemos.

Tenemos una acción (en el caso de procedimientos) o valor (en el de las funciones) virtual parametrizada.

Se está ocultando información: los datos locales y la secuencia de instrucciones del subprograma.

Recordemos, se separa la especificación (el qué: lo que hace la función o el procedimiento) de la implementación (el cómo: las instrucciones concretas que lo hacen).

Tipo abstracto de datos (TAD)


Un TAD es una colección de valores y de operaciones definidos mediante una espeficación independiente de cualquier representación.

La programación con TADs requiere dos pasos.

è Definición del tipo. Establecer los valores que puede tomar el tipo y las operaciones necesarias para manipular los valores y especificar su interfaz. Esto tiene dos partes:
·         Parte sintáctica. Cómo se llama la operación, si es una función o un procedimiento, que parámetros tiene, en que orden y de qué tipo.
·         Parte semántica. Qué hace la operación con los parámetros de entrada, cómo modificar los de salida y qué devuelve (si se trata de una función). En otras palabras, para qué sirve esa operación y cuál es su comportamiento.
è Implementación del tipo. Elegir la representación de los valores e implementar las operaciones

Encapsulación


El concepto fundamental subyacente bajo la programación de TADs es la encapsulación.

La encapsulación consiste basicamente en:
è La privacidad de la representación (el usuario no conoce los detalles del tipo)
è La protección del tipo (el usuario sólo puede utilizar las operaciones previstas)

Diseño modular


La programación a gran escala exige la partición del código en módulos.

Un módulo es una unidad del programa que puede ser desarrollada independientemente del resto.

La descomposición en módulos debe cumplir unos requisitos.
è Que cada módulo tenga una conexión mínima con el resto. La interfaz
è Que la mayor parte de los cambios del programa afecten sólo a un número pequeño de módulos.
è Que el tamaño de cada módulo sea adecuado (si es muy grande es dificil hacer cambios, si es muy pequeño es costoso por los trabajos adicionales de especificación, documentación, control de versiones…)

Un TAD puede encapsularse en un módulo.
è La interfaz es reducida. El nombre del tipo y los encabezamientos de las operaciones.
è Puede cambiarse la implementación independientemente (para mejorarla, por ejemplo), siempre y cuando mantengamos la interfaz.

El tamaño del módulo suele ser suficientemente grande (implementación de las operaciones).

TADs como base del diseño modular


El uso de procedimientos y funciones (diseño descendente) facilita la programación a pequeña escala (programas pequeños).

Sin embargo esto es insuficiente para la programación a gran escala. Es necesario utilizar el diseño modular.

Programas = datos + algoritmos
Programas = datos + (algoritmos de control)
Programas = (datos + algoritmos de datos) + algoritmos de control
Programas = TADs + algoritmos de control

Hasta ahora conocíamos la forma de abstraer algoritmos (mediante funciones y procedimientos que podemos agrupar en módulos). Ahora conocemos la forma de abstraer datos (mediante TADs que también pueden constituir módulos).

TADs genéricos y algoritmos genéricos


Se pueden definir TADs genéricos (o tipos parametrizados) con algunas características indefinidas.

Estas características pueden ser concretadas posteriormente de diversas formas según las necesidades, obteniendo ejemplares de TADs concretos distintos.

La genericidad facilia la reutilización de algoritmos. Por ejemplo, si se implementa un algoritmo de ordenación de vectores, los tipos de datos de los índices y de los elementos del vector no afectan al algoritmo, siempre y cuando se disponga de una función de orden que diga si un elemento es mayor que otro.

Módulo de declaración ordenacion_g.ads

generic
            type ind is (<>); -- cualquier tipo discreto
            type elem is private; -- cualquier tipo
            type vector is array (ind range <>) of elem;
            with funcion “>”(a,b:elem) return boolean;

package ordenacion_g is
            procedure ordena (v:in out vector);
end; -- del módulo de declaración

Módulo de implementación ordenacion_g.adb

package body ordenacion_g is
            procedure ordena (v: in out vector) is
                        i,j:ind; m,t:elem; n:integer;

begin
            --iniciailización
            i:=v'first;
            j:=v'last;
            n;=ind'pos(i)
            n=n+ind'pos(j)
            n=n/2;
            m=v(ind'val(n));
-        partición del vector en dos
            while i<=j loop
                        while n>v(i) loop
                                   i=ind'succ(i);
                        end loop;
                        while v(j)>m loop
                                   j:=ind'pred(j);
            …
end ordenacion_g

Uso desde un programa de un ejemplar concreto de vector

with ordenacion_g;
procedure mi_programa is
            type color is (rojo, azul, gris);
            type dia is (lu,ma,mi,ju,vi,sa,do);
            type vect is array (day range <>) of color;
            x:vect(ma..vi):=(gris,azul,rojo,gris);
            package o is new ordenacion_g(dia,color,vect,”>”);
                                  
begin
            …
            o.ordena(x);
            …
end mi_programa;

¿Qué gano además con los TADs y la modularidad?


Pues oculto totalmente como se representa la información y cómo se implementan los algoritmos.

Podría cambiar en el futuro ambas cosas, y mientras mantenga la interfaz, el usuario del módulo ni lo notará.

De esta manera, podría hacer una versión rápida que funcionara, y después hacer versiones sucesivas que fueran refinando y mejorando las anteriores, especialmente en cuanto a eficiencia, funcionalidad o capacidad.

Ejemplo. Una pila

Por ejemplo supongamos que tengo un problema para el que necesito una pila, y me urge tener una pila disponible para hacer pruebas, porque lo importante es probar el problema en sí mismo.

De hecho, el problema lo va a resolver otra persona, a mi me encargan que tenga cuanto antes una pila operativa… Y yo no sé ni lo que es un puntero.

Pila. La interfaz

Lo más importante es que yo tenga claro lo que es una pia, aunque no tenga muy claro cómo implementarla, y que el que la va a usar también lo tenga claro (la implementación a él le va a dar igual completamente, a mi no). Y que lo que él va a usar es exactamente lo mismo que yo voy a implementar.

Es decir, hace falta definir antes de empezar a trabajar cada uno por su lado, que operaciones va a hacer, que atributos van a tener, de qué tipo, en qué orden y qué hace exactamente cada operación y en qué condiciones funciona.

Podrían ser las siguientes:
-          Crear pila: à Pila
-          Apilar: Pila elemento à Pila
-          Parcial desapilar: Pila à Pila
-          Parcial cima: Pila à Elemento
-          esVacia: Pila à Booleano

Especificación formal

especificación pila
            usa booleanos
            parametro formal
                        generico elemento
            generico pila
            operaciones
                        creaPila:->pila
                        Crear pila: → pila
                        apilar: pila elemento → pila
parcial desapilar: pila → pila
parcial cima: pila → elemento
                        esVacia: pila → booleano
            dominios de definicion           p:pila, e:elemento
                        desapilar(apilar(p,e))
                        cima(apilar(p,e))
            ecuaciones      p:pila, e:elemento
                        desapilar(apilar(p,e))=e
                        cima(apilar(p,e))=e
                        esVacia(creaPila)=verdad
                        esVacia(apilar(p,e))=falso
fin especificación

Implementación estática

Mientras pienso en cómo dar una solución definitiva al problema que tengo entre manos (y mientras me estudio cómo funcionan los punteros en el lenguaje de programación en el que tengo que hacer el desarrollo), lo que voy a hacer es montar algo que funcione, aunque sea una solución de andar por casa, ya que total, nadie sabrá jamás que he hecho eso, y mi jefe estará contento porque el otro programador tendrá en dos horas una pila operativa para hacer las pruebas sobre ella.

Así que sin más puedo simular una pila conun vector con espacio para un número máximo de elementos, y un contador cima que me dice hasta dónde lo he llenado.

Implementación dinámica.

Luego con tranquilidad, cuando ya domine los punteros, desarrollo en los días siguientes una pila “de verdad”.

Sin más que mantener la interfaz, el otro programador ni se enterará del cambio.

Esta pila por supuesto tendrá sus nodos y sus punteros al nodo siguiente, y todo lo que yo estime necesario.

Si en el futuro quiero mejorar alguna función o procedimiento, haciendo una nueva versión mejorada de la pila, siempre y cuando mantenga la interfaz, podré hacerlo sin ningún problema, sin que el otro programador tenga que modificar ni una línea, y sin que ni siquiera se llegue a enterar del cambio, ya que él no apreciará diferencia alguna (salvo posiblemente en capacidad o eficiencia).

Es decir:

Pilas:
è Implementación estática. Un vector y un entero que diga que componente es la cima
è Implementación dinámica. Colección de nodos enlazados mediante punteros. Se inserta siempre por el principio y un puntero apunta siempre a la cima (que es el principio).

Cola:
è Implementación estática. Vector circular (el siguiente elemento del últmo es el primero) y dos índices que digan que componente son la primera y última.

è Implementación dinámica. Nodos enlazados por punteros (uni o bidireccionalmente según necesidades) y dos punteros que apuntan al primero y último.

13/2/15

Programación. Introducción a ADA

8:52 Posted by Inazio , No comments

Características generales

è   Lenguaje de propósito general
è   Es profesional (complejo, no pensado para aprendices)
è   Incorporación de puntos clave de la teoría de la programación
·        Legibilidad. Evita notación demasiado concisa (es más costoso el mantenimiento que la producción de software. “Un programa se lee más veces de las que se escribe”).
·        Fuerte y esteticamente tipado. Gran cantidad para definir datos de tipos diferentes. Cada dato puede usarse sólo en operaciones específicas de su tipo. La utilización inadecuada se detecta en tiempo de compilación.
·        Diseño a gran escala. Programación modular. Mecanismos de encapsulación. Compilación separada.
·        Abstracción de datos. Separación clara entre especificación, representación e implementación.
·        Módulos genéricos
·        Programa concurrente. Descripción de procesos que pueden ejecutarse concurrentemente. Definición de operaciones de sincronización entre esos procesos.
·        Manejo de excepciones. Definición de comportamientos de recuperación ante situaciones de error no previstas.

Escribir en ADA

è   El fichero tendrá extensión .adb
è   ; para finalizar una orden
è   No existen las llaves
è   -- es un comentario
è   with sirve para incluir paquetes
è   procedure [nombre] is es el procedimiento principal, que tendrá el mismo nombre que el archivo fuente.
è   use hace referencia a los paquetes
è   begin es el comienzo del programa
è   put(“”); es para mostrar por pantalla cadenas de texto
è   get(“”); sirve para capturar caracteres
è   constant es usado para la declaración de constantes
è   while loop  / end loop es para condiciones de mientras que…
è   if
            then
end if                         es usado para condiciones de si…
è   /= distinto de
è   := Asignación
è   = Comparación

Compilación en ADA 

Para compilar debes instalar el gnat.

Para su instalación, escribe:
è   sudo apt-get update (para actualizar repositorios)
è   sudo apt-get install gnat-4.6 (versión hasta la fecha – 10/02/2015)

Para compilar, escribe este comando:
è   gnatmake nombreArchivoSinLaExtensión

E/S Simple

è   text.io – Entrada y salida de caracteres
è   integer_text.io – Entrada y salida de enteros

Reservas

ADA tiene 69 palabras reservadas. Son éstas:

Tipos escalables

pi:constant float:=3.1415; -- Inicializo constante pi con valor de 3.1415
final:constant character:=’.’; -- Inicializo constante final con valor inicial de ‘.’
i, j, k: integer; -- i, j y k son enteros

ADA es fuertemente tipado. No se puede asignar valor a una variable de un tipo diferente.

Subtipos

Caracteriza un subconjunto de los valores de un tipo. No constituye un nuevo tipo (la asignación está permitida).

Tipos definidos por enumeración

Hay dos ya predefinidos. Booleanos y caracteres.

type dia is (lunes, martes, miercoles, jueves, viernes, sabado, domingo);
subtype laboral is dia range lunes..viernes;
d1:dia;d2:laboral;

Atributos

dia ‘first:=lunes; -- Primero
dia ‘last:=sabado; -- Último
dia ‘succ(lunes):=martes; -- Sucesor
dia ‘pred(martes):=lunes; -- Preedecesor
dia ‘pos(lunes):=0; -- Posición
dia ‘val(1):=martes; -- Valor
dia ‘image(lunes):=”LUNES”; -- Convertir a cadena de texto
dia ‘value(“martes”):=martes; -- Convertir cadena de texto al tipo definido

Tipo booleano

type boolean is (false,true);
a,b,c,d:boolean;
((not a) and b) or (c xor d);

Tipos enteros

Hay algunos predefinidos:
è   type integer is …; -- enteros
è   type short-integer is …; -- enteros cortos
è   type long –integer is …; -- enteros largos
è   subtype natural is integer range 0..integer ‘last; -- De 0 en adelante
è   subtype positives is integer range 1..integer ‘last; -- De 1 en adelante

Orde de las propiedades

1.      and, or, xor
2.      not
3.      =, /=, <, <=, >, >=, in, not in
4.      +. – (binarios)
5.     

Tipos reales

type misReales is digits 7;
n:integer;x:float;

-- No se admite aritmetica mixta

n+x -- incorrecto

-- Forma correcta (una de las dos)

float(n)+x
n+integer(x)

La conversion de real a entero aplica un redondeo

Estructuras de control

If

       if
            then …
       end if;

       if
            then …
            else …
       end if;

       if
            then …
            elsif
                        then …
            else …
       end if;

Case

       case … is …
            when … =>…  -- Una opción
            when … | … | … => … -- Varias opciones
            when … .. … => … -- Con rango
            when … => NULL; -- Nulo
            when others => … -- Default
       end case;

Estructuras iterativas

While

       while … loop
            …
       end loop;

For

       for d in dia loop
            …
       end loop;

       for d in reverse lunes..viernes loop
            …
       end loop;
       loop
            …
       end loop;

       loop
            …;
            exit;
            …;
       end loop;

       loop
            …
            exit when…;
            …
       end loop;

Estructuración de control. Subalgoritmos

Procedimientos y funciones

Paso de parámetros:
       in (entrada), out(salida), in out (entrada/salida)

En ADA, por defecto, todas son de entrada.

procedure toto (x:T1;y:in out T2) is
       …
end toto;

toto(e,z); -- Llamada normal
toto(y=>z;x=>e) – Llamada nombrada

Funciones

function factorial(n:natural)
       return natural is
begin
       if n in 0..1
            then return 1;
       else
            return n*factorial(n-1);
       end if;
end factorial;

Existe sobrcarga, puedo llamar a 7 funciones de la misma manera (suma de coches, de motos…), que el compilador distinguirá las funciones por el contexto de los operandos (enteros, reales, vectores).
Es decir, el significado es distinguido por el contexto.

Las funciones y procedimientos deben estar en funciones y procedimientos. Hay jerarquía, y el orden importa.

Vectores

Definiciones restringidas

type t1 is array (1..10) of boolean; -- Vector de 10 posiciones de booleanos

type t2 is array (dia) of t1; -- t2 es vector de posiciones de lunes a sábado que contienen valores contenidos en t1

type t3 is array (lunes..jueves, -10..14) of t1; -- Matriz

x:t1, y:t2, z:t3;

y(i+j);
y(martes);
y(martes)(i+j);
z(martes,i+j);
x(5..8);
y(martes..viernes);

Definiciones no restringidas

type matriz is array (positive range <>. positive range <>) of real; /* range <> es de cualquier rango */

function “+”(a,b:matriz)
            return matriz is
begin .. end “+”;

Atributos relacionados con los índices

function “+”(a,b,matriz)
            return matriz is
   suma:matriz(a'range(1),a'range(2));

begin
            for i in a'range(1) loop
                        for j in a'range(2) loop
                                   suma(i,j):=a(i,j)+b(i,j);
                        end loop;
            end loop;
            return suma;
end “+”;

Constantes de tipos vectoriales

m1:=((1..3=>1.0);(1=>2.0;2=>3.0;3=>4.0));
m2:=mat23’(1=>(1=>1.0;others=>0.0);2=>(2:=1.0,others=>0.0));

Others exige límites conocidos

Tipo no restringido predefinido: strings

type string is array(positive range <>) of character;
x0:string(1..8);
subtype s1 is string(2..8);
subtype línea is string(1..80);

x1:s1;
l:linea;

1(3..10):=x0;
1(2..4:=x0(2..6);
1(1..8):=x0(1..4)&”A”&x1(2..4);

Las constantes tipo cadena entre comillas dobles.
x0 es una cadena de caracteres de longitud exactamente 8

Cadenas à Tamaño exacto. De ocho caracteres exactamente, por ejemplo
Cadena bount it à No tan estrictas. Hasta 8 caracteres

Punteros

type celda;
type enlace is access celda;
type celda is
       record
            valor:integer;
            siguiente:enlace;
       end record;
e:enlace;

e:=new celda;
e.valor:=13;

Liberación de memoria de datos inaccesibles

with unchecked_deallocation;
procedure disponer is new
       unchecked_desallocation(celda,enlace);

e:enlace;
disponer(e);