(* Small step CBV semantics *)
Fixpoint is_value (t : term) : bool :=
  match t with
    | Const _ | Abs _ => true
    | _ => false
  end.Fixpoint subst (y : var) (t1 : term) (t2 : term) : term :=
  match t2 with
    | Const n => Const n
    | Id x =>
      if eq_nat_dec x y then t1 else t2
    | App t t' =>
      App (subst y t1 t) (subst y t1 t')
    | Abs t =>
      subst (S y) t1 t
  end.Notation "'do!' X <- A ; B" :=
  (bindGen A (fun X => B))
    (at level 200, X ident, A at level 100, B at level 200).(* Generator of simple types *)
Definition gen_type : G type := bindGen arbitrary gen_type_size.(* Returns the list of bindings that have type tau in e *)
Definition vars_with_type (e : env) (tau : type) : list term :=
  map (fun p => Id (snd p))
      (filter (fun p => proj1_sig (Sumbool.bool_of_sumbool (type_eq_dec tau (fst p))))
              (combine e (seq 0 (List.length e)))).Definition sigT_of_prod {A B : Type} (p : A * B) : {_ : A & B} :=
  let (a, b) := p in existT (fun _ : A => B) a b.Definition lt_pair (c1 c2 : (nat * type)) : Prop :=
  lexprod nat (fun _ => type) lt (fun _ => lt_type) (sigT_of_prod c1) (sigT_of_prod c2).

Lemma gen_term_size_eq (e : env) (p : nat * type) : gen_term_size p e = gen_term_size_unfold p e.