Using set comprehension on binary relationships in

2019-07-22 12:59发布

I have the following signatures:

sig Id, Grade {}

sig Foo {
    result : Id -> Grade
}

Now I want to create a function that takes in a foo variable and returns all associating Foo -> Grade relationships:

fun results[ id : Id ]: Foo -> Grade {
    //return all Foo->Grade binary relationships such that "id -> grade" in Foo.result
}

i.e.

So if the "result" relationship is like this:

(foo0, id0, grade0)
(foo0, id1, grade0)
(foo0, id2, grade1)
(foo1, id0, grade2)
(foo1, id3, grade3)
(foo2, id0, grade0)

and I run function "results[ id0 ]" I would get:

(foo0, grade0)
(foo1, grade2)
(foo2, grade0)

Now I guess I would use some sort of set comprehension, but the issue is that set comprehension only works with unary sets, not binary sets.

标签: alloy
1条回答
祖国的老花朵
2楼-- · 2019-07-22 13:29

Now i guess I would use some sort of set comprehension, but the issue is that set comprehension only works with unary sets, not binary sets.

Right the first time (yes, use set comprehension), not quite right the second (set comprehensions work fine with relations). See section B.8 of the language reference, or 3.5.5 of Software Abstractions.

Try something like this (not checked!):

fun results[ id : Id ]: Foo -> Grade {
/* return all Foo->Grade binary relationships
   such that "id -> grade" in Foo.result */
   { f : Foo, g : Grade 
     | f -> id -> g in result } 
   /* not Foo.result, that was a slip */
}

There may be a clever way to write the required set without a comprehension, just using box joins and dot joins, but if there is, at the moment it's eluding me. The closest I get is

{ f : Foo, g : Grade | f.result.g = id }
查看更多
登录 后发表回答