1queuelive

This file contains a simple liveness proof, also shown in figure 3 in the tool paper submission.

To verify this file, run:

$ ivy_check liveness.ivy
...
OK
include order

instance nat : unbounded_sequence

module signal(data) = {
    action raise(val:data)

    specification {
        relation now
        var value : data
        after init { now := false; }
        before raise {
            value := val;
            now := true;
            now := false;
        }
        invariant ~now
    }
}

type id

isolate bar = {

    action send(x:id)

    action recv

    specification {
        var head : nat
        var tail : nat
        var queue(X:nat) : id

        after init {
            head := 0;
            tail := 0;
        }

        instance sending : signal(id)
        instance receiving : signal(id)

        before send {
            queue(tail) := x;
            tail := tail.next;
            sending.raise(x);
        }

        before recv {
            require head < tail;
            call receiving.raise(queue(head));
            head := head.next;
        }

        temporal property
        forall X. ((globally eventually receiving.now)
                   & (eventually sending.now & sending.value = X) ->
                     (eventually receiving.now & receiving.value = X))
        proof {
            tactic skolemize;
            tactic l2s_auto with {
                definition work_created(X) = (X < tail)
                definition work_needed(X) = ~exists Y. Y < X & queue(Y) = _X
                definition work_done(X) = (X < head)
                definition work_start = (sending.now & sending.value = _X)
                definition work_progress = receiving.now
            }
            showgoals
        }
    }
} with nat

export bar.send
export bar.recv