Ltac ifeq :=
    match goal with
      [ H : context [ eq_nat_dec ?x ?x ] |- _ ] => destruct (eq_nat_dec x x) as [_|]; [|congruence]
    | [ |- context [ eq_nat_dec ?x ?x ] ] => destruct (eq_nat_dec x x) as [_|]; [|congruence]
    | [ H : context [ eq_nat_dec ?x ?y ] |- _ ] => destruct (eq_nat_dec x y)
    | [ |- context [ eq_nat_dec ?x ?y ] ] => destruct (eq_nat_dec x y)
    end.

(* Specifications: *)
Lemma nth_nth_upd {A} (l : list A) i x y j : nth l i = Some x -> nth (nth_upd l i y) j = if eq_nat_dec i j then Some y else nth l j.
Lemma nth_upd_app_1 {A} (l1 l2 : list A) i x y : nth l1 i = Some x -> nth_upd l1 i y ++ l2 = nth_upd (l1 ++ l2) i y.
Lemma nth_app_1 {A} (l1 l2 : list A) i x : nth l1 i = Some x -> nth (l1 ++ l2) i = Some x.
Lemma nth_snoc {A} i (l : list A) x : i <> List.length l -> nth (l ++ x :: nil) i = nth l i.
Lemma nth_snoc_len {A} (l : list A) x : nth (l ++ x :: nil) (List.length l) = Some x.
Lemma nth_len {A} (l : list A) : nth l (List.length l) = None.
Lemma length_nth_upd {A} (l : list A) i x : List.length (nth_upd l i x) = List.length l.
Lemma nth_nth_upd' {A} i j l (x : A) : j <> i -> nth (nth_upd l i x) j = nth l j.
Lemma nth_nth_upd {A} (l : list A) i x y j : nth l i = Some x -> nth (nth_upd l i y) j = if eq_nat_dec i j then Some y else nth l j.
Lemma nth_upd_app_1 {A} (l1 l2 : list A) i x y : nth l1 i = Some x -> nth_upd l1 i y ++ l2 = nth_upd (l1 ++ l2) i y.
Lemma nth_app_1 {A} (l1 l2 : list A) i x : nth l1 i = Some x -> nth (l1 ++ l2) i = Some x.
Lemma nth_snoc {A} i (l : list A) x : i <> List.length l -> nth (l ++ x :: nil) i = nth l i.
Lemma nth_snoc_len {A} (l : list A) x : nth (l ++ x :: nil) (List.length l) = Some x.
Lemma nth_len {A} (l : list A) : nth l (List.length l) = None.
Lemma length_nth_upd {A} (l : list A) i x : List.length (nth_upd l i x) = List.length l.
Lemma nth_nth_upd' {A} i j l (x : A) : j <> i -> nth (nth_upd l i x) j = nth l j.
Lemma nth_nth_upd {A} (l : list A) i x y j : nth l i = Some x -> nth (nth_upd l i y) j = if eq_nat_dec i j then Some y else nth l j.
Lemma nth_upd_app_1 {A} (l1 l2 : list A) i x y : nth l1 i = Some x -> nth_upd l1 i y ++ l2 = nth_upd (l1 ++ l2) i y.
Lemma nth_app_1 {A} (l1 l2 : list A) i x : nth l1 i = Some x -> nth (l1 ++ l2) i = Some x.
Lemma nth_snoc {A} i (l : list A) x : i <> List.length l -> nth (l ++ x :: nil) i = nth l i.
Lemma nth_snoc_len {A} (l : list A) x : nth (l ++ x :: nil) (List.length l) = Some x.
Lemma nth_len {A} (l : list A) : nth l (List.length l) = None.
Lemma length_nth_upd {A} (l : list A) i x : List.length (nth_upd l i x) = List.length l.
Lemma nth_nth_upd' {A} i j l (x : A) : j <> i -> nth (nth_upd l i x) j = nth l j.