あなたのモデルには多くの不正確な点があります。
これを実装するには、署名内のフィールドのlone
多重度修飾子で十分です。すべての人にタスクを 1 つだけ割り当てたい場合は、 に変更できます。assigned
Person
lone
one
同じタスクが割り当てられている2人の人物はいないと言うために代わりに書く必要がValid
あるため、述語の制約は間違っています。さらに、それを保証する制約を追加する必要があります。あるいは、 と書くこともできます。最後に、量指定子本体に書き込む必要をなくすために、キーワードを使用して、たとえば、、または.p1.assigned not in p2.assigned
p1.assigned = p2.assigned
p1 != p2
all p1, p2: Person | p1 != p2 implies p1.assigned != p2.assigned
p1 != p2
disj
no disj p1, p2: Person | p1.assigned = p2.assigned
all disj p1, p2: Person | p1.assigned != p2.assigned
Task
署名の追加された事実セクションの制約は、assigned
フィールドについてまったく言及していないため、間違っています。これは、各人と割り当てられたタスクについて、その人がすべてのスキルを持っていると言うために行う必要があることです。タスクに必要です。あなたが書いたことは、すべてのタスクについて、すべての人がそのタスクに必要なすべてのスキルを持っていることを意味します。これを満たす唯一の方法は、すべてのタスクが同じスキル セットを持っている場合です。これは、モデルで得たすべてのインスタンスでまさに気づいたことです。
これをモデル化する方法は次のとおりです (フィールド名と署名名がわずかに変更されていることに注意してください。これにより、モデルが少し読みやすく理解しやすくなっています)。
some sig Skill {}
some sig Person {
hasSkill: some Skill,
assignedTask: lone Task
}
some sig Task {
requiredSkills: some Skill
}
// everyone must have the required skills for the assigned task
fact requiredTaskSkills {
all p:Person | p.hasSkill in p.assignedTask.requiredSkills
}
// everyone has at least one assigned task
pred atLeastOneTask {
all p: Person | one p.assignedTask
}
// no two persons can have the same task assigned
pred uniqueTaskAssignments {
no disj p1, p2: Person | p1.assignedTask = p2.assignedTask
}
run {
atLeastOneTask and uniqueTaskAssignments
}