I have two classes A and B and a relation with extra data of class R on them.
So, A and B are related to each other via R.
sig A {}
sig B {}
sig R {
a : A,
b : B,
data : Bool
}
here, Bool is defined as:
sig Bool {}
sig True, False extends Bool {}
Now, I extend A like this:
sig A{
allb : some B
}
Which contains all instances of B for which there is a relation between this A and that B and where the data is of type True.
I want to express the following logical statement as an Alloy fact:
(source: dropproxy.com)
I assume here that True == 1 and False != 1 and that the sets A and R contain all instances of A and R respectively.
What I've tried so far is to define a fun trueR(a : A) which should return all R's for which R.a = a and r.data = True and a fact allbIsRTrue which states that for each A allb should be the sum of the R.b's returned by trueR.
However, here is where I get stuck, I can't find the right construct to sum over sets in the reference and tries with sum have resulted in syntax errors.
How would I specify my formal constraint as an Alloy fact?
I think you want to use set comprehension. In Alloy, this is the syntax for set comprehension
{x: X | f(x)}
The expression above evaluates to a set of X's for which f(x) holds.
In your example, to express the fact for allB you can write something like
fact fAllB {
all a: A |
a.allB = {b: B |
some r: R | r.ra = a and r.rb = b and r.data = True}
}
In English, this fact reads "for all a of set A, a.allB is a set of all B's such that there exist some r which "connects" those exact a and b and for which r.data is True.
Note the following modifications I made to the rest of your model:
I made the Bool sig abstract because you probably don't want bools that are neither True nor False
I made the True and False sigs singleton sigs (i.e., one sig) because you probably want to have exactly one atom of each of them
I renamed relations a and b to ra and rb to avoid name aliasing and potential confusion
Here is the rest of your model that I used for this example
abstract sig Bool {}
one sig True, False extends Bool {}
sig A {
allB: set B
}
sig B {}
sig R {
ra : A,
rb : B,
data : Bool
}
Related
How do I write a function in Ally that returns a subset of the parameter:
fun subset( s : set univ ) : set univ {..}
I can write a predicate:
pred subset( disj a, b : set univ ) { b in a }
However, a function would be nicer to read but I am not sure how to put constraints on the return value?
I don't see any clean way to do it.
A dirty hack to achieve your goal would be to differentiate univ elements by, e.g., ranking them. To do so, I'd introduce an arbitrary signature in which a rank relation is defined, associating an integer to each univ element.
Then, returning an arbitrary subset would simply consist in removing from a given set elements who have e.g. the highest rank.
fun subset( s : set univ ) : set univ {
let maxRank= max[diff.rank[s]] |
s - diff.rank.maxRank
}
one sig diff{
// remove -Int if you plan to use your subset function on sets of Int as well
rank : (univ -Int) -> one Int
}
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
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.
I have two set comprehension predicates (uniary) as bellow in Alloy:
pred A (o : Object){ .. }
pred B (o : Object) { ..}
I would like to define predicates, one of which is disjoint union and another one is Cartesian product of A and B.
PS: To define their union and intersection I can define the following predicate:
pred Union(o : Object){
A[o] or B[o]
}
pred Inter(o:Object){
A[o] and B[o]
}
I would like to get similar predicates for Cartesian product and disjoint union.
Thanks
You may be conflating the concepts of predicates and the concepts of sets. You have good company (Frege, for one), but it turns out to be dangerous.
The expressions o in A[o] and o in B[o] should raise a type error, since if A and B are predicates, then the expressions A[o] and B[o] should evaluate to true or false, and not to sets of which o could conceivably be a member.
If you want a predicate U which is true of an object when either A or B or both are true for that object, then you want something like
pred U[o : Object] { A[o] or B[o] }
And if you want an exclusive disjunction -- I assume that this is what you mean when you speak of a disjoint union -- then
pred X[o : Object] { (A[o] and not B[o]) or (B[o] and not A[o]) }
If you want the sets for which A, B, and X are true, then you want to write
{ o : Object | A[o] }
{ o : Object | B[o] }
{ o : Object | X[o] }
The third of these can of course be written
{ o : Object | (A[o] and not B[o]) or (B[o] and not A[o]) }
The set comprehension notation (again, I encourage you to read the relevant documentation) can also handle sets of tuples; the Cartesian product of the sets of objects satisfying A and B would be written this way:
{ a, b : Object | A[a] and B[b] }
Here is the solution to what I was looking for:
cartesian product of A and B are defined as A * B = {(a,b) | a in A and b in B}. So putting it in Alloy syntax with set comprehension expression would be as follows:
pred ACartesB(o1:Object, o2: Object){
A[o1] and B[o2]
}
disjoint union of A and B are defined as A+B= {(a,1) union (b,2) | a in A and b in B}. 1 and 2 are indexes to distinguish the same elements of A and B in A+B. So putting it in alloy context would be as the following:
pred AdisjUnionB(o:Object, i: Int){
(A[o] and i=1) or (B[o] and i=2)
}
PS:
we assume that we have sig Object {} in our signature.
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.