我有一个Alloy规范代表模型转换规则。在规范中,我使用高阶量化来指定规则匹配。一个奇怪的事情是分析仪的工作方式不同于"一些"和"一个",我无法理解。
例如,在pred rule_enter [trans:Trans]中(参见第240行),我使用两个高阶量化来编码图形转换规则的左侧和右侧的匹配。 的 *********************例************************* *************
some e_check0:Acheck&trans.darrows, e_TP0:ATP&(trans.source.arrows-trans.darrows), e_PF10:APF1&trans.darrows, e_TR0:ATR&(trans.source.arrows-trans.darrows), e_F1R0:AF1R&trans.darrows |
let n_P0 = e_check0.src, n_T0 = e_TP0.src, n_R0 = e_TR0.trg, n_F10 = e_PF10.trg |
(n_P0 = e_check0.trg and n_P0 = e_TP0.trg and n_P0 = e_PF10.src and n_T0 = e_TR0.src and n_F10 = e_F1R0.src and n_R0 = e_F1R0.trg and
n_F10 in NF1&trans.dnodes and
n_P0 in NP&(trans.source.nodes-trans.dnodes) and n_T0 in NT&(trans.source.nodes-trans.dnodes) and n_R0 in NR&(trans.source.nodes-trans.dnodes))
some e_crit0:Acrit&trans.aarrows, e_TP0:ATP&(trans.source.arrows-trans.darrows), e_PF20:APF2&trans.aarrows, e_TR0:ATR&(trans.source.arrows-trans.darrows), e_F2R0:AF2R&trans.aarrows |
let n_P0 = e_crit0.src, n_T0 = e_TP0.src, n_R0 = e_TR0.trg, n_F20 = e_PF20.trg |
(n_P0 = e_crit0.trg and n_P0 = e_TP0.trg and n_P0 = e_PF20.src and n_T0 = e_TR0.src and n_F20 = e_F2R0.src and n_R0 = e_F2R0.trg and
n_F20 in NF2&trans.anodes and
n_P0 in NP&(trans.source.nodes-trans.dnodes) and n_T0 in NT&(trans.source.nodes-trans.dnodes) and n_R0 in NR&(trans.source.nodes-trans.dnodes))
这里我使用关键字" some"。分析仪可以使用范围10。
但如果我使用关键字" one",分析器会报告范围5的以下错误: 的 *********************例************************* *************
Executing "Check check$1 for 5 but exactly 1 Trans, exactly 2 Graph, exactly 1 Rule"
Solver=minisat(jni) Bitwidth=0 MaxSeq=0 SkolemDepth=1 Symmetry=20
Generating CNF...
.
Translation capacity exceeded.
In this scope, universe contains 89 atoms
and relations of arity 5 cannot be represented.
Visit http://alloy.mit.edu/ for advice on refactoring.
我的问题是两种量化有不同表现的原因吗?
答案 0 :(得分:2)
one
使用集合理解和基数运算符进行编码,例如
one s: S | p[s]
转换为
#{s: S | p[s]} = 1
设置理解不能被限制,所以当有问题的量词是高阶时,Alloy就会放弃。
答案 1 :(得分:1)
合金中通常不允许高阶量化。但是,一些存在量化(即某些)可以通过称为 skolemization 的过程转换为可解决的过程,我认为这不适用唯一性量化(即一个)。对于(一阶)合金示例,该过程简要解释here。
我无法处理你的例子(对不起),但我猜这就是这种情况。
答案 2 :(得分:0)
我对你的例子没有具体的答案,但通常编码one
比some
更复杂:让我们假设你有一个最大限度地包含元素a,b的集合S,角
Alloy将问题转化为SAT问题。
您可以使用3个布尔变量xa
,xb
,xc
在SAT问题中编码S,其中xa=TRUE
(分别为FALSE
)表示a在S中(不在S中)。
语句some S
现在可以轻松编码为公式
xa \/ xb \/ xc
(\/
为逻辑或)。
另一方面,对于one
,您需要另外编码,如果其中一个变量xa
,xb
,xc
为真,则其他变量为假。 E.g。
xa \/ xb \/ xc
xa => not( xb \/ xc )
xb => not( xa \/ xc )
xc => not( xa \/ xb )
以联合正常形式(CNF,这就是SAT求解器作为输入所用的)你有条款:
xa \/ xb \/ xc
-xa \/ -xb
-xa \/ -xc
-xb \/ -xa
-xb \/ -xc
-xc \/ -xa
-xc \/ -xb
也许有一些技术可以优化,但您可以看到one
需要编码的条款多于some
。