From mathcomp.ssreflect
From mathcomp
From fcsl
From DiSeL
Set Implicit Arguments.
Unset Strict Implicit.
Unset Printing Implicit Defensive.
(* Shared state, as implemented by the message soup.  At this point, the implementation is based on top of standard union maps. This defines the procedure for allocating new messages: just by taking the next-to-the largest id in the corresponding batch. Indeed, this is not particularly nice, as it assumes the _global_ message soup.  It's not clear at this moment, what will be the best representation of the soup so it would be in the same time _local_ and also would allow for th allocation. Perhaps, we should just consider local soups, ensuring that they all carry distinct labels, and then when cojoin them, make sure that for clashing message id's protocol labels are different.  *)
Section TaggedMessages.
Structure TaggedMessage :=
TMsg {
tag: nat;
(* Okay, this is a big omissin, but for now I'm sick and tired to deal with casts everywhere, so for the moment the contents of the messages are going to be just sequences of natural number, and it's up to the client-supplied coherence predicate to restrict them appropriately, relating this thing to tags *)
tms_cont :> seq nat
}.
End TaggedMessages.
Section Shared.
Definition Label := [ordType of nat].
(* (Heterogenious) messages are parametrized by  - lab   - protocol Label - ptype - protocol, defining the content type - content  - the contents of the message - from/to  - IDs of the sender.receiver node - active - a bit, indicating whether the message hasn't been consumed yet (i.e., read)  I'm not sure, if we're going to need anything else. *)
Structure msg (mtype : Type) :=
Msg {content  : mtype;
from     : nat;
to       : nat;
active   : bool }.
(* Message IDs: pairs Label * id, where Label comes from the protocol. *)
Definition mid := [ordType of nat].
(* Message soup (for a specific protocol) is just a partial finite map from message IDs (mid) to arbitrary Messages. *)
Definition soup : Type :=
union_map mid (msg (TaggedMessage)).
Variables (s: soup) (V: valid s).
(* Allocating new message in the soup *)
Definition post_msg m : soup * mid :=
let: f := fresh s in (s \+ f \\-> m, f).

(* Specifications: *)
Lemma post_valid m :  valid (post_msg m).1.
Lemma mark_other m m' s' :
valid s' -> m' == m = false -> find m' (consume_msg s' m) = find m' s'.
Lemma consume_valid s' m : valid s' -> valid (consume_msg s' m).
Lemma consumeUn (s': soup) (i : mid) mm
(j : mid) : valid (s' \+ i \\-> mm) ->
consume_msg (s' \+ i \\-> mm) j =
if i == j then s' \+ i \\-> mark_msg mm
else (consume_msg s' j) \+ (i \\-> mm).