Как включить аспекты доказательства в спецификацию, чтобы каждая функция и процедура имели аспект Post и, при необходимости, аспект Pre, который описывает правильное поведение кода ниже:
package Stack with SPARK_Mode is
pragma Elaborate_Body;
Stack_Size : constant := 100;
type Pointer_Range is range 0 .. Stack_Size;
subtype Index_Range is Pointer_Range range 1 .. Stack_Size;
type Vector is array(Index_Range) of Integer;
S: Vector;
Pointer: Pointer_Range;
function isEmpty return Boolean;
procedure Push(X : in Integer)
with
Global => (In_out => (S, Pointer)),
Depends => (S => (S, Pointer, X),
Pointer => Pointer);
procedure Pop(X : out Integer)
with
Global => (input => S, in_out => Pointer),
Depends => (Pointer => Pointer,
X => (S, Pointer));
end Stack;
Короче говоря, вы должны добавить аспект пост-условия к каждой подпрограмме в пакете и аспект предусловия к тем подпрограммам, которые в нем нуждаются.
Предусловия и постусловия в Аде объясняются на http://www.ada-auth.org/standards/22rm/html/RM-6-1-1.html.
В чем твоя проблема, на самом деле? Речь идет о синтаксисе аспектов до/после условия или об их содержании и значении? Или речь идет о значении «надлежащего поведения» в постановке задачи? В последнем случае попытайтесь представить, что может быть неправильным поведением или неправильным использованием операции Push или Pop в стеке с фиксированным максимальным размером.
Ниже приведен возможный набор пост-условий и предварительных условий для вашего примера. Фактический набор должен зависеть от фактических требований к поведению вашего стека. Этот пример — просто типичный набор условий для стека.
package Stack with SPARK_MODE is
pragma Elaborate_Body;
Stack_Size : constant := 100;
type Pointer_Range is range 0 .. Stack_Size;
subtype Index_Range is Pointer_Range range 1..Stack_Size;
type Vector is array (Index_Range) of Integer;
S : Vector;
Pointer : Pointer_Range := 0;
function isEmpty return Boolean with
Post => IsEmpty'Result = (if Pointer = 0 then True else False);
procedure Push(X : in Integer) with
Global => (In_Out => (S, Pointer)),
Depends => (S => (S, Pointer, X), Pointer => Pointer),
Pre => Pointer < Stack_Size,
Post => Pointer = Pointer'Old + 1 and S(Pointer) = X;
procedure Pop(X : out Integer) with
Global => (In_Out => (S, Pointer)),
Depends => (Pointer => Pointer,
X => (S, Pointer),
S => S),
Pre => not isEmpty,
Post => Pointer = Pointer'Old - 1 and X = S(Pointer'Old);
end Stack;
Аспекты подпрограммы записываются в конце объявления подпрограммы после ключевого слова with и перед завершающей точкой с запятой. Если аспектов несколько, они разделяются запятыми. Показанные операции Push и Pop уже имеют по два аспекта: глобальный аспект и аспект зависимостей. Вы добавляете аспекты Pre и Post в эти списки аспектов, ставя перед каждым разделяющую запятую: procedure Push ... with Global => ..., Depends => ..., Pre => ..., Post => . ..;