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.
Definition no_message (c : Config) :=
forall s1 s2 : Site, In s1 LS -> In s2 LS -> bm c s1 s2 = empty Message.
(**  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.
Remark add_reduce2 :
forall x y z a : Z, x = a -> (x + (y + z))%Z = (a + y + z)%Z.
Remark add_reduce3 :
forall x y z a : Z, x = a -> y = z -> (x + y)%Z = (a + z)%Z.
Remark add_reduce10 :
forall x y w z a : Z,
w = y -> (a > 0)%Z -> (x + (y + (z - a)) < x + (w + z))%Z.
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.
Remark add_reduce12 : forall x y : Z, x = y -> x = (y + 0)%Z.
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.
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.
Remark add_reduce15 : forall x y a : Z, (x < y)%Z -> (a + x < a + y)%Z.
Remark add_reduce16 :
forall x1 x2 y b : Z,
x1 = x2 -> (1 - b < 0)%Z -> (x1 - b + (y + 1) < x2 + y)%Z.
Remark add_reduce17 : forall x y a : Z, x = y -> (x + a)%Z = (y + a)%Z.
Remark add_reduce18 : forall x y a : Z, x = y -> a = 0%Z -> x = (y + a)%Z.
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.
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.
Remark add_reduce23 :
forall x y : Z, (x >= 0)%Z -> (y >= 0)%Z -> (0 <= x + y)%Z.
(* 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))`.  Lemma termination_measure_positive : forall c : Config, (0 <= termination_measure c)%Z.  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)}.   (** 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_config2 :
forall c : Config,
legal c -> no_message c -> no_rt c -> forall t : class_trans c, copy_p c t.