Have an object in one set or another, but not both? - alloy

This is homework and I'm having a lot of trouble with it. I am using Alloy to model a library. Here are the definitions of the objects:
sig Library {
patrons : set Person,
on_shelves : set Book,
}
sig Book {
authors : set Person,
loaned_to : set Person,
}
sig Person{}
Then we need to have to have a fact that states, every book is either on the shelf, or taken out by a patron. However, they cannot be in both places.
// Every book must either be loaned to a patron or
// on the shelves.
fact AllBooksLoanedOrOnShelves {}
I have tried this...
fact AllBooksLoanedOrOnShelves {
some b : Book {
one b.loaned_to =>
no (b & Library.on_shelves)
else
b in Library.on_shelves
}
}
But it's not working... the books always are on the shelves. want to say, "For every book, if it is not being loaned, it is on the shelf. Otherwise, it's out."
Corrections, examples, and hints are greatly appreciated.

If every book must be either on loan to someone or on the shelves, then (a) no book will be both on loan and on the shelves (assuming you mean that "or" as exclusive), so the intersection of the onloan set and the onshelf set will be empty, and (b) the set of books will be equal to the union of the onloan and onshelf sets.
The set of books on loan at any time is the domain of the loaned_to relation. The set of books on the shelf in a given library L is the value of L.onshelves; the set of books on the shelves in all known libraries is Library.onshelves.
So you might say
fact in_or_out_not_both {
no Library.onshelves & loaned_to.Person
}
fact all_books_in_or_out {
Book = Library.onshelves + loaned_to.Person
}
Or you might need to say slightly different things, depending on just what you mean. Note that these constraints don't say that a book on loan must be on loan to a single borrower.

Your fact is wrong. You want to say something for all books (not "some"). And that something is basically an XOR.
Here's one that works:
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)
}

Ok correct me if I'm wrong, but I believe this is the fact you're after:
fact {
disj[Library.on_shelves, Person.~loaned_to]
}
And a little explanation. Library.on_shelves is the set of books on the right side of the on_shelves relation, i.e. all the books that are on the shelves. ~loaned_to is the reverse relation of type Person -> Book and Person.~loaned_to is the set of books loaned to any person.
The disj predicate declares that the two sets have no common atoms (disjoint sets).

I am not very familiar with Alloy.
But I think this or something similar would work.
Every book is either on the shelves or is loaned to a a patron.
fact AllBooksLoanedOrOnShelves {
all b: Book | b in Library.on_shelves || b.loaned_to in Library.patrons
}

This question is 6 years old now, but I'm learning Alloy, and I wanted to offer my take on a solution.
fact AllBooksLoanedOrOnShelves {
no (Library.on_shelves & loaned_to.Person)
}
This can be read as "the intersection of the set of books that are on shelves and the set of books that are loaned out, is empty".

Related

sig literals in Alloy

