-- $Id: matrix.gnat,v 1.0 2003/06/11 12:09:00 dada Exp $
-- http://dada.perl.it/shootout/
-- Ada 95 code by C.C.

with Text_IO, Ada.Strings.Fixed, Ada.Command_Line;

procedure Matrix is
   function L_Trim (Source : String; Side : Ada.Strings.Trim_End :=
               Ada.Strings.Left) return String renames Ada.Strings.Fixed.Trim;

   type Int is new Integer;
   type Int_Matrix is array (Positive range <>, Positive range <>) of Int;

   function Mk_Matrix (NRows, NCols : Natural) return Int_Matrix is
      Count    : Int := 1;
      M        : Int_Matrix (1 .. NRows, 1 .. NCols);
   begin
      for I in M'Range (1) loop
         for J in M'Range (2) loop
            M (I, J) := Count;
            Count := Count + 1;
         end loop;
      end loop;
      return M;
   end Mk_Matrix;

   procedure M_Mult (M1, M2 : Int_Matrix; MM : in out Int_Matrix) is
      pragma Inline (M_Mult);
      pragma Suppress (Index_Check);
      Sum      : Int;
   begin
      if not (M1'First (2) = M2'First (1) and M1'Last (2) = M2'Last (1) and
               M1'First (1) = MM'First (1) and M1'Last (1) = MM'Last (1) and
               M2'First (2) = MM'First (2) and M2'Last (2) = MM'Last (2)) then
         raise Constraint_Error;
      end if;
      for I in M1'Range (1) loop
         for J in M2'Range (2) loop
            Sum := 0;
            for KK in M1'Range (2) loop
               Sum := Sum + M1 (I, KK) * M2 (KK, J);
            end loop;
            MM (I, J) := Sum;
         end loop;
      end loop;
   end M_Mult;

   Size     : constant Natural := 30;
   M1, M2, MM : Int_Matrix (1 .. Size, 1 .. Size);
   N        : Positive := 1;
begin
   begin
      N := Positive'Value (Ada.Command_Line.Argument (1));
   exception
      when Constraint_Error => null;
   end;
   M1 := Mk_Matrix (Size, Size);
   M2 := Mk_Matrix (Size, Size);
   for Iter in 1 .. N loop
      M_Mult (M1, M2, MM);
   end loop;
   Text_IO.Put_Line (L_Trim (Int'Image (MM (1, 1))) & Int'Image (MM (3, 4)) &
            Int'Image (MM (4, 3)) & Int'Image (MM (5, 5)));
end Matrix;