Newsgroup: it.comp.lang.pascal
Titolo: Aiuto urgente!!!

Sto tentando da alcuni giorni di scrivere un programma che realizzi alcune
operazioni sulle liste concatenate. Ora però sono bloccata da uno "STACK
OVERFLOW ERROR". Il punto errato è nella FUNCTION UNION, che dovrebbe
realizzare l'unione di 2 liste. Ovviamente senza l' UNION non funziona
nemmeno  INTERSECTION, che fa invece l'intersezione di 2 liste.
Il codice è questo:
 PROGRAM lista (input , output) ;
USES crt ;
    CONST min = 1 ;
                         max = 10 ;
    TYPE indice = min..max ;
                   atom = integer ;
                   pointer = ^list ;
                   list = RECORD
                                    element_type    : (atomic , sublist) ;
                                    element_value   : atom ;
                                   next            : pointer ;
                                     sublist_pointer : pointer ;
                                END;
    VAR lista1,lista2,a_car,a_union : pointer ;
   FUNCTION NULL (x : pointer) : boolean ;
         BEGIN
           IF x = NIL
             THEN NULL := TRUE
               ELSE NULL := FALSE
        END ;
   FUNCTION CAR (lista : pointer) : pointer ;       (*calcola il primo
elemento della lista*)
        BEGIN
            IF NULL (lista)
               THEN CAR := NIL
             ELSE
                  BEGIN
                  car^ := lista^ ;
                     car^.next := NIL
                  END
       END ;
     FUNCTION CDR (lista : pointer) : pointer ;        (*calcola tutta la
lista tranne il primo elemento*)
          FUNCTION AUX1 (x : pointer) : pointer ;
                BEGIN              {  AUX1  }
                AUX1 := x^.next ;
                  IF NULL (x^.next)
                      THEN AUX1 := AUX1(x^.next)^.next
             END ;              {  AUX1  }
         BEGIN                {  CDR  }
            IF NULL (lista)
               THEN CDR := NIL
               ELSE CDR := AUX1 (lista)
       END ;                {  CDR  }
     FUNCTION AT_EL (x : pointer) : boolean ;      { Controlla se un
elemento è ATomic_ELement  }
          BEGIN
                IF x^.element_type = atomic
                    THEN AT_EL := TRUE
                     ELSE AT_EL := FALSE
        END ;
    FUNCTION EQ ( x,y : pointer) : string ;                {Controlla se 2
elementi sono uguali}
         BEGIN
           IF (AT_EL (x) = FALSE) OR (AT_EL (y) = FALSE)
               THEN EQ := 'EQ non eseguibile'
                      ELSE
                        IF x = y
                           THEN EQ := 'TRUE'
                            ELSE EQ := 'FALSE' ;
            END ;
     FUNCTION CONS (x , y : pointer ) : pointer ;
{Inserisce x come sottolista di y}
         BEGIN
            IF NULL (y)
                THEN cons := NIL
               ELSE  BEGIN
                          cons := y ;
                        IF NULL (x)
                           THEN cons^.sublist_pointer := NIL
                         ELSE cons^.sublist_pointer := x
              END
       END;
     FUNCTION MEMBER ( x,y : pointer ) : boolean ;
            VAR a_car,a_cdr:pointer;
                   BEGIN
                    IF NULL (y)
                      THEN MEMBER := FALSE
                     ELSE   IF NOT NULL (CAR (x))
                               THEN IF eq (x , car (y)) = 'TRUE'
                                          THEN MEMBER := TRUE
                                        ELSE  IF NOT NULL (CDR (y))
                                                THEN MEMBER := MEMBER (x ,
cdr (y))
             END ;
     FUNCTION UNION ( x , y : pointer ) : pointer ;
            VAR a_car,a_cdr : pointer ;
               BEGIN
                 IF NULL (x)
                    THEN union := y
                     ELSE   BEGIN
                                 IF NOT NULL (CAR (x))
                                 THEN   BEGIN
                                              a_car := CAR (x) ;
                                             IF NOT NULL (CDR (x))
                                                 THEN BEGIN
                                                         a_cdr := CDR (x) ;
                                                         IF MEMBER (a_car,y)
                                                        THEN UNION := UNION
