------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--        S Y S T E M . P E R F E C T _ H A S H _ G E N E R A T O R S       --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--                     Copyright (C) 2002-2021, AdaCore                     --
--                                                                          --
-- GNAT is free software;  you can  redistribute it  and/or modify it under --
-- terms of the  GNU General Public License as published  by the Free Soft- --
-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
--                                                                          --
-- As a special exception under Section 7 of GPL version 3, you are granted --
-- additional permissions described in the GCC Runtime Library Exception,   --
-- version 3.1, as published by the Free Software Foundation.               --
--                                                                          --
-- You should have received a copy of the GNU General Public License and    --
-- a copy of the GCC Runtime Library Exception along with this program;     --
-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
-- <http://www.gnu.org/licenses/>.                                          --
--                                                                          --
-- GNAT was originally developed  by the GNAT team at  New York University. --
-- Extensive contributions were provided by Ada Core Technologies Inc.      --
--                                                                          --
------------------------------------------------------------------------------

with GNAT.Heap_Sort_G;
with GNAT.Table;

with System.OS_Lib; use System.OS_Lib;

package body System.Perfect_Hash_Generators is

   --  We are using the algorithm of J. Czech as described in Zbigniew J.
   --  Czech, George Havas, and Bohdan S. Majewski ``An Optimal Algorithm for
   --  Generating Minimal Perfect Hash Functions'', Information Processing
   --  Letters, 43(1992) pp.257-264, Oct.1992

   --  This minimal perfect hash function generator is based on random graphs
   --  and produces a hash function of the form:

   --             h (w) = (g (f1 (w)) + g (f2 (w))) mod m

   --  where f1 and f2 are functions that map strings into integers, and g is
   --  a function that maps integers into [0, m-1]. h can be order preserving.
   --  For instance, let W = {w_0, ..., w_i, ..., w_m-1}, h can be defined
   --  such that h (w_i) = i.

   --  This algorithm defines two possible constructions of f1 and f2. Method
   --  b) stores the hash function in less memory space at the expense of
   --  greater CPU time.

   --  a) fk (w) = sum (for i in 1 .. length (w)) (Tk (i, w (i))) mod n

   --     size (Tk) = max (for w in W) (length (w)) * size (used char set)

   --  b) fk (w) = sum (for i in 1 .. length (w)) (Tk (i) * w (i)) mod n

   --     size (Tk) = max (for w in W) (length (w)) but the table lookups are
   --     replaced by multiplications.

   --  where Tk values are randomly generated. n is defined later on but the
   --  algorithm recommends to use a value a little bit greater than 2m. Note
   --  that for large values of m, the main memory space requirements comes
   --  from the memory space for storing function g (>= 2m entries).

   --  Random graphs are frequently used to solve difficult problems that do
   --  not have polynomial solutions. This algorithm is based on a weighted
   --  undirected graph. It comprises two steps: mapping and assignment.

   --  In the mapping step, a graph G = (V, E) is constructed, where = {0, 1,
   --  ..., n-1} and E = {(for w in W) (f1 (w), f2 (w))}. In order for the
   --  assignment step to be successful, G has to be acyclic. To have a high
   --  probability of generating an acyclic graph, n >= 2m. If it is not
   --  acyclic, Tk have to be regenerated.

   --  In the assignment step, the algorithm builds function g. As G is
   --  acyclic, there is a vertex v1 with only one neighbor v2. Let w_i be
   --  the word such that v1 = f1 (w_i) and v2 = f2 (w_i). Let g (v1) = 0 by
   --  construction and g (v2) = (i - g (v1)) mod n (or h (i) - g (v1) mod n).
   --  If word w_j is such that v2 = f1 (w_j) and v3 = f2 (w_j), g (v3) = (j -
   --  g (v2)) mod (or to be general, (h (j) - g (v2)) mod n). If w_i has no
   --  neighbor, then another vertex is selected. The algorithm traverses G to
   --  assign values to all the vertices. It cannot assign a value to an
   --  already assigned vertex as G is acyclic.

   subtype Word_Id   is Integer;
   subtype Key_Id    is Integer;
   subtype Vertex_Id is Integer;
   subtype Edge_Id   is Integer;
   subtype Table_Id  is Integer;

   No_Vertex : constant Vertex_Id := -1;
   No_Edge   : constant Edge_Id   := -1;
   No_Table  : constant Table_Id  := -1;

   type Word_Type is new String_Access;
   procedure Free_Word (W : in out Word_Type) renames Free;
   function New_Word (S : String) return Word_Type;

   procedure Resize_Word (W : in out Word_Type; Len : Natural);
   --  Resize string W to have a length Len

   type Key_Type is record
      Edge : Edge_Id;
   end record;
   --  A key corresponds to an edge in the algorithm graph

   type Vertex_Type is record
      First : Edge_Id;
      Last  : Edge_Id;
   end record;
   --  A vertex can be involved in several edges. First and Last are the bounds
   --  of an array of edges stored in a global edge table.

   type Edge_Type is record
      X   : Vertex_Id;
      Y   : Vertex_Id;
      Key : Key_Id;
   end record;
   --  An edge is a peer of vertices. In the algorithm, a key is associated to
   --  an edge.

   package WT is new GNAT.Table (Word_Type, Word_Id, 0, 32, 32);
   package IT is new GNAT.Table (Integer, Integer, 0, 32, 32);
   --  The two main tables. WT is used to store the words in their initial
   --  version and in their reduced version (that is words reduced to their
   --  significant characters). As an instance of GNAT.Table, WT does not
   --  initialize string pointers to null. This initialization has to be done
   --  manually when the table is allocated. IT is used to store several
   --  tables of components containing only integers.

   function Image (Int : Integer; W : Natural := 0) return String;
   function Image (Str : String;  W : Natural := 0) return String;
   --  Return a string which includes string Str or integer Int preceded by
   --  leading spaces if required by width W.

   function Trim_Trailing_Nuls (Str : String) return String;
   --  Return Str with trailing NUL characters removed

   Output : File_Descriptor renames System.OS_Lib.Standout;
   --  Shortcuts

   EOL : constant Character := ASCII.LF;

   Max  : constant := 78;
   Last : Natural  := 0;
   Line : String (1 .. Max);
   --  Use this line to provide buffered IO

   procedure Add (C : Character);
   procedure Add (S : String);
   --  Add a character or a string in Line and update Last

   procedure Put
     (F  : File_Descriptor;
      S  : String;
      F1 : Natural;
      L1 : Natural;
      C1 : Natural;
      F2 : Natural;
      L2 : Natural;
      C2 : Natural);
   --  Write string S into file F as a element of an array of one or two
   --  dimensions. Fk (resp. Lk and Ck) indicates the first (resp last and
   --  current) index in the k-th dimension. If F1 = L1 the array is considered
   --  as a one dimension array. This dimension is described by F2 and L2. This
   --  routine takes care of all the parenthesis, spaces and commas needed to
   --  format correctly the array. Moreover, the array is well indented and is
   --  wrapped to fit in a 80 col line. When the line is full, the routine
   --  writes it into file F. When the array is completed, the routine adds
   --  semi-colon and writes the line into file F.

   procedure New_Line (File : File_Descriptor);
   --  Simulate Ada.Text_IO.New_Line with GNAT.OS_Lib

   procedure Put (File : File_Descriptor; Str : String);
   --  Simulate Ada.Text_IO.Put with GNAT.OS_Lib

   procedure Put_Used_Char_Set (File : File_Descriptor; Title : String);
   --  Output a title and a used character set

   procedure Put_Int_Vector
     (File   : File_Descriptor;
      Title  : String;
      Vector : Integer;
      Length : Natural);
   --  Output a title and a vector

   procedure Put_Int_Matrix
     (File  : File_Descriptor;
      Title : String;
      Table : Table_Id;
      Len_1 : Natural;
      Len_2 : Natural);
   --  Output a title and a matrix. When the matrix has only one non-empty
   --  dimension (Len_2 = 0), output a vector.

   procedure Put_Edges (File : File_Descriptor; Title : String);
   --  Output a title and an edge table

   procedure Put_Initial_Keys (File : File_Descriptor; Title : String);
   --  Output a title and a key table

   procedure Put_Reduced_Keys (File : File_Descriptor; Title : String);
   --  Output a title and a key table

   procedure Put_Vertex_Table (File : File_Descriptor; Title : String);
   --  Output a title and a vertex table

   ----------------------------------
   -- Character Position Selection --
   ----------------------------------

   --  We reduce the maximum key size by selecting representative positions
   --  in these keys. We build a matrix with one word per line. We fill the
   --  remaining space of a line with ASCII.NUL. The heuristic selects the
   --  position that induces the minimum number of collisions. If there are
   --  collisions, select another position on the reduced key set responsible
   --  of the collisions. Apply the heuristic until there is no more collision.

   procedure Apply_Position_Selection;
   --  Apply Position selection and build the reduced key table

   procedure Parse_Position_Selection (Argument : String);
   --  Parse Argument and compute the position set. Argument is list of
   --  substrings separated by commas. Each substring represents a position
   --  or a range of positions (like x-y).

   procedure Select_Character_Set;
   --  Define an optimized used character set like Character'Pos in order not
   --  to allocate tables of 256 entries.

   procedure Select_Char_Position;
   --  Find a min char position set in order to reduce the max key length. The
   --  heuristic selects the position that induces the minimum number of
   --  collisions. If there are collisions, select another position on the
   --  reduced key set responsible of the collisions. Apply the heuristic until
   --  there is no collision.

   -----------------------------
   -- Random Graph Generation --
   -----------------------------

   procedure Random (Seed : in out Natural);
   --  Simulate Ada.Discrete_Numerics.Random

   procedure Generate_Mapping_Table
     (Tab  : Table_Id;
      L1   : Natural;
      L2   : Natural;
      Seed : in out Natural);
   --  Random generation of the tables below. T is already allocated

   procedure Generate_Mapping_Tables
     (Opt  : Optimization;
      Seed : in out Natural);
   --  Generate the mapping tables T1 and T2. They are used to define fk (w) =
   --  sum (for i in 1 .. length (w)) (Tk (i, w (i))) mod n. Keys, NK and Chars
   --  are used to compute the matrix size.

   ---------------------------
   -- Algorithm Computation --
   ---------------------------

   procedure Compute_Edges_And_Vertices (Opt : Optimization);
   --  Compute the edge and vertex tables. These are empty when a self loop is
   --  detected (f1 (w) = f2 (w)). The edge table is sorted by X value and then
   --  Y value. Keys is the key table and NK the number of keys. Chars is the
   --  set of characters really used in Keys. NV is the number of vertices
   --  recommended by the algorithm. T1 and T2 are the mapping tables needed to
   --  compute f1 (w) and f2 (w).

   function Acyclic return Boolean;
   --  Return True when the graph is acyclic. Vertices is the current vertex
   --  table and Edges the current edge table.

   procedure Assign_Values_To_Vertices;
   --  Execute the assignment step of the algorithm. Keys is the current key
   --  table. Vertices and Edges represent the random graph. G is the result of
   --  the assignment step such that:
   --    h (w) = (g (f1 (w)) + g (f2 (w))) mod m

   function Sum
     (Word  : Word_Type;
      Table : Table_Id;
      Opt   : Optimization) return Natural;
   --  For an optimization of CPU_Time return
   --    fk (w) = sum (for i in 1 .. length (w)) (Tk (i, w (i))) mod n
   --  For an optimization of Memory_Space return
   --    fk (w) = sum (for i in 1 .. length (w)) (Tk (i) * w (i)) mod n
   --  Here NV = n

   -------------------------------
   -- Internal Table Management --
   -------------------------------

   function Allocate (N : Natural; S : Natural := 1) return Table_Id;
   --  Allocate N * S ints from IT table

   ----------
   -- Keys --
   ----------

   Keys : Table_Id := No_Table;
   NK   : Natural  := 0;
   --  NK : Number of Keys

   function Initial (K : Key_Id) return Word_Id;
   pragma Inline (Initial);

   function Reduced (K : Key_Id) return Word_Id;
   pragma Inline (Reduced);

   function  Get_Key (N : Key_Id) return Key_Type;
   procedure Set_Key (N : Key_Id; Item : Key_Type);
   --  Get or Set Nth element of Keys table

   ------------------
   -- Char_Pos_Set --
   ------------------

   Char_Pos_Set     : Table_Id := No_Table;
   Char_Pos_Set_Len : Natural;
   --  Character Selected Position Set

   function  Get_Char_Pos (P : Natural) return Natural;
   procedure Set_Char_Pos (P : Natural; Item : Natural);
   --  Get or Set the string position of the Pth selected character

   -------------------
   -- Used_Char_Set --
   -------------------

   Used_Char_Set     : Table_Id := No_Table;
   Used_Char_Set_Len : Natural;
   --  Used Character Set : Define a new character mapping. When all the
   --  characters are not present in the keys, in order to reduce the size
   --  of some tables, we redefine the character mapping.

   function  Get_Used_Char (C : Character) return Natural;
   procedure Set_Used_Char (C : Character; Item : Natural);

   ------------
   -- Tables --
   ------------

   T1     : Table_Id := No_Table;
   T2     : Table_Id := No_Table;
   T1_Len : Natural;
   T2_Len : Natural;
   --  T1  : Values table to compute F1
   --  T2  : Values table to compute F2

   function  Get_Table (T : Integer; X, Y : Natural) return Natural;
   procedure Set_Table (T : Integer; X, Y : Natural; Item : Natural);

   -----------
   -- Graph --
   -----------

   G     : Table_Id := No_Table;
   G_Len : Natural;
   --  Values table to compute G

   NT : Natural;
   --  Number of tries running the algorithm before raising an error

   function  Get_Graph (N : Natural) return Integer;
   procedure Set_Graph (N : Natural; Item : Integer);
   --  Get or Set Nth element of graph

   -----------
   -- Edges --
   -----------

   Edge_Size : constant := 3;
   Edges     : Table_Id := No_Table;
   Edges_Len : Natural;
   --  Edges  : Edge table of the random graph G

   function  Get_Edges (F : Natural) return Edge_Type;
   procedure Set_Edges (F : Natural; Item : Edge_Type);

   --------------
   -- Vertices --
   --------------

   Vertex_Size : constant := 2;

   Vertices : Table_Id := No_Table;
   --  Vertex table of the random graph G

   NV : Natural;
   --  Number of Vertices

   function  Get_Vertices (F : Natural) return Vertex_Type;
   procedure Set_Vertices (F : Natural; Item : Vertex_Type);
   --  Comments needed ???

   Opt : Optimization;
   --  Optimization mode (memory vs CPU)

   Max_Key_Len : Natural := 0;
   Min_Key_Len : Natural := 0;
   --  Maximum and minimum of all the word length

   S : Natural;
   --  Seed

   function Type_Size (L : Natural) return Natural;
   --  Given the last L of an unsigned integer type T, return its size

   -------------
   -- Acyclic --
   -------------

   function Acyclic return Boolean is
      Marks : array (0 .. NV - 1) of Vertex_Id := (others => No_Vertex);

      function Traverse (Edge : Edge_Id; Mark : Vertex_Id) return Boolean;
      --  Propagate Mark from X to Y. X is already marked. Mark Y and propagate
      --  it to the edges of Y except the one representing the same key. Return
      --  False when Y is marked with Mark.

      --------------
      -- Traverse --
      --------------

      function Traverse (Edge : Edge_Id; Mark : Vertex_Id) return Boolean is
         E : constant Edge_Type := Get_Edges (Edge);
         K : constant Key_Id    := E.Key;
         Y : constant Vertex_Id := E.Y;
         M : constant Vertex_Id := Marks (E.Y);
         V : Vertex_Type;

      begin
         if M = Mark then
            return False;

         elsif M = No_Vertex then
            Marks (Y) := Mark;
            V := Get_Vertices (Y);

            for J in V.First .. V.Last loop

               --  Do not propagate to the edge representing the same key

               if Get_Edges (J).Key /= K
                 and then not Traverse (J, Mark)
               then
                  return False;
               end if;
            end loop;
         end if;

         return True;
      end Traverse;

      Edge  : Edge_Type;

   --  Start of processing for Acyclic

   begin
      --  Edges valid range is

      for J in 1 .. Edges_Len - 1 loop

         Edge := Get_Edges (J);

         --  Mark X of E when it has not been already done

         if Marks (Edge.X) = No_Vertex then
            Marks (Edge.X) := Edge.X;
         end if;

         --  Traverse E when this has not already been done

         if Marks (Edge.Y) = No_Vertex
           and then not Traverse (J, Edge.X)
         then
            return False;
         end if;
      end loop;

      return True;
   end Acyclic;

   ---------
   -- Add --
   ---------

   procedure Add (C : Character) is
      pragma Assert (C /= ASCII.NUL);
   begin
      Line (Last + 1) := C;
      Last := Last + 1;
   end Add;

   ---------
   -- Add --
   ---------

   procedure Add (S : String) is
      Len : constant Natural := S'Length;
   begin
      for J in S'Range loop
         pragma Assert (S (J) /= ASCII.NUL);
         null;
      end loop;

      Line (Last + 1 .. Last + Len) := S;
      Last := Last + Len;
   end Add;

   --------------
   -- Allocate --
   --------------

   function Allocate (N : Natural; S : Natural := 1) return Table_Id is
      L : constant Integer := IT.Last;
   begin
      IT.Set_Last (L + N * S);

      --  Initialize, so debugging printouts don't trip over uninitialized
      --  components.

      for J in L + 1 .. IT.Last loop
         IT.Table (J) := -1;
      end loop;

      return L + 1;
   end Allocate;

   ------------------------------
   -- Apply_Position_Selection --
   ------------------------------

   procedure Apply_Position_Selection is
   begin
      for J in 0 .. NK - 1 loop
         declare
            IW : constant String := WT.Table (Initial (J)).all;
            RW : String (1 .. IW'Length) := (others => ASCII.NUL);
            N  : Natural := IW'First - 1;

         begin
            --  Select the characters of Word included in the position
            --  selection.

            for C in 0 .. Char_Pos_Set_Len - 1 loop
               exit when IW (Get_Char_Pos (C)) = ASCII.NUL;
               N := N + 1;
               RW (N) := IW (Get_Char_Pos (C));
            end loop;

            --  Build the new table with the reduced word. Be careful
            --  to deallocate the old version to avoid memory leaks.

            Free_Word (WT.Table (Reduced (J)));
            WT.Table (Reduced (J)) := New_Word (RW);
            Set_Key (J, (Edge => No_Edge));
         end;
      end loop;
   end Apply_Position_Selection;

   -------------------------------
   -- Assign_Values_To_Vertices --
   -------------------------------

   procedure Assign_Values_To_Vertices is
      X : Vertex_Id;

      procedure Assign (X : Vertex_Id);
      --  Execute assignment on X's neighbors except the vertex that we are
      --  coming from which is already assigned.

      ------------
      -- Assign --
      ------------

      procedure Assign (X : Vertex_Id) is
         E : Edge_Type;
         V : constant Vertex_Type := Get_Vertices (X);

      begin
         for J in V.First .. V.Last loop
            E := Get_Edges (J);

            if Get_Graph (E.Y) = -1 then
               pragma Assert (NK /= 0);
               Set_Graph (E.Y, (E.Key - Get_Graph (X)) mod NK);
               Assign (E.Y);
            end if;
         end loop;
      end Assign;

   --  Start of processing for Assign_Values_To_Vertices

   begin
      --  Value -1 denotes an uninitialized value as it is supposed to
      --  be in the range 0 .. NK.

      if G = No_Table then
         G_Len := NV;
         G := Allocate (G_Len, 1);
      end if;

      for J in 0 .. G_Len - 1 loop
         Set_Graph (J, -1);
      end loop;

      for K in 0 .. NK - 1 loop
         X := Get_Edges (Get_Key (K).Edge).X;

         if Get_Graph (X) = -1 then
            Set_Graph (X, 0);
            Assign (X);
         end if;
      end loop;

      for J in 0 .. G_Len - 1 loop
         if Get_Graph (J) = -1 then
            Set_Graph (J, 0);
         end if;
      end loop;

      if Verbose then
         Put_Int_Vector (Output, "Assign Values To Vertices", G, G_Len);
      end if;
   end Assign_Values_To_Vertices;

   -------------
   -- Compute --
   -------------

   procedure Compute (Position : String) is
      Success : Boolean := False;

   begin
      if NK = 0 then
         raise Program_Error with "keywords set cannot be empty";
      end if;

      if Verbose then
         Put_Initial_Keys (Output, "Initial Key Table");
      end if;

      if Position'Length /= 0 then
         Parse_Position_Selection (Position);
      else
         Select_Char_Position;
      end if;

      if Verbose then
         Put_Int_Vector
           (Output, "Char Position Set", Char_Pos_Set, Char_Pos_Set_Len);
      end if;

      Apply_Position_Selection;

      if Verbose then
         Put_Reduced_Keys (Output, "Reduced Keys Table");
      end if;

      Select_Character_Set;

      if Verbose then
         Put_Used_Char_Set (Output, "Character Position Table");
      end if;

      --  Perform Czech's algorithm

      for J in 1 .. NT loop
         Generate_Mapping_Tables (Opt, S);
         Compute_Edges_And_Vertices (Opt);

         --  When graph is not empty (no self-loop from previous operation) and
         --  not acyclic.

         if 0 < Edges_Len and then Acyclic then
            Success := True;
            exit;
         end if;
      end loop;

      if not Success then
         raise Too_Many_Tries;
      end if;

      Assign_Values_To_Vertices;
   end Compute;

   --------------------------------
   -- Compute_Edges_And_Vertices --
   --------------------------------

   procedure Compute_Edges_And_Vertices (Opt : Optimization) is
      X           : Natural;
      Y           : Natural;
      Key         : Key_Type;
      Edge        : Edge_Type;
      Vertex      : Vertex_Type;
      Not_Acyclic : Boolean := False;

      procedure Move (From : Natural; To : Natural);
      function Lt (L, R : Natural) return Boolean;
      --  Subprograms needed for GNAT.Heap_Sort_G

      --------
      -- Lt --
      --------

      function Lt (L, R : Natural) return Boolean is
         EL : constant Edge_Type := Get_Edges (L);
         ER : constant Edge_Type := Get_Edges (R);
      begin
         return EL.X < ER.X or else (EL.X = ER.X and then EL.Y < ER.Y);
      end Lt;

      ----------
      -- Move --
      ----------

      procedure Move (From : Natural; To : Natural) is
      begin
         Set_Edges (To, Get_Edges (From));
      end Move;

      package Sorting is new GNAT.Heap_Sort_G (Move, Lt);

   --  Start of processing for Compute_Edges_And_Vertices

   begin
      --  We store edges from 1 to 2 * NK and leave zero alone in order to use
      --  GNAT.Heap_Sort_G.

      Edges_Len := 2 * NK + 1;

      if Edges = No_Table then
         Edges := Allocate (Edges_Len, Edge_Size);
      end if;

      if Vertices = No_Table then
         Vertices := Allocate (NV, Vertex_Size);
      end if;

      for J in 0 .. NV - 1 loop
         Set_Vertices (J, (No_Vertex, No_Vertex - 1));
      end loop;

      --  For each w, X = f1 (w) and Y = f2 (w)

      for J in 0 .. NK - 1 loop
         Key := Get_Key (J);
         Key.Edge := No_Edge;
         Set_Key (J, Key);

         X := Sum (WT.Table (Reduced (J)), T1, Opt);
         Y := Sum (WT.Table (Reduced (J)), T2, Opt);

         --  Discard T1 and T2 as soon as we discover a self loop

         if X = Y then
            Not_Acyclic := True;
            exit;
         end if;

         --  We store (X, Y) and (Y, X) to ease assignment step

         Set_Edges (2 * J + 1, (X, Y, J));
         Set_Edges (2 * J + 2, (Y, X, J));
      end loop;

      --  Return an empty graph when self loop detected

      if Not_Acyclic then
         Edges_Len := 0;

      else
         if Verbose then
            Put_Edges      (Output, "Unsorted Edge Table");
            Put_Int_Matrix (Output, "Function Table 1", T1,
                            T1_Len, T2_Len);
            Put_Int_Matrix (Output, "Function Table 2", T2,
                            T1_Len, T2_Len);
         end if;

         --  Enforce consistency between edges and keys. Construct Vertices and
         --  compute the list of neighbors of a vertex First .. Last as Edges
         --  is sorted by X and then Y. To compute the neighbor list, sort the
         --  edges.

         Sorting.Sort (Edges_Len - 1);

         if Verbose then
            Put_Edges      (Output, "Sorted Edge Table");
            Put_Int_Matrix (Output, "Function Table 1", T1,
                            T1_Len, T2_Len);
            Put_Int_Matrix (Output, "Function Table 2", T2,
                            T1_Len, T2_Len);
         end if;

         --  Edges valid range is 1 .. 2 * NK

         for E in 1 .. Edges_Len - 1 loop
            Edge := Get_Edges (E);
            Key  := Get_Key (Edge.Key);

            if Key.Edge = No_Edge then
               Key.Edge := E;
               Set_Key (Edge.Key, Key);
            end if;

            Vertex := Get_Vertices (Edge.X);

            if Vertex.First = No_Edge then
               Vertex.First := E;
            end if;

            Vertex.Last := E;
            Set_Vertices (Edge.X, Vertex);
         end loop;

         if Verbose then
            Put_Reduced_Keys (Output, "Key Table");
            Put_Edges        (Output, "Edge Table");
            Put_Vertex_Table (Output, "Vertex Table");
         end if;
      end if;
   end Compute_Edges_And_Vertices;

   ------------
   -- Define --
   ------------

   procedure Define
     (Name      : Table_Name;
      Item_Size : out Natural;
      Length_1  : out Natural;
      Length_2  : out Natural)
   is
   begin
      case Name is
         when Character_Position =>
            Item_Size := 31;
            Length_1  := Char_Pos_Set_Len;
            Length_2  := 0;

         when Used_Character_Set =>
            Item_Size := 8;
            Length_1  := 256;
            Length_2  := 0;

         when Function_Table_1
            | Function_Table_2
         =>
            Item_Size := Type_Size (NV);
            Length_1  := T1_Len;
            Length_2  := T2_Len;

         when Graph_Table =>
            Item_Size := Type_Size (NK);
            Length_1  := NV;
            Length_2  := 0;
      end case;
   end Define;

   --------------
   -- Finalize --
   --------------

   procedure Finalize is
   begin
      if Verbose then
         Put (Output, "Finalize");
         New_Line (Output);
      end if;

      --  Deallocate all the WT components (both initial and reduced ones) to
      --  avoid memory leaks.

      for W in 0 .. WT.Last loop

         --  Note: WT.Table (NK) is a temporary variable, do not free it since
         --  this would cause a double free.

         if W /= NK then
            Free_Word (WT.Table (W));
         end if;
      end loop;

      WT.Release;
      IT.Release;

      --  Reset all variables for next usage

      Keys := No_Table;

      Char_Pos_Set     := No_Table;
      Char_Pos_Set_Len := 0;

      Used_Char_Set     := No_Table;
      Used_Char_Set_Len := 0;

      T1 := No_Table;
      T2 := No_Table;

      T1_Len := 0;
      T2_Len := 0;

      G     := No_Table;
      G_Len := 0;

      Edges     := No_Table;
      Edges_Len := 0;

      Vertices := No_Table;
      NV       := 0;

      NK := 0;
      Max_Key_Len := 0;
      Min_Key_Len := 0;
   end Finalize;

   ----------------------------
   -- Generate_Mapping_Table --
   ----------------------------

   procedure Generate_Mapping_Table
     (Tab  : Integer;
      L1   : Natural;
      L2   : Natural;
      Seed : in out Natural)
   is
   begin
      for J in 0 .. L1 - 1 loop
         for K in 0 .. L2 - 1 loop
            Random (Seed);
            Set_Table (Tab, J, K, Seed mod NV);
         end loop;
      end loop;
   end Generate_Mapping_Table;

   -----------------------------
   -- Generate_Mapping_Tables --
   -----------------------------

   procedure Generate_Mapping_Tables
     (Opt  : Optimization;
      Seed : in out Natural)
   is
   begin
      --  If T1 and T2 are already allocated no need to do it twice. Reuse them
      --  as their size has not changed.

      if T1 = No_Table and then T2 = No_Table then
         declare
            Used_Char_Last : Natural := 0;
            Used_Char      : Natural;

         begin
            if Opt = CPU_Time then
               for P in reverse Character'Range loop
                  Used_Char := Get_Used_Char (P);
                  if Used_Char /= 0 then
                     Used_Char_Last := Used_Char;
                     exit;
                  end if;
               end loop;
            end if;

            T1_Len := Char_Pos_Set_Len;
            T2_Len := Used_Char_Last + 1;
            T1 := Allocate (T1_Len * T2_Len);
            T2 := Allocate (T1_Len * T2_Len);
         end;
      end if;

      Generate_Mapping_Table (T1, T1_Len, T2_Len, Seed);
      Generate_Mapping_Table (T2, T1_Len, T2_Len, Seed);

      if Verbose then
         Put_Used_Char_Set (Output, "Used Character Set");
         Put_Int_Matrix (Output, "Function Table 1", T1,
                        T1_Len, T2_Len);
         Put_Int_Matrix (Output, "Function Table 2", T2,
                        T1_Len, T2_Len);
      end if;
   end Generate_Mapping_Tables;

   ------------------
   -- Get_Char_Pos --
   ------------------

   function Get_Char_Pos (P : Natural) return Natural is
      N : constant Natural := Char_Pos_Set + P;
   begin
      return IT.Table (N);
   end Get_Char_Pos;

   ---------------
   -- Get_Edges --
   ---------------

   function Get_Edges (F : Natural) return Edge_Type is
      N : constant Natural := Edges + (F * Edge_Size);
      E : Edge_Type;
   begin
      E.X   := IT.Table (N);
      E.Y   := IT.Table (N + 1);
      E.Key := IT.Table (N + 2);
      return E;
   end Get_Edges;

   ---------------
   -- Get_Graph --
   ---------------

   function Get_Graph (N : Natural) return Integer is
   begin
      return IT.Table (G + N);
   end Get_Graph;

   -------------
   -- Get_Key --
   -------------

   function Get_Key (N : Key_Id) return Key_Type is
      K : Key_Type;
   begin
      K.Edge := IT.Table (Keys + N);
      return K;
   end Get_Key;

   ---------------
   -- Get_Table --
   ---------------

   function Get_Table (T : Integer; X, Y : Natural) return Natural is
      N : constant Natural := T + (Y * T1_Len) + X;
   begin
      return IT.Table (N);
   end Get_Table;

   -------------------
   -- Get_Used_Char --
   -------------------

   function Get_Used_Char (C : Character) return Natural is
      N : constant Natural := Used_Char_Set + Character'Pos (C);
   begin
      return IT.Table (N);
   end Get_Used_Char;

   ------------------
   -- Get_Vertices --
   ------------------

   function Get_Vertices (F : Natural) return Vertex_Type is
      N : constant Natural := Vertices + (F * Vertex_Size);
      V : Vertex_Type;
   begin
      V.First := IT.Table (N);
      V.Last  := IT.Table (N + 1);
      return V;
   end Get_Vertices;

   -----------
   -- Image --
   -----------

   function Image (Int : Integer; W : Natural := 0) return String is
      B : String (1 .. 32);
      L : Natural := 0;

      procedure Img (V : Natural);
      --  Compute image of V into B, starting at B (L), incrementing L

      ---------
      -- Img --
      ---------

      procedure Img (V : Natural) is
      begin
         if V > 9 then
            Img (V / 10);
         end if;

         L := L + 1;
         B (L) := Character'Val ((V mod 10) + Character'Pos ('0'));
      end Img;

   --  Start of processing for Image

   begin
      if Int < 0 then
         L := L + 1;
         B (L) := '-';
         Img (-Int);
      else
         Img (Int);
      end if;

      return Image (B (1 .. L), W);
   end Image;

   -----------
   -- Image --
   -----------

   function Image (Str : String; W : Natural := 0) return String is
      Len : constant Natural := Str'Length;
      Max : Natural := Len;

   begin
      if Max < W then
         Max := W;
      end if;

      declare
         Buf : String (1 .. Max) := (1 .. Max => ' ');

      begin
         for J in 0 .. Len - 1 loop
            Buf (Max - Len + 1 + J) := Str (Str'First + J);
         end loop;

         return Buf;
      end;
   end Image;

   -------------
   -- Initial --
   -------------

   function Initial (K : Key_Id) return Word_Id is
   begin
      return K;
   end Initial;

   ----------------
   -- Initialize --
   ----------------

   procedure Initialize
     (Seed  : Natural;
      V     : Positive;
      Optim : Optimization;
      Tries : Positive)
   is
   begin
      if Verbose then
         Put (Output, "Initialize");
         New_Line (Output);
      end if;

      --  Deallocate the part of the table concerning the reduced words.
      --  Initial words are already present in the table. We may have reduced
      --  words already there because a previous computation failed. We are
      --  currently retrying and the reduced words have to be deallocated.

      for W in Reduced (0) .. WT.Last loop
         Free_Word (WT.Table (W));
      end loop;

      IT.Init;

      --  Initialize of computation variables

      Keys := No_Table;

      Char_Pos_Set     := No_Table;
      Char_Pos_Set_Len := 0;

      Used_Char_Set     := No_Table;
      Used_Char_Set_Len := 0;

      T1 := No_Table;
      T2 := No_Table;

      T1_Len := 0;
      T2_Len := 0;

      G     := No_Table;
      G_Len := 0;

      Edges     := No_Table;
      Edges_Len := 0;

      if V <= 2 * NK then
         raise Program_Error with "K to V ratio cannot be lower than 2";
      end if;

      Vertices := No_Table;
      NV       := V;

      S    := Seed;
      Opt  := Optim;
      NT   := Tries;

      Keys := Allocate (NK);

      --  Resize initial words to have all of them at the same size
      --  (so the size of the largest one).

      for K in 0 .. NK - 1 loop
         Resize_Word (WT.Table (Initial (K)), Max_Key_Len);
      end loop;

      --  Allocated the table to store the reduced words. As WT is a
      --  GNAT.Table (using C memory management), pointers have to be
      --  explicitly initialized to null.

      WT.Set_Last (Reduced (NK - 1));

      --  Note: Reduced (0) = NK + 1

      WT.Table (NK) := null;

      for W in 0 .. NK - 1 loop
         WT.Table (Reduced (W)) := null;
      end loop;
   end Initialize;

   ------------
   -- Insert --
   ------------

   procedure Insert (Value : String) is
      Len  : constant Natural := Value'Length;

   begin
      if Verbose then
         Put (Output, "Inserting """ & Value & """");
         New_Line (Output);
      end if;

      for J in Value'Range loop
         pragma Assert (Value (J) /= ASCII.NUL);
         null;
      end loop;

      WT.Set_Last (NK);
      WT.Table (NK) := New_Word (Value);
      NK := NK + 1;

      if Max_Key_Len < Len then
         Max_Key_Len := Len;
      end if;

      if Min_Key_Len = 0 or else Len < Min_Key_Len then
         Min_Key_Len := Len;
      end if;
   end Insert;

   --------------
   -- New_Line --
   --------------

   procedure New_Line (File : File_Descriptor) is
   begin
      if Write (File, EOL'Address, 1) /= 1 then
         raise Program_Error;
      end if;
   end New_Line;

   --------------
   -- New_Word --
   --------------

   function New_Word (S : String) return Word_Type is
   begin
      return new String'(S);
   end New_Word;

   ------------------------------
   -- Parse_Position_Selection --
   ------------------------------

   procedure Parse_Position_Selection (Argument : String) is
      N : Natural          := Argument'First;
      L : constant Natural := Argument'Last;
      M : constant Natural := Max_Key_Len;

      T : array (1 .. M) of Boolean := (others => False);

      function Parse_Index return Natural;
      --  Parse argument starting at index N to find an index

      -----------------
      -- Parse_Index --
      -----------------

      function Parse_Index return Natural is
         C : Character := Argument (N);
         V : Natural   := 0;

      begin
         if C = '$' then
            N := N + 1;
            return M;
         end if;

         if C not in '0' .. '9' then
            raise Program_Error with "cannot read position argument";
         end if;

         while C in '0' .. '9' loop
            V := V * 10 + (Character'Pos (C) - Character'Pos ('0'));
            N := N + 1;
            exit when L < N;
            C := Argument (N);
         end loop;

         return V;
      end Parse_Index;

   --  Start of processing for Parse_Position_Selection

   begin
      --  Empty specification means all the positions

      if L < N then
         Char_Pos_Set_Len := M;
         Char_Pos_Set := Allocate (Char_Pos_Set_Len);

         for C in 0 .. Char_Pos_Set_Len - 1 loop
            Set_Char_Pos (C, C + 1);
         end loop;

      else
         loop
            declare
               First, Last : Natural;

            begin
               First := Parse_Index;
               Last  := First;

               --  Detect a range

               if N <= L and then Argument (N) = '-' then
                  N := N + 1;
                  Last := Parse_Index;
               end if;

               --  Include the positions in the selection

               for J in First .. Last loop
                  T (J) := True;
               end loop;
            end;

            exit when L < N;

            if Argument (N) /= ',' then
               raise Program_Error with "cannot read position argument";
            end if;

            N := N + 1;
         end loop;

         --  Compute position selection length

         N := 0;
         for J in T'Range loop
            if T (J) then
               N := N + 1;
            end if;
         end loop;

         --  Fill position selection

         Char_Pos_Set_Len := N;
         Char_Pos_Set := Allocate (Char_Pos_Set_Len);

         N := 0;
         for J in T'Range loop
            if T (J) then
               Set_Char_Pos (N, J);
               N := N + 1;
            end if;
         end loop;
      end if;
   end Parse_Position_Selection;

   ---------
   -- Put --
   ---------

   procedure Put (File : File_Descriptor; Str : String) is
      Len : constant Natural := Str'Length;
   begin
      for J in Str'Range loop
         pragma Assert (Str (J) /= ASCII.NUL);
         null;
      end loop;

      if Write (File, Str'Address, Len) /= Len then
         raise Program_Error;
      end if;
   end Put;

   ---------
   -- Put --
   ---------

   procedure Put
     (F  : File_Descriptor;
      S  : String;
      F1 : Natural;
      L1 : Natural;
      C1 : Natural;
      F2 : Natural;
      L2 : Natural;
      C2 : Natural)
   is
      Len : constant Natural := S'Length;

      procedure Flush;
      --  Write current line, followed by LF

      -----------
      -- Flush --
      -----------

      procedure Flush is
      begin
         Put (F, Line (1 .. Last));
         New_Line (F);
         Last := 0;
      end Flush;

   --  Start of processing for Put

   begin
      if C1 = F1 and then C2 = F2 then
         Last := 0;
      end if;

      if Last + Len + 3 >= Max then
         Flush;
      end if;

      if Last = 0 then
         Add ("     ");

         if F1 <= L1 then
            if C1 = F1 and then C2 = F2 then
               Add ('(');

               if F1 = L1 then
                  Add ("0 .. 0 => ");
               end if;

            else
               Add (' ');
            end if;
         end if;
      end if;

      if C2 = F2 then
         Add ('(');

         if F2 = L2 then
            Add ("0 .. 0 => ");
         end if;

      else
         Add (' ');
      end if;

      Add (S);

      if C2 = L2 then
         Add (')');

         if F1 > L1 then
            Add (';');
            Flush;

         elsif C1 /= L1 then
            Add (',');
            Flush;

         else
            Add (')');
            Add (';');
            Flush;
         end if;

      else
         Add (',');
      end if;
   end Put;

   ---------------
   -- Put_Edges --
   ---------------

   procedure Put_Edges (File  : File_Descriptor; Title : String) is
      E  : Edge_Type;
      F1 : constant Natural := 1;
      L1 : constant Natural := Edges_Len - 1;
      M  : constant Natural := Max / 5;

   begin
      Put (File, Title);
      New_Line (File);

      --  Edges valid range is 1 .. Edge_Len - 1

      for J in F1 .. L1 loop
         E := Get_Edges (J);
         Put (File, Image (J, M),     F1, L1, J, 1, 4, 1);
         Put (File, Image (E.X, M),   F1, L1, J, 1, 4, 2);
         Put (File, Image (E.Y, M),   F1, L1, J, 1, 4, 3);
         Put (File, Image (E.Key, M), F1, L1, J, 1, 4, 4);
      end loop;
   end Put_Edges;

   ----------------------
   -- Put_Initial_Keys --
   ----------------------

   procedure Put_Initial_Keys (File : File_Descriptor; Title : String) is
      F1 : constant Natural := 0;
      L1 : constant Natural := NK - 1;
      M  : constant Natural := Max / 5;
      K  : Key_Type;

   begin
      Put (File, Title);
      New_Line (File);

      for J in F1 .. L1 loop
         K := Get_Key (J);
         Put (File, Image (J, M),           F1, L1, J, 1, 3, 1);
         Put (File, Image (K.Edge, M),      F1, L1, J, 1, 3, 2);
         Put (File, Trim_Trailing_Nuls (WT.Table (Initial (J)).all),
                    F1, L1, J, 1, 3, 3);
      end loop;
   end Put_Initial_Keys;

   --------------------
   -- Put_Int_Matrix --
   --------------------

   procedure Put_Int_Matrix
     (File   : File_Descriptor;
      Title  : String;
      Table  : Integer;
      Len_1  : Natural;
      Len_2  : Natural)
   is
      F1 : constant Integer := 0;
      L1 : constant Integer := Len_1 - 1;
      F2 : constant Integer := 0;
      L2 : constant Integer := Len_2 - 1;
      Ix : Natural;

   begin
      Put (File, Title);
      New_Line (File);

      if Len_2 = 0 then
         for J in F1 .. L1 loop
            Ix := IT.Table (Table + J);
            Put (File, Image (Ix), 1, 0, 1, F1, L1, J);
         end loop;

      else
         for J in F1 .. L1 loop
            for K in F2 .. L2 loop
               Ix := IT.Table (Table + J + K * Len_1);
               Put (File, Image (Ix), F1, L1, J, F2, L2, K);
            end loop;
         end loop;
      end if;
   end Put_Int_Matrix;

   --------------------
   -- Put_Int_Vector --
   --------------------

   procedure Put_Int_Vector
     (File   : File_Descriptor;
      Title  : String;
      Vector : Integer;
      Length : Natural)
   is
      F2 : constant Natural := 0;
      L2 : constant Natural := Length - 1;

   begin
      Put (File, Title);
      New_Line (File);

      for J in F2 .. L2 loop
         Put (File, Image (IT.Table (Vector + J)), 1, 0, 1, F2, L2, J);
      end loop;
   end Put_Int_Vector;

   ----------------------
   -- Put_Reduced_Keys --
   ----------------------

   procedure Put_Reduced_Keys (File : File_Descriptor; Title : String) is
      F1 : constant Natural := 0;
      L1 : constant Natural := NK - 1;
      M  : constant Natural := Max / 5;
      K  : Key_Type;

   begin
      Put (File, Title);
      New_Line (File);

      for J in F1 .. L1 loop
         K := Get_Key (J);
         Put (File, Image (J, M),           F1, L1, J, 1, 3, 1);
         Put (File, Image (K.Edge, M),      F1, L1, J, 1, 3, 2);
         Put (File, Trim_Trailing_Nuls (WT.Table (Reduced (J)).all),
                    F1, L1, J, 1, 3, 3);
      end loop;
   end Put_Reduced_Keys;

   -----------------------
   -- Put_Used_Char_Set --
   -----------------------

   procedure Put_Used_Char_Set (File : File_Descriptor; Title : String) is
      F : constant Natural := Character'Pos (Character'First);
      L : constant Natural := Character'Pos (Character'Last);

   begin
      Put (File, Title);
      New_Line (File);

      for J in Character'Range loop
         Put
           (File, Image (Get_Used_Char (J)), 1, 0, 1, F, L, Character'Pos (J));
      end loop;
   end Put_Used_Char_Set;

   ----------------------
   -- Put_Vertex_Table --
   ----------------------

   procedure Put_Vertex_Table (File : File_Descriptor; Title : String) is
      F1 : constant Natural := 0;
      L1 : constant Natural := NV - 1;
      M  : constant Natural := Max / 4;
      V  : Vertex_Type;

   begin
      Put (File, Title);
      New_Line (File);

      for J in F1 .. L1 loop
         V := Get_Vertices (J);
         Put (File, Image (J, M),       F1, L1, J, 1, 3, 1);
         Put (File, Image (V.First, M), F1, L1, J, 1, 3, 2);
         Put (File, Image (V.Last, M),  F1, L1, J, 1, 3, 3);
      end loop;
   end Put_Vertex_Table;

   ------------
   -- Random --
   ------------

   procedure Random (Seed : in out Natural) is

      --  Park & Miller Standard Minimal using Schrage's algorithm to avoid
      --  overflow: Xn+1 = 16807 * Xn mod (2 ** 31 - 1)

      R : Natural;
      Q : Natural;
      X : Integer;

   begin
      R := Seed mod 127773;
      Q := Seed / 127773;
      X := 16807 * R - 2836 * Q;

      Seed := (if X < 0 then X + 2147483647 else X);
   end Random;

   -------------
   -- Reduced --
   -------------

   function Reduced (K : Key_Id) return Word_Id is
   begin
      return K + NK + 1;
   end Reduced;

   -----------------
   -- Resize_Word --
   -----------------

   procedure Resize_Word (W : in out Word_Type; Len : Natural) is
      S1 : constant String := W.all;
      S2 : String (1 .. Len) := (others => ASCII.NUL);
      L  : constant Natural := S1'Length;
   begin
      if L /= Len then
         Free_Word (W);
         S2 (1 .. L) := S1;
         W := New_Word (S2);
      end if;
   end Resize_Word;

   --------------------------
   -- Select_Char_Position --
   --------------------------

   procedure Select_Char_Position is

      type Vertex_Table_Type is array (Natural range <>) of Vertex_Type;

      procedure Build_Identical_Keys_Sets
        (Table : in out Vertex_Table_Type;
         Last  : in out Natural;
         Pos   : Natural);
      --  Build a list of keys subsets that are identical with the current
      --  position selection plus Pos. Once this routine is called, reduced
      --  words are sorted by subsets and each item (First, Last) in Sets
      --  defines the range of identical keys.
      --  Need comment saying exactly what Last is ???

      function Count_Different_Keys
        (Table : Vertex_Table_Type;
         Last  : Natural;
         Pos   : Natural) return Natural;
      --  For each subset in Sets, count the number of different keys if we add
      --  Pos to the current position selection.

      Sel_Position : IT.Table_Type (1 .. Max_Key_Len);
      Last_Sel_Pos : Natural := 0;
      Max_Sel_Pos  : Natural := 0;

      -------------------------------
      -- Build_Identical_Keys_Sets --
      -------------------------------

      procedure Build_Identical_Keys_Sets
        (Table : in out Vertex_Table_Type;
         Last  : in out Natural;
         Pos   : Natural)
      is
         S : constant Vertex_Table_Type := Table (Table'First .. Last);
         C : constant Natural           := Pos;
         --  Shortcuts (why are these not renames ???)

         F : Integer;
         L : Integer;
         --  First and last words of a subset

         Offset : Natural;
         --  GNAT.Heap_Sort assumes that the first array index is 1. Offset
         --  defines the translation to operate.

         function Lt (L, R : Natural) return Boolean;
         procedure Move (From : Natural; To : Natural);
         --  Subprograms needed by GNAT.Heap_Sort_G

         --------
         -- Lt --
         --------

         function Lt (L, R : Natural) return Boolean is
            C     : constant Natural := Pos;
            Left  : Natural;
            Right : Natural;

         begin
            if L = 0 then
               Left  := NK;
               Right := Offset + R;
            elsif R = 0 then
               Left  := Offset + L;
               Right := NK;
            else
               Left  := Offset + L;
               Right := Offset + R;
            end if;

            return WT.Table (Left)(C) < WT.Table (Right)(C);
         end Lt;

         ----------
         -- Move --
         ----------

         procedure Move (From : Natural; To : Natural) is
            Target, Source : Natural;

         begin
            if From = 0 then
               Source := NK;
               Target := Offset + To;
            elsif To = 0 then
               Source := Offset + From;
               Target := NK;
            else
               Source := Offset + From;
               Target := Offset + To;
            end if;

            WT.Table (Target) := WT.Table (Source);
            WT.Table (Source) := null;
         end Move;

         package Sorting is new GNAT.Heap_Sort_G (Move, Lt);

      --  Start of processing for Build_Identical_Key_Sets

      begin
         Last := 0;

         --  For each subset in S, extract the new subsets we have by adding C
         --  in the position selection.

         for J in S'Range loop
            pragma Annotate (CodePeer, Modified, S (J));

            if S (J).First = S (J).Last then
               F := S (J).First;
               L := S (J).Last;
               Last := Last + 1;
               Table (Last) := (F, L);

            else
               Offset := Reduced (S (J).First) - 1;
               Sorting.Sort (S (J).Last - S (J).First + 1);

               F := S (J).First;
               L := F;
               for N in S (J).First .. S (J).Last loop

                  --  For the last item, close the last subset

                  if N = S (J).Last then
                     Last := Last + 1;
                     Table (Last) := (F, N);

                  --  Two contiguous words are identical when they have the
                  --  same Cth character.

                  elsif WT.Table (Reduced (N))(C) =
                        WT.Table (Reduced (N + 1))(C)
                  then
                     L := N + 1;

                  --  Find a new subset of identical keys. Store the current
                  --  one and create a new subset.

                  else
                     Last := Last + 1;
                     Table (Last) := (F, L);
                     F := N + 1;
                     L := F;
                  end if;
               end loop;
            end if;
         end loop;
      end Build_Identical_Keys_Sets;

      --------------------------
      -- Count_Different_Keys --
      --------------------------

      function Count_Different_Keys
        (Table : Vertex_Table_Type;
         Last  : Natural;
         Pos   : Natural) return Natural
      is
         N : array (Character) of Natural;
         C : Character;
         T : Natural := 0;

      begin
         --  For each subset, count the number of words that are still
         --  different when we include Pos in the position selection. Only
         --  focus on this position as the other positions already produce
         --  identical keys.

         for S in 1 .. Last loop

            --  Count the occurrences of the different characters

            N := (others => 0);
            for K in Table (S).First .. Table (S).Last loop
               C := WT.Table (Reduced (K))(Pos);
               N (C) := N (C) + 1;
            end loop;

            --  Update the number of different keys. Each character used
            --  denotes a different key.

            for J in N'Range loop
               if N (J) > 0 then
                  T := T + 1;
               end if;
            end loop;
         end loop;

         return T;
      end Count_Different_Keys;

   --  Start of processing for Select_Char_Position

   begin
      --  Initialize the reduced words set

      for K in 0 .. NK - 1 loop
         WT.Table (Reduced (K)) := New_Word (WT.Table (Initial (K)).all);
      end loop;

      declare
         Differences          : Natural;
         Max_Differences      : Natural := 0;
         Old_Differences      : Natural;
         Max_Diff_Sel_Pos     : Natural := 0; -- init to kill warning
         Max_Diff_Sel_Pos_Idx : Natural := 0; -- init to kill warning
         Same_Keys_Sets_Table : Vertex_Table_Type (1 .. NK);
         Same_Keys_Sets_Last  : Natural := 1;

      begin
         for C in Sel_Position'Range loop
            Sel_Position (C) := C;
         end loop;

         Same_Keys_Sets_Table (1) := (0, NK - 1);

         loop
            --  Preserve maximum number of different keys and check later on
            --  that this value is strictly incrementing. Otherwise, it means
            --  that two keys are strictly identical.

            Old_Differences := Max_Differences;

            --  The first position should not exceed the minimum key length.
            --  Otherwise, we may end up with an empty word once reduced.

            Max_Sel_Pos :=
              (if Last_Sel_Pos = 0 then Min_Key_Len else Max_Key_Len);

            --  Find which position increases more the number of differences

            for J in Last_Sel_Pos + 1 .. Max_Sel_Pos loop
               Differences := Count_Different_Keys
                 (Same_Keys_Sets_Table,
                  Same_Keys_Sets_Last,
                  Sel_Position (J));

               if Verbose then
                  Put (Output,
                       "Selecting position" & Sel_Position (J)'Img &
                         " results in" & Differences'Img &
                         " differences");
                  New_Line (Output);
               end if;

               if Differences > Max_Differences then
                  Max_Differences      := Differences;
                  Max_Diff_Sel_Pos     := Sel_Position (J);
                  Max_Diff_Sel_Pos_Idx := J;
               end if;
            end loop;

            if Old_Differences = Max_Differences then
               raise Program_Error with "some keys are identical";
            end if;

            --  Insert selected position and sort Sel_Position table

            Last_Sel_Pos := Last_Sel_Pos + 1;
            Sel_Position (Last_Sel_Pos + 1 .. Max_Diff_Sel_Pos_Idx) :=
              Sel_Position (Last_Sel_Pos .. Max_Diff_Sel_Pos_Idx - 1);
            Sel_Position (Last_Sel_Pos) := Max_Diff_Sel_Pos;

            for P in 1 .. Last_Sel_Pos - 1 loop
               if Max_Diff_Sel_Pos < Sel_Position (P) then
                  pragma Annotate
                    (CodePeer, False_Positive,
                     "test always false", "false positive?");

                  Sel_Position (P + 1 .. Last_Sel_Pos) :=
                    Sel_Position (P .. Last_Sel_Pos - 1);
                  Sel_Position (P) := Max_Diff_Sel_Pos;
                  exit;
               end if;
            end loop;

            exit when Max_Differences = NK;

            Build_Identical_Keys_Sets
              (Same_Keys_Sets_Table,
               Same_Keys_Sets_Last,
               Max_Diff_Sel_Pos);

            if Verbose then
               Put (Output,
                    "Selecting position" & Max_Diff_Sel_Pos'Img &
                      " results in" & Max_Differences'Img &
                      " differences");
               New_Line (Output);
               Put (Output, "--");
               New_Line (Output);
               for J in 1 .. Same_Keys_Sets_Last loop
                  for K in
                    Same_Keys_Sets_Table (J).First ..
                    Same_Keys_Sets_Table (J).Last
                  loop
                     Put (Output,
                          Trim_Trailing_Nuls (WT.Table (Reduced (K)).all));
                     New_Line (Output);
                  end loop;
                  Put (Output, "--");
                  New_Line (Output);
               end loop;
            end if;
         end loop;
      end;

      Char_Pos_Set_Len := Last_Sel_Pos;
      Char_Pos_Set := Allocate (Char_Pos_Set_Len);

      for C in 1 .. Last_Sel_Pos loop
         Set_Char_Pos (C - 1, Sel_Position (C));
      end loop;
   end Select_Char_Position;

   --------------------------
   -- Select_Character_Set --
   --------------------------

   procedure Select_Character_Set is
      Last : Natural := 0;
      Used : array (Character) of Boolean := (others => False);
      Char : Character;

   begin
      for J in 0 .. NK - 1 loop
         for K in 0 .. Char_Pos_Set_Len - 1 loop
            Char := WT.Table (Initial (J))(Get_Char_Pos (K));
            exit when Char = ASCII.NUL;
            Used (Char) := True;
         end loop;
      end loop;

      Used_Char_Set_Len := 256;
      Used_Char_Set := Allocate (Used_Char_Set_Len);

      for J in Used'Range loop
         if Used (J) then
            Set_Used_Char (J, Last);
            Last := Last + 1;
         else
            Set_Used_Char (J, 0);
         end if;
      end loop;
   end Select_Character_Set;

   ------------------
   -- Set_Char_Pos --
   ------------------

   procedure Set_Char_Pos (P : Natural; Item : Natural) is
      N : constant Natural := Char_Pos_Set + P;
   begin
      IT.Table (N) := Item;
   end Set_Char_Pos;

   ---------------
   -- Set_Edges --
   ---------------

   procedure Set_Edges (F : Natural; Item : Edge_Type) is
      N : constant Natural := Edges + (F * Edge_Size);
   begin
      IT.Table (N)     := Item.X;
      IT.Table (N + 1) := Item.Y;
      IT.Table (N + 2) := Item.Key;
   end Set_Edges;

   ---------------
   -- Set_Graph --
   ---------------

   procedure Set_Graph (N : Natural; Item : Integer) is
   begin
      IT.Table (G + N) := Item;
   end Set_Graph;

   -------------
   -- Set_Key --
   -------------

   procedure Set_Key (N : Key_Id; Item : Key_Type) is
   begin
      IT.Table (Keys + N) := Item.Edge;
   end Set_Key;

   ---------------
   -- Set_Table --
   ---------------

   procedure Set_Table (T : Integer; X, Y : Natural; Item : Natural) is
      N : constant Natural := T + ((Y * T1_Len) + X);
   begin
      IT.Table (N) := Item;
   end Set_Table;

   -------------------
   -- Set_Used_Char --
   -------------------

   procedure Set_Used_Char (C : Character; Item : Natural) is
      N : constant Natural := Used_Char_Set + Character'Pos (C);
   begin
      IT.Table (N) := Item;
   end Set_Used_Char;

   ------------------
   -- Set_Vertices --
   ------------------

   procedure Set_Vertices (F : Natural; Item : Vertex_Type) is
      N : constant Natural := Vertices + (F * Vertex_Size);
   begin
      IT.Table (N)     := Item.First;
      IT.Table (N + 1) := Item.Last;
   end Set_Vertices;

   ---------
   -- Sum --
   ---------

   function Sum
     (Word  : Word_Type;
      Table : Table_Id;
      Opt   : Optimization) return Natural
   is
      S : Natural := 0;
      R : Natural;

   begin
      case Opt is
         when CPU_Time =>
            for J in 0 .. T1_Len - 1 loop
               exit when Word (J + 1) = ASCII.NUL;
               R := Get_Table (Table, J, Get_Used_Char (Word (J + 1)));
               pragma Assert (NV /= 0);
               S := (S + R) mod NV;
            end loop;

         when Memory_Space =>
            for J in 0 .. T1_Len - 1 loop
               exit when Word (J + 1) = ASCII.NUL;
               R := Get_Table (Table, J, 0);
               pragma Assert (NV /= 0);
               S := (S + R * Character'Pos (Word (J + 1))) mod NV;
            end loop;
      end case;

      return S;
   end Sum;

   ------------------------
   -- Trim_Trailing_Nuls --
   ------------------------

   function Trim_Trailing_Nuls (Str : String) return String is
   begin
      for J in reverse Str'Range loop
         if Str (J) /= ASCII.NUL then
            return Str (Str'First .. J);
         end if;
      end loop;

      return Str;
   end Trim_Trailing_Nuls;

   ---------------
   -- Type_Size --
   ---------------

   function Type_Size (L : Natural) return Natural is
   begin
      if L <= 2 ** 8 then
         return 8;
      elsif L <= 2 ** 16 then
         return 16;
      else
         return 32;
      end if;
   end Type_Size;

   -----------
   -- Value --
   -----------

   function Value
     (Name : Table_Name;
      J    : Natural;
      K    : Natural := 0) return Natural
   is
   begin
      case Name is
         when Character_Position =>
            return Get_Char_Pos (J);

         when Used_Character_Set =>
            return Get_Used_Char (Character'Val (J));

         when Function_Table_1 =>
            return Get_Table (T1, J, K);

         when Function_Table_2 =>
            return Get_Table (T2, J, K);

         when Graph_Table =>
            return Get_Graph (J);
      end case;
   end Value;

end System.Perfect_Hash_Generators;
