Alloy 中定义的约束如何产生更好的软件?

How do constraints defined in Alloy result in better software?

Alloy这里是新手

我真的很喜欢在 Alloy 中创建约束并让分析器根据约束检查模型是否有效。

但我问自己,“这些约束定义仅仅是心理体操,还是有助于构建更好的软件?”

举个具体的例子。在电子邮件客户端地址簿的模型中,可以定义此约束以将新条目添加到地址簿中:

The address mapping in the new book b’ is equal to the address mapping in the old book b, with the addition of a link from the name to the address. This constraint is expressed in Alloy as: b'.addr = b.addr + n->a

真漂亮

但是当 add 操作在代码中实现时,我很难看到它的相关性。例如,我在 Common Lisp 中实现了 add 操作:

(defun add (b n a)
   "Add a new entry, (n a), to address book b"
   (adjoin (list n a) b :key #'first))

换句话说:“这是一个名为 add 的函数的定义,它具有三个参数:b na(书籍、姓名、地址)。使用 Common Lisp 集合函数 adjoin,将列表 (n a) 添加到 b。”

该函数似乎正确地实现了一个简单的 add 函数。 我如何处理我在 Alloy 中定义的约束?我应该编写额外的代码来表达约束吗?在伪代码中:[1]

(defun add (b n a)
   "Add a new entry, (n a), to address book b"
   (adjoin (list n a) b :key #'first)
   Check that nothing has changed in the
   address book except that it now has
   a n->a mapping)

编写这样的代码似乎需要大量工作,而且没有明显的好处。

所以我的问题是:在代码中实现 Alloy 模型时,我应该如何处理 Alloy 中定义的约束?

此外,是否有介绍如何将 Alloy 模型转换为代码的教程,包括如何在代码中使用 Alloy 约束定义的说明?

谢谢。

[1]注:我发现在Common Lisp中有一个叫做Screamer的语言扩展用于约束编程

我认为这个问题源于对某些建模语言(如 Alloy)的目标和功能的轻微误解,并涉及形式化方法、验证和软件建模的一些基本方面。获得背景故事的好资源可能会让事情变得更清楚,包括像你提到的 Calculus of Computation, as well as the book about Alloy 这样的书。

约束是 first-class 建模语言的公民。这个想法是约束反映了一个人想要建模的代码的语义(并检查其属性)。因此,从一个角度来看,Alloy 程序代表代码本身,不需要编写额外的代码(例如,在函数式语言中)或将声明的约束与代码混合。但是,Alloy程序不能直接执行;相反,它们只能用于根据此类程序(即约束集)生成模型。

更具体地说,Alloy 约束 b'.addr = b.addr + n->a,在适当的解释下,可能确实捕获了 Lisp 中添加操作的行为,因此检查涉及约束的一些属性对应于检查这些属性是否适用于 Lisp 中的给定操作。这是 Alloy 用于软件建模和验证的标准(并且可以说是预期的)用途。 (此外,Alloy 经常用于对没有明确映射到程序的系统进行建模,例如某些类型的 cyber-physical 系统 [1]。)请注意,这当然需要模型一Alloy 中的写入必须正确地建模手头的程序(关于它的语义),以便检查属性是有意义的。

如前所述,Alloy 本身无法生成可执行代码(例如您给出的代码,是用 Common Lisp 编写的)。但是,有多种方法使用 Alloy 和 Alloy 生成的模型来生成代码片段或测试用例。 (同样,根据手头的具体程序。)此外,Alloy 的扩展名为 Alloy* [2],它增加了在 Alloy 内求解高阶约束的可能性(关系量化)可用于生成程序;执行操作并接受不同输入的实际代码(根据模型,类似于 add 函数)。同样,此类程序用 Alloy 模型表示,需要(付出额外的努力)将这些模型转换为某种所需编程语言的程序。

话虽如此,请注意某些(验证)系统确实允许您将规范与代码混合使用,其中规范可能是:以与要执行的代码相同的方式编写(如 verification/synthesis 框架 Leon [3]);或用不同的语言(与可执行代码的语言不同)编写,而规范通过其他方式(如 Dafny [4] 中的注释)绑定到代码。

[1] Kang、Eunsuk 等。 "Model-based security analysis of a water treatment system." 第二届智能系统软件工程国际研讨会论文集 Cyber-Physical。美国计算机学会,2016.

[2] 米利切维奇、亚历山大等人。 "Alloy*: A general-purpose higher-order relational constraint solver." 第 37 届国际软件会议论文集 Engineering-Volume 1. IEEE Press, 2015.

[3] Blanc, Régis, et al. "An overview of the Leon verification system: Verification by translation to recursive functions." Proceedings of the 4th Workshop on Scala. ACM, 2013.

[4] Leino, K. Rustan M. "Dafny: An automatic program verifier for functional correctness." 人工智能编程和推理逻辑国际会议。斯普林格柏林海德堡,2010 年。