Definition Bag_of_Data := Site -> Site -> queue Data.(* This is taken straight from Jean's file *)

Definition Post_message (m0 : Message) (b0 : Bag_of_message)
  (s0 s1 : Site) :=
  change_queue (queue Message) b0 s0 s1 (input Message m0 (b0 s0 s1)).Definition Collect_message (b0 : Bag_of_message) (s0 s1 : Site) :=
  change_queue (queue Message) b0 s0 s1 (first_out Message (b0 s0 s1)).

(* Specifications: *)
Lemma post_here : forall (b0 : Bag_of_message) (m0 : Message) (s0 s1 : Site), Post_message m0 b0 s0 s1 s0 s1 = input Message m0 (b0 s0 s1).
Lemma post_elsewhere : forall (b0 : Bag_of_message) (m0 : Message) (s0 s1 s2 s3 : Site), s0 <> s2 \/ s1 <> s3 -> Post_message m0 b0 s0 s1 s2 s3 = b0 s2 s3.
Lemma collect_here : forall (b0 : Bag_of_message) (s0 s1 : Site), Collect_message b0 s0 s1 s0 s1 = first_out Message (b0 s0 s1).
Lemma collect_elsewhere : forall (b0 : Bag_of_message) (s0 s1 s2 s3 : Site), s0 <> s2 \/ s1 <> s3 -> Collect_message b0 s0 s1 s2 s3 = b0 s2 s3.
Lemma in_post : forall (m m' : Message) (bom : Bag_of_message) (s1 s2 s3 s4 : Site), m <> m' -> In_queue Message m (Post_message Message m' bom s1 s2 s3 s4) -> In_queue Message m (bom s3 s4).
Lemma not_in_post : forall (m m' : Message) (bom : Bag_of_message) (s1 s2 s3 s4 : Site), m <> m' -> ~ In_queue Message m (bom s3 s4) -> ~ In_queue Message m (Post_message Message m' bom s1 s2 s3 s4).
Lemma not_in_collect : forall (m : Message) (bom : Bag_of_message) (s1 s2 s3 s4 : Site), ~ In_queue Message m (bom s3 s4) -> ~ In_queue Message m (Collect_message Message bom s1 s2 s3 s4).
Lemma in_collect : forall (m : Message) (bom : Bag_of_message) (s1 s2 s3 s4 : Site), In_queue Message m (Collect_message Message bom s1 s2 s3 s4) -> In_queue Message m (bom s3 s4).
Lemma in_queue_decidable : forall (m : Message) (q : queue Message), {In_queue Message m q} + {~ In_queue Message m q}.
Lemma reduce_post_message : forall (m : Message) (s1 s2 : Site) (b : Bag_of_message), reduce Message f (Post_message Message m b s1 s2 s1 s2) = (reduce Message f (b s1 s2) + f m)%Z.
Lemma reduce_collect_message : forall (m : Message) (s1 s2 : Site) (b : Bag_of_message), first Message (b s1 s2) = value Message m -> reduce Message f (Collect_message Message b s1 s2 s1 s2) = (reduce Message f (b s1 s2) - f m)%Z.
Lemma reduce_post_message_null : forall (m : Message) (s1 s2 s3 s4 : Site) (b : Bag_of_message), f m = 0%Z -> reduce Message f (Post_message Message m b s1 s2 s3 s4) = reduce Message f (b s3 s4).
Lemma reduce_collect_message_null : forall (m : Message) (s1 s2 s3 s4 : Site) (b : Bag_of_message), first Message (b s1 s2) = value Message m -> f m = 0%Z -> reduce Message f (Collect_message Message b s1 s2 s3 s4) = reduce Message f (b s3 s4).