高完整性系统工程(四): An Overview of Alloy

目录

1. 概述

2. 指定软件设计

3. 验证设计规范

4. 验证预期属性


1. 概述

在第一章中,我们将解释如何使用 Alloy 来探索一个非常简单的软件组件的设计,即大多数操作系统中存在的众所周知的垃圾箱 或回收站。目的是对如何使用 Alloy 指定和分析软件设计进行简要的(有时是肤浅的)概述。Alloy 规范语言和分析技术的全部细节将在以下章节中给出。

Trash 的目标是:

  1. 1. 使已删除的文件仍然可以恢复,直到执行清空 Trash 的(可撤消的)操作
    1.         a. 当文件被删除时,它存储在 Trash 中;
      1.         b. 仍在 Trash 中时,可以恢复文件;
        1.         c. 清空后,Trash 中包含的所有文件将被永久删除。

更具体地说,在本章中,我们将展示如何在以下任务中使用 Alloy:

  1. 在非常抽象的层次上正式指定垃圾桶组件的结构和行为的设计。

  2. 通过仿真验证此设计,即使用 Alloy Analyzer 检查它是否允许 Trash 的某些预期行为。

  3. 引出并验证 Trash 组件的一些预期属性。

2. 指定软件设计

转换系统(Transition systems是推理系统行为最标准的形式主义之一,是描述和推理软件系统设计的一种非常方便和抽象的形式主义。转换系统包含系统在随时间演化时可能处于的不同状态(states,识别其中哪些是可能的初始状态(initial states,并通过识别将每个状态连接到每个可能的后续状态的转换(transitions来清楚地描述系统如何演化。

指定转换系统的第一步是描述其状态的结构。在 Alloy 中:

系统的结构是根据集合(sets关系(relations来描述的。

集合(sets称为签名(signatures),并使用关键字 sig 声明,后跟强制签名名称和括在大括号之间的可选字段(field声明列表

字段(fields是将封闭签名的元素连接到其他元素的关系(relations

我们不会在本章中使用字段,因此我们在本例中的签名声明在名称后总是有一对空括号。

在 Alloy 中,签名由所谓的原子(atoms组成,没有任何内部结构或任何特定语义的元素,其名称将由 Analyzer 自动生成。默认情况下,在 Alloy 中,所有签名和关系的值都是不可变的。要声明可变(或变量)签名,只需 var 在签名声明之前添加关键字。

在非常抽象的层面上,我们可以使用两个集合来描述 Trash 组件的状态:文件系统中随时存在的文件集合,以及当前在垃圾桶中的文件的子集。因此,在我们的 Alloy 规范中,我们将分别声明两个变量签名:File 和 Trash。为了表明后者是前者的子集,在声明中, Trash 我们将使用关键字 in 后跟包含签名的名称。因此,Trash state 的 Alloy 规格如下。

var sig File {}
var sig Trash in File {}

在这个例子中,签名 File 是一个顶级签名(top-level signature,不包含在任何其他签名中,而是 Trash 一个子集签名(subset signatur

在 Alloy 中,所有顶级签名都是不相交的。可变顶级签名也是如此:

它们总是不相交的,即使在不同的时间点,这意味着原子(atoms不能在状态转换中从一个顶级签名移动到另一个顶级签名。

在描述了我们系统的状态之后,我们现在可以继续指定它的预期行为,即 Trash 转换系统的初始状态和转换是什么。与许多正式规范语言不同,Alloy 没有特殊的语法来声明此转换系统。相反,它遵循 Leslie Lamport 在动作的时间逻辑(Temporal Logic of Actions中引入的想法,即通过一个时态逻辑公式来隐式地指定转换系统,该公式识别哪些是其有效的执行轨迹。

轨迹(trace是无限的状态序列,充分描述了系统的可能行为

指定转换系统的公式通常由两部分组成:

  • a. 一个公式指定什么是有效的初始状态;
  • b. 另一个指定每个状态下可能的转换。

在我们的示例中,在初始状态下我们有一个空垃圾桶。要测试一组是否为空,我们可以使用关键字 no后面跟要检查的集合表达式(为了检查它是否为非空,我们可以使用关键字 some,并检查它是否至多包含一个元素,关键字 lone)。要施加约束以限制系统的有效痕迹,我们可以使用关键字 fact 后跟一个可选的名称和一个用大括号括起来的公式。如果该公式不包含时间运算符,即如果它是一个普通的一阶公式,它约束状态中的集合和关系的值,那么它只需要保持在每条轨迹的初始状态。在我们的示例中,有效的初始状态因此可以由以下事实指定。

fact init {
      
  no Trash
}

要指定有效的转换,首先考虑系统中的事件(events(或操作)会更容易每个事件都会引发许多转换。对于垃圾箱组件,我们有三个事件:

  • a. 删除文件
  • b. 恢复文件
  • c. 清空垃圾箱

要指定一个事件,我们将编写一个公式,该公式适用于轨迹的特定状态,前提是该事件可以在该状态下发生,并且轨迹的下一个状态是该事件的有效结果。这两个条件通常分别称为守卫(guard和事件的影响(effect为了指定影响,我们需要以某种方式评估下一个状态下公式的值,或者参考下一个状态下集合和关系的值。为了评估下一个状态下的公式,我们在它前面加上时间运算符 after。为了评估下一个状态下的表达式,我们将其附加操作符'。出于可读性原因,在单独的谓词(predicates中指定每个事件很方便。

谓词是一个命名的公式,只有在调用时才会成立(例如在事实中)。

要声明谓词,应使用关键字 pred,后跟谓词名称、可选的谓词参数列表和括在花括号中的公式。例如,空垃圾事件可以通过以下三个公式的结合来指定。

pred empty {
      
  some Trash and       // guard
  after no Trash and   // effect on Trash
  File' = File - Trash // effect on File
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值