有一个或另一个对象,但不是两个?

时间:2011-09-17 00:49:23

标签: alloy

这是家庭作业,我遇到了很多麻烦。我正在使用Alloy来建模库。以下是对象的定义:

sig Library {
    patrons : set Person,
    on_shelves : set Book,
}

sig Book {
    authors : set Person,
    loaned_to : set Person,
}

sig Person{}

然后我们需要有一个事实,即状态,每本书都在书架上,或由赞助人取出。但是,他们不能在两个地方。

// Every book must either be loaned to a patron or
// on the shelves.
fact AllBooksLoanedOrOnShelves {}

我试过这个......

fact AllBooksLoanedOrOnShelves {
    some b : Book {
        one b.loaned_to =>
            no (b & Library.on_shelves)
        else
            b in Library.on_shelves
    }
}

但它不起作用......这些书总是在货架上。我想说,“对于每本书,如果它没有被借出,它就在货架上。否则,它就出来了。”

非常感谢更正,示例和提示。

5 个答案:

答案 0 :(得分:4)

如果每本书都必须借给某人或书架,那么(a)任何书籍都不会被借出和上架(假设你的意思是“或”作为排他性的),所以onloan set和onshelf set将是空的,并且(b)这套书将等于onloan和onshelf集合的联合。

随时借出的这套书籍是loaned_to关系的范畴。给定库L中书架上的一组书籍是L.onshelves的值;所有已知图书馆书架上的书籍都是Library.onshelves

所以你可能会说

fact in_or_out_not_both {
  no Library.onshelves & loaned_to.Person 
}
fact all_books_in_or_out {
  Book = Library.onshelves + loaned_to.Person
}

或者你可能需要说一些略有不同的东西,这取决于你的意思。请注意,这些限制并不是说贷款簿必须借给一个借款人。

答案 1 :(得分:1)

您的fact错了。你想为所有书(不是“一些”)说些什么。而那件事基本上就是XOR。

这是一个有效的方法:

fact AllBooksLoanedOrOnShelves{
  all b : Book|
    (b in Library.on_shelves and no p:Person | p in b.loaned_to)
    or
    (not b in Library.on_shelves and one p:Person | p in b.loaned_to)
}

答案 2 :(得分:1)

如果我错了,请纠正我,但我相信这是你所追求的事实:

fact {
  disj[Library.on_shelves, Person.~loaned_to]
}

还有一点解释。 Library.on_shelveson_shelves关系右侧的书籍集,即书架上的所有书籍。 ~loaned_toPerson -> Book类型的反向关系,Person.~loaned_to是借给任何人的书籍集。

disj谓词声明这两个集合没有共同的原子(不相交的集合)。

答案 3 :(得分:0)

我对Alloy不是很熟悉。 但我认为这或类似的东西都可行。

每本书都在书架上或借给顾客。

fact AllBooksLoanedOrOnShelves {
all b: Book | b in Library.on_shelves || b.loaned_to in Library.patrons
}

答案 4 :(得分:0)

这个问题现在已经有6年了,但我正在学习Alloy,我想提出解决方案。

fact AllBooksLoanedOrOnShelves {
    no (Library.on_shelves & loaned_to.Person)
}

这可以理解为“书架上的书籍和借出的书籍的交集是空的”。