How can I write out a literal for a sig in Alloy? Consider the example below.
sig Foo { a: Int }
fact { #Foo = 1 }
If I execute this, I get
| this/Foo | a |
|----------|---|
| Foo⁰ | 7 |
In the evaluator, I know I can get a reference to the Foo instance with Foo$0 but how can I write a literal that represents the same value?
I've tried {a: 7}, but this is not equal to Foo$0. This is intentionally a trivial example, but I'm debugging a more complex model and I need to be able to write out literals of sigs with multiple fields.
Ah, this is one of the well hidden secrets! :-) Clearly in your model you cannot refer to atoms since the model is defining all possible values of those atoms. However, quite often you need your hands on some atom to reason about it. That is, you want to be able to name some objects.
The best way to get 'constants' is to create a predicate you call from a run clause. In this predicate, you define names for atoms you want to discuss. You only have to make sure this predicate is true.
pred collision[ car1, car2 : Car, road : Road ] {
// here you can reason about car1 and car2
}
run collision for 10
Another way is to create a quantification whenever you need to have some named objects:
run {
some car1, car2 : Car, road : Road {
// here you can reason about car1 and car2 and road
}
} for 10
There was a recent discussion to add these kinds of instances to the language so that Kodkod could take advantage of them. (It would allow faster solving and it is extremely useful for test cases of your model.) However, during a discussion this solution I presented came forward and it does not require any new syntax.
try to put a limitation for 'Integer' in the 'run' command. I mean :
sig Foo {a : Int}
fact{ #Foo = 1}
pred show {}
run show for 1 Foo, 2 Int

Constructing a relation in Alloy

In the dining philosophers problem we have a table with Philosophers and Forks.
sig P {}
sig F {}
For this problem I want the following relation that represents the table:
P1 -> F1
F1 -> P2
P2 -> F2
F2 -> P3
P3 -> F3
F3 -> P1
I.e. each P would point to an F and each F to a P, and this would form a circle. I would like to call a function to get this relation:
fun table : (P+F) one -> one (P+F) { ... }
I've been trying hard to make this work but it feels like I am missing something fundamental that also is relevant for other problems I am having. Somehow I miss a 'constructor'.
Any pointers?
Additional
#Hovercouch gave an working solution with a helper sig. However, this required a non-natural extension to the P and F and introduced a new sig. This can also be solved by:
sig P, F {}
one sig Table {
setting : (P+F) one -> one (P+F)
} {
# P = # F
all p : P, f : F | P in p.^setting and F in f.^setting
}
run {} for 6
Which addresses the non-natural inheritance concerns.
However, it still seems very global and a lot of work for an imho very simple problem. Still keeping the question open to see if there are other solutions.
If you're willing to add a helper object, we can do this by making an abstract sig Thing and then making both P and F instances of Thing:
abstract sig Thing {
next: Thing
} {
Thing = this.^#next
}
sig F extends Thing {} {
next in P
}
sig P extends Thing {} {
next in F
}
fact SameNumberOfThings {
#P = #F
}
run {} for 6
There may be a design tradeoff involved here, between expressive power and tractability.
There is certainly an issue of what counts as clean or intuitive; you say that the 'next'-ness of P and F is "an aspect of the table setting" and not "an aspect of P or F". I think I understand your thinking, but I don't think you are likely to have any more success defining a principled way to distinguish between "aspects" of P and F and relations in whose domain or range they appear, any more than any of the philosophers who have tried, over the last couple thousand years, to distinguish reliably between essence and accidence.
And if we accept that the distinction is unreliable, but we nevertheless find it useful, then the question becomes "who made the rule that a relation defined as part of a signature must relate to an (intrinsic) aspect of the individuals involved, and not to an extrinsic relation which is not an aspect of the individuals?" The answer is: you did, not [the creators of] Alloy. If one insists too strongly on one's intuitions about the constructs one wants to use to express something, there is a certain risk of insisting not just that the thing should be expressible but that we should be able to express it using a particular construct. That kind of insistence can teach us a lot about a notation, but sometimes it's easier to accept that the designers of the notation also had intuitions.
This general topic is discussed in Daniel Jackson's Software Abstractions under the questions Does Alloy allow freestanding declarations? (in discussion following section 3.5.3 on higher-order quantification) and Must all relations be declared as fields? (in discussion following section 4.2.2 on basic field declarations). The nut of the discussion is "If you want to declare some relations that don't belong naturally to any existing signatures, you can simply declare them as fields of a singleton signature." Mutatis mutandis, the example given looks a lot the Table sig in your addendum.
TL;DR yes, you may find it a bit cumbersome, but the singleton sig to contain a relation you don't want to define on its first member really is as close to an established idiom as there is, for this sort of thing.

Alloy - Dealing with unbounded universal quantifiers

Good afternoon,
I've been experiencing an issue with Alloy when dealing with unbounded universal quantifiers. As explained in Daniel Jackson's book 'Software Abstractions' (Section 5.3 'Unbounded Universal Quantifiers'), Alloy has a subtle limitation regarding universal quantifiers and assertion checking. Alloy produces spurious counterexamples in some cases, such as the next one to check that sets are closed under union (shown in the aforementioned book):
sig Set {
elements: set Element
}
sig Element {}
assert Closed {
all s0, s1: Set | some s2: Set |
s2.elements = s0.elements + s1.elements
}
check Closed for 3
Producing a counterexample such as:
Set = {(S0),(S1)}
Element = {(E0),(E1)}
s0 = {(S0)}
s1 = {(S1)}
elements = {(S0,E0), (S1,E1)}
where the analyser didn't populate Set with enough values (a missing Set atom, S2, containing the union of S0 and S1).
Two solutions to this general problem are suggested then in the book:
1) Declaring a generator axiom to force Alloy to generate all possible instances.
For example:
fact SetGenerator{
some s: Set | no s.elements
all s: Set, e: Element |
some s': Set | s'.elements = s.elements + e
}
This solution, however, produces a scope explosion and may also lead to inconsistencies.
2) Omitting the generator axiom and using the bounded-universal form for constraints. That is, quantified variable's bounding expression doesn't mention the names of generated signatures. However, not every assertion can be expressed in such a form.
My question is: is there any specific rule to choose any of these solutions? It isn't clear to me from the book.
Thanks.
No, there's no specific rule (or at least none that I've come up with). In practice, this doesn't arise very often, so I would deal with each case as it comes up. Do you have a particular example in mind?
Also, bear in mind that sometimes you can formulate your problem with a higher order quantifier (ie a quantifier over a set or relation) and in that case you can use Alloy*, an extension of Alloy that supports higher order analysis.

