Section NthOrderSystemUnification.
Variable (X: Const).
Implicit Types (sigma: fin -> exp X) (e: eq X) (E : eqs X).
Definition eq_ordertyping n Gamma e A := Gamma ⊢(n) fst e : A /\ Gamma ⊢(n) snd e : A.
Notation "Gamma ⊢₂( n ')' e : A" := (eq_ordertyping n Gamma e A) (at level 80, e at level 99).
Reserved Notation  "Gamma ⊢₊₊( n ) E : L" (at level 80, E at level 99).
Inductive eqs_ordertyping Gamma n : eqs X -> list type -> Prop :=
| eqs_ordertyping_nil: Gamma ⊢₊₊(n) nil : nil
| eqs_ordertyping_cons s t  A E L: Gamma ⊢(n) s : A -> Gamma ⊢(n) t : A -> Gamma ⊢₊₊(n) E : L -> Gamma ⊢₊₊(n) ((s,t) :: E) : A :: L
where  "Gamma ⊢₊₊( n ) E : L" := (eqs_ordertyping Gamma n E L).
Hint Constructors eqs_ordertyping : core.
Hint Resolve left_typing right_typing left_ordertyping right_ordertyping : core.
Hint Rewrite Vars'_cons Vars'_app : simplify.
Hint Rewrite left_subst_eqs right_subst_eqs : simplify.
Hint Resolve linearize_terms_ordertyping : core.
Global Program Instance orduni_ordsysuni n (I: orduni n X): ordsysuni n :=
{ Gamma₀' := Gamma₀; E₀' := [(s₀, t₀)]; L₀' := [A₀]; H₀' := _; }.
Global Program Instance ordsysuni_orduni {n} (I: ordsysuni n): ord' L₀' < n -> orduni n X :=
{
Gamma₀ := Gamma₀';
s₀ := linearize_terms (left_side E₀');
t₀ := linearize_terms (right_side E₀');
A₀ := (Arr (rev L₀') alpha) → alpha;
H1₀ := _;
H2₀ := _;
}.
Next Obligation.
assert (1 <= n) by (destruct n; lia); eauto.
Qed.
Next Obligation.
assert (1 <= n) by (destruct n; lia); eauto.
Qed.

Lemma SOU_OU n (I: ordsysuni n) (H: ord' L₀' < n):
SOU n I <-> OU n X (ordsysuni_orduni I H).