SoloCodigo

Programación General => Otros Lenguajes de Programación => ADA => Mensaje iniciado por: SkG en Miércoles 10 de Diciembre de 2008, 15:14

Título: Error manejando listas
Publicado por: SkG en Miércoles 10 de Diciembre de 2008, 15:14
Hola, empecé esta año con programación en ADA y me ha surgido un problema con una práctica.

Se que el modulo funciona ya que con un programa de prueba que nos ha dado el profesor funciona y con otra practica también pero con esta otra practica me da un error, a ver si podéis echarme una mano.

criba.adb (el programa):
Código: Text
  1. ----------------------------------------------------------------
  2. -- Criba de Eratostenes
  3. --
  4. -- Creación de una lista que contenga todos los primos menores
  5. -- que el numero que el usuario introduce
  6. ----------------------------------------------------------------
  7.  
  8. with Ada.Text_IO; use Ada.Text_IO;
  9. with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
  10. with Ada.Numerics.Elementary_Functions; use Ada.Numerics.Elementary_Functions;
  11. with Lista;
  12.  
  13. procedure criba is
  14.    ----------------------------------------------------------------
  15.    -- Declaración de tipos y paquetes
  16.    ----------------------------------------------------------------
  17.    package ListaCriba is new Lista(Natural); use ListaCriba;
  18.    subtype LCriba is ListaCriba.Tipo;
  19.  
  20.    ----------------------------------------------------------------
  21.    -- Declaración de funciones y procedimientos
  22.    ----------------------------------------------------------------
  23.    function Primo(N,Div:positive) return boolean is
  24.    -- POST: Res = True si not Div(X,N) para todo valor de X|2 <= X < sqrt(N)
  25.    begin
  26.       if Div > integer(sqrt(float(N))) then
  27.          return True;
  28.       else
  29.          return (N mod Div/=0) and then Primo(N,Div+1);
  30.       end if;
  31.    end Primo;
  32.  
  33.    function Criba_Aux(N,Cand,Inc:positive) return LCriba is
  34.    begin
  35.       if Cand > N then
  36.          return Vacia;
  37.       elsif Primo(Cand,2) then
  38.          return Cons(Cand, Criba_Aux(N, Cand+Inc, 6-Inc));
  39.       else
  40.          return Criba_Aux(N, Cand+Inc, 6-Inc);
  41.       end if;
  42.    end Criba_Aux;
  43.  
  44.    function Criba(N:positive) return LCriba is
  45.    -- Incluimos 2 y 3 en la criba y empezamos desde el 5
  46.    -- POST: Devuelve todos los primos anteriores al numero especificado
  47.    begin
  48.       if Es_Vacia(N) then
  49.          return vacia;
  50.       else
  51.          return Cons(2,Cons(3,Criba_Aux(N,5,2)));
  52.       end if;
  53.    end Criba;
  54.  
  55.    procedure ImprPrimo(N:positive) is
  56.       begin
  57.       Put(N,0);
  58.    end ImprPrimo;
  59.  
  60.    procedure ImprCriba is new Escribir(ImprPrimo);
  61.  
  62.    ----------------------------------------------------------------
  63.    -- Delcaración de variables y/o constantes
  64.    ----------------------------------------------------------------
  65.    N: natural;
  66.  
  67.    ----------------------------------------------------------------
  68.    -- Parte ejecutiva
  69.    ----------------------------------------------------------------
  70. begin
  71.  
  72.    Put("Introduce un numero: "); Get(N); New_Line;
  73.    Put("Primos anteriores a ese numero:"); New_Line;
  74.    ImprCriba(Criba(N));
  75.  
  76. end criba;
  77.  
