You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Alloy Analyzer会重复生成相同的解决方案?

为何Alloy Analyzer会重复生成相同的解决方案?

示例

运行以下Alloy模型时,明明只存在一种可行解决方案,但工具却多次重复生成它。有没有办法避免重复输出?

open util/integer

abstract sig Robot {
    capability: set Capability,
}

abstract sig Capability {
    do: set AtomicTask
}

abstract sig AtomicTask {
    x: one Int,
    y: one Int
}

fact{all rt: Capability | #capability.rt=1} //所有出现的Capability必须分配给一个机器人
fact{all r: Robot | #r.capability.do>0} //所有出现的Robot必须分配任务
fact{all rt: Capability | #rt.do>0} //所有出现的Capability必须分配任务
fact{all r:Robot | #r<=1} //每个Robot最多出现一次

// ----------------机器人:

sig r2 extends Robot{}
{disj[capability ,  Capability-r2at2-r2at3-r2at4]}
fact{#r2<=1}

// ----------------能力:

sig r2at2 extends Capability{}
{all d:do | d in at2}
sig r2at3 extends Capability{}
{all d:do | d in at3}
sig r2at4 extends Capability{}
{all d:do | d in at4}

fact{#r2at2<=1
#r2at3<=1
#r2at4<=1
} //机器人能力最多出现一次(如果机器人存在且能力已分配任务)

// ----------------原子任务:

abstract sig at2,at4,at3 extends AtomicTask {}
fact{all a:at2 | #do.a=1}   //所需机器人数量
fact{all a:at4 | #do.a=1}   //所需机器人数量
fact{all a:at3 | #do.a=1}   //所需机器人数量
sig at4_1 extends at4{} {x=10 y=5}
sig at3_2 extends at3{} {x=10 y=5}
sig at2_3 extends at2{} {x=10 y=5}
fact{#at4_1=1
#at3_2=1
#at2_3=1
}

// ----------------谓词:

pred TaskAllocation{
}

// ----------------约束:

 fact {all at: at4| one d: do.at | d in r2.capability}
 fact {all at: at3| one d: do.at | d in r2.capability}
 fact {all at: at2| one d: do.at | d in r2.capability}

// ----------------运行命令:

run TaskAllocation for
7 Int, 3 Capability, exactly 3 AtomicTask, 1 Robot

文本格式的输出结果如下:

---INSTANCE---
---INSTANCE---
integers={-64, -63, -62, -61, -60, -59, -58, -57, -56, -55, -54, -53, -52, -51, -50, -49, -48, -47, -46, -45, -44, -43, -42, -41, -40, -39, -38, -37, -36, -35, -34, -33, -32, -31, -30, -29, -28, -27, -26, -25, -24, -23, -22, -21, -20, -19, -18, -17, -16, -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63}
univ={-1, -10, -11, -12, -13, -14, -15, -16, -17, -18, -19, -2, -20, -21, -22, -23, -24, -25, -26, -27, -28, -29, -3, -30, -31, -32, -33, -34, -35, -36, -37, -38, -39, -4, -40, -41, -42, -43, -44, -45, -46, -47, -48, -49, -5, -50, -51, -52, -53, -54, -55, -56, -57, -58, -59, -6, -60, -61, -62, -63, -64, -7, -8, -9, 0, 1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 2, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 3, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 4, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 5, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 6, 60, 61, 62, 63, 7, 8, 9, at2_3$0, at3_2$0, at4_1$0, r2$0, r2at2$0, r2at3$0, r2at4$0}
Int={-1, -10, -11, -12, -13, -14, -15, -16, -17, -18, -19, -2, -20, -21, -22, -23, -24, -25, -26, -27, -28, -29, -3, -30, -31, -32, -33, -34, -35, -36, -37, -38, -39, -4, -40, -41, -42, -43, -44, -45, -46, -47, -48, -49, -5, -50, -51, -52, -53, -54, -55, -56, -57, -58, -59, -6, -60, -61, -62, -63, -64, -7, -8, -9, 0, 1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 2, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 3, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 4, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 5, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 6, 60, 61, 62, 63, 7, 8, 9}
seq/Int={0, 1, 2, 3}
String={}
none={}
this/Robot={r2$0}
this/Robot<:capability={r2$0->r2at2$0, r2$0->r2at3$0, r2$0->r2at4$0}
this/r2={r2$0}
this/Capability={r2at2$0, r2at3$0, r2at4$0}
this/Capability<:do={r2at2$0->at2_3$0, r2at3$0->at3_2$0, r2at4$0->at4_1$0}
this/r2at2={r2at2$0}
this/r2at3={r2at3$0}
this/r2at4={r2at4$0}
this/AtomicTask={at2_3$0, at3_2$0, at4_1$0}
this/AtomicTask<:x={at2_3$0->10, at3_2$0->10, at4_1$0->10}
this/AtomicTask<:y={at2_3$0->5, at3_2$0->5, at4_1$0->5}
this/at2={at2_3$0}
this/at2_3={at2_3$0}
this/at4={at4_1$0}
this/at4_1={at4_1$0}
this/at3={at3_2$0}
this/at3_2={at3_2$0}

原因分析

Alloy Analyzer默认会生成所有满足约束的实例,包括结构完全相同的同构实例——这些实例只是元素的内部标识符(比如r2$0)不同,但实际逻辑结构完全一致。你的模型已经通过exactly和#sig=1等约束固定了唯一的逻辑解,但工具默认不会自动过滤同构实例,所以会重复输出看起来一样的结果。

解决方法

  • 开启同构实例过滤:在Alloy Analyzer的运行窗口中,找到"Options"选项,勾选"Suppress isomorphic instances"(抑制同构实例)。这样工具会自动识别并跳过结构相同的实例,只输出唯一的逻辑解。
  • 确认模型约束的严谨性:你的模型已经通过#at4_1=1、exactly 3 AtomicTask等约束固定了每个元素的实例数量,确保了逻辑上只有唯一解,所以开启过滤后就能解决重复问题。

内容的提问来源于stack exchange,提问作者Griselle Z

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 19:47:25