(* Invertion principles for transitions and location invariants *)
Derive Inversion_clear cl_TRT_IN with
(forall st1 st2 : S_Ck ST, TrT st1 In st2) Sort Prop.
Derive Inversion_clear cl_TRT_EXIT with
(forall st1 st2 : S_Ck ST, TrT st1 Exit st2) Sort Prop.
Derive Inversion_clear cl_TRT_INC_TIME with
(forall st1 st2 : S_Ck ST, TrT st1 Tick st2) Sort Prop.
Derive Inversion_clear cl_TRC_APPROACH with
(forall sc1 sc2 : S_Ck SC, TrC sc1 Approach sc2) Sort Prop.
Derive Inversion_clear cl_TRC_LOWER with
(forall sc1 sc2 : S_Ck SC, TrC sc1 Lower sc2) Sort Prop.
Derive Inversion_clear cl_TRC_EXIT with
(forall sc1 sc2 : S_Ck SC, TrC sc1 Exit sc2) Sort Prop.
Derive Inversion_clear cl_TRC_RAISE with
(forall sc1 sc2 : S_Ck SC, TrC sc1 Raise sc2) Sort Prop.
Derive Inversion_clear cl_TRC_INC_TIME with
(forall sc1 sc2 : S_Ck SC, TrC sc1 Tick sc2) Sort Prop.
Derive Inversion_clear cl_TRG_LOWER with
(forall sg1 sg2 : S_Ck SG, TrG sg1 Lower sg2) Sort Prop.
Derive Inversion_clear cl_TRG_DOWN with
(forall sg1 sg2 : S_Ck SG, TrG sg1 Down sg2) Sort Prop.
Derive Inversion_clear cl_TRG_RAISE with
(forall sg1 sg2 : S_Ck SG, TrG sg1 Raise sg2) Sort Prop.
Derive Inversion_clear cl_TRG_UP with
(forall sg1 sg2 : S_Ck SG, TrG sg1 Up sg2) Sort Prop.
Derive Inversion_clear cl_TRG_INC_TIME with
(forall sg1 sg2 : S_Ck SG, TrG sg1 Tick sg2) Sort Prop.
Derive Inversion_clear cl_Ifar with (forall x : Clock, InvT (Far, x)) Sort
Prop.
Derive Inversion_clear cl_Inear with (forall x : Clock, InvT (Near, x)) Sort
Prop.
Derive Inversion_clear cl_Iinside with (forall x : Clock, InvT (Inside, x))
Sort Prop.
Derive Inversion_clear cl_Isc1 with (forall y : Clock, InvC (Sc1, y)) Sort
Prop.
Derive Inversion_clear cl_Isc2 with (forall y : Clock, InvC (Sc2, y)) Sort
Prop.
Derive Inversion_clear cl_Isc3 with (forall y : Clock, InvC (Sc3, y)) Sort
Prop.
Derive Inversion_clear cl_Isc4 with (forall y : Clock, InvC (Sc4, y)) Sort
Prop.
Derive Inversion_clear cl_Iopen with (forall z : Clock, InvG (Open, z)) Sort
Prop.
Derive Inversion_clear cl_Ilowering with
(forall z : Clock, InvG (Lowering, z)) Sort Prop.
Derive Inversion_clear cl_Iclosed with (forall z : Clock, InvG (Closed, z))
Sort Prop.
Derive Inversion_clear cl_Iraising with (forall z : Clock, InvG (Raising, z))
Sort Prop.
(* Some tactics *)
Ltac Easy := try discriminate; auto with *.
Ltac Easy2 := intros; try discriminate; auto with *.
Ltac Simpl_or eq := elim eq; intro; Easy.
Ltac Simpl_and eq := elim eq; intros; Easy.
Ltac Generalize_Easy eq := generalize eq; intro; Easy.
Ltac Split3_Trivial := split; [ auto with * | split; auto with * ].
Ltac BeginForAll :=
unfold ForAll in |- *; simple induction 1;
[ simpl in |- *; intros; Easy | idtac ].
Ltac SplitTrans :=
intros s1 s2 l rs_s1 p_s1 tr_gl; generalize rs_s1; clear rs_s1;
generalize p_s1; clear p_s1; elim tr_gl.
Ltac SplitTrans_Simpl :=
SplitTrans;
[ Simpl_In
| Simpl_Down
| Simpl_Up
| Simpl_Approach
| Simpl_Exit
| Simpl_Lower
| Simpl_Raise
| Simpl_Tick ]
with Simpl_In :=
intros st1 st2 trt_In; inversion trt_In using cl_TRT_IN;
intros x gt_x_kt1 lt_x_kt2 sc sg; elim sc; elim sg;
simpl in |- *; intros; Easy
with Simpl_Down :=
intros sg1 sg2 trg_Down; inversion trg_Down using cl_TRG_DOWN;
intros z lt_z_kg1 st sc; elim st; elim sc; simpl in |- *;
intros; Easy
with Simpl_Up :=
intros sg1 sg2 trg_Up; inversion trg_Up using cl_TRG_UP;
intros z ge_z_kg2 lt_z_kg3 st sc; elim st; elim sc;
simpl in |- *; intros; Easy
with Simpl_Approach :=
intros st1 st2 sc1 sc2 trt_Approach trc_Approach;
inversion trt_Approach using cl_TRT_APPROACH;
inversion trc_Approach using cl_TRC_APPROACH; intros y x sg;
elim sg; simpl in |- *; intros; Easy
with Simpl_Exit :=
intros st1 st2 sc1 sc2 trt_Exit trc_Exit;
inversion trt_Exit using cl_TRT_EXIT; inversion trc_Exit using cl_TRC_EXIT;
intros y x lt_x_kt2 sg; elim sg; simpl in |- *;
intros; Easy
with Simpl_Lower :=
intros sc1 sc2 sg1 sg2 trc_Lower trg_Lower;
inversion trc_Lower using cl_TRC_LOWER;
inversion trg_Lower using cl_TRG_LOWER; intros z y eq_y_kc1 st;
elim st; simpl in |- *; intros; Easy
with Simpl_Raise :=
intros sc1 sc2 sg1 sg2 trc_Raise trg_Raise;
inversion trc_Raise using cl_TRC_RAISE;
inversion trg_Raise using cl_TRG_RAISE; intros z y lt_y_kc2 st;
elim st; simpl in |- *; intros; Easy
with Simpl_Tick :=
intros st1 st2 sc1 sc2 sg1 sg2 trt_Tick trc_Tick trg_Tick;
inversion trt_Tick using cl_TRT_INC_TIME;
inversion trc_Tick using cl_TRC_INC_TIME;
inversion trg_Tick using cl_TRG_INC_TIME; simpl in |- *;
intros; Easy.
Notation InvTCG :=
(fun s : StGlobal =>
match s with
| (st_x, (sc_y, sg_z)) => InvT st_x /\ InvC sc_y /\ InvG sg_z
end) (only parsing).
Notation ForAll_TCG := (ForAll TrGlobal) (only parsing).
Notation Exists_TCG := (Exists TrGlobal) (only parsing).
(* The initial state of the system TCG satisfy the location invariants *)

Lemma Inv_SiniTCG :
(fun s : StGlobal =>
match s with
| (st_x, (sc_y, sg_z)) => InvT st_x /\ InvC sc_y /\ InvG sg_z
end) SiniTCG.