Electronicdesign 6017 59321优惠

契约驱动的编程使规范超越了石器时代

2013年2月4日
合同编程的工业化时代开启了软件开发的新时代。正如开发技术从汇编到结构化语言,从结构化语言到面向对象,基于契约的编程为软件设计提供了又一种抽象。

这篇文章是嵌入式软件系列:使用Ada契约强制编码

拿你日常工作中使用的任何界面来说。它可能是来自标准组件的应用程序编程接口(API)、公司内部共享的一些库,或者是隔壁隔间的某个人正在为你开发的一段代码。你怎么知道该叫它什么?

现代语言通过类型、函数声明或参数说明提供了标识服务的各种方法,以及引用这些服务的各种方法。某些语言可能会给你更多。Java指定可能抛出的异常,Ada允许你指定类型范围,C允许…嗯,算了。

但是,这种级别的规范几乎没有揭示应用程序的行为,因此需要一些其他的、非正式的、不需要任何工具检查的东西:臭名昭著的文档,几乎只以注释的形式存在。“为什么这是个问题呢?”你可能会说。“让人们发表评论已经够难的了!”

在许多情况下,文档是一项成就。但当可靠性受到威胁时,它只是一个石器时代的规范。如何验证规格书是正确的?如何验证调用者以他们应该的方式进行调用以及他们依赖于他们应该依赖的属性?如何确保在项目的整个生命周期中,在各种修复、重构和重写之后,规范保持一致?

一些替代的技术超越了简单的注释来指定行为,并使用工具检查的形式主义。这里,我们将特别考虑三种语言:C、Java和Ada。我们还将展示,一旦编写了规范,它不仅可以用于文档,还可以直接用于测试和静态分析工具。

表的内容

前置条件、后置条件和类型不变式

让我们首先介绍契约的概念。在编程语言中,契约通常是一个布尔表达式,在程序中的某些点进行验证。最有趣的契约可能是后置条件。它定义了函数调用后必须为真的属性。通常,它可以是指定该函数的行为或需求的一种方法。它是对实现者的约束(实现者必须在实现中满足后置条件)和对调用者的保证(调用者可以在调用后依赖后置条件)。

为了实现后置条件,我们通常需要两件事:函数的正确实现和在调用之前需要满足的一组属性。这些属性称为先决条件。先决条件是对调用者的约束(调用者必须在调用之前完成它,以确保正确的行为)和对实现者的保证(实现者可以依赖于其实现中的先决条件)。后置条件是给予调用者的保证(调用后环境的状态)和对实现者的约束(函数必须执行的内容)。

类型不变式是一个属性,对于给定类型的每个对象,它必须始终为真。它可以描述值范围、字段之间的关系和类似的属性。

在这里,我们将考虑一个简单的系统,其中物理对象在二维环境中移动。每个对象都与X和Y坐标、大小和标识符相关联。函数iterate在每个循环中被调用,它负责一步一步地更新对象的位置。对象将存储在列表中。

除了结构规范,我们还会添加一些行为需求:

  1. X和Y必须在区间[-200.0,200]内。
  2. Size必须在间隔[0 ..]内。100]。
  3. 除设置为特殊的未初始化值外,所有对象id必须唯一。
  4. 迭代只能在已经初始化的对象上调用。
  5. 迭代不能改变对象的大小或ID。
  6. 通过迭代所做的每次移动都必须小于对象大小的十分之一。

其中一些需求可以清楚地映射到类型不变量,即1、2和3,它们是类型和数据的专有属性,在程序的整个生命周期中都必须为真。其他的可以映射为先决条件,特别是4。最后,需求5和6描述了函数的行为,因此映射到后置条件。现在,可以使用基于Java、C和Ada的三种不同语言来实现上述规范。

Java和JML

Java建模语言(Java Modeling Language, JML)是Java的扩展,使用常规Java编译器,Java代码应该是可兼容的。因此,所有JML注释都是用特殊的java注释编写的,以//@或/*@开头。让我们先翻译并注释下面的代码。

