问题
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.
回答1:
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 }
来源:https://stackoverflow.com/questions/28921494/using-set-comprehension-on-binary-relationships-in-alloy