(a_cdr,y)
                                                        ELSE UNION := CONS
(a_car , UNION (a_cdr , y))
                                               END
                              END
               END
    END ;
       FUNCTION INTERSECTION ( x , y : pointer ) : pointer ;
              BEGIN
                    IF NULL (x)
                         THEN intersection := NIL
                          ELSE IF MEMBER (car(x),y)
                                    THEN intersection := cons (car (x) ,
intersection (cdr (x) , y))
                                    ELSE intersection := intersection (cdr
(x) , y)
               END ;
          PROCEDURE CREALISTA (VAR lista : pointer) ;
                 VAR p : pointer ;
                                  x : integer ;
                                 i : indice ;
                              BEGIN
                                    FOR i := min TO max DO   BEGIN
                                             new (p) ;
                                               p^.element_type := atomic ;
                                            p^.element_value := random(100)
;
                                             p^.next := lista ;
                                              p^.sublist_pointer := NIL ;
                                               lista := p
                                        END
                            END ;
        PROCEDURE STAMPALISTA (lista : pointer) ;
              BEGIN
                    IF NULL (lista) THEN writeln
                       ELSE  BEGIN
                             write ('  ',lista^.element_value) ;
                          IF NOT NULL (lista^.sublist_pointer)
                           THEN STAMPALISTA (lista^.sublist_pointer) ;
                         STAMPALISTA (lista^.next)
                       END
           END ;
     BEGIN      {  MAIN  }
        clrscr;
        assign (output,'lista.ris') ;
     rewrite (output) ;
       CREALISTA (lista1) ;
      write(' Lista 1 : ');
       STAMPALISTA (lista1) ;
     write ('CAR : ') ;
      a_car:=car(lista1) ;
      IF NULL (a_car)
       THEN writeln('non eseguibile')
    ELSE STAMPALISTA (a_car) ;
     write ('CDR : ') ;
     STAMPALISTA (CDR (lista1)) ;
     CREALISTA (lista2) ;
     write ('Lista 2 : ') ;
     STAMPALISTA (lista2) ;
     write ('CONS : ') ;
     STAMPALISTA (CONS (a_car,lista2)) ;
     writeln ('EQ (LISTA 1,LISTA 2) : ', EQ (lista1,lista2)) ;
     writeln ('ATOM (LISTA 1) : ',AT_EL (lista1)) ;
     writeln ('MEMBER (LISTA 1,CDR LISTA 1) : ',MEMBER (lista1,CDR
(lista1))) ;
     a_union := union(lista1,lista2) ;
     writeln ('UNION (LISTA 1,LISTA 2) : ') ;
     STAMPALISTA (a_union) ;
     STAMPALISTA (intersection(lista1,lista2)) ;
  close (output) ;
     readln;
   END.
Ringrazio già da ora tutti coloro che vorranno aiutarmi.

...


           ELSE NULL := FALSE
si puo' fare
	NULL:=(x=NIL)
Fabio
fabi...@rocketmail.com

avrebbe senso lo stesso.
Sono d'accordo, anch'io non ho capito bene la funzione di certe istruzioni.
Vorrei analizzare il codice, ma ho una forte difficolta' a capire che cosa debba
fare.
Ho capito che stai cercando di implementare delle funzioni LISP, ma se ci
spiegassi meglio come queste funzionano forse si riuscirebbe ad implementarle in
modo diverso.
Skyscraper
----------------------------------------------------------------
"Sopra il camper la capra campa, sotto il camper la capra crepa"
--
Posted from 
itaca.ulysse.it
 [195.223.254.1]
via Mailgate.ORG Server - 
http://www.mailgate.org

quando lista non ha ancora nessun valore
Non e' vero.
La creazione della lista e' corretta, dato che la procedura che quoti non e'
l'originale !!!
La lista viene creata nell'ordine inverso a quello con cui vengono aggiunti gli
elementi.



Guarda che io non ho quotato nessuna procedure CREALISTA
La procedura che riporto nel mio post e' quella FATTA DA ME e NON
quella della signorina Paola Bellini.
Quella di Paola NON FUNZIONA.
Prova a fare:
CREALISTA(lista1);
STAMPALISTA(lista1)
e succedera' un casino.
Fabio
fabi...@rocketmail.com

