-------------------------------------------------------------------------------
-- (C) Altran Praxis Limited
-------------------------------------------------------------------------------
--
-- The SPARK toolset is free software; you can redistribute it and/or modify it
-- under terms of the GNU General Public License as published by the Free
-- Software Foundation; either version 3, or (at your option) any later
-- version. The SPARK toolset is distributed in the hope that it will be
-- useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
-- Public License for more details. You should have received a copy of the GNU
-- General Public License distributed with the SPARK toolset; see file
-- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy of
-- the license.
--
--=============================================================================

with Cell_Storage;
with Cells;
with Pairs;

--# inherit Cells,
--#         Cell_Storage,
--#         Clists,
--#         Pairs,
--#         Statistics,
--#         Structures;

package Labels is

   type Label is private;

   function LabelHead (L : Label) return Cells.Cell;

   function FirstPair (Heap : Cells.Heap_Record;
                       L    : Label) return Pairs.Pair;

   function NextPair (Heap : Cells.Heap_Record;
                      P    : Pairs.Pair) return Pairs.Pair;

   function IsNull (L : Label) return Boolean;

   function CellToLabel (C : Cells.Cell) return Label;

   procedure AppendPair (Heap      : in out Cells.Heap_Record;
                         NewPair   : in     Pairs.Pair;
                         LabelName : in     Label);
   --# derives Heap from *,
   --#                   LabelName,
   --#                   NewPair;

   procedure CreateLabel (Heap     : in out Cells.Heap_Record;
                          NewLabel :    out Label);
   --# global in out Statistics.TableUsage;
   --# derives Heap,
   --#         Statistics.TableUsage from *,
   --#                                    Heap &
   --#         NewLabel              from Heap;

   procedure CopyLabel (Heap     : in out Cells.Heap_Record;
                        Original : in     Label;
                        Copy     :    out Label);
   --# global in out Statistics.TableUsage;
   --# derives Copy,
   --#         Heap                  from Heap,
   --#                                    Original &
   --#         Statistics.TableUsage from *,
   --#                                    Heap,
   --#                                    Original;

   procedure AddLabels (Heap    : in out Cells.Heap_Record;
                        Label_1 : in     Label;
                        Label_2 : in     Label);
   --# derives Heap from *,
   --#                   Label_1,
   --#                   Label_2;

   procedure MultiplyLabels
     (Heap    : in out Cells.Heap_Record;
      Label_1 : in     Label;
      Label_2 : in     Label;
      Product :    out Label);
   --# global in out Statistics.TableUsage;
   --# derives Heap,
   --#         Statistics.TableUsage from *,
   --#                                    Heap,
   --#                                    Label_1,
   --#                                    Label_2 &
   --#         Product               from Heap;

private
   type Label is range 0 .. Cell_Storage.Cell'Last;
   --# assert Label'Base is Integer;
end Labels;
