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          
      }.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          
      }.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          
      }.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          
      }.(* (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 }.(* (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 }.(* (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 }.(* (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 }.(* (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 }.(* (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 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)).(* Marking is  *)
  Definition mark_msg T (m : msg T) : msg T :=
    Msg (content m) (from m) (to m) false.Definition is_active (id : mid) :=
    exists m, find id s = Some m /\ active m.Definition is_consumed (id : mid) :=
    exists m, find id s = Some m /\ ~~ active m.

(* Specifications: *)
Lemma find_consume s' (id: mid) m: valid s' -> find id s' = Some m -> find id (consume_msg s' id) = Some (mark_msg m).
Lemma find_mark m s' msg : valid s' -> find m (consume_msg s' m) = Some msg -> exists msg', find m s' = Some msg' /\ msg = mark_msg msg'.
Lemma consume_valid s' m : valid s' -> valid (consume_msg s' m).