l'originale !!!
Ehm !! chiedo scusa ! eh eh pensavo che stessi postando la sua routine :)
La fretta ! la fretta !...
 ___
(___)
()__
(___)
 __()
(___)


modo diverso.
Premetto per rispondere a Virgiliop Lattanzi che il compilatore è ilTurbo
Pascal 7.0 della BORLAND.
La funzione CAR deve restituire il primo elemento della lista.
Sostanzialmente l'struzione
car^ := lista^
crea una copia dell'oggetto puntato da lista e lo fa puntare da car.
L'istruzione
car^.next:=nil
isola il primo elemento da tutto il resto della lista.
La funzione CDR effettivamente è un pò contorta e l'ho riscritta così:
  FUNCTION CDR (lista : pointer) : pointer ;
    BEGIN
          IF NULL (lista)
          THEN CDR := NIL
                  ELSE CDR := lista^.next
    END ;
opera nello stesso modo di CAR e restituisce tutta la lista escluso il primo
elemento, cioè il CAR.
La funzione AT_EL deve controllare se gli elementi della lista sono di tipo
atomic o sublist, cioè se sono o no presenti sottoliste.
La funzione EQ confronta due liste osottoliste o elementi qualsiasi di
liste, se sono uguali restituisce true, altrimenrti false.
 EQ è definita solo se AT_EL risulta true, almeno così dicono i testi, ma
non chiedetemi perchè.
Fin quì però a me funzionano senza problemi. Il guaio è con tutto il resto.
CONS dovrebbe inserire x come sottolista di y, ma non funziona sempre (non
ho capito però in quali casi non funziona).
Ho apportato una modifica alla funzione che ora è :
  FUNCTION CONS (x , y : pointer ) : pointer ;
    BEGIN
        IF NULL (y)
     THEN cons := NIL
          ELSE  BEGIN
                         cons^ := y^ ;
                         IF NULL (x)
                          THEN cons^.sublist_pointer := NIL
                              ELSE cons^.sublist_pointer := x
                 END
    END;
E' cambiata solo l'istruzione
cons^:=y^
che dovrebbe funzionare come in CAR e CDR.
MEMBER è sostanzialmente la ricerca dell'elemento x nella lista y. Credevo
funzionasse, invece mi sono accorto
che restituisce sempre true, qualsiasin siano i dati in ingresso. Il codice
di questa funzione è abbastanza contorto
e mi rendo conto che esistono modi più semplici per farlo( è del tutto
inutile richiamare CAR e CDR, basterebbe una ricerca lineare)
ma per l'esame mi seve implementato ricorsivamente e con chiamate a CAR e
CDR (con la piccola differenza che dovrebbe anche funzionare). Arrivo dunque
al punto peggiore.
UNION deve fare l'unione di 2 liste.L'unione è intesa come negli insiemi,
cioè se ci sono elementi uguali non vanno ripetuti.
Anche questa deve essere ricorsiva e con chiamate a CAR e CDR.
INTERSECTION deve fare l'intersezione di 2 liste. Anche quì è intesa in
senso insiemistico, cioè deve restituire tutti e solo gli elementi comuni
alle 2 liste.
L'ultimo problema è costituito dall'istruzione nel main
a_car := CAR(lista1)
Perchè non posso usare direttamante la funzione dove mi serve ma devo
metterci la variabile a_car?
Se non uso la variabile il car no funziona più.
Concludo facendo presente che l'esame è lunedì mattina e senza questo
programma sono disperata.
Grazie
                                              CIAO


fabi...@rocketmail.com
Hai ragione ! scusami ! ;)
Skyscraper
---------------------------
andrea_...@bigfoot.com


liste, se sono uguali restituisce true, altrimenrti false.
Ma in questa funzione non dovresti controllare il campo ELEMENT_VALUE?
dovresti mettere   x^.element_value = y^.element_value
Tu invece controlli i puntatori facendo x=y
Altre cose poi non vanno.
Fabio
fabi...@rocketmail.com