Commit f2acfbce by Claire Dross Committed by Arnaud Charlet

a-cforma.adb, [...] (=): Generic parameter removed to allow the use of regular…

a-cforma.adb, [...] (=): Generic parameter removed to allow the use of regular equality over elements in...

2017-04-27  Claire Dross  <dross@adacore.com>

	* a-cforma.adb, a-cforma.ads (=): Generic parameter removed to
	allow the use of regular equality over elements in contracts.
	(Formal_Model): Ghost package containing model functions that
	are used in subprogram contracts.
	(Current_To_Last): Removed, model functions should be used instead.
	(First_To_Previous): Removed, model functions should be used instead.
	(Strict_Equal): Removed, model functions should be used instead.
	(No_Overlap): Removed, model functions should be used instead.
	* a-cofuma.adb, a-cofuma.ads (Enable_Handling_Of_Equivalence)
	Boolean generic parameter to disable contracts for equivalence
	between keys.
	(Witness): Create a witness of a key that is used for handling of
	equivalence between keys.
	(Has_Witness): Check whether a witness is contained in a map.
	(W_Get): Get the element associated to a witness.
	(Lift_Equivalent_Keys): Removed, equivalence between keys is handled
	directly.
	* a-cofuse.adb, a-cofuse.ads (Enable_Handling_Of_Equivalence)
	Boolean generic parameter to disable contracts for equivalence
	between keys.
	* a-cfhama.adb, a-cfhama.ads (Formal_Model.P) Disable handling
	of equivalence on functional maps.
	* a-cfdlli.adb, a-cfdlli.ads (Formal_Model.P) Disable handling
	of equivalence on functional maps.

