blob: fd25294ea389e85b97408607385007f0fb9d6394 [file] [log] [blame]
pragma Spark_Mode (On);
generic
type Element_Type is private;
package Predicate8_Pkg is
pragma Annotate (GNATprove, Terminating, Predicate8_Pkg);
subtype Small_Natural is Natural range 0 .. Natural'Last / 2;
subtype Small_Positive is Natural range 1 .. Natural'Last / 2;
type Element_Array_Type is array (Small_Positive range <>) of Element_Type;
type Ring_Buffer_Type (Max_Size : Small_Positive) is private
with Default_Initial_Condition => Empty (Ring_Buffer_Type);
function Empty
(Buffer : in Ring_Buffer_Type) return Boolean;
function Full
(Buffer : in Ring_Buffer_Type) return Boolean;
function Size
(Buffer : in Ring_Buffer_Type) return Natural;
function Free
(Buffer : in Ring_Buffer_Type) return Natural;
function First
(Buffer : in Ring_Buffer_Type) return Element_Type
with
Pre => not Empty (Buffer);
function Last
(Buffer : in Ring_Buffer_Type) return Element_Type
with
Pre => not Empty (Buffer);
procedure Get
(Buffer : in out Ring_Buffer_Type;
Element : out Element_Type)
with
Pre => not Empty (Buffer) and
Size (Buffer) >= 1,
Post => not Full (Buffer) and then
Element = First (Buffer'Old) and then
Size (Buffer) = Size (Buffer'Old) - 1;
procedure Put
(Buffer : in out Ring_Buffer_Type;
Element : in Element_Type)
with
Pre => not Full (Buffer),
Post => not Empty (Buffer) and then
Last (Buffer) = Element and then
Size (Buffer) = Size (Buffer'Old) + 1;
procedure Clear
(Buffer : in out Ring_Buffer_Type)
with
Post => Empty (Buffer) and then
not Full (Buffer) and then
Size (Buffer) = 0;
private
type Ring_Buffer_Type (Max_Size : Small_Positive) is record
Count : Small_Natural := 0;
Head : Small_Positive := 1;
Tail : Small_Positive := Max_Size;
Items : Element_Array_Type (1 .. Max_Size);
end record
with Dynamic_Predicate =>
(Max_Size <= Small_Positive'Last and
Count <= Max_Size and
Head <= Max_Size and
Tail <= Max_Size and
((Count = 0 and Tail = Max_Size and Head = 1) or
(Count = Max_Size + Tail - Head + 1) or
(Count = Tail - Head + 1)));
end Predicate8_Pkg;