{ File: diagtri.pas }

program Matrici;
{ Legge una matrice (N per N) di elementi reali, ne calcola la somma della
  diagonale principale, stampandola e stampando anche messaggi in cui
  dice se la matrice e' diagonale e se e' triangolare superiore.
  }

const
  N = 3;

type
  MatriceReali = array [1..N, 1..N] of real;

var
  mat  : MatriceReali;
  test : boolean;       { test sulla triangolarita' }
  s    : real;          { per la somma sulla diagonale principale }


  procedure LeggiMatReali (var m: MatriceReali);
  { Identica a quella per la lettura di matrici di interi. }
  var
    i, j : 1..N;
  begin
    for i := 1 to N do
    begin
      write(' riga ', i : 2, ' ');
      for j := 1 to N do
        read(m[i, j]);
    end;
    readln
  end; { LeggiMatReali }


  procedure StampaMatReali (var m: MatriceReali);
  { Cambia rispetto alle matrici intere:
    il formato di stampa degli elementi va curato diversamente }
  var
    i, j : 1..N;
  begin
    for i := 1 to N do
    begin
      for j := 1 to N do	  { stampa riga i-esima }
        write(m[i, j]:6:2, ' ');
      writeln;		          { a capo per la prossima riga }
    end
  end; { StampaMatReali }


  procedure SMDiag (m: MatriceReali; var somma: real);
  { Somma le componenti della diagonale principale
    (caratterizzate dal fatto di avere uguale indice di riga e colonna)
    e trasmette all'esterno il risultato nella variabile di output somma }
  var
    i : 1..N;
  begin
    for i:=1 to N do
      somma := somma + m[i,i]
  end; { SMDiag }



  procedure TestTriang (m: MatriceReali; var triang: boolean);
  var
    i, j : 1..N;    { contatori per scandire le componenti della matrice }

  { Si usa triang direttamente come accumulatore logico:
    per ogni elemento della matrice sotto alla diagonale,
        se l'elemento e' diverso da zero
           allora la matrice NON e' triangolare superiore.
           In tal caso si assegna FALSE a triang e si smette di controllare
           gli elementi.
    Se si e' arrivati a controllare anche l'ultimo elemento senza aver mai
    assegnato a TRIANG il valore true allora la matrice e' triangolare
    superiore.

    NB: Ci interessa considerare solo gli elementi della matrice che
        giacciono sotto alla diagonale principale:
        per ciascuna riga, i, gli elementi che ci interessano sono quelli con
        indice di colonna da 1 a (i-1).
        Infatti l'elemento [i,i] sta proprio sulla diagonale
        e quelli sulla riga i con indice di colonna >i stanno nella parte di
        matrice sopra alla diagonale.
        Inoltre nessun elemento della prima riga e' di interesse
        (il primo sta sulla diagonale e gli altri sopra).
  }

  begin
    triang := TRUE; { inizializzazione: allo stato dei fatti la matrice
                      potrebbe essere triangolare superiore; non lo e' se
                      incontriamo un elemento <>0 al di sotto della diagonale }

    i := 2;         { i e' indice di riga }

    while (i <= N) and triang do { per tutte le righe dalla seconda in poi,
                                mentre non abbiamo incontrato un elemento <>0 }
    begin
      j := 1;       { inizializzazione indice di colonna per questa riga }

      while (j <= (i-1)) and triang do
        { per tutti gli elementi di interesse su questa riga e mentre
          non ne abbiamo incontrato uno diverso da zero }
      begin
        if M[i,j] <> 0 then          { controllo elemento }
          triang := FALSE;

        j := j+1;                    { prossimo elemento sulla riga }
      end; { secondo while }

      i := i+1;     { incremento per prossima riga }
    end; { primo while }

    { Si esce dal ciclo con triang = FALSE solo nel caso in cui triang e' stata
      esplicitamente assegnata durante uno dei controlli.
      In tal caso la matrice NON e' triangolare superiore.
      Se triang non e' mai stato riassegnato, dopo la sua inizializzazione,
      e' rimasto = TRUE. In questo caso la matrice e' triangolare superiore}

  end; { TestTriang }


begin { Matrici }
  writeln('inizio programma: leggo una matrice ', N:2, ' X', N:2,
          ' di numeri reali');
  LeggiMatReali(mat);

  { stampa di controllo }
  writeln;
  StampaMatReali(mat);
  writeln;

  { calcolo somma diag princ e sua stampa in output }
  write('somma degli elementi sulla diagonale principale: ');
  SMDiag(mat, s);
  writeln(s:6:2);
  writeln;

  { verifica triangolare superiore }
  write(' la matrice ');
  TestTriang(mat, test);
  if test then
    writeln('e'' triangolare superiore.')
  else
    writeln('non e'' triangolare superiore.');
  { readln }
end. { Matrici }