Alloy - Irreflexivity - alloy

I just started using Alloy. I have a question about the following minimal example:
module test
abstract sig MySig {
my_rel : set MySig
}
//fact my_rel_irrefl {no iden & my_rel } // this works
fact my_rel_irrelfl {my_rel not in iden} // this does not work
run {}
Why is the second my_rel_irrelfl not working? My thinking was that, e.g.
MySig = {N0,N1,N2}
iden = {(N0,N0),(N1,N1),(N2,N2)}
If there is an element (x,x), where x in MySig in the relation my_rel then it has to be in iden as well.
However, I get this model:
model found by alloy
I.e. one where my_rel is reflexive.

my_rel not in iden says that my_rel is not a subset of iden. Since N0 -> N1 in my_rel and N0 -> N1 not in iden, my_rel isn't a subset and the fact still holds.

Related

Alloy pred/fun parameter constraint

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)?

Alloy - Count atoms used by other atoms

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

specifying properties of relations in alloy

I am trying to express certain mathematical properties of relations in Alloy, but I am not sure if I have the right approach yet, as I am just a beginner. Would appreciate any insights from the community of experts out there!
Specifying the fact that domain of a relation as singleton. e.g. Is the following a reasonable and correct way to do that?
pred SingletonDomain(r: univ->univ) {
one ~r
}
sig S2 {}
sig S1 {
child: set S2
}
fact {
SingletonDomain [child]
}
or should it be something like the following
pred SingletonDomain (r: univ->univ) {
#S2.~r = 1
}
This is not very modular since the use of S2 is very specific to the particular signature.
Specifying the fact that a relation is a total order. At the moment I am using the following, basically I am simulating xor
pred total[r: univ->univ] {
all disj e, e': Event | (e.r = e' and e'.r != e) or (e.r != e' and e'.r = e)
}
Thanks
To specify the fact that the domain of a given relation is a singleton, your first attempt is really close to do the trick. The only problem is that one ~r enforces the inverse of the r relation (and thus the r relation itself) to be composed of a single tuple. This is not what you want to express.
What you want to express is that all elements in the range of the r relation have the same (so only one) image through its inverse relation '.
You should thus write the following predicate :
pred SingletonDomain(r: univ->univ) {
one univ.~r
}
For your second question, your predicate doesn't handle cases were e -> e' -> e '' -> e. To handle those, you can use transitive closure.

Automata with rules and invariances

I was inspired by the slide http://alloy.mit.edu/alloy/tutorials/day-course/s4_dynamic.pdf of Greg Dennis and Rob Seater, to model an automaton whose transitions are defined by rules and invariances but I can not understand why satisfy the constraints even in the presence of invariances and contradictory rules.
sig State {value : one Int}
sig System { trans : State -> State }
pred i1[s : State] { s.value < 4 }
pred i2[s : State] { s.value > 0 }
pred r1[s, s' : State, m, m' : System] {
s.value = -1 and s'.value = 0 and change[s, s', m, m']
}
pred r2[s, s' : State, m, m' : System] {
s.value = 1 and s'.value = 2 and change[s, s', m, m']
}
pred change[s, s' : State, m, m' : System] {
m'.trans = m.trans + s -> s'
}
assert ruleSafe {
all s, s' : State, m,m' : System |
i1[s] and i2[s] and r1[s,s',m,m'] and r2[s,s',m,m'] =>
i1[s'] and i2[s']
}
check ruleSafe
First, a side note: It's not clear what the value relation is intended to be doing, but do remember that integers in Alloy tend to be very narrow and overflow behavior can make rules like s.value < 4 produce unexpected results. Whenever integers are used only to ensure a nice supply of distinct values, or ordered values it is almost always better to use an uninterpreted type in Alloy with some relations to ensure the necessary constraints.
However, that's not the main source of your confusion. I think you believe that since r1 requires its first argument to have a value of -1 and r2 requires the same argument to have a value of 1, any condition involving both r1 and r2 with the same first argument cannot possibly be satisfied, and there can be no instances of a model which is required to satisfy such a predicate. Almost true!
I think you're correct that r1 and r2 cannot both be true for the same set of arguments (or any sets of arguments with the same first argument s). But the constraint you specify uses r1[s,s',m,m'] and r2[s,s',m,m'] in the antecedent of a conditional. Before you go any further, stop and think: What is the truth value of a conditional if the antecedent is false?
If you are having trouble seeing what is going on, try examining the instances of your model in which the antecedent of your conditional is true for all pairs of States and Systems. Concretely, add the following to your model and look at the instances it produces.
pred antecedent {
all s, s' : State, m, m' : System
| i1[s] and i2[s] and r1[s,s',m,m'] and r2[s,s',m,m']
}
run antecedent
It took me a minute or two before I understood what I was seeing; if it takes you longer than a few minutes, you might try the following variant definition of antecedent and see if it enlightens you.
pred antecedent {
all s, s' : State, m, m' : System
| i1[s] and i2[s] and r1[s,s',m,m'] and r2[s,s',m,m']
some State
some System
}
You are not the first user of first-order logic to have been taken by surprise when a conditional statement in your model turned out to be vacuously true when you expected it to be false. You won't be the last.

Alloy - Lone instance

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.

Resources