Set Implicit Arguments.
Unset Strict Implicit.
(* Call-by-value semantics *)
Section CBV.
Variables variable function constructor : Type.
Variable max_arity : nat.
Notation value := (Syntax.value constructor).
Notation term := (Syntax.term variable function constructor).
Notation pattern := (Syntax.pattern variable constructor).
Notation rule := (Syntax.rule variable function constructor).
(* proof tree *)
Inductive cbv : Type :=
| cbv_constr : list cbv -> term -> value -> cbv
| cbv_split : list cbv -> cbv -> term -> value -> cbv
| cbv_function : nat -> (variable -> value) -> cbv -> term -> value -> cbv.
(* Smarter induction principle than the one automatically generated *)

Lemma cbv_ind2 :
forall (P : cbv -> Prop),
(forall lp t v, (forall p, In p lp -> P p) -> P (cbv_constr lp t v)) ->
(forall lp p t v, (forall p, In p lp -> P p) -> P p -> P (cbv_split lp p t v)) ->
(forall n s p t v, P p -> P (cbv_function n s p t v)) ->
forall p, P p.