Section INVARIANT6.
Variable c0 : Config.
Fixpoint inc_dec_in_queue (s : Site) (q : queue Message) {struct q} : Prop :=
match q with
| empty => False
| input (inc_dec s2) q' =>
if eq_site_dec s2 s then True else False
| input _ q' => inc_dec_in_queue s q'
end.
(* note that the contrary is not true ! *)
(* s1 is parent of s0 *)
Inductive parent : Site -> Site -> Prop :=
parent_intro :
forall s1 s0 : Site,
rt c0 s0 = true -> inc_dec_in_queue s1 (bm c0 s0 owner) -> parent s1 s0.
(* s1 is ancestor of s0 *)
Inductive ancestor : Site -> Site -> Prop :=
| short : forall s1 s0 : Site, parent s1 s0 -> ancestor s1 s0
| long :
forall s2 s1 s0 : Site,
ancestor s2 s1 -> parent s1 s0 -> ancestor s2 s0.
Inductive direct_son : Site -> Prop :=
direct_son_intro :
forall s : Site,
s <> owner ->
rt c0 s = true ->
(forall s1 : Site, ~ inc_dec_in_queue s1 (bm c0 s owner)) ->
direct_son s.
Inductive indirect_son1 : Site -> Prop :=
indirect_son1_intro :
forall s : Site,
s <> owner ->
rt c0 s = true ->
~ (forall s1 : Site, ~ inc_dec_in_queue s1 (bm c0 s owner)) ->
indirect_son1 s.
(*  {s1:Site | (inc_dec_in_queue s1 (bm c0 s owner))}  *)
Inductive indirect_son2 : Site -> Prop :=
indirect_son2_intro :
forall s s1 : Site,
s <> owner /\ rt c0 s = true /\ direct_son s1 /\ ancestor s1 s ->
indirect_son2 s.
(* by specifying the lemma as follows, I don't need to know that there is no cycle in the relation *)

Lemma decide_ancestor :
forall x s s1 : Site,
direct_son x ->
ancestor x s ->
indirect_son1 s1 -> (s1 = s \/ ancestor s1 s) \/ s1 <> s /\ ~ ancestor s1 s.