public class Object {public static String NO_INIT = 0;public int id = NO_INIT;Public float x, y, size = 0;// @公共不变式x >= -200 && x <= 200;// @公共不变式>= -220 && y <= 200;// @公共不变式sie >= 0 && size <= 100;// @需要id /= NO_INIT;// @可分配的x // @可分配的y // @确保数学。√数学。pw (\old (x) - x, 2) // @ + Math。\旧的(y) - y, 2)) <= size / 10; public void iterate () ( { … } ) public static Object [] list = new Object [100]; // @ public invariant // @ (\forall int j; j >= 0 && j < list.size; // @ list [j].id.equals (NO_INIT) || // @ (\forall int k; k >= j + 1 && k < list.size; // @ !list [j].id.equals (list [k].id)));

ACSL和JML示例之间的第一个显著区别是,虽然JML允许引入可执行的契约,这些契约可以引用代码中的实际实体,但ACSL目前是纯形式化的。因此,ACSL不能调用“实”函数,只能调用正式函数,只能根据相应的正式属性进行推理。这就是Math公理的特殊目的,它引入了pow和sqrt形式函数。

Range_Object公理定义了一个对象的x, y和大小字段的值范围。然后在类型不变式中使用这个公理来验证对象类型的所有实例都遵守这个公理。还要注意\valid (v)结构,它指定指针必须是有效的(可以被解引用)。

除了这两个区别之外,这与JML示例非常接近。有关ACSL的更多信息,请访问http://frama-c.com/acsl.html

艾达和艾达2012

Ada 2012语言的主要新特性之一是它能够在语言定义中包含重要的契约信息,而不需要外部工具以及相应的动态语义。下面的代码展示了如何在Ada 2012中编写前面示例中的相同规范。

包对象是No_Init:常量:= 0;type对象是记录Id: Integer:= No_Init;X, Y:浮动范围-200.0…200.0: = 0.0;尺寸:浮动范围0.0 ..100.0: = 0.0;结束记录;过程迭代(V: in out Object), Pre => V. id /= No_Init, Post => V. size = V. size 'Old,然后V. id = V. id 'Old,然后Sqrt ((V. x = V. x 'Old) ** 2 + (V. y -V.Y'Old) **) <= V. size / 10.0;类型Arr是数组(整数范围<>)的对象Dynamic_Predicate =>(为所有J在Arr'Range => Arr (J).Id = No_Init或其他(为所有K在J + 1 ..Arr' => Arr (J).Id /= Arr (K.Id)); List : Arr (1 .. 100); end Object ;

这只是一个例子,说明了在试图引入强大的形式证明技术时所产生的各种约束。这类问题可以通过使用比低级指针(比如SPARK中的引用)约束更大的结构来检测。这里还有更多要说的,但它可能是即将发表的一篇论文的主题。

结论

合同编程的工业化时代开启了软件开发的新时代。正如开发技术从汇编到结构化语言,从结构化语言到面向对象,基于契约的编程为软件设计提供了又一种抽象。

在很长一段时间里,这些技术只适用于具有一些扩展数学知识的开发人员。由于Ada 2012等新的形式主义,它们现在基于任何软件开发人员都可以理解的语义,使它们的使用民主化。现在正是尝试它们的好时机!

更多信息请参阅嵌入式软件系列:使用Ada契约强制编码



昆汀Ochem 具有软件工程背景,专门从事关键应用软件开发。他有超过10年的Ada开发经验。如今,他是AdaCore的技术客户经理,负责与航空电子、铁路、太空和国防工业相关的项目。他还在巴黎EPITA大学教授航电标准DO-178B课程。可以联系到他ochem@adacore.com。


从我们的合作伙伴

线性稳压器的包装限制范围

0.05。0.10。0.15。0.20。0.25。0.30。0 1 2 3 4 5 6。监管机构。退学。操作。 Output current. rating of device. Set by maximum input voltage. and minimum…

协同处理器体系结构:一种用于快速成型的嵌入式系统体系结构

2021年7月6日
编者注:尽管它以数字处理性能和吞吐量而闻名,但协处理器体系结构提供了嵌入式系统…

实时操作系统(RTOS)及其应用

2021年2月25日,
什么是操作系统。实时操作系统(RTOS)是一个轻量级的操作系统,用于在资源和时间限制下简化多任务和任务集成……

内置电源开关保护您的电源路径

电源开关提供从电压源或地到负载的电气连接。我们多样化的投资组合包括几种拓扑,从si…

超高可靠性,低延迟

当你读这篇文章时,5G正在美国推广。有些人有一个兼容5G的手机,可以连接到AT&T网络,T-Mobile,等等。

用集成负载开关优化低压应用中的配电

雷切尔·理查森。随着智能手机、5G、物联网、汽车信息等领域的创新,高速、低功耗的存储库和处理器正变得越来越普遍……

声音你的意见!

本网站要求您注册或登录后发表评论。
目前还没有任何评论。想开始对话吗?

从我们的合作伙伴

线性稳压器的包装限制范围

0.05。0.10。0.15。0.20。0.25。0.30。0 1 2 3 4 5 6。监管机构。退学。操作。 Output current. rating of device. Set by maximum input voltage. and minimum…

协同处理器体系结构:一种用于快速成型的嵌入式系统体系结构

编者注:尽管它以数字处理性能和吞吐量而闻名,但协处理器体系结构提供了嵌入式系统…

实时操作系统(RTOS)及其应用

什么是操作系统。实时操作系统(RTOS)是一个轻量级的操作系统,用于在资源和时间限制下简化多任务和任务集成……

内置电源开关保护您的电源路径

电源开关提供从电压源或地到负载的电气连接。我们多样化的投资组合包括几种拓扑,从si…

超高可靠性,低延迟

当你读这篇文章时,5G正在美国推广。有些人有一个兼容5G的手机,可以连接到AT&T网络,T-Mobile,等等。
Baidu