disjoint union and Cartesian product in Alloy - alloy

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.

Related

Sum of nested values in Alloy

I'm starting with definitions similar to these below
sig Sub { vals : set Int }
sig Top { subs : set Sub }
I'd like an expression that can produce the sum of all values contained inside something of type Top. Top when written as a nested set, would be something like {{3, 4}, {7}}. The result of the nested sum in this case should be 14.
This function of course just gives the number of elements in the outer set.
fun allsum[t: Top] : one Int { #t }
I believe I need to use the built-in sum function and a set comprehension, but Alloy syntax is still somewhat arcane to me.
For this, you need a nested sum expression:
fun allsum[t: Top] : Int {
sum s: t.subs | (sum v: s.vals | v)
}
The general format is:
sum e: <set> | <expression involving e>

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
}

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.

Accumulation of union of sets

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
}

Resources