(************************************************************************)
(* Atomic implactions are stored in AVL Trees ai over lists of normal   *)
(* clauses.                                                             *)
(* For the node with the key field=i and with the data field=bs,        *)
(* we define that, for each b in bs, (Imp (Atom i) b) is in ai.         *)

Definition atomic_imps := AVL nf_list.Definition AI_Nil := AVL_NIL nf_list.(************************************************************************)
(* Atoms are stored in AVL Trees ai over unit.                          *)
(* For the node with the key field=i,                                   *)
(* we define that (Atom i) is in ai.                                    *)
(* (Definition in Kripke_Trees.v                                        *)


(************************************************************************)
(* The formulae on the left-hand side of the sequent are given by:      *)

Inductive in_ngamma (work : nf_list) (ds : disjs) (ni : nested_imps)
(ai : atomic_imps) (a : atoms) : normal_form -> Set :=
  | In_Work :
      forall (n : nat) (c : normal_form),
      my_nth normal_form n work c -> in_ngamma work ds ni ai a c
  | In_Disjs :
      forall (n : nat) (i j : Int),
      my_nth disj n ds (i, j) -> in_ngamma work ds ni ai a (NDisj i j)
  | In_Nested_Imps :
      forall (n : nat) (x : nimp),
      my_nth nimp n (nested_imps2nimps ni) x ->
      in_ngamma work ds ni ai a (NImp_NF x)
  | In_Atomic_Imps :
      forall (i : Int) (b : normal_form) (n : nat) (bs : nf_list),
      LOOKUP nf_list i ai bs ->
      my_nth normal_form n bs b -> in_ngamma work ds ni ai a (AImp i b)
  | In_Atoms :
      forall i : Int,
      LOOKUP unit i a tt -> in_ngamma work ds ni ai a (NAtom i).(************************************************************************)
(* Atoms are stored in AVL Trees ai over unit.                          *)
(* For the node with the key field=i,                                   *)
(* we define that (Atom i) is in ai.                                    *)
(* (Definition in Kripke_Trees.v                                        *)


(************************************************************************)
(* The formulae on the left-hand side of the sequent are given by:      *)

Inductive in_ngamma (work : nf_list) (ds : disjs) (ni : nested_imps)
(ai : atomic_imps) (a : atoms) : normal_form -> Set :=
  | In_Work :
      forall (n : nat) (c : normal_form),
      my_nth normal_form n work c -> in_ngamma work ds ni ai a c
  | In_Disjs :
      forall (n : nat) (i j : Int),
      my_nth disj n ds (i, j) -> in_ngamma work ds ni ai a (NDisj i j)
  | In_Nested_Imps :
      forall (n : nat) (x : nimp),
      my_nth nimp n (nested_imps2nimps ni) x ->
      in_ngamma work ds ni ai a (NImp_NF x)
  | In_Atomic_Imps :
      forall (i : Int) (b : normal_form) (n : nat) (bs : nf_list),
      LOOKUP nf_list i ai bs ->
      my_nth normal_form n bs b -> in_ngamma work ds ni ai a (AImp i b)
  | In_Atoms :
      forall i : Int,
      LOOKUP unit i a tt -> in_ngamma work ds ni ai a (NAtom i).(************************************************************************)
(* Atoms are stored in AVL Trees ai over unit.                          *)
(* For the node with the key field=i,                                   *)
(* we define that (Atom i) is in ai.                                    *)
(* (Definition in Kripke_Trees.v                                        *)


(************************************************************************)
(* The formulae on the left-hand side of the sequent are given by:      *)

Inductive in_ngamma (work : nf_list) (ds : disjs) (ni : nested_imps)
(ai : atomic_imps) (a : atoms) : normal_form -> Set :=
  | In_Work :
      forall (n : nat) (c : normal_form),
      my_nth normal_form n work c -> in_ngamma work ds ni ai a c
  | In_Disjs :
      forall (n : nat) (i j : Int),
      my_nth disj n ds (i, j) -> in_ngamma work ds ni ai a (NDisj i j)
  | In_Nested_Imps :
      forall (n : nat) (x : nimp),
      my_nth nimp n (nested_imps2nimps ni) x ->
      in_ngamma work ds ni ai a (NImp_NF x)
  | In_Atomic_Imps :
      forall (i : Int) (b : normal_form) (n : nat) (bs : nf_list),
      LOOKUP nf_list i ai bs ->
      my_nth normal_form n bs b -> in_ngamma work ds ni ai a (AImp i b)
  | In_Atoms :
      forall i : Int,
      LOOKUP unit i a tt -> in_ngamma work ds ni ai a (NAtom i).(************************************************************************)
(* Atoms are stored in AVL Trees ai over unit.                          *)
(* For the node with the key field=i,                                   *)
(* we define that (Atom i) is in ai.                                    *)
(* (Definition in Kripke_Trees.v                                        *)


(************************************************************************)
(* The formulae on the left-hand side of the sequent are given by:      *)

Inductive in_ngamma (work : nf_list) (ds : disjs) (ni : nested_imps)
(ai : atomic_imps) (a : atoms) : normal_form -> Set :=
  | In_Work :
      forall (n : nat) (c : normal_form),
      my_nth normal_form n work c -> in_ngamma work ds ni ai a c
  | In_Disjs :
      forall (n : nat) (i j : Int),
      my_nth disj n ds (i, j) -> in_ngamma work ds ni ai a (NDisj i j)
  | In_Nested_Imps :
      forall (n : nat) (x : nimp),
      my_nth nimp n (nested_imps2nimps ni) x ->
      in_ngamma work ds ni ai a (NImp_NF x)
  | In_Atomic_Imps :
      forall (i : Int) (b : normal_form) (n : nat) (bs : nf_list),
      LOOKUP nf_list i ai bs ->
      my_nth normal_form n bs b -> in_ngamma work ds ni ai a (AImp i b)
  | In_Atoms :
      forall i : Int,
      LOOKUP unit i a tt -> in_ngamma work ds ni ai a (NAtom i).(************************************************************************)
(* Atoms are stored in AVL Trees ai over unit.                          *)
(* For the node with the key field=i,                                   *)
(* we define that (Atom i) is in ai.                                    *)
(* (Definition in Kripke_Trees.v                                        *)


(************************************************************************)
(* The formulae on the left-hand side of the sequent are given by:      *)

Inductive in_ngamma (work : nf_list) (ds : disjs) (ni : nested_imps)
(ai : atomic_imps) (a : atoms) : normal_form -> Set :=
  | In_Work :
      forall (n : nat) (c : normal_form),
      my_nth normal_form n work c -> in_ngamma work ds ni ai a c
  | In_Disjs :
      forall (n : nat) (i j : Int),
      my_nth disj n ds (i, j) -> in_ngamma work ds ni ai a (NDisj i j)
  | In_Nested_Imps :
      forall (n : nat) (x : nimp),
      my_nth nimp n (nested_imps2nimps ni) x ->
      in_ngamma work ds ni ai a (NImp_NF x)
  | In_Atomic_Imps :
      forall (i : Int) (b : normal_form) (n : nat) (bs : nf_list),
      LOOKUP nf_list i ai bs ->
      my_nth normal_form n bs b -> in_ngamma work ds ni ai a (AImp i b)
  | In_Atoms :
      forall i : Int,
      LOOKUP unit i a tt -> in_ngamma work ds ni ai a (NAtom i).(************************************************************************)
(* Atoms are stored in AVL Trees ai over unit.                          *)
(* For the node with the key field=i,                                   *)
(* we define that (Atom i) is in ai.                                    *)
(* (Definition in Kripke_Trees.v                                        *)


(************************************************************************)
(* The formulae on the left-hand side of the sequent are given by:      *)

Inductive in_ngamma (work : nf_list) (ds : disjs) (ni : nested_imps)
(ai : atomic_imps) (a : atoms) : normal_form -> Set :=
  | In_Work :
      forall (n : nat) (c : normal_form),
      my_nth normal_form n work c -> in_ngamma work ds ni ai a c
  | In_Disjs :
      forall (n : nat) (i j : Int),
      my_nth disj n ds (i, j) -> in_ngamma work ds ni ai a (NDisj i j)
  | In_Nested_Imps :
      forall (n : nat) (x : nimp),
      my_nth nimp n (nested_imps2nimps ni) x ->
      in_ngamma work ds ni ai a (NImp_NF x)
  | In_Atomic_Imps :
      forall (i : Int) (b : normal_form) (n : nat) (bs : nf_list),
      LOOKUP nf_list i ai bs ->
      my_nth normal_form n bs b -> in_ngamma work ds ni ai a (AImp i b)
  | In_Atoms :
      forall i : Int,
      LOOKUP unit i a tt -> in_ngamma work ds ni ai a (NAtom i).

Lemma in_ngamma_ni_x_ni_rev : forall (work : nf_list) (ds : disjs) (x : nested_imp) (ni1 ni2 : nested_imps) (ai : atomic_imps) (a : atoms) (c : normal_form), in_ngamma work ds (ni1 ++ x :: ni2) ai a c -> in_ngamma work ds (ni1 ++ ni2) ai a c + {c = NImp_NF (nested_imp2nimp x)}.