(* ou l'on trouvera successivement la definition des transitions avec
les preconditions, puis l'action elle_meme, pour finir avec la
definition d'un etat legal comme etant celui obtenu a partir de l'etat
initial et d'un nombre quelconque de transitions *)

Inductive class_trans (c : Config) : Set :=
  | make_copy :
      forall s1 s2 : Site,
      s1 <> s2 -> s2 <> owner -> access s1 (rt c) -> class_trans c
  | receive_dec :
      forall s1 s2 : Site,
      first Message (bm c s1 s2) = value Message dec -> class_trans c
  | receive_inc :
      forall s1 s3 : Site,
      first Message (bm c s1 owner) = value Message (inc_dec s3) ->
      class_trans c
  | receive_copy1 :
      forall s1 s2 : Site,
      rt c s2 = true ->
      first Message (bm c s1 s2) = value Message copy -> class_trans c
  | receive_copy2 :
      forall s2 : Site,
      rt c s2 = false ->
      first Message (bm c owner s2) = value Message copy -> class_trans c
  | receive_copy3 :
      forall s1 s2 : Site,
      rt c s2 = false ->
      s1 <> owner ->
      first Message (bm c s1 s2) = value Message copy -> class_trans c
  | delete_entry :
      forall s : Site,
      st c s = 0%Z -> rt c s = true -> s <> owner -> class_trans c.(* ou l'on trouvera successivement la definition des transitions avec
les preconditions, puis l'action elle_meme, pour finir avec la
definition d'un etat legal comme etant celui obtenu a partir de l'etat
initial et d'un nombre quelconque de transitions *)

Inductive class_trans (c : Config) : Set :=
  | make_copy :
      forall s1 s2 : Site,
      s1 <> s2 -> s2 <> owner -> access s1 (rt c) -> class_trans c
  | receive_dec :
      forall s1 s2 : Site,
      first Message (bm c s1 s2) = value Message dec -> class_trans c
  | receive_inc :
      forall s1 s3 : Site,
      first Message (bm c s1 owner) = value Message (inc_dec s3) ->
      class_trans c
  | receive_copy1 :
      forall s1 s2 : Site,
      rt c s2 = true ->
      first Message (bm c s1 s2) = value Message copy -> class_trans c
  | receive_copy2 :
      forall s2 : Site,
      rt c s2 = false ->
      first Message (bm c owner s2) = value Message copy -> class_trans c
  | receive_copy3 :
      forall s1 s2 : Site,
      rt c s2 = false ->
      s1 <> owner ->
      first Message (bm c s1 s2) = value Message copy -> class_trans c
  | delete_entry :
      forall s : Site,
      st c s = 0%Z -> rt c s = true -> s <> owner -> class_trans c.(* ou l'on trouvera successivement la definition des transitions avec
les preconditions, puis l'action elle_meme, pour finir avec la
definition d'un etat legal comme etant celui obtenu a partir de l'etat
initial et d'un nombre quelconque de transitions *)

Inductive class_trans (c : Config) : Set :=
  | make_copy :
      forall s1 s2 : Site,
      s1 <> s2 -> s2 <> owner -> access s1 (rt c) -> class_trans c
  | receive_dec :
      forall s1 s2 : Site,
      first Message (bm c s1 s2) = value Message dec -> class_trans c
  | receive_inc :
      forall s1 s3 : Site,
      first Message (bm c s1 owner) = value Message (inc_dec s3) ->
      class_trans c
  | receive_copy1 :
      forall s1 s2 : Site,
      rt c s2 = true ->
      first Message (bm c s1 s2) = value Message copy -> class_trans c
  | receive_copy2 :
      forall s2 : Site,
      rt c s2 = false ->
      first Message (bm c owner s2) = value Message copy -> class_trans c
  | receive_copy3 :
      forall s1 s2 : Site,
      rt c s2 = false ->
      s1 <> owner ->
      first Message (bm c s1 s2) = value Message copy -> class_trans c
  | delete_entry :
      forall s : Site,
      st c s = 0%Z -> rt c s = true -> s <> owner -> class_trans c.(* ou l'on trouvera successivement la definition des transitions avec
les preconditions, puis l'action elle_meme, pour finir avec la
definition d'un etat legal comme etant celui obtenu a partir de l'etat
initial et d'un nombre quelconque de transitions *)

Inductive class_trans (c : Config) : Set :=
  | make_copy :
      forall s1 s2 : Site,
      s1 <> s2 -> s2 <> owner -> access s1 (rt c) -> class_trans c
  | receive_dec :
      forall s1 s2 : Site,
      first Message (bm c s1 s2) = value Message dec -> class_trans c
  | receive_inc :
      forall s1 s3 : Site,
      first Message (bm c s1 owner) = value Message (inc_dec s3) ->
      class_trans c
  | receive_copy1 :
      forall s1 s2 : Site,
      rt c s2 = true ->
      first Message (bm c s1 s2) = value Message copy -> class_trans c
  | receive_copy2 :
      forall s2 : Site,
      rt c s2 = false ->
      first Message (bm c owner s2) = value Message copy -> class_trans c
  | receive_copy3 :
      forall s1 s2 : Site,
      rt c s2 = false ->
      s1 <> owner ->
      first Message (bm c s1 s2) = value Message copy -> class_trans c
  | delete_entry :
      forall s : Site,
      st c s = 0%Z -> rt c s = true -> s <> owner -> class_trans c.(* ou l'on trouvera successivement la definition des transitions avec
les preconditions, puis l'action elle_meme, pour finir avec la
definition d'un etat legal comme etant celui obtenu a partir de l'etat
initial et d'un nombre quelconque de transitions *)

Inductive class_trans (c : Config) : Set :=
  | make_copy :
      forall s1 s2 : Site,
      s1 <> s2 -> s2 <> owner -> access s1 (rt c) -> class_trans c
  | receive_dec :
      forall s1 s2 : Site,
      first Message (bm c s1 s2) = value Message dec -> class_trans c
  | receive_inc :
      forall s1 s3 : Site,
      first Message (bm c s1 owner) = value Message (inc_dec s3) ->
      class_trans c
  | receive_copy1 :
      forall s1 s2 : Site,
      rt c s2 = true ->
      first Message (bm c s1 s2) = value Message copy -> class_trans c
  | receive_copy2 :
      forall s2 : Site,
      rt c s2 = false ->
      first Message (bm c owner s2) = value Message copy -> class_trans c
  | receive_copy3 :
      forall s1 s2 : Site,
      rt c s2 = false ->
      s1 <> owner ->
      first Message (bm c s1 s2) = value Message copy -> class_trans c
  | delete_entry :
      forall s : Site,
      st c s = 0%Z -> rt c s = true -> s <> owner -> class_trans c.(* ou l'on trouvera successivement la definition des transitions avec
les preconditions, puis l'action elle_meme, pour finir avec la
definition d'un etat legal comme etant celui obtenu a partir de l'etat
initial et d'un nombre quelconque de transitions *)

Inductive class_trans (c : Config) : Set :=
  | make_copy :
      forall s1 s2 : Site,
      s1 <> s2 -> s2 <> owner -> access s1 (rt c) -> class_trans c
  | receive_dec :
      forall s1 s2 : Site,
      first Message (bm c s1 s2) = value Message dec -> class_trans c
  | receive_inc :
      forall s1 s3 : Site,
      first Message (bm c s1 owner) = value Message (inc_dec s3) ->
      class_trans c
  | receive_copy1 :
      forall s1 s2 : Site,
      rt c s2 = true ->
      first Message (bm c s1 s2) = value Message copy -> class_trans c
  | receive_copy2 :
      forall s2 : Site,
      rt c s2 = false ->
      first Message (bm c owner s2) = value Message copy -> class_trans c
  | receive_copy3 :
      forall s1 s2 : Site,
      rt c s2 = false ->
      s1 <> owner ->
      first Message (bm c s1 s2) = value Message copy -> class_trans c
  | delete_entry :
      forall s : Site,
      st c s = 0%Z -> rt c s = true -> s <> owner -> class_trans c.(* ou l'on trouvera successivement la definition des transitions avec
les preconditions, puis l'action elle_meme, pour finir avec la
definition d'un etat legal comme etant celui obtenu a partir de l'etat
initial et d'un nombre quelconque de transitions *)

Inductive class_trans (c : Config) : Set :=
  | make_copy :
      forall s1 s2 : Site,
      s1 <> s2 -> s2 <> owner -> access s1 (rt c) -> class_trans c
  | receive_dec :
      forall s1 s2 : Site,
      first Message (bm c s1 s2) = value Message dec -> class_trans c
  | receive_inc :
      forall s1 s3 : Site,
      first Message (bm c s1 owner) = value Message (inc_dec s3) ->
      class_trans c
  | receive_copy1 :
      forall s1 s2 : Site,
      rt c s2 = true ->
      first Message (bm c s1 s2) = value Message copy -> class_trans c
  | receive_copy2 :
      forall s2 : Site,
      rt c s2 = false ->
      first Message (bm c owner s2) = value Message copy -> class_trans c
  | receive_copy3 :
      forall s1 s2 : Site,
      rt c s2 = false ->
      s1 <> owner ->
      first Message (bm c s1 s2) = value Message copy -> class_trans c
  | delete_entry :
      forall s : Site,
      st c s = 0%Z -> rt c s = true -> s <> owner -> class_trans c.(* ou l'on trouvera successivement la definition des transitions avec
les preconditions, puis l'action elle_meme, pour finir avec la
definition d'un etat legal comme etant celui obtenu a partir de l'etat
initial et d'un nombre quelconque de transitions *)

Inductive class_trans (c : Config) : Set :=
  | make_copy :
      forall s1 s2 : Site,
      s1 <> s2 -> s2 <> owner -> access s1 (rt c) -> class_trans c
  | receive_dec :
      forall s1 s2 : Site,
      first Message (bm c s1 s2) = value Message dec -> class_trans c
  | receive_inc :
      forall s1 s3 : Site,
      first Message (bm c s1 owner) = value Message (inc_dec s3) ->
      class_trans c
  | receive_copy1 :
      forall s1 s2 : Site,
      rt c s2 = true ->
      first Message (bm c s1 s2) = value Message copy -> class_trans c
  | receive_copy2 :
      forall s2 : Site,
      rt c s2 = false ->
      first Message (bm c owner s2) = value Message copy -> class_trans c
  | receive_copy3 :
      forall s1 s2 : Site,
      rt c s2 = false ->
      s1 <> owner ->
      first Message (bm c s1 s2) = value Message copy -> class_trans c
  | delete_entry :
      forall s : Site,
      st c s = 0%Z -> rt c s = true -> s <> owner -> class_trans c.Definition transition (c : Config) (t : class_trans c) :=
  match t with
  | make_copy s1 s2 h1 h2 h3 => copy_trans c s1 s2
  | receive_dec s1 s2 h1 => rec_dec_trans c s1 s2
  | receive_inc s1 s3 h1 => rec_inc_trans c s1 s3
  | receive_copy1 s1 s2 h1 h2 => rec_copy1_trans c s1 s2
  | receive_copy2 s2 h1 h2 => rec_copy2_trans c s2
  | receive_copy3 s1 s2 h1 h2 h3 => rec_copy3_trans c s1 s2
  | delete_entry s h1 h2 h3 => delete_trans c s
  end.Inductive legal : Config -> Prop :=
  | begin : legal config_init
  | after :
      forall (c : Config) (t : class_trans c),
      legal c -> legal (transition c t).Inductive legal : Config -> Prop :=
  | begin : legal config_init
  | after :
      forall (c : Config) (t : class_trans c),
      legal c -> legal (transition c t).Inductive legal : Config -> Prop :=
  | begin : legal config_init
  | after :
      forall (c : Config) (t : class_trans c),
      legal c -> legal (transition c t).

(* Specifications: *)
Lemma le_dt_time : forall (c0 : Config) (s0 : Site), legal c0 -> dt c0 s0 <= time c0.
Lemma not_owner_inc : forall (c : Config) (s0 s1 s2 : Site), legal c -> In_queue Message (inc_dec s0) (bm c s1 s2) -> s0 <> owner.
Lemma not_owner_first_inc : forall (c : Config) (s0 s1 s2 : Site), legal c -> first Message (bm c s1 s2) = value Message (inc_dec s0) -> s0 <> owner.
Lemma copy_diff_site : forall (c0 : Config) (s1 s2 : Site), legal c0 -> In_queue Message copy (bm c0 s1 s2) -> s1 <> s2.
Lemma first_copy_diff_site : forall (c0 : Config) (s1 s2 : Site), legal c0 -> first Message (bm c0 s1 s2) = value Message copy -> s1 <> s2.
Lemma two : forall (c0 : Config) (s0 : Site), legal c0 -> s0 <> owner -> st c0 s0 = sigma_ctrl s0 (bm c0).
Lemma four : forall c : Config, legal c -> (st c owner + sigma_yi c)%Z = sigma_xi c.
Lemma legal_false_D : forall (c0 : Config) (s0 : Site), legal c0 -> rt c0 s0 = false -> D_queue (bm c0 s0 owner).
Lemma legal_alternate : forall (s0 : Site) (c0 : Config), legal c0 -> alternate (bm c0 s0 owner).
Lemma le_xi_yi : forall s0 : Site, (xi c0 s0 >= yi c0 s0)%Z.
Lemma le_sigma_xi_yi : (sigma_xi c0 >= sigma_yi c0)%Z.
Lemma st_owner_pos : (st c0 owner >= 0)%Z.
Lemma st_rt : forall s0 : Site, s0 <> owner -> (st c0 s0 > 0)%Z -> rt c0 s0 = true.
Lemma parent_rt : forall s0 s1 : Site, parent c0 s1 s0 -> rt c0 s1 = true.
Lemma ancestor_rt : forall s1 s2 : Site, ancestor c0 s2 s1 -> rt c0 s2 = true.
Lemma in_queue_parent_dec : forall (c1 : Config) (s1 : Site), {s2 : Site | In_queue Message (inc_dec s2) (bm c1 s1 owner)} + {(forall s2 : Site, ~ In_queue Message (inc_dec s2) (bm c1 s1 owner))}.
Lemma parent_dec : forall (c1 : Config) (s1 : Site), {s2 : Site | parent c1 s2 s1} + {(forall s2 : Site, ~ parent c1 s2 s1)}.
Lemma parent_cr : forall (c0 : Config) (s1 s2 : Site), legal c0 -> parent c0 s1 s2 -> dt c0 s1 < dt c0 s2.
Lemma wf_parent : forall c0 : Config, legal c0 -> well_founded (parent c0).