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.

(* this generalizes [age_to_join_eq], but we do use [age_to_join_eq] inside this proof *)
Lemma age_to_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_to k x1) (age_to k x2) (age_to k x3).