(*   This program reads in pairs of two-dimensional square matrices of
integers from the default input file, computes the product, and writes
the results to the default output file.

variables:
   MatrixSize - number of rows or columns (all matrices are square)
   InputMatrixOne, InputMatrixTwo - integer input matrices
   OutputMatrix - integer output matrix
   QuitChar - character variable to query the user to quit    *)

program MatrixMult(Input,Output);

const MatrixSize =  8;

type  Matrices = array[1..MatrixSize,1..MatrixSize] of LONGINT;

var   InputMatrixOne, InputMatrixTwo, OutputMatrix : Matrices;
      QuitChar : char;

(* ----------------------------------------------------
Prompts user to enter a matrix and reads it in by columns/rows *)

  procedure ReadMatrix(var InMatrix : Matrices);
  var I,J : integer;
  begin
      writeln('INPUT AN 8X8 MATRIX:'); 
      for I := 1 to MatrixSize do begin
          for J := 1 to MatrixSize do read(InMatrix[I,J]);
          readln
          end; (* for *)
      writeln; writeln
  end; (* ReadMatrix *)

(* ----------------------------------------------------
Writes out a matrix by columns/rows                         *)

  procedure WriteMatrix(OutMatrix : Matrices);
  var I,J : integer;
  begin
      writeln; writeln('MATRIX PRODUCT IS:'); writeln;
      for I := 1 to MatrixSize do begin
          for J := 1 to MatrixSize do write(OutMatrix[I,J] : 4);
          writeln
          end; (* for *)
      writeln; writeln
  end;(* WriteMatrix *)

(* -----------------------------------------------------
Multiplies two input matrices                             *)

  procedure Product(var ProdMatrix : Matrices;
                        OneMatrix,TwoMatrix : Matrices);
  var I, J, K : integer;
      Result  : LONGINT;
  begin
      for I := 1 to MatrixSize do 
          for J := 1 to MatrixSize do begin
              Result := 0;
              for K := 1 to MatrixSize do
                  Result := Result + OneMatrix[I,K] * TwoMatrix[K,J];
              ProdMatrix[I,J] := Result
              end (* for *)
  end; (* Product *)

(* -----------------------------------------------------*)
begin (* MultMatrix *)
    repeat
        ReadMatrix(InputMatrixOne);    (* input first matrix *)
        ReadMatrix(InputMatrixTwo);    (* input second matrix *)
        Product(OutputMatrix,InputMatrixOne,InputMatrixTwo); (* multiply them *)
        WriteMatrix(OutputMatrix);     (* output the resulting matrix *)
        write('ANOTHER MATRIX?  ');    (* query for another matrix *)
        read(QuitChar); writeln
    until not (QuitChar in ['Y','y'])
end. (* MultMatrix *)
