(* Remplace l'element de l a la position par new *)
Fixpoint replace (l : list A) : nat -> A -> list A :=
  fun (position : nat) (new : A) =>
  match l return (list A) with
  | nil =>
      (* nil *)  nil
  | x :: l' =>
      (* (cons x l') *)
      match position return (list A) with
      | O =>
          (* O *)  new :: l'
          (* (S n') *)
      | S n' => x :: replace l' n' new
      end
  end.

(* Specifications: *)
Lemma replace_ok : forall (l : list A) (i : nat) (x : A), (***************) i < length l -> elemlist A (replace l i x) i = x :: nil.
Lemma replace_keep_others : forall (l : list A) (i p : nat) (x : A), (************************) i < length l -> p < length l -> i <> p -> elemlist A (replace l p x) i = elemlist A l i.
Lemma length_replace : forall (l : list A) (p : nat) (x : A), (*******************) p < length l -> length (replace l p x) = length l.
Lemma replace_sym : forall (l : list A) (p p' : nat) (x x' : A), (****************) p < length l -> p' < length l -> p <> p' -> replace (replace l p' x') p x = replace (replace l p x) p' x'.
Lemma replace_newer : forall (l : list A) (p : nat) (x x' : A), (*****************) p < length l -> replace (replace l p x) p x' = replace l p x'.