Fixpoint upd (i : nat) {A} new (l : list A) : option (list A) :=
  match i, l with
  | O, _ :: l => Some (new :: l)
  | _, nil => None
  | S i, x :: l =>
    match upd i new l with
    | Some l' => Some (x :: l')
    | None => None
    end
  end.

Lemma age_by_join {A} {JA: Join A} {PA: Perm_alg A} {agA: ageable A} {AgeA: Age_alg A} : forall k x1 x2 x3, join x1 x2 x3 -> join (age_by k x1) (age_by k x2) (age_by k x3).