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.
Definition ordertypingSubst n Delta sigma Gamma :=
forall i A, nth Gamma i = Some A -> Delta ⊢(n) sigma i : A.
Notation "Delta ⊩( n ) sigma : Gamma" := (ordertypingSubst n Delta sigma Gamma)
(at level 80, sigma at level 99).

Lemma ordertypingSubst_complete Delta sigma Gamma:
Delta ⊩ sigma : Gamma -> exists n, Delta ⊩(n) sigma : Gamma.