[inizio] [indice generale] [precedente] [successivo] [indice analitico] [contributi]


179. Scheme: esempi di programmazione

Questo capitolo raccoglie solo alcuni esempi di programmazione, in parte già descritti in altri capitoli. Lo scopo di questi esempi è solo didattico, utilizzando forme non ottimizzate per la velocità di esecuzione.

179.1 Problemi elementari di programmazione

In questa sezione vengono mostrati alcuni algoritmi elementari portati in Scheme. Per la spiegazione degli algoritmi, se non sono già conosciuti, occorre leggere quanto riportato nel capitolo 152.

179.1.1 Somma tra due numeri positivi

Il problema della somma tra due numeri positivi, attraverso l'incremento unitario, è stato descritto nella sezione 152.2.1.

; ======================================================================
; somma1.scm 
; Somma esclusivamente valori positivi.
; ======================================================================

; ======================================================================
; (somma <x> <y>)
; ----------------------------------------------------------------------
(define (somma x y)
    (define z x)
    (define i 1)

    (do ()
	((> i y))

	(set! z (+ z 1))
	(set! i (+ i 1))
    )

    z
)

; ======================================================================
; Inizio del programma.
; ----------------------------------------------------------------------
(define x 0)
(define y 0)
(define z 0)

(display "Inserisci il primo numero intero positivo: ")
(set! x (read))
(newline)
(display "Inserisci il secondo numero intero positivo: ")
(set! y (read))
(newline)
(set! z (somma x y))
(display x) (display " + ") (display y) (display " = ") (display z)
(newline)

; ======================================================================

In alternativa, si può modificare la funzione `somma', in modo che il ciclo `do' gestisca la dichiarazione e l'incremento delle variabili che usa. Tuttavia, in questo caso, la variabile `z' deve essere «copiata» in modo da poter trasmettere il risultato all'esterno del ciclo `do'.

(define (somma x y)
    (define risultato 0)

    (do ( (z x (+ z 1)) (i 1 (+ i 1)) )
	((> i y))
	(set! risultato z)
    )

    risultato
)

Volendo gestire la cosa in modo un po' più elegante, occorre togliere la variabile `z' dalla gestione del ciclo `do':

(define (somma x y)
    (define z x)

    (do ( (i 1 (+ i 1)) )
	((> i y))
	(set! z (+ z 1))
    )

    z
)

179.1.2 Moltiplicazione di due numeri positivi attraverso la somma

Il problema della moltiplicazione tra due numeri positivi, attraverso la somma, è stato descritto nella sezione 152.2.2.

; ======================================================================
; moltiplica1.scm 
; Moltiplica esclusivamente valori positivi.
; ======================================================================

; ======================================================================
; (moltiplica <x> <y>)
; ----------------------------------------------------------------------
(define (moltiplica x y)
    (define z 0)
    (define i 1)

    (do ()
	((> i y))

	(set! z (+ z x))
	(set! i (+ i 1))
    )

    z
)

; ======================================================================
; Inizio del programma.
; ----------------------------------------------------------------------
(define x 0)
(define y 0)
(define z 0)

(display "Inserisci il primo numero intero positivo: ")
(set! x (read))
(newline)
(display "Inserisci il secondo numero intero positivo: ")
(set! y (read))
(newline)
(set! z (moltiplica x y))
(display x) (display " * ") (display y) (display " = ") (display z)
(newline)

; ======================================================================

In alternativa, si può modificare la funzione `moltiplica', in modo che il ciclo `do' gestisca la dichiarazione e l'incremento dell'indice `i'.

(define (moltiplica x y)
    (define z 0)

    (do ( (i 1 (+ i 1)) )
	((> i y))

	(set! z (+ z x))
    )

    z
)

179.1.3 Divisione intera tra due numeri positivi

Il problema della divisione tra due numeri positivi, attraverso la sottrazione, è stato descritto nella sezione 152.2.3.

; ======================================================================
; dividi1.scm 
; Divide esclusivamente valori positivi.
; ======================================================================

; ======================================================================
; (dividi <x> <y>)
; ----------------------------------------------------------------------
(define (dividi x y)
    (define z 0)
    (define i x)

    (do ()
	((< i y))

	(set! i (- i y))
	(set! z (+ z 1))
    )

    z
)

; ======================================================================
; Inizio del programma.
; ----------------------------------------------------------------------
(define x 0)
(define y 0)
(define z 0)

(display "Inserisci il primo numero intero positivo: ")
(set! x (read))
(newline)
(display "Inserisci il secondo numero intero positivo: ")
(set! y (read))
(newline)
(set! z (dividi x y))
(display x) (display " / ") (display y) (display " = ") (display z)
(newline)

; ======================================================================

In alternativa, si può modificare la funzione `dividi', in modo che il ciclo `do' gestisca la dichiarazione e il decremento della variabile `i'. Per la precisione, la variabile `z' non può essere dichiarata nello stesso modo, perché serve anche al di fuori del ciclo.

