File : a-cforma.ads


   1 ------------------------------------------------------------------------------
   2 --                                                                          --
   3 --                         GNAT LIBRARY COMPONENTS                          --
   4 --                                                                          --
   5 --   A D A . C O N T A I N E R S . F O R M A L _ O R D E R E D _ M A P S    --
   6 --                                                                          --
   7 --                                 S p e c                                  --
   8 --                                                                          --
   9 --          Copyright (C) 2004-2015, Free Software Foundation, Inc.         --
  10 --                                                                          --
  11 -- This specification is derived from the Ada Reference Manual for use with --
  12 -- GNAT. The copyright notice above, and the license provisions that follow --
  13 -- apply solely to the  contents of the part following the private keyword. --
  14 --                                                                          --
  15 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
  16 -- terms of the  GNU General Public License as published  by the Free Soft- --
  17 -- ware  Foundation;  either version 3,  or (at your option) any later ver- --
  18 -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
  19 -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
  20 -- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
  21 --                                                                          --
  22 --                                                                          --
  23 --                                                                          --
  24 --                                                                          --
  25 --                                                                          --
  26 -- You should have received a copy of the GNU General Public License and    --
  27 -- a copy of the GCC Runtime Library Exception along with this program;     --
  28 -- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
  29 -- <http://www.gnu.org/licenses/>.                                          --
  30 ------------------------------------------------------------------------------
  31 
  32 --  This spec is derived from package Ada.Containers.Bounded_Ordered_Maps in
  33 --  the Ada 2012 RM. The modifications are meant to facilitate formal proofs by
  34 --  making it easier to express properties, and by making the specification of
  35 --  this unit compatible with SPARK 2014. Note that the API of this unit may be
  36 --  subject to incompatible changes as SPARK 2014 evolves.
  37 
  38 --  The modifications are:
  39 
  40 --    A parameter for the container is added to every function reading the
  41 --    content of a container: Key, Element, Next, Query_Element, Previous,
  42 --    Has_Element, Iterate, Reverse_Iterate. This change is motivated by the
  43 --    need to have cursors which are valid on different containers (typically a
  44 --    container C and its previous version C'Old) for expressing properties,
  45 --    which is not possible if cursors encapsulate an access to the underlying
  46 --    container. The operators "<" and ">" that could not be modified that way
  47 --    have been removed.
  48 
  49 --    There are four new functions:
  50 
  51 --      function Strict_Equal (Left, Right : Map) return Boolean;
  52 --      function Overlap (Left, Right : Map) return Boolean;
  53 --      function First_To_Previous  (Container : Map; Current : Cursor)
  54 --         return Map;
  55 --      function Current_To_Last (Container : Map; Current : Cursor)
  56 --         return Map;
  57 
  58 --    See detailed specifications for these subprograms
  59 
  60 private with Ada.Containers.Red_Black_Trees;
  61 
  62 generic
  63    type Key_Type is private;
  64    type Element_Type is private;
  65 
  66    with function "<" (Left, Right : Key_Type) return Boolean is <>;
  67    with function "=" (Left, Right : Element_Type) return Boolean is <>;
  68 
  69 package Ada.Containers.Formal_Ordered_Maps with
  70   Pure,
  71   SPARK_Mode
  72 is
  73    pragma Annotate (GNATprove, External_Axiomatization);
  74    pragma Annotate (CodePeer, Skip_Analysis);
  75 
  76    function Equivalent_Keys (Left, Right : Key_Type) return Boolean with
  77      Global => null;
  78 
  79    type Map (Capacity : Count_Type) is private with
  80      Iterable => (First       => First,
  81                   Next        => Next,
  82                   Has_Element => Has_Element,
  83                   Element     => Element),
  84      Default_Initial_Condition => Is_Empty (Map);
  85    pragma Preelaborable_Initialization (Map);
  86 
  87    type Cursor is private;
  88    pragma Preelaborable_Initialization (Cursor);
  89 
  90    Empty_Map : constant Map;
  91 
  92    No_Element : constant Cursor;
  93 
  94    function "=" (Left, Right : Map) return Boolean with
  95      Global => null;
  96 
  97    function Length (Container : Map) return Count_Type with
  98      Global => null;
  99 
 100    function Is_Empty (Container : Map) return Boolean with
 101      Global => null;
 102 
 103    procedure Clear (Container : in out Map) with
 104      Global => null;
 105 
 106    procedure Assign (Target : in out Map; Source : Map) with
 107      Global => null,
 108      Pre    => Target.Capacity >= Length (Source);
 109 
 110    function Copy (Source : Map; Capacity : Count_Type := 0) return Map with
 111      Global => null,
 112      Pre    => Capacity = 0 or else Capacity >= Source.Capacity;
 113 
 114    function Key (Container : Map; Position : Cursor) return Key_Type with
 115      Global => null,
 116      Pre    => Has_Element (Container, Position);
 117 
 118    function Element
 119      (Container : Map;
 120       Position  : Cursor) return Element_Type
 121    with
 122      Global => null,
 123      Pre    => Has_Element (Container, Position);
 124 
 125    procedure Replace_Element
 126      (Container : in out Map;
 127       Position  : Cursor;
 128       New_Item  : Element_Type)
 129    with
 130      Global => null,
 131      Pre    => Has_Element (Container, Position);
 132 
 133    procedure Move (Target : in out Map; Source : in out Map) with
 134      Global => null,
 135      Pre    => Target.Capacity >= Length (Source);
 136 
 137    procedure Insert
 138      (Container : in out Map;
 139       Key       : Key_Type;
 140       New_Item  : Element_Type;
 141       Position  : out Cursor;
 142       Inserted  : out Boolean)
 143    with
 144      Global => null,
 145      Pre    => Length (Container) < Container.Capacity;
 146 
 147    procedure Insert
 148      (Container : in out Map;
 149       Key       : Key_Type;
 150       New_Item  : Element_Type)
 151    with
 152      Global => null,
 153      Pre    => Length (Container) < Container.Capacity
 154                  and then (not Contains (Container, Key));
 155 
 156    procedure Include
 157      (Container : in out Map;
 158       Key       : Key_Type;
 159       New_Item  : Element_Type)
 160    with
 161      Global => null,
 162      Pre    => Length (Container) < Container.Capacity;
 163 
 164    procedure Replace
 165      (Container : in out Map;
 166       Key       : Key_Type;
 167       New_Item  : Element_Type)
 168    with
 169      Global => null,
 170      Pre    => Contains (Container, Key);
 171 
 172    procedure Exclude (Container : in out Map; Key : Key_Type) with
 173      Global => null;
 174 
 175    procedure Delete (Container : in out Map; Key : Key_Type) with
 176      Global => null,
 177      Pre    => Contains (Container, Key);
 178 
 179    procedure Delete (Container : in out Map; Position : in out Cursor) with
 180      Global => null,
 181      Pre    => Has_Element (Container, Position);
 182 
 183    procedure Delete_First (Container : in out Map) with
 184      Global => null;
 185 
 186    procedure Delete_Last (Container : in out Map) with
 187      Global => null;
 188 
 189    function First (Container : Map) return Cursor with
 190      Global => null;
 191 
 192    function First_Element (Container : Map) return Element_Type with
 193      Global => null,
 194      Pre    => not Is_Empty (Container);
 195 
 196    function First_Key (Container : Map) return Key_Type with
 197      Global => null,
 198      Pre    => not Is_Empty (Container);
 199 
 200    function Last (Container : Map) return Cursor with
 201      Global => null;
 202 
 203    function Last_Element (Container : Map) return Element_Type with
 204      Global => null,
 205      Pre    => not Is_Empty (Container);
 206 
 207    function Last_Key (Container : Map) return Key_Type with
 208      Global => null,
 209      Pre    => not Is_Empty (Container);
 210 
 211    function Next (Container : Map; Position : Cursor) return Cursor with
 212      Global => null,
 213      Pre    => Has_Element (Container, Position) or else Position = No_Element;
 214 
 215    procedure Next (Container : Map; Position : in out Cursor) with
 216      Global => null,
 217      Pre    => Has_Element (Container, Position) or else Position = No_Element;
 218 
 219    function Previous (Container : Map; Position : Cursor) return Cursor with
 220      Global => null,
 221      Pre    => Has_Element (Container, Position) or else Position = No_Element;
 222 
 223    procedure Previous (Container : Map; Position : in out Cursor) with
 224      Global => null,
 225      Pre    => Has_Element (Container, Position) or else Position = No_Element;
 226 
 227    function Find (Container : Map; Key : Key_Type) return Cursor with
 228      Global => null;
 229 
 230    function Element (Container : Map; Key : Key_Type) return Element_Type with
 231      Global => null,
 232      Pre    => Contains (Container, Key);
 233 
 234    function Floor (Container : Map; Key : Key_Type) return Cursor with
 235      Global => null;
 236 
 237    function Ceiling (Container : Map; Key : Key_Type) return Cursor with
 238      Global => null;
 239 
 240    function Contains (Container : Map; Key : Key_Type) return Boolean with
 241      Global => null;
 242 
 243    function Has_Element (Container : Map; Position : Cursor) return Boolean
 244    with
 245      Global => null;
 246 
 247    function Strict_Equal (Left, Right : Map) return Boolean with
 248      Ghost,
 249      Global => null;
 250    --  Strict_Equal returns True if the containers are physically equal, i.e.
 251    --  they are structurally equal (function "=" returns True) and that they
 252    --  have the same set of cursors.
 253 
 254    function First_To_Previous (Container : Map; Current : Cursor) return Map
 255    with
 256      Ghost,
 257      Global => null,
 258      Pre    => Has_Element (Container, Current) or else Current = No_Element;
 259 
 260    function Current_To_Last (Container : Map; Current : Cursor) return Map
 261    with
 262      Ghost,
 263      Global => null,
 264      Pre    => Has_Element (Container, Current) or else Current = No_Element;
 265    --  First_To_Previous returns a container containing all elements preceding
 266    --  Current (excluded) in Container. Current_To_Last returns a container
 267    --  containing all elements following Current (included) in Container.
 268    --  These two new functions can be used to express invariant properties in
 269    --  loops which iterate over containers. First_To_Previous returns the part
 270    --  of the container already scanned and Current_To_Last the part not
 271    --  scanned yet.
 272 
 273    function Overlap (Left, Right : Map) return Boolean with
 274      Global => null;
 275    --  Overlap returns True if the containers have common keys
 276 
 277 private
 278    pragma SPARK_Mode (Off);
 279 
 280    pragma Inline (Next);
 281    pragma Inline (Previous);
 282 
 283    subtype Node_Access is Count_Type;
 284 
 285    use Red_Black_Trees;
 286 
 287    type Node_Type is record
 288       Has_Element : Boolean := False;
 289       Parent  : Node_Access := 0;
 290       Left    : Node_Access := 0;
 291       Right   : Node_Access := 0;
 292       Color   : Red_Black_Trees.Color_Type := Red;
 293       Key     : Key_Type;
 294       Element : Element_Type;
 295    end record;
 296 
 297    package Tree_Types is
 298      new Ada.Containers.Red_Black_Trees.Generic_Bounded_Tree_Types (Node_Type);
 299 
 300    type Map (Capacity : Count_Type) is
 301      new Tree_Types.Tree_Type (Capacity) with null record;
 302 
 303    type Cursor is record
 304       Node : Node_Access;
 305    end record;
 306 
 307    Empty_Map : constant Map := (Capacity => 0, others => <>);
 308 
 309    No_Element : constant Cursor := (Node => 0);
 310 
 311 end Ada.Containers.Formal_Ordered_Maps;