(*+ Stdlib: some list functions *)
Fixpoint nth_upd {A} (l : list A) i x :=
match l with
| nil => nil
| y :: l =>
match i with
| O => x :: l
| S i => y :: nth_upd l i x
end
end.

(* Specifications: *)
Lemma eq_nat_dec (a b : nat) : {a=b}+{a<>b}. decide equality. Defined.
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.
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 eq_nat_dec (a b : nat) : {a=b}+{a<>b}. decide equality. Defined.
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.
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.