发现 Alloy 规格的意外实例
Unexpected Instance found for Alloy specification
我尝试使用 Alloy 进行建模,但遇到了一个我无法理解的问题。我有以下规格:
module tour/AddressBook1
sig Name, Addr{}
sig Book {
addr: Name->lone Addr
}
// operation: adds a (name, address) to the Book b, resulting in b'
pred add (b, b' : Book, n:Name, a:Addr) {
b'.addr = b.addr + n->a
}
run add for 3 but 2 Book
到目前为止没有什么特别的。它实际上是 Daniel Jackson 的书 'Software abstraction' 中的示例。
它本质上是对书籍进行建模,这些书籍具有与之关联的(名称,地址)对。 add-predicate 应该获取 Book-instance b 并通过向其添加(可能已经存在的)(name,address)-pair 来从中创建另一个 Book-instance b'。
找到的前几个示例简单且令人信服,但单击“下一步”按钮我最终得到以下示例(上面的完整视图,下方书籍的等效投影)
我看到两本书,起始书 Book0 有两对 (Name0, Addr2) 和 (Name1, Addr1)。从注释中我们还可以看到添加操作将添加新的 duo (Name1, Addr2)。当我现在查看结果书 Book1 时
{(Name0, Addr0),(Name1, Addr2)} 而不是
{(Name0, Addr2),(Name1, Addr1),(Name1, Addr2)}
为什么这被认为是合法实例?
(Alloy Analyzer 4.2,构建日期 2012-09-25 15:54 美国东部时间)
这里有两个令人困惑的地方:
Book0
不参与运算。相反 Book1
具有 b0
和 b1
的作用。
将 n->a
添加到一本书中并不能断言这是一个新地址。在这个例子中,Book1
在 add
之前和之后都有这个地址。
这是因为操作
b'.addr = b.addr + n->a
使用设置联合。分解为一个更简单的例子:
{1, 2} = {1} + {2}
是真的。但是
{1, 2} = {1, 2} + {2}
也是如此。所以在最初的例子中,没有什么可以排除 n->a
已经成为 b.addr
的一部分。而 Alloy 分析器只是生成所有符合给定约束条件的实例。
您可以通过在 add
中添加断言来改进此示例:
b.addr[n] != a
我尝试使用 Alloy 进行建模,但遇到了一个我无法理解的问题。我有以下规格:
module tour/AddressBook1
sig Name, Addr{}
sig Book {
addr: Name->lone Addr
}
// operation: adds a (name, address) to the Book b, resulting in b'
pred add (b, b' : Book, n:Name, a:Addr) {
b'.addr = b.addr + n->a
}
run add for 3 but 2 Book
到目前为止没有什么特别的。它实际上是 Daniel Jackson 的书 'Software abstraction' 中的示例。
它本质上是对书籍进行建模,这些书籍具有与之关联的(名称,地址)对。 add-predicate 应该获取 Book-instance b 并通过向其添加(可能已经存在的)(name,address)-pair 来从中创建另一个 Book-instance b'。
找到的前几个示例简单且令人信服,但单击“下一步”按钮我最终得到以下示例(上面的完整视图,下方书籍的等效投影)
我看到两本书,起始书 Book0 有两对 (Name0, Addr2) 和 (Name1, Addr1)。从注释中我们还可以看到添加操作将添加新的 duo (Name1, Addr2)。当我现在查看结果书 Book1 时 {(Name0, Addr0),(Name1, Addr2)} 而不是 {(Name0, Addr2),(Name1, Addr1),(Name1, Addr2)}
为什么这被认为是合法实例?
(Alloy Analyzer 4.2,构建日期 2012-09-25 15:54 美国东部时间)
这里有两个令人困惑的地方:
Book0
不参与运算。相反Book1
具有b0
和b1
的作用。将
n->a
添加到一本书中并不能断言这是一个新地址。在这个例子中,Book1
在add
之前和之后都有这个地址。 这是因为操作b'.addr = b.addr + n->a
使用设置联合。分解为一个更简单的例子:
{1, 2} = {1} + {2}
是真的。但是
{1, 2} = {1, 2} + {2}
也是如此。所以在最初的例子中,没有什么可以排除
n->a
已经成为b.addr
的一部分。而 Alloy 分析器只是生成所有符合给定约束条件的实例。
您可以通过在 add
中添加断言来改进此示例:
b.addr[n] != a