In the following alloy model:
sig Family{
father: one Member,
mother: one Member,
daughter: set Member,
son: set Member
}
sig Member{}
fact {
all m:Member | one m.~(father+mother+daughter+son)
(none->none) = (mother & son) + (daughter & son) +(father & mother) + (father & daughter) + (father & son) + (mother & daughter)
}
pred show(){}
run show for 12 but exactly 2 Family, exactly 5 Member
there is no distinction between the son and daughter relations in the sense of constraints on them (At least as far as I understand) But when I run this model, it gives me 3 instances: it permutes son between two families, but it does not permutes daughter! Why this happens?
PS:
when I try it for exactly 1 Family the analyzer does not discriminate son and daughter but when I increase the Family to 2 or three the discrimination occurs!
Related
Below is an Alloy model representing this set of integers: {0, 2, 4, 6}
As you know, the plus symbol (+) denotes set union. How can 0 be unioned to 2? 0 and 2 are not sets. I thought the union operator applies only to sets? Isn't this violating a basic notion of set union?
Second question: Is there a better way to model this, one that is less cognitively jarring?
one sig List {
numbers: set Int
} {
numbers = 0 + 2 + 4 + 6
}
In Alloy, everything you work with is a set of tuples. none is the empty set, and many sets are sets of relations (tuples with arity > 1). So also each integer, when you use it, is a set with a relation of arity 1 and cardinality 1. I.e. in Alloy when you use 1 it is really {(1)}, a set of a type containing the atom 1. I.e. the definition is in reality like:
enum Int {-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7}
Ints in Alloy are just not very good integers :-( The finite set of atoms is normally not a problem but with Ints there are just too few of them to be really useful. Worse, they quickly overflow and Alloy is not good in handling this at all.
But I do agree it looks ugly. I have an even worse problem with seq.
0-A + 1->B + 2->C + 3->C
I already experimented with adding literal seq to Alloy and got an experimental version running. Maybe sets could also be implemented this way:
// does not work in Alloy 4
seq [ A, B, C, C ] = 0->A + 1->B + 2->C + 3->C
set [ 1, 2, 3, 3 ] = 1+2+3
Today you could do this:
let x[a , b ] = { a + b }
run {
x[1,x[2,x[3,4]]] = 1+2+3+4
} for 4 int
But not sure I like this any better. If macros would have meta fields or would make the arguments available as a sequence (like most interpreters have) then we could do this
// does not work in Alloy 4
let list[ args ... ] = Int.args // args = seq univ
run {
range[ list[1,2,3,4,4] ] = 1+2+3+4
}
If you like the seq [ A, B, C, C ] syntax or the varargs then start a thread on the AlloyTools list. As said, I got the seq [ A, B, C, C ] working in a prototype.
Consider the Alloy model below, a stripped-to-the-essence version of a student submission. The problem is a course scheduling system, and the student was trying to say there are no conflicts (two distinct courses meeting in the same place at the same time):
abstract sig Room{}
one sig S20, S30, S50 extends Room{}
abstract sig Period{}
one sig Mon, Tue, Wed, Thu, Fri extends Period{}
// Courses and the room and periods when they meet.
some sig Course {
where : Room,
when : some Period
}
// No two Courses with any common meeting Periods can be
// in the same Room - from the student.
pred NoRoomConflicts_student {
no c : Course | no d : Course |
c != d && some c.when & d.when && d.where = c.where
}
run NoRoomConflicts_student
// No two Courses with any common meeting Periods can be
// in the same Room - my recasting.
pred NoRoomConflicts_alt {
no c : Course, d : Course |
c != d && some c.when & d.when && d.where = c.where
}
run NoRoomConflicts_alt
When NoRoomConflicts_alt is run we get solutions that conform to the spec.
But when NoRoomConflicts_student is run, suddenly "d" becomes a binary relation between Courses and the solutions show conflicts.
(a) Why was "d" transformed in this way?
(b) Given (a), shouldn't c != d raise a type error?
Note: I'm not claiming that the two predicates are equivalent (my head aches trying to do the double negation) - I just want to know how "d" suddenly becomes a binary relation when NoRoomConflicts is run.
Version: Alloy Analyzer 4.2_2015-02-22 (build date: 2015-02-22 18:21 EST)
First, what you're seeing in the solution is that certain quantified variables (d in this case) get skolemized so that you can see their values. If you're solving a constraint of the form (all x | some y | ...), the skolemized value of y will have to be a relation -- giving a y value for each x. This is not the actual type of the Alloy variable, which is why there is no type error. For a full explanation, see Section 5.2.2 of my book (Software Abstractions).
Second, the two formulas are not the same. This is explained on page 293 of my book. In short, it's because "no c, d | P" means you can't find a c and d such that P, and "no c | no d | P" means you can't find a c such that you can't find a d such that P.
Here's the alloy code for the example we're going over in my class:
abstract sig Airport {
flight: set Airport
}
one sig CMX, DTW, MSP, BRD, CDG extends Airport {}
fact {
-- flight = CMX->DTW + DTW->MSP + MSP->CMX + DTW->CDG + CDG->DTW + MSP->BRD + BRD->MSP
}
fun flight2: Airport->Airport {flight.flight}
fun flight3: Airport->Airport {flight.flight2}
fun flight4: Airport->Airport {flight.flight3}
fun flight5: Airport->Airport {flight.flight4}
pred show {
flight5 in flight2
flight2 not in flight5
-- #flight = 10
}
run show for 5 Airport, 6 Int
I want to know what the last line means. Specifically, what does "6 Int" mean?
The last line defines an upperbound (called a scope) to the number of atoms conforming to the given concepts in any satisfying instance to be found when running this command.
In your example, you will look for instances which contains at most 5 Airport atoms. Int is a built-in type in Alloy. As you didn't declare any Int-typed field, the part 6 Int won't have big impacts on the instance finding process.
The number associated to Int in the scope do not correspond to the maximum number of Int atom in instances to be found but to the bit-width to be used to represent Integers.
With a bit-width of 6, your instance will contains integers from -32 to 31.
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.
Consider the following simple variant of the Address Book example
sig Name, Addr {}
sig Book { addr : Name -> Addr } // no lone on Addr
pred show(b:Book) { some n : Name | #addr[b,n] > 1 }
run show for exactly 2 Book, exactly 2 Addr, exactly 2 Name
In some model instances, I can get the following results in the evaluator
all b:Book | show[b]
--> yields false
some b:Book | show[b]
--> yields true
show[Book]
--> yields true
If show was a relation, then one might expect to get an answer like: { true, false }. Given that it is a predicate, a single Boolean value is returned. I would have expected show[Book] to be a shorthand for the universally quantified expression above it. Instead, it seems to be using existential quantification to fold the results. Anyone know what might be the rational for this, or have another explanation for the meaning of show[Book]?
(I'm not sure I have the correct words for this, so bear with me if this seems fuzzy.)
Bear in mind that all expressions in Alloy that denote individuals denote sets of individuals, and that there is no distinction available in the language between 'individual X' and 'the singleton set whose member is the individual X'. ([Later addendum:] In the terms more usually used: the general rule in Alloy's logic is that all values are relations. Binary relations are sets of pairs, n-ary relations sets of n-tuples, sets are unary relations, and scalars are singleton sets. See the discussion in sec. 3.2.2 of Software Abstractions, or the slide "Everything's a relation" in the Alloy Analyzer 4 tutorial by Greg Dennis and Rob Seater.)
Given the declaration you give of the 'show' predicate, it's easy to expect that the argument of 'show' should be a single Book -- or more correctly, a singleton set of Book --, and then to expect further that if the argument is not actually a singleton set (as in the expression show[Book] here) then the system will coerce it to being a singleton set, or interpret it with some sort of implicit existential or universal quantification. But in the declaration pred show(b:Book) ..., the expression b:Book just names an object b which will be a set of objects in the signature Book. (To require that b be a singleton set, write pred show(one b: Book) ....) The expression which constitutes the body of show is evaluated for b = Book just as readily as for b = Book$0.
The appearance of existential quantification is a consequence of the way the dot operator at the heart of the expression addr[b,n] (or equivalently n.(b.addr) is defined. Actually, if you experiment you'll find that show[Book] is true whenever there is any name for which the set of all books contains a mapping to two different addresses, even in cases where an existential interpretation would fail. Try adding this to your model, for example:
pred hmmmm { show[Book] and no b: Book | show[b] }
run hmmmm for exactly 2 Book, exactly 2 Addr, exactly 2 Name