(* relation d'une adresse d'occurence dans les prec_list *)

Inductive prec_occur : prec_list -> ad -> Prop :=
  | prec_hd :
      forall (a : ad) (pl0 pl1 : prec_list),
      prec_occur (prec_cons a pl0 pl1) a
  | prec_int0 :
      forall (a b : ad) (pl0 pl1 : prec_list),
      prec_occur pl0 b -> prec_occur (prec_cons a pl0 pl1) b
  | prec_int1 :
      forall (a b : ad) (pl0 pl1 : prec_list),
      prec_occur pl1 b -> prec_occur (prec_cons a pl0 pl1) b.(* relation d'une adresse d'occurence dans les prec_list *)

Inductive prec_occur : prec_list -> ad -> Prop :=
  | prec_hd :
      forall (a : ad) (pl0 pl1 : prec_list),
      prec_occur (prec_cons a pl0 pl1) a
  | prec_int0 :
      forall (a b : ad) (pl0 pl1 : prec_list),
      prec_occur pl0 b -> prec_occur (prec_cons a pl0 pl1) b
  | prec_int1 :
      forall (a b : ad) (pl0 pl1 : prec_list),
      prec_occur pl1 b -> prec_occur (prec_cons a pl0 pl1) b.(* relation d'une adresse d'occurence dans les prec_list *)

Inductive prec_occur : prec_list -> ad -> Prop :=
  | prec_hd :
      forall (a : ad) (pl0 pl1 : prec_list),
      prec_occur (prec_cons a pl0 pl1) a
  | prec_int0 :
      forall (a b : ad) (pl0 pl1 : prec_list),
      prec_occur pl0 b -> prec_occur (prec_cons a pl0 pl1) b
  | prec_int1 :
      forall (a b : ad) (pl0 pl1 : prec_list),
      prec_occur pl1 b -> prec_occur (prec_cons a pl0 pl1) b.(* relation d'une adresse d'occurence dans les prec_list *)

Inductive prec_occur : prec_list -> ad -> Prop :=
  | prec_hd :
      forall (a : ad) (pl0 pl1 : prec_list),
      prec_occur (prec_cons a pl0 pl1) a
  | prec_int0 :
      forall (a b : ad) (pl0 pl1 : prec_list),
      prec_occur pl0 b -> prec_occur (prec_cons a pl0 pl1) b
  | prec_int1 :
      forall (a b : ad) (pl0 pl1 : prec_list),
      prec_occur pl1 b -> prec_occur (prec_cons a pl0 pl1) b.(* relation de "contenu" pour les prec_list *)

Inductive prec_contained : prec_list -> prec_list -> Prop :=
  | prec_id : forall p : prec_list, prec_contained p p
  | prec_c_int0 :
      forall (p p0 p1 : prec_list) (a : ad),
      prec_contained p p0 -> prec_contained p (prec_cons a p0 p1)
  | prec_c_int1 :
      forall (p p0 p1 : prec_list) (a : ad),
      prec_contained p p1 -> prec_contained p (prec_cons a p0 p1).(* relation de "contenu" pour les prec_list *)

Inductive prec_contained : prec_list -> prec_list -> Prop :=
  | prec_id : forall p : prec_list, prec_contained p p
  | prec_c_int0 :
      forall (p p0 p1 : prec_list) (a : ad),
      prec_contained p p0 -> prec_contained p (prec_cons a p0 p1)
  | prec_c_int1 :
      forall (p p0 p1 : prec_list) (a : ad),
      prec_contained p p1 -> prec_contained p (prec_cons a p0 p1).(* relation de "contenu" pour les prec_list *)

Inductive prec_contained : prec_list -> prec_list -> Prop :=
  | prec_id : forall p : prec_list, prec_contained p p
  | prec_c_int0 :
      forall (p p0 p1 : prec_list) (a : ad),
      prec_contained p p0 -> prec_contained p (prec_cons a p0 p1)
  | prec_c_int1 :
      forall (p p0 p1 : prec_list) (a : ad),
      prec_contained p p1 -> prec_contained p (prec_cons a p0 p1).(* relation de "contenu" pour les prec_list *)

Inductive prec_contained : prec_list -> prec_list -> Prop :=
  | prec_id : forall p : prec_list, prec_contained p p
  | prec_c_int0 :
      forall (p p0 p1 : prec_list) (a : ad),
      prec_contained p p0 -> prec_contained p (prec_cons a p0 p1)
  | prec_c_int1 :
      forall (p p0 p1 : prec_list) (a : ad),
      prec_contained p p1 -> prec_contained p (prec_cons a p0 p1).(* définition de l'appartenance d'un état à un pre dta *)

Definition state_in_dta (d : preDTA) (s : state) : Prop :=
  exists a : ad, MapGet state d a = Some s.Definition state_in_dta_diff (d : preDTA) (s : state) 
  (a : ad) : Prop := exists b : ad, MapGet state d b = Some s /\ a <> b.(* définition de l'appartenance d'une adjacence à un pre dta *)

Definition prec_in_dta (d : preDTA) (p : prec_list) : Prop :=
  exists s : state,
    (exists a : ad,
       (exists c : ad,
          MapGet state d a = Some s /\
          MapGet prec_list s c = Some p)).Definition prec_in_dta_cont (d : preDTA) (p : prec_list) : Prop :=
  exists s : state,
    (exists b : ad,
       (exists c : ad,
          (exists p0 : prec_list,
             MapGet state d b = Some s /\
             MapGet prec_list s c = Some p0 /\ prec_contained p p0))).Definition prec_in_dta_diff (d : preDTA) (p : prec_list) 
  (a : ad) : Prop :=
  exists s : state,
    (exists b : ad,
       (exists c : ad,
          MapGet state d b = Some s /\
          MapGet prec_list s c = Some p /\ a <> b)).Definition prec_in_dta_diff_cont (d : preDTA) (p : prec_list) 
  (a : ad) : Prop :=
  exists s : state,
    (exists b : ad,
       (exists c : ad,
          (exists p0 : prec_list,
             MapGet state d b = Some s /\
             MapGet prec_list s c = Some p0 /\
             prec_contained p p0 /\ a <> b))).(* définition de l'appartenance d'une adjacence à un etat *)

Definition prec_in_state (s : state) (p : prec_list) : Prop :=
  exists c : ad, MapGet prec_list s c = Some p.

(* Specifications: *)
Lemma prec_in_state_M0_false : forall p : prec_list, ~ prec_in_state (M0 prec_list) p.
Lemma state_in_dta_M0_false : forall s : state, ~ state_in_dta (M0 state) s.
Lemma prec_occur_1 : forall (a : ad) (p0 p1 p2 : prec_list), prec_contained (prec_cons a p0 p1) p2 -> prec_occur p2 a.
Lemma prec_contained_0 : forall (a : ad) (p0 p1 p2 : prec_list), prec_contained (prec_cons a p0 p1) p2 -> prec_contained p0 p2.
Lemma prec_contained_1 : forall (a : ad) (p0 p1 p2 : prec_list), prec_contained (prec_cons a p0 p1) p2 -> prec_contained p1 p2.