lista.ads (especificaciones del modulo):
Código: Text
  1. ----------------------------------------------------------------
  2. -- lista.ads
  3. -- Módulo para manejo de listas en Ada (Especificación)
  4. ----------------------------------------------------------------
  5.  
  6. generic type Tipo_Elemento is private; -- Tipo de los elementos
  7.  
  8. package lista is
  9.    ----------------------------------------
  10.    -- Declaración de tipos
  11.    ----------------------------------------
  12.    type Tipo is private; -- Tipo para declarar listas
  13.    type Tipo_Elementos is array (Positive range <>) of Tipo_Elemento; -- Tipo para la función ListaCons
  14.  
  15.    ----------------------------------------
  16.    -- Funciones de manejo de listas
  17.    ----------------------------------------
  18.    function Vacia return Tipo;
  19.    -- PRE: cierto
  20.    -- POST: resultado = <>
  21.  
  22.    function Es_Vacia(L:Tipo) return Boolean;
  23.    -- PRE: cierto
  24.    -- POST: resultado = (Longitud (L) - 0)
  25.  
  26.    function Primero(L:Tipo) return Tipo_Elemento;
  27.    -- PRE: Es Vacia (L)
  28.    -- POST: resultado = L(1)
  29.  
  30.    function Resto(L:Tipo) return Tipo;
  31.    -- PRE: EsVacia (L)
  32.    -- POST: resultado = L(2..)
  33.  
  34.    function Cons(E:Tipo_Elemento;L:Tipo) return Tipo;
  35.    -- PRE: cierto
  36.    -- POST: resultado(l) = E / resultado(2..) = L
  37.  
  38.    function Lista_Cons(Elementos:Tipo_Elementos) return Tipo; -- Función para manejar constantes de tipo lista
  39.    -- PRE: Cierto
  40.    -- POST: Generar una lista formada por 'elementos'
  41.  
  42.    ---------------------------------------
  43.    -- Procedimiento para imprimir listas
  44.    ----------------------------------------
  45.   generic with procedure Put_Elemento(E:Tipo_Elemento);
  46.   procedure Escribir(L:Tipo);
  47.   Error_De_Lista: exception;
  48.   private type Desc;
  49.   type Tipo is access Desc;
  50.  
  51. end lista;
  52.  