(define (dividi x y)
    (define z 0)

    (do ( (i x (- i y)) )
	((< i y))

	(set! z (+ z 1))
    )

    z
)

179.1.4 Elevamento a potenza

Il problema dell'elevamento a potenza tra due numeri positivi, attraverso la moltiplicazione, è stato descritto nella sezione 152.2.4.

; ======================================================================
; potenza1.scm 
; Eleva a potenza.
; ======================================================================

; ======================================================================
; (potenza <x> <y>)
; ----------------------------------------------------------------------
(define (potenza x y)
    (define z 1)
    (define i 1)

    (do ()
	((> i y))

	(set! z (* z x))
	(set! i (+ i 1))
    )

    z
)

; ======================================================================
; Inizio del programma.
; ----------------------------------------------------------------------
(define x 0)
(define y 0)
(define z 0)

(display "Inserisci il primo numero intero positivo: ")
(set! x (read))
(newline)
(display "Inserisci il secondo numero intero positivo: ")
(set! y (read))
(newline)
(set! z (potenza x y))
(display x) (display " ** ") (display y) (display " = ") (display z)
(newline)

; ======================================================================

In alternativa, si può modificare la funzione `potenza', in modo che il ciclo `do' gestisca la dichiarazione e l'incremento della variabile `i'.

(define (potenza x y)
    (define z 1)

    (do ( (i 1 (+ i 1)) )
	((> i y))

	(set! z (* z x))
    )

    z
)

È possibile usare anche un algoritmo ricorsivo.

(define (potenza x y)
    (if (= x 0)
	0
	(if (= y 0)
	    1
	    (* x (potenza x (- y 1)))
	)
    )
)

179.1.5 Radice quadrata

Il problema della radice quadrata è stato descritto nella sezione 152.2.5.

; ======================================================================
; radice1.scm 
; Radice quadrata.
; ======================================================================

; ======================================================================
; (radice <x>)
; ----------------------------------------------------------------------
(define (radice x)
    (define z -1)
    (define t 0)
    (define uscita #f)

    (do ()
	(uscita)

	(set! z (+ z 1))
	(set! t (* z z))
	(if (> t x)
	    ; È stato superato il valore massimo
	    (begin
		(set! z (- z 1))
		(set! uscita #t)
	    )
	)
    )

    z
)

; ======================================================================
; Inizio del programma.
; ----------------------------------------------------------------------
(define x 0)
(define z 0)

(display "Inserisci il numero intero positivo: ")
(set! x (read))
(newline)
(set! z (radice x))
(display "La radice quadrata di ") (display x) (display " è ") (display z)
(newline)

; ======================================================================

179.1.6 Fattoriale

Il problema del fattoriale è stato descritto nella sezione 152.2.6.

; ======================================================================
; fattoriale1.scm 
; Fattoriale.
; ======================================================================

; ======================================================================
; (fattoriale <x>)
; ----------------------------------------------------------------------
(define (fattoriale x)
    (define i (- x 1))

    (do ()
	( (<= i 0) )

	(set! x (* x i))
	(set! i (- i 1))
    )

    x
)

; ======================================================================
; Inizio del programma.
; ----------------------------------------------------------------------
(define x 0)
(define z 0)

(display "Inserisci il numero intero positivo: ")
(set! x (read))
(newline)
(set! z (fattoriale x))
(display x) (display "! = ") (display z)
(newline)

; ======================================================================

In alternativa, l'algoritmo si può tradurre in modo ricorsivo.

(define (fattoriale x)
    (if (> x 1)
	(* x (fattoriale (- x 1)))
	1
    )
)

179.1.7 Massimo comune divisore

Il problema del massimo comune divisore, tra due numeri positivi, è stato descritto nella sezione 152.2.7.

; ======================================================================
; mcd1.scm 
; Massimo Comune Divisore.
; ======================================================================

; ======================================================================
; (moltiplica <x> <y>)
; ----------------------------------------------------------------------
(define (mcd x y)
    (do ()
	( (= x y) )

	(if (> x y)
	    (set! x (- x y))
	    (set! y (- y x))
	)
    )

    x
)

; ======================================================================
; Inizio del programma.
; ----------------------------------------------------------------------
(define x 0)
(define y 0)
(define z 0)

(display "Inserisci il primo numero intero positivo: ")
(set! x (read))
(newline)
(display "Inserisci il secondo numero intero positivo: ")
(set! y (read))
(newline)
(set! z (mcd x y))
(display "MCD di ") (display x) (display " e ") (display y)
(display " è ") (display z)
(newline)

; ======================================================================

179.1.8 Numero primo

Il problema della determinazione se un numero sia primo o meno, è stato descritto nella sezione 152.2.8.

; ======================================================================
; primo1.scm 
; Numero primo.
; ======================================================================

; ======================================================================
; (primo <x>)
; ----------------------------------------------------------------------
(define (primo x)
    (define np #t)
    (define i 2)
    (define j 0)

    (do ()
	( (or (>= i x) (not np)) )

	(set! j (truncate (/ x i)))
	(set! j (- x (* j i)))
	(if (= j 0)
	    (set! np #f)
	    (set! i (+ i 1))
	)
    )

    np
)

; ======================================================================
; Inizio del programma.
; ----------------------------------------------------------------------
(define x 0)

(display "Inserisci un numero intero positivo: ")
(set! x (read))
(newline)
(if (primo x)
    (display "È un numero primo")
    (display "Non è un numero primo")
)
(newline)

; ======================================================================

179.2 Scansione di array

In questa sezione vengono mostrati alcuni algoritmi, legati alla scansione degli array, portati in Scheme, dove vengono usati i vettori di questo linguaggio. Per la spiegazione degli algoritmi, se non sono già conosciuti, occorre leggere quanto riportato nel capitolo 152.

179.2.1 Ricerca sequenziale

Il problema della ricerca sequenziale all'interno di un array, è stato descritto nella sezione 152.3.1.

; ======================================================================
; ricerca_sequenziale1.scm 
; Ricerca Sequenziale.
; ======================================================================

; ======================================================================
; (ricerca <vettore> <x> <ele-inf> <ele-sup>)
; ----------------------------------------------------------------------
(define (ricerca vettore x a z)
    (define risultato -1)

    (do ( (i a (+ i 1)) )
	( (> i z) )

	(if (= x (vector-ref vettore i))
	    (set! risultato i)
	)
    )
    risultato
)

; ======================================================================
; Inizio del programma.
; ----------------------------------------------------------------------

(define DIM 100)
(define vettore (make-vector DIM))
(define x 0)
(define i 0)
(define z 0)

(display "Inserire la quantità di elementi; ")
(display DIM)
(display " al massimo: ")
(set! z (read))
(newline)

(if (> z DIM)
    (set! z DIM)
)

(display "Inserire i valori del vettore.")
(newline)
(do ( (i 0 (+ i 1)) )
    ( (>= i z) )

    (display "elemento ")
    (display i)
    (display " ")
    (vector-set! vettore i (read))
    (newline)
)

(display "Inserire il valore da cercare: ")
(set! x (read))
(newline)

(set! i (ricerca vettore x 0 (- z 1)))

(display "Il valore cercato si trova nell'elemento ")
(display i)
(newline)

; ======================================================================

Esiste anche una soluzione ricorsiva che viene mostrata di seguito:

(define (ricerca vettore x a z)
    (if (> a z)
	; La corrispondenza non è stata trovata.
	1
	(if (= x (vector-ref vettore a))
	    a
	    (ricerca vettore x (+ a 1) z)
	)
    )
)

179.2.2 Ricerca binaria

Il problema della ricerca binaria all'interno di un array, è stato descritto nella sezione 152.3.2.

; ======================================================================
; ricerca_binaria1.scm 
; Ricerca Binaria.
; ======================================================================

; ======================================================================
; (ricerca <vettore> <x> <ele-inf> <ele-sup>)
; ----------------------------------------------------------------------
(define (ricerca vettore x a z)
    (define m (truncate (/ (+ a z) 2)))

    (if (or (< m a) (> m z))
	; Non restano elementi da controllare: l'elemento cercato
	; non c'è.
	-1

	(if (< x (vector-ref vettore m))
	    ; Si ripete la ricerca nella parte inferiore.
    	    (ricerca vettore x a (- m 1))

	    (if (> x (vector-ref vettore m))
    		; Si ripete la ricerca nella parte superiore.
		(ricerca vettore x (+ m 1) z)

		; Se x è uguale a vettore[m], l'obiettivo è
		; stato trovato.
		m
	    )
	)
    )
)		

; ======================================================================
; Inizio del programma.
; ----------------------------------------------------------------------

(define DIM 100)
(define vettore (make-vector DIM))
(define x 0)
(define i 0)
(define z 0)

(display "Inserire la quantità di elementi; ")
(display DIM)
(display " al massimo: ")
(set! z (read))
(newline)

(if (> z DIM)
    (set! z DIM)
)

(display "Inserire i valori del vettore (in modo ordinato).")
(newline)
(do ( (i 0 (+ i 1)) )
    ( (>= i z) )

    (display "elemento ")
    (display i)
    (display " ")
    (vector-set! vettore i (read))
    (newline)
)

(display "Inserire il valore da cercare: ")
(set! x (read))
(newline)

(set! i (ricerca vettore x 0 (- z 1)))

(display "Il valore cercato si trova nell'elemento ")
(display i)
(newline)

; ======================================================================

179.3 Algoritmi tradizionali

In questa sezione vengono mostrati alcuni algoritmi tradizionali portati in Scheme. Per la spiegazione degli algoritmi, se non sono già conosciuti, occorre leggere quanto riportato nel capitolo 152.

179.3.1 Bubblesort

Il problema del Bubblesort è stato descritto nella sezione 152.4.1. Viene mostrato prima una soluzione iterativa, e in seguito la funzione `bsort' in versione ricorsiva.

