下面是一个代表这组整数的Alloy模型:{0, 2, 4, 6}
如您所知,加号(+)
表示设置联合。 0
如何与2
联合? 0
和2
不是集合。我认为union运算符只适用于集合?这不是违反集合联盟的基本概念吗?
第二个问题:是否有更好的方法对此进行建模,一种认知不太明显的方法?
one sig List {
numbers: set Int
} {
numbers = 0 + 2 + 4 + 6
}
答案 0 :(得分:1)
在Alloy中,您使用的所有内容都是一组元组。 none
是空集,许多集是关系集(arity> 1的元组)。因此,当您使用它时,每个整数都是一个具有arity 1和基数1的关系的集合。在合金中,当你使用1时,它实际上是{(1)},一组包含原子1的类型。这个定义实际上就像:
enum Int {-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7}
合金中的Ints只是不是很好的整数:-(有限的原子组通常不是问题,但是它们只有很少的它们才真正有用。更糟糕的是,它们很快溢出而且合金不好处理这个问题。
但我同意它看起来很难看。我有一个更糟糕的问题。
0-A + 1->B + 2->C + 3->C
我已经尝试向Alloy添加文字seq并运行实验版本。也许集合也可以这样实现:
// does not work in Alloy 4
seq [ A, B, C, C ] = 0->A + 1->B + 2->C + 3->C
set [ 1, 2, 3, 3 ] = 1+2+3
今天你可以这样做:
let x[a , b ] = { a + b }
run {
x[1,x[2,x[3,4]]] = 1+2+3+4
} for 4 int
但不确定我更喜欢这个。如果宏有元字段或者将参数作为序列提供(就像大多数解释器一样)那么我们可以这样做
// does not work in Alloy 4
let list[ args ... ] = Int.args // args = seq univ
run {
range[ list[1,2,3,4,4] ] = 1+2+3+4
}
如果你喜欢seq [ A, B, C, C ]
语法或varargs,那么在AlloyTools列表上启动一个线程。如上所述,我让seq [ A, B, C, C ]
在原型中工作。