From-SVN: r247328
parent 12ead254
2017-04-27 Claire Dross <dross@adacore.com>
* a-cforma.adb, a-cforma.ads (=): Generic parameter removed to
allow the use of regular equality over elements in contracts.
(Formal_Model): Ghost package containing model functions that
are used in subprogram contracts.
(Current_To_Last): Removed, model functions should be used instead.
(First_To_Previous): Removed, model functions should be used instead.
(Strict_Equal): Removed, model functions should be used instead.
(No_Overlap): Removed, model functions should be used instead.
* a-cofuma.adb, a-cofuma.ads (Enable_Handling_Of_Equivalence)
Boolean generic parameter to disable contracts for equivalence
between keys.
(Witness): Create a witness of a key that is used for handling of
equivalence between keys.
(Has_Witness): Check whether a witness is contained in a map.
(W_Get): Get the element associated to a witness.
(Lift_Equivalent_Keys): Removed, equivalence between keys is handled
directly.
* a-cofuse.adb, a-cofuse.ads (Enable_Handling_Of_Equivalence)
Boolean generic parameter to disable contracts for equivalence
between keys.
* a-cfhama.adb, a-cfhama.ads (Formal_Model.P) Disable handling
of equivalence on functional maps.
* a-cfdlli.adb, a-cfdlli.ads (Formal_Model.P) Disable handling
of equivalence on functional maps.
2017-04-27 Hristian Kirtchev <kirtchev@adacore.com> 2017-04-27 Hristian Kirtchev <kirtchev@adacore.com>
* exp_ch9.adb (Expand_Entry_Barrier): Code * exp_ch9.adb (Expand_Entry_Barrier): Code
......
...@@ -153,7 +153,8 @@ is ...@@ -153,7 +153,8 @@ is
package P is new Ada.Containers.Functional_Maps package P is new Ada.Containers.Functional_Maps
(Key_Type => Cursor, (Key_Type => Cursor,
Element_Type => Positive_Count_Type, Element_Type => Positive_Count_Type,
Equivalent_Keys => "="); Equivalent_Keys => "=",
Enable_Handling_Of_Equivalence => False);
function "=" function "="
(Left : P.Map; (Left : P.Map;
......
...@@ -68,7 +68,7 @@ is ...@@ -68,7 +68,7 @@ is
Next => Next, Next => Next,
Has_Element => Has_Element, Has_Element => Has_Element,
Element => Key), Element => Key),
Default_Initial_Condition => Is_Empty (Map) and Length (Map) = 0; Default_Initial_Condition => Is_Empty (Map);
pragma Preelaborable_Initialization (Map); pragma Preelaborable_Initialization (Map);
Empty_Map : constant Map; Empty_Map : constant Map;
...@@ -120,7 +120,8 @@ is ...@@ -120,7 +120,8 @@ is
package P is new Ada.Containers.Functional_Maps package P is new Ada.Containers.Functional_Maps
(Key_Type => Cursor, (Key_Type => Cursor,
Element_Type => Positive_Count_Type, Element_Type => Positive_Count_Type,
Equivalent_Keys => "="); Equivalent_Keys => "=",
Enable_Handling_Of_Equivalence => False);
function "=" function "="
(Left : P.Map; (Left : P.Map;
...@@ -262,7 +263,7 @@ is ...@@ -262,7 +263,7 @@ is
function Is_Empty (Container : Map) return Boolean with function Is_Empty (Container : Map) return Boolean with
Global => null, Global => null,
Post => Is_Empty'Result = M.Is_Empty (Model (Container)); Post => Is_Empty'Result = (Length (Container) = 0);
procedure Clear (Container : in out Map) with procedure Clear (Container : in out Map) with
Global => null, Global => null,
...@@ -503,6 +504,12 @@ is ...@@ -503,6 +504,12 @@ is
Model (Container)'Old, Model (Container)'Old,
Key) Key)
-- Key is inserted in Container
and K.Get (Keys (Container),
P.Get (Positions (Container), Find (Container, Key))) =
Key
-- Mapping from cursors to keys is preserved -- Mapping from cursors to keys is preserved
and Mapping_Preserved and Mapping_Preserved
......
...@@ -148,6 +148,13 @@ package body Ada.Containers.Functional_Maps with SPARK_Mode => Off is ...@@ -148,6 +148,13 @@ package body Ada.Containers.Functional_Maps with SPARK_Mode => Off is
return Find (Container.Keys, Key) > 0; return Find (Container.Keys, Key) > 0;
end Has_Key; end Has_Key;
-----------------
-- Has_Witness --
-----------------
function Has_Witness (Container : Map; Witness : Count_Type) return Boolean
is (Witness in 1 .. Length (Container.Keys));
-------------- --------------
-- Is_Empty -- -- Is_Empty --
-------------- --------------
...@@ -233,16 +240,6 @@ package body Ada.Containers.Functional_Maps with SPARK_Mode => Off is ...@@ -233,16 +240,6 @@ package body Ada.Containers.Functional_Maps with SPARK_Mode => Off is
return Length (Container.Elements); return Length (Container.Elements);
end Length; end Length;
--------------------------
-- Lift_Equivalent_Keys --
--------------------------
procedure Lift_Equivalent_Keys
(Container : Map;
Left : Key_Type;
Right : Key_Type)
is null;
--------------- ---------------
-- Same_Keys -- -- Same_Keys --
--------------- ---------------
...@@ -264,4 +261,19 @@ package body Ada.Containers.Functional_Maps with SPARK_Mode => Off is ...@@ -264,4 +261,19 @@ package body Ada.Containers.Functional_Maps with SPARK_Mode => Off is
Elements => Elements =>
Set (Container.Elements, Find (Container.Keys, Key), New_Item)); Set (Container.Elements, Find (Container.Keys, Key), New_Item));
-----------
-- W_Get --
-----------
function W_Get (Container : Map; Witness : Count_Type) return Element_Type
is
(Get (Container.Elements, Witness));
-------------
-- Witness --
-------------
function Witness (Container : Map; Key : Key_Type) return Count_Type is
(Find (Container.Keys, Key));
end Ada.Containers.Functional_Maps; end Ada.Containers.Functional_Maps;
...@@ -36,6 +36,10 @@ generic ...@@ -36,6 +36,10 @@ generic
type Key_Type (<>) is private; type Key_Type (<>) is private;
type Element_Type (<>) is private; type Element_Type (<>) is private;
with function Equivalent_Keys (Left, Right : Key_Type) return Boolean; with function Equivalent_Keys (Left, Right : Key_Type) return Boolean;
Enable_Handling_Of_Equivalence : Boolean := True;
-- This constant should only be set to False when no particular handling
-- of equivalence over keys is needed, that is, Equivalent_Keys defines a
-- key uniquely.
package Ada.Containers.Functional_Maps with SPARK_Mode is package Ada.Containers.Functional_Maps with SPARK_Mode is
...@@ -57,38 +61,40 @@ package Ada.Containers.Functional_Maps with SPARK_Mode is ...@@ -57,38 +61,40 @@ package Ada.Containers.Functional_Maps with SPARK_Mode is
----------------------- -----------------------
-- Maps are axiomatized using Has_Key and Get, encoding respectively the -- Maps are axiomatized using Has_Key and Get, encoding respectively the
-- presence of a key in a map and an accessor to elements associated to its -- presence of a key in a map and an accessor to elements associated with
-- keys. The length of a map is also added to protect Add against overflows -- its keys. The length of a map is also added to protect Add against
-- but it is not actually modeled. -- overflows but it is not actually modeled.
function Has_Key (Container : Map; Key : Key_Type) return Boolean with function Has_Key (Container : Map; Key : Key_Type) return Boolean with
Global => null;
-- Return True if Key is present in Container -- Return True if Key is present in Container
function Get (Container : Map; Key : Key_Type) return Element_Type with
Global => null, Global => null,
Pre => Has_Key (Container, Key); Post =>
-- Return the element associated to Key is present in Container (if Enable_Handling_Of_Equivalence then
function Length (Container : Map) return Count_Type with -- Has_Key returns the same result on all equivalent keys
Global => null;
-- Return the number of mappings in Container
procedure Lift_Equivalent_Keys (if (for some K of Container => Equivalent_Keys (K, Key)) then
(Container : Map; Has_Key'Result));
Left : Key_Type;
Right : Key_Type) function Get (Container : Map; Key : Key_Type) return Element_Type with
-- Lemma function which can be called manually to allow GNATprove to deduce -- Return the element associated with Key in Container
-- that Has_Key and Get always return the same result on equivalent keys.
with
Ghost,
Global => null, Global => null,
Pre => Equivalent_Keys (Left, Right), Pre => Has_Key (Container, Key),
Post => Post =>
Has_Key (Container, Left) = Has_Key (Container, Right) (if Enable_Handling_Of_Equivalence then
and (if Has_Key (Container, Left) then
Get (Container, Left) = Get (Container, Right)); -- Get returns the same result on all equivalent keys
Get'Result = W_Get (Container, Witness (Container, Key))
and (for all K of Container =>
(if Equivalent_Keys (K, Key) then
Witness (Container, Key) = Witness (Container, K))));
function Length (Container : Map) return Count_Type with
Global => null;
-- Return the number of mappings in Container
------------------------ ------------------------
-- Property Functions -- -- Property Functions --
...@@ -236,8 +242,8 @@ package Ada.Containers.Functional_Maps with SPARK_Mode is ...@@ -236,8 +242,8 @@ package Ada.Containers.Functional_Maps with SPARK_Mode is
(Container : Map; (Container : Map;
Key : Key_Type; Key : Key_Type;
New_Item : Element_Type) return Map New_Item : Element_Type) return Map
-- Returns Container, where the element associated to Key has been replaced -- Returns Container, where the element associated with Key has been
-- by New_Item. -- replaced by New_Item.
with with
Global => null, Global => null,
...@@ -248,6 +254,35 @@ package Ada.Containers.Functional_Maps with SPARK_Mode is ...@@ -248,6 +254,35 @@ package Ada.Containers.Functional_Maps with SPARK_Mode is
and Same_Keys (Container, Set'Result) and Same_Keys (Container, Set'Result)
and Elements_Equal_Except (Container, Set'Result, Key); and Elements_Equal_Except (Container, Set'Result, Key);
------------------------------
-- Handling of Equivalence --
------------------------------
-- These functions are used to specify that Get returns the same value on
-- equivalent keys. They should not be used directly in user code.
function Has_Witness (Container : Map; Witness : Count_Type) return Boolean
with
Ghost,
Global => null;
-- Returns True if there is a key with witness Witness in Container
function Witness (Container : Map; Key : Key_Type) return Count_Type with
-- Returns the witness of Key in Container
Ghost,
Global => null,
Pre => Has_Key (Container, Key),
Post => Has_Witness (Container, Witness'Result);
function W_Get (Container : Map; Witness : Count_Type) return Element_Type
with
-- Returns the element associated with a witness in Container
Ghost,
Global => null,
Pre => Has_Witness (Container, Witness);
--------------------------- ---------------------------
-- Iteration Primitives -- -- Iteration Primitives --
--------------------------- ---------------------------
......
...@@ -37,6 +37,10 @@ generic ...@@ -37,6 +37,10 @@ generic
with function Equivalent_Elements with function Equivalent_Elements
(Left : Element_Type; (Left : Element_Type;
Right : Element_Type) return Boolean; Right : Element_Type) return Boolean;
Enable_Handling_Of_Equivalence : Boolean := True;
-- This constant should only be set to False when no particular handling
-- of equivalence over elements is needed, that is, Equivalent_Elements
-- defines an element uniquely.
package Ada.Containers.Functional_Sets with SPARK_Mode is package Ada.Containers.Functional_Sets with SPARK_Mode is
...@@ -49,6 +53,9 @@ package Ada.Containers.Functional_Sets with SPARK_Mode is ...@@ -49,6 +53,9 @@ package Ada.Containers.Functional_Sets with SPARK_Mode is
-- Sets are empty when default initialized. -- Sets are empty when default initialized.
-- "For in" quantification over sets should not be used. -- "For in" quantification over sets should not be used.
-- "For of" quantification over sets iterates over elements. -- "For of" quantification over sets iterates over elements.
-- Note that, for proof, "for of" quantification is understood modulo
-- equivalence (quantification includes elements equivalent to elements of
-- the map).
----------------------- -----------------------
-- Basic operations -- -- Basic operations --
...@@ -59,9 +66,17 @@ package Ada.Containers.Functional_Sets with SPARK_Mode is ...@@ -59,9 +66,17 @@ package Ada.Containers.Functional_Sets with SPARK_Mode is
-- against overflows but it is not actually modeled. -- against overflows but it is not actually modeled.
function Contains (Container : Set; Item : Element_Type) return Boolean with function Contains (Container : Set; Item : Element_Type) return Boolean with
Global => null;
-- Return True if Item is contained in Container -- Return True if Item is contained in Container
Global => null,
Post =>
(if Enable_Handling_Of_Equivalence then
-- Contains returns the same result on all equivalent elements
(if (for some E of Container => Equivalent_Elements (E, Item)) then
Contains'Result));
function Length (Container : Set) return Count_Type with function Length (Container : Set) return Count_Type with
Global => null; Global => null;
-- Return the number of elements in Container -- Return the number of elements in Container
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment