Alloy Analyzer: Quantifiers and Set Products - alloy

I have encountered the following issue in Alloy. Consider the toy code which tries to capture even labeled entities (V1 is for State and V2 is for ProductStateSet):
enum State {s1, s2, s3, s4, s5, s6}
enum DummySet {b,c}
let ProductStateSet = DummySet->State
pred evenV1 (state: State){
(state = s2) or (state=s4) or (state=s6)
}
pred evensetV1 (stateset: State) {
all state: stateset | evenV1[state]
}
assert a2V1 {
evensetV1[(s2 + s4)]
}
pred evenV2 (state: ProductStateSet){
(state = b->s2) or (state=b->s4) or (state=b->s6)
}
assert a1V2 {
evenV2[b->s2]
}
pred evensetV2 (stateset: ProductStateSet) {
all state: stateset | evenV2[state]
}
assert a2V2 {
evensetV2[ (b->s2) + (b->s4) ]
}
The assertion a2V1 is true, but a2V2 is false, when I would have expected them to be the same. Why is this so, and what is the proper way to use quantifiers when dealing with set products?
If I change "evenset" to have "some" rather than "all", no issues with evensetV1, but for evensetV2 I get:
pred evensetV2 (stateset: ProductStateSet) {
some state: stateset | evenV2[state]
}
assert a2V2 {
evensetV2[ (b->s2) + (b->s4) ]
}
Executing "Check a2V2"
Solver=sat4j Bitwidth=4 MaxSeq=4 SkolemDepth=1 Symmetry=20
Generating CNF...
.
Analysis cannot be performed since it requires higher-order
quantification that could not be skolemized.
Another question for this example regarding set comprehension: I can write an assertion like:
assert a3V1{
#{state: State | evenV1[state]} > 2
}
Is there a way to print out the set elements, that is, can I print out the below set?
{state: State | evenV1[state]}
Thanks!

Regarding your first question:
EDITED (first answer was wrong)
Running the assertion gives 2 counter examples.
One is expected, in the sense that none -> none is not considered in the evenV2 predicate. But the other (see below) doesn't make sense for me.
My only logical explanation is that the quantification variable "state" of evenSetV2 is badly interpreted when given in parameter of evenV2 even though it seems somehow farfetched ...
I think whenever possible, one should avoid quantification and prefer more straightforward set operations. Implementing the predicate and assertion as follows solves the problem (you don't even need to differentiate between the singleton and the set approach anymore):
pred evenV2 ( state: ProductStateSet){
DummySet.state in (s2+s4+s6)
}
assert a2V2 {
evenV2[ (b->s4)+ (b->s6)]
}
END EDIT
For the second question, the Alloy evaluator is your friend.

Related

Why does alloy model with but 1 set A return instance of more than 1 A

I am sorry for the title, I tried hard to make it as understandable as possible but I know I failed.
Here is the simple model:
sig ETHBusStation {
next: set ETHBusStation
}
one sig Polyterrasse, HaldenRight, HaldenLeft, Hoengg extends ETHBusStation {}
sig ETHBus {
station: lone ETHBusStation
}
fact {
//no (Hoengg - HaldenRight)
all s: ETHBusStation | ETHBusStation in s.^next and some s.next
all b1, b2: ETHBus | b1.station != b2.station}
run {} for 2 but 1 ETHBusStation
when I run the analyzer it finds an instance with one of each Polyterrasse, HaldenRight, HaldenLeft, Hoengg
but since these are all disjoint subsets of ETHBusStation, how can this be with the but 1 parameter?
I am expecting it to have a single station that links to itself via next.
I am grateful for any hints and tips.
If we use in instead of extends it behaves as expected, but then they also don't have to be disjoint which makes sense.
I believe the scope declaration is being overridden by the one sig decl. If it didn't do this, the expected behavior would be to find no instances, since the sig decl claims that exactly four bus stations exist, and the scope says that there is at most one bus station.

How are inital states established in dynamic models under Electrum 2?

I cribbed from the hotel door lock example and came up with this MWE for vehicle doors.
enum LockState {Locked, Unlocked}
sig Door {
var state: LockState
}
sig Vehicle {
doors : disj set Door
}
//actions
pred unlock[d: Door]{
d.state' = Unlocked
}
pred lock[d: Door]{
d.state' = Locked
}
//traces
pred init{
all s: Door.state | s = Locked
}
pred trace{
init
always {
some d: Door |
unlock[d] or
lock[d]
}
}
//demonstrate
run {} for 4 but exactly 2 Vehicle, 4 Time
Which to my suprise allows the instance shown below, in which some doors are locked and some not. How do I establish the condition that all doors are locked at the earliest time?
Initial states are defined without any temporal keywords, as you did in init.
The problem is that you defined your trace as a predicate. If you define it as a fact it will always be applied. However, if you make it a predicate (my preference since it feels less global) you must include it from the run command. Pick one:
run trace for 4 but exactly 2 Vehicle, 4 Time
run { trace } for 4 but exactly 2 Vehicle, 4 Time
However, your model will then still not run well.
You provide an always but no goal. So after one state Alloy is happy. You should provide an eventually so Alloy will attempt to continue until it is satisfied.
You allow vehicles without doors, I would use some Door instead of set Door
Your init can be done cleaner like Door.state = Locked
In your trace, each step sets one Door. However, you're not specifying what the state of the other doors should be. If you do not specify a value for the next state, they can become anything. These should be explicitly set to have their old value.
So I came up with the following model:
enum LockState { Locked, Unlocked }
sig Door { var state: LockState }
sig Vehicle { doors : disj some Door }
pred Door.unlock { this.state' = Unlocked }
pred Door.lock { this.state' = Locked }
pred trace {
Door.state = Locked
always (
some d: Vehicle.doors {
(d.unlock or d.lock)
unchanged[state,d]
}
)
eventually Door.state = Unlocked
}
run trace for 4 but exactly 2 Vehicle
pred unchanged[ r : univ->univ, x : set univ ] {
(r - x->univ)' = (r - x->univ)
}
updated Added an unchanged predicate.

Alloy - scope for this/Univ, ordering, "open" statement

I am having errors in Alloy (4.2) specifications of the following kind:
You must specify a scope for sig "this/Univ"
The issue is easy to reproduce with a toy example:
open util/ordering[State]
open util/integer
sig State { value : Int }
fact {
first.value = 0
all s:State, s': s.next | s'.value = plus[s.value, 1]
}
run { } for 5 State, 3 Int
All of the above is fine. Now, when I define State in an external file and import it with an open statement, I get the "Univ scope" error:
open util/ordering[State]
open util/integer
open State
fact {
first.value = 0
all s:State, s': s.next | s'.value = plus[s.value, 1]
}
run { } for 5 State, 3 Int
I tried several variations of the above without success.
Why does this happen and how can it be solved?
In my project, it would be useful for me to define the target sig of the ordering module in a different file.
Thanks,
Eduardo
This is an Alloy "design bug".
It was decided that a Univ signature would appear when no signatures are defined in the module in order to check some property over built-in relations (e.g., unit, iden, none).
You have many ways of going around this problem, here is a selection :
You can add ",0 Univ" at the end of your run command
You can add a signature in your Alloy module
You can specify a global scope of zero (run { } for 0 but 5 State, 3 Int )
See this question for additional informations

duck typing in D

I'm new to D, and I was wondering whether it's possible to conveniently do compile-time-checked duck typing.
For instance, I'd like to define a set of methods, and require that those methods be defined for the type that's being passed into a function. It's slightly different from interface in D because I wouldn't have to declare that "type X implements interface Y" anywhere - the methods would just be found, or compilation would fail. Also, it would be good to allow this to happen on any type, not just structs and classes. The only resource I could find was this email thread, which suggests that the following approach would be a decent way to do this:
void process(T)(T s)
if( __traits(hasMember, T, "shittyNameThatProbablyGetsRefactored"))
// and presumably something to check the signature of that method
{
writeln("normal processing");
}
... and suggests that you could make it into a library call Implements so that the following would be possible:
struct Interface {
bool foo(int, float);
static void boo(float);
...
}
static assert (Implements!(S, Interface));
struct S {
bool foo(int i, float f) { ... }
static void boo(float f) { ... }
...
}
void process(T)(T s) if (Implements!(T, Interface)) { ... }
Is is possible to do this for functions which are not defined in a class or struct? Are there other/new ways to do it? Has anything similar been done?
Obviously, this set of constraints is similar to Go's type system. I'm not trying to start any flame wars - I'm just using D in a way that Go would also work well for.
This is actually a very common thing to do in D. It's how ranges work. For instance, the most basic type of range - the input range - must have 3 functions:
bool empty(); //Whether the range is empty
T front(); // Get the first element in the range
void popFront(); //pop the first element off of the range
Templated functions then use std.range.isInputRange to check whether a type is a valid range. For instance, the most basic overload of std.algorithm.find looks like
R find(alias pred = "a == b", R, E)(R haystack, E needle)
if (isInputRange!R &&
is(typeof(binaryFun!pred(haystack.front, needle)) : bool))
{ ... }
isInputRange!R is true if R is a valid input range, and is(typeof(binaryFun!pred(haystack.front, needle)) : bool) is true if pred accepts haystack.front and needle and returns a type which is implicitly convertible to bool. So, this overload is based entirely on static duck typing.
As for isInputRange itself, it looks something like
template isInputRange(R)
{
enum bool isInputRange = is(typeof(
{
R r = void; // can define a range object
if (r.empty) {} // can test for empty
r.popFront(); // can invoke popFront()
auto h = r.front; // can get the front of the range
}));
}
It's an eponymous template, so when it's used, it gets replaced with the symbol with its name, which in this case is an enum of type bool. And that bool is true if the type of the expression is non-void. typeof(x) results in void if the expression is invalid; otherwise, it's the type of the expression x. And is(y) results in true if y is non-void. So, isInputRange will end up being true if the code in the typeof expression compiles, and false otherwise.
The expression in isInputRange verifies that you can declare a variable of type R, that R has a member (be it a function, variable, or whatever) named empty which can be used in a condition, that R has a function named popFront which takes no arguments, and that R has a member front which returns a value. This is the API expected of an input range, and the expression inside of typeof will compile if R follows that API, and therefore, isInputRange will be true for that type. Otherwise, it will be false.
D's standard library has quite a few such eponymous templates (typically called traits) and makes heavy use of them in its template constraints. std.traits in particular has quite a few of them. So, if you want more examples of how such traits are written, you can look in there (though some of them are fairly complicated). The internals of such traits are not always particularly pretty, but they do encapsulate the duck typing tests nicely so that template constraints are much cleaner and more understandable (they'd be much, much uglier if such tests were inserted in them directly).
So, that's the normal approach for static duck typing in D. It does take a bit of practice to figure out how to write them well, but that's the standard way to do it, and it works. There have been people who have suggested trying to come up with something similar to your Implements!(S, Interface) suggestion, but nothing has really come of that of yet, and such an approach would actually be less flexible, making it ill-suited for a lot of traits (though it could certainly be made to work with basic ones). Regardless, the approach that I've described here is currently the standard way to do it.
Also, if you don't know much about ranges, I'd suggest reading this.
Implements!(S, Interface) is possible but did not get enough attention to get into standard library or get better language support. Probably if I won't be the only one telling it is the way to go for duck typing, we will have a chance to have it :)
Proof of concept implementation to tinker around:
http://dpaste.1azy.net/6d8f2dc4
import std.traits;
bool Implements(T, Interface)()
if (is(Interface == interface))
{
foreach (method; __traits(allMembers, Interface))
{
foreach (compareTo; MemberFunctionsTuple!(Interface, method))
{
bool found = false;
static if ( !hasMember!(T, method) )
{
pragma(msg, T, " has no member ", method);
return false;
}
else
{
foreach (compareWhat; __traits(getOverloads, T, method))
{
if (is(typeof(compareTo) == typeof(compareWhat)))
{
found = true;
break;
}
}
if (!found)
{
return false;
}
}
}
}
return true;
}
interface Test
{
bool foo(int, double);
void boo();
}
struct Tested
{
bool foo(int, double);
// void boo();
}
pragma(msg, Implements!(Tested, Test)());
void main()
{
}

Disseminating a token in Alloy

I'm following an example in Daniel Jackson's excellent book (Software Abstractions), specifically the example in which he has a token-ring setup in order to elect a leader.
I'm attempting to extend this example (Ring election) to ensure that the token, instead of being limited to one, is being passed around to all members within the provided time (and each member only being elected once, not multiple times). However (mostly due to my inexperience in Alloy), I'm having issues figuring out the best way. Initially I'd thought that I could play with some of the operators (changing -'s to +'s), but I don't seem to be quite hitting the nail on the head.
Below is the code from the example. I've marked up a few areas with questions...any and all help is appreciated. I'm using Alloy 4.2.
module chapter6/ringElection1 --- the version up to the top of page 181
open util/ordering[Time] as TO
open util/ordering[Process] as PO
sig Time {}
sig Process {
succ: Process,
toSend: Process -> Time,
elected: set Time
}
// ensure processes are in a ring
fact ring {
all p: Process | Process in p.^succ
}
pred init [t: Time] {
all p: Process | p.toSend.t = p
}
//QUESTION: I'd thought that within this predicate and the following fact, that I could
// change the logic from only having one election at a time to all being elected eventually.
// However, I can't seem to get the logic down for this portion.
pred step [t, t': Time, p: Process] {
let from = p.toSend, to = p.succ.toSend |
some id: from.t {
from.t' = from.t - id
to.t' = to.t + (id - p.succ.prevs)
}
}
fact defineElected {
no elected.first
all t: Time-first | elected.t = {p: Process | p in p.toSend.t - p.toSend.(t.prev)}
}
fact traces {
init [first]
all t: Time-last |
let t' = t.next |
all p: Process |
step [t, t', p] or step [t, t', succ.p] or skip [t, t', p]
}
pred skip [t, t': Time, p: Process] {
p.toSend.t = p.toSend.t'
}
pred show { some elected }
run show for 3 Process, 4 Time
// This generates an instance similar to Fig 6.4
//QUESTION: here I'm attempting to assert that ALL Processes have an election,
// however the 'all' keyword has been deprecated. Is there an appropriate command in
// Alloy 4.2 to take the place of this?
assert OnlyOneElected { all elected.Time }
check OnlyOneElected for 10 Process, 20 Time
This network protocol is exactly about how to elect a single process to be the leader, so I don't really understand the meaning of your idea of having "all processes elected eventually".
instead of all elected.Time, you can equivalently write elected.Time = Process (since the type of elected is Process -> Time). This just says that elected.Time (all processes elected at any time step) is exactly the set of all processes, which, obviously, doesn't mean that "only one process is elected", as suggested by the name of your assertion.

Resources