(* This program is free software; you can redistribute it and/or      *)
(* modify it under the terms of the GNU Lesser General Public License *)
(* as published by the Free Software Foundation; either version 2.1   *)
(* of the License, or (at your option) any later version.             *)
(*                                                                    *)
(* This program is distributed in the hope that it will be useful,    *)
(* but WITHOUT ANY WARRANTY; without even the implied warranty of     *)
(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      *)
(* GNU General Public License for more details.                       *)
(*                                                                    *)
(* You should have received a copy of the GNU Lesser General Public   *)
(* License along with this program; if not, write to the Free         *)
(* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *)
(* 02110-1301 USA                                                     *)


Require Import List.
Require Import DistributedReferenceCounting.machine2.invariant8.

Unset Standard Proposition Elimination Names.

(** 

Here, we study liveness of the algorithm.
We prove 

1. If there is a message in a queue, there always exists a transition
   that can consume that message.

2. We can define notion of measure and prove that every transition
   (except copy) decrease the mesure.
  
3. Then, the idea was to use the notion of well_found relation so
   a to prove that if we prevent copy transitions, we always reach
   a final configuration where no message can be processed.

   There was a bit of 'coding' to use these well-founded relations.
   
   I needed to talk about configuration which were legal.  So
   I defined a inductive type (a strong dependent sum), legal_config,
   which contains a configuration and a proof that it is legal.

   I then reached two problems, one easy to solve (I think), and
   more difficult.

   a.  I need to convert Z numbers into nat, and I don;t know
       how to do it.
      I had to assume the existence of the following axiom:
     Axiom Z_nat_axiom:
    (x,y:Z)  `0<=x` -> `0<=y` -> `y<x` -> (lt (convert_to_nat y) (convert_to_nat x)).

   b.  Well founded relations must be decidable:
      Definition decidable_relation:=
      [E:Set] [R:E->E->Prop] (x:E){y:E | (R y x)}+{((y:E)~(R y x))}.

     In order to prove that, I had to eliminate H in lemma decidable_no_copy_succ.

     H : (EX t:(class_trans c) | ~(copy_p c t)/\(legal (transition c t)))
          \/((t:(class_trans c))(copy_p c t))
 
     Unfortunately, H is a propositition and  and the Well founded
     relation is a set.  Therefore, we cannot perform an elimination.
  
     So I assumed I has axioms ex_rec and or_rec.  
     Why was legal defined as a Config->Prop and not a set?
     Why not do everything with set?


  BUT, HAVE I PROVED that all no_copy sequences terminate?

There are still more things to prove:
- what's happening when we introduce copy, can we say
  anything about infinite transitions?

*)




Lemma always_process_messages :
 forall c : Config,
 legal c ->
 forall (s1 s2 : Site) (m : Message),
 first Message (bm c s1 s2) = value Message m ->
 exists t : class_trans c,
   legal (transition c t) /\
   bm (transition c t) s1 s2 = first_out Message (bm c s1 s2).
Proof.
(* Goal: forall (c : Config) (_ : legal c) (s1 s2 : Site) (m : Message) (_ : @eq (exc Message) (first Message (bm c s1 s2)) (value Message m)), @ex (class_trans c) (fun t : class_trans c => and (legal (transition c t)) (@eq (queue Message) (bm (transition c t) s1 s2) (first_out Message (bm c s1 s2)))) *)
  intros c H.
(* Goal: forall _ : not (no_message (get_c (last_successor y0))), no_message (get_c (last_successor y0)) *)
  generalize H.
(* Goal: lt (convert_to_nat (termination_measure c)) (convert_to_nat (termination_measure c0)) *)
  elim H.
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
  simpl in |- *.
(* Goal: forall (_ : legal config_init) (s1 s2 : Site) (m : Message) (_ : @eq (exc Message) (error Message) (value Message m)), @ex (class_trans config_init) (fun t : class_trans config_init => and (legal (transition config_init t)) (@eq (queue Message) (bm (transition config_init t) s1 s2) (empty Message))) *)
(* Goal: forall (c : Config) (t : class_trans c) (_ : legal c) (_ : forall (_ : legal c) (s1 s2 : Site) (m : Message) (_ : @eq (exc Message) (first Message (bm c s1 s2)) (value Message m)), @ex (class_trans c) (fun t0 : class_trans c => and (legal (transition c t0)) (@eq (queue Message) (bm (transition c t0) s1 s2) (first_out Message (bm c s1 s2))))) (_ : legal (transition c t)) (s1 s2 : Site) (m : Message) (_ : @eq (exc Message) (first Message (bm (transition c t) s1 s2)) (value Message m)), @ex (class_trans (transition c t)) (fun t0 : class_trans (transition c t) => and (legal (transition (transition c t) t0)) (@eq (queue Message) (bm (transition (transition c t) t0) s1 s2) (first_out Message (bm (transition c t) s1 s2)))) *)
  intros; discriminate.
  
(* Goal: forall (c : Config) (t : class_trans c) (_ : legal c) (_ : forall (_ : legal c) (s1 s2 : Site) (m : Message) (_ : @eq (exc Message) (first Message (bm c s1 s2)) (value Message m)), @ex (class_trans c) (fun t0 : class_trans c => and (legal (transition c t0)) (@eq (queue Message) (bm (transition c t0) s1 s2) (first_out Message (bm c s1 s2))))) (_ : legal (transition c t)) (s1 s2 : Site) (m : Message) (_ : @eq (exc Message) (first Message (bm (transition c t) s1 s2)) (value Message m)), @ex (class_trans (transition c t)) (fun t0 : class_trans (transition c t) => and (legal (transition (transition c t) t0)) (@eq (queue Message) (bm (transition (transition c t) t0) s1 s2) (first_out Message (bm (transition c t) s1 s2)))) *)
  intros c0 t H0 H1 H2 s1 s2 m.
(* Goal: forall _ : @eq (exc Message) (first Message (bm (transition c0 t) s1 s2)) (value Message m), @ex (class_trans (transition c0 t)) (fun t0 : class_trans (transition c0 t) => and (legal (transition (transition c0 t) t0)) (@eq (queue Message) (bm (transition (transition c0 t) t0) s1 s2) (first_out Message (bm (transition c0 t) s1 s2)))) *)
  case m.
  
  (* dec *)
  
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  intro.
(* Goal: @ex (class_trans (transition c0 t)) (fun t0 : class_trans (transition c0 t) => and (legal (transition (transition c0 t) t0)) (@eq (queue Message) (bm (transition (transition c0 t) t0) s1 s2) (first_out Message (bm (transition c0 t) s1 s2)))) *)
(* Goal: forall (s : Site) (_ : @eq (exc Message) (first Message (bm (transition c0 t) s1 s2)) (value Message (inc_dec s))), @ex (class_trans (transition c0 t)) (fun t0 : class_trans (transition c0 t) => and (legal (transition (transition c0 t) t0)) (@eq (queue Message) (bm (transition (transition c0 t) t0) s1 s2) (first_out Message (bm (transition c0 t) s1 s2)))) *)
(* Goal: forall _ : @eq (exc Message) (first Message (bm (transition c0 t) s1 s2)) (value Message copy), @ex (class_trans (transition c0 t)) (fun t0 : class_trans (transition c0 t) => and (legal (transition (transition c0 t) t0)) (@eq (queue Message) (bm (transition (transition c0 t) t0) s1 s2) (first_out Message (bm (transition c0 t) s1 s2)))) *)
  split with (receive_dec (transition c0 t) s1 s2 H3).
(* Goal: and (@eq Config (transition c x3) (transition c x3)) (not (copy_p c x3)) *)
  split.
(* Goal: legal (transition c (delete_entry c x H3 H2 H1)) *)
(* Goal: or (@ex (class_trans c) (fun t : class_trans c => and (not (copy_p c t)) (legal (transition c t)))) (forall t : class_trans c, copy_p c t) *)
  apply after.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
  
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
  simpl in |- *.
