当模型中有两个实例时,如何向签名的字段添加限制

时间:2013-10-11 21:21:21

标签: alloy

我有以下的Alloy模型描述了一群人。简化问题。这是一个示例代码片段。

sig groupofpeople {
member: set person,
country: Country
}{
 #person=2
} 

sig people {
teamleader: Bool,
position: String
}

所以现在我们在一个小组中有两个人。接下来,我想为群组中的人添加一些限制。例如,我希望组中的两个人总是有一个团队领导和一个团队成员。我使用以下事实来做到这一点:

fact {
all n: people , m: people - n {
        n.teamleader not in m.teamleader
    }
}

现在我遇到一个让我无法前进的问题。我想要的模型是,如果一个组的国家是“美国”,那么团队领导者的位置是“US_TL”,团队成员的位置是“US_TM”。如果国家是“英国”,那么团队领导者的位置是“UK_TL”,团队成员的位置是“UK_TM”,依此类推。

我尝试添加类似的内容:

all n: groupofpeople {
        (n.country in US => (
        n.member.position="US_TL" or 
        n.member.position= "US_TM"))  or
        (n.country in UK => (
        n.member.position ="UK_TL" or 
        n.member.position = "UK_TM"))
    }

但预测显然有问题,而且模型无法为我生成正确的解决方案。你能帮我解决一下我模型中的问题吗?

2 个答案:

答案 0 :(得分:2)

你在这里发布的模型没有编译,所以我无法确定问题(因为有很多,所以这可能只是错别字)。似乎不正确的是最后or量词中两个含义之间的all:根据您对任务的描述,它应该是and

如果我理解了模型的理想属性,那么我将如何重写它(如果这不是你想要实现的,请澄清你的问题并发布一个语法正确的模型):

open util/boolean

abstract sig Country {}
one sig US extends Country {}
one sig UK extends Country {}

sig GroupOfPeople {
  member: set Person,
  country: one Country
}{
  #member=2
} 

sig Person {
  teamleader: Bool,
  position: String
}

fact {
  all g: GroupOfPeople {
    all n: g.member, m: g.member - n {
      n.teamleader not in m.teamleader
    }
  }
}

run {
  all n: GroupOfPeople {
    (n.country in US => (
        n.member.position="US_TL" or 
        n.member.position= "US_TM"))
    (n.country in UK => (
        n.member.position ="UK_TL" or 
        n.member.position = "UK_TM"))
    }
} for 5

答案 1 :(得分:1)

通过

替换上面的sig人员的定义会不会更好
abstract sig Person{position : String}
sig Leader, Follower extends Person

fact one_leader {
  all g : GroupOfPeople | one (g.member & Leader)
}

甚至更好地把这个事实放在GroupOfPeople的不变量中:

one (member & Leader)