PADEC - Coq Library
Library Padec.BFS.BFS_common_bis
*Certified Round Complexity of Self-Stabilizing Algorithms*
From Coq Require Import SetoidList.
From Coq Require Import SetoidClass.
From Coq Require Import Bool.
From Coq Require Import ZArith.
From Coq Require Import Lia.
From Coq Require Import SetoidClass.
From Coq Require Import Bool.
From Coq Require Import ZArith.
From Coq Require Import Lia.
From Padec Require Import SetoidUtil.
From Padec Require Import NatUtils.
From Padec Require Import ListUtils.
From Padec Require Import OptionUtil.
From Padec Require Import Algorithm.
From Padec Require Import RelModel.
From Padec Require Import Count.
From Padec Require Import Graph_Diameter.
From Padec Require Import Tree_topology_ALT.
From Padec Require Import BFS_algo_bis.
Open Scope nat_scope.
Open Scope signature_scope.
Set Implicit Arguments.
From Padec Require Import NatUtils.
From Padec Require Import ListUtils.
From Padec Require Import OptionUtil.
From Padec Require Import Algorithm.
From Padec Require Import RelModel.
From Padec Require Import Count.
From Padec Require Import Graph_Diameter.
From Padec Require Import Tree_topology_ALT.
From Padec Require Import BFS_algo_bis.
Open Scope nat_scope.
Open Scope signature_scope.
Set Implicit Arguments.
BFS Spanning Tree Under a Distributed Weakly Daemon:
Common definitions and resultsAssumption about the topology:
The network should be: bidirected, connected and rooted
Section BFS_Network.
Context {Chans: Channels}
{Net: Network}.
Class BFS_Assume :=
mkBFS {
G: relation Node;
G_compat: Proper pequiv G;
G_dec: Decider G;
Bidir: forall x y, G x y -> G y x;
Connected: is_connected G;
Root: Node;
Diam := compute_diameter'
all_nodes_prop G_compat G_dec Root (DA := Node_dec);
}.
Context {Graph_assumption: BFS_Assume}.
Definition Graph_Network_matching: Prop :=
forall x y, G x y <-> exists c, is_channel x c y.
Definition Input_matching
(_root: Node -> bool)
(_neighbors: Node -> list Channel): Prop :=
Network_assumption Net _neighbors /\
(forall x, _root x = true <-> x == Root).
Global Instance Input_matching_compat: Proper pequiv Input_matching.
#[refine] Global Instance BFS_RO_assumption: Stable_Assumption
(Algo := BFS_algo)
(Net := Net)
:= {| Assume_RO :=
(fun ro: Node -> BFSROState =>
Input_matching
(fun n: Node => root (ro n))
(fun n: Node => neighbors (ro n))
)|}.
End BFS_Network.
Context {Chans: Channels}
{Net: Network}.
Class BFS_Assume :=
mkBFS {
G: relation Node;
G_compat: Proper pequiv G;
G_dec: Decider G;
Bidir: forall x y, G x y -> G y x;
Connected: is_connected G;
Root: Node;
Diam := compute_diameter'
all_nodes_prop G_compat G_dec Root (DA := Node_dec);
}.
Context {Graph_assumption: BFS_Assume}.
Definition Graph_Network_matching: Prop :=
forall x y, G x y <-> exists c, is_channel x c y.
Definition Input_matching
(_root: Node -> bool)
(_neighbors: Node -> list Channel): Prop :=
Network_assumption Net _neighbors /\
(forall x, _root x = true <-> x == Root).
Global Instance Input_matching_compat: Proper pequiv Input_matching.
#[refine] Global Instance BFS_RO_assumption: Stable_Assumption
(Algo := BFS_algo)
(Net := Net)
:= {| Assume_RO :=
(fun ro: Node -> BFSROState =>
Input_matching
(fun n: Node => root (ro n))
(fun n: Node => neighbors (ro n))
)|}.
End BFS_Network.
Section BFS_common.
Context {Chans: Channels}
{Net: Network}
{Graph_assumption: BFS_Assume}
{Graph_network_assumption: Graph_Network_matching}.
Existing Instance G_compat.
Notation Algo := (BFS_algo).
Notation Env := (Env (Net := Net) (Algo := Algo)).
Definition Input_Assume (g: Env): Prop :=
Input_matching (fun n => (root (g n))) (fun n => neighbors (g n)).
Global Instance Input_Assume_compat: Proper pequiv Input_Assume.
Lemma Input_Assume_Stable:
forall g' g, Step g' g -> Input_Assume g -> Input_Assume g'.
Context {Chans: Channels}
{Net: Network}
{Graph_assumption: BFS_Assume}
{Graph_network_assumption: Graph_Network_matching}.
Existing Instance G_compat.
Notation Algo := (BFS_algo).
Notation Env := (Env (Net := Net) (Algo := Algo)).
Definition Input_Assume (g: Env): Prop :=
Input_matching (fun n => (root (g n))) (fun n => neighbors (g n)).
Global Instance Input_Assume_compat: Proper pequiv Input_Assume.
Lemma Input_Assume_Stable:
forall g' g, Step g' g -> Input_Assume g -> Input_Assume g'.
Access to parent node
Fixpoint Par_ (c: Channel) (p: Node) (l: list Channel): Node :=
match l with
| nil => p
| cc :: ll => if Channel_dec c cc
then match peer p c with None => p | Some q => q end
else Par_ c p ll
end.
Definition Par' (s: BFSState) (p: Node): Node :=
Par_ (par s) p (neighbors s).
Definition Par (g: Env) (p: Node): Node := Par' (g p) p.
Instance Par__compat: Proper pequiv Par_.
Global Instance Par'_compat: Proper pequiv Par'.
Global Instance Par_compat: Proper pequiv Par.
Lemma Par__spec_chan:
forall c p l, InA equiv c l -> InA equiv c (peers p) ->
is_channel p c (Par_ c p l).
Lemma Par__chan_conv:
forall c l p q,
InA equiv c l -> peer p c == Some q -> Par_ c p l == q.
Lemma Par__None:
forall c p l, peer p c == None -> Par_ c p l == p.
Lemma Par__spec:
forall c p l, InA equiv c l -> InA equiv c (peers p) ->
G p (Par_ c p l).
Lemma Par'_spec_chan:
forall (s: BFSState) p (ass: equivlistA equiv (neighbors s) (peers p)),
InA equiv (par s) (peers p) ->
is_channel p (par s) (Par' s p).
Lemma Par'_spec:
forall (s: BFSState) p (ass: equivlistA equiv (neighbors s) (peers p)),
InA equiv (par s) (peers p) -> G p (Par' s p).
Lemma Par_spec_chan:
forall g (ass: Input_Assume g) p,
InA equiv (par (g p)) (peers p) -> is_channel p (par (g p)) (Par g p).
Lemma Par_spec:
forall g (ass: Input_Assume g) p,
InA equiv (par (g p)) (peers p) -> G p (Par g p).
Lemma Dist_p_spec:
forall l, l <> nil ->
InA equiv (Dist_p l) l /\
forall a, InA equiv a l -> Dist_p l <= a.
Lemma Dist_p_spec':
forall l dd, l <> nil ->
dd = Dist_p l <->
InA equiv dd l /\
forall a, InA equiv a l -> dd <= a.
Lemma Dist_p_ge:
forall l a, l <> nil ->
(forall x, InA equiv x l -> x >= a)
-> Dist_p l >= a.
Notation neigh g p := (neighbor_list (g p) (local_env g p)).
Lemma RUN_unfold:
forall (g: Env) (p: Node),
RUN g p =
(if root (g p)
then simple_run_Root (g p)
else
if Nat.eq_dec (d (g p)) (Dist_p (map S (map snd (neigh g p)))) then
if Nat.eq_dec (d (g p)) (S match local_env g p (par (g p)) with
| Some s => d s | None => d (g p) end) then
{| d := d (g p); par := par (g p); BFSROpart := g p |}
else
{| d := d (g p); par := Par_dist (d (g p)) (par (g p)) (neigh g p);
BFSROpart := g p |}
else
{| d := Dist_p (map S (map snd (neigh g p))); par := par (g p);
BFSROpart := g p |}).
match l with
| nil => p
| cc :: ll => if Channel_dec c cc
then match peer p c with None => p | Some q => q end
else Par_ c p ll
end.
Definition Par' (s: BFSState) (p: Node): Node :=
Par_ (par s) p (neighbors s).
Definition Par (g: Env) (p: Node): Node := Par' (g p) p.
Instance Par__compat: Proper pequiv Par_.
Global Instance Par'_compat: Proper pequiv Par'.
Global Instance Par_compat: Proper pequiv Par.
Lemma Par__spec_chan:
forall c p l, InA equiv c l -> InA equiv c (peers p) ->
is_channel p c (Par_ c p l).
Lemma Par__chan_conv:
forall c l p q,
InA equiv c l -> peer p c == Some q -> Par_ c p l == q.
Lemma Par__None:
forall c p l, peer p c == None -> Par_ c p l == p.
Lemma Par__spec:
forall c p l, InA equiv c l -> InA equiv c (peers p) ->
G p (Par_ c p l).
Lemma Par'_spec_chan:
forall (s: BFSState) p (ass: equivlistA equiv (neighbors s) (peers p)),
InA equiv (par s) (peers p) ->
is_channel p (par s) (Par' s p).
Lemma Par'_spec:
forall (s: BFSState) p (ass: equivlistA equiv (neighbors s) (peers p)),
InA equiv (par s) (peers p) -> G p (Par' s p).
Lemma Par_spec_chan:
forall g (ass: Input_Assume g) p,
InA equiv (par (g p)) (peers p) -> is_channel p (par (g p)) (Par g p).
Lemma Par_spec:
forall g (ass: Input_Assume g) p,
InA equiv (par (g p)) (peers p) -> G p (Par g p).
Lemma Dist_p_spec:
forall l, l <> nil ->
InA equiv (Dist_p l) l /\
forall a, InA equiv a l -> Dist_p l <= a.
Lemma Dist_p_spec':
forall l dd, l <> nil ->
dd = Dist_p l <->
InA equiv dd l /\
forall a, InA equiv a l -> dd <= a.
Lemma Dist_p_ge:
forall l a, l <> nil ->
(forall x, InA equiv x l -> x >= a)
-> Dist_p l >= a.
Notation neigh g p := (neighbor_list (g p) (local_env g p)).
Lemma RUN_unfold:
forall (g: Env) (p: Node),
RUN g p =
(if root (g p)
then simple_run_Root (g p)
else
if Nat.eq_dec (d (g p)) (Dist_p (map S (map snd (neigh g p)))) then
if Nat.eq_dec (d (g p)) (S match local_env g p (par (g p)) with
| Some s => d s | None => d (g p) end) then
{| d := d (g p); par := par (g p); BFSROpart := g p |}
else
{| d := d (g p); par := Par_dist (d (g p)) (par (g p)) (neigh g p);
BFSROpart := g p |}
else
{| d := Dist_p (map S (map snd (neigh g p))); par := par (g p);
BFSROpart := g p |}).
RUN: root
neighbor list
Lemma neighbor_list_prop:
forall (g: Env) (ass: Input_Assume g) (pg: Proper pequiv g)
p c dd,
InA equiv (c, dd) (neigh g p) <->
exists q, is_channel p c q /\ dd = d (g q).
Lemma neighbor_list_proj:
forall s l (l_compat: Proper pequiv l)
c n, InA equiv (c, n) (neighbor_list s l) ->
InA equiv c (neighbors s).
Lemma get_neigh: forall p r, ~ p == r -> exists q, G p q.
Lemma has_neigh':
forall p r, ~ p == r -> exists c q, is_channel p c q.
Lemma technical_neigh:
forall p q (g: Env), Proper pequiv g ->
Input_Assume g -> ~ p == q ->
map S (map snd (neigh g p)) <> nil.
Definition Neigh p: list Node :=
filter (fun q => if G_dec p q then true else false) all_nodes.
Global Instance Neigh_compat: Proper pequiv Neigh.
Lemma Neigh_spec (p: Node):
forall q, InA equiv q (Neigh p) <-> G p q.
Lemma Neigh_not_nil: forall p, ~ p == Root -> Neigh p <> nil.
Definition dist_Neigh g p := (map (fun q => d (g q)) (Neigh p)).
Lemma dist_Neigh_spec:
forall g (pg: Proper pequiv g) p x,
InA equiv x (dist_Neigh g p) <->
exists q, G p q /\ d (g q) = x.
Lemma Sdist_Neigh_spec:
forall g (pg: Proper pequiv g) p x,
InA equiv x (map S (dist_Neigh g p)) <->
exists q, G p q /\ S (d (g q)) = x.
Global Instance min_list_compat_equivlist:
Proper (equivlistA equiv ==> eq) min_list.
Global Instance Dist_p_compat_equivlist:
Proper (equivlistA equiv ==> eq) Dist_p.
Lemma Dist_p2:
forall g (ass: Input_Assume g) (pg: Proper pequiv g) p,
Dist_p (map S (map snd (neigh g p))) =
Dist_p (map S (dist_Neigh g p)).
Lemma technical_not_nil0:
forall g p, ~ p == Root -> dist_Neigh g p <> nil.
Lemma technical_not_nil:
forall g p, ~ p == Root -> map S (dist_Neigh g p) <> nil.
Lemma DistOK:
forall (g: Env) (ass: Input_Assume g) (pg: Proper pequiv g)
p dd,
~ p == Root ->
Dist_p (map S (dist_Neigh g p)) = dd ->
(exists q, G p q /\ S (d (g q)) = dd) /\
forall q, G p q -> S (d (g q)) >= dd.
forall (g: Env) (ass: Input_Assume g) (pg: Proper pequiv g)
p c dd,
InA equiv (c, dd) (neigh g p) <->
exists q, is_channel p c q /\ dd = d (g q).
Lemma neighbor_list_proj:
forall s l (l_compat: Proper pequiv l)
c n, InA equiv (c, n) (neighbor_list s l) ->
InA equiv c (neighbors s).
Lemma get_neigh: forall p r, ~ p == r -> exists q, G p q.
Lemma has_neigh':
forall p r, ~ p == r -> exists c q, is_channel p c q.
Lemma technical_neigh:
forall p q (g: Env), Proper pequiv g ->
Input_Assume g -> ~ p == q ->
map S (map snd (neigh g p)) <> nil.
Definition Neigh p: list Node :=
filter (fun q => if G_dec p q then true else false) all_nodes.
Global Instance Neigh_compat: Proper pequiv Neigh.
Lemma Neigh_spec (p: Node):
forall q, InA equiv q (Neigh p) <-> G p q.
Lemma Neigh_not_nil: forall p, ~ p == Root -> Neigh p <> nil.
Definition dist_Neigh g p := (map (fun q => d (g q)) (Neigh p)).
Lemma dist_Neigh_spec:
forall g (pg: Proper pequiv g) p x,
InA equiv x (dist_Neigh g p) <->
exists q, G p q /\ d (g q) = x.
Lemma Sdist_Neigh_spec:
forall g (pg: Proper pequiv g) p x,
InA equiv x (map S (dist_Neigh g p)) <->
exists q, G p q /\ S (d (g q)) = x.
Global Instance min_list_compat_equivlist:
Proper (equivlistA equiv ==> eq) min_list.
Global Instance Dist_p_compat_equivlist:
Proper (equivlistA equiv ==> eq) Dist_p.
Lemma Dist_p2:
forall g (ass: Input_Assume g) (pg: Proper pequiv g) p,
Dist_p (map S (map snd (neigh g p))) =
Dist_p (map S (dist_Neigh g p)).
Lemma technical_not_nil0:
forall g p, ~ p == Root -> dist_Neigh g p <> nil.
Lemma technical_not_nil:
forall g p, ~ p == Root -> map S (dist_Neigh g p) <> nil.
Lemma DistOK:
forall (g: Env) (ass: Input_Assume g) (pg: Proper pequiv g)
p dd,
~ p == Root ->
Dist_p (map S (dist_Neigh g p)) = dd ->
(exists q, G p q /\ S (d (g q)) = dd) /\
forall q, G p q -> S (d (g q)) >= dd.
RUN: non root nodes -- CD Action
Lemma RUN_CD0:
forall (g: Env) (ass: Input_Assume g) (pg: Proper pequiv g)
p (hr: ~ p == Root),
d (RUN g p) = Dist_p (map S (dist_Neigh g p)).
Lemma RUN_CD2:
forall (g: Env) (ass: Input_Assume g) (pg: Proper pequiv g)
p (hr: ~ p == Root),
(exists q, G p q /\ S (d (g q)) = d (RUN g p)) /\
forall q, G p q -> S (d (g q)) >= d (RUN g p).
Lemma filter_cons:
forall A (f: A -> bool) a l,
filter f (a :: l) = if f a then a :: filter f l
else filter f l.
Lemma Par_dist_prop:
forall l pd dum,
(exists c n, InA equiv (c, n) l /\ S n = pd) ->
exists nn, InA equiv (Par_dist pd dum l, nn) l /\ S nn = pd.
forall (g: Env) (ass: Input_Assume g) (pg: Proper pequiv g)
p (hr: ~ p == Root),
d (RUN g p) = Dist_p (map S (dist_Neigh g p)).
Lemma RUN_CD2:
forall (g: Env) (ass: Input_Assume g) (pg: Proper pequiv g)
p (hr: ~ p == Root),
(exists q, G p q /\ S (d (g q)) = d (RUN g p)) /\
forall q, G p q -> S (d (g q)) >= d (RUN g p).
Lemma filter_cons:
forall A (f: A -> bool) a l,
filter f (a :: l) = if f a then a :: filter f l
else filter f l.
Lemma Par_dist_prop:
forall l pd dum,
(exists c n, InA equiv (c, n) l /\ S n = pd) ->
exists nn, InA equiv (Par_dist pd dum l, nn) l /\ S nn = pd.
RUN: non root nodes -- CP Action
Lemma RUN_CP:
forall (g: Env) (ass: Input_Assume g) (pg: Proper pequiv g)
p, ~ p == Root ->
d (g p) = Dist_p (map S (dist_Neigh g p)) ->
G p (Par' (RUN g p) p) /\
d (g p) = S (d (g (Par' (RUN g p) p))).
forall (g: Env) (ass: Input_Assume g) (pg: Proper pequiv g)
p, ~ p == Root ->
d (g p) = Dist_p (map S (dist_Neigh g p)) ->
G p (Par' (RUN g p) p) /\
d (g p) = S (d (g (Par' (RUN g p) p))).
enabled / disabled nodes
Lemma disabled_root:
forall g: Env, Input_Assume g ->
enabled_b g Root = false <-> d (g Root) = 0.
Lemma enabled_root:
forall g: Env,
Input_Assume g ->
enabled_b g Root = true <-> d (g Root) <> 0.
Lemma disabled_non_root':
forall p, ~ p == Root -> forall g: Env,
Input_Assume g -> Proper pequiv g ->
enabled_b g p = false ->
d (g p) = Dist_p (map S (dist_Neigh g p)) /\
d (g p) = S (d (g (Par g p))).
Lemma disabled_non_root_CP:
forall p, ~ p == Root -> forall g: Env,
Input_Assume g -> Proper pequiv g ->
enabled_b g p = false ->
G p (Par g p) /\
forall q, G p q -> d (g p) <= S (d (g q)).
Lemma disabled_non_root:
forall p, ~ p == Root -> forall g: Env,
Input_Assume g -> Proper pequiv g ->
enabled_b g p = false ->
G p (Par g p) /\ d (g p) = S (d (g (Par g p))) /\
forall q, G p q -> d (g p) <= S (d (g q)).
Lemma enabled_non_root':
forall p, ~ p == Root -> forall g: Env,
Input_Assume g -> Proper pequiv g ->
enabled_b g p = true ->
d (g p) <> Dist_p (map S (dist_Neigh g p)) \/
d (g p) <> S (d (g (Par g p))).
Lemma enabled_non_root_CD1:
forall p, ~ p == Root -> forall g: Env,
Input_Assume g -> Proper pequiv g ->
~ InA equiv (d (g p)) (map S (dist_Neigh g p))
-> enabled_b g p = true.
Lemma enabled_non_root_CD2:
forall p, ~ p == Root -> forall g: Env,
Input_Assume g -> Proper pequiv g ->
(exists q, G p q /\ d (g p) > S (d (g q)))
-> enabled_b g p = true.
Lemma enabled_non_root_CP:
forall p, ~ p == Root -> forall g: Env,
Input_Assume g -> Proper pequiv g ->
d (g p) = Dist_p (map S (dist_Neigh g p))
-> d (g p) <> S (d (g (Par g p)))
-> enabled_b g p = true.
forall g: Env, Input_Assume g ->
enabled_b g Root = false <-> d (g Root) = 0.
Lemma enabled_root:
forall g: Env,
Input_Assume g ->
enabled_b g Root = true <-> d (g Root) <> 0.
Lemma disabled_non_root':
forall p, ~ p == Root -> forall g: Env,
Input_Assume g -> Proper pequiv g ->
enabled_b g p = false ->
d (g p) = Dist_p (map S (dist_Neigh g p)) /\
d (g p) = S (d (g (Par g p))).
Lemma disabled_non_root_CP:
forall p, ~ p == Root -> forall g: Env,
Input_Assume g -> Proper pequiv g ->
enabled_b g p = false ->
G p (Par g p) /\
forall q, G p q -> d (g p) <= S (d (g q)).
Lemma disabled_non_root:
forall p, ~ p == Root -> forall g: Env,
Input_Assume g -> Proper pequiv g ->
enabled_b g p = false ->
G p (Par g p) /\ d (g p) = S (d (g (Par g p))) /\
forall q, G p q -> d (g p) <= S (d (g q)).
Lemma enabled_non_root':
forall p, ~ p == Root -> forall g: Env,
Input_Assume g -> Proper pequiv g ->
enabled_b g p = true ->
d (g p) <> Dist_p (map S (dist_Neigh g p)) \/
d (g p) <> S (d (g (Par g p))).
Lemma enabled_non_root_CD1:
forall p, ~ p == Root -> forall g: Env,
Input_Assume g -> Proper pequiv g ->
~ InA equiv (d (g p)) (map S (dist_Neigh g p))
-> enabled_b g p = true.
Lemma enabled_non_root_CD2:
forall p, ~ p == Root -> forall g: Env,
Input_Assume g -> Proper pequiv g ->
(exists q, G p q /\ d (g p) > S (d (g q)))
-> enabled_b g p = true.
Lemma enabled_non_root_CP:
forall p, ~ p == Root -> forall g: Env,
Input_Assume g -> Proper pequiv g ->
d (g p) = Dist_p (map S (dist_Neigh g p))
-> d (g p) <> S (d (g (Par g p)))
-> enabled_b g p = true.
Step
Lemma step_Root:
forall (g g': Env),
Input_Assume g ->
Step g' g -> has_moved_b g' g Root = true ->
d (g' Root) = 0.
Lemma step_CD0:
forall (g g': Env) (ass: Input_Assume g) (st: Step g' g)
p, ~ p == Root -> has_moved_b g' g p = true ->
d (g' p) = Dist_p (map S (dist_Neigh g p)).
Lemma step_CD2:
forall (g g': Env) (ass: Input_Assume g) (st: Step g' g)
p, ~ p == Root -> has_moved_b g' g p = true ->
(exists q, G p q /\ S (d (g q)) = d (g' p)) /\
(forall q, G p q -> S (d (g q)) >= d (g' p)).
Lemma step_CP:
forall (g g': Env) (ass: Input_Assume g) (st: Step g' g)
p, ~ p == Root -> has_moved_b g' g p = true ->
d (g p) = Dist_p (map S (dist_Neigh g p)) ->
G p (Par g' p) /\ d (g p) = S (d (g (Par g' p))).
Definition Par_Rel (gg: Env): relation Node :=
(fun n n' => if Node_dec n Root then False else
Par gg n == n').
Global Instance Par_Rel_compat: Proper pequiv Par_Rel.
forall (g g': Env),
Input_Assume g ->
Step g' g -> has_moved_b g' g Root = true ->
d (g' Root) = 0.
Lemma step_CD0:
forall (g g': Env) (ass: Input_Assume g) (st: Step g' g)
p, ~ p == Root -> has_moved_b g' g p = true ->
d (g' p) = Dist_p (map S (dist_Neigh g p)).
Lemma step_CD2:
forall (g g': Env) (ass: Input_Assume g) (st: Step g' g)
p, ~ p == Root -> has_moved_b g' g p = true ->
(exists q, G p q /\ S (d (g q)) = d (g' p)) /\
(forall q, G p q -> S (d (g q)) >= d (g' p)).
Lemma step_CP:
forall (g g': Env) (ass: Input_Assume g) (st: Step g' g)
p, ~ p == Root -> has_moved_b g' g p = true ->
d (g p) = Dist_p (map S (dist_Neigh g p)) ->
G p (Par g' p) /\ d (g p) = S (d (g (Par g' p))).
Definition Par_Rel (gg: Env): relation Node :=
(fun n n' => if Node_dec n Root then False else
Par gg n == n').
Global Instance Par_Rel_compat: Proper pequiv Par_Rel.
Par_Rel: no edge from root
Lemma Par_Rel_is_root: forall g, is_root (Par_Rel g) Root.
End BFS_common.
Close Scope signature_scope.
Close Scope nat_scope.
Unset Implicit Arguments.
End BFS_common.
Close Scope signature_scope.
Close Scope nat_scope.
Unset Implicit Arguments.