; ======================================================================
; bsort1.scm 
; Bubblesort.
; ======================================================================

; ======================================================================
; (ordina <vettore> <ele-inf> <ele-sup>)
; ----------------------------------------------------------------------
(define (ordina vettore a z)
    (define scambio 0)

    (do ( (j a (+ j 1)) )
	( (>= j z) )
	
	(do ( (k (+ j 1) (+ k 1)) )
	    ( (> k z) )

	    (if (< (vector-ref vettore k) (vector-ref vettore j))
		; Scambia i valori.
		(begin
		    (set! scambio (vector-ref vettore k))
		    (vector-set! vettore k (vector-ref vettore j))
		    (vector-set! vettore j scambio)
		)
	    )
        )
    )

    vettore
)

; ======================================================================
; Inizio del programma.
; ----------------------------------------------------------------------

(define DIM 100)
(define vettore (make-vector DIM))
(define x 0)
(define i 0)
(define z 0)

(display "Inserire la quantità di elementi; ")
(display DIM)
(display " al massimo: ")
(set! z (read))
(newline)

(if (> z DIM)
    (set! z DIM)
)

(display "Inserire i valori del vettore.")
(newline)
(do ( (i 0 (+ i 1)) )
    ( (>= i z) )

    (display "elemento ")
    (display i)
    (display " ")
    (vector-set! vettore i (read))
    (newline)
)