lista.adb (el modulo):
Código: Text
  1. ----------------------------------------------------------------
  2. -- lista.adb
  3. -- Módulo para manejo de listas en Ada (Implementación)
  4. ----------------------------------------------------------------
  5.  
  6. with Ada.Text_IO; use Ada.Text_IO;
  7.  
  8. package body lista is
  9.  
  10.    type Desc is record
  11.       Elemento: Tipo_Elemento;
  12.       Siguiente: Tipo;
  13.    end record;
  14.  
  15.    function Vacia return Tipo is
  16.    begin
  17.       return NULL;
  18.    end Vacia;
  19.  
  20.    function Es_Vacia(L:Tipo) return Boolean is
  21.    begin
  22.       return L = NULL;
  23.    end Es_Vacia;
  24.  
  25.    function Copia(L:Tipo) return Tipo is
  26.    Aux,Copia,Nuevo: Tipo := L;
  27.    begin
  28.       if Aux = NULL then
  29.          Copia := NULL;
  30.       else
  31.          Copia := new Desc'(Aux.ALL.Elemento,NULL);
  32.          Nuevo := Copia;
  33.          while Aux.ALL.Siguiente /= NULL loop
  34.             Aux := Aux.ALL.Siguiente;
  35.             Nuevo.ALL.Siguiente := new Desc'(Aux.ALL.Elemento,NULL);
  36.             Nuevo := Nuevo.ALL.Siguiente;
  37.          end loop;
  38.       end if;
  39.       return Copia;
  40.    end Copia;
  41.  
  42.    function Cons(E:Tipo_Elemento;L:Tipo) return Tipo is
  43.    begin
  44.       return new Desc'(E,Copia(L));
  45.    end Cons;
  46.  
  47.    function Cons_Final(E:Tipo_Elemento;L:Tipo) return Tipo is
  48.    Aux: Tipo;
  49.    begin
  50.       if L = NULL then
  51.          return new Desc'(E,NULL);
  52.       else
  53.          Aux := L;
  54.          while Aux.Siguiente /= NULL loop
  55.             Aux := Aux.Siguiente;
  56.          end loop;
  57.          Aux.Siguiente := NEW Desc'(E, NULL);
  58.          return L;
  59.       end if;
  60.    end Cons_Final;
  61.  
  62.    function Primero(L:Tipo) return Tipo_Elemento is
  63.    begin
  64.       if Es_Vacia (L) then
  65.          raise Error_De_Lista;
  66.       else
  67.          return L.Elemento;
  68.       end if;
  69.    end Primero;
  70.  
  71.    function Resto(L:Tipo) return Tipo is
  72.    begin
  73.       if Es_Vacia(L) then
  74.          raise Error_De_Lista;
  75.       else
  76.          return Copia(L.Siguiente);
  77.       end if;
  78.    end Resto;
  79.  
  80.    function Longitud(L:Tipo) return Natural is
  81.    C: Natural := 0;
  82.    LI: Tipo := L;
  83.    begin
  84.       while LI /= NULL loop
  85.          C:=C+1;
  86.          LI := LI.Siguiente;
  87.       end loop;
  88.       return C;
  89.    end Longitud;
  90.  
  91.    function Lista_Cons(Elementos:Tipo_Elementos) return Tipo is
  92.    Lista: Tipo;
  93.    I: Positive;
  94.    begin
  95.       I := 1;
  96.       Lista := Vacia;
  97.       for I in Elementos'First..Elementos'Last loop
  98.          Lista := Cons_Final(Elementos(I),Lista);
  99.       end loop;
  100.       return Lista;
  101.    end Lista_Cons;
  102.  
  103.    procedure Escribir(L:Tipo) is
  104.    LI: Tipo := L;
  105.    begin
  106.       Put("[");
  107.       while LI /= NULL loop
  108.          Put_Elemento(LI.Elemento);
  109.          LI := LI.Siguiente;
  110.          if LI /= NULL then
  111.             Put(",");
  112.          end if;
  113.       end loop;
  114.       Put("]");
  115.    end Escribir;
  116. end lista;
  117.  
 
Este es el error (compilando con GNAT 2008 en Windows 32bits y en Linux x64):
 
Código: Text
  1. $ gnatmake criba.adb
  2. gcc-ada -c criba.adb
  3. criba.adb:48:19: expected private type "Tipo" defined at lista.ads:12, instance at line 17
  4. criba.adb:48:19: found type "Standard.Integer"
  5. gnatmake: "criba.adb" compilation error
  6.  

Gracias por adelantado.
Título: Re: Error manejando listas
Publicado por: SkG en Miércoles 10 de Diciembre de 2008, 15:55
Lo solucioné, aunque de forma un poco brusca:

Código: Text
  1.    function Criba(N:positive) return LCriba is
  2.    -- Incluimos 2 y 3 en la criba y empezamos desde el 5
  3.    -- POST: Devuelve todos los primos anteriores al numero especificado
  4.    begin
  5.      ----------------------------------------------------------------
  6.      -- NOTA: Si usamos el codigo comentado nos da error. Como no
  7.      --       es posible introducir una lista vacia por teclado
  8.      --       no es necesario comprobar si es vacia
  9.      ----------------------------------------------------------------
  10.      -- 'Excepted private type "Tipo" defined at lista.ads:12, instance at line 17'
  11.      -- 'found type "Standar.Integer"'
  12.      ----------------------------------------------------------------
  13.      -- if Es_Vacia(N) then
  14.      --    return Vacia;
  15.      -- else
  16.          return Cons(2,Cons(3,Criba_Aux(N,5,2)));
  17.      -- end if;
  18.    end Criba;
  19.  

Llevaba unos días dándole vueltas al error...