Section Order.
Fixpoint ord A :=
match A with
| typevar beta => 1
| A → B => max (S (ord A)) (ord B)
end.
Fixpoint ord' Gamma :=
match Gamma with
| nil => 0
| A :: Gamma => max (ord A) (ord' Gamma)
end.
End Order.
Hint Resolve ord'_cons : core.
(* ** Order Typing *)
Reserved Notation "Gamma '⊢(' n ')' s ':' A" (at level 80, s at level 99).
Inductive ordertyping n Gamma: exp X -> type -> Prop :=
| ordertypingVar x A:
ord A <= n -> nth Gamma x = Some A -> Gamma ⊢(n) (var x) : A
| ordertypingConst c:
ord (ctype X c) <= S n  -> Gamma ⊢(n) (const c) : ctype X c
| ordertypingLam s A B:
A :: Gamma ⊢(n) s : B -> Gamma ⊢(n) lambda s : A → B
| ordertypingApp s t A B:
Gamma ⊢(n) s : A → B -> Gamma ⊢(n) t : A -> Gamma ⊢(n) s t : B
where "Gamma '⊢(' n ')' s ':' A" := (ordertyping n Gamma s A).
Hint Constructors ordertyping : core.
Hint Resolve ordertyping_monotone : core.

Lemma vars_ordertyping n x s A Gamma:
x ∈ vars s -> Gamma ⊢(n) s : A -> exists B, nth Gamma x = Some B /\ ord B <= n.