Section inversion_lemmas.
(* The inversion tactic won't work for the dependent predicate ra_ca so we build the inversion lemma by hand.  Notice the presence of type-castings (eq_rect ...) which disappear when we instanciate that lemma on the individual cases (the lemmas ra_ca_*_inv below)  The statement of the lemma is complicated but the proof is trivial !! *)
(* The next proofs by hand are long but not complicated ... we simply have to discard all the unnecessary cases generated by the general inversion lemma using the discriminate tactic *)
(* Automation is our friend here *)
(* This is to destruct the inversion lemma  This lemma creates variables which are partly hard coded ... this is not ideal and could be improved *)
Local Ltac myinv :=
let H := fresh in
intros H;
apply ra_ca_inv in H;
destruct H as   [ (? & ? & ?)
| [ (? & ? & ? & ?)
| [ (? & ? & ? & ?)
| [ (? & ? & ? & ?)
| [ (? & ? & ? & w' & q' & m' & ? & ? & ? & ?)
| [ (? & ? & ? & ? & m' & ? & ? & ? & ?)
| [ (? & ? & ? & y' & ? & ? & p' & q' & ? & ? & ? & ? & ?)
| (? & m' & w' & q' & ? & ? & ? & ?)
] ] ] ] ] ] ].
Ltac injc H := injection H; clear H;
repeat match goal with
|- _ = _ -> _ =>
intro; subst end.
Ltac eqgoal :=
match goal with
|- ?a -> ?b => replace a with b; auto
end.
Ltac inst H :=
let K := fresh in
match goal with
| [ G : ?x -> _ |- _ ] =>
match G with
H => assert (x) as K; [ clear H | specialize (H K); clear K ]
end
end.
Fact eq_gen { X } (P : X -> Type) x : (forall y, y = x -> P y) -> P x.
(* These 4 proofs use variable names which are hard coded in the tactic myinv ... they should not conflict with other variables names but be warned that this is not an ideal situation for the stability of those proofs *)

Lemma ra_ca_rec_0_inv k f g v n x :
[@ra_rec k f g; 0##v] -[n>> x -> exists m, n = S m /\ [f;v] -[m>> x.