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

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

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

   subtype Nat is Interfaces.Integer_32 range 0 .. Interfaces.Integer_32'Last;
   subtype Pos is Nat range 1 .. Nat'Last;         --  Largest is 2_147_483_647
   use type Nat;

   function Ack (M, N : Nat) return Pos is
      pragma Suppress (Overflow_Check);
      pragma Suppress (Range_Check);
   begin
      if M = 0 then
         return N + 1;
      elsif N = 0 then
         return Ack (M - 1, 1);
      else
         return Ack (M - 1, Ack (M, N - 1));
      end if;
   end Ack;

   N        : Pos := 1;
begin
   if Ada.Command_Line.Argument_Count > 0 then
      N := Pos'Value (Ada.Command_Line.Argument (1));
   end if;
   Text_IO.Put_Line ("Ack(3," & L_Trim (Pos'Image (N)) & "):" &
            Pos'Image (Ack (3, N)));
end Ackermann;