Inductive Const_leq (s : nat) : term -> Prop :=
| IdLe : forall x, Const_leq s (Id x)
| ConstLe : forall n, n <= s -> Const_leq s (Const n)
| AppLe :
forall t1 t2,
Const_leq s t1 -> Const_leq s t2 ->
Const_leq s (App t1 t2)
| AbsLe :
forall t,
Const_leq s t -> Const_leq s (Abs t).
Fixpoint max_const (t : term) : nat :=
match t with
| Id _ => 0
| Const n => n
| App t1 t2 => max (max_const t1) (max_const t2)
| Abs t => max_const t
end.

(* Specifications: *)
Lemma Const_leq_trans :
forall t n1 n2,
n1 <= n2 ->
Const_leq n1 t -> Const_leq n2 t.
Lemma max_const_Const_leq :
forall t, Const_leq (max_const t) t.
Lemma gen_type_size_correctSize :
forall (n s : nat),
semGenSize (gen_type_size n) s <--> [set tau | type_size tau = n].
Lemma gen_type_correctSize :
forall (s : nat),
semGenSize gen_type s <--> [set tau | type_size tau <= s].
Lemma gen_term_no_app_correctSize :
forall (tau : type) (e : env) (s: nat),
semGenSize (gen_term_no_app tau e) s <-->
[set t | typing e t tau /\ app_free t /\ Const_leq s t].
Lemma gen_term_size_correct :
forall (tau : type) (e : env) (n : nat) (s : nat),
semGenSize (gen_term_size (n, tau) e) s <-->
[set t |
(exists maxtau, typing_max_tau e t tau maxtau /\ maxtau <= s) /\
Const_leq s t /\
(exists h, app_no t = h /\ h <= n)].
Lemma gen_term_correct :
forall (tau : type),
semGen (gen_term tau) <--> [set t | typing nil t tau].