(set! vettore (ordina vettore 0 (- z 1)))

(display "Il vettore ordinato è il seguente: ")
(newline)
(do ( (i 0 (+ i 1)) )
    ( (>= i z) )

    (display (vector-ref vettore i))
    (display " ")
)
(newline)

; ======================================================================

Segue la funzione `ordina' in versione ricorsiva.

(define (ordina vettore a z)
    (define scambio 0)

    (if (< a z)
	(begin
	    ; Scansione interna dell'array per collocare nella
	    ; posizione a l'elemento giusto.
	    (do ( (k (+ a 1) (+ k 1)) )
		( (> k z) )

		(if (< (vector-ref vettore k) (vector-ref vettore a))
		    ; Scambia i valori.
		    (begin
			(set! scambio (vector-ref vettore k))
			(vector-set! vettore k (vector-ref vettore a))
			(vector-set! vettore a scambio)
		    )
		)
	    )

    	    (set! vettore (ordina vettore (+ a 1) z))
	)
    )
    vettore
)

179.3.2 Torre di Hanoi

Il problema della torre di Hanoi è stato descritto nella sezione 152.4.2.

; ======================================================================
; hanoi1.scm 
; Torre di Hanoi.
; ======================================================================

; ======================================================================
; (hanoi <n-anelli> <piolo-iniziale> <piolo-finale>)
; ----------------------------------------------------------------------
(define (hanoi n p1 p2)
    (if (> n 0)
	(begin
	    (hanoi (- n 1) p1 (- 6 (+ p1 p2)))
	    (begin
		(display "Muovi l'anello ")
		(display n)
		(display " dal piolo ")
		(display p1)
		(display " ")
		(display p2)
		(newline)
	    )
	    (hanoi (- n 1) (- 6 (+ p1 p2)) p2)
	)
    )
)


; ======================================================================
; Inizio del programma.
; ----------------------------------------------------------------------
(define n 0)
(define p1 0)
(define p2 0)

(display "Inserisci il numero di pioli: ")
(set! n (read))
(newline)
(display "Inserisci il numero del piolo iniziale (da 1 a 3): ")
(set! p1 (read))
(newline)
(display "Inserisci il numero del piolo finale (da 1 a 3): ")
(set! p2 (read))
(newline)
(hanoi n p1 p2)

; ======================================================================

179.3.3 Quicksort

L'algoritmo del Quicksort è stato descritto nella sezione 152.4.3.

; ======================================================================
; qsort1.scm 
; Quicksort.
; ======================================================================

; ----------------------------------------------------------------------
; Dichiara il vettore a cui faranno riferimento tutte le funzioni.
; Il vettore non viene passato alle funzioni tra gli argomenti, per
; semplificare le funzioni, soprattutto nel caso di «part», che
; deve restituire anche un altro valore.
; ----------------------------------------------------------------------
(define DIM 100)
(define vettore (make-vector DIM))

; ======================================================================
; (inverti-elementi <indice-1> <indice-2>)
; ----------------------------------------------------------------------
(define (inverti-elementi a z)
    (define scambio 0)
    (set! scambio (vector-ref vettore a))
    (vector-set! vettore a (vector-ref vettore z))
    (vector-set! vettore z scambio)
)

; ======================================================================
; (part <ele-inf> <ele-sup>)
; ----------------------------------------------------------------------
(define (part a z)
    ; Si assume che «a» sia inferiore a «z».
    (define i (+ a 1))
    (define cf z)
    ; Vengono preparate delle variabili per controllare l'uscita dai cicli.
    (define uscita1 #f)
    (define uscita2 #f)
    (define uscita3 #f)

    ; Inizia il ciclo di scansione dell'array.
    (set! uscita1 #f)
    (do ()
	(uscita1)
	(set! uscita2 #f)
	(do ()
	    (uscita2)

	    ; Sposta «i» a destra.
	    (if (or
		    (> (vector-ref vettore i) (vector-ref vettore a))
		    (>= i cf)
		)
		; Interrompe il ciclo interno.
		(set! uscita2 #t)
		; Altrimenti incrementa l'indice
		(set! i (+ i 1))
	    )
	)
	(set! uscita3 #f)
	(do ()
	    (uscita3)

	    ; Sposta «cf» a sinistra.
	    (if (<= (vector-ref vettore cf) (vector-ref vettore a))
		; Interrompe il ciclo interno.
		(set! uscita3 #t)
		; Altrimenti decrementa l'indice
		(set! cf (- cf 1))
	    )
	)

	(if (<= cf i)
	    ; È avvenuto l'incontro tra «i» e «cf».
	    (set! uscita1 #t)
	    ; Altrimenti vengono scambiati i valori.
	    (begin
		(inverti-elementi i cf)
		(set! i (+ i 1))
		(set! cf (- cf 1))
	    )
	)
    )

    ; A questo punto vettore[a..z] è stato ripartito e «cf» è la
    ; collocazione di vettore[a].
    (inverti-elementi a cf)

    ; A questo punto, vettore[cf] è un elemento (un valore) nella
    ; posizione giusta, e «cf» è ciò che viene restituito.
    cf
)

; ======================================================================
; (ordina <ele-inf> <ele-sup>)
; ----------------------------------------------------------------------
(define (ordina a z)
    ; Viene preparata la variabile «cf».
    (define cf 0)

    (if (> z a)
	(begin
	    (set! cf (part a z))
	    (ordina a (- cf 1))
	    (ordina (+ cf 1) z)
	)
    )
)

; ======================================================================
; Inizio del programma.
; ----------------------------------------------------------------------

(define x 0)
(define i 0)
(define z 0)

(display "Inserire la quantità di elementi; ")
(display DIM)
(display " al massimo: ")
(set! z (read))
(newline)

(if (> z DIM)
    (set! z DIM)
)

(display "Inserire i valori del vettore.")
(newline)
(do ( (i 0 (+ i 1)) )
    ( (>= i z) )

    (display "elemento ")
    (display i)
    (display " ")
    (vector-set! vettore i (read))
    (newline)
)

; Il vettore non viene trasferito come argomento della funzione,
; ma risulta accessibile esternamente.
(ordina 0 (- z 1))

(display "Il vettore ordinato è il seguente: ")
(newline)
(do ( (i 0 (+ i 1)) )
    ( (>= i z) )

    (display (vector-ref vettore i))
    (display " ")
)
(newline)

; ======================================================================

179.3.4 Permutazioni

L'algoritmo ricorsivo delle permutazioni è stato descritto nella sezione 152.4.4.

; ======================================================================
; permuta1.scm 
; Permutazioni.
; ======================================================================

; ----------------------------------------------------------------------
; Dichiara il vettore a cui faranno riferimento tutte le funzioni.
; ----------------------------------------------------------------------
(define DIM 100)
(define vettore (make-vector DIM))

; ----------------------------------------------------------------------
; Sempre per motivi pratici, rende disponibile la dimensione utilizzata
; effettivamente.
; ----------------------------------------------------------------------
(define n-elementi 0)

; ======================================================================
; (inverti-elementi <indice-1> <indice-2>)
; ----------------------------------------------------------------------
(define (inverti-elementi a z)
    (define scambio 0)
    (set! scambio (vector-ref vettore a))
    (vector-set! vettore a (vector-ref vettore z))
    (vector-set! vettore z scambio)
)

; ======================================================================
; (visualizza)
; ----------------------------------------------------------------------
(define (visualizza)
    (do ( (i 0 (+ i 1)) )
	( (>= i n-elementi) )

	(display (vector-ref vettore i))
	(display " ")
    )
    (newline)
)

; ======================================================================
; (permuta <inizio> <fine>)
; ----------------------------------------------------------------------
(define (permuta a z)
    (define k 0)

    ; Se il segmento di array contiene almeno due elementi, si
    ; procede.
    (if (>= (- z a) 1)
	; Inizia un ciclo di scambi tra l'ultimo elemento e uno
	; degli altri contenuti nel segmento di array.
	(do ( (k z (- k 1)) )
	    ( (< k a) )

	    ; Scambia i valori.
	    (inverti-elementi k z)

	    ; Esegue una chiamata ricorsiva per permutare un
	    ; segmento più piccolo dell'array.
	    (permuta a (- z 1))

	    ; Scambia i valori.
	    (inverti-elementi k z)
	)

	; Altrimenti, visualizza l'array e utilizza una variabile
	; dichiarata globalmente.
	(visualizza)
    )
)

; ======================================================================
; Inizio del programma.
; ----------------------------------------------------------------------
(display "Inserire la quantità di elementi; ")
(display DIM)
(display " al massimo: ")
(set! n-elementi (read))
(newline)

(if (> n-elementi DIM)
    (set! n-elementi DIM)
)

(display "Inserire i valori del vettore.")
(newline)
(do ( (i 0 (+ i 1)) )
    ( (>= i n-elementi) )

    (display "elemento ")
    (display i)
    (display " ")
    (vector-set! vettore i (read))
    (newline)
)

; Il vettore non viene trasferito come argomento della funzione,
; ma risulta accessibile esternamente.
(permuta 0 (- n-elementi 1))

; ======================================================================

---------------------------

Appunti Linux 2000.04.12 --- Copyright © 1997-2000 Daniele Giacomini --  daniele @ pluto.linux.it


[inizio] [indice generale] [precedente] [successivo] [indice analitico] [contributi]