End CGNoBadCycles.
(*s [(CG_add x y d)] adds the edge (x,y) of weight d to G, in case an edge already exists, only the minimal one is kept *)
Definition CG_add (x y : ad) (d : D) :=
match MapGet _ cg x with
| None => MapPut _ cg x (M1 _ y d)
| Some edges =>
match MapGet _ edges y with
| None => MapPut _ cg x (MapPut _ edges y d)
| Some d0 => MapPut _ cg x (MapPut _ edges y (Dmin d d0))
end
end.
End CGDist.
(*s Properties of [CG_add] *)
Section CGAdd.
Variable cg1 : CGraph1.
Variable x y : ad.
Variable d : D.
Definition cg2 := CG_add cg1 x y d.

(* Specifications: *)
Lemma CG_add_edge_1 :
forall x0 y0 : ad,
CG_edge cg2 x0 y0 =
(if Neqb x x0 && Neqb y y0
then Ddmin (Some d) (CG_edge cg1 x0 y0)
else CG_edge cg1 x0 y0).
Lemma CG_add_edge_2 :
forall x0 y0 : ad, Ddle (CG_edge cg2 x0 y0) (CG_edge cg1 x0 y0) = true.
Lemma CG_add_1 :
forall rho : ad -> D,
CGsat cg1 rho -> Dle (rho x) (Dplus (rho y) d) = true -> CGsat cg2 rho.
Lemma CG_add_2 : forall rho : ad -> D, CGsat cg2 rho -> CGsat cg1 rho.
Lemma CG_add_3 :
forall rho : ad -> D, CGsat cg2 rho -> Dle (rho x) (Dplus (rho y) d) = true.
(*s Every path in the new graph [cg2] either goes through the new edge from [x] to [y], or is a path in the old graph cg1: *)
Lemma CG_add_4_1 :
forall (l : list ad) (x0 y0 : ad) (d0 : D),
CG_path cg2 y0 d0 (x0 :: l) ->
{l0 : list ad &  {l1 : list ad | x0 :: l = l0 ++ x :: y :: l1}} +
CG_path cg1 y0 d0 (x0 :: l).
Lemma CG_add_4_2 :
forall (l : list ad) (last : ad) (d0 : D),
CG_path cg2 last d0 l -> ad_in_list y l = false -> CG_path cg1 last d0 l.
Lemma CG_add_4_3 :
forall (x0 : ad) (d0 : D) (l : list ad),
ad_list_stutters (y :: l) = false ->
CG_path cg2 x0 d0 (y :: l) -> CG_path cg1 x0 d0 (y :: l).
Lemma CG_add_4_4 :
forall (l : list ad) (last : ad) (d0 : D),
CG_path cg2 last d0 l -> ad_in_list x l = false -> CG_path cg1 last d0 l.
Lemma CG_add_4_5 :
forall (d0 : D) (l : list ad),
ad_list_stutters (l ++ x :: nil) = false ->
CG_path cg2 x d0 (l ++ x :: nil) -> CG_path cg1 x d0 (l ++ x :: nil).