Inductive prechain_dom_ok (A : Set) : mEnsemble A -> prechain A -> Prop :=
  | domok_single :
      forall (x : Map A) (T : mEnsemble A),
      T x -> prechain_dom_ok A T (single A x)
  | domok_concat :
      forall (x : Map A) (T : mEnsemble A) (p : prechain A),
      T x -> prechain_dom_ok A T p -> prechain_dom_ok A T (concat A p x).Inductive prechain_dom_ok (A : Set) : mEnsemble A -> prechain A -> Prop :=
  | domok_single :
      forall (x : Map A) (T : mEnsemble A),
      T x -> prechain_dom_ok A T (single A x)
  | domok_concat :
      forall (x : Map A) (T : mEnsemble A) (p : prechain A),
      T x -> prechain_dom_ok A T p -> prechain_dom_ok A T (concat A p x).Inductive prechain_dom_ok (A : Set) : mEnsemble A -> prechain A -> Prop :=
  | domok_single :
      forall (x : Map A) (T : mEnsemble A),
      T x -> prechain_dom_ok A T (single A x)
  | domok_concat :
      forall (x : Map A) (T : mEnsemble A) (p : prechain A),
      T x -> prechain_dom_ok A T p -> prechain_dom_ok A T (concat A p x).Fixpoint chain_length (A : Set) (p : prechain A) {struct p} : nat :=
  match p with
  | single x => 1
  | concat x y => S (chain_length A x)
  end.Definition prechain_last (A : Set) (p : prechain A) : 
  Map A := match p with
           | single x => x
           | concat z x => x
           end.Inductive prechain_incr (A : Set) : mRelation A -> prechain A -> Prop :=
  | incr_single :
      forall (x : Map A) (r : mRelation A), prechain_incr A r (single A x)
  | incr_concat :
      forall (x : Map A) (r : mRelation A) (p : prechain A),
      r (prechain_last A p) x ->
      prechain_incr A r p -> prechain_incr A r (concat A p x).Inductive prechain_incr (A : Set) : mRelation A -> prechain A -> Prop :=
  | incr_single :
      forall (x : Map A) (r : mRelation A), prechain_incr A r (single A x)
  | incr_concat :
      forall (x : Map A) (r : mRelation A) (p : prechain A),
      r (prechain_last A p) x ->
      prechain_incr A r p -> prechain_incr A r (concat A p x).Inductive prechain_incr (A : Set) : mRelation A -> prechain A -> Prop :=
  | incr_single :
      forall (x : Map A) (r : mRelation A), prechain_incr A r (single A x)
  | incr_concat :
      forall (x : Map A) (r : mRelation A) (p : prechain A),
      r (prechain_last A p) x ->
      prechain_incr A r p -> prechain_incr A r (concat A p x).Inductive chain (A : Set) :
mEnsemble A -> mRelation A -> prechain A -> Prop :=
  | chain_single :
      forall (x : Map A) (T : mEnsemble A) (r : mRelation A),
      T x -> chain A T r (single A x)
  | chain_concat_s :
      forall (x y : Map A) (T : mEnsemble A) (r : mRelation A),
      T x -> T y -> r x y -> chain A T r (concat A (single A x) y)
  | chain_concat_m :
      forall (x y : Map A) (z : prechain A) (T : mEnsemble A)
        (r : mRelation A),
      T y ->
      r x y ->
      chain A T r (concat A z x) -> chain A T r (concat A (concat A z x) y).Inductive chain (A : Set) :
mEnsemble A -> mRelation A -> prechain A -> Prop :=
  | chain_single :
      forall (x : Map A) (T : mEnsemble A) (r : mRelation A),
      T x -> chain A T r (single A x)
  | chain_concat_s :
      forall (x y : Map A) (T : mEnsemble A) (r : mRelation A),
      T x -> T y -> r x y -> chain A T r (concat A (single A x) y)
  | chain_concat_m :
      forall (x y : Map A) (z : prechain A) (T : mEnsemble A)
        (r : mRelation A),
      T y ->
      r x y ->
      chain A T r (concat A z x) -> chain A T r (concat A (concat A z x) y).Inductive chain (A : Set) :
mEnsemble A -> mRelation A -> prechain A -> Prop :=
  | chain_single :
      forall (x : Map A) (T : mEnsemble A) (r : mRelation A),
      T x -> chain A T r (single A x)
  | chain_concat_s :
      forall (x y : Map A) (T : mEnsemble A) (r : mRelation A),
      T x -> T y -> r x y -> chain A T r (concat A (single A x) y)
  | chain_concat_m :
      forall (x y : Map A) (z : prechain A) (T : mEnsemble A)
        (r : mRelation A),
      T y ->
      r x y ->
      chain A T r (concat A z x) -> chain A T r (concat A (concat A z x) y).Inductive chain (A : Set) :
mEnsemble A -> mRelation A -> prechain A -> Prop :=
  | chain_single :
      forall (x : Map A) (T : mEnsemble A) (r : mRelation A),
      T x -> chain A T r (single A x)
  | chain_concat_s :
      forall (x y : Map A) (T : mEnsemble A) (r : mRelation A),
      T x -> T y -> r x y -> chain A T r (concat A (single A x) y)
  | chain_concat_m :
      forall (x y : Map A) (z : prechain A) (T : mEnsemble A)
        (r : mRelation A),
      T y ->
      r x y ->
      chain A T r (concat A z x) -> chain A T r (concat A (concat A z x) y).

(* Specifications: *)
Lemma chain_def_ok : forall (A : Set) (T : mEnsemble A) (r : mRelation A) (p : prechain A), chain A T r p -> prechain_dom_ok A T p.
Lemma chain_incr : forall (A : Set) (T : mEnsemble A) (r : mRelation A) (p : prechain A), chain A T r p -> prechain_incr A r p.