Alloy: using "in" and getting error "in can be used only between 2 expressions of the same arity."

Here are the signatures
one sig Library {
books: set Book,
patrons: set Patron,
circulation: Patron lone -> some Book
}
sig Book { }
sig Patron {
curbooks: set Book
}
Question ->What I want to do is : write a fact that the books currently with a patron are accounted in the library's circulation relation
fact curPatronBooksConsistent {
lone l : Library | all b : l.patrons.curbooks | b in l.circulation
}
Now I understand the nature of the error: in can be used only between 2 expressions of the same arity.
Left type = this/Book
Right type = this/Patron->this/Book
However I do not know how to nor can I find any examples of returning only a "set" of books that are associated with the library.circulation. I realize this is not a set but a relationship so how do I express that in Alloy?
all the books belonging to the patrons e.g. all p.curbooks are mapped in the l.circulation?
Thank you all in advance.
Welcome to Stack Overflow. You say
However I do not know how to nor can I find any examples of returning only a "set" of books that are associated with the library.circulation.
Look again at discussions of the dot (join) operator; you should find plenty of examples. The relation circulation is a ternary relation Library -> Patron -> Book. Your expression l.circulation performs a join and reduces the arity, producing a relation Patron -> Book.
How do you get a relation of the form Patron -> Book down to a set of books?
One obvious way is to join it to a set of Patrons with an expression like Patron.(l.circulation). That's probably not what you want -- you probably want to say that every book shown as in some patron's curbooks is checked out not just to some patron but to that particular patron.

Equality in alloy

I've got an Alloy model which contains the following :
abstract sig person{}
one sig john,Steve extends person {Gender: man}
sig man{}
fact {
all name: person, Gender: man |
name.Gender = name.Gender => person =person}
How can I make equality between two signatures?
It's not clear from your question what you want to do, and from your sample Alloy code it looks as if you may be suffering from some confusions.
First, the model you show uses the name Gender in two different ways, which is not illegal in itself but seems to suggest some confusion. (It certainly confuses the willies out of this reader.)
In the declaration for the two singleton signatures john and Steve, Gender denotes two binary relations, one holding between the signature john and the signature man, the other holding between Steve and man. To say the same thing in symbolic form, Gender denotes (a) some subset of john -> man, and (b) some subset of Steve -> man.
In the anonymous fact, however, Gender denotes a variable of type man.
Your model will be easier to understand if you find a way to rename one or the other of these. Since variable names in a quantified expression are arbitrary, your fact will mean the same thing if you reformulate it as
fact { all P : person, M : man | P.M = P.M => person = person }
If that's not what you meant to say, then you may have meant to say something like
fact { all P : person, M : man |
P.Gender = P.Gender => person = person
}
Renaming the variable forces you to choose one meaning or the other. This is a good thing. (It is an unfortunate fact that neither formulation is actually satisfactory in Alloy. But let's deal with one problem at a time; getting rid of the double use of the name Gender is the first step.)
A second issue is that whichever formulation of the fact you meant, it almost certainly doesn't mean what you wanted it to mean. Ignoring the specifics of the model for a moment, your fact takes the form
fact { all V1 : sig1, V2 : sig2 |
Expression = Expression => sig1 = sig1
}
where Expression is either V1.V2 or V1.Relation, for some Relation defined in the model. There are several things wrong here:
V1.V2 is meaningless where V1 and V2 are both names of signatures or variables ranging over given signatures: the dot operator is meaningful only if one of its arguments is the name of a relation.
If any expression E is meaningful at all, then a Boolean expression of the form E = E (for example, person.Gender = person.Gender) is true regardless of what E means. Anything denoted by E is naturally going to be equal to itself. So the conditional might as well be written
1 = 1 => person = person
For the same reason, person = person will always be true, regardless of the model: for any model instance the set of persons in the instance will be identical to the set of persons in the instance. So the conditional will always be true, and the fact won't actually impose any constraint on instances of the model.
It's not clear how best to help you move forward. Perhaps one way to start would be to ask yourself which of the following statements you are trying to capture in your model.
There is a set of persons.
Some persons are males (have gender = 'man'). Others are not males.
John is a male individual.
Steve is a male individual.
John and Steve are distinct individuals.
If x and y are individuals with the same gender, then x and y are the same individual. I.e. no two individuals have the same gender.
Note that these statements cannot all be true at the same time. (If that's not obvious, you might do worse than try to figure out why. Alloy can be helpful in that effort.)
Good luck.

Resources