(* Goal: Z.lt (Z.add (Z.add (sigma_but Site s2 eq_site_dec LS (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (termination_rt_count (Set_rec_table (rt c) s2 s2))) (Z.add (Z.add (sigma2_table Site LS LS (queue Message) (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s1 then if eq_site_dec s4 s2 then Z0 else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner)) (reduce Message termination_count (Collect_message Message (bm c) s1 s2 s1 s2))) (Z.add (reduce Message termination_count (bm c s2 owner)) (Zpos (xO xH))))) (Z.add (sigma Site LS (fun s : Site => termination_rt_count (rt c s))) (Z.add (Z.add (sigma2_table Site LS LS (queue Message) (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s1 then if eq_site_dec s4 s2 then Z0 else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (bm c)) (reduce Message termination_count (bm c s1 s2))) (reduce Message termination_count (bm c s2 owner)))) *)
(* Goal: or (not (@eq Site s2 s1)) (not (@eq Site owner s2)) *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: or (not (@eq Site s1 s2)) (not (@eq Site s2 owner)) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  rewrite collect_here.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
  
  (* inc_dec *)
  
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  case (eq_site_dec s2 owner); intro.
(* Goal: @ex (class_trans (transition c0 t)) (fun t0 : class_trans (transition c0 t) => and (legal (transition (transition c0 t) t0)) (@eq (queue Message) (bm (transition (transition c0 t) t0) s1 s2) (first_out Message (bm (transition c0 t) s1 s2)))) *)
(* Goal: forall _ : @eq (exc Message) (first Message (bm (transition c0 t) s1 s2)) (value Message copy), @ex (class_trans (transition c0 t)) (fun t0 : class_trans (transition c0 t) => and (legal (transition (transition c0 t) t0)) (@eq (queue Message) (bm (transition (transition c0 t) t0) s1 s2) (first_out Message (bm (transition c0 t) s1 s2)))) *)
(* Goal: forall _ : @eq (exc Message) (first Message (bm (transition c0 t) s1 s2)) (value Message copy), @ex (class_trans (transition c0 t)) (fun t0 : class_trans (transition c0 t) => and (legal (transition (transition c0 t) t0)) (@eq (queue Message) (bm (transition (transition c0 t) t0) s1 s2) (first_out Message (bm (transition c0 t) s1 s2)))) *)
  rewrite e in H3.
(* Goal: @ex (class_trans (transition c0 t)) (fun t0 : class_trans (transition c0 t) => and (legal (transition (transition c0 t) t0)) (@eq (queue Message) (bm (transition (transition c0 t) t0) s1 s2) (first_out Message (bm (transition c0 t) s1 s2)))) *)
(* Goal: @ex (class_trans (transition c0 t)) (fun t0 : class_trans (transition c0 t) => and (legal (transition (transition c0 t) t0)) (@eq (queue Message) (bm (transition (transition c0 t) t0) s1 s2) (first_out Message (bm (transition c0 t) s1 s2)))) *)
(* Goal: forall _ : @eq (exc Message) (first Message (bm (transition c0 t) s1 s2)) (value Message copy), @ex (class_trans (transition c0 t)) (fun t0 : class_trans (transition c0 t) => and (legal (transition (transition c0 t) t0)) (@eq (queue Message) (bm (transition (transition c0 t) t0) s1 s2) (first_out Message (bm (transition c0 t) s1 s2)))) *)
  split with (receive_inc (transition c0 t) s1 s H3).
(* Goal: and (@eq Config (transition c x3) (transition c x3)) (not (copy_p c x3)) *)
  split.
(* Goal: legal (transition c (delete_entry c x H3 H2 H1)) *)
(* Goal: or (@ex (class_trans c) (fun t : class_trans c => and (not (copy_p c t)) (legal (transition c t)))) (forall t : class_trans c, copy_p c t) *)
  apply after.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
  
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
  simpl in |- *.
(* Goal: forall _ : @eq (queue Message) (Post_message Message copy (bm c) s1 s2 x0 x1) (first_out Message (bm c x0 x1)), not True *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  rewrite post_elsewhere.
(* Goal: Z.lt (Z.add (Z.add (termination_rt_count true) (Z.sub (reduce Message termination_count (bm c s1 s2)) (termination_count copy))) (Z.add (reduce Message termination_count (bm c s2 owner)) (Zpos (xO xH)))) (Z.add (Z.add (termination_rt_count (rt c s2)) (reduce Message termination_count (bm c s1 s2))) (reduce Message termination_count (bm c s2 owner))) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: @eq (exc Message) (first Message (bm c s1 s2)) (value Message copy) *)
(* Goal: or (not (@eq Site s2 s1)) (not (@eq Site owner s2)) *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: or (not (@eq Site s1 s2)) (not (@eq Site s2 owner)) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  rewrite e.
(* Goal: Z.lt (Z.add (Z.add (sigma_but Site s2 eq_site_dec LS (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (termination_rt_count (Set_rec_table (rt c) s2 s2))) (Z.add (Z.add (sigma2_table Site LS LS (queue Message) (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s1 then if eq_site_dec s4 s2 then Z0 else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner)) (reduce Message termination_count (Collect_message Message (bm c) s1 s2 s1 s2))) (Z.add (reduce Message termination_count (bm c s2 owner)) (Zpos (xO xH))))) (Z.add (sigma Site LS (fun s : Site => termination_rt_count (rt c s))) (Z.add (Z.add (sigma2_table Site LS LS (queue Message) (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s1 then if eq_site_dec s4 s2 then Z0 else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (bm c)) (reduce Message termination_count (bm c s1 s2))) (reduce Message termination_count (bm c s2 owner)))) *)
(* Goal: or (not (@eq Site s2 s1)) (not (@eq Site owner s2)) *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: or (not (@eq Site s1 s2)) (not (@eq Site s2 owner)) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  rewrite collect_here.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
  
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  left; unfold not in |- *; intro.
(* Goal: False *)
(* Goal: @ex (class_trans (transition c0 t)) (fun t0 : class_trans (transition c0 t) => and (legal (transition (transition c0 t) t0)) (@eq (queue Message) (bm (transition (transition c0 t) t0) s1 s2) (first_out Message (bm (transition c0 t) s1 s2)))) *)
(* Goal: forall _ : @eq (exc Message) (first Message (bm (transition c0 t) s1 s2)) (value Message copy), @ex (class_trans (transition c0 t)) (fun t0 : class_trans (transition c0 t) => and (legal (transition (transition c0 t) t0)) (@eq (queue Message) (bm (transition (transition c0 t) t0) s1 s2) (first_out Message (bm (transition c0 t) s1 s2)))) *)
  generalize H3; rewrite H4; rewrite empty_q_to_me.
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
  simpl in |- *.
(* Goal: forall _ : @eq (exc Message) (error Message) (value Message copy), False *)
(* Goal: @In Site s1 LS *)
(* Goal: @In Site s2 LS *)
(* Goal: False *)
  intro; discriminate.
  
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
  
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  generalize (inc_dec_owner3 (transition c0 t) s1 s2 H2 n); intro.
(* Goal: @ex (class_trans (transition c0 t)) (fun t0 : class_trans (transition c0 t) => and (legal (transition (transition c0 t) t0)) (@eq (queue Message) (bm (transition (transition c0 t) t0) s1 s2) (first_out Message (bm (transition c0 t) s1 s2)))) *)
(* Goal: forall _ : @eq (exc Message) (first Message (bm (transition c0 t) s1 s2)) (value Message copy), @ex (class_trans (transition c0 t)) (fun t0 : class_trans (transition c0 t) => and (legal (transition (transition c0 t) t0)) (@eq (queue Message) (bm (transition (transition c0 t) t0) s1 s2) (first_out Message (bm (transition c0 t) s1 s2)))) *)
  elim (H4 s).
(* Goal: In_queue Message (inc_dec s) (bm (transition c0 t) s1 s2) *)
(* Goal: forall _ : @eq (exc Message) (first Message (bm (transition c0 t) s1 s2)) (value Message copy), @ex (class_trans (transition c0 t)) (fun t0 : class_trans (transition c0 t) => and (legal (transition (transition c0 t) t0)) (@eq (queue Message) (bm (transition (transition c0 t) t0) s1 s2) (first_out Message (bm (transition c0 t) s1 s2)))) *)
  apply first_in.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.

  (* copy *)
  
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  elim (decide_rt (transition c0 t) s2); intro.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  case (eq_site_dec s1 owner); intro.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  intro.
(* Goal: @ex (class_trans (transition c0 t)) (fun t0 : class_trans (transition c0 t) => and (legal (transition (transition c0 t) t0)) (@eq (queue Message) (bm (transition (transition c0 t) t0) s1 s2) (first_out Message (bm (transition c0 t) s1 s2)))) *)
(* Goal: forall _ : @eq (exc Message) (first Message (bm (transition c0 t) s1 s2)) (value Message copy), @ex (class_trans (transition c0 t)) (fun t0 : class_trans (transition c0 t) => and (legal (transition (transition c0 t) t0)) (@eq (queue Message) (bm (transition (transition c0 t) t0) s1 s2) (first_out Message (bm (transition c0 t) s1 s2)))) *)
(* Goal: forall _ : @eq (exc Message) (first Message (bm (transition c0 t) s1 s2)) (value Message copy), @ex (class_trans (transition c0 t)) (fun t0 : class_trans (transition c0 t) => and (legal (transition (transition c0 t) t0)) (@eq (queue Message) (bm (transition (transition c0 t) t0) s1 s2) (first_out Message (bm (transition c0 t) s1 s2)))) *)
  rewrite e in H3.
(* Goal: @ex (class_trans (transition c0 t)) (fun t0 : class_trans (transition c0 t) => and (legal (transition (transition c0 t) t0)) (@eq (queue Message) (bm (transition (transition c0 t) t0) s1 s2) (first_out Message (bm (transition c0 t) s1 s2)))) *)
(* Goal: forall _ : @eq (exc Message) (first Message (bm (transition c0 t) s1 s2)) (value Message copy), @ex (class_trans (transition c0 t)) (fun t0 : class_trans (transition c0 t) => and (legal (transition (transition c0 t) t0)) (@eq (queue Message) (bm (transition (transition c0 t) t0) s1 s2) (first_out Message (bm (transition c0 t) s1 s2)))) *)
(* Goal: forall _ : @eq (exc Message) (first Message (bm (transition c0 t) s1 s2)) (value Message copy), @ex (class_trans (transition c0 t)) (fun t0 : class_trans (transition c0 t) => and (legal (transition (transition c0 t) t0)) (@eq (queue Message) (bm (transition (transition c0 t) t0) s1 s2) (first_out Message (bm (transition c0 t) s1 s2)))) *)
  split with (receive_copy2 (transition c0 t) s2 a H3).
(* Goal: and (@eq Config (transition c x3) (transition c x3)) (not (copy_p c x3)) *)
  split.
(* Goal: legal (transition c (delete_entry c x H3 H2 H1)) *)
(* Goal: or (@ex (class_trans c) (fun t : class_trans c => and (not (copy_p c t)) (legal (transition c t)))) (forall t : class_trans c, copy_p c t) *)
  apply after.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
  
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
  simpl in |- *.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  rewrite e; rewrite collect_here; auto.
  
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  intro.
(* Goal: @ex (class_trans (transition c0 t)) (fun t0 : class_trans (transition c0 t) => and (legal (transition (transition c0 t) t0)) (@eq (queue Message) (bm (transition (transition c0 t) t0) s1 s2) (first_out Message (bm (transition c0 t) s1 s2)))) *)
(* Goal: forall _ : @eq (exc Message) (first Message (bm (transition c0 t) s1 s2)) (value Message copy), @ex (class_trans (transition c0 t)) (fun t0 : class_trans (transition c0 t) => and (legal (transition (transition c0 t) t0)) (@eq (queue Message) (bm (transition (transition c0 t) t0) s1 s2) (first_out Message (bm (transition c0 t) s1 s2)))) *)
  cut (s2 <> owner).
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  intro.
(* Goal: @ex (class_trans (transition c0 t)) (fun t0 : class_trans (transition c0 t) => and (legal (transition (transition c0 t) t0)) (@eq (queue Message) (bm (transition (transition c0 t) t0) s1 s2) (first_out Message (bm (transition c0 t) s1 s2)))) *)
(* Goal: not (@eq Site s2 owner) *)
(* Goal: forall _ : @eq (exc Message) (first Message (bm (transition c0 t) s1 s2)) (value Message copy), @ex (class_trans (transition c0 t)) (fun t0 : class_trans (transition c0 t) => and (legal (transition (transition c0 t) t0)) (@eq (queue Message) (bm (transition (transition c0 t) t0) s1 s2) (first_out Message (bm (transition c0 t) s1 s2)))) *)
  split with (receive_copy3 (transition c0 t) s1 s2 a n H4 H3).
(* Goal: and (@eq Config (transition c x3) (transition c x3)) (not (copy_p c x3)) *)
  split.
(* Goal: legal (transition c (delete_entry c x H3 H2 H1)) *)
(* Goal: or (@ex (class_trans c) (fun t : class_trans c => and (not (copy_p c t)) (legal (transition c t)))) (forall t : class_trans c, copy_p c t) *)
  apply after.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
  
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
  simpl in |- *.
(* Goal: forall _ : @eq (queue Message) (Post_message Message copy (bm c) s1 s2 x0 x1) (first_out Message (bm c x0 x1)), not True *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  rewrite post_elsewhere.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  rewrite collect_here; auto.
(* Goal: sumor (@sig legal_config (fun y : legal_config => no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) (forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) *)
(* Goal: forall _ : forall t : class_trans c, copy_p c t, sumor (@sig legal_config (fun y : legal_config => no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) (forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) *)
  left. (* (Left; Auto). *)
(* Goal: not (@eq Site s2 s1) *)
(* Goal: not (@eq Site s2 owner) *)
(* Goal: forall _ : @eq (exc Message) (first Message (bm (transition c0 t) s1 s2)) (value Message copy), @ex (class_trans (transition c0 t)) (fun t0 : class_trans (transition c0 t) => and (legal (transition (transition c0 t) t0)) (@eq (queue Message) (bm (transition (transition c0 t) t0) s1 s2) (first_out Message (bm (transition c0 t) s1 s2)))) *)
  unfold not in |- *; intro; generalize H3.
(* Goal: forall _ : @eq (exc Message) (first Message (bm (transition c0 t) s1 s2)) (value Message copy), False *)
(* Goal: not (@eq Site s2 owner) *)
(* Goal: forall _ : @eq (exc Message) (first Message (bm (transition c0 t) s1 s2)) (value Message copy), @ex (class_trans (transition c0 t)) (fun t0 : class_trans (transition c0 t) => and (legal (transition (transition c0 t) t0)) (@eq (queue Message) (bm (transition (transition c0 t) t0) s1 s2) (first_out Message (bm (transition c0 t) s1 s2)))) *)
  rewrite H5; rewrite empty_q_to_me.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  simpl in |- *; intro.
(* Goal: not (@eq (queue E) (input E d (empty E)) (empty E)) *)
(* Goal: forall (e : E) (q : queue E) (_ : forall (m : E) (_ : @eq (exc E) (first E (input E e q)) (value E m)), not (@eq (queue E) (input E e q) (first_out E (input E e q)))) (m : E) (_ : @eq (exc E) (first E (input E d (input E e q))) (value E m)), not (@eq (queue E) (input E d (input E e q)) (first_out E (input E d (input E e q)))) *)
  discriminate.
  
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
  
(* Goal: not (@eq Site s2 owner) *)
(* Goal: forall _ : @eq (exc Message) (first Message (bm (transition c0 t) s1 s2)) (value Message copy), @ex (class_trans (transition c0 t)) (fun t0 : class_trans (transition c0 t) => and (legal (transition (transition c0 t) t0)) (@eq (queue Message) (bm (transition (transition c0 t) t0) s1 s2) (first_out Message (bm (transition c0 t) s1 s2)))) *)
  unfold not in |- *; intro; generalize a.
(* Goal: forall _ : @eq bool (rt (transition c0 t) s2) false, False *)
(* Goal: forall _ : @eq (exc Message) (first Message (bm (transition c0 t) s1 s2)) (value Message copy), @ex (class_trans (transition c0 t)) (fun t0 : class_trans (transition c0 t) => and (legal (transition (transition c0 t) t0)) (@eq (queue Message) (bm (transition (transition c0 t) t0) s1 s2) (first_out Message (bm (transition c0 t) s1 s2)))) *)
  rewrite H4; rewrite owner_rt_true.
(* Goal: forall _ : @eq bool true false, False *)
(* Goal: legal (transition c0 t) *)
(* Goal: forall _ : @eq (exc Message) (first Message (bm (transition c0 t) s1 s2)) (value Message copy), @ex (class_trans (transition c0 t)) (fun t0 : class_trans (transition c0 t) => and (legal (transition (transition c0 t) t0)) (@eq (queue Message) (bm (transition (transition c0 t) t0) s1 s2) (first_out Message (bm (transition c0 t) s1 s2)))) *)
  auto with bool.
  
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
  
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  intro.
(* Goal: @ex (class_trans (transition c0 t)) (fun t0 : class_trans (transition c0 t) => and (legal (transition (transition c0 t) t0)) (@eq (queue Message) (bm (transition (transition c0 t) t0) s1 s2) (first_out Message (bm (transition c0 t) s1 s2)))) *)
  split with (receive_copy1 (transition c0 t) s1 s2 b H3).
(* Goal: and (@eq Config (transition c x3) (transition c x3)) (not (copy_p c x3)) *)
  split.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  apply after; auto.
  
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
  simpl in |- *.
(* Goal: forall _ : @eq (queue Message) (Post_message Message copy (bm c) s1 s2 x0 x1) (first_out Message (bm c x0 x1)), not True *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  rewrite post_elsewhere.
(* Goal: Z.lt (Z.add (Z.add (sigma_but Site s2 eq_site_dec LS (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (termination_rt_count (Set_rec_table (rt c) s2 s2))) (Z.add (Z.add (sigma2_table Site LS LS (queue Message) (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s1 then if eq_site_dec s4 s2 then Z0 else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner)) (reduce Message termination_count (Collect_message Message (bm c) s1 s2 s1 s2))) (Z.add (reduce Message termination_count (bm c s2 owner)) (Zpos (xO xH))))) (Z.add (sigma Site LS (fun s : Site => termination_rt_count (rt c s))) (Z.add (Z.add (sigma2_table Site LS LS (queue Message) (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s1 then if eq_site_dec s4 s2 then Z0 else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (bm c)) (reduce Message termination_count (bm c s1 s2))) (reduce Message termination_count (bm c s2 owner)))) *)
(* Goal: or (not (@eq Site s2 s1)) (not (@eq Site owner s2)) *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: or (not (@eq Site s1 s2)) (not (@eq Site s2 owner)) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  rewrite collect_here.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
  
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  case (eq_site_dec s1 s2); intro.
(* Goal: or (not (@eq Site s2 s1)) (not (@eq Site s1 s2)) *)
(* Goal: or (not (@eq Site s2 s1)) (not (@eq Site s1 s2)) *)
  generalize H3; rewrite e; rewrite empty_q_to_me.
(* Goal: forall _ : @eq (exc Message) (error Message) (value Message copy), False *)
(* Goal: @In Site s1 LS *)
(* Goal: @In Site s2 LS *)
(* Goal: False *)
  simpl in |- *; intro; discriminate.
  
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
  
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
Qed.

(* copy predicate *)

Definition copy_p (c : Config) (t : class_trans c) :=
  match t with
  | make_copy s1 s2 h1 h2 => True
  | _ => False
  end.


Section LEGAL_NO_COPY.

(** this inductive definition defines legal_no_copy
   as a predicate over a configuration c, which is accessible
   with legal transitions from a legal config c0,
   without using any copy transition *)

Variable c0 : Config.



Inductive legal_no_copy : Config -> Prop :=
  | no_copy_init : legal c0 -> legal_no_copy c0
  | after_no_copy :
      forall (c : Config) (t : class_trans c),
      ~ copy_p c t -> legal_no_copy c -> legal_no_copy (transition c t).

End LEGAL_NO_COPY.


Lemma legal_no_copy_is_legal :
 forall c c0 : Config, legal_no_copy c0 c -> legal c.
Proof.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: lt (convert_to_nat (termination_measure c)) (convert_to_nat (termination_measure c0)) *)
  elim H.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: legal (transition c (delete_entry c x H3 H2 H1)) *)
(* Goal: or (@ex (class_trans c) (fun t : class_trans c => and (not (copy_p c t)) (legal (transition c t)))) (forall t : class_trans c, copy_p c t) *)
  apply after.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
Qed.


Lemma decide_empty_queue :
 forall (c : Config) (s1 s2 : Site),
 {bm c s1 s2 = empty Message} + {bm c s1 s2 <> empty Message}.
Proof.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: sumbool (@eq (queue Message) (bm c s1 s2) (empty Message)) (not (@eq (queue Message) (bm c s1 s2) (empty Message))) *)
  elim (bm c s1 s2).
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  left; auto.
  
(* Goal: forall (d : Message) (q : queue Message) (_ : sumbool (@eq (queue Message) q (empty Message)) (not (@eq (queue Message) q (empty Message)))), sumbool (@eq (queue Message) (input Message d q) (empty Message)) (not (@eq (queue Message) (input Message d q) (empty Message))) *)
  simpl in |- *; right.
(* Goal: not (@eq (queue E) (input E d (empty E)) (empty E)) *)
(* Goal: forall (e : E) (q : queue E) (_ : forall (m : E) (_ : @eq (exc E) (first E (input E e q)) (value E m)), not (@eq (queue E) (input E e q) (first_out E (input E e q)))) (m : E) (_ : @eq (exc E) (first E (input E d (input E e q))) (value E m)), not (@eq (queue E) (input E d (input E e q)) (first_out E (input E d (input E e q)))) *)
  discriminate.
Qed.


Definition no_message (c : Config) :=
  forall s1 s2 : Site, In s1 LS -> In s2 LS -> bm c s1 s2 = empty Message.

Lemma decide_no_message :
 forall c : Config, {no_message c} + {~ no_message c}.
Proof.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: forall (c : Config) (_ : legal c) (_ : not (no_message c)), @ex Site (fun s1 : Site => @ex Site (fun s2 : Site => and (not (@eq Site s1 s2)) (not (@eq (queue Message) (bm c s1 s2) (empty Message))))) *)
  unfold no_message in |- *.
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
  simpl in |- *.
(* Goal: sumbool (forall (s1 s2 : Site) (_ : @In Site s1 LS) (_ : @In Site s2 LS), @eq (queue Message) (bm c s1 s2) (empty Message)) (not (forall (s1 s2 : Site) (_ : @In Site s1 LS) (_ : @In Site s2 LS), @eq (queue Message) (bm c s1 s2) (empty Message))) *)
  pattern LS at 1 3 in |- *.
(* Goal: sumbool (forall (s1 : Site) (_ : @In Site s1 LS) (_ : not (@eq Site s1 owner)), @eq bool (rt c s1) false) (@ex Site (fun s1 : Site => and (not (@eq Site s1 owner)) (@eq bool (rt c s1) true))) *)
  elim LS.
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
  simpl in |- *.
(* Goal: sumbool (forall (s2 : Site) (_ : False), @eq (queue Message) (bm c a s2) (empty Message)) (not (forall (s2 : Site) (_ : False) (_ : not (@eq Site s2 a)), @eq (queue Message) (bm c a s2) (empty Message))) *)
(* Goal: forall (a0 : Site) (l : list Site) (_ : sumbool (forall (s2 : Site) (_ : @In Site s2 l), @eq (queue Message) (bm c a s2) (empty Message)) (not (forall (s2 : Site) (_ : @In Site s2 l) (_ : not (@eq Site s2 a)), @eq (queue Message) (bm c a s2) (empty Message)))), sumbool (forall (s2 : Site) (_ : @In Site s2 (@cons Site a0 l)), @eq (queue Message) (bm c a s2) (empty Message)) (not (forall (s2 : Site) (_ : @In Site s2 (@cons Site a0 l)) (_ : not (@eq Site s2 a)), @eq (queue Message) (bm c a s2) (empty Message))) *)
  left; intros; contradiction.
  
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
  simpl in |- *.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: lt (convert_to_nat (termination_measure c)) (convert_to_nat (termination_measure c0)) *)
  elim H.
(* Goal: forall (a0 : Site) (l : list Site) (_ : forall _ : not (forall (s2 : Site) (_ : @In Site s2 l) (_ : not (@eq Site s2 a)), @eq (queue Message) (bm c a s2) (empty Message)), @ex Site (fun s2 : Site => and (not (@eq Site a s2)) (not (@eq (queue Message) (bm c a s2) (empty Message))))) (_ : not (forall (s2 : Site) (_ : @In Site s2 (@cons Site a0 l)) (_ : not (@eq Site s2 a)), @eq (queue Message) (bm c a s2) (empty Message))), @ex Site (fun s2 : Site => and (not (@eq Site a s2)) (not (@eq (queue Message) (bm c a s2) (empty Message)))) *)
  clear H.
(* Goal: sumbool (forall (s1 : Site) (_ : @In Site s1 LS) (_ : not (@eq Site s1 owner)), @eq bool (rt c s1) false) (@ex Site (fun s1 : Site => and (not (@eq Site s1 owner)) (@eq bool (rt c s1) true))) *)
  elim LS.
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
  simpl in |- *.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  intro.
(* Goal: sumor (@sig legal_config (fun y : legal_config => no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) (forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) *)
(* Goal: forall _ : forall t : class_trans c, copy_p c t, sumor (@sig legal_config (fun y : legal_config => no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) (forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) *)
  left.
(* Goal: forall (s1 s2 : Site) (_ : False) (_ : @In Site s2 LS), @eq (queue Message) (bm c s1 s2) (empty Message) *)
(* Goal: forall (a : Site) (l : list Site) (_ : forall (_ : legal c) (_ : not (forall (s1 s2 : Site) (_ : @In Site s1 l) (_ : @In Site s2 LS), @eq (queue Message) (bm c s1 s2) (empty Message))), @ex Site (fun s1 : Site => @ex Site (fun s2 : Site => and (not (@eq Site s1 s2)) (not (@eq (queue Message) (bm c s1 s2) (empty Message)))))) (_ : legal c) (_ : not (forall (s1 s2 : Site) (_ : @In Site s1 (@cons Site a l)) (_ : @In Site s2 LS), @eq (queue Message) (bm c s1 s2) (empty Message))), @ex Site (fun s1 : Site => @ex Site (fun s2 : Site => and (not (@eq Site s1 s2)) (not (@eq (queue Message) (bm c s1 s2) (empty Message))))) *)
  intros; contradiction.
  
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: lt (convert_to_nat (termination_measure c)) (convert_to_nat (termination_measure c0)) *)
  elim H.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  elim (decide_empty_queue c a a0); intro.
(* Goal: sumor (@sig legal_config (fun y : legal_config => no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) (forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) *)
(* Goal: forall _ : forall t : class_trans c, copy_p c t, sumor (@sig legal_config (fun y : legal_config => no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) (forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) *)
  left.
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
  simpl in |- *.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  elim H0; intro.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  elim H1; intro.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  rewrite <- H2; rewrite <- H3; auto.
  
(* Goal: @eq (queue Message) (bm c a s2) (empty Message) *)
(* Goal: sumbool (forall (s2 : Site) (_ : or (@eq Site a0 s2) (@In Site s2 l)), @eq (queue Message) (bm c a s2) (empty Message)) (not (forall (s2 : Site) (_ : or (@eq Site a0 s2) (@In Site s2 l)) (_ : not (@eq Site s2 a)), @eq (queue Message) (bm c a s2) (empty Message))) *)
(* Goal: sumbool (forall (s2 : Site) (_ : or (@eq Site a0 s2) (@In Site s2 l)), @eq (queue Message) (bm c a s2) (empty Message)) (not (forall (s2 : Site) (_ : or (@eq Site a0 s2) (@In Site s2 l)) (_ : not (@eq Site s2 a)), @eq (queue Message) (bm c a s2) (empty Message))) *)
(* Goal: sumbool (forall (s2 : Site) (_ : or (@eq Site a0 s2) (@In Site s2 l)), @eq (queue Message) (bm c a s2) (empty Message)) (not (forall (s2 : Site) (_ : or (@eq Site a0 s2) (@In Site s2 l)) (_ : not (@eq Site s2 a)), @eq (queue Message) (bm c a s2) (empty Message))) *)
  apply a2.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
  
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
  
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  elim H1; intro.
(* Goal: @eq bool (rt c s1) false *)
(* Goal: sumbool (forall (s1 : Site) (_ : @In Site s1 (@cons Site a l)) (_ : not (@eq Site s1 owner)), @eq bool (rt c s1) false) (@ex Site (fun s1 : Site => and (not (@eq Site s1 owner)) (@eq bool (rt c s1) true))) *)
(* Goal: sumbool (forall (s1 : Site) (_ : @In Site s1 (@cons Site a l)) (_ : not (@eq Site s1 owner)), @eq bool (rt c s1) false) (@ex Site (fun s1 : Site => and (not (@eq Site s1 owner)) (@eq bool (rt c s1) true))) *)
  apply a1.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
  
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
  simpl in |- *.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
  
(* Goal: @eq (queue Message) (bm c a s2) (empty Message) *)
(* Goal: sumbool (forall (s2 : Site) (_ : or (@eq Site a0 s2) (@In Site s2 l)), @eq (queue Message) (bm c a s2) (empty Message)) (not (forall (s2 : Site) (_ : or (@eq Site a0 s2) (@In Site s2 l)) (_ : not (@eq Site s2 a)), @eq (queue Message) (bm c a s2) (empty Message))) *)
(* Goal: sumbool (forall (s2 : Site) (_ : or (@eq Site a0 s2) (@In Site s2 l)), @eq (queue Message) (bm c a s2) (empty Message)) (not (forall (s2 : Site) (_ : or (@eq Site a0 s2) (@In Site s2 l)) (_ : not (@eq Site s2 a)), @eq (queue Message) (bm c a s2) (empty Message))) *)
(* Goal: sumbool (forall (s2 : Site) (_ : or (@eq Site a0 s2) (@In Site s2 l)), @eq (queue Message) (bm c a s2) (empty Message)) (not (forall (s2 : Site) (_ : or (@eq Site a0 s2) (@In Site s2 l)) (_ : not (@eq Site s2 a)), @eq (queue Message) (bm c a s2) (empty Message))) *)
  apply a2.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
  
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
  
(* Goal: sumor (@sig legal_config (fun y : legal_config => no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) (forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) *)
  right.
(* Goal: @eq (queue Message) (bm c a s2) (empty Message) *)
(* Goal: sumbool (forall (s2 : Site) (_ : or (@eq Site a0 s2) (@In Site s2 l)), @eq (queue Message) (bm c a s2) (empty Message)) (not (forall (s2 : Site) (_ : or (@eq Site a0 s2) (@In Site s2 l)) (_ : not (@eq Site s2 a)), @eq (queue Message) (bm c a s2) (empty Message))) *)
  unfold not in |- *.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  intro.
(* Goal: False *)
(* Goal: forall _ : not (forall (s1 s2 : Site) (_ : or (@eq Site a s1) (@In Site s1 l)) (_ : @In Site s2 l0), @eq (queue Message) (bm c s1 s2) (empty Message)), sumbool (forall (s1 s2 : Site) (_ : or (@eq Site a s1) (@In Site s1 l)) (_ : @In Site s2 (@cons Site a0 l0)), @eq (queue Message) (bm c s1 s2) (empty Message)) (not (forall (s1 s2 : Site) (_ : or (@eq Site a s1) (@In Site s1 l)) (_ : @In Site s2 (@cons Site a0 l0)), @eq (queue Message) (bm c s1 s2) (empty Message))) *)
(* Goal: forall (s1 s2 : Site) (_ : @In Site s1 l) (_ : @In Site s2 l0), @eq (queue Message) (bm c s1 s2) (empty Message) *)
(* Goal: forall _ : not (forall (s1 s2 : Site) (_ : @In Site s1 l) (_ : @In Site s2 LS), @eq (queue Message) (bm c s1 s2) (empty Message)), sumbool (forall (s1 s2 : Site) (_ : or (@eq Site a s1) (@In Site s1 l)) (_ : @In Site s2 LS), @eq (queue Message) (bm c s1 s2) (empty Message)) (not (forall (s1 s2 : Site) (_ : or (@eq Site a s1) (@In Site s1 l)) (_ : @In Site s2 LS), @eq (queue Message) (bm c s1 s2) (empty Message))) *)
  generalize (H0 a a0).
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  intro.
(* Goal: or (@ex (class_trans c) (fun t : class_trans c => and (not (copy_p c t)) (legal (transition c t)))) (forall t : class_trans c, copy_p c t) *)
(* Goal: or (@ex (class_trans c) (fun t : class_trans c => and (not (copy_p c t)) (legal (transition c t)))) (forall t : class_trans c, copy_p c t) *)
  elim b.
(* Goal: @eq (queue Message) (bm c s1 s2) (empty Message) *)
(* Goal: forall _ : not (forall (s1 s2 : Site) (_ : or (@eq Site a s1) (@In Site s1 l)) (_ : @In Site s2 LS), @eq (queue Message) (bm c s1 s2) (empty Message)), @ex Site (fun s1 : Site => @ex Site (fun s2 : Site => and (not (@eq Site s1 s2)) (not (@eq (queue Message) (bm c s1 s2) (empty Message))))) *)
  apply H1.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
  
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  simpl in |- *; auto.
  
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  intro.
(* Goal: sumor (@sig legal_config (fun y : legal_config => no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) (forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) *)
  right.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  unfold not in |- *; intro.
(* Goal: or (@ex (class_trans c) (fun t : class_trans c => and (not (copy_p c t)) (legal (transition c t)))) (forall t : class_trans c, copy_p c t) *)
(* Goal: or (@ex (class_trans c) (fun t : class_trans c => and (not (copy_p c t)) (legal (transition c t)))) (forall t : class_trans c, copy_p c t) *)
  elim b.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: @eq (queue Message) (bm c a s2) (empty Message) *)
(* Goal: @ex Site (fun s2 : Site => and (not (@eq Site a s2)) (not (@eq (queue Message) (bm c a s2) (empty Message)))) *)
  apply H0.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
  
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  simpl in |- *; auto.
  
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: @eq bool (rt c s1) false *)
(* Goal: sumbool (forall (s1 : Site) (_ : @In Site s1 (@cons Site a l)) (_ : not (@eq Site s1 owner)), @eq bool (rt c s1) false) (@ex Site (fun s1 : Site => and (not (@eq Site s1 owner)) (@eq bool (rt c s1) true))) *)
(* Goal: sumbool (forall (s1 : Site) (_ : @In Site s1 (@cons Site a l)) (_ : not (@eq Site s1 owner)), @eq bool (rt c s1) false) (@ex Site (fun s1 : Site => and (not (@eq Site s1 owner)) (@eq bool (rt c s1) true))) *)
  apply a1.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
  
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  simpl in |- *; auto.
  
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  intro.
(* Goal: sumor (@sig legal_config (fun y : legal_config => no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) (forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) *)
  right.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  unfold not in |- *; intro.
(* Goal: or (@ex (class_trans c) (fun t : class_trans c => and (not (copy_p c t)) (legal (transition c t)))) (forall t : class_trans c, copy_p c t) *)
(* Goal: or (@ex (class_trans c) (fun t : class_trans c => and (not (copy_p c t)) (legal (transition c t)))) (forall t : class_trans c, copy_p c t) *)
  elim b.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: @eq (queue Message) (bm c a s2) (empty Message) *)
(* Goal: @ex Site (fun s2 : Site => and (not (@eq Site a s2)) (not (@eq (queue Message) (bm c a s2) (empty Message)))) *)
  apply H0.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
  
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
Qed.

Lemma decide_exist_non_empty_queue1 :
 forall (c : Config) (a : Site),
 legal c ->
 {(forall s2 : Site, In s2 LS -> bm c a s2 = empty Message)} +
 {~ (forall s2 : Site, In s2 LS -> s2 <> a -> bm c a s2 = empty Message)}.
Proof.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: sumbool (forall (s1 : Site) (_ : @In Site s1 LS) (_ : not (@eq Site s1 owner)), @eq bool (rt c s1) false) (@ex Site (fun s1 : Site => and (not (@eq Site s1 owner)) (@eq bool (rt c s1) true))) *)
  elim LS.
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
  simpl in |- *.
(* Goal: sumbool (forall (s2 : Site) (_ : False), @eq (queue Message) (bm c a s2) (empty Message)) (not (forall (s2 : Site) (_ : False) (_ : not (@eq Site s2 a)), @eq (queue Message) (bm c a s2) (empty Message))) *)
(* Goal: forall (a0 : Site) (l : list Site) (_ : sumbool (forall (s2 : Site) (_ : @In Site s2 l), @eq (queue Message) (bm c a s2) (empty Message)) (not (forall (s2 : Site) (_ : @In Site s2 l) (_ : not (@eq Site s2 a)), @eq (queue Message) (bm c a s2) (empty Message)))), sumbool (forall (s2 : Site) (_ : @In Site s2 (@cons Site a0 l)), @eq (queue Message) (bm c a s2) (empty Message)) (not (forall (s2 : Site) (_ : @In Site s2 (@cons Site a0 l)) (_ : not (@eq Site s2 a)), @eq (queue Message) (bm c a s2) (empty Message))) *)
  left; intros; contradiction.
  
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
  simpl in |- *.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  elim (decide_empty_queue c a a0); intro.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  case (eq_site_dec a a0); intro.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  elim H0; intro.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  left; intros.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  elim H1; intros.
(* Goal: @eq (queue Message) (bm c a s2) (empty Message) *)
(* Goal: @eq (queue Message) (bm c a s2) (empty Message) *)
(* Goal: sumbool (forall (s2 : Site) (_ : or (@eq Site a0 s2) (@In Site s2 l)), @eq (queue Message) (bm c a s2) (empty Message)) (not (forall (s2 : Site) (_ : or (@eq Site a0 s2) (@In Site s2 l)) (_ : not (@eq Site s2 a)), @eq (queue Message) (bm c a s2) (empty Message))) *)
(* Goal: sumbool (forall (s2 : Site) (_ : or (@eq Site a0 s2) (@In Site s2 l)), @eq (queue Message) (bm c a s2) (empty Message)) (not (forall (s2 : Site) (_ : or (@eq Site a0 s2) (@In Site s2 l)) (_ : not (@eq Site s2 a)), @eq (queue Message) (bm c a s2) (empty Message))) *)
(* Goal: sumbool (forall (s2 : Site) (_ : or (@eq Site a0 s2) (@In Site s2 l)), @eq (queue Message) (bm c a s2) (empty Message)) (not (forall (s2 : Site) (_ : or (@eq Site a0 s2) (@In Site s2 l)) (_ : not (@eq Site s2 a)), @eq (queue Message) (bm c a s2) (empty Message))) *)
  rewrite <- H2.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
  
(* Goal: @eq (queue Message) (bm c a s2) (empty Message) *)
(* Goal: sumbool (forall (s2 : Site) (_ : or (@eq Site a0 s2) (@In Site s2 l)), @eq (queue Message) (bm c a s2) (empty Message)) (not (forall (s2 : Site) (_ : or (@eq Site a0 s2) (@In Site s2 l)) (_ : not (@eq Site s2 a)), @eq (queue Message) (bm c a s2) (empty Message))) *)
(* Goal: sumbool (forall (s2 : Site) (_ : or (@eq Site a0 s2) (@In Site s2 l)), @eq (queue Message) (bm c a s2) (empty Message)) (not (forall (s2 : Site) (_ : or (@eq Site a0 s2) (@In Site s2 l)) (_ : not (@eq Site s2 a)), @eq (queue Message) (bm c a s2) (empty Message))) *)
(* Goal: sumbool (forall (s2 : Site) (_ : or (@eq Site a0 s2) (@In Site s2 l)), @eq (queue Message) (bm c a s2) (empty Message)) (not (forall (s2 : Site) (_ : or (@eq Site a0 s2) (@In Site s2 l)) (_ : not (@eq Site s2 a)), @eq (queue Message) (bm c a s2) (empty Message))) *)
  apply a2.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
  
(* Goal: sumor (@sig legal_config (fun y : legal_config => no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) (forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) *)
  right.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  unfold not in |- *; intros.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  elim b; intros.
(* Goal: @eq (queue Message) (bm c a s2) (empty Message) *)
(* Goal: sumbool (forall (s2 : Site) (_ : or (@eq Site a0 s2) (@In Site s2 l)), @eq (queue Message) (bm c a s2) (empty Message)) (not (forall (s2 : Site) (_ : or (@eq Site a0 s2) (@In Site s2 l)) (_ : not (@eq Site s2 a)), @eq (queue Message) (bm c a s2) (empty Message))) *)
  unfold not in |- *.
(* Goal: @eq (queue Message) (bm c s1 s2) (empty Message) *)
(* Goal: forall _ : not (forall (s1 s2 : Site) (_ : or (@eq Site a s1) (@In Site s1 l)) (_ : @In Site s2 LS), @eq (queue Message) (bm c s1 s2) (empty Message)), @ex Site (fun s1 : Site => @ex Site (fun s2 : Site => and (not (@eq Site s1 s2)) (not (@eq (queue Message) (bm c s1 s2) (empty Message))))) *)
  apply H1.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
  
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  intro.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  elim H3; auto.
  
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  elim H0; intros.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  left; intros.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  case (eq_site_dec s2 a0); intro.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  rewrite e; auto.
  
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  elim H1; intro.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  elim n0; auto.
  
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  apply a2; auto.
  
(* Goal: sumor (@sig legal_config (fun y : legal_config => no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) (forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) *)
  right.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  unfold not in |- *; intros.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  elim b; intros.
(* Goal: @eq (queue Message) (bm c a s2) (empty Message) *)
(* Goal: sumbool (forall (s2 : Site) (_ : or (@eq Site a0 s2) (@In Site s2 l)), @eq (queue Message) (bm c a s2) (empty Message)) (not (forall (s2 : Site) (_ : or (@eq Site a0 s2) (@In Site s2 l)) (_ : not (@eq Site s2 a)), @eq (queue Message) (bm c a s2) (empty Message))) *)
  unfold not in |- *.
(* Goal: @eq (queue Message) (bm c s1 s2) (empty Message) *)
(* Goal: forall _ : not (forall (s1 s2 : Site) (_ : or (@eq Site a s1) (@In Site s1 l)) (_ : @In Site s2 LS), @eq (queue Message) (bm c s1 s2) (empty Message)), @ex Site (fun s1 : Site => @ex Site (fun s2 : Site => and (not (@eq Site s1 s2)) (not (@eq (queue Message) (bm c s1 s2) (empty Message))))) *)
  apply H1.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
  
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intro; elim H3; auto.
  
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  elim H0; intros.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  case (eq_site_dec a a0); intro.
(* Goal: or (@ex (class_trans c) (fun t : class_trans c => and (not (copy_p c t)) (legal (transition c t)))) (forall t : class_trans c, copy_p c t) *)
(* Goal: or (@ex (class_trans c) (fun t : class_trans c => and (not (copy_p c t)) (legal (transition c t)))) (forall t : class_trans c, copy_p c t) *)
  elim b.
(* Goal: Z.lt (Z.add (Z.add (termination_rt_count true) (Z.sub (reduce Message termination_count (bm c s1 s2)) (termination_count copy))) (Z.add (reduce Message termination_count (bm c s2 owner)) (Zpos (xO xH)))) (Z.add (Z.add (termination_rt_count (rt c s2)) (reduce Message termination_count (bm c s1 s2))) (reduce Message termination_count (bm c s2 owner))) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: @eq (exc Message) (first Message (bm c s1 s2)) (value Message copy) *)
(* Goal: or (not (@eq Site s2 s1)) (not (@eq Site owner s2)) *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: or (not (@eq Site s1 s2)) (not (@eq Site s2 owner)) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  rewrite e.
(* Goal: @eq (queue Message) (bm c a0 a0) (empty Message) *)
(* Goal: sumbool (forall (s2 : Site) (_ : or (@eq Site a0 s2) (@In Site s2 l)), @eq (queue Message) (bm c a s2) (empty Message)) (not (forall (s2 : Site) (_ : or (@eq Site a0 s2) (@In Site s2 l)) (_ : not (@eq Site s2 a)), @eq (queue Message) (bm c a s2) (empty Message))) *)
(* Goal: sumbool (forall (s2 : Site) (_ : or (@eq Site a0 s2) (@In Site s2 l)), @eq (queue Message) (bm c a s2) (empty Message)) (not (forall (s2 : Site) (_ : or (@eq Site a0 s2) (@In Site s2 l)) (_ : not (@eq Site s2 a)), @eq (queue Message) (bm c a s2) (empty Message))) *)
  rewrite empty_q_to_me.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
  
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
  
(* Goal: sumor (@sig legal_config (fun y : legal_config => no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) (forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) *)
  right.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  unfold not in |- *; intros.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  generalize (H1 a0); intro.
(* Goal: False *)
(* Goal: sumbool (forall (s2 : Site) (_ : or (@eq Site a0 s2) (@In Site s2 l)), @eq (queue Message) (bm c a s2) (empty Message)) (not (forall (s2 : Site) (_ : or (@eq Site a0 s2) (@In Site s2 l)) (_ : not (@eq Site s2 a)), @eq (queue Message) (bm c a s2) (empty Message))) *)
  cut (a0 = a0 \/ In a0 l).
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  intro.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  generalize (H2 H3); intro.
(* Goal: False *)
(* Goal: or (@eq Site a0 a0) (@In Site a0 l) *)
(* Goal: sumbool (forall (s2 : Site) (_ : or (@eq Site a0 s2) (@In Site s2 l)), @eq (queue Message) (bm c a s2) (empty Message)) (not (forall (s2 : Site) (_ : or (@eq Site a0 s2) (@In Site s2 l)) (_ : not (@eq Site s2 a)), @eq (queue Message) (bm c a s2) (empty Message))) *)
  decompose [and] H4.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  elim b; auto.
  
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
  
(* Goal: sumor (@sig legal_config (fun y : legal_config => no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) (forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) *)
  right.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  unfold not in |- *; intro.
(* Goal: False *)
  elim b0.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  unfold not in |- *; intros.
(* Goal: @eq (queue Message) (bm c s1 s2) (empty Message) *)
(* Goal: forall _ : not (forall (s1 s2 : Site) (_ : or (@eq Site a s1) (@In Site s1 l)) (_ : @In Site s2 LS), @eq (queue Message) (bm c s1 s2) (empty Message)), @ex Site (fun s1 : Site => @ex Site (fun s2 : Site => and (not (@eq Site s1 s2)) (not (@eq (queue Message) (bm c s1 s2) (empty Message))))) *)
  apply H1.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
  
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.

Qed.


Lemma exist_non_empty_queue :
 forall c : Config,
 legal c ->
 ~ no_message c ->
 exists s1 : Site,
   (exists s2 : Site, s1 <> s2 /\ bm c s1 s2 <> empty Message).

Proof.
(* Goal: forall (c : Config) (_ : legal c) (_ : not (no_message c)), @ex Site (fun s1 : Site => @ex Site (fun s2 : Site => and (not (@eq Site s1 s2)) (not (@eq (queue Message) (bm c s1 s2) (empty Message))))) *)
  unfold no_message in |- *.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  intro.
(* Goal: forall (_ : legal c) (_ : not (forall (s1 s2 : Site) (_ : @In Site s1 LS) (_ : @In Site s2 LS), @eq (queue Message) (bm c s1 s2) (empty Message))), @ex Site (fun s1 : Site => @ex Site (fun s2 : Site => and (not (@eq Site s1 s2)) (not (@eq (queue Message) (bm c s1 s2) (empty Message))))) *)
  pattern LS at 1 in |- *.
(* Goal: sumbool (forall (s1 : Site) (_ : @In Site s1 LS) (_ : not (@eq Site s1 owner)), @eq bool (rt c s1) false) (@ex Site (fun s1 : Site => and (not (@eq Site s1 owner)) (@eq bool (rt c s1) true))) *)
  elim LS.
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
  simpl in |- *.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: sumor (@sig legal_config (fun y : legal_config => no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) (forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) *)
(* Goal: forall _ : forall t : class_trans c, copy_p c t, sumor (@sig legal_config (fun y : legal_config => no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) (forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) *)
  elim H0.
(* Goal: forall (s1 s2 : Site) (_ : False) (_ : @In Site s2 LS), @eq (queue Message) (bm c s1 s2) (empty Message) *)
(* Goal: forall (a : Site) (l : list Site) (_ : forall (_ : legal c) (_ : not (forall (s1 s2 : Site) (_ : @In Site s1 l) (_ : @In Site s2 LS), @eq (queue Message) (bm c s1 s2) (empty Message))), @ex Site (fun s1 : Site => @ex Site (fun s2 : Site => and (not (@eq Site s1 s2)) (not (@eq (queue Message) (bm c s1 s2) (empty Message)))))) (_ : legal c) (_ : not (forall (s1 s2 : Site) (_ : @In Site s1 (@cons Site a l)) (_ : @In Site s2 LS), @eq (queue Message) (bm c s1 s2) (empty Message))), @ex Site (fun s1 : Site => @ex Site (fun s2 : Site => and (not (@eq Site s1 s2)) (not (@eq (queue Message) (bm c s1 s2) (empty Message))))) *)
  intros; contradiction.
  
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
  simpl in |- *.
(* Goal: forall (a : Site) (l : list Site) (_ : forall (_ : legal c) (_ : not (forall (s1 s2 : Site) (_ : @In Site s1 l) (_ : @In Site s2 LS), @eq (queue Message) (bm c s1 s2) (empty Message))), @ex Site (fun s1 : Site => @ex Site (fun s2 : Site => and (not (@eq Site s1 s2)) (not (@eq (queue Message) (bm c s1 s2) (empty Message)))))) (_ : legal c) (_ : not (forall (s1 s2 : Site) (_ : or (@eq Site a s1) (@In Site s1 l)) (_ : @In Site s2 LS), @eq (queue Message) (bm c s1 s2) (empty Message))), @ex Site (fun s1 : Site => @ex Site (fun s2 : Site => and (not (@eq Site s1 s2)) (not (@eq (queue Message) (bm c s1 s2) (empty Message))))) *)
  intros a l H HLeg.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  elim (decide_exist_non_empty_queue1 c a HLeg); intro.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  intro.
(* Goal: @ex E (fun x : E => @eq (exc E) match q1 with | @empty _ => value E e | @input _ d q => first E q1 end (value E x)) *)
  apply H.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
  
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  unfold not in |- *; intro.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  elim H0; intros.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  elim H2; intro.
(* Goal: @eq (queue Message) (bm c s1 s2) (empty Message) *)
(* Goal: @eq (queue Message) (bm c s1 s2) (empty Message) *)
(* Goal: forall _ : not (forall (s1 s2 : Site) (_ : or (@eq Site a s1) (@In Site s1 l)) (_ : @In Site s2 LS), @eq (queue Message) (bm c s1 s2) (empty Message)), @ex Site (fun s1 : Site => @ex Site (fun s2 : Site => and (not (@eq Site s1 s2)) (not (@eq (queue Message) (bm c s1 s2) (empty Message))))) *)
  rewrite <- H4.
(* Goal: @eq (queue Message) (bm c a s2) (empty Message) *)
(* Goal: @eq (queue Message) (bm c s1 s2) (empty Message) *)
(* Goal: forall _ : not (forall (s1 s2 : Site) (_ : or (@eq Site a s1) (@In Site s1 l)) (_ : @In Site s2 LS), @eq (queue Message) (bm c s1 s2) (empty Message)), @ex Site (fun s1 : Site => @ex Site (fun s2 : Site => and (not (@eq Site s1 s2)) (not (@eq (queue Message) (bm c s1 s2) (empty Message))))) *)
  apply a0.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
  
(* Goal: @eq (queue Message) (bm c s1 s2) (empty Message) *)
(* Goal: forall _ : not (forall (s1 s2 : Site) (_ : or (@eq Site a s1) (@In Site s1 l)) (_ : @In Site s2 LS), @eq (queue Message) (bm c s1 s2) (empty Message)), @ex Site (fun s1 : Site => @ex Site (fun s2 : Site => and (not (@eq Site s1 s2)) (not (@eq (queue Message) (bm c s1 s2) (empty Message))))) *)
  apply H1.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
  
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
  
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: @ex Site (fun s1 : Site => and (not (@eq Site s1 owner)) (@eq bool (rt c s1) true)) *)
  split with a.
(* Goal: @ex Site (fun s2 : Site => and (not (@eq Site a s2)) (not (@eq (queue Message) (bm c a s2) (empty Message)))) *)
  generalize b.
(* Goal: sumbool (forall (s1 : Site) (_ : @In Site s1 LS) (_ : not (@eq Site s1 owner)), @eq bool (rt c s1) false) (@ex Site (fun s1 : Site => and (not (@eq Site s1 owner)) (@eq bool (rt c s1) true))) *)
  elim LS.
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
  simpl in |- *.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  intro.
(* Goal: forall (s1 s2 : Site) (_ : False) (_ : @In Site s2 LS), @eq (queue Message) (bm c s1 s2) (empty Message) *)
(* Goal: forall (a : Site) (l : list Site) (_ : forall (_ : legal c) (_ : not (forall (s1 s2 : Site) (_ : @In Site s1 l) (_ : @In Site s2 LS), @eq (queue Message) (bm c s1 s2) (empty Message))), @ex Site (fun s1 : Site => @ex Site (fun s2 : Site => and (not (@eq Site s1 s2)) (not (@eq (queue Message) (bm c s1 s2) (empty Message)))))) (_ : legal c) (_ : not (forall (s1 s2 : Site) (_ : @In Site s1 (@cons Site a l)) (_ : @In Site s2 LS), @eq (queue Message) (bm c s1 s2) (empty Message))), @ex Site (fun s1 : Site => @ex Site (fun s2 : Site => and (not (@eq Site s1 s2)) (not (@eq (queue Message) (bm c s1 s2) (empty Message))))) *)
  elim b0; intros; contradiction.
  
(* Goal: forall (a0 : Site) (l : list Site) (_ : forall _ : not (forall (s2 : Site) (_ : @In Site s2 l) (_ : not (@eq Site s2 a)), @eq (queue Message) (bm c a s2) (empty Message)), @ex Site (fun s2 : Site => and (not (@eq Site a s2)) (not (@eq (queue Message) (bm c a s2) (empty Message))))) (_ : not (forall (s2 : Site) (_ : @In Site s2 (@cons Site a0 l)) (_ : not (@eq Site s2 a)), @eq (queue Message) (bm c a s2) (empty Message))), @ex Site (fun s2 : Site => and (not (@eq Site a s2)) (not (@eq (queue Message) (bm c a s2) (empty Message)))) *)
  clear H.
(* Goal: forall (a0 : Site) (l : list Site) (_ : forall _ : not (forall (s2 : Site) (_ : @In Site s2 l) (_ : not (@eq Site s2 a)), @eq (queue Message) (bm c a s2) (empty Message)), @ex Site (fun s2 : Site => and (not (@eq Site a s2)) (not (@eq (queue Message) (bm c a s2) (empty Message))))) (_ : not (forall (s2 : Site) (_ : @In Site s2 (@cons Site a0 l)) (_ : not (@eq Site s2 a)), @eq (queue Message) (bm c a s2) (empty Message))), @ex Site (fun s2 : Site => and (not (@eq Site a s2)) (not (@eq (queue Message) (bm c a s2) (empty Message)))) *)
  clear H0.
(* Goal: forall (a0 : Site) (l : list Site) (_ : forall _ : not (forall (s2 : Site) (_ : @In Site s2 l) (_ : not (@eq Site s2 a)), @eq (queue Message) (bm c a s2) (empty Message)), @ex Site (fun s2 : Site => and (not (@eq Site a s2)) (not (@eq (queue Message) (bm c a s2) (empty Message))))) (_ : not (forall (s2 : Site) (_ : @In Site s2 (@cons Site a0 l)) (_ : not (@eq Site s2 a)), @eq (queue Message) (bm c a s2) (empty Message))), @ex Site (fun s2 : Site => and (not (@eq Site a s2)) (not (@eq (queue Message) (bm c a s2) (empty Message)))) *)
  clear b.
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
  simpl in |- *.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  elim (decide_empty_queue c a a0); intro.
(* Goal: @ex E (fun x : E => @eq (exc E) match q1 with | @empty _ => value E e | @input _ d q => first E q1 end (value E x)) *)
  apply H.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  unfold not in |- *; intros.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  elim b; intros.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  elim H1; intro.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  rewrite <- H3; auto.
  
(* Goal: @eq (queue Message) (bm c a s2) (empty Message) *)
(* Goal: @ex Site (fun s2 : Site => and (not (@eq Site a s2)) (not (@eq (queue Message) (bm c a s2) (empty Message)))) *)
  apply H0.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
  
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
  
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  case (eq_site_dec a a0); intro.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  elim b0; rewrite e; rewrite empty_q_to_me; auto.
  
(* Goal: @ex Site (fun s2 : Site => and (not (@eq Site a s2)) (not (@eq (queue Message) (bm c a s2) (empty Message)))) *)
  split with a0.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  split; auto.
Qed.


(**

Define a measure:
  for instance: 2 for inc_dec
                1 for dec.
                2 for rt=true
  Show that any legal_no_copy transition
  decreases the measure.
  By induction, there is a minimum.
*)


Definition termination_count (m : Message) :=
  match m with
  | copy => 5%Z
  | dec => 1%Z
  | inc_dec s3 => 2%Z
  end.

Definition termination_q_count (s1 s2 : Site) (q : queue Message) :=
  reduce Message termination_count q.

Definition termination_q_measure (bm : Bag_of_message) :=
  sigma2_table Site LS LS (queue Message) termination_q_count bm.
Definition termination_rt_count (b : bool) := if b then 2%Z else 0%Z.

Definition termination_rt_measure (t : Site -> bool) :=
  sigma_table Site LS Z (Z_id Site)
    (fun s : Site => termination_rt_count (t s)).

Definition termination_measure (c : Config) :=
  (termination_rt_measure (rt c) + termination_q_measure (bm c))%Z.

Inductive legal_no_copy2 : Config -> Config -> Prop :=
  | no_copy_init2 : forall c : Config, legal c -> legal_no_copy2 c c
  | after_no_copy2 :
      forall (c c0 : Config) (t : class_trans c),
      ~ copy_p c t ->
      legal_no_copy2 c c0 -> legal_no_copy2 (transition c t) c0.


Lemma legal_no_copy_transitive2 :
 forall c0 : Config,
 legal c0 ->
 forall c1 c2 : Config,
 legal_no_copy2 c1 c0 -> legal_no_copy2 c2 c1 -> legal_no_copy2 c2 c0.
Proof.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: legal_no_copy2 c2 c0 *)
  generalize H0.
(* Goal: False *)
  elim H1.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
  
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: legal_no_copy2 (transition c t) c0 *)
  apply after_no_copy2.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
  
(* Goal: False *)
  apply H4.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
Qed.

Remark add_reduce2 :
 forall x y z a : Z, x = a -> (x + (y + z))%Z = (a + y + z)%Z.
Proof.
(* Goal: forall (x y : Z) (_ : Z.ge x Z0) (_ : Z.ge y Z0), Z.le Z0 (Z.add x y) *)
intros; omega.
Qed.

Remark add_reduce3 :
 forall x y z a : Z, x = a -> y = z -> (x + y)%Z = (a + z)%Z.
Proof.
(* Goal: forall (x y : Z) (_ : Z.ge x Z0) (_ : Z.ge y Z0), Z.le Z0 (Z.add x y) *)
intros; omega.
Qed.

Remark add_reduce10 :
 forall x y w z a : Z,
 w = y -> (a > 0)%Z -> (x + (y + (z - a)) < x + (w + z))%Z.
Proof.
(* Goal: forall (x y : Z) (_ : Z.ge x Z0) (_ : Z.ge y Z0), Z.le Z0 (Z.add x y) *)
intros; omega.
Qed.

Remark add_reduce11 :
 forall x1 x2 y w z a b : Z,
 x1 = x2 ->
 w = y -> (b - a < 0)%Z -> (x1 + b + (y + (z - a)) < x2 + (w + z))%Z.
Proof.
(* Goal: forall (x y : Z) (_ : Z.ge x Z0) (_ : Z.ge y Z0), Z.le Z0 (Z.add x y) *)
intros; omega.
Qed.

Remark add_reduce12 : forall x y : Z, x = y -> x = (y + 0)%Z.
Proof.
(* Goal: forall (x y : Z) (_ : Z.ge x Z0) (_ : Z.ge y Z0), Z.le Z0 (Z.add x y) *)
intros; omega.
Qed.

Remark add_reduce13 :
 forall x1 x2 y w z a b : Z,
 x1 = x2 ->
 w = y -> (b + a < 0)%Z -> (x1 + b + (y + (z + a)) < x2 + (w + z))%Z.
Proof.
(* Goal: forall (x y : Z) (_ : Z.ge x Z0) (_ : Z.ge y Z0), Z.le Z0 (Z.add x y) *)
intros; omega.
Qed.


Remark add_reduce14 :
 forall x1 x2 x3 y w z a b : Z,
 x1 = x2 ->
 w = y -> (b + a < x3)%Z -> (x1 + b + (y + (z + a)) < x2 + x3 + (w + z))%Z.
Proof.
(* Goal: forall (x y : Z) (_ : Z.ge x Z0) (_ : Z.ge y Z0), Z.le Z0 (Z.add x y) *)
intros; omega.
Qed.


Remark add_reduce15 : forall x y a : Z, (x < y)%Z -> (a + x < a + y)%Z.
Proof.
(* Goal: forall (x y : Z) (_ : Z.ge x Z0) (_ : Z.ge y Z0), Z.le Z0 (Z.add x y) *)
intros; omega.
Qed.

Remark add_reduce16 :
 forall x1 x2 y b : Z,
 x1 = x2 -> (1 - b < 0)%Z -> (x1 - b + (y + 1) < x2 + y)%Z.
Proof.
(* Goal: forall (x y : Z) (_ : Z.ge x Z0) (_ : Z.ge y Z0), Z.le Z0 (Z.add x y) *)
intros; omega.
Qed.

Remark add_reduce17 : forall x y a : Z, x = y -> (x + a)%Z = (y + a)%Z.
Proof.
(* Goal: forall (x y : Z) (_ : Z.ge x Z0) (_ : Z.ge y Z0), Z.le Z0 (Z.add x y) *)
intros; omega.
Qed.

Remark add_reduce18 : forall x y a : Z, x = y -> a = 0%Z -> x = (y + a)%Z.
Proof.
(* Goal: forall (x y : Z) (_ : Z.ge x Z0) (_ : Z.ge y Z0), Z.le Z0 (Z.add x y) *)
intros; omega.
Qed.

Remark add_reduce19 :
 forall x1 x2 x3 y1 y2 y3 y4 : Z,
 x1 = y1 ->
 (y2 - y4 + (y3 + 1) < x2 + x3)%Z ->
 (y1 + (y2 - y4) + (y3 + 1) < x1 + x2 + x3)%Z.
Proof.
(* Goal: forall (x y : Z) (_ : Z.ge x Z0) (_ : Z.ge y Z0), Z.le Z0 (Z.add x y) *)
intros; omega.
Qed.

Remark add_reduce22 :
 forall a b x0 y0 x1 x2 x3 y1 y2 y3 y4 : Z,
 x1 = y1 ->
 a = b ->
 (x0 + (y2 - y4) + (y3 + 2) < y0 + x2 + x3)%Z ->
 (a + x0 + (y1 + (y2 - y4) + (y3 + 2)) < b + y0 + (x1 + x2 + x3))%Z.
Proof.
(* Goal: forall (x y : Z) (_ : Z.ge x Z0) (_ : Z.ge y Z0), Z.le Z0 (Z.add x y) *)
intros; omega.
Qed.

Remark add_reduce23 :
 forall x y : Z, (x >= 0)%Z -> (y >= 0)%Z -> (0 <= x + y)%Z.
Proof.
(* Goal: forall (x y : Z) (_ : Z.ge x Z0) (_ : Z.ge y Z0), Z.le Z0 (Z.add x y) *)
intros; omega.
Qed.

(* 
Section BUT_XY.

Variable Data: Set.
Local Table2:=  Site ->  Site -> Data.
Variable f: Site -> Site -> Data->Z.


Lemma sigma2_sigma2_but_x_y:
 (s0,s1:Site) (t:Table2)
 (sigma2_table Site LS LS Data f t) = `(sigma2_but_table Site eq_site_dec LS LS Data s0 s1 f t) 
                                       + (f s0 s1 (t s0 s1))`.
Proof.
  Intro.
  Intro.
  Intro.
  Generalize (finite_site s1).
  Generalize (finite_site s0).
  (Pattern 1 3 5 LS; Elim LS).
  Simpl.
  (Intros; Contradiction).
  
  Intros.
  Unfold sigma2_table sigma2_but_table.
  Simpl.
  (Case (eq_site_dec a s0); Intro).
  Unfold sigma_table.
  Rewrite (sigma_sigma_but Site a eq_site_dec).
  Rewrite (sigma_sigma_but Site a eq_site_dec) with l:=(cons a l).
  Simpl.
  Case (eq_site_dec a a).
  Intro.
  Case (eq_site_dec a s0).
  Intro.
  Rewrite <- sigma_sigma_but_not_in with x0:=a.
  Rewrite <- sigma_sigma_but_not_in with x0:=a.
  Rewrite (sigma_sigma_but Site s1 eq_site_dec) with l:=LS.
  Unfold sigma_but_table.
  Rewrite e1.
  Unfold Z_id.
  Apply add_reduce2.
  Apply sigma_simpl.
  Intros.
  Case (eq_site_dec x s0).
  Intro.
  (Generalize H0; Rewrite e1).
  Simpl.
  (Case (eq_site_dec s0 s0); Intro).
  Intro.
  (Elim H3; Rewrite <- e2; Auto).
  
  (Elim n; Auto).
  
  Intro.
  Auto.
  
  Auto.
  
  (Generalize H0; Simpl).
  Rewrite e.
  (Case (eq_site_dec s0 s0); Intro).
  Auto.
  
  (Elim n; Auto).
  
  (Generalize H0; Simpl).
  (Case (eq_site_dec s0 a); Intro).
  (Rewrite e; Auto).
  
  (Elim n; Auto).
  
  Intro.
  (Elim n; Auto).
  
  Intro.
  (Elim n; Auto).
  
  (Rewrite e; Auto).
  (Generalize H0; Rewrite e; Auto).
  
  (Generalize H0; Rewrite e).
  Auto.
  
  (Unfold sigma_table; Simpl).
  Generalize H.
  Unfold sigma2_table.
  Unfold sigma_table.
  Intro.
  Rewrite H2.
  (Unfold Z_id; Simpl).
  (Case (eq_site_dec a s0); Intro).
  (Elim n; Auto).
  
  Unfold sigma2_but_table.
  Unfold sigma_table.
  Unfold Z_id.
  Omega.
  
  (Generalize H0; Simpl).
  (Case (eq_site_dec s0 a); Intro).
  (Elim n; Auto).
  
  Auto.
  
  Auto.
    
Save.

Lemma sigma2_but_simpl : (s0,s1:Site) (t:Table2) (f,g:Site->Site->Data->Z)
 ((x,y:Site) ~((x=s0)/\(y=s1))->(f x y (t x y))=(g x y (t x y)))->
  (sigma2_but_table Site eq_site_dec LS LS Data s0 s1 f t)
  =
  (sigma2_but_table Site eq_site_dec LS LS Data s0 s1 g t ).
Proof.
  Intros.
  Generalize (finite_site s1).
  Generalize (finite_site s0).
  (Pattern 1 3 5 LS; Elim LS).
  Simpl.
  (Intros; Contradiction).
  
  Simpl.
  Intros a l.
  (Case (eq_site_dec s0 a); Intro).
  Rewrite e.
  Simpl.
  Intros.
  Unfold sigma2_but_table.
  (Unfold sigma_table; Simpl).
  Unfold Z_id.
  (Case (eq_site_dec a a); Intro).
  Apply add_reduce3.
  Generalize H2.
  (Elim LS; Simpl).
  (Intro; Contradiction).
  
  Intros.
  (Unfold sigma_but_table; Simpl).
  Generalize H4.
  (Case (eq_site_dec a0 s1); Intro).
  Rewrite e1.
  (Case (eq_site_dec s1 s1); Intros).
  Rewrite <- (sigma_sigma_but_not_in Site s1 eq_site_dec).
  Rewrite <- (sigma_sigma_but_not_in Site s1 eq_site_dec).
  Apply sigma_simpl.
  Intros.
  Apply H.
  (Unfold not; Intro).
  Decompose [and] H7.
  (Elim H5; Rewrite <- H10; Auto).
  
  Auto.
  
  Exact H5.
  
  (Elim n; Auto).
  
  (Case (eq_site_dec s1 a0); Intro).
  (Elim n; Auto).
  
  Intros.
  Apply add_reduce3.
  Apply H.
  (Unfold not; Intro).
  Decompose [and] H6.
  (Elim n; Auto).
  
  Generalize H3.
  Unfold sigma_but_table.
  Auto.
  
  Apply sigma_simpl.
  Intros.
  (Case (eq_site_dec x a); Intro).
  (Elim H1; Rewrite <- e1; Auto).
  
  Apply sigma_simpl.
  Intros.
  Apply H.
  (Unfold not; Intro).
  (Decompose [and] H5; Elim n; Rewrite <- e; Auto).
  
  (Elim n; Auto).
  
  Unfold sigma2_but_table.
  (Unfold sigma_table; Simpl).
  Intros.
  (Case (eq_site_dec a s0); Intro).
  (Elim n; Auto).
  
  Rewrite H0.
  Apply add_reduce3.
  Unfold Z_id.
  Apply sigma_simpl.
  Intros.
  Apply H.
  (Unfold not; Intro; Elim n0).
  (Decompose [and] H4; Auto).
  
  Auto.
  
  Auto.
  
  Auto.

Save.

(* Interestingly, the proof of the following Lemma is exactly the same
as the proof of the previous lemma *)

Lemma sigma2_but_simpl2 : (s0,s1:Site) (t1,t2:Table2) (f:Site->Site->Data->Z)
 ((x,y:Site) ~((x=s0)/\(y=s1))->(f x y (t1 x y))=(f x y (t2 x y)))->
  (sigma2_but_table Site eq_site_dec LS LS Data s0 s1 f t1)
  =
  (sigma2_but_table Site eq_site_dec LS LS Data s0 s1 f t2 ).
Proof.
  Intros.
  Generalize (finite_site s1).
  Generalize (finite_site s0).
  (Pattern 1 3 5 LS; Elim LS).
  Simpl.
  (Intros; Contradiction).
  
  Simpl.
  Intros a l.
  (Case (eq_site_dec s0 a); Intro).
  Rewrite e.
  Simpl.
  Intros.
  Unfold sigma2_but_table.
  (Unfold sigma_table; Simpl).
  Unfold Z_id.
  (Case (eq_site_dec a a); Intro).
  Apply add_reduce3.
  Generalize H2.
  (Elim LS; Simpl).
  (Intro; Contradiction).
  
  Intros.
  (Unfold sigma_but_table; Simpl).
  Generalize H4.
  (Case (eq_site_dec a0 s1); Intro).
  Rewrite e1.
  (Case (eq_site_dec s1 s1); Intros).
  Rewrite <- (sigma_sigma_but_not_in Site s1 eq_site_dec).
  Rewrite <- (sigma_sigma_but_not_in Site s1 eq_site_dec).
  Apply sigma_simpl.
  Intros.
  Apply H.
  (Unfold not; Intro).
  Decompose [and] H7.
  (Elim H5; Rewrite <- H10; Auto).
  
  Auto.
  
  Exact H5.
  
  (Elim n; Auto).
  
  (Case (eq_site_dec s1 a0); Intro).
  (Elim n; Auto).
  
  Intros.
  Apply add_reduce3.
  Apply H.
  (Unfold not; Intro).
  Decompose [and] H6.
  (Elim n; Auto).
  
  Generalize H3.
  Unfold sigma_but_table.
  Auto.
  
  Apply sigma_simpl.
  Intros.
  (Case (eq_site_dec x a); Intro).
  (Elim H1; Rewrite <- e1; Auto).
  
  Apply sigma_simpl.
  Intros.
  Apply H.
  (Unfold not; Intro).
  (Decompose [and] H5; Elim n; Rewrite <- e; Auto).
  
  (Elim n; Auto).
  
  Unfold sigma2_but_table.
  (Unfold sigma_table; Simpl).
  Intros.
  (Case (eq_site_dec a s0); Intro).
  (Elim n; Auto).
  
  Rewrite H0.
  Apply add_reduce3.
  Unfold Z_id.
  Apply sigma_simpl.
  Intros.
  Apply H.
  (Unfold not; Intro; Elim n0).
  (Decompose [and] H4; Auto).
  
  Auto.
  
  Auto.
  
  Auto.
Save.

End BUT_XY.

*)

(* another way of defining sigma_but:

   On the one hand, it is less convenient, because the functional
   argument is changed, which later, if we use sigma2_simpl, will
   imply a tedious case analysis.


   On the other hand, it is more convenient, because I can
   apply sigma2_but several times, there are transformed into
   a sigma2_table.
*)
(*
Lemma new_sigma2_sigma2_but_x_y:
 (s0,s1:Site)(Data:Set) (f:Site->Site->Data->Z)
 (t:Site ->  Site -> Data)
 (sigma2_table Site LS LS Data f t) = `(new_sigma2_but_table Site eq_site_dec LS LS Data s0 s1 f t) 
                                       + (f s0 s1 (t s0 s1))`.
Proof.
  Intros.
  Unfold new_sigma2_but_table.
  Rewrite sigma2_sigma2_but_x_y with s0:=s0 s1:=s1.
  Apply add_reduce17.
  Rewrite sigma2_sigma2_but_x_y with s0:=s0 s1:=s1.
  Apply add_reduce18.
  Apply sigma2_but_simpl.
  Intros.
  (Case (eq_site_dec x s0); Intro).
  (Case (eq_site_dec y s1); Intro).
  (Elim H; Auto).
  Auto.
  Auto.
  Rewrite case_eq.
  Rewrite case_eq.
  Auto.
Save.

*)


Lemma termination_measure_decreases :
 forall (c : Config) (t : class_trans c),
 legal c ->
 ~ copy_p c t ->
 (termination_measure (transition c t) < termination_measure c)%Z.

Proof.
  simple induction t; simpl in |- *;
   unfold termination_measure, termination_rt_measure, termination_q_measure
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
    in |- *; simpl in |- *; intros.

  (* 1 *)

(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  elim H0; auto.

  (* 2 *)
  
  rewrite
   sigma2_sigma2_but_x_y
                         with
                         (s0 := s1)
                        (s1 := s2)
                        (eq_site_dec := eq_site_dec).
(* Goal: Z.lt (Z.add (Z.add (sigma_but Site s2 eq_site_dec LS (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (termination_rt_count (Set_rec_table (rt c) s2 s2))) (Z.add (Z.add (sigma2_table Site LS LS (queue Message) (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s1 then if eq_site_dec s4 s2 then Z0 else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner)) (reduce Message termination_count (Collect_message Message (bm c) s1 s2 s1 s2))) (Z.add (reduce Message termination_count (bm c s2 owner)) (Zpos (xO xH))))) (Z.add (sigma Site LS (fun s : Site => termination_rt_count (rt c s))) (Z.add (Z.add (sigma2_table Site LS LS (queue Message) (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s1 then if eq_site_dec s4 s2 then Z0 else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (bm c)) (reduce Message termination_count (bm c s1 s2))) (reduce Message termination_count (bm c s2 owner)))) *)
(* Goal: or (not (@eq Site s2 s1)) (not (@eq Site owner s2)) *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: or (not (@eq Site s1 s2)) (not (@eq Site s2 owner)) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  rewrite collect_here.
(* Goal: Z.ge (termination_q_count x_ x_0 (bm c x_ x_0)) Z0 *)
  unfold termination_q_count in |- *.
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (Z.add (sigma2_but_table Site eq_site_dec LS LS (queue Message) s1 s2 (fun (_ _ : Site) (q : queue Message) => reduce Message termination_count q) (Collect_message Message (bm c) s1 s2)) (reduce Message termination_count (first_out Message (bm c s1 s2))))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) (fun (_ _ : Site) (q : queue Message) => reduce Message termination_count q) (bm c))) *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (Collect_message Message (bm c) s1 owner) owner s3))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (Collect_message Message (bm c) s1 s2) s2 s1))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (sigma2_table Site LS LS (queue Message) termination_q_count (Collect_message Message (bm c) owner s2))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  rewrite reduce_first_out with (m := dec).
  rewrite
   sigma2_sigma2_but_x_y
                         with
                         (s0 := s1)
                        (s1 := s2)
                        (eq_site_dec := eq_site_dec).
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (Z.add (sigma2_but_table Site eq_site_dec LS LS (queue Message) s1 s2 (fun (_ _ : Site) (q : queue Message) => reduce Message termination_count q) (Collect_message Message (bm c) s1 s2)) (Z.sub (reduce Message termination_count (bm c s1 s2)) (termination_count dec)))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (Z.add (sigma2_but_table Site eq_site_dec LS LS (queue Message) s1 s2 (fun (_ _ : Site) (q : queue Message) => reduce Message termination_count q) (bm c)) (reduce Message termination_count (bm c s1 s2)))) *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: @eq (exc Message) (first Message (bm c s1 s2)) (value Message dec) *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (Collect_message Message (bm c) s1 owner) owner s3))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (Collect_message Message (bm c) s1 s2) s2 s1))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (sigma2_table Site LS LS (queue Message) termination_q_count (Collect_message Message (bm c) owner s2))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  apply add_reduce10.
(* Goal: @eq Z (sigma2_but_table Site eq_site_dec LS LS (queue Message) s owner (fun (_ _ : Site) (q : queue Message) => reduce Message termination_count q) (bm c)) (sigma2_but_table Site eq_site_dec LS LS (queue Message) s owner (fun (_ _ : Site) (q : queue Message) => reduce Message termination_count q) (Post_message Message dec (bm c) s owner)) *)
(* Goal: Z.lt (Z.add (termination_rt_count (Reset_rec_table (rt c) s s)) (Zpos xH)) (termination_rt_count (rt c s)) *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
  apply sigma2_but_simpl2.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: Z.lt (Z.add (Z.add (sigma_but Site s2 eq_site_dec LS (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (termination_rt_count (Set_rec_table (rt c) s2 s2))) (Z.add (sigma2_table Site LS LS (queue Message) (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner)) (Z.add (reduce Message termination_count (Collect_message Message (bm c) s1 s2 s2 owner)) (Zpos (xO xH))))) (Z.add (sigma Site LS (fun s : Site => termination_rt_count (rt c s))) (Z.add (sigma2_table Site LS LS (queue Message) (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (bm c)) (reduce Message termination_count (bm c s2 owner)))) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  rewrite collect_elsewhere.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
  
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  case (eq_queue_dec s1 x s2 y); intro.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  elim H1; auto.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  decompose [and] a; split; auto.
  
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
(* Goal: only_once Site eq_site_dec owner LS *)
  apply finite_site.
(* Goal: only_once Site eq_site_dec owner LS *)
  apply finite_site.

  
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
  unfold termination_count in |- *; simpl in |- *.
(* Goal: @eq Z Z0 Z0 *)
(* Goal: forall (a : E) (l : list E) (_ : @eq Z (sigma E l f) Z0), @eq Z (Z.add (f a) (sigma E l f)) Z0 *)
  omega.
(* Goal: only_once Site eq_site_dec owner LS *)
  apply finite_site.
(* Goal: only_once Site eq_site_dec owner LS *)
  apply finite_site.

(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
(* Goal: only_once Site eq_site_dec owner LS *)
  apply finite_site.
(* Goal: only_once Site eq_site_dec owner LS *)
  apply finite_site.

  (* 3 *)

(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (Collect_message Message (bm c) s1 s2) s2 s1))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (sigma2_table Site LS LS (queue Message) termination_q_count (Collect_message Message (bm c) owner s2))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  apply add_reduce15.
  rewrite
   new_sigma2_sigma2_but_x_y
                             with
                             (s0 := owner)
                            (s1 := s3)
                            (eq_site_dec := eq_site_dec).
  rewrite
   new_sigma2_sigma2_but_x_y
                             with
                             (s0 := owner)
                            (s1 := s3)
                            (eq_site_dec := eq_site_dec).
(* Goal: Z.lt (Z.add (Z.add (sigma_but Site s2 eq_site_dec LS (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (termination_rt_count (Set_rec_table (rt c) s2 s2))) (Z.add (Z.add (new_sigma2_but_table Site eq_site_dec LS LS (queue Message) s1 s2 (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner)) (if eq_site_dec s1 s2 then if eq_site_dec s2 owner then Z0 else reduce Message termination_count (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner s1 s2) else reduce Message termination_count (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner s1 s2))) (Z.add (reduce Message termination_count (bm c s2 owner)) (Zpos (xO xH))))) (Z.add (sigma Site LS (fun s : Site => termination_rt_count (rt c s))) (Z.add (Z.add (new_sigma2_but_table Site eq_site_dec LS LS (queue Message) s1 s2 (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (bm c)) (if eq_site_dec s1 s2 then if eq_site_dec s2 owner then Z0 else reduce Message termination_count (bm c s1 s2) else reduce Message termination_count (bm c s1 s2))) (reduce Message termination_count (bm c s2 owner)))) *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: or (not (@eq Site s1 s2)) (not (@eq Site s2 owner)) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  unfold new_sigma2_but_table in |- *.
(* Goal: forall _ : @eq (queue Message) (Post_message Message copy (bm c) x0 x1 x0 x1) (first_out Message (bm c x0 x1)), not True *)
(* Goal: forall _ : @eq (queue Message) (Post_message Message copy (bm c) s1 s2 x0 x1) (first_out Message (bm c x0 x1)), not True *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  rewrite post_here.
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
  unfold termination_q_count in |- *; simpl in |- *.
(* Goal: Z.lt (Z.add (Z.add (sigma_but Site s2 eq_site_dec LS (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (termination_rt_count (Set_rec_table (rt c) s2 s2))) (Z.add (sigma2_table Site LS LS (queue Message) (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner)) (Z.add (reduce Message termination_count (Collect_message Message (bm c) s1 s2 s2 owner)) (Zpos (xO xH))))) (Z.add (sigma Site LS (fun s : Site => termination_rt_count (rt c s))) (Z.add (sigma2_table Site LS LS (queue Message) (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (bm c)) (reduce Message termination_count (bm c s2 owner)))) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  rewrite collect_elsewhere.
  rewrite
   new_sigma2_sigma2_but_x_y
                             with
                             (s0 := s1)
                            (s1 := owner)
                            (eq_site_dec := eq_site_dec).
  rewrite
   new_sigma2_sigma2_but_x_y
                             with
                             (s0 := s1)
                            (s1 := owner)
                            (eq_site_dec := eq_site_dec).
(* Goal: Z.lt (Z.add (Z.add (sigma_but Site s2 eq_site_dec LS (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (termination_rt_count (Set_rec_table (rt c) s2 s2))) (Z.add (Z.add (new_sigma2_but_table Site eq_site_dec LS LS (queue Message) s1 s2 (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner)) (if eq_site_dec s1 s2 then if eq_site_dec s2 owner then Z0 else reduce Message termination_count (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner s1 s2) else reduce Message termination_count (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner s1 s2))) (Z.add (reduce Message termination_count (bm c s2 owner)) (Zpos (xO xH))))) (Z.add (sigma Site LS (fun s : Site => termination_rt_count (rt c s))) (Z.add (Z.add (new_sigma2_but_table Site eq_site_dec LS LS (queue Message) s1 s2 (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (bm c)) (if eq_site_dec s1 s2 then if eq_site_dec s2 owner then Z0 else reduce Message termination_count (bm c s1 s2) else reduce Message termination_count (bm c s1 s2))) (reduce Message termination_count (bm c s2 owner)))) *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: or (not (@eq Site s1 s2)) (not (@eq Site s2 owner)) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  unfold new_sigma2_but_table in |- *.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  case (eq_site_dec s1 owner); intro.
(* Goal: Z.lt (Z.add (Z.add (sigma2_table Site LS LS (queue Message) (fun (s2 s4 : Site) (d : queue Message) => if eq_site_dec s2 s1 then if eq_site_dec s4 owner then Z0 else if eq_site_dec s2 owner then if eq_site_dec s4 s3 then Z0 else reduce Message termination_count d else reduce Message termination_count d else if eq_site_dec s2 owner then if eq_site_dec s4 s3 then Z0 else reduce Message termination_count d else reduce Message termination_count d) (Post_message Message dec (Collect_message Message (bm c) s1 owner) owner s3)) (if eq_site_dec owner s3 then Z0 else reduce Message termination_count (Post_message Message dec (Collect_message Message (bm c) s1 owner) owner s3 s1 owner))) (Z.add (reduce Message termination_count (bm c owner s3)) (Zpos xH))) (Z.add (Z.add (sigma2_table Site LS LS (queue Message) (fun (s2 s4 : Site) (d : queue Message) => if eq_site_dec s2 s1 then if eq_site_dec s4 owner then Z0 else if eq_site_dec s2 owner then if eq_site_dec s4 s3 then Z0 else reduce Message termination_count d else reduce Message termination_count d else if eq_site_dec s2 owner then if eq_site_dec s4 s3 then Z0 else reduce Message termination_count d else reduce Message termination_count d) (bm c)) (if eq_site_dec owner s3 then Z0 else reduce Message termination_count (bm c s1 owner))) (reduce Message termination_count (bm c owner s3))) *)
(* Goal: Z.lt (Z.add (Z.add (sigma2_table Site LS LS (queue Message) (fun (s2 s4 : Site) (d : queue Message) => if eq_site_dec s2 s1 then if eq_site_dec s4 owner then Z0 else if eq_site_dec s2 owner then if eq_site_dec s4 s3 then Z0 else reduce Message termination_count d else reduce Message termination_count d else if eq_site_dec s2 owner then if eq_site_dec s4 s3 then Z0 else reduce Message termination_count d else reduce Message termination_count d) (Post_message Message dec (Collect_message Message (bm c) s1 owner) owner s3)) (reduce Message termination_count (Post_message Message dec (Collect_message Message (bm c) s1 owner) owner s3 s1 owner))) (Z.add (reduce Message termination_count (bm c owner s3)) (Zpos xH))) (Z.add (Z.add (sigma2_table Site LS LS (queue Message) (fun (s2 s4 : Site) (d : queue Message) => if eq_site_dec s2 s1 then if eq_site_dec s4 owner then Z0 else if eq_site_dec s2 owner then if eq_site_dec s4 s3 then Z0 else reduce Message termination_count d else reduce Message termination_count d else if eq_site_dec s2 owner then if eq_site_dec s4 s3 then Z0 else reduce Message termination_count d else reduce Message termination_count d) (bm c)) (reduce Message termination_count (bm c s1 owner))) (reduce Message termination_count (bm c owner s3))) *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: or (not (@eq Site s1 owner)) (not (@eq Site owner s3)) *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s3 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s3 LS *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (Collect_message Message (bm c) s1 s2) s2 s1))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (sigma2_table Site LS LS (queue Message) termination_q_count (Collect_message Message (bm c) owner s2))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  generalize e; rewrite e0.
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
  rewrite empty_q_to_me; simpl in |- *.
(* Goal: forall _ : @eq (exc Message) (error Message) (value Message copy), False *)
(* Goal: @In Site s1 LS *)
(* Goal: @In Site s2 LS *)
(* Goal: False *)
  intro; discriminate.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
(* Goal: forall _ : @eq (queue Message) (Post_message Message copy (bm c) s1 s2 x0 x1) (first_out Message (bm c x0 x1)), not True *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  rewrite post_elsewhere.
(* Goal: Z.lt (Z.add (Z.add (sigma_but Site s2 eq_site_dec LS (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (termination_rt_count (Set_rec_table (rt c) s2 s2))) (Z.add (Z.add (sigma2_table Site LS LS (queue Message) (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s1 then if eq_site_dec s4 s2 then Z0 else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner)) (reduce Message termination_count (Collect_message Message (bm c) s1 s2 s1 s2))) (Z.add (reduce Message termination_count (bm c s2 owner)) (Zpos (xO xH))))) (Z.add (sigma Site LS (fun s : Site => termination_rt_count (rt c s))) (Z.add (Z.add (sigma2_table Site LS LS (queue Message) (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s1 then if eq_site_dec s4 s2 then Z0 else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (bm c)) (reduce Message termination_count (bm c s1 s2))) (reduce Message termination_count (bm c s2 owner)))) *)
(* Goal: or (not (@eq Site s2 s1)) (not (@eq Site owner s2)) *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: or (not (@eq Site s1 s2)) (not (@eq Site s2 owner)) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  rewrite collect_here.
(* Goal: Z.lt (Z.add (Z.add (sigma2_table Site LS LS (queue Message) (fun (s2 s4 : Site) (d : queue Message) => if eq_site_dec s2 s1 then if eq_site_dec s4 owner then Z0 else if eq_site_dec s2 owner then if eq_site_dec s4 s3 then Z0 else reduce Message termination_count d else reduce Message termination_count d else if eq_site_dec s2 owner then if eq_site_dec s4 s3 then Z0 else reduce Message termination_count d else reduce Message termination_count d) (Post_message Message dec (Collect_message Message (bm c) s1 owner) owner s3)) (reduce Message termination_count (first_out Message (bm c s1 owner)))) (Z.add (reduce Message termination_count (bm c owner s3)) (Zpos xH))) (Z.add (Z.add (sigma2_table Site LS LS (queue Message) (fun (s2 s4 : Site) (d : queue Message) => if eq_site_dec s2 s1 then if eq_site_dec s4 owner then Z0 else if eq_site_dec s2 owner then if eq_site_dec s4 s3 then Z0 else reduce Message termination_count d else reduce Message termination_count d else if eq_site_dec s2 owner then if eq_site_dec s4 s3 then Z0 else reduce Message termination_count d else reduce Message termination_count d) (bm c)) (reduce Message termination_count (bm c s1 owner))) (reduce Message termination_count (bm c owner s3))) *)
(* Goal: or (not (@eq Site owner s1)) (not (@eq Site s3 owner)) *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: or (not (@eq Site s1 owner)) (not (@eq Site owner s3)) *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s3 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s3 LS *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (Collect_message Message (bm c) s1 s2) s2 s1))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (sigma2_table Site LS LS (queue Message) termination_q_count (Collect_message Message (bm c) owner s2))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  rewrite reduce_first_out with (m := inc_dec s3).
(* Goal: Z.lt (Z.add (Z.add (sigma2_table Site LS LS (queue Message) (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s1 then if eq_site_dec s4 s2 then Z0 else if eq_site_dec s3 s2 then if eq_site_dec s4 s1 then Z0 else reduce Message termination_count d else reduce Message termination_count d else if eq_site_dec s3 s2 then if eq_site_dec s4 s1 then Z0 else reduce Message termination_count d else reduce Message termination_count d) (Post_message Message dec (Collect_message Message (bm c) s1 s2) s2 s1)) (Z.sub (reduce Message termination_count (bm c s1 s2)) (termination_count copy))) (Z.add (reduce Message termination_count (bm c s2 s1)) (Zpos xH))) (Z.add (Z.add (sigma2_table Site LS LS (queue Message) (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s1 then if eq_site_dec s4 s2 then Z0 else if eq_site_dec s3 s2 then if eq_site_dec s4 s1 then Z0 else reduce Message termination_count d else reduce Message termination_count d else if eq_site_dec s3 s2 then if eq_site_dec s4 s1 then Z0 else reduce Message termination_count d else reduce Message termination_count d) (bm c)) (reduce Message termination_count (bm c s1 s2))) (reduce Message termination_count (bm c s2 s1))) *)
(* Goal: @eq (exc Message) (first Message (bm c s1 s2)) (value Message copy) *)
(* Goal: or (not (@eq Site s2 s1)) (not (@eq Site s1 s2)) *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: or (not (@eq Site s1 s2)) (not (@eq Site s2 s1)) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (sigma2_table Site LS LS (queue Message) termination_q_count (Collect_message Message (bm c) owner s2))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  apply add_reduce19.
(* Goal: @eq Z (sigma2_table Site LS LS (queue Message) (rooted s0) (bm c0)) Z0 *)
(* Goal: legal c0 *)
(* Goal: not (@eq Site s0 owner) *)
  unfold sigma2_table in |- *.
(* Goal: @eq Z (sigma_table Site LS Z (Z_id Site) (fun s3 : Site => sigma_table Site LS (queue Message) (fun (s4 : Site) (d : queue Message) => if eq_site_dec s3 s1 then if eq_site_dec s4 s2 then Z0 else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (bm c s3))) (sigma_table Site LS Z (Z_id Site) (fun s3 : Site => sigma_table Site LS (queue Message) (fun (s4 : Site) (d : queue Message) => if eq_site_dec s3 s1 then if eq_site_dec s4 s2 then Z0 else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner s3))) *)
(* Goal: @eq Z (sigma_but Site s2 eq_site_dec LS (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (sigma_but Site s2 eq_site_dec LS (fun s : Site => termination_rt_count (rt c s))) *)
(* Goal: Z.lt (Z.add (Z.add (termination_rt_count (Set_rec_table (rt c) s2 s2)) (Z.sub (reduce Message termination_count (bm c s1 s2)) (termination_count copy))) (Z.add (reduce Message termination_count (bm c s2 owner)) (Zpos (xO xH)))) (Z.add (Z.add (termination_rt_count (rt c s2)) (reduce Message termination_count (bm c s1 s2))) (reduce Message termination_count (bm c s2 owner))) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: @eq (exc Message) (first Message (bm c s1 s2)) (value Message copy) *)
(* Goal: or (not (@eq Site s2 s1)) (not (@eq Site owner s2)) *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: or (not (@eq Site s1 s2)) (not (@eq Site s2 owner)) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  apply sigma_table_simpl.
(* Goal: @eq (forall _ : Site, Z) (fun s3 : Site => sigma_table Site LS (queue Message) (fun (s4 : Site) (d : queue Message) => if eq_site_dec s3 s1 then if eq_site_dec s4 s2 then Z0 else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (bm c s3)) (fun s3 : Site => sigma_table Site LS (queue Message) (fun (s4 : Site) (d : queue Message) => if eq_site_dec s3 s1 then if eq_site_dec s4 s2 then Z0 else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner s3)) *)
(* Goal: @eq Z (sigma_but Site s2 eq_site_dec LS (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (sigma_but Site s2 eq_site_dec LS (fun s : Site => termination_rt_count (rt c s))) *)
(* Goal: Z.lt (Z.add (Z.add (termination_rt_count (Set_rec_table (rt c) s2 s2)) (Z.sub (reduce Message termination_count (bm c s1 s2)) (termination_count copy))) (Z.add (reduce Message termination_count (bm c s2 owner)) (Zpos (xO xH)))) (Z.add (Z.add (termination_rt_count (rt c s2)) (reduce Message termination_count (bm c s1 s2))) (reduce Message termination_count (bm c s2 owner))) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: @eq (exc Message) (first Message (bm c s1 s2)) (value Message copy) *)
(* Goal: or (not (@eq Site s2 s1)) (not (@eq Site owner s2)) *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: or (not (@eq Site s1 s2)) (not (@eq Site s2 owner)) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  apply funct_eq.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  intro.
(* Goal: @eq Z (sigma_table Site LS Z (Z_id Site) (fun s1 : Site => sigma_table Site LS (queue Message) (rooted s0 s1) (bm c0 s1))) Z0 *)
(* Goal: legal c0 *)
(* Goal: not (@eq Site s0 owner) *)
  unfold sigma_table in |- *.
(* Goal: @eq Z (sigma Site LS (fun s : Site => if eq_site_dec e1 s1 then if eq_site_dec s s2 then Z0 else if eq_site_dec e1 s2 then if eq_site_dec s owner then Z0 else reduce Message termination_count (bm c e1 s) else reduce Message termination_count (bm c e1 s) else if eq_site_dec e1 s2 then if eq_site_dec s owner then Z0 else reduce Message termination_count (bm c e1 s) else reduce Message termination_count (bm c e1 s))) (sigma Site LS (fun s : Site => if eq_site_dec e1 s1 then if eq_site_dec s s2 then Z0 else if eq_site_dec e1 s2 then if eq_site_dec s owner then Z0 else reduce Message termination_count (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner e1 s) else reduce Message termination_count (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner e1 s) else if eq_site_dec e1 s2 then if eq_site_dec s owner then Z0 else reduce Message termination_count (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner e1 s) else reduce Message termination_count (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner e1 s))) *)
(* Goal: @eq Z (sigma_but Site s2 eq_site_dec LS (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (sigma_but Site s2 eq_site_dec LS (fun s : Site => termination_rt_count (rt c s))) *)
(* Goal: Z.lt (Z.add (Z.add (termination_rt_count (Set_rec_table (rt c) s2 s2)) (Z.sub (reduce Message termination_count (bm c s1 s2)) (termination_count copy))) (Z.add (reduce Message termination_count (bm c s2 owner)) (Zpos (xO xH)))) (Z.add (Z.add (termination_rt_count (rt c s2)) (reduce Message termination_count (bm c s1 s2))) (reduce Message termination_count (bm c s2 owner))) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: @eq (exc Message) (first Message (bm c s1 s2)) (value Message copy) *)
(* Goal: or (not (@eq Site s2 s1)) (not (@eq Site owner s2)) *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: or (not (@eq Site s1 s2)) (not (@eq Site s2 owner)) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  apply sigma_simpl.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  case (eq_site_dec e0 s1); intro.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  case (eq_site_dec x owner); intro.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  case (eq_site_dec e0 owner); intro.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  case (eq_site_dec x s3); intro.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
(* Goal: forall _ : @eq (queue Message) (Post_message Message copy (bm c) s1 s2 x0 x1) (first_out Message (bm c x0 x1)), not True *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  rewrite post_elsewhere.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  rewrite collect_elsewhere; auto.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
(* Goal: forall _ : @eq (queue Message) (Post_message Message copy (bm c) s1 s2 x0 x1) (first_out Message (bm c x0 x1)), not True *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  rewrite post_elsewhere.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  rewrite collect_elsewhere; auto.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  case (eq_site_dec e0 owner); intro.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  case (eq_site_dec x s3); intro.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
(* Goal: forall _ : @eq (queue Message) (Post_message Message copy (bm c) s1 s2 x0 x1) (first_out Message (bm c x0 x1)), not True *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  rewrite post_elsewhere.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  rewrite collect_elsewhere; auto.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
(* Goal: forall _ : @eq (queue Message) (Post_message Message copy (bm c) s1 s2 x0 x1) (first_out Message (bm c x0 x1)), not True *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  rewrite post_elsewhere.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  rewrite collect_elsewhere; auto.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
  unfold termination_count in |- *; simpl in |- *.
(* Goal: @eq Z Z0 Z0 *)
(* Goal: forall (a : E) (l : list E) (_ : @eq Z (sigma E l f) Z0), @eq Z (Z.add (f a) (sigma E l f)) Z0 *)
  omega.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
(* Goal: only_once Site eq_site_dec owner LS *)
  apply finite_site.
(* Goal: only_once Site eq_site_dec owner LS *)
  apply finite_site.
(* Goal: only_once Site eq_site_dec owner LS *)
  apply finite_site.
(* Goal: only_once Site eq_site_dec owner LS *)
  apply finite_site.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  left; unfold not in |- *; intro.
(* Goal: @eq (queue Message) (bm c a0 a0) (empty Message) *)
(* Goal: sumbool (forall (s2 : Site) (_ : or (@eq Site a0 s2) (@In Site s2 l)), @eq (queue Message) (bm c a s2) (empty Message)) (not (forall (s2 : Site) (_ : or (@eq Site a0 s2) (@In Site s2 l)) (_ : not (@eq Site s2 a)), @eq (queue Message) (bm c a s2) (empty Message))) *)
(* Goal: sumbool (forall (s2 : Site) (_ : or (@eq Site a0 s2) (@In Site s2 l)), @eq (queue Message) (bm c a s2) (empty Message)) (not (forall (s2 : Site) (_ : or (@eq Site a0 s2) (@In Site s2 l)) (_ : not (@eq Site s2 a)), @eq (queue Message) (bm c a s2) (empty Message))) *)
  generalize e; rewrite H1; rewrite empty_q_to_me.
(* Goal: forall _ : @eq (exc Message) (error Message) (value Message copy), False *)
(* Goal: @In Site s1 LS *)
(* Goal: @In Site s2 LS *)
(* Goal: False *)
  simpl in |- *; intro; discriminate.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
(* Goal: only_once Site eq_site_dec owner LS *)
  apply finite_site.
(* Goal: only_once Site eq_site_dec owner LS *)
  apply finite_site.
(* Goal: only_once Site eq_site_dec owner LS *)
  apply finite_site.
(* Goal: only_once Site eq_site_dec owner LS *)
  apply finite_site.

  (* 4 *)

(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (Collect_message Message (bm c) s1 s2) s2 s1))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (sigma2_table Site LS LS (queue Message) termination_q_count (Collect_message Message (bm c) owner s2))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  apply add_reduce15.
  rewrite
   new_sigma2_sigma2_but_x_y
                             with
                             (s0 := s2)
                            (s1 := s1)
                            (eq_site_dec := eq_site_dec).
  rewrite
   new_sigma2_sigma2_but_x_y
                             with
                             (s0 := s2)
                            (s1 := s1)
                            (eq_site_dec := eq_site_dec).
(* Goal: Z.lt (Z.add (Z.add (sigma_but Site s2 eq_site_dec LS (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (termination_rt_count (Set_rec_table (rt c) s2 s2))) (Z.add (Z.add (new_sigma2_but_table Site eq_site_dec LS LS (queue Message) s1 s2 (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner)) (if eq_site_dec s1 s2 then if eq_site_dec s2 owner then Z0 else reduce Message termination_count (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner s1 s2) else reduce Message termination_count (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner s1 s2))) (Z.add (reduce Message termination_count (bm c s2 owner)) (Zpos (xO xH))))) (Z.add (sigma Site LS (fun s : Site => termination_rt_count (rt c s))) (Z.add (Z.add (new_sigma2_but_table Site eq_site_dec LS LS (queue Message) s1 s2 (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (bm c)) (if eq_site_dec s1 s2 then if eq_site_dec s2 owner then Z0 else reduce Message termination_count (bm c s1 s2) else reduce Message termination_count (bm c s1 s2))) (reduce Message termination_count (bm c s2 owner)))) *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: or (not (@eq Site s1 s2)) (not (@eq Site s2 owner)) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  unfold new_sigma2_but_table in |- *.
(* Goal: forall _ : @eq (queue Message) (Post_message Message copy (bm c) x0 x1 x0 x1) (first_out Message (bm c x0 x1)), not True *)
(* Goal: forall _ : @eq (queue Message) (Post_message Message copy (bm c) s1 s2 x0 x1) (first_out Message (bm c x0 x1)), not True *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  rewrite post_here.
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
  unfold termination_q_count in |- *; simpl in |- *.
(* Goal: Z.lt (Z.add (Z.add (sigma_but Site s2 eq_site_dec LS (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (termination_rt_count (Set_rec_table (rt c) s2 s2))) (Z.add (sigma2_table Site LS LS (queue Message) (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner)) (Z.add (reduce Message termination_count (Collect_message Message (bm c) s1 s2 s2 owner)) (Zpos (xO xH))))) (Z.add (sigma Site LS (fun s : Site => termination_rt_count (rt c s))) (Z.add (sigma2_table Site LS LS (queue Message) (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (bm c)) (reduce Message termination_count (bm c s2 owner)))) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  rewrite collect_elsewhere.
  rewrite
   new_sigma2_sigma2_but_x_y
                             with
                             (s0 := s1)
                            (s1 := s2)
                            (eq_site_dec := eq_site_dec).
  rewrite
   new_sigma2_sigma2_but_x_y
                             with
                             (s0 := s1)
                            (s1 := s2)
                            (eq_site_dec := eq_site_dec).
(* Goal: Z.lt (Z.add (Z.add (sigma_but Site s2 eq_site_dec LS (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (termination_rt_count (Set_rec_table (rt c) s2 s2))) (Z.add (Z.add (new_sigma2_but_table Site eq_site_dec LS LS (queue Message) s1 s2 (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner)) (if eq_site_dec s1 s2 then if eq_site_dec s2 owner then Z0 else reduce Message termination_count (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner s1 s2) else reduce Message termination_count (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner s1 s2))) (Z.add (reduce Message termination_count (bm c s2 owner)) (Zpos (xO xH))))) (Z.add (sigma Site LS (fun s : Site => termination_rt_count (rt c s))) (Z.add (Z.add (new_sigma2_but_table Site eq_site_dec LS LS (queue Message) s1 s2 (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (bm c)) (if eq_site_dec s1 s2 then if eq_site_dec s2 owner then Z0 else reduce Message termination_count (bm c s1 s2) else reduce Message termination_count (bm c s1 s2))) (reduce Message termination_count (bm c s2 owner)))) *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: or (not (@eq Site s1 s2)) (not (@eq Site s2 owner)) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  unfold new_sigma2_but_table in |- *.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  case (eq_site_dec s1 s2); intro.
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
  generalize e0; rewrite e1; rewrite empty_q_to_me; simpl in |- *.
(* Goal: forall _ : @eq (exc Message) (error Message) (value Message copy), False *)
(* Goal: @In Site s1 LS *)
(* Goal: @In Site s2 LS *)
(* Goal: False *)
  intro; discriminate.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
(* Goal: forall _ : @eq (queue Message) (Post_message Message copy (bm c) s1 s2 x0 x1) (first_out Message (bm c x0 x1)), not True *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  rewrite post_elsewhere.
(* Goal: Z.lt (Z.add (Z.add (sigma_but Site s2 eq_site_dec LS (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (termination_rt_count (Set_rec_table (rt c) s2 s2))) (Z.add (Z.add (sigma2_table Site LS LS (queue Message) (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s1 then if eq_site_dec s4 s2 then Z0 else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner)) (reduce Message termination_count (Collect_message Message (bm c) s1 s2 s1 s2))) (Z.add (reduce Message termination_count (bm c s2 owner)) (Zpos (xO xH))))) (Z.add (sigma Site LS (fun s : Site => termination_rt_count (rt c s))) (Z.add (Z.add (sigma2_table Site LS LS (queue Message) (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s1 then if eq_site_dec s4 s2 then Z0 else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (bm c)) (reduce Message termination_count (bm c s1 s2))) (reduce Message termination_count (bm c s2 owner)))) *)
(* Goal: or (not (@eq Site s2 s1)) (not (@eq Site owner s2)) *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: or (not (@eq Site s1 s2)) (not (@eq Site s2 owner)) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  rewrite collect_here.
(* Goal: Z.lt (Z.add (Z.add (sigma_but Site s2 eq_site_dec LS (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (termination_rt_count (Set_rec_table (rt c) s2 s2))) (Z.add (Z.add (sigma2_table Site LS LS (queue Message) (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s1 then if eq_site_dec s4 s2 then Z0 else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner)) (reduce Message termination_count (first_out Message (bm c s1 s2)))) (Z.add (reduce Message termination_count (bm c s2 owner)) (Zpos (xO xH))))) (Z.add (sigma Site LS (fun s : Site => termination_rt_count (rt c s))) (Z.add (Z.add (sigma2_table Site LS LS (queue Message) (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s1 then if eq_site_dec s4 s2 then Z0 else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (bm c)) (reduce Message termination_count (bm c s1 s2))) (reduce Message termination_count (bm c s2 owner)))) *)
(* Goal: or (not (@eq Site s2 s1)) (not (@eq Site owner s2)) *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: or (not (@eq Site s1 s2)) (not (@eq Site s2 owner)) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  rewrite reduce_first_out with (m := copy).
(* Goal: Z.lt (Z.add (Z.add (sigma2_table Site LS LS (queue Message) (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s1 then if eq_site_dec s4 s2 then Z0 else if eq_site_dec s3 s2 then if eq_site_dec s4 s1 then Z0 else reduce Message termination_count d else reduce Message termination_count d else if eq_site_dec s3 s2 then if eq_site_dec s4 s1 then Z0 else reduce Message termination_count d else reduce Message termination_count d) (Post_message Message dec (Collect_message Message (bm c) s1 s2) s2 s1)) (Z.sub (reduce Message termination_count (bm c s1 s2)) (termination_count copy))) (Z.add (reduce Message termination_count (bm c s2 s1)) (Zpos xH))) (Z.add (Z.add (sigma2_table Site LS LS (queue Message) (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s1 then if eq_site_dec s4 s2 then Z0 else if eq_site_dec s3 s2 then if eq_site_dec s4 s1 then Z0 else reduce Message termination_count d else reduce Message termination_count d else if eq_site_dec s3 s2 then if eq_site_dec s4 s1 then Z0 else reduce Message termination_count d else reduce Message termination_count d) (bm c)) (reduce Message termination_count (bm c s1 s2))) (reduce Message termination_count (bm c s2 s1))) *)
(* Goal: @eq (exc Message) (first Message (bm c s1 s2)) (value Message copy) *)
(* Goal: or (not (@eq Site s2 s1)) (not (@eq Site s1 s2)) *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: or (not (@eq Site s1 s2)) (not (@eq Site s2 s1)) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (sigma2_table Site LS LS (queue Message) termination_q_count (Collect_message Message (bm c) owner s2))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  apply add_reduce19.
(* Goal: @eq Z (sigma2_table Site LS LS (queue Message) (rooted s0) (bm c0)) Z0 *)
(* Goal: legal c0 *)
(* Goal: not (@eq Site s0 owner) *)
  unfold sigma2_table in |- *.
(* Goal: @eq Z (sigma_table Site LS Z (Z_id Site) (fun s3 : Site => sigma_table Site LS (queue Message) (fun (s4 : Site) (d : queue Message) => if eq_site_dec s3 s1 then if eq_site_dec s4 s2 then Z0 else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (bm c s3))) (sigma_table Site LS Z (Z_id Site) (fun s3 : Site => sigma_table Site LS (queue Message) (fun (s4 : Site) (d : queue Message) => if eq_site_dec s3 s1 then if eq_site_dec s4 s2 then Z0 else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner s3))) *)
(* Goal: @eq Z (sigma_but Site s2 eq_site_dec LS (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (sigma_but Site s2 eq_site_dec LS (fun s : Site => termination_rt_count (rt c s))) *)
(* Goal: Z.lt (Z.add (Z.add (termination_rt_count (Set_rec_table (rt c) s2 s2)) (Z.sub (reduce Message termination_count (bm c s1 s2)) (termination_count copy))) (Z.add (reduce Message termination_count (bm c s2 owner)) (Zpos (xO xH)))) (Z.add (Z.add (termination_rt_count (rt c s2)) (reduce Message termination_count (bm c s1 s2))) (reduce Message termination_count (bm c s2 owner))) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: @eq (exc Message) (first Message (bm c s1 s2)) (value Message copy) *)
(* Goal: or (not (@eq Site s2 s1)) (not (@eq Site owner s2)) *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: or (not (@eq Site s1 s2)) (not (@eq Site s2 owner)) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  apply sigma_table_simpl.
(* Goal: @eq (forall _ : Site, Z) (fun s3 : Site => sigma_table Site LS (queue Message) (fun (s4 : Site) (d : queue Message) => if eq_site_dec s3 s1 then if eq_site_dec s4 s2 then Z0 else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (bm c s3)) (fun s3 : Site => sigma_table Site LS (queue Message) (fun (s4 : Site) (d : queue Message) => if eq_site_dec s3 s1 then if eq_site_dec s4 s2 then Z0 else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner s3)) *)
(* Goal: @eq Z (sigma_but Site s2 eq_site_dec LS (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (sigma_but Site s2 eq_site_dec LS (fun s : Site => termination_rt_count (rt c s))) *)
(* Goal: Z.lt (Z.add (Z.add (termination_rt_count (Set_rec_table (rt c) s2 s2)) (Z.sub (reduce Message termination_count (bm c s1 s2)) (termination_count copy))) (Z.add (reduce Message termination_count (bm c s2 owner)) (Zpos (xO xH)))) (Z.add (Z.add (termination_rt_count (rt c s2)) (reduce Message termination_count (bm c s1 s2))) (reduce Message termination_count (bm c s2 owner))) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: @eq (exc Message) (first Message (bm c s1 s2)) (value Message copy) *)
(* Goal: or (not (@eq Site s2 s1)) (not (@eq Site owner s2)) *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: or (not (@eq Site s1 s2)) (not (@eq Site s2 owner)) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  apply funct_eq.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  intro.
(* Goal: @eq Z (sigma_table Site LS Z (Z_id Site) (fun s1 : Site => sigma_table Site LS (queue Message) (rooted s0 s1) (bm c0 s1))) Z0 *)
(* Goal: legal c0 *)
(* Goal: not (@eq Site s0 owner) *)
  unfold sigma_table in |- *.
(* Goal: @eq Z (sigma Site LS (fun s : Site => if eq_site_dec e1 s1 then if eq_site_dec s s2 then Z0 else if eq_site_dec e1 s2 then if eq_site_dec s owner then Z0 else reduce Message termination_count (bm c e1 s) else reduce Message termination_count (bm c e1 s) else if eq_site_dec e1 s2 then if eq_site_dec s owner then Z0 else reduce Message termination_count (bm c e1 s) else reduce Message termination_count (bm c e1 s))) (sigma Site LS (fun s : Site => if eq_site_dec e1 s1 then if eq_site_dec s s2 then Z0 else if eq_site_dec e1 s2 then if eq_site_dec s owner then Z0 else reduce Message termination_count (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner e1 s) else reduce Message termination_count (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner e1 s) else if eq_site_dec e1 s2 then if eq_site_dec s owner then Z0 else reduce Message termination_count (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner e1 s) else reduce Message termination_count (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner e1 s))) *)
(* Goal: @eq Z (sigma_but Site s2 eq_site_dec LS (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (sigma_but Site s2 eq_site_dec LS (fun s : Site => termination_rt_count (rt c s))) *)
(* Goal: Z.lt (Z.add (Z.add (termination_rt_count (Set_rec_table (rt c) s2 s2)) (Z.sub (reduce Message termination_count (bm c s1 s2)) (termination_count copy))) (Z.add (reduce Message termination_count (bm c s2 owner)) (Zpos (xO xH)))) (Z.add (Z.add (termination_rt_count (rt c s2)) (reduce Message termination_count (bm c s1 s2))) (reduce Message termination_count (bm c s2 owner))) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: @eq (exc Message) (first Message (bm c s1 s2)) (value Message copy) *)
(* Goal: or (not (@eq Site s2 s1)) (not (@eq Site owner s2)) *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: or (not (@eq Site s1 s2)) (not (@eq Site s2 owner)) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  apply sigma_simpl.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  case (eq_site_dec e1 s1); intro.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  case (eq_site_dec x s2); intro.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  case (eq_site_dec e1 s2); intro.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  case (eq_site_dec x s1); intro.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
(* Goal: forall _ : @eq (queue Message) (Post_message Message copy (bm c) s1 s2 x0 x1) (first_out Message (bm c x0 x1)), not True *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  rewrite post_elsewhere.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  rewrite collect_elsewhere; auto.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
(* Goal: forall _ : @eq (queue Message) (Post_message Message copy (bm c) s1 s2 x0 x1) (first_out Message (bm c x0 x1)), not True *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  rewrite post_elsewhere.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  rewrite collect_elsewhere; auto.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  case (eq_site_dec e1 s2); intro.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  case (eq_site_dec x s1); intro.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
(* Goal: forall _ : @eq (queue Message) (Post_message Message copy (bm c) s1 s2 x0 x1) (first_out Message (bm c x0 x1)), not True *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  rewrite post_elsewhere.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  rewrite collect_elsewhere; auto.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
(* Goal: forall _ : @eq (queue Message) (Post_message Message copy (bm c) s1 s2 x0 x1) (first_out Message (bm c x0 x1)), not True *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  rewrite post_elsewhere.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  rewrite collect_elsewhere; auto.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
  unfold termination_count in |- *; simpl in |- *.
(* Goal: @eq Z Z0 Z0 *)
(* Goal: forall (a : E) (l : list E) (_ : @eq Z (sigma E l f) Z0), @eq Z (Z.add (f a) (sigma E l f)) Z0 *)
  omega.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
(* Goal: only_once Site eq_site_dec owner LS *)
  apply finite_site.
(* Goal: only_once Site eq_site_dec owner LS *)
  apply finite_site.
(* Goal: only_once Site eq_site_dec owner LS *)
  apply finite_site.
(* Goal: only_once Site eq_site_dec owner LS *)
  apply finite_site.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  left; unfold not in |- *; intro.
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
  generalize e0; rewrite H1; rewrite empty_q_to_me; simpl in |- *.
(* Goal: forall _ : @eq (exc Message) (error Message) (value Message copy), False *)
(* Goal: @In Site s1 LS *)
(* Goal: @In Site s2 LS *)
(* Goal: False *)
  intro; discriminate.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
(* Goal: only_once Site eq_site_dec owner LS *)
  apply finite_site.
(* Goal: only_once Site eq_site_dec owner LS *)
  apply finite_site.
(* Goal: only_once Site eq_site_dec owner LS *)
  apply finite_site.
(* Goal: only_once Site eq_site_dec owner LS *)
  apply finite_site.

  (* 5 *)
  
  rewrite
   sigma2_sigma2_but_x_y
                         with
                         (s0 := owner)
                        (s1 := s2)
                        (eq_site_dec := eq_site_dec).
(* Goal: Z.lt (Z.add (Z.add (sigma_but Site s2 eq_site_dec LS (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (termination_rt_count (Set_rec_table (rt c) s2 s2))) (Z.add (Z.add (sigma2_table Site LS LS (queue Message) (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s1 then if eq_site_dec s4 s2 then Z0 else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner)) (reduce Message termination_count (Collect_message Message (bm c) s1 s2 s1 s2))) (Z.add (reduce Message termination_count (bm c s2 owner)) (Zpos (xO xH))))) (Z.add (sigma Site LS (fun s : Site => termination_rt_count (rt c s))) (Z.add (Z.add (sigma2_table Site LS LS (queue Message) (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s1 then if eq_site_dec s4 s2 then Z0 else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (bm c)) (reduce Message termination_count (bm c s1 s2))) (reduce Message termination_count (bm c s2 owner)))) *)
(* Goal: or (not (@eq Site s2 s1)) (not (@eq Site owner s2)) *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: or (not (@eq Site s1 s2)) (not (@eq Site s2 owner)) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  rewrite collect_here.
(* Goal: Z.ge (termination_q_count x_ x_0 (bm c x_ x_0)) Z0 *)
  unfold termination_q_count in |- *.
(* Goal: Z.lt (Z.add (Z.add (sigma_but Site s2 eq_site_dec LS (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (termination_rt_count (Set_rec_table (rt c) s2 s2))) (Z.add (Z.add (sigma2_table Site LS LS (queue Message) (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s1 then if eq_site_dec s4 s2 then Z0 else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner)) (reduce Message termination_count (first_out Message (bm c s1 s2)))) (Z.add (reduce Message termination_count (bm c s2 owner)) (Zpos (xO xH))))) (Z.add (sigma Site LS (fun s : Site => termination_rt_count (rt c s))) (Z.add (Z.add (sigma2_table Site LS LS (queue Message) (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s1 then if eq_site_dec s4 s2 then Z0 else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (bm c)) (reduce Message termination_count (bm c s1 s2))) (reduce Message termination_count (bm c s2 owner)))) *)
(* Goal: or (not (@eq Site s2 s1)) (not (@eq Site owner s2)) *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: or (not (@eq Site s1 s2)) (not (@eq Site s2 owner)) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  rewrite reduce_first_out with (m := copy).
(* Goal: @eq Z (sigma_table Site LS Z (Z_id Site) (fun s1 : Site => sigma_table Site LS (queue Message) (rooted s0 s1) (bm c0 s1))) Z0 *)
(* Goal: legal c0 *)
(* Goal: not (@eq Site s0 owner) *)
  unfold sigma_table in |- *.
(* Goal: Z.lt (Z.add (Z.add (sigma_but Site s2 eq_site_dec LS (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (termination_rt_count (Set_rec_table (rt c) s2 s2))) (Z.add (Z.add (sigma2_table Site LS LS (queue Message) (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s1 then if eq_site_dec s4 s2 then Z0 else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner)) (Z.sub (reduce Message termination_count (bm c s1 s2)) (termination_count copy))) (Z.add (reduce Message termination_count (bm c s2 owner)) (Zpos (xO xH))))) (Z.add (sigma Site LS (fun s : Site => termination_rt_count (rt c s))) (Z.add (Z.add (sigma2_table Site LS LS (queue Message) (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s1 then if eq_site_dec s4 s2 then Z0 else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (bm c)) (reduce Message termination_count (bm c s1 s2))) (reduce Message termination_count (bm c s2 owner)))) *)
(* Goal: @eq (exc Message) (first Message (bm c s1 s2)) (value Message copy) *)
(* Goal: or (not (@eq Site s2 s1)) (not (@eq Site owner s2)) *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: or (not (@eq Site s1 s2)) (not (@eq Site s2 owner)) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  rewrite (sigma_sigma_but Site s2 eq_site_dec).
(* Goal: @eq Z (sigma Site LS (fun s : Site => Z_id Site s (sigma Site LS (fun s1 : Site => rooted s0 s s1 (bm c0 s s1))))) Z0 *)
(* Goal: legal c0 *)
(* Goal: not (@eq Site s0 owner) *)
  unfold Z_id in |- *.
  rewrite
   sigma2_sigma2_but_x_y
                         with
                         (s0 := owner)
                        (s1 := s2)
                        (eq_site_dec := eq_site_dec).
(* Goal: Z.lt (Z.add (Z.add (sigma_but Site s2 eq_site_dec LS (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (termination_rt_count (Set_rec_table (rt c) s2 s2))) (Z.add (sigma2_but_table Site eq_site_dec LS LS (queue Message) owner s2 (fun (_ _ : Site) (q : queue Message) => reduce Message termination_count q) (Collect_message Message (bm c) owner s2)) (Z.sub (reduce Message termination_count (bm c owner s2)) (termination_count copy)))) (Z.add (sigma Site LS (fun s : Site => termination_rt_count (rt c s))) (Z.add (sigma2_but_table Site eq_site_dec LS LS (queue Message) owner s2 (fun (_ _ : Site) (q : queue Message) => reduce Message termination_count q) (bm c)) (reduce Message termination_count (bm c owner s2)))) *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: @eq (exc Message) (first Message (bm c owner s2)) (value Message copy) *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  apply add_reduce11.
(* Goal: Z.lt (Z.add (Z.add (sigma_but Site s2 eq_site_dec LS (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (termination_rt_count (Set_rec_table (rt c) s2 s2))) (Z.add (Z.add (sigma2_table Site LS LS (queue Message) (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s1 then if eq_site_dec s4 s2 then Z0 else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner)) (Z.sub (reduce Message termination_count (bm c s1 s2)) (termination_count copy))) (Z.add (reduce Message termination_count (bm c s2 owner)) (Zpos (xO xH))))) (Z.add (sigma Site LS (fun s : Site => termination_rt_count (rt c s))) (Z.add (Z.add (sigma2_table Site LS LS (queue Message) (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s1 then if eq_site_dec s4 s2 then Z0 else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (bm c)) (reduce Message termination_count (bm c s1 s2))) (reduce Message termination_count (bm c s2 owner)))) *)
(* Goal: @eq (exc Message) (first Message (bm c s1 s2)) (value Message copy) *)
(* Goal: or (not (@eq Site s2 s1)) (not (@eq Site owner s2)) *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: or (not (@eq Site s1 s2)) (not (@eq Site s2 owner)) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  rewrite (sigma_sigma_but Site s2 eq_site_dec).
(* Goal: @eq Z (sigma_but Site s2 eq_site_dec LS (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (Z.add (sigma_but Site s2 eq_site_dec LS (fun s : Site => termination_rt_count (rt c s))) (termination_rt_count (rt c s2))) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: @eq Z (sigma2_but_table Site eq_site_dec LS LS (queue Message) owner s2 (fun (_ _ : Site) (q : queue Message) => reduce Message termination_count q) (bm c)) (sigma2_but_table Site eq_site_dec LS LS (queue Message) owner s2 (fun (_ _ : Site) (q : queue Message) => reduce Message termination_count q) (Collect_message Message (bm c) owner s2)) *)
(* Goal: Z.lt (Z.sub (termination_rt_count (Set_rec_table (rt c) s2 s2)) (termination_count copy)) Z0 *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: @eq (exc Message) (first Message (bm c owner s2)) (value Message copy) *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  rewrite e; unfold termination_rt_count in |- *.
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
  simpl in |- *.
(* Goal: @eq Z (sigma_but Site s2 eq_site_dec LS (fun s : Site => if Set_rec_table (rt c) s2 s then Zpos (xO xH) else Z0)) (Z.add (sigma_but Site s2 eq_site_dec LS (fun s : Site => if rt c s then Zpos (xO xH) else Z0)) Z0) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: @eq Z (sigma2_but_table Site eq_site_dec LS LS (queue Message) owner s2 (fun (_ _ : Site) (q : queue Message) => reduce Message termination_count q) (bm c)) (sigma2_but_table Site eq_site_dec LS LS (queue Message) owner s2 (fun (_ _ : Site) (q : queue Message) => reduce Message termination_count q) (Collect_message Message (bm c) owner s2)) *)
(* Goal: Z.lt (Z.sub (termination_rt_count (Set_rec_table (rt c) s2 s2)) (termination_count copy)) Z0 *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: @eq (exc Message) (first Message (bm c owner s2)) (value Message copy) *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  apply add_reduce12.
(* Goal: @eq Z (sigma_but Site s eq_site_dec LS (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma_but Site s eq_site_dec LS (fun s : Site => termination_rt_count (rt c s))) *)
(* Goal: @eq Z (sigma2_but_table Site eq_site_dec LS LS (queue Message) s owner (fun (_ _ : Site) (q : queue Message) => reduce Message termination_count q) (bm c)) (sigma2_but_table Site eq_site_dec LS LS (queue Message) s owner (fun (_ _ : Site) (q : queue Message) => reduce Message termination_count q) (Post_message Message dec (bm c) s owner)) *)
(* Goal: Z.lt (Z.add (termination_rt_count (Reset_rec_table (rt c) s s)) (Zpos xH)) (termination_rt_count (rt c s)) *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
  apply sigma_but_simpl.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: @eq Z (if Set_rec_table (rt c) s2 s then Zpos (xO xH) else Z0) (if rt c s then Zpos (xO xH) else Z0) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: @eq Z (sigma2_but_table Site eq_site_dec LS LS (queue Message) owner s2 (fun (_ _ : Site) (q : queue Message) => reduce Message termination_count q) (bm c)) (sigma2_but_table Site eq_site_dec LS LS (queue Message) owner s2 (fun (_ _ : Site) (q : queue Message) => reduce Message termination_count q) (Collect_message Message (bm c) owner s2)) *)
(* Goal: Z.lt (Z.sub (termination_rt_count (Set_rec_table (rt c) s2 s2)) (termination_count copy)) Z0 *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: @eq (exc Message) (first Message (bm c owner s2)) (value Message copy) *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  unfold Set_rec_table in |- *.
(* Goal: @eq Z (if change_site bool (rt c) s2 true s then Zpos (xO xH) else Z0) (if rt c s then Zpos (xO xH) else Z0) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: @eq Z (sigma2_but_table Site eq_site_dec LS LS (queue Message) owner s2 (fun (_ _ : Site) (q : queue Message) => reduce Message termination_count q) (bm c)) (sigma2_but_table Site eq_site_dec LS LS (queue Message) owner s2 (fun (_ _ : Site) (q : queue Message) => reduce Message termination_count q) (Collect_message Message (bm c) owner s2)) *)
(* Goal: Z.lt (Z.sub (termination_rt_count (Set_rec_table (rt c) s2 s2)) (termination_count copy)) Z0 *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: @eq (exc Message) (first Message (bm c owner s2)) (value Message copy) *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  cut (change_site bool (rt c) s2 true s = rt c s).
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  intro.
(* Goal: @eq Z (rooted s0 x_ x_0 (bm c0 x_ x_0)) Z0 *)
(* Goal: legal c0 *)
(* Goal: not (@eq Site s0 owner) *)
  rewrite H2.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
  
(* Goal: @eq Z (termination_rt_count (change_site bool (rt c) s false s0)) (termination_rt_count (rt c s0)) *)
(* Goal: @eq Z (sigma2_but_table Site eq_site_dec LS LS (queue Message) s owner (fun (_ _ : Site) (q : queue Message) => reduce Message termination_count q) (bm c)) (sigma2_but_table Site eq_site_dec LS LS (queue Message) s owner (fun (_ _ : Site) (q : queue Message) => reduce Message termination_count q) (Post_message Message dec (bm c) s owner)) *)
(* Goal: Z.lt (Z.add (termination_rt_count (Reset_rec_table (rt c) s s)) (Zpos xH)) (termination_rt_count (rt c s)) *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
  rewrite other_site.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
(* Goal: only_once Site eq_site_dec owner LS *)
  apply finite_site.
(* Goal: @eq Z (sigma2_but_table Site eq_site_dec LS LS (queue Message) s owner (fun (_ _ : Site) (q : queue Message) => reduce Message termination_count q) (bm c)) (sigma2_but_table Site eq_site_dec LS LS (queue Message) s owner (fun (_ _ : Site) (q : queue Message) => reduce Message termination_count q) (Post_message Message dec (bm c) s owner)) *)
(* Goal: Z.lt (Z.add (termination_rt_count (Reset_rec_table (rt c) s s)) (Zpos xH)) (termination_rt_count (rt c s)) *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
  apply sigma2_but_simpl2.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  case (eq_queue_dec owner x s2 y); intro.
(* Goal: @eq Z (reduce Message termination_count (bm c x y)) (reduce Message termination_count (Post_message Message dec (bm c) s owner x y)) *)
(* Goal: @eq Z (reduce Message termination_count (bm c x y)) (reduce Message termination_count (Post_message Message dec (bm c) s owner x y)) *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: Z.lt (Z.add (termination_rt_count (Reset_rec_table (rt c) s s)) (Zpos xH)) (termination_rt_count (rt c s)) *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
  elim H1; decompose [and] a.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  split; auto.
(* Goal: Z.lt (Z.add (Z.add (sigma_but Site s2 eq_site_dec LS (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (termination_rt_count (Set_rec_table (rt c) s2 s2))) (Z.add (sigma2_table Site LS LS (queue Message) (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner)) (Z.add (reduce Message termination_count (Collect_message Message (bm c) s1 s2 s2 owner)) (Zpos (xO xH))))) (Z.add (sigma Site LS (fun s : Site => termination_rt_count (rt c s))) (Z.add (sigma2_table Site LS LS (queue Message) (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (bm c)) (reduce Message termination_count (bm c s2 owner)))) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  rewrite collect_elsewhere.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
(* Goal: only_once Site eq_site_dec owner LS *)
 apply finite_site.
(* Goal: only_once Site eq_site_dec owner LS *)
 apply finite_site.
(* Goal: @eq Z (if Set_rec_table (rt c) s2 s then Zpos (xO xH) else Z0) (if rt c s then Zpos (xO xH) else Z0) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: @eq Z (sigma2_but_table Site eq_site_dec LS LS (queue Message) owner s2 (fun (_ _ : Site) (q : queue Message) => reduce Message termination_count q) (bm c)) (sigma2_but_table Site eq_site_dec LS LS (queue Message) owner s2 (fun (_ _ : Site) (q : queue Message) => reduce Message termination_count q) (Collect_message Message (bm c) owner s2)) *)
(* Goal: Z.lt (Z.sub (termination_rt_count (Set_rec_table (rt c) s2 s2)) (termination_count copy)) Z0 *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: @eq (exc Message) (first Message (bm c owner s2)) (value Message copy) *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  unfold termination_rt_count in |- *; unfold Set_rec_table in |- *.
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
  unfold termination_count in |- *; simpl in |- *.
(* Goal: Z.lt (Z.sub (if change_site bool (rt c) s2 true s2 then Zpos (xO xH) else Z0) (Zpos (xI (xO xH)))) Z0 *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: @eq (exc Message) (first Message (bm c owner s2)) (value Message copy) *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  cut (change_site bool (rt c) s2 true s2 = true).
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  intro.
(* Goal: not (@eq (queue E) (input E d (input E e q1)) (first_out E (input E d (input E e q1)))) *)
(* Goal: @eq (queue E) (first_out E (input E d (input E e q1))) (input E d (first_out E (input E e q1))) *)
  rewrite H1.
(* Goal: @eq Z Z0 Z0 *)
(* Goal: forall (a : E) (l : list E) (_ : @eq Z (sigma E l f) Z0), @eq Z (Z.add (f a) (sigma E l f)) Z0 *)
  omega.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  rewrite that_site; auto.
(* Goal: only_once Site eq_site_dec owner LS *)
  apply finite_site.
(* Goal: only_once Site eq_site_dec owner LS *)
  apply finite_site.
(* Goal: only_once Site eq_site_dec owner LS *)
  apply finite_site.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
(* Goal: only_once Site eq_site_dec owner LS *)
  apply finite_site.
(* Goal: only_once Site eq_site_dec owner LS *)
  apply finite_site.

  (* 6 *)

(* Goal: @eq Z (sigma_table Site LS Z (Z_id Site) (fun s1 : Site => sigma_table Site LS (queue Message) (rooted s0 s1) (bm c0 s1))) Z0 *)
(* Goal: legal c0 *)
(* Goal: not (@eq Site s0 owner) *)
  unfold sigma_table in |- *.
(* Goal: Z.lt (Z.add (Z.add (sigma_but Site s2 eq_site_dec LS (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (termination_rt_count (Set_rec_table (rt c) s2 s2))) (Z.add (Z.add (sigma2_table Site LS LS (queue Message) (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s1 then if eq_site_dec s4 s2 then Z0 else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner)) (Z.sub (reduce Message termination_count (bm c s1 s2)) (termination_count copy))) (Z.add (reduce Message termination_count (bm c s2 owner)) (Zpos (xO xH))))) (Z.add (sigma Site LS (fun s : Site => termination_rt_count (rt c s))) (Z.add (Z.add (sigma2_table Site LS LS (queue Message) (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s1 then if eq_site_dec s4 s2 then Z0 else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (bm c)) (reduce Message termination_count (bm c s1 s2))) (reduce Message termination_count (bm c s2 owner)))) *)
(* Goal: @eq (exc Message) (first Message (bm c s1 s2)) (value Message copy) *)
(* Goal: or (not (@eq Site s2 s1)) (not (@eq Site owner s2)) *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: or (not (@eq Site s1 s2)) (not (@eq Site s2 owner)) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  rewrite (sigma_sigma_but Site s2 eq_site_dec).
(* Goal: @eq Z (sigma Site LS (fun s : Site => Z_id Site s (sigma Site LS (fun s1 : Site => rooted s0 s s1 (bm c0 s s1))))) Z0 *)
(* Goal: legal c0 *)
(* Goal: not (@eq Site s0 owner) *)
  unfold Z_id in |- *.
  rewrite
   new_sigma2_sigma2_but_x_y
                             with
                             (s0 := s2)
                            (s1 := owner)
                            (eq_site_dec := eq_site_dec).
  rewrite
   new_sigma2_sigma2_but_x_y
                             with
                             (s0 := s2)
                            (s1 := owner)
                            (eq_site_dec := eq_site_dec).
(* Goal: Z.lt (Z.add (Z.add (sigma_but Site s2 eq_site_dec LS (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (termination_rt_count (Set_rec_table (rt c) s2 s2))) (Z.add (Z.add (new_sigma2_but_table Site eq_site_dec LS LS (queue Message) s1 s2 (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner)) (if eq_site_dec s1 s2 then if eq_site_dec s2 owner then Z0 else reduce Message termination_count (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner s1 s2) else reduce Message termination_count (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner s1 s2))) (Z.add (reduce Message termination_count (bm c s2 owner)) (Zpos (xO xH))))) (Z.add (sigma Site LS (fun s : Site => termination_rt_count (rt c s))) (Z.add (Z.add (new_sigma2_but_table Site eq_site_dec LS LS (queue Message) s1 s2 (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (bm c)) (if eq_site_dec s1 s2 then if eq_site_dec s2 owner then Z0 else reduce Message termination_count (bm c s1 s2) else reduce Message termination_count (bm c s1 s2))) (reduce Message termination_count (bm c s2 owner)))) *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: or (not (@eq Site s1 s2)) (not (@eq Site s2 owner)) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  unfold new_sigma2_but_table in |- *.
(* Goal: forall _ : @eq (queue Message) (Post_message Message copy (bm c) x0 x1 x0 x1) (first_out Message (bm c x0 x1)), not True *)
(* Goal: forall _ : @eq (queue Message) (Post_message Message copy (bm c) s1 s2 x0 x1) (first_out Message (bm c x0 x1)), not True *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  rewrite post_here.
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
  unfold termination_q_count in |- *; simpl in |- *.
(* Goal: Z.lt (Z.add (Z.add (sigma_but Site s2 eq_site_dec LS (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (termination_rt_count (Set_rec_table (rt c) s2 s2))) (Z.add (sigma2_table Site LS LS (queue Message) (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner)) (Z.add (reduce Message termination_count (Collect_message Message (bm c) s1 s2 s2 owner)) (Zpos (xO xH))))) (Z.add (sigma Site LS (fun s : Site => termination_rt_count (rt c s))) (Z.add (sigma2_table Site LS LS (queue Message) (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (bm c)) (reduce Message termination_count (bm c s2 owner)))) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  rewrite collect_elsewhere.
  rewrite
   new_sigma2_sigma2_but_x_y
                             with
                             (s0 := s1)
                            (s1 := s2)
                            (eq_site_dec := eq_site_dec).
  rewrite
   new_sigma2_sigma2_but_x_y
                             with
                             (s0 := s1)
                            (s1 := s2)
                            (eq_site_dec := eq_site_dec).
(* Goal: Z.lt (Z.add (Z.add (sigma_but Site s2 eq_site_dec LS (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (termination_rt_count (Set_rec_table (rt c) s2 s2))) (Z.add (Z.add (new_sigma2_but_table Site eq_site_dec LS LS (queue Message) s1 s2 (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner)) (if eq_site_dec s1 s2 then if eq_site_dec s2 owner then Z0 else reduce Message termination_count (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner s1 s2) else reduce Message termination_count (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner s1 s2))) (Z.add (reduce Message termination_count (bm c s2 owner)) (Zpos (xO xH))))) (Z.add (sigma Site LS (fun s : Site => termination_rt_count (rt c s))) (Z.add (Z.add (new_sigma2_but_table Site eq_site_dec LS LS (queue Message) s1 s2 (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (bm c)) (if eq_site_dec s1 s2 then if eq_site_dec s2 owner then Z0 else reduce Message termination_count (bm c s1 s2) else reduce Message termination_count (bm c s1 s2))) (reduce Message termination_count (bm c s2 owner)))) *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: or (not (@eq Site s1 s2)) (not (@eq Site s2 owner)) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  unfold new_sigma2_but_table in |- *.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  case (eq_site_dec s1 s2); intro.
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
  generalize e0; rewrite e1; rewrite empty_q_to_me; simpl in |- *.
(* Goal: forall _ : @eq (exc Message) (error Message) (value Message copy), False *)
(* Goal: @In Site s1 LS *)
(* Goal: @In Site s2 LS *)
(* Goal: False *)
  intro; discriminate.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
(* Goal: forall _ : @eq (queue Message) (Post_message Message copy (bm c) s1 s2 x0 x1) (first_out Message (bm c x0 x1)), not True *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  rewrite post_elsewhere.
(* Goal: Z.lt (Z.add (Z.add (sigma_but Site s2 eq_site_dec LS (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (termination_rt_count (Set_rec_table (rt c) s2 s2))) (Z.add (Z.add (sigma2_table Site LS LS (queue Message) (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s1 then if eq_site_dec s4 s2 then Z0 else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner)) (reduce Message termination_count (Collect_message Message (bm c) s1 s2 s1 s2))) (Z.add (reduce Message termination_count (bm c s2 owner)) (Zpos (xO xH))))) (Z.add (sigma Site LS (fun s : Site => termination_rt_count (rt c s))) (Z.add (Z.add (sigma2_table Site LS LS (queue Message) (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s1 then if eq_site_dec s4 s2 then Z0 else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (bm c)) (reduce Message termination_count (bm c s1 s2))) (reduce Message termination_count (bm c s2 owner)))) *)
(* Goal: or (not (@eq Site s2 s1)) (not (@eq Site owner s2)) *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: or (not (@eq Site s1 s2)) (not (@eq Site s2 owner)) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  rewrite collect_here.
(* Goal: Z.lt (Z.add (Z.add (sigma_but Site s2 eq_site_dec LS (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (termination_rt_count (Set_rec_table (rt c) s2 s2))) (Z.add (Z.add (sigma2_table Site LS LS (queue Message) (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s1 then if eq_site_dec s4 s2 then Z0 else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner)) (reduce Message termination_count (first_out Message (bm c s1 s2)))) (Z.add (reduce Message termination_count (bm c s2 owner)) (Zpos (xO xH))))) (Z.add (sigma Site LS (fun s : Site => termination_rt_count (rt c s))) (Z.add (Z.add (sigma2_table Site LS LS (queue Message) (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s1 then if eq_site_dec s4 s2 then Z0 else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (bm c)) (reduce Message termination_count (bm c s1 s2))) (reduce Message termination_count (bm c s2 owner)))) *)
(* Goal: or (not (@eq Site s2 s1)) (not (@eq Site owner s2)) *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: or (not (@eq Site s1 s2)) (not (@eq Site s2 owner)) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  rewrite reduce_first_out with (m := copy).
(* Goal: Z.lt (Z.add (Z.add (sigma_but Site s2 eq_site_dec LS (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (termination_rt_count (Set_rec_table (rt c) s2 s2))) (Z.add (Z.add (sigma2_table Site LS LS (queue Message) (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s1 then if eq_site_dec s4 s2 then Z0 else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner)) (Z.sub (reduce Message termination_count (bm c s1 s2)) (termination_count copy))) (Z.add (reduce Message termination_count (bm c s2 owner)) (Zpos (xO xH))))) (Z.add (sigma Site LS (fun s : Site => termination_rt_count (rt c s))) (Z.add (Z.add (sigma2_table Site LS LS (queue Message) (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s1 then if eq_site_dec s4 s2 then Z0 else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (bm c)) (reduce Message termination_count (bm c s1 s2))) (reduce Message termination_count (bm c s2 owner)))) *)
(* Goal: @eq (exc Message) (first Message (bm c s1 s2)) (value Message copy) *)
(* Goal: or (not (@eq Site s2 s1)) (not (@eq Site owner s2)) *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: or (not (@eq Site s1 s2)) (not (@eq Site s2 owner)) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  rewrite (sigma_sigma_but Site s2 eq_site_dec).
(* Goal: Z.lt (Z.add (Z.add (sigma_but Site s2 eq_site_dec LS (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (termination_rt_count (Set_rec_table (rt c) s2 s2))) (Z.add (Z.add (sigma2_table Site LS LS (queue Message) (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s1 then if eq_site_dec s4 s2 then Z0 else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner)) (Z.sub (reduce Message termination_count (bm c s1 s2)) (termination_count copy))) (Z.add (reduce Message termination_count (bm c s2 owner)) (Zpos (xO xH))))) (Z.add (Z.add (sigma_but Site s2 eq_site_dec LS (fun s : Site => termination_rt_count (rt c s))) (termination_rt_count (rt c s2))) (Z.add (Z.add (sigma2_table Site LS LS (queue Message) (fun (s3 s4 : Site) (d : queue Message) => if eq_site_dec s3 s1 then if eq_site_dec s4 s2 then Z0 else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (bm c)) (reduce Message termination_count (bm c s1 s2))) (reduce Message termination_count (bm c s2 owner)))) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: @eq (exc Message) (first Message (bm c s1 s2)) (value Message copy) *)
(* Goal: or (not (@eq Site s2 s1)) (not (@eq Site owner s2)) *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: or (not (@eq Site s1 s2)) (not (@eq Site s2 owner)) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  apply add_reduce22.
(* Goal: @eq Z (sigma2_table Site LS LS (queue Message) (rooted s0) (bm c0)) Z0 *)
(* Goal: legal c0 *)
(* Goal: not (@eq Site s0 owner) *)
  unfold sigma2_table in |- *.
(* Goal: @eq Z (sigma_table Site LS Z (Z_id Site) (fun s3 : Site => sigma_table Site LS (queue Message) (fun (s4 : Site) (d : queue Message) => if eq_site_dec s3 s1 then if eq_site_dec s4 s2 then Z0 else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (bm c s3))) (sigma_table Site LS Z (Z_id Site) (fun s3 : Site => sigma_table Site LS (queue Message) (fun (s4 : Site) (d : queue Message) => if eq_site_dec s3 s1 then if eq_site_dec s4 s2 then Z0 else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner s3))) *)
(* Goal: @eq Z (sigma_but Site s2 eq_site_dec LS (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (sigma_but Site s2 eq_site_dec LS (fun s : Site => termination_rt_count (rt c s))) *)
(* Goal: Z.lt (Z.add (Z.add (termination_rt_count (Set_rec_table (rt c) s2 s2)) (Z.sub (reduce Message termination_count (bm c s1 s2)) (termination_count copy))) (Z.add (reduce Message termination_count (bm c s2 owner)) (Zpos (xO xH)))) (Z.add (Z.add (termination_rt_count (rt c s2)) (reduce Message termination_count (bm c s1 s2))) (reduce Message termination_count (bm c s2 owner))) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: @eq (exc Message) (first Message (bm c s1 s2)) (value Message copy) *)
(* Goal: or (not (@eq Site s2 s1)) (not (@eq Site owner s2)) *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: or (not (@eq Site s1 s2)) (not (@eq Site s2 owner)) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  apply sigma_table_simpl.
(* Goal: @eq (forall _ : Site, Z) (fun s3 : Site => sigma_table Site LS (queue Message) (fun (s4 : Site) (d : queue Message) => if eq_site_dec s3 s1 then if eq_site_dec s4 s2 then Z0 else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (bm c s3)) (fun s3 : Site => sigma_table Site LS (queue Message) (fun (s4 : Site) (d : queue Message) => if eq_site_dec s3 s1 then if eq_site_dec s4 s2 then Z0 else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d else if eq_site_dec s3 s2 then if eq_site_dec s4 owner then Z0 else reduce Message termination_count d else reduce Message termination_count d) (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner s3)) *)
(* Goal: @eq Z (sigma_but Site s2 eq_site_dec LS (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (sigma_but Site s2 eq_site_dec LS (fun s : Site => termination_rt_count (rt c s))) *)
(* Goal: Z.lt (Z.add (Z.add (termination_rt_count (Set_rec_table (rt c) s2 s2)) (Z.sub (reduce Message termination_count (bm c s1 s2)) (termination_count copy))) (Z.add (reduce Message termination_count (bm c s2 owner)) (Zpos (xO xH)))) (Z.add (Z.add (termination_rt_count (rt c s2)) (reduce Message termination_count (bm c s1 s2))) (reduce Message termination_count (bm c s2 owner))) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: @eq (exc Message) (first Message (bm c s1 s2)) (value Message copy) *)
(* Goal: or (not (@eq Site s2 s1)) (not (@eq Site owner s2)) *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: or (not (@eq Site s1 s2)) (not (@eq Site s2 owner)) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  apply funct_eq.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  intro.
(* Goal: @eq Z (sigma_table Site LS Z (Z_id Site) (fun s1 : Site => sigma_table Site LS (queue Message) (rooted s0 s1) (bm c0 s1))) Z0 *)
(* Goal: legal c0 *)
(* Goal: not (@eq Site s0 owner) *)
  unfold sigma_table in |- *.
(* Goal: @eq Z (sigma Site LS (fun s : Site => if eq_site_dec e1 s1 then if eq_site_dec s s2 then Z0 else if eq_site_dec e1 s2 then if eq_site_dec s owner then Z0 else reduce Message termination_count (bm c e1 s) else reduce Message termination_count (bm c e1 s) else if eq_site_dec e1 s2 then if eq_site_dec s owner then Z0 else reduce Message termination_count (bm c e1 s) else reduce Message termination_count (bm c e1 s))) (sigma Site LS (fun s : Site => if eq_site_dec e1 s1 then if eq_site_dec s s2 then Z0 else if eq_site_dec e1 s2 then if eq_site_dec s owner then Z0 else reduce Message termination_count (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner e1 s) else reduce Message termination_count (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner e1 s) else if eq_site_dec e1 s2 then if eq_site_dec s owner then Z0 else reduce Message termination_count (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner e1 s) else reduce Message termination_count (Post_message Message (inc_dec s1) (Collect_message Message (bm c) s1 s2) s2 owner e1 s))) *)
(* Goal: @eq Z (sigma_but Site s2 eq_site_dec LS (fun s : Site => termination_rt_count (Set_rec_table (rt c) s2 s))) (sigma_but Site s2 eq_site_dec LS (fun s : Site => termination_rt_count (rt c s))) *)
(* Goal: Z.lt (Z.add (Z.add (termination_rt_count (Set_rec_table (rt c) s2 s2)) (Z.sub (reduce Message termination_count (bm c s1 s2)) (termination_count copy))) (Z.add (reduce Message termination_count (bm c s2 owner)) (Zpos (xO xH)))) (Z.add (Z.add (termination_rt_count (rt c s2)) (reduce Message termination_count (bm c s1 s2))) (reduce Message termination_count (bm c s2 owner))) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: @eq (exc Message) (first Message (bm c s1 s2)) (value Message copy) *)
(* Goal: or (not (@eq Site s2 s1)) (not (@eq Site owner s2)) *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: or (not (@eq Site s1 s2)) (not (@eq Site s2 owner)) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  apply sigma_simpl.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  case (eq_site_dec e1 s1); intro.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  case (eq_site_dec x s2); intro.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  case (eq_site_dec e1 s2); intro.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  case (eq_site_dec x owner); intro.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
(* Goal: forall _ : @eq (queue Message) (Post_message Message copy (bm c) s1 s2 x0 x1) (first_out Message (bm c x0 x1)), not True *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  rewrite post_elsewhere.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  rewrite collect_elsewhere; auto.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
(* Goal: forall _ : @eq (queue Message) (Post_message Message copy (bm c) s1 s2 x0 x1) (first_out Message (bm c x0 x1)), not True *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  rewrite post_elsewhere.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  rewrite collect_elsewhere; auto.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  case (eq_site_dec e1 s2); intro.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  case (eq_site_dec x owner); intro.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
(* Goal: forall _ : @eq (queue Message) (Post_message Message copy (bm c) s1 s2 x0 x1) (first_out Message (bm c x0 x1)), not True *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  rewrite post_elsewhere.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  rewrite collect_elsewhere; auto.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
(* Goal: forall _ : @eq (queue Message) (Post_message Message copy (bm c) s1 s2 x0 x1) (first_out Message (bm c x0 x1)), not True *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  rewrite post_elsewhere.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  rewrite collect_elsewhere; auto.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
(* Goal: @eq Z (sigma_but Site s eq_site_dec LS (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma_but Site s eq_site_dec LS (fun s : Site => termination_rt_count (rt c s))) *)
(* Goal: @eq Z (sigma2_but_table Site eq_site_dec LS LS (queue Message) s owner (fun (_ _ : Site) (q : queue Message) => reduce Message termination_count q) (bm c)) (sigma2_but_table Site eq_site_dec LS LS (queue Message) s owner (fun (_ _ : Site) (q : queue Message) => reduce Message termination_count q) (Post_message Message dec (bm c) s owner)) *)
(* Goal: Z.lt (Z.add (termination_rt_count (Reset_rec_table (rt c) s s)) (Zpos xH)) (termination_rt_count (rt c s)) *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
  apply sigma_but_simpl.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: @eq Z (termination_rt_count (change_site bool (rt c) s false s0)) (termination_rt_count (rt c s0)) *)
(* Goal: @eq Z (sigma2_but_table Site eq_site_dec LS LS (queue Message) s owner (fun (_ _ : Site) (q : queue Message) => reduce Message termination_count q) (bm c)) (sigma2_but_table Site eq_site_dec LS LS (queue Message) s owner (fun (_ _ : Site) (q : queue Message) => reduce Message termination_count q) (Post_message Message dec (bm c) s owner)) *)
(* Goal: Z.lt (Z.add (termination_rt_count (Reset_rec_table (rt c) s s)) (Zpos xH)) (termination_rt_count (rt c s)) *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
  unfold Set_rec_table in |- *; rewrite other_site.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
(* Goal: Z.lt (Z.add (Z.add (termination_rt_count (Set_rec_table (rt c) s2 s2)) (Z.sub (reduce Message termination_count (bm c s1 s2)) (termination_count copy))) (Z.add (reduce Message termination_count (bm c s2 owner)) (Zpos (xO xH)))) (Z.add (Z.add (termination_rt_count (rt c s2)) (reduce Message termination_count (bm c s1 s2))) (reduce Message termination_count (bm c s2 owner))) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: @eq (exc Message) (first Message (bm c s1 s2)) (value Message copy) *)
(* Goal: or (not (@eq Site s2 s1)) (not (@eq Site owner s2)) *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: or (not (@eq Site s1 s2)) (not (@eq Site s2 owner)) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  unfold Set_rec_table in |- *; rewrite that_site.
(* Goal: Z.lt (Z.add (Z.add (termination_rt_count true) (Z.sub (reduce Message termination_count (bm c s1 s2)) (termination_count copy))) (Z.add (reduce Message termination_count (bm c s2 owner)) (Zpos (xO xH)))) (Z.add (Z.add (termination_rt_count (rt c s2)) (reduce Message termination_count (bm c s1 s2))) (reduce Message termination_count (bm c s2 owner))) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: @eq (exc Message) (first Message (bm c s1 s2)) (value Message copy) *)
(* Goal: or (not (@eq Site s2 s1)) (not (@eq Site owner s2)) *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: or (not (@eq Site s1 s2)) (not (@eq Site s2 owner)) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  rewrite e.
(* Goal: Z.ge (termination_rt_count (rt c x_)) Z0 *)
(* Goal: Z.ge (sigma2_table Site LS LS (queue Message) termination_q_count (bm c)) Z0 *)
  unfold termination_rt_count in |- *.
(* Goal: Z.lt (Z.add (Z.add (Zpos (xO xH)) (Z.sub (reduce Message termination_count (bm c s1 s2)) (termination_count copy))) (Z.add (reduce Message termination_count (bm c s2 owner)) (Zpos (xO xH)))) (Z.add (Z.add Z0 (reduce Message termination_count (bm c s1 s2))) (reduce Message termination_count (bm c s2 owner))) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: @eq (exc Message) (first Message (bm c s1 s2)) (value Message copy) *)
(* Goal: or (not (@eq Site s2 s1)) (not (@eq Site owner s2)) *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec s1 LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: or (not (@eq Site s1 s2)) (not (@eq Site s2 owner)) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  cut (termination_count copy > 4)%Z.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  intro.
(* Goal: @eq Z Z0 Z0 *)
(* Goal: forall (a : E) (l : list E) (_ : @eq Z (sigma E l f) Z0), @eq Z (Z.add (f a) (sigma E l f)) Z0 *)
  omega.
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
  simpl in |- *.
(* Goal: @eq Z Z0 Z0 *)
(* Goal: forall (a : E) (l : list E) (_ : @eq Z (sigma E l f) Z0), @eq Z (Z.add (f a) (sigma E l f)) Z0 *)
  omega.
(* Goal: only_once Site eq_site_dec owner LS *)
  apply finite_site.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
(* Goal: only_once Site eq_site_dec owner LS *)
  apply finite_site.
(* Goal: only_once Site eq_site_dec owner LS *)
  apply finite_site.
(* Goal: only_once Site eq_site_dec owner LS *)
  apply finite_site.
(* Goal: only_once Site eq_site_dec owner LS *)
  apply finite_site.
(* Goal: or (not (@eq Site s1 s2)) (not (@eq Site s2 owner)) *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s2 LS *)
(* Goal: Z.lt (Z.add (sigma_table Site LS Z (Z_id Site) (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma2_table Site LS LS (queue Message) termination_q_count (Post_message Message dec (bm c) s owner))) (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  left; unfold not in |- *; intro; generalize e0.
(* Goal: @eq (queue Message) (bm c a0 a0) (empty Message) *)
(* Goal: sumbool (forall (s2 : Site) (_ : or (@eq Site a0 s2) (@In Site s2 l)), @eq (queue Message) (bm c a s2) (empty Message)) (not (forall (s2 : Site) (_ : or (@eq Site a0 s2) (@In Site s2 l)) (_ : not (@eq Site s2 a)), @eq (queue Message) (bm c a s2) (empty Message))) *)
(* Goal: sumbool (forall (s2 : Site) (_ : or (@eq Site a0 s2) (@In Site s2 l)), @eq (queue Message) (bm c a s2) (empty Message)) (not (forall (s2 : Site) (_ : or (@eq Site a0 s2) (@In Site s2 l)) (_ : not (@eq Site s2 a)), @eq (queue Message) (bm c a s2) (empty Message))) *)
  rewrite H1; rewrite empty_q_to_me.
(* Goal: forall _ : @eq (exc Message) (error Message) (value Message copy), False *)
(* Goal: @In Site s1 LS *)
(* Goal: @In Site s2 LS *)
(* Goal: False *)
  simpl in |- *; intro; discriminate.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
(* Goal: only_once Site eq_site_dec owner LS *)
  apply finite_site.
(* Goal: only_once Site eq_site_dec owner LS *)
  apply finite_site.
(* Goal: only_once Site eq_site_dec owner LS *)
  apply finite_site.
(* Goal: only_once Site eq_site_dec owner LS *)
  apply finite_site.
(* Goal: only_once Site eq_site_dec owner LS *)
  apply finite_site.


  (* 7 *)
  
  rewrite
   sigma2_sigma2_but_x_y
                         with
                         (s0 := s)
                        (s1 := owner)
                        (eq_site_dec := eq_site_dec).
(* Goal: forall _ : @eq (queue Message) (Post_message Message copy (bm c) x0 x1 x0 x1) (first_out Message (bm c x0 x1)), not True *)
(* Goal: forall _ : @eq (queue Message) (Post_message Message copy (bm c) s1 s2 x0 x1) (first_out Message (bm c x0 x1)), not True *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  rewrite post_here.
  rewrite
   sigma2_sigma2_but_x_y
                         with
                         (s0 := s)
                        (s1 := owner)
                        (eq_site_dec := eq_site_dec).
(* Goal: Z.ge (termination_q_count x_ x_0 (bm c x_ x_0)) Z0 *)
  unfold termination_q_count in |- *.
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
  simpl in |- *.
(* Goal: @eq Z (sigma_table Site LS Z (Z_id Site) (fun s1 : Site => sigma_table Site LS (queue Message) (rooted s0 s1) (bm c0 s1))) Z0 *)
(* Goal: legal c0 *)
(* Goal: not (@eq Site s0 owner) *)
  unfold sigma_table in |- *.
(* Goal: Z.lt (Z.add (Z.add (sigma_but Site s eq_site_dec LS (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (termination_rt_count (Reset_rec_table (rt c) s s))) (Z.add (sigma2_but_table Site eq_site_dec LS LS (queue Message) s owner (fun (_ _ : Site) (q : queue Message) => reduce Message termination_count q) (Post_message Message dec (bm c) s owner)) (Z.add (reduce Message termination_count (bm c s owner)) (Zpos xH)))) (Z.add (sigma Site LS (fun s : Site => termination_rt_count (rt c s))) (Z.add (sigma2_but_table Site eq_site_dec LS LS (queue Message) s owner (fun (_ _ : Site) (q : queue Message) => reduce Message termination_count q) (bm c)) (reduce Message termination_count (bm c s owner)))) *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
  rewrite (sigma_sigma_but Site s eq_site_dec).
(* Goal: @eq Z (sigma Site LS (fun s : Site => Z_id Site s (sigma Site LS (fun s1 : Site => rooted s0 s s1 (bm c0 s s1))))) Z0 *)
(* Goal: legal c0 *)
(* Goal: not (@eq Site s0 owner) *)
  unfold Z_id in |- *.
(* Goal: @eq Z (sigma_table Site LS Z (Z_id Site) (fun s1 : Site => sigma_table Site LS (queue Message) (rooted s0 s1) (bm c0 s1))) Z0 *)
(* Goal: legal c0 *)
(* Goal: not (@eq Site s0 owner) *)
  unfold sigma_table in |- *.
(* Goal: Z.lt (Z.add (Z.add (sigma_but Site s eq_site_dec LS (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (termination_rt_count (Reset_rec_table (rt c) s s))) (Z.add (sigma2_but_table Site eq_site_dec LS LS (queue Message) s owner (fun (_ _ : Site) (q : queue Message) => reduce Message termination_count q) (Post_message Message dec (bm c) s owner)) (Z.add (reduce Message termination_count (bm c s owner)) (Zpos xH)))) (Z.add (sigma Site LS (fun s : Site => termination_rt_count (rt c s))) (Z.add (sigma2_but_table Site eq_site_dec LS LS (queue Message) s owner (fun (_ _ : Site) (q : queue Message) => reduce Message termination_count q) (bm c)) (reduce Message termination_count (bm c s owner)))) *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
  rewrite (sigma_sigma_but Site s eq_site_dec).
(* Goal: Z.lt (Z.add (Z.add (sigma_but Site s eq_site_dec LS (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (termination_rt_count (Reset_rec_table (rt c) s s))) (Z.add (sigma2_but_table Site eq_site_dec LS LS (queue Message) s owner (fun (_ _ : Site) (q : queue Message) => reduce Message termination_count q) (Post_message Message dec (bm c) s owner)) (Z.add (reduce Message termination_count (bm c s owner)) (Zpos xH)))) (Z.add (Z.add (sigma_but Site s eq_site_dec LS (fun s : Site => termination_rt_count (rt c s))) (termination_rt_count (rt c s))) (Z.add (sigma2_but_table Site eq_site_dec LS LS (queue Message) s owner (fun (_ _ : Site) (q : queue Message) => reduce Message termination_count q) (bm c)) (reduce Message termination_count (bm c s owner)))) *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
  apply add_reduce14.
(* Goal: @eq Z (sigma_but Site s eq_site_dec LS (fun s0 : Site => termination_rt_count (Reset_rec_table (rt c) s s0))) (sigma_but Site s eq_site_dec LS (fun s : Site => termination_rt_count (rt c s))) *)
(* Goal: @eq Z (sigma2_but_table Site eq_site_dec LS LS (queue Message) s owner (fun (_ _ : Site) (q : queue Message) => reduce Message termination_count q) (bm c)) (sigma2_but_table Site eq_site_dec LS LS (queue Message) s owner (fun (_ _ : Site) (q : queue Message) => reduce Message termination_count q) (Post_message Message dec (bm c) s owner)) *)
(* Goal: Z.lt (Z.add (termination_rt_count (Reset_rec_table (rt c) s s)) (Zpos xH)) (termination_rt_count (rt c s)) *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
  apply sigma_but_simpl.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: @eq Z (termination_rt_count (Reset_rec_table (rt c) s s0)) (termination_rt_count (rt c s0)) *)
(* Goal: @eq Z (sigma2_but_table Site eq_site_dec LS LS (queue Message) s owner (fun (_ _ : Site) (q : queue Message) => reduce Message termination_count q) (bm c)) (sigma2_but_table Site eq_site_dec LS LS (queue Message) s owner (fun (_ _ : Site) (q : queue Message) => reduce Message termination_count q) (Post_message Message dec (bm c) s owner)) *)
(* Goal: Z.lt (Z.add (termination_rt_count (Reset_rec_table (rt c) s s)) (Zpos xH)) (termination_rt_count (rt c s)) *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
  unfold Reset_rec_table in |- *.
(* Goal: @eq Z (termination_rt_count (change_site bool (rt c) s false s0)) (termination_rt_count (rt c s0)) *)
(* Goal: @eq Z (sigma2_but_table Site eq_site_dec LS LS (queue Message) s owner (fun (_ _ : Site) (q : queue Message) => reduce Message termination_count q) (bm c)) (sigma2_but_table Site eq_site_dec LS LS (queue Message) s owner (fun (_ _ : Site) (q : queue Message) => reduce Message termination_count q) (Post_message Message dec (bm c) s owner)) *)
(* Goal: Z.lt (Z.add (termination_rt_count (Reset_rec_table (rt c) s s)) (Zpos xH)) (termination_rt_count (rt c s)) *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
  rewrite other_site.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
(* Goal: @eq Z (sigma2_but_table Site eq_site_dec LS LS (queue Message) s owner (fun (_ _ : Site) (q : queue Message) => reduce Message termination_count q) (bm c)) (sigma2_but_table Site eq_site_dec LS LS (queue Message) s owner (fun (_ _ : Site) (q : queue Message) => reduce Message termination_count q) (Post_message Message dec (bm c) s owner)) *)
(* Goal: Z.lt (Z.add (termination_rt_count (Reset_rec_table (rt c) s s)) (Zpos xH)) (termination_rt_count (rt c s)) *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
  apply sigma2_but_simpl2.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  case (eq_queue_dec s x owner y); intro.
(* Goal: @eq Z (reduce Message termination_count (bm c x y)) (reduce Message termination_count (Post_message Message dec (bm c) s owner x y)) *)
(* Goal: @eq Z (reduce Message termination_count (bm c x y)) (reduce Message termination_count (Post_message Message dec (bm c) s owner x y)) *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: Z.lt (Z.add (termination_rt_count (Reset_rec_table (rt c) s s)) (Zpos xH)) (termination_rt_count (rt c s)) *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
  elim H1; decompose [and] a.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  split; auto.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  rewrite post_elsewhere; auto.
(* Goal: only_once Site eq_site_dec owner LS *)
  apply finite_site.
(* Goal: only_once Site eq_site_dec owner LS *)
  apply finite_site.
(* Goal: Z.lt (Z.add (termination_rt_count (Reset_rec_table (rt c) s s)) (Zpos xH)) (termination_rt_count (rt c s)) *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
 unfold Reset_rec_table in |- *; rewrite that_site.
(* Goal: Z.lt (Z.add (termination_rt_count false) (Zpos xH)) (termination_rt_count (rt c s)) *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
(* Goal: only_once Site eq_site_dec s LS *)
(* Goal: only_once Site eq_site_dec owner LS *)
  rewrite e0.
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
  unfold termination_rt_count in |- *; simpl in |- *.
(* Goal: @eq Z Z0 Z0 *)
(* Goal: forall (a : E) (l : list E) (_ : @eq Z (sigma E l f) Z0), @eq Z (Z.add (f a) (sigma E l f)) Z0 *)
  omega.
(* Goal: only_once Site eq_site_dec owner LS *)
  apply finite_site.
(* Goal: only_once Site eq_site_dec owner LS *)
  apply finite_site.
(* Goal: only_once Site eq_site_dec owner LS *)
  apply finite_site.
(* Goal: only_once Site eq_site_dec owner LS *)
  apply finite_site.
(* Goal: only_once Site eq_site_dec owner LS *)
  apply finite_site.
(* Goal: only_once Site eq_site_dec owner LS *)
  apply finite_site.
Qed.

Lemma termination_measure_positive :
 forall c : Config, (0 <= termination_measure c)%Z.
Proof.
(* Goal: forall c : Config, Z.le Z0 (termination_measure c) *)
  unfold termination_measure in |- *.
(* Goal: forall c : Config, Z.le Z0 (Z.add (termination_rt_measure (rt c)) (termination_q_measure (bm c))) *)
  unfold termination_rt_measure, termination_q_measure in |- *.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: Z.le Z0 (Z.add (sigma_table Site LS Z (Z_id Site) (fun s : Site => termination_rt_count (rt c s))) (sigma2_table Site LS LS (queue Message) termination_q_count (bm c))) *)
  apply add_reduce23.
(* Goal: @eq Z (sigma_table Site LS Z (Z_id Site) (fun s1 : Site => sigma_table Site LS (queue Message) (rooted s0 s1) (bm c0 s1))) Z0 *)
(* Goal: legal c0 *)
(* Goal: not (@eq Site s0 owner) *)
  unfold sigma_table in |- *.
(* Goal: Z.ge (sigma Site LS (fun s : Site => termination_q_count x_ s (bm c x_ s))) Z0 *)
  apply sigma_pos.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: @eq Z (sigma Site LS (fun s : Site => Z_id Site s (sigma Site LS (fun s1 : Site => rooted s0 s s1 (bm c0 s s1))))) Z0 *)
(* Goal: legal c0 *)
(* Goal: not (@eq Site s0 owner) *)
  unfold Z_id in |- *.
(* Goal: Z.ge (termination_rt_count (rt c x_)) Z0 *)
(* Goal: Z.ge (sigma2_table Site LS LS (queue Message) termination_q_count (bm c)) Z0 *)
  unfold termination_rt_count in |- *.
(* Goal: Z.ge (if rt c x_ then Zpos (xO xH) else Z0) Z0 *)
(* Goal: Z.ge (sigma2_table Site LS LS (queue Message) termination_q_count (bm c)) Z0 *)
  case (rt c x_).
(* Goal: @eq Z Z0 Z0 *)
(* Goal: forall (a : E) (l : list E) (_ : @eq Z (sigma E l f) Z0), @eq Z (Z.add (f a) (sigma E l f)) Z0 *)
  omega.
  
(* Goal: @eq Z Z0 Z0 *)
(* Goal: forall (a : E) (l : list E) (_ : @eq Z (sigma E l f) Z0), @eq Z (Z.add (f a) (sigma E l f)) Z0 *)
  omega.
  
(* Goal: @eq Z (sigma2_table Site LS LS (queue Message) (rooted s0) (bm c0)) Z0 *)
(* Goal: legal c0 *)
(* Goal: not (@eq Site s0 owner) *)
  unfold sigma2_table in |- *.
(* Goal: @eq Z (sigma_table Site LS Z (Z_id Site) (fun s1 : Site => sigma_table Site LS (queue Message) (rooted s0 s1) (bm c0 s1))) Z0 *)
(* Goal: legal c0 *)
(* Goal: not (@eq Site s0 owner) *)
  unfold sigma_table in |- *.
(* Goal: Z.ge (sigma Site LS (fun s : Site => termination_q_count x_ s (bm c x_ s))) Z0 *)
  apply sigma_pos.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: @eq Z (sigma Site LS (fun s : Site => Z_id Site s (sigma Site LS (fun s1 : Site => rooted s0 s s1 (bm c0 s s1))))) Z0 *)
(* Goal: legal c0 *)
(* Goal: not (@eq Site s0 owner) *)
  unfold Z_id in |- *.
(* Goal: Z.ge (sigma Site LS (fun s : Site => termination_q_count x_ s (bm c x_ s))) Z0 *)
  apply sigma_pos.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: Z.ge (termination_q_count x_ x_0 (bm c x_ x_0)) Z0 *)
  unfold termination_q_count in |- *.
(* Goal: Z.ge (reduce Message termination_count (bm c x_ x_0)) Z0 *)
  apply reduce_positive_or_null.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: Z.ge (termination_count a) Z0 *)
  unfold termination_count in |- *.
(* Goal: Z.ge match a with | dec => Zpos xH | inc_dec s3 => Zpos (xO xH) | copy => Zpos (xI (xO xH)) end Z0 *)
  case a.
(* Goal: @eq Z Z0 Z0 *)
(* Goal: forall (a : E) (l : list E) (_ : @eq Z (sigma E l f) Z0), @eq Z (Z.add (f a) (sigma E l f)) Z0 *)
  omega.
  
(* Goal: @eq Z Z0 Z0 *)
(* Goal: forall (a : E) (l : list E) (_ : @eq Z (sigma E l f) Z0), @eq Z (Z.add (f a) (sigma E l f)) Z0 *)
  intro; omega.
  
(* Goal: @eq Z Z0 Z0 *)
(* Goal: forall (a : E) (l : list E) (_ : @eq Z (sigma E l f) Z0), @eq Z (Z.add (f a) (sigma E l f)) Z0 *)
  omega.
Qed.

Definition no_rt (c : Config) :=
  forall s1 : Site, In s1 LS -> s1 <> owner -> rt c s1 = false.

Lemma decide_no_rt :
 forall c : Config,
 {no_rt c} + {(exists s1 : Site, s1 <> owner /\ rt c s1 = true)}.
Proof.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: sumbool (no_rt c) (@ex Site (fun s1 : Site => and (not (@eq Site s1 owner)) (@eq bool (rt c s1) true))) *)
  unfold no_rt in |- *.
(* Goal: sumbool (forall (s1 : Site) (_ : @In Site s1 LS) (_ : not (@eq Site s1 owner)), @eq bool (rt c s1) false) (@ex Site (fun s1 : Site => and (not (@eq Site s1 owner)) (@eq bool (rt c s1) true))) *)
  elim LS.
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
  simpl in |- *.
(* Goal: sumbool (forall (s1 : Site) (_ : False) (_ : not (@eq Site s1 owner)), @eq bool (rt c s1) false) (@ex Site (fun s1 : Site => and (not (@eq Site s1 owner)) (@eq bool (rt c s1) true))) *)
(* Goal: forall (a : Site) (l : list Site) (_ : sumbool (forall (s1 : Site) (_ : @In Site s1 l) (_ : not (@eq Site s1 owner)), @eq bool (rt c s1) false) (@ex Site (fun s1 : Site => and (not (@eq Site s1 owner)) (@eq bool (rt c s1) true)))), sumbool (forall (s1 : Site) (_ : @In Site s1 (@cons Site a l)) (_ : not (@eq Site s1 owner)), @eq bool (rt c s1) false) (@ex Site (fun s1 : Site => and (not (@eq Site s1 owner)) (@eq bool (rt c s1) true))) *)
  left; contradiction.
  
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  case (eq_site_dec a owner); intro.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  elim H; intro.
(* Goal: sumor (@sig legal_config (fun y : legal_config => no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) (forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) *)
(* Goal: forall _ : forall t : class_trans c, copy_p c t, sumor (@sig legal_config (fun y : legal_config => no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) (forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) *)
  left.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
  generalize H0; simpl in |- *.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  case (eq_site_dec s1 a); intro.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  elim H1; rewrite e0; auto.
  
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  intro.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  elim H2; auto.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intro; elim n; auto.
  
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  right; auto.
  
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  elim (decide_rt c a); intro.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  elim H; intro.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  left; intros.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  case (eq_site_dec s1 a); intro.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  rewrite e; auto.
  
(* Goal: @eq bool (rt c s1) false *)
(* Goal: sumbool (forall (s1 : Site) (_ : @In Site s1 (@cons Site a l)) (_ : not (@eq Site s1 owner)), @eq bool (rt c s1) false) (@ex Site (fun s1 : Site => and (not (@eq Site s1 owner)) (@eq bool (rt c s1) true))) *)
(* Goal: sumbool (forall (s1 : Site) (_ : @In Site s1 (@cons Site a l)) (_ : not (@eq Site s1 owner)), @eq bool (rt c s1) false) (@ex Site (fun s1 : Site => and (not (@eq Site s1 owner)) (@eq bool (rt c s1) true))) *)
  apply a1.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  generalize H0; simpl in |- *; intro.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  elim H2; intro; auto.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  elim n0; auto.
  
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
  
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  right; auto.
  
(* Goal: sumor (@sig legal_config (fun y : legal_config => no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) (forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) *)
  right.
(* Goal: @ex Site (fun s1 : Site => and (not (@eq Site s1 owner)) (@eq bool (rt c s1) true)) *)
  split with a.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
Qed.


(** to be complete, we might represent explicitly a local gc! 
and we could try to prove something like this.
 If there is a s1, it means that the gc is has kicked in 


Variable local_gc: Config -> Site -> bool.


Lemma decide_no_rt_gc:
  (c:Config) 
   {(s1:Site) (In s1 LS) -> ~(s1=owner) ->  (rt c s1)=true -> (local_gc c s1)=false}
   +
   {(EX s1:Site |  (In s1 LS) -> ~(s1=owner) /\ (rt c s1)=true /\ (local_gc c s1)=true)}.

*)

Lemma blocked_config :
 forall c : Config,
 legal c ->
 no_message c -> no_rt c -> ~ (exists t : class_trans c, ~ copy_p c t).
Proof.
(* Goal: forall (c : Config) (_ : legal c) (_ : no_message c) (_ : no_rt c) (t : class_trans c), copy_p c t *)
  unfold no_message, no_rt in |- *.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  unfold not in |- *; intro.
(* Goal: no_message c *)
  elim H2.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  simple induction x; simpl in |- *; intros.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  apply H3; auto.
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
  generalize e.
(* Goal: forall _ : @eq (exc Message) (first Message (bm c s1 s2)) (value Message copy), False *)
(* Goal: False *)
  rewrite H0.
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
  simpl in |- *.
(* Goal: forall _ : @eq (exc Message) (error Message) (value Message copy), False *)
(* Goal: @In Site s1 LS *)
(* Goal: @In Site s2 LS *)
(* Goal: False *)
  intro; discriminate.
(* Goal: @In Site x_0 LS *)
(* Goal: legal c0 *)
(* Goal: not (@eq Site s0 owner) *)
  apply in_s_LS.
(* Goal: @In Site x_0 LS *)
(* Goal: legal c0 *)
(* Goal: not (@eq Site s0 owner) *)
  apply in_s_LS.
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
  generalize e.
(* Goal: forall _ : @eq (exc Message) (first Message (bm c s1 s2)) (value Message copy), False *)
(* Goal: False *)
  rewrite H0.
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
  simpl in |- *.
(* Goal: forall _ : @eq (exc Message) (error Message) (value Message copy), False *)
(* Goal: @In Site s1 LS *)
(* Goal: @In Site s2 LS *)
(* Goal: False *)
  intro; discriminate.
(* Goal: @In Site x_0 LS *)
(* Goal: legal c0 *)
(* Goal: not (@eq Site s0 owner) *)
  apply in_s_LS.
(* Goal: @In Site x_0 LS *)
(* Goal: legal c0 *)
(* Goal: not (@eq Site s0 owner) *)
  apply in_s_LS.
(* Goal: False *)
(* Goal: False *)
  generalize e0.
(* Goal: forall _ : @eq (exc Message) (first Message (bm c s1 s2)) (value Message copy), False *)
(* Goal: False *)
  rewrite H0.
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
  simpl in |- *.
(* Goal: forall _ : @eq (exc Message) (error Message) (value Message copy), False *)
(* Goal: @In Site s1 LS *)
(* Goal: @In Site s2 LS *)
(* Goal: False *)
  intro; discriminate.
(* Goal: @In Site x_0 LS *)
(* Goal: legal c0 *)
(* Goal: not (@eq Site s0 owner) *)
  apply in_s_LS.
(* Goal: @In Site x_0 LS *)
(* Goal: legal c0 *)
(* Goal: not (@eq Site s0 owner) *)
  apply in_s_LS.
(* Goal: False *)
(* Goal: False *)
  generalize e0.
(* Goal: forall _ : @eq (exc Message) (first Message (bm c s1 s2)) (value Message copy), False *)
(* Goal: False *)
  rewrite H0.
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
  simpl in |- *.
(* Goal: forall _ : @eq (exc Message) (error Message) (value Message copy), False *)
(* Goal: @In Site s1 LS *)
(* Goal: @In Site s2 LS *)
(* Goal: False *)
  intro; discriminate.
(* Goal: @In Site x_0 LS *)
(* Goal: legal c0 *)
(* Goal: not (@eq Site s0 owner) *)
  apply in_s_LS.
(* Goal: @In Site x_0 LS *)
(* Goal: legal c0 *)
(* Goal: not (@eq Site s0 owner) *)
  apply in_s_LS.
(* Goal: False *)
(* Goal: False *)
  generalize e0.
(* Goal: forall _ : @eq (exc Message) (first Message (bm c s1 s2)) (value Message copy), False *)
(* Goal: False *)
  rewrite H0.
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
  simpl in |- *.
(* Goal: forall _ : @eq (exc Message) (error Message) (value Message copy), False *)
(* Goal: @In Site s1 LS *)
(* Goal: @In Site s2 LS *)
(* Goal: False *)
  intro; discriminate.
(* Goal: @In Site x_0 LS *)
(* Goal: legal c0 *)
(* Goal: not (@eq Site s0 owner) *)
  apply in_s_LS.
(* Goal: @In Site x_0 LS *)
(* Goal: legal c0 *)
(* Goal: not (@eq Site s0 owner) *)
  apply in_s_LS.
(* Goal: not (@eq (queue E) (input E d (input E e q1)) (first_out E (input E d (input E e q1)))) *)
(* Goal: @eq (queue E) (first_out E (input E d (input E e q1))) (input E d (first_out E (input E e q1))) *)
  generalize e0; rewrite H1.
(* Goal: not (@eq (queue E) (input E d (empty E)) (empty E)) *)
(* Goal: forall (e : E) (q : queue E) (_ : forall (m : E) (_ : @eq (exc E) (first E (input E e q)) (value E m)), not (@eq (queue E) (input E e q) (first_out E (input E e q)))) (m : E) (_ : @eq (exc E) (first E (input E d (input E e q))) (value E m)), not (@eq (queue E) (input E d (input E e q)) (first_out E (input E d (input E e q)))) *)
  discriminate.
(* Goal: @In Site x_0 LS *)
(* Goal: legal c0 *)
(* Goal: not (@eq Site s0 owner) *)
  apply in_s_LS.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
Qed.

Lemma blocked_config2 :
 forall c : Config,
 legal c -> no_message c -> no_rt c -> forall t : class_trans c, copy_p c t.
Proof.
(* Goal: forall (c : Config) (_ : legal c) (_ : no_message c) (_ : no_rt c) (t : class_trans c), copy_p c t *)
  unfold no_message, no_rt in |- *.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  simple induction t; simpl in |- *; intros; auto.
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
  generalize e.
(* Goal: forall _ : @eq (exc Message) (first Message (bm c s1 s2)) (value Message copy), False *)
(* Goal: False *)
  rewrite H0.
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
  simpl in |- *.
(* Goal: forall _ : @eq (exc Message) (error Message) (value Message copy), False *)
(* Goal: @In Site s1 LS *)
(* Goal: @In Site s2 LS *)
(* Goal: False *)
  intro; discriminate.
(* Goal: @In Site x_0 LS *)
(* Goal: legal c0 *)
(* Goal: not (@eq Site s0 owner) *)
  apply in_s_LS.
(* Goal: @In Site x_0 LS *)
(* Goal: legal c0 *)
(* Goal: not (@eq Site s0 owner) *)
  apply in_s_LS.
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
(* Goal: False *)
  generalize e.
(* Goal: forall _ : @eq (exc Message) (first Message (bm c s1 s2)) (value Message copy), False *)
(* Goal: False *)
  rewrite H0.
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
  simpl in |- *.
(* Goal: forall _ : @eq (exc Message) (error Message) (value Message copy), False *)
(* Goal: @In Site s1 LS *)
(* Goal: @In Site s2 LS *)
(* Goal: False *)
  intro; discriminate.
(* Goal: @In Site x_0 LS *)
(* Goal: legal c0 *)
(* Goal: not (@eq Site s0 owner) *)
  apply in_s_LS.
(* Goal: @In Site x_0 LS *)
(* Goal: legal c0 *)
(* Goal: not (@eq Site s0 owner) *)
  apply in_s_LS.
(* Goal: False *)
(* Goal: False *)
  generalize e0.
(* Goal: forall _ : @eq (exc Message) (first Message (bm c s1 s2)) (value Message copy), False *)
(* Goal: False *)
  rewrite H0.
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
  simpl in |- *.
(* Goal: forall _ : @eq (exc Message) (error Message) (value Message copy), False *)
(* Goal: @In Site s1 LS *)
(* Goal: @In Site s2 LS *)
(* Goal: False *)
  intro; discriminate.
(* Goal: @In Site x_0 LS *)
(* Goal: legal c0 *)
(* Goal: not (@eq Site s0 owner) *)
  apply in_s_LS.
(* Goal: @In Site x_0 LS *)
(* Goal: legal c0 *)
(* Goal: not (@eq Site s0 owner) *)
  apply in_s_LS.
(* Goal: False *)
(* Goal: False *)
  generalize e0.
(* Goal: forall _ : @eq (exc Message) (first Message (bm c s1 s2)) (value Message copy), False *)
(* Goal: False *)
  rewrite H0.
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
  simpl in |- *.
(* Goal: forall _ : @eq (exc Message) (error Message) (value Message copy), False *)
(* Goal: @In Site s1 LS *)
(* Goal: @In Site s2 LS *)
(* Goal: False *)
  intro; discriminate.
(* Goal: @In Site x_0 LS *)
(* Goal: legal c0 *)
(* Goal: not (@eq Site s0 owner) *)
  apply in_s_LS.
(* Goal: @In Site x_0 LS *)
(* Goal: legal c0 *)
(* Goal: not (@eq Site s0 owner) *)
  apply in_s_LS.
(* Goal: False *)
(* Goal: False *)
  generalize e0.
(* Goal: forall _ : @eq (exc Message) (first Message (bm c s1 s2)) (value Message copy), False *)
(* Goal: False *)
  rewrite H0.
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
  simpl in |- *.
(* Goal: forall _ : @eq (exc Message) (error Message) (value Message copy), False *)
(* Goal: @In Site s1 LS *)
(* Goal: @In Site s2 LS *)
(* Goal: False *)
  intro; discriminate.
(* Goal: @In Site x_0 LS *)
(* Goal: legal c0 *)
(* Goal: not (@eq Site s0 owner) *)
  apply in_s_LS.
(* Goal: @In Site x_0 LS *)
(* Goal: legal c0 *)
(* Goal: not (@eq Site s0 owner) *)
  apply in_s_LS.
(* Goal: not (@eq (queue E) (input E d (input E e q1)) (first_out E (input E d (input E e q1)))) *)
(* Goal: @eq (queue E) (first_out E (input E d (input E e q1))) (input E d (first_out E (input E e q1))) *)
  generalize e0; rewrite H1.
(* Goal: not (@eq (queue E) (input E d (empty E)) (empty E)) *)
(* Goal: forall (e : E) (q : queue E) (_ : forall (m : E) (_ : @eq (exc E) (first E (input E e q)) (value E m)), not (@eq (queue E) (input E e q) (first_out E (input E e q)))) (m : E) (_ : @eq (exc E) (first E (input E d (input E e q))) (value E m)), not (@eq (queue E) (input E d (input E e q)) (first_out E (input E d (input E e q)))) *)
  discriminate.
(* Goal: @In Site x_0 LS *)
(* Goal: legal c0 *)
(* Goal: not (@eq Site s0 owner) *)
  apply in_s_LS.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
Qed.



Section LOGIC.
Variable U : Set.

Lemma ex_not_not_all :
 forall P : U -> Prop, (exists n : U, ~ P n) -> ~ (forall n : U, P n).
Proof.
(* Goal: forall (P : forall _ : U, Prop) (_ : @ex U (fun n : U => P n)), not (forall n : U, not (P n)) *)
unfold not in |- *; intros P exnot allP.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
elim exnot; auto.
Qed.


Lemma ex_not_not_all2 :
 forall P : U -> Prop, (exists n : U, P n) -> ~ (forall n : U, ~ P n).
Proof.
(* Goal: forall (P : forall _ : U, Prop) (_ : @ex U (fun n : U => P n)), not (forall n : U, not (P n)) *)
  unfold not in |- *; intros P exnot allP.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  elim exnot; auto.
Qed.

Lemma PNNP : forall p : Prop, p -> ~ ~ p.
Proof.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
intros.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
auto.
Qed.

End LOGIC.


Lemma sigma_f_null :
 forall (E : Set) (f : E -> Z) (l : list E),
 (forall x_ : E, f x_ = 0%Z) -> sigma E l f = 0%Z.
Proof.
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
 intros; elim l; simpl in |- *.
(* Goal: @eq Z Z0 Z0 *)
(* Goal: forall (a : E) (l : list E) (_ : @eq Z (sigma E l f) Z0), @eq Z (Z.add (f a) (sigma E l f)) Z0 *)
 omega.

(* Goal: @eq Z Z0 Z0 *)
(* Goal: forall (a : E) (l : list E) (_ : @eq Z (sigma E l f) Z0), @eq Z (Z.add (f a) (sigma E l f)) Z0 *)
 intros; generalize (H a); omega.
Qed.


Lemma null_st :
 forall (c0 : Config) (s0 : Site),
 legal c0 -> s0 <> owner -> no_message c0 -> st c0 s0 = 0%Z.
Proof.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: @eq Z (st c0 s0) Z0 *)
  rewrite invariant2.
(* Goal: @eq Z (sigma_rooted s0 (bm c0)) Z0 *)
(* Goal: legal c0 *)
(* Goal: not (@eq Site s0 owner) *)
  unfold sigma_rooted in |- *.
(* Goal: @eq Z (sigma2_table Site LS LS (queue Message) (rooted s0) (bm c0)) Z0 *)
(* Goal: legal c0 *)
(* Goal: not (@eq Site s0 owner) *)
  unfold sigma2_table in |- *.
(* Goal: @eq Z (sigma_table Site LS Z (Z_id Site) (fun s1 : Site => sigma_table Site LS (queue Message) (rooted s0 s1) (bm c0 s1))) Z0 *)
(* Goal: legal c0 *)
(* Goal: not (@eq Site s0 owner) *)
  unfold sigma_table in |- *.
(* Goal: @eq Z (sigma Site LS (fun s : Site => Z_id Site s (sigma Site LS (fun s1 : Site => rooted s0 s s1 (bm c0 s s1))))) Z0 *)
(* Goal: legal c0 *)
(* Goal: not (@eq Site s0 owner) *)
  unfold Z_id in |- *.
(* Goal: @eq Z (sigma Site LS (fun s : Site => rooted s0 x_ s (bm c0 x_ s))) Z0 *)
(* Goal: legal c0 *)
(* Goal: not (@eq Site s0 owner) *)
  apply sigma_f_null.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: @eq Z (sigma Site LS (fun s : Site => rooted s0 x_ s (bm c0 x_ s))) Z0 *)
(* Goal: legal c0 *)
(* Goal: not (@eq Site s0 owner) *)
  apply sigma_f_null.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: forall (c : Config) (_ : legal c) (_ : not (no_message c)), @ex Site (fun s1 : Site => @ex Site (fun s2 : Site => and (not (@eq Site s1 s2)) (not (@eq (queue Message) (bm c s1 s2) (empty Message))))) *)
  generalize H1; unfold no_message in |- *.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  intro.
(* Goal: @eq Z (rooted s0 x_ x_0 (bm c0 x_ x_0)) Z0 *)
(* Goal: legal c0 *)
(* Goal: not (@eq Site s0 owner) *)
  rewrite H2.
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
  simpl in |- *.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
(* Goal: @In Site x_0 LS *)
(* Goal: legal c0 *)
(* Goal: not (@eq Site s0 owner) *)
  apply in_s_LS.
(* Goal: @In Site x_0 LS *)
(* Goal: legal c0 *)
(* Goal: not (@eq Site s0 owner) *)
  apply in_s_LS.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
Qed.

Lemma not_empty_implies_last :
 forall (E : Set) (q : queue E),
 q <> empty E -> exists x : E, first E q = value E x.
Proof.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  intro.
(* Goal: forall (q : queue E) (m : E) (_ : @eq (exc E) (first E q) (value E m)), not (@eq (queue E) q (first_out E q)) *)
  simple induction q.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  elim H; auto.
(* Goal: forall (d : E) (q : queue E) (_ : forall _ : not (@eq (queue E) q (empty E)), @ex E (fun x : E => @eq (exc E) (first E q) (value E x))) (_ : not (@eq (queue E) (input E d q) (empty E))), @ex E (fun x : E => @eq (exc E) (first E (input E d q)) (value E x)) *)
  intros d q0.
(* Goal: forall (_ : forall (m : E) (_ : @eq (exc E) (first E q0) (value E m)), not (@eq (queue E) q0 (first_out E q0))) (m : E) (_ : @eq (exc E) (first E (input E d q0)) (value E m)), not (@eq (queue E) (input E d q0) (first_out E (input E d q0))) *)
  case q0.
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
  simpl in |- *.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: @ex E (fun x : E => @eq (exc E) (value E d) (value E x)) *)
(* Goal: forall (e : E) (q : queue E) (_ : forall _ : not (@eq (queue E) (input E e q) (empty E)), @ex E (fun x : E => @eq (exc E) (first E (input E e q)) (value E x))) (_ : not (@eq (queue E) (input E d (input E e q)) (empty E))), @ex E (fun x : E => @eq (exc E) (first E (input E d (input E e q))) (value E x)) *)
  split with d.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
  simpl in |- *.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: @ex E (fun x : E => @eq (exc E) match q1 with | @empty _ => value E e | @input _ d q => first E q1 end (value E x)) *)
  apply H.
(* Goal: not (@eq (queue E) (input E d (empty E)) (empty E)) *)
(* Goal: forall (e : E) (q : queue E) (_ : forall (m : E) (_ : @eq (exc E) (first E (input E e q)) (value E m)), not (@eq (queue E) (input E e q) (first_out E (input E e q)))) (m : E) (_ : @eq (exc E) (first E (input E d (input E e q))) (value E m)), not (@eq (queue E) (input E d (input E e q)) (first_out E (input E d (input E e q)))) *)
  discriminate.
Qed.

Lemma different_queue1 :
 forall (E : Set) (q : queue E) (m : E), input E m q <> first_out E q.
Proof.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  intro.
(* Goal: forall (q : queue E) (m : E) (_ : @eq (exc E) (first E q) (value E m)), not (@eq (queue E) q (first_out E q)) *)
  simple induction q.
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
  simpl in |- *.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: not (@eq (queue E) (input E d (empty E)) (empty E)) *)
(* Goal: forall (e : E) (q : queue E) (_ : forall (m : E) (_ : @eq (exc E) (first E (input E e q)) (value E m)), not (@eq (queue E) (input E e q) (first_out E (input E e q)))) (m : E) (_ : @eq (exc E) (first E (input E d (input E e q))) (value E m)), not (@eq (queue E) (input E d (input E e q)) (first_out E (input E d (input E e q)))) *)
  discriminate.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
  simpl in |- *.
(* Goal: forall _ : not (no_message (get_c (last_successor y0))), no_message (get_c (last_successor y0)) *)
  generalize H.
(* Goal: forall (_ : forall (m : E) (_ : @eq (exc E) (first E q0) (value E m)), not (@eq (queue E) q0 (first_out E q0))) (m : E) (_ : @eq (exc E) (first E (input E d q0)) (value E m)), not (@eq (queue E) (input E d q0) (first_out E (input E d q0))) *)
  case q0.
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
  simpl in |- *.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: not (@eq (queue E) (input E d (empty E)) (empty E)) *)
(* Goal: forall (e : E) (q : queue E) (_ : forall (m : E) (_ : @eq (exc E) (first E (input E e q)) (value E m)), not (@eq (queue E) (input E e q) (first_out E (input E e q)))) (m : E) (_ : @eq (exc E) (first E (input E d (input E e q))) (value E m)), not (@eq (queue E) (input E d (input E e q)) (first_out E (input E d (input E e q)))) *)
  discriminate.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: not (@eq (queue E) (input E m (input E d (input E e q1))) (input E d (first_out E (input E e q1)))) *)
  cut (input E d (input E e q1) <> first_out E (input E e q1)).
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  intro.
(* Goal: not (@eq (queue E) (input E d (input E e q1)) (input E d (first_out E (input E e q1)))) *)
(* Goal: @eq (queue E) (first_out E (input E d (input E e q1))) (input E d (first_out E (input E e q1))) *)
  injection.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  elim H1; auto.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
Qed.

Lemma different_queue2 :
 forall (E : Set) (q : queue E) (m : E),
 first E q = value E m -> q <> first_out E q.
Proof.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  intro.
(* Goal: forall (q : queue E) (m : E) (_ : @eq (exc E) (first E q) (value E m)), not (@eq (queue E) q (first_out E q)) *)
  simple induction q.
(* Goal: forall (_ : legal config_init) (s1 s2 : Site) (m : Message) (_ : @eq (exc Message) (error Message) (value Message m)), @ex (class_trans config_init) (fun t : class_trans config_init => and (legal (transition config_init t)) (@eq (queue Message) (bm (transition config_init t) s1 s2) (empty Message))) *)
(* Goal: forall (c : Config) (t : class_trans c) (_ : legal c) (_ : forall (_ : legal c) (s1 s2 : Site) (m : Message) (_ : @eq (exc Message) (first Message (bm c s1 s2)) (value Message m)), @ex (class_trans c) (fun t0 : class_trans c => and (legal (transition c t0)) (@eq (queue Message) (bm (transition c t0) s1 s2) (first_out Message (bm c s1 s2))))) (_ : legal (transition c t)) (s1 s2 : Site) (m : Message) (_ : @eq (exc Message) (first Message (bm (transition c t) s1 s2)) (value Message m)), @ex (class_trans (transition c t)) (fun t0 : class_trans (transition c t) => and (legal (transition (transition c t) t0)) (@eq (queue Message) (bm (transition (transition c t) t0) s1 s2) (first_out Message (bm (transition c t) s1 s2)))) *)
  simpl in |- *; intros; discriminate.
  
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  intro; intro.
(* Goal: forall (_ : forall (m : E) (_ : @eq (exc E) (first E q0) (value E m)), not (@eq (queue E) q0 (first_out E q0))) (m : E) (_ : @eq (exc E) (first E (input E d q0)) (value E m)), not (@eq (queue E) (input E d q0) (first_out E (input E d q0))) *)
  case q0.
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
  simpl in |- *.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: not (@eq (queue E) (input E d (empty E)) (empty E)) *)
(* Goal: forall (e : E) (q : queue E) (_ : forall (m : E) (_ : @eq (exc E) (first E (input E e q)) (value E m)), not (@eq (queue E) (input E e q) (first_out E (input E e q)))) (m : E) (_ : @eq (exc E) (first E (input E d (input E e q))) (value E m)), not (@eq (queue E) (input E d (input E e q)) (first_out E (input E d (input E e q)))) *)
  discriminate.
  
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
  cut
   (first_out E (input E d (input E e q1)) =
    input E d (first_out E (input E e q1))).
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  intro.
(* Goal: not (@eq (queue E) (input E d (input E e q1)) (first_out E (input E d (input E e q1)))) *)
(* Goal: @eq (queue E) (first_out E (input E d (input E e q1))) (input E d (first_out E (input E e q1))) *)
  rewrite H1.
(* Goal: not (@eq (queue E) (input E d (input E e q1)) (input E d (first_out E (input E e q1)))) *)
(* Goal: @eq (queue E) (first_out E (input E d (input E e q1))) (input E d (first_out E (input E e q1))) *)
  injection.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  generalize H; unfold not in |- *; intro.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  intro.
(* Goal: False *)
(* Goal: @eq (queue E) (first_out E (input E d (input E e q1))) (input E d (first_out E (input E e q1))) *)
  apply (H3 m).
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
  
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
  
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  simpl in |- *; auto.
Qed.

(** decide if there is a legal successor 
   Ideally, I should have introduce a decidable predicate
   to decide if Delete transitions were permitted. *)

Lemma decide_no_copy_successor :
 forall c : Config,
 legal c ->
 (exists t : class_trans c, ~ copy_p c t /\ legal (transition c t)) \/
 (forall t : class_trans c, copy_p c t).

Proof.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  elim (decide_no_message c); intro.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  elim (decide_no_rt c); intro.
(* Goal: sumor (@sig legal_config (fun y : legal_config => no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) (forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) *)
  right.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: copy_p c t *)
(* Goal: or (@ex (class_trans c) (fun t : class_trans c => and (not (copy_p c t)) (legal (transition c t)))) (forall t : class_trans c, copy_p c t) *)
(* Goal: or (@ex (class_trans c) (fun t : class_trans c => and (not (copy_p c t)) (legal (transition c t)))) (forall t : class_trans c, copy_p c t) *)
  apply blocked_config2.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
(* Goal: or (@ex (class_trans c) (fun t : class_trans c => and (not (copy_p c t)) (legal (transition c t)))) (forall t : class_trans c, copy_p c t) *)
(* Goal: or (@ex (class_trans c) (fun t : class_trans c => and (not (copy_p c t)) (legal (transition c t)))) (forall t : class_trans c, copy_p c t) *)
  elim b.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: lt (convert_to_nat (termination_measure c)) (convert_to_nat (termination_measure c0)) *)
  decompose [and] H0.
(* Goal: or (@ex (class_trans c) (fun t : class_trans c => and (not (copy_p c t)) (legal (transition c t)))) (forall t : class_trans c, copy_p c t) *)
(* Goal: or (@ex (class_trans c) (fun t : class_trans c => and (not (copy_p c t)) (legal (transition c t)))) (forall t : class_trans c, copy_p c t) *)
  generalize (null_st c x H H1 a).
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  intro.
(* Goal: sumor (@sig legal_config (fun y : legal_config => no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) (forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) *)
(* Goal: forall _ : forall t : class_trans c, copy_p c t, sumor (@sig legal_config (fun y : legal_config => no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) (forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) *)
  left.
(* Goal: @ex (class_trans c) (fun t : class_trans c => and (not (copy_p c t)) (legal (transition c t))) *)
(* Goal: or (@ex (class_trans c) (fun t : class_trans c => and (not (copy_p c t)) (legal (transition c t)))) (forall t : class_trans c, copy_p c t) *)
  split with (delete_entry c x H3 H2 H1).
(* Goal: and (@eq Config (transition c x3) (transition c x3)) (not (copy_p c x3)) *)
  split.
(* Goal: not (copy_p c x3) *)
  unfold copy_p in |- *.
(* Goal: not False *)
(* Goal: legal (transition c (delete_entry c x H3 H2 H1)) *)
(* Goal: or (@ex (class_trans c) (fun t : class_trans c => and (not (copy_p c t)) (legal (transition c t)))) (forall t : class_trans c, copy_p c t) *)
  unfold not in |- *; contradiction.
  
(* Goal: legal (transition c (delete_entry c x H3 H2 H1)) *)
(* Goal: or (@ex (class_trans c) (fun t : class_trans c => and (not (copy_p c t)) (legal (transition c t)))) (forall t : class_trans c, copy_p c t) *)
  apply after.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
  
(* Goal: or (@ex (class_trans c) (fun t : class_trans c => and (not (copy_p c t)) (legal (transition c t)))) (forall t : class_trans c, copy_p c t) *)
  elim (exist_non_empty_queue c H b).
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: sumor (@sig legal_config (fun y : legal_config => no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) (forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) *)
(* Goal: forall _ : forall t : class_trans c, copy_p c t, sumor (@sig legal_config (fun y : legal_config => no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) (forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) *)
  elim H0.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: @sig legal_config (fun y : legal_config => no_copy_succ y (@existT Config legal_as_set c (intro_leg c l))) *)
(* Goal: forall _ : forall t : class_trans c, copy_p c t, sumor (@sig legal_config (fun y : legal_config => no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) (forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) *)
  decompose [and] H1.
(* Goal: or (@ex (class_trans c) (fun t : class_trans c => and (not (copy_p c t)) (legal (transition c t)))) (forall t : class_trans c, copy_p c t) *)
  generalize (not_empty_implies_last Message (bm c x x0) H3).
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  intro.
(* Goal: or (@ex (class_trans c) (fun t : class_trans c => and (not (copy_p c t)) (legal (transition c t)))) (forall t : class_trans c, copy_p c t) *)
  elim H4.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: or (@ex (class_trans c) (fun t : class_trans c => and (not (copy_p c t)) (legal (transition c t)))) (forall t : class_trans c, copy_p c t) *)
  generalize (always_process_messages c H x x0 x1 H5).
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  intro.
(* Goal: no_message c *)
  elim H6.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: or (@ex (class_trans c) (fun t : class_trans c => and (not (copy_p c t)) (legal (transition c t)))) (forall t : class_trans c, copy_p c t) *)
  decompose [and] H7.
(* Goal: sumor (@sig legal_config (fun y : legal_config => no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) (forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) *)
(* Goal: forall _ : forall t : class_trans c, copy_p c t, sumor (@sig legal_config (fun y : legal_config => no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) (forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) *)
  left.
(* Goal: @ex (class_trans c) (fun t : class_trans c => and (not (copy_p c t)) (legal (transition c t))) *)
  split with x2.
(* Goal: and (@eq Config (transition c x3) (transition c x3)) (not (copy_p c x3)) *)
  split.
(* Goal: not (copy_p c x3) *)
  unfold copy_p in |- *.
(* Goal: not match x2 with | @make_copy _ s1 s2 h1 h2 => True | @receive_dec _ s1 s2 e => False | @receive_inc _ s1 s3 e => False | @receive_copy1 _ s1 s2 e e0 => False | @receive_copy2 _ s2 e e0 => False | @receive_copy3 _ s1 s2 e n n0 e0 => False | @delete_entry _ s e e0 n => False end *)
(* Goal: legal (transition c x2) *)
  generalize H9.
(* Goal: forall _ : @eq (queue Message) (bm (transition c x2) x x0) (first_out Message (bm c x x0)), not match x2 with | @make_copy _ s1 s2 h1 h2 => True | @receive_dec _ s1 s2 e => False | @receive_inc _ s1 s3 e => False | @receive_copy1 _ s1 s2 e e0 => False | @receive_copy2 _ s2 e e0 => False | @receive_copy3 _ s1 s2 e n n0 e0 => False | @delete_entry _ s e e0 n => False end *)
(* Goal: legal (transition c x2) *)
  case x2.
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
  simpl in |- *.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: not True *)
(* Goal: forall (s1 s2 : Site) (e : @eq (exc Message) (first Message (bm c s1 s2)) (value Message dec)) (_ : @eq (queue Message) (bm (transition c (receive_dec c s1 s2 e)) x x0) (first_out Message (bm c x x0))), not False *)
(* Goal: forall (s1 s3 : Site) (e : @eq (exc Message) (first Message (bm c s1 owner)) (value Message (inc_dec s3))) (_ : @eq (queue Message) (bm (transition c (receive_inc c s1 s3 e)) x x0) (first_out Message (bm c x x0))), not False *)
(* Goal: forall (s1 s2 : Site) (e : @eq bool (rt c s2) true) (e0 : @eq (exc Message) (first Message (bm c s1 s2)) (value Message copy)) (_ : @eq (queue Message) (bm (transition c (receive_copy1 c s1 s2 e e0)) x x0) (first_out Message (bm c x x0))), not False *)
(* Goal: forall (s2 : Site) (e : @eq bool (rt c s2) false) (e0 : @eq (exc Message) (first Message (bm c owner s2)) (value Message copy)) (_ : @eq (queue Message) (bm (transition c (receive_copy2 c s2 e e0)) x x0) (first_out Message (bm c x x0))), not False *)
(* Goal: forall (s1 s2 : Site) (e : @eq bool (rt c s2) false) (n : not (@eq Site s1 owner)) (n0 : not (@eq Site s2 owner)) (e0 : @eq (exc Message) (first Message (bm c s1 s2)) (value Message copy)) (_ : @eq (queue Message) (bm (transition c (receive_copy3 c s1 s2 e n n0 e0)) x x0) (first_out Message (bm c x x0))), not False *)
(* Goal: forall (s : Site) (e : @eq Z (st c s) Z0) (e0 : @eq bool (rt c s) true) (n : not (@eq Site s owner)) (_ : @eq (queue Message) (bm (transition c (delete_entry c s e e0 n)) x x0) (first_out Message (bm c x x0))), not False *)
(* Goal: legal (transition c x2) *)
  generalize H10.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  case (eq_queue_dec s1 x s2 x0); intro.
(* Goal: forall _ : @eq (queue Message) (Post_message Message copy (bm c) s1 s2 x0 x1) (first_out Message (bm c x0 x1)), not True *)
(* Goal: forall _ : @eq (queue Message) (Post_message Message copy (bm c) s1 s2 x0 x1) (first_out Message (bm c x0 x1)), not True *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  decompose [and] a0.
(* Goal: forall _ : @eq (queue Message) (Post_message Message copy (bm c) s1 s2 x x0) (first_out Message (bm c x x0)), not True *)
(* Goal: forall _ : @eq (queue Message) (Post_message Message copy (bm c) s1 s2 x x0) (first_out Message (bm c x x0)), not True *)
(* Goal: forall (s1 s2 : Site) (e : @eq (exc Message) (first Message (bm c s1 s2)) (value Message dec)) (_ : @eq (queue Message) (bm (transition c (receive_dec c s1 s2 e)) x x0) (first_out Message (bm c x x0))), not False *)
(* Goal: forall (s1 s3 : Site) (e : @eq (exc Message) (first Message (bm c s1 owner)) (value Message (inc_dec s3))) (_ : @eq (queue Message) (bm (transition c (receive_inc c s1 s3 e)) x x0) (first_out Message (bm c x x0))), not False *)
(* Goal: forall (s1 s2 : Site) (e : @eq bool (rt c s2) true) (e0 : @eq (exc Message) (first Message (bm c s1 s2)) (value Message copy)) (_ : @eq (queue Message) (bm (transition c (receive_copy1 c s1 s2 e e0)) x x0) (first_out Message (bm c x x0))), not False *)
(* Goal: forall (s2 : Site) (e : @eq bool (rt c s2) false) (e0 : @eq (exc Message) (first Message (bm c owner s2)) (value Message copy)) (_ : @eq (queue Message) (bm (transition c (receive_copy2 c s2 e e0)) x x0) (first_out Message (bm c x x0))), not False *)
(* Goal: forall (s1 s2 : Site) (e : @eq bool (rt c s2) false) (n : not (@eq Site s1 owner)) (n0 : not (@eq Site s2 owner)) (e0 : @eq (exc Message) (first Message (bm c s1 s2)) (value Message copy)) (_ : @eq (queue Message) (bm (transition c (receive_copy3 c s1 s2 e n n0 e0)) x x0) (first_out Message (bm c x x0))), not False *)
(* Goal: forall (s : Site) (e : @eq Z (st c s) Z0) (e0 : @eq bool (rt c s) true) (n : not (@eq Site s owner)) (_ : @eq (queue Message) (bm (transition c (delete_entry c s e e0 n)) x x0) (first_out Message (bm c x x0))), not False *)
(* Goal: legal (transition c x2) *)
  rewrite H11; rewrite H12.
(* Goal: forall _ : @eq (queue Message) (Post_message Message copy (bm c) x0 x1 x0 x1) (first_out Message (bm c x0 x1)), not True *)
(* Goal: forall _ : @eq (queue Message) (Post_message Message copy (bm c) s1 s2 x0 x1) (first_out Message (bm c x0 x1)), not True *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  rewrite post_here.
(* Goal: forall _ : @eq (queue Message) (input Message copy (bm c x x0)) (first_out Message (bm c x x0)), not True *)
(* Goal: forall _ : @eq (queue Message) (Post_message Message copy (bm c) s1 s2 x x0) (first_out Message (bm c x x0)), not True *)
(* Goal: forall (s1 s2 : Site) (e : @eq (exc Message) (first Message (bm c s1 s2)) (value Message dec)) (_ : @eq (queue Message) (bm (transition c (receive_dec c s1 s2 e)) x x0) (first_out Message (bm c x x0))), not False *)
(* Goal: forall (s1 s3 : Site) (e : @eq (exc Message) (first Message (bm c s1 owner)) (value Message (inc_dec s3))) (_ : @eq (queue Message) (bm (transition c (receive_inc c s1 s3 e)) x x0) (first_out Message (bm c x x0))), not False *)
(* Goal: forall (s1 s2 : Site) (e : @eq bool (rt c s2) true) (e0 : @eq (exc Message) (first Message (bm c s1 s2)) (value Message copy)) (_ : @eq (queue Message) (bm (transition c (receive_copy1 c s1 s2 e e0)) x x0) (first_out Message (bm c x x0))), not False *)
(* Goal: forall (s2 : Site) (e : @eq bool (rt c s2) false) (e0 : @eq (exc Message) (first Message (bm c owner s2)) (value Message copy)) (_ : @eq (queue Message) (bm (transition c (receive_copy2 c s2 e e0)) x x0) (first_out Message (bm c x x0))), not False *)
(* Goal: forall (s1 s2 : Site) (e : @eq bool (rt c s2) false) (n : not (@eq Site s1 owner)) (n0 : not (@eq Site s2 owner)) (e0 : @eq (exc Message) (first Message (bm c s1 s2)) (value Message copy)) (_ : @eq (queue Message) (bm (transition c (receive_copy3 c s1 s2 e n n0 e0)) x x0) (first_out Message (bm c x x0))), not False *)
(* Goal: forall (s : Site) (e : @eq Z (st c s) Z0) (e0 : @eq bool (rt c s) true) (n : not (@eq Site s owner)) (_ : @eq (queue Message) (bm (transition c (delete_entry c s e e0 n)) x x0) (first_out Message (bm c x x0))), not False *)
(* Goal: legal (transition c x2) *)
  generalize (different_queue1 Message (bm c x x0) copy).
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  elim H11; auto.
  
(* Goal: forall _ : @eq (queue Message) (Post_message Message copy (bm c) s1 s2 x0 x1) (first_out Message (bm c x0 x1)), not True *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  rewrite post_elsewhere.
(* Goal: forall _ : @eq (queue Message) (bm c x x0) (first_out Message (bm c x x0)), not True *)
(* Goal: or (not (@eq Site s1 x)) (not (@eq Site s2 x0)) *)
(* Goal: forall (s1 s2 : Site) (e : @eq (exc Message) (first Message (bm c s1 s2)) (value Message dec)) (_ : @eq (queue Message) (bm (transition c (receive_dec c s1 s2 e)) x x0) (first_out Message (bm c x x0))), not False *)
(* Goal: forall (s1 s3 : Site) (e : @eq (exc Message) (first Message (bm c s1 owner)) (value Message (inc_dec s3))) (_ : @eq (queue Message) (bm (transition c (receive_inc c s1 s3 e)) x x0) (first_out Message (bm c x x0))), not False *)
(* Goal: forall (s1 s2 : Site) (e : @eq bool (rt c s2) true) (e0 : @eq (exc Message) (first Message (bm c s1 s2)) (value Message copy)) (_ : @eq (queue Message) (bm (transition c (receive_copy1 c s1 s2 e e0)) x x0) (first_out Message (bm c x x0))), not False *)
(* Goal: forall (s2 : Site) (e : @eq bool (rt c s2) false) (e0 : @eq (exc Message) (first Message (bm c owner s2)) (value Message copy)) (_ : @eq (queue Message) (bm (transition c (receive_copy2 c s2 e e0)) x x0) (first_out Message (bm c x x0))), not False *)
(* Goal: forall (s1 s2 : Site) (e : @eq bool (rt c s2) false) (n : not (@eq Site s1 owner)) (n0 : not (@eq Site s2 owner)) (e0 : @eq (exc Message) (first Message (bm c s1 s2)) (value Message copy)) (_ : @eq (queue Message) (bm (transition c (receive_copy3 c s1 s2 e n n0 e0)) x x0) (first_out Message (bm c x x0))), not False *)
(* Goal: forall (s : Site) (e : @eq Z (st c s) Z0) (e0 : @eq bool (rt c s) true) (n : not (@eq Site s owner)) (_ : @eq (queue Message) (bm (transition c (delete_entry c s e e0 n)) x x0) (first_out Message (bm c x x0))), not False *)
(* Goal: legal (transition c x2) *)
  generalize (different_queue2 Message (bm c x x0) x1 H5).
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  elim H11; auto.
  
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
  
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros; unfold not in |- *; auto.
  
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros; unfold not in |- *; auto.
  
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros; unfold not in |- *; auto.
  
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros; unfold not in |- *; auto.
  
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros; unfold not in |- *; auto.
  
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros; unfold not in |- *; auto.
  
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
Qed.


Section ROOT_SUCC.

Inductive legal_as_set : Config -> Set :=
    intro_leg : forall c : Config, legal c -> legal_as_set c.



Definition legal_config := sigS legal_as_set.

Definition get_c (lc : sigS legal_as_set) :=
  match lc with
  | existS c L => c
  end.

(* WATCH OUT: successor is first argument, predecessor is second *)
Definition no_copy_succ (lc2 lc1 : legal_config) :=
  exists t : class_trans (get_c lc1),
    get_c lc2 = transition (get_c lc1) t /\ ~ copy_p (get_c lc1) t.



Definition convert_to_nat (n : Z) :=
  match n with
  | Zpos x => nat_of_P x
  | _ => 0
  end.


Definition no_copy_measure (lc : legal_config) :=
  match lc with
  | existS c _ => convert_to_nat (termination_measure c)
  end.

Definition decidable_relation (E : Set) (R : E -> E -> Prop) :=
  forall x : E, {y : E | R y x} + {(forall y : E, ~ R y x)}.


Axiom
  or_rec : forall (A B : Prop) (P : Set), (A -> P) -> (B -> P) -> A \/ B -> P.
Axiom
  ex_rec :
    forall (A : Set) (P : A -> Prop) (P0 : Set),
    (forall x : A, P x -> P0) -> ex P -> P0.


Lemma decidable_no_copy_succ : decidable_relation legal_config no_copy_succ.
Proof.
(* Goal: decidable_relation legal_config no_copy_succ *)
  unfold decidable_relation in |- *.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  intro.
(* Goal: forall (y : legal_config) (_ : no_copy_succ x y), lt (no_copy_measure x) (no_copy_measure y) *)
  elim x.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: forall (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message x)), no_message x *)
  elim p.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: sumor (@sig legal_config (fun y : legal_config => no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) (forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) *)
  generalize (decide_no_copy_successor c l).
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  intro.
(* Goal: lt (convert_to_nat (termination_measure c)) (convert_to_nat (termination_measure c0)) *)
  elim H.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  intro.
(* Goal: sumor (@sig legal_config (fun y : legal_config => no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) (forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) *)
(* Goal: forall _ : forall t : class_trans c, copy_p c t, sumor (@sig legal_config (fun y : legal_config => no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) (forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) *)
  elim H0.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: sumor (@sig legal_config (fun y : legal_config => no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) (forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) *)
(* Goal: forall _ : forall t : class_trans c, copy_p c t, sumor (@sig legal_config (fun y : legal_config => no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) (forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) *)
  left.
(* Goal: @sig legal_config (fun y : legal_config => no_copy_succ y (@existT Config legal_as_set c (intro_leg c l))) *)
(* Goal: forall _ : forall t : class_trans c, copy_p c t, sumor (@sig legal_config (fun y : legal_config => no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) (forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) *)
  decompose [and] H1.
  split
   with
     (existS legal_as_set (transition c x1) (intro_leg (transition c x1) H3)).
(* Goal: no_copy_succ (@existT Config legal_as_set (transition c x3) (intro_leg (transition c x3) H10)) (@existT Config legal_as_set c (intro_leg c l)) *)
  unfold no_copy_succ in |- *.
(* Goal: @ex (class_trans (get_c (@existT Config legal_as_set c (intro_leg c l)))) (fun t : class_trans (get_c (@existT Config legal_as_set c (intro_leg c l))) => and (@eq Config (get_c (@existT Config legal_as_set (transition c x3) (intro_leg (transition c x3) H10))) (transition (get_c (@existT Config legal_as_set c (intro_leg c l))) t)) (not (copy_p (get_c (@existT Config legal_as_set c (intro_leg c l))) t))) *)
  unfold get_c in |- *.
(* Goal: @ex (class_trans c) (fun t : class_trans c => and (@eq Config (transition c x1) (transition c t)) (not (copy_p c t))) *)
(* Goal: forall _ : forall t : class_trans c, copy_p c t, sumor (@sig legal_config (fun y : legal_config => no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) (forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) *)
  split with x1.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  split; auto.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  intro.
(* Goal: sumor (@sig legal_config (fun y : legal_config => no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) (forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set c (intro_leg c l)))) *)
  right.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  intro.
(* Goal: no_copy_succ (@existT Config legal_as_set (transition c x3) (intro_leg (transition c x3) H10)) (@existT Config legal_as_set c (intro_leg c l)) *)
  unfold no_copy_succ in |- *.
(* Goal: @ex (class_trans (get_c (@existT Config legal_as_set c (intro_leg c l)))) (fun t : class_trans (get_c (@existT Config legal_as_set c (intro_leg c l))) => and (@eq Config (get_c (@existT Config legal_as_set (transition c x3) (intro_leg (transition c x3) H10))) (transition (get_c (@existT Config legal_as_set c (intro_leg c l))) t)) (not (copy_p (get_c (@existT Config legal_as_set c (intro_leg c l))) t))) *)
  unfold get_c in |- *.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  unfold not in |- *; intro.
(* Goal: False *)
  elim H1.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: False *)
  decompose [and] H2.
(* Goal: False *)
  apply H4.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
Qed.

Definition relation_decreases (E : Set) (R : E -> E -> Prop)
  (f : E -> nat) := forall x y : E, R x y -> f x < f y.


Lemma Z_nat_business :
 forall x y : positive, nat_of_P y < nat_of_P x -> (Zpos y < Zpos x)%Z.
Proof.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: forall _ : Z.lt (Zpos y) (Zpos x), @eq comparison (Pos.compare_cont Eq y x) Lt *)
  unfold Zlt in |- *.
(* Goal: forall _ : @eq comparison (Z.compare (Zpos y) (Zpos x)) Lt, @eq comparison (Pos.compare_cont Eq y x) Lt *)
  unfold Zcompare in |- *.
(* Goal: @eq comparison (Pos.compare y x) Lt *)
  apply nat_of_P_lt_Lt_compare_complement_morphism.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
Qed.

Lemma Z_nat_business1 :
 forall x y : positive, (Zpos y < Zpos x)%Z -> nat_of_P y < nat_of_P x.
Proof.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: lt (Pos.to_nat y) (Pos.to_nat x) *)
  apply nat_of_P_lt_Lt_compare_morphism.
(* Goal: forall _ : not (no_message (get_c (last_successor y0))), no_message (get_c (last_successor y0)) *)
  generalize H.
(* Goal: forall _ : Z.lt (Zpos y) (Zpos x), @eq comparison (Pos.compare_cont Eq y x) Lt *)
  unfold Zlt in |- *.
(* Goal: forall _ : @eq comparison (Z.compare (Zpos y) (Zpos x)) Lt, @eq comparison (Pos.compare_cont Eq y x) Lt *)
  unfold Zcompare in |- *.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
Qed.

Axiom
  Z_nat_axiom :
    forall x y : Z,
    (0 <= x)%Z ->
    (0 <= y)%Z -> (y < x)%Z -> convert_to_nat y < convert_to_nat x.


(*  What I want to prove.
Lemma Z_nat_business2:
 (x:Z)  `0<=x` -> `0<x` -> (lt (0) (convert_to_nat `x`)).

Lemma Z_nat_business3:
 (x,y:Z)  `0<=x` -> `0<=y` -> `y<x` -> (lt (convert y) (convert x)).

Lemma Z_nat_business4:
 (x,y:positive)  (lt (convert y) (convert x)) -> (lt (convert y) (convert x)).

*)
(* use Theorem bij1 : (m:nat) (convert (anti_convert m)) = (S m). *)


Lemma no_copy_succ_decreases :
 relation_decreases legal_config no_copy_succ no_copy_measure.
Proof.
(* Goal: relation_decreases legal_config no_copy_succ no_copy_measure *)
  unfold relation_decreases in |- *.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  intro.
(* Goal: forall (y : legal_config) (_ : no_copy_succ x y), lt (no_copy_measure x) (no_copy_measure y) *)
  elim x.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  intro.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  intro.
(* Goal: forall (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message x)), no_message x *)
  elim p.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  intro; intro; intro.
(* Goal: forall _ : no_copy_succ (@existT Config legal_as_set c (intro_leg c l)) y, lt (no_copy_measure (@existT Config legal_as_set c (intro_leg c l))) (no_copy_measure y) *)
  elim y.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  intro; intro.
(* Goal: forall _ : no_copy_succ (@existT Config legal_as_set c (intro_leg c l)) (@existT Config legal_as_set x1 p0), lt (no_copy_measure (@existT Config legal_as_set c (intro_leg c l))) (no_copy_measure (@existT Config legal_as_set x1 p0)) *)
  elim p0.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  intro; intro.
(* Goal: no_copy_succ (@existT Config legal_as_set (transition c x3) (intro_leg (transition c x3) H10)) (@existT Config legal_as_set c (intro_leg c l)) *)
  unfold no_copy_succ in |- *.
(* Goal: @ex (class_trans (get_c (@existT Config legal_as_set c (intro_leg c l)))) (fun t : class_trans (get_c (@existT Config legal_as_set c (intro_leg c l))) => and (@eq Config (get_c (@existT Config legal_as_set (transition c x3) (intro_leg (transition c x3) H10))) (transition (get_c (@existT Config legal_as_set c (intro_leg c l))) t)) (not (copy_p (get_c (@existT Config legal_as_set c (intro_leg c l))) t))) *)
  unfold get_c in |- *.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  intro.
(* Goal: lt (no_copy_measure (@existT Config legal_as_set c (intro_leg c l))) (no_copy_measure (@existT Config legal_as_set c0 (intro_leg c0 l0))) *)
  unfold no_copy_measure in |- *.
(* Goal: lt (convert_to_nat (termination_measure c)) (convert_to_nat (termination_measure c0)) *)
  elim H.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: lt (convert_to_nat (termination_measure c)) (convert_to_nat (termination_measure c0)) *)
  decompose [and] H0.
(* Goal: lt (convert_to_nat (termination_measure c)) (convert_to_nat (termination_measure c0)) *)
  generalize (termination_measure_decreases c0 x2 l0 H2).
(* Goal: forall _ : Z.lt (termination_measure (transition c0 x2)) (termination_measure c0), lt (convert_to_nat (termination_measure c)) (convert_to_nat (termination_measure c0)) *)
  rewrite <- H1.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  intro.
(* Goal: lt (convert_to_nat (termination_measure c)) (convert_to_nat (termination_measure c0)) *)
  apply Z_nat_axiom.
(* Goal: Z.le Z0 (termination_measure c) *)
(* Goal: Z.lt (termination_measure c) (termination_measure c0) *)
  apply termination_measure_positive.
(* Goal: Z.le Z0 (termination_measure c) *)
(* Goal: Z.lt (termination_measure c) (termination_measure c0) *)
  apply termination_measure_positive.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
Qed.

Definition last_successor :=
  root legal_config no_copy_measure no_copy_succ decidable_no_copy_succ
    no_copy_succ_decreases.


Lemma last_successor_is_last :
 forall y0 y : legal_config, ~ no_copy_succ y (last_successor y0).
Proof.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: not (no_copy_succ y (last_successor y0)) *)
  unfold last_successor in |- *.
(* Goal: not (no_copy_succ y (root legal_config no_copy_measure no_copy_succ decidable_no_copy_succ no_copy_succ_decreases y0)) *)
  apply root_no_R.
Qed.


(* QUESTION:  What does the following lemma mean?  
  That there is a given transition sequence that terminates
  or that all of them terminate?
*)

Lemma last_successor_has_no_message :
 forall y0 : legal_config, no_message (get_c (last_successor y0)).
Proof.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: no_message (get_c (last_successor y0)) *)
  generalize (last_successor_is_last y0).
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  intro.
(* Goal: no_message (get_c (last_successor y0)) *)
  elim (decide_no_message (get_c (last_successor y0))).
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
  
(* Goal: forall _ : not (no_message (get_c (last_successor y0))), no_message (get_c (last_successor y0)) *)
  generalize H.
(* Goal: forall (_ : forall y : legal_config, not (no_copy_succ y (last_successor y0))) (_ : not (no_message (get_c (last_successor y0)))), no_message (get_c (last_successor y0)) *)
  elim (last_successor y0).
(* Goal: forall (x : Config) (p : legal_as_set x) (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message (get_c (@existT Config legal_as_set x p)))), no_message (get_c (@existT Config legal_as_set x p)) *)
  simpl in |- *.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  intro; intro.
(* Goal: forall (_ : forall y : legal_config, not (no_copy_succ y (@existT Config legal_as_set x p))) (_ : not (no_message x)), no_message x *)
  elim p.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: no_message c *)
  generalize (exist_non_empty_queue c l b).
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  intro.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  elim H1; intro.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  intro.
(* Goal: no_message c *)
  elim H2.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  intro.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: no_message c *)
  decompose [and] H3.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  generalize (not_empty_implies_last Message (bm c x0 x1) H5); intro.
(* Goal: no_message c *)
  elim H6.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  generalize (always_process_messages c l x0 x1 x2 H7); intro.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  elim H8; intro.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  intro.
(* Goal: no_message c *)
  decompose [and] H9.
  elim
   (H0
      (existS legal_as_set (transition c x3)
         (intro_leg (transition c x3) H10))).
(* Goal: no_copy_succ (@existT Config legal_as_set (transition c x3) (intro_leg (transition c x3) H10)) (@existT Config legal_as_set c (intro_leg c l)) *)
  unfold no_copy_succ in |- *.
(* Goal: @ex (class_trans (get_c (@existT Config legal_as_set c (intro_leg c l)))) (fun t : class_trans (get_c (@existT Config legal_as_set c (intro_leg c l))) => and (@eq Config (get_c (@existT Config legal_as_set (transition c x3) (intro_leg (transition c x3) H10))) (transition (get_c (@existT Config legal_as_set c (intro_leg c l))) t)) (not (copy_p (get_c (@existT Config legal_as_set c (intro_leg c l))) t))) *)
  unfold get_c in |- *.
(* Goal: @ex (class_trans c) (fun t : class_trans c => and (@eq Config (transition c x3) (transition c t)) (not (copy_p c t))) *)
  split with x3.
(* Goal: and (@eq Config (transition c x3) (transition c x3)) (not (copy_p c x3)) *)
  split.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
  
(* Goal: not (copy_p c x3) *)
  unfold copy_p in |- *.
(* Goal: not match x3 with | @make_copy _ s1 s2 h1 h2 => True | @receive_dec _ s1 s2 e => False | @receive_inc _ s1 s3 e => False | @receive_copy1 _ s1 s2 e e0 => False | @receive_copy2 _ s2 e e0 => False | @receive_copy3 _ s1 s2 e n n0 e0 => False | @delete_entry _ s e e0 n => False end *)
  generalize H11.
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  elim x3; simpl in |- *; intros.
(* Goal: not True *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  generalize H12.
(* Goal: forall _ : and (legal (transition c x3)) (@eq (queue Message) (bm (transition c x3) x0 x1) (first_out Message (bm c x0 x1))), no_message c *)
  case (eq_queue_dec s1 x0 s2 x1); intro.
(* Goal: forall _ : @eq (queue Message) (Post_message Message copy (bm c) s1 s2 x0 x1) (first_out Message (bm c x0 x1)), not True *)
(* Goal: forall _ : @eq (queue Message) (Post_message Message copy (bm c) s1 s2 x0 x1) (first_out Message (bm c x0 x1)), not True *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  decompose [and] a0.
(* Goal: forall _ : @eq (queue Message) (Post_message Message copy (bm c) s1 s2 x0 x1) (first_out Message (bm c x0 x1)), not True *)
(* Goal: forall _ : @eq (queue Message) (Post_message Message copy (bm c) s1 s2 x0 x1) (first_out Message (bm c x0 x1)), not True *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  rewrite H13; rewrite H14.
(* Goal: forall _ : @eq (queue Message) (Post_message Message copy (bm c) x0 x1 x0 x1) (first_out Message (bm c x0 x1)), not True *)
(* Goal: forall _ : @eq (queue Message) (Post_message Message copy (bm c) s1 s2 x0 x1) (first_out Message (bm c x0 x1)), not True *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  rewrite post_here.
(* Goal: forall _ : @eq (queue Message) (input Message copy (bm c x0 x1)) (first_out Message (bm c x0 x1)), not True *)
(* Goal: forall _ : @eq (queue Message) (Post_message Message copy (bm c) s1 s2 x0 x1) (first_out Message (bm c x0 x1)), not True *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  generalize (different_queue1 Message (bm c x0 x1) copy).
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  elim H13; auto.
(* Goal: forall _ : @eq (queue Message) (Post_message Message copy (bm c) s1 s2 x0 x1) (first_out Message (bm c x0 x1)), not True *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  rewrite post_elsewhere.
(* Goal: forall _ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  generalize (different_queue2 Message (bm c x0 x1) x2 H7).
(* Goal: forall (_ : not (@eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1)))) (_ : @eq (queue Message) (bm c x0 x1) (first_out Message (bm c x0 x1))), not True *)
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  intros.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  elim H13; auto.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  auto.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  tauto.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  tauto.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  tauto.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  tauto.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  tauto.
(* Goal: or (not (@eq Site s1 x0)) (not (@eq Site s2 x1)) *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
(* Goal: not False *)
  tauto.
Qed.

End ROOT_SUCC.


