Definition nominal_induction
  : forall (P : n_exp -> Type),
    (forall x : atom, P (n_var x)) ->
    (forall (x : atom) (t : n_exp),
        (forall y : atom, P (swap x y t)) -> P (n_abs x t)) ->
    (forall t1 t2 : n_exp, P t1 -> P t2 -> P (n_app t1 t2)) ->
    forall t : n_exp, P t :=
  fun P VAR APP ABS t =>
  nominal_induction_size (size t) t ltac:(auto) P VAR APP ABS.(** Our real substitution function uses the size of the size of the term
    as that extra argument. *)
Definition subst (u : n_exp) (x:atom) (t:n_exp) :=
  subst_rec (size t) t u x.

(* Specifications: *)
Lemma subst_size : forall n (u : n_exp) (x:atom) (t:n_exp), size t <= n -> subst_rec n t u x = subst_rec (size t) t u x.
Lemma subst_eq_var : forall u x, subst u x (n_var x) = u.
Lemma subst_neq_var : forall u x y, x <> y -> subst u x (n_var y) = n_var y.
Lemma subst_app : forall u x t1 t2, subst u x (n_app t1 t2) = n_app (subst u x t1) (subst u x t2).
Lemma aeq_refl : forall n, aeq n n.
Lemma subst_equivariance : forall u x y z t, swap x y (subst u z t) = subst (swap x y u) (swap_var x y z) (swap x y t).
Lemma subst_same : forall t y, aeq (subst (n_var y) y t) t.
Lemma aeq_sym : forall t1 t2, aeq t1 t2 -> aeq t2 t1.
Lemma aeq_trans_aux : forall n t2 t1 t3, size t2 <= n -> aeq t1 t2 -> aeq t2 t3 -> aeq t1 t3.