Alloy - Count atoms used by other atoms - predicate

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

Related

Variable-Value pairs (i.e., maps) are not retained when one of them gets nullified

I have the following simple model where I try to simulate the nullification of a select Data from a Dataset. Data to Val (d2v) mapping is a field of a signature called Dynamic whose instances correspond to different states of the model (before and after). When I try to simulate this model, I get two unrelated Dynamic instances, even though I explicitly set the d2v mappings of the two Dynamic instances to be the same (except of course the mapping of Data instance being passed to nullify predicate). In other words, the variable-value pairings of the two instances of Dynamic do not match. What am I missing?
sig Data {}
sig Val {}
sig Dynamic {
d2v: Data -> lone Val,
}
pred nullify [dyn, dyn': Dynamic, d:Data] {
d in dyn.d2v.univ implies
dyn'.d2v = dyn.d2v - (d -> d.(dyn.d2v))
else
dyn'.d2v = dyn.d2v
}
run nullify for exactly 3 Data,
exactly 3 Val,
exactly 2 Dynamic
Here is an example evaluation of the two instances of Dynamic.d2v from Alloy:
sig Dynamic
Dynamic$0
field d2v
Data$2 -> Val$2
Dynamic$1
field d2v
Data$0 -> Val$1
Data$1 -> Val$0
where Data$2 is the argument of remove predicate. What I would expect, for instance, is the following:
sig Dynamic
Dynamic$0
field d2v
Data$2 -> Val$2
Data$0 -> Val$1
Data$1 -> Val$0
Dynamic$1
field d2v
Data$0 -> Val$1
Data$1 -> Val$0
Are you sure that the instance binds dyn and dyn' to Dynamic$0 and Dynamic$1? It could bind them both to Dynamic$1 for example, satisfying the else arm of your predicate.

How to write a function in Alloy that returns a subset

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
}

Ordering in Alloy using util/ordering

I am trying to learn about how ordering works in Alloy. I have a time signature which I have used to instantiate the ordering module. I want the predicate addPage to add a page to the book at time t' where t' = t.next. (Basically add a page to the Book on the next time) However it is not working as expected and instead Time2 has lesser number of pages than Time1. Can someone explain to me why this is happening? Thanks.
open util/ordering[Page] as P0
open util/ordering[Time] as T0
sig Page {}
sig Time {}
sig Book
{
pages: Page -> Time
}
pred addPage(b:Book, p:Page, t: Time)
{
t != T0/last implies
{
let t' = t.next |
b.pages.t' = b.pages.t + p
}
}
run addPage {} for 3
The problem are the extra curly braces in the run statement.
I think Alloy executes an empty predicate in this case.
Try:
run addPage for 3
instead. You will see a visualization where the selected instances for b, t and p are marked.
You're trying to change state which can only be simulated in constraint logic.
Please notice that the expression in addPage is basically ineffective /run your model without it/ and that there's only one Book atom in the solution.
Here's a model you can start with and gradually refine.
open util/ordering[Time]
sig Page {}
sig Time {}
sig Book {
pages : Page lone -> Time // each Time atom is mapped to at most one Page atom
}
pred addPage(b0, b1 : Book, pg : Page, t0, t1 : Time) {
one pg and // one page at a time (it's likely redundant)
not pg in b0.pages.Time and // it's a 'new' page
b0.pages + pg->t1 = b1.pages and // 'new state' of b0
t1 = t0.next // pg is 'added' with the next time stamp
}
run addPage for 3 but 2 Book
I used the optional 'and' operators, placed t1 = t0.next at the end of the constraint, positioned b1.pages /representing the 'new state'/ on the right and used quotes in the comments to emphasize that there's no real state change and sequence of operation in the sense imperative programming works.

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.

Alloy: Int meaning of field

i saw the following Alloy definition:
one sig Number { i:Int[3]}
//what does Int[3] mean. I mean what is the meaning of the above field 'i'
It means i is a relation between the singleton set Number and the singleton subset of Int with the atom 3. In object notation it's like Number.i = 3

Resources