When I execute the following example using Alloy, either v4.2 or v5, I get an instance that appear twice in solution space.
sig A {}
sig B extends A { }
pred P { }
run P for 2
Generated instances:
1:A={}, B={}
2:A={A$0}, B={}
3:A={B$0}, B={B$0}
4:A={A$0, B$0}, B={B$0}
5:A={A$0, A$1}, B={}
6:A={A$0, B$0}, B={B$0} // same as instance 4
7:A={B$0, B$1}, B={B$0, B$1}
Any suggestions?
Try to specify a different scope for each signature
for example:
run P for 2 A, 4 B
Related
The following Alloy predicate p has a parameter t declared as a singleton of type S. Invoke run p gives the correct result because the predicate body states that t may contain two different elements s and s'. However, in the second run command, a set of two disjoint elements of type S is passed into predicate p and this command gives an instance. Why is it the case?
sig S {}
pred p(t: one S) {
some s, s': t | s != s'
}
r1: run p -- no instance found
r2: run { -- instance found
some disj s0, s1: S {
S = s0 + s1
p[S]
}
}
See https://stackoverflow.com/a/43002442/1547046. Same issue, I think.
BTW, there's a nice research problem here. Can you define a coherent semantics for argument declarations that would be better (that is, simpler, unsurprising, and well defined in all contexts)?
I'm trying to notice a change in atom relations to other atoms. Using the below signatures :
sig Word, Definition{}
sig Dictionary {
def: Word -> lone Definition
}
I then use a predicate to show what happens when you add a new relation to a Dictionary by having another Dictionarywhich is the same but with one more relation.
pred addRelation [d,d':Dictionary,w:Word,f:Definition] {
d'.word = d.word + w -> f
}
To see if the number of Word atoms used by the first Dictionary increase I can show only the instances where this occurs using:
#d'.def.Definition > #d.def.Definition
However, is there a way to see if the number of Definition atoms used by the second Dictionary atom has increased? I've been using trial and error in the Alloy Evaluator to try and find a value for this but have come up short.
Thanks!
Like this?
sig Word, Definition{}
sig Dictionary {
def: Word -> lone Definition
}
pred addRelation [d,d':Dictionary,w:Word,f:Definition] {
d'.def = d.def + w -> f
#d'.def[Word] > #d.def[Word]
}
run addRelation
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 have the following specification in Alloy:
sig A {}
sig Q{isA: one A}
fact {
all c1,c2:Q | c1.isA=c2.isA => c1=c2 // injective mapping
all a1:A | some c1:Q | c1.isA=a1 //surjective
}
In my models the above fact repeats similarly between different signature. I tried to factor out it as a separate module so I created a module as below:
module library/copy [A,Q]
fact {
all c1,c2:Q | c1.isA=c2.isA => c1=c2 // injective mapping
all a1:A | some c1:Q | c1.isA=a1 //surjective
}
Then I tries to use it as bellow:
module family
open library/copy [Person,QP]
sig Person {}
sig QP{isA:Person}
run {} for 4
but Alloy complains that "The name "isA" cannot be found." in the module.
What is wrong with my approach? and Why alloy complains?
In my previous answer I tried to address your "similarly between different signature" point, that is, I thought your main goal was to have a module that somehow enforces that there is a field named isA in the sig associated with parameter Q, and that isA is both injective and surjective. I realize now that what you probably want is reusable predicates that assert that a given binary relation is injective/sujective; this you can achieve in Alloy:
library/copy.als
module copy [Domain, Range]
pred inj[rel: Domain -> Range] {
all c1,c2: Domain | c1.rel=c2.rel => c1=c2 // injective mapping
}
pred surj[rel: Domain -> Range] {
all a1: Range | some c1: Domain | c1.rel=a1 //surjective
}
family.als
open copy[QP, Person]
sig Person {}
sig QP{isA:Person}
fact {
inj[isA]
surj[isA]
}
run {} for 4
In fact, you can open the built-in util/relation module and use the injective and sujective predicates to achieve the same thing, e.g.:
family.als
open util/relation
sig Person {}
sig QP{isA:Person}
fact {
injective[isA, Person]
surjective[isA, Person]
}
run {} for 4
You can open the util/relation file (File -> Open Sample Models) and see a different way to implement these two predicates. You can then even check that your way of asserting injective/surjective is equivalent to the built-in way:
open copy[QP, Person]
open util/relation
sig Person {}
sig QP{isA:Person}
check {
inj[isA] <=> injective[isA, Person]
surj[isA] <=> surjective[isA, Person]
} for 4 expect 0 // no counterexample is expected to be found
Modules in Alloy are treated as independent units (i.e., a module can access only the stuff defined in that module itself and the modules explicitly opened in that module), so when compiling the "copy" module, isA is indeed undefined. A theoretical solution would be to additionally parametrize the "copy" module by the isA relation, but in Alloy module parameters can only be sigs.
A possible solution for your problem would be to define abstract sigs A and Q in module "copy", and then in other modules define concrete sigs that extend A and Q, e.g.,
copy.als:
module library/copy
abstract sig A {}
abstract sig Q {isA: one A}
fact {
all c1,c2:Q | c1.isA=c2.isA => c1=c2 // injective mapping
all a1:A | some c1:Q | c1.isA=a1 //surjective
}
family.als:
open library/copy
sig Person extends A {}
sig QP extends Q {} {
this.#isA in Person // restrict the content of isA to Person
}
run {} for 4
Using inheritance to achieve this kind of code reuse is conceptually not ideal, but in practice is often good enough and I can't think of another way to do it in Alloy.
I am writing a simple Alloy code but I cannot understand how can I say AT MOST one A has associate with p.D (so AT MOST would be One or Zero). So I wrote the below code but the assertion presents no counter-example with an instance of P1 without D. Could you help me how can I define my fact in terms of having AT MOST one instance for p.D where I can see a counter example that p has no connection for its D.
abstract sig A {}
sig A1,A2,A3 extends A{}
abstract sig P {}
sig P1 extends P {D: A}
fact
{
all p: P1 | lone (p.D & A)
}
assert asr
{no p: P1 | no (p.D & A)}
check asr for 5
Your specification (introduction of sig P1) says that for each p in P1 is always related by d to exactly one a in A. Your fact is redundant ("0 or 1" is implied by "always 1").
You could declare "sig P1 extends P (D : lone A}". (The fact would still be redundant.)
Also note that the "& A"s in your fact and assertion are redundant.
You might have meant the fact to be
fact {lone P1.D}
which says that all those instances of P1 which are related to an A are related to the same A.