Я пытался изучить основы использования SPARK, и я разобрался с предварительными и последующими условиями, но я не уверен, заменят ли они место проверки? например, функция для самолета, который не переключится в режим взлета, пока все двери не будут закрыты и заперты. Нужно ли мне добавлять код в тело процедуры, чтобы остановить это поведение, или достаточно предварительных и конечных условий? Для меня это неясно, потому что ни в одном из моих учебных пособий этого не делается, но когда я тестирую процедуры, я не ограничен в нарушении условий.
Заменяют ли предварительные и последующие условия проверку в функции?
Ответы (3)
Первый: если вы используете компилятор GNAT, вы должны добавить флаг -gnata
к флагам компилятора или использовать файл конфигурации для GNAT с pragma Assertion_Policy(Check);
, чтобы включить проверку для Pre- и Post-условий. Без одной из этих опций все проверки игнорируются. Вот почему вам позволено нарушать их.
Предварительные условия имеют место непосредственно перед выполнением выбранной подпрограммы. Например, функция, объявленная как:
function Add(A, B: Positive) return Positive is (A + B) with
Pre => A < 10;
Это предварительное условие будет проверено перед выполнением функции. Например:
I := Add(2, 2);
Put_Line(Positive'Image(I)); -- prints 4 as expected
begin
I := Add(10, 2); -- Crash, exception on violation of precondition
exception
when ASSERT_FAILURE =>
Put_Line(Positive'Image(I)); -- prints 4
end;
Постусловия проверяются на подпрограммах после их выполнения. Другой пример:
procedure Increment(A: in out Positive) with
Post => A < 20 is
begin
A := A + 1;
end Increment;
И использование:
I := 2;
Increment(I);
Put_Line(Positive'Image(I)); -- prints 3
I := 19;
begin
I := Increment(I); -- Crash, exception on violation of postcondition
exception
when ASSERT_FAILURE =>
Put_Line(Positive'Image(I)); -- prints 19
end;
Во многих случаях можно использовать предусловия и постусловия вместо проверки внутри подпрограммы. С другой стороны, иногда подпрограмма должна многократно отслеживать событие или условие, а затем должным образом реагировать на событие или условие. В таких случаях часто лучше выполнять этот мониторинг в рамках подпрограммы.
Причина, по которой я смог нарушить свои условия, заключается в том, что мне нужно было разрешить утверждение условий, как заявил тиндил. Я решил это, добавив
pragma Assertion_Policy (Check);
к моему файлу спецификации.