Inductive cbv : Type :=
| cbv_constr : list cbv -> cache -> term -> cache -> value -> cbv
| cbv_split : list cbv -> cbv -> cache -> term -> cache -> value -> cbv
| cbv_update : nat -> (variable -> value) -> cbv -> cache -> term -> cache -> value -> cbv
| cbv_read : cache -> term -> value -> cbv.
(* Smarter induction principle than the one automatically generated *)

Lemma cbv_ind2_gen :
forall (P : cbv -> Prop)(Q : list cbv -> Prop),
Q nil ->
(forall p lp, P p -> Q lp -> Q (p :: lp)) ->
(forall lp c1 t c2 v, Q lp -> P (cbv_constr lp c1 t c2 v)) ->
(forall lp p c1 t c2 v, Q lp -> P p -> P (cbv_split lp p c1 t c2 v)) ->
(forall n s p c1 t c2 v, P p -> P (cbv_update n s p c1 t c2 v)) ->
(forall c t v, P (cbv_read c t v)) ->
forall p, P p.