(*s Introducing graphs of objects in [D] *)

Definition CGraph1 := Map (Map D).Definition CGraph := option CGraph1.Definition CG_edge (x y : ad) :=
  match MapGet _ cg x with
  | Some edges =>
      match MapGet _ edges y with
      | Some d => Some d
      | _ => None
      end
  | _ => None
  end.(*s Let $\rho$ be an interpretation of adresses as elements in [D], 
    the graph [cg] is satisfied by $\rho$ if for any edge 
    from $x$ to $y$ indexed by $d$, we have $\rho(x) \leq \rho(y)+d$
   A graph is consistent if there exists an interpretation which satisfies it.
*)

Definition CGsat (rho : ad -> D) :=
  forall (x y : ad) (d : D),
  CG_edge x y = Some d -> Dle (rho x) (Dplus (rho y) d) = true.Definition CGconsistent := sig CGsat.(* [CG_path last d l] if there exists a path starting from [last] with successive 
   vertexes $l=[x0;...;xn]$ $(xn=last)$ and [d] is the sum of the weights on the 
   edges *)

Inductive CG_path (last : ad) : D -> list ad -> Set :=
  | CG_p1 : forall x : ad, x = last -> CG_path last Dz (x :: nil)
  | CG_p2 :
      forall (x y : ad) (l : list ad) (d : D),
      CG_path last d (y :: l) ->
      forall d' : D,
      CG_edge x y = Some d' -> CG_path last (Dplus d d') (x :: y :: l).(* [CG_path last d l] if there exists a path starting from [last] with successive 
   vertexes $l=[x0;...;xn]$ $(xn=last)$ and [d] is the sum of the weights on the 
   edges *)

Inductive CG_path (last : ad) : D -> list ad -> Set :=
  | CG_p1 : forall x : ad, x = last -> CG_path last Dz (x :: nil)
  | CG_p2 :
      forall (x y : ad) (l : list ad) (d : D),
      CG_path last d (y :: l) ->
      forall d' : D,
      CG_edge x y = Some d' -> CG_path last (Dplus d d') (x :: y :: l).(* [CG_path last d l] if there exists a path starting from [last] with successive 
   vertexes $l=[x0;...;xn]$ $(xn=last)$ and [d] is the sum of the weights on the 
   edges *)

Inductive CG_path (last : ad) : D -> list ad -> Set :=
  | CG_p1 : forall x : ad, x = last -> CG_path last Dz (x :: nil)
  | CG_p2 :
      forall (x y : ad) (l : list ad) (d : D),
      CG_path last d (y :: l) ->
      forall d' : D,
      CG_edge x y = Some d' -> CG_path last (Dplus d d') (x :: y :: l).(* If $\rho$ satisfies the graph and there is a path from [last] to [x] of 
   weight d then $\rho(x) \leq \rho(last)+d$
*)

Definition first (l : list ad) : ad :=
  match l with
  | nil => N0
  | x :: _ => x
  end.

Lemma ad_simple_path_bounded_card : forall (l : list ad) (last x : ad) (d : D), CG_path last d (x :: l) -> ad_list_stutters (x :: l) = false -> length (x :: l) <= S (MapCard _ cg).