{ File: insint.pas }

{ Scopo: realizzazione del tipo di dato astratto
         "insieme di interi"
         tramite liste collegate }

type
  TipoIntero    = integer;  { vengono rappresentati solo gli interi
                              nell'intervallo -MAXINT..MAXINT }

  TipoElemLista = TipoIntero;

{$I TIPOLIS.PAS }  { Inclusione delle dichiarazioni di tipo per le liste. }

  TipoInsInteri = TipoLista;


{$I LISTE.PAS }    { Inclusione delle procedure che operano sulle liste e che
                     non richiedono il confronto tra elementi. }

function UgualeElemento (intero1, intero2: TipoIntero): boolean;
{ Funzione di supporto per il confronto tra due elementi, usata nelle procedure
  sulle liste che richiedono il confronto tra elementi. }
begin
  UgualeElemento := (intero1 = intero2)
end;

{$I LISTECON.PAS } { Inclusione delle procedure che operano sulle liste e che
                     richiedono il confronto tra elementi. }


procedure InitInsInteri (var ins: TipoInsInteri);
{ Inizializza l'insieme di interi ins all'insieme vuoto inizializzando la
  lista che rappresenta l'insieme. }
begin
  InitLista(ins)
end; { InitInsInteri }


function TestInsiemeVuoto (ins: TipoInsInteri): boolean;
{ Restituisce TRUE se ins rappreseta l'insieme vuoto, FALSE altrimenti. }
begin
  TestInsiemeVuoto := TestListaVuota(ins)
end; { TestInsiemeVuoto }


procedure InserisciIntero (var ins: TipoInsInteri; intero: TipoIntero);
{ Inserisce intero nell'insieme di interi ins. }
begin
  if not EsisteInLista(ins, intero) then
    InserisciTestaLista(ins, intero)
end; { InserisciIntero }


procedure EliminaIntero (var ins: TipoInsInteri; intero: TipoIntero);
{ Elimina intero dall'insieme di interi ins. }
begin
  CancellaElementoLista(ins, intero)
end; { EliminaIntero }


function VerificaAppartenenza (ins     : TipoInsInteri;
                               intero : TipoIntero): boolean;
{ Restituisce TRUE se intero appartiene ad ins, FALSE altrimenti. }
begin
  VerificaAppartenenza := EsisteInLista(ins, intero)
end; { VerificaAppartenenza }


procedure Unione (ins1, ins2: TipoInsInteri; var ins_unione: TipoInsInteri);
{ Restituisce in ins_unione l'unione dei due insiemi ins1 e ins2. }
var
  intero : TipoIntero;
begin
  { la lista che rappresenta il primo insieme viene copiata nella lista risultato }
  CopiaLista(ins1, ins_unione);

  { ogni intero in ins2 non ancora presente in ins1 viene inserito nella lista
    risultato }
  while not TestListaVuota(ins2) do
  begin
    TestaLista(ins2, intero);
    if not EsisteInLista(ins1, intero) then
      InserisciTestaLista(ins_unione, intero);
    RestoLista(ins2)
  end
end; { Unione }


procedure Intersezione (ins1, ins2: TipoInsInteri; var ins_int: TipoInsInteri);
{ Restituisce in ins_int l'intersezione dei due insiemi ins1 e ins2. }
var
  intero : TipoIntero;
begin
  { la lista risultato viene inizializzata alla lista vuota }
  InitLista(ins_int);

  { ogni intero in ins1 presente anche in ins2 viene inserito nella lista
    risultato }
  while not TestListaVuota(ins1) do
  begin
    TestaLista(ins1, intero);
    if EsisteInLista(ins2, intero) then
      InserisciTestaLista(ins_int, intero);
    RestoLista(ins1)
  end
end; { Intersezione }


procedure Complemento (ins: TipoInsInteri; var ins_compl: TipoInsInteri);
{ Restituisce in ins_compl il complemento dell'insieme ins. }
begin
  writeln('ERRORE: la rappresentazione scelta NON permette di implementare');
  writeln('        l''operazione di complemento di un insieme');
  writeln('Viene restituito l''insieme vuoto');
  InitLista(ins_compl);
end; { Complemento }