Section CGNoBadCycles.
Variable
no_bad_cycles :
forall (x : ad) (d : D) (l : list ad),
CG_path x d (x :: l) -> Dle Dz d = true.
(*s The edges are in the domain of the graph *)
(*s The length of a path without repetition is less than the cardinal of the map representing the graph *)
Inductive and_sp (A : Set) (B : Prop) : Set :=
conj_sp : A -> B -> and_sp A B.
(*s Given a path, one may find a shortest path withour repetition *)
(*s [(ad_simple_path_naive_search x y prefix n)] is true when there esists a path [x::l] from [y] to [x] of length less than [n] with edges not in prefix *)
Fixpoint ad_simple_path_naive_search (x y : ad) (l : list ad)
(n : nat) {struct n} : bool :=
N.eqb x y
|| match n with
| O => false
| S n' =>
match MapGet _ cg x with
| None => false
| Some edges =>
let l' := x :: l in (* builds reverse path *)
match
MapSweep D
(fun (z : ad) (d : D) =>
if ad_in_list z l'
then false
else ad_simple_path_naive_search z y l' n') edges
with
| None => false
| Some _ => true
end
end
end.
(*s Definition of simple paths : paths without repetition *)
Definition CG_simple_path (last : ad) (d : D) (l : list ad) :=
and_sp (CG_path last d l) (ad_list_stutters l = false).
(*s Computing the minimum of edges in a Map *)
Definition all_min (f : ad -> D -> option D) := MapFold _ _ None Ddmin f.
(*s [(ad_simple_path_dist_1 x y l n)] computes the minimum weight of a path from [x] to [y] of maximal length [n] which does not contain vertexes from [l] *)
Fixpoint ad_simple_path_dist_1 (x y : ad) (l : list ad)
(n : nat) {struct n} : option D :=
if N.eqb x y
then Some Dz
else
match n with
| O => None
| S n' =>
match MapGet _ cg x with
| None => None
| Some edges =>
let l' := x :: l in (* builds reverse path *)
all_min
(fun (z : ad) (d : D) =>
if ad_in_list z l'
then None
else Ddplus (ad_simple_path_dist_1 z y l' n') d) edges
end
end.
(*s [(ad_simple_path_dist x y)] computes the minimum path from x to y *)
Definition ad_simple_path_dist (x y : ad) :=
ad_simple_path_dist_1 x y nil (MapCard _ cg).

Lemma ad_simple_path_dist_complete :
forall (x y : ad) (d : D),
ad_simple_path_dist x y = Some d ->
{l : list ad &
and_sp (CG_path y d (x :: l)) (ad_list_stutters (x :: l) = false)}.