      PROGRAM FRT130900

      IMPLICIT NONE 
      INTEGER DIM
      PARAMETER (DIM=3)
      INTEGER MAT(DIM,DIM)
      CHARACTER*12 NOMEFILE
      
C useremo una funzione SPECULA per calcolare il valore richiesto dall'esercizio
      LOGICAL SPECULA

      WRITE(*,*) 'NOME FILE DI INPUT?'
      READ(*,*) NOMEFILE

      WRITE(*,*) NOMEFILE

      CALL LEGGIMATRICE(MAT,DIM,NOMEFILE)
      CALL STAMPAMATRICE(MAT, DIM)

      IF (SPECULA(MAT,DIM)) THEN
        WRITE(*,*) 'LA MATRICE E'' SPECULARE!'
      ELSE
        WRITE(*,*) 'SFORTUNATAMENTE LA MATRICE NON E'' SPECULARE'
      ENDIF
      WRITE(*,*) 'qualcosa per terminare ...'
      READ(*,*) NOMEFILE
      STOP
      END

C definizione della funzione SPECULA (soluzione dell'esercizio proposto)
C M e' una matrice quadrata di interi di dimensione D;
C la variabile locale EST e' un booleano di appoggio

C ALGORITMO
C 1) inizializzazione di EST (.TRUE.) 
C    Questo sara' il risultato della function se M e' speculare
C 2) esame di M  
C    per ogni elemento del triangolo superiore 
C    (elementi [i,j] con i=1...D e j=i+1...D)
C    se M(i,j) e` diverso da M(j,i)
C       EST=.FALSE. e si esce dal ciclo (cicli) di scansione
C 3) SPECULA vene assegnata con il contenuto di EST
C
      LOGICAL FUNCTION SPECULA (M,D)
      IMPLICIT NONE 
      INTEGER I,J,D,M(D,D)
      LOGICAL EST
     	
      I = 1
      est = .TRUE.

C mentre la specularita' della matrice non e' stata smentita (EST e' .TRUE.)
C        e I e' minore/uguale D
C    1) J=I+1
C    2) mentre 
C         la specularita' della matrice non e' stata smentita (EST e' .TRUE.)
C         e J e' minore/uguale D
C       se (i,j)=/=(j,i)
C         abbiamo smentito la specularita' (e si esegue (EST=.FALSE.)
C       altrimenti si passa al prossimo valore di J (J+1)
C
C quando EST diventa .FALSE. si esce dal ciclo interno e poi da quello esterno
C (se non diventa mai .FALSE., rimane .TRUE. e questo e' il suo valore
C all'uscita "naturale" dai cicli
C
      DO WHILE ((I.LE.D).AND.EST)
        J=I+1
        DO WHILE (J.LE.D.AND.EST)
          IF (M(I,J).NE.M(J,I)) THEN
            EST=.FALSE.
          ELSE
            J=J+1
          END IF
        END DO
        I=I+1
      END DO

      SPECULA=EST
      RETURN
      END

C definizione della subroutine LEGGIMATRICE
C legge una matrice di dimensione D dal file di nome NMF
      SUBROUTINE LEGGIMATRICE (M,D,NMF)

      IMPLICIT NONE
      INTEGER I, J, D, M(D,D)
      CHARACTER*12 NMF
	
      OPEN(9,FILE=NMF)
      DO 50 I=1,D
        READ (9,*) (M(I,J), J=1,D)
 50   CONTINUE
      CLOSE(9)

      RETURN
      END

C definizione della subroutine STAMPAMATRICE
C stampa una matrice di dimensione D su standard output
      SUBROUTINE STAMPAMATRICE (M,D)
      IMPLICIT NONE 
      INTEGER I, J, D, M(D,D)
      
      DO 60 I=1,D
        WRITE (*,*) (M(I,J), J=1,D)
 60   CONTINUE

      RETURN
      END
