3

我一直在尝试学习使用 SPARK 的基础知识,并且我已经使用前置和后置条件进行了研究,但我不确定它们是否可以代替验证?例如,除非所有门都关闭并锁定,否则飞机不会切换到起飞模式的功能。我是否需要在程序主体中添加代码来停止这种行为,或者前置条件和后置条件是否足够?我不清楚,因为我的课程教程实际上都没有这样做,但是当我测试程序时,我不受违反条件的限制。

4

3 回答 3

4

第一个:如果您使用 GNAT 编译器,则必须将标志添加-gnata到编译器标志或使用 GNAT 的配置文件pragma Assertion_Policy(Check);来启用对前置条件和后置条件的检查。如果没有这些选项之一,所有检查都将被忽略。这就是为什么您可以违反它们。

先决条件发生所选子程序执行之前。例如,函数声明为:

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;
于 2021-04-24T15:12:52.430 回答
3

在许多情况下,可以在子程序验证的 leu 中使用前置条件和后置条件。另一方面,有时子程序必须反复监视一个事件或条件,然后正确响应该事件或条件。在这些情况下,通常最好在子程序中执行该监视。

于 2021-04-24T14:46:41.750 回答
2

我能够违反我的条件的原因是因为我需要启用条件断言,如thindil所述。我通过添加解决了它

pragma Assertion_Policy (Check);

到我的规范文件。

于 2021-04-24T16:34:56.583 回答