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.

(* Specifications: *)
Lemma permutation_upd {A} i (l l' : list A) x : upd i x l = Some l' -> Permutation l' (x :: all_but i l).
Lemma upd_lt {A} i x l : @upd i A x l <> None <-> lt i (length l).
Lemma upd_app_Some {A} i x (l1 l1' l2 : list A) : upd i x l1 = Some l1' -> upd i x (l1 ++ l2) = Some (l1' ++ l2).
Lemma upd_app_None {A} i x (l1 l2 : list A) : upd i x l1 = None -> upd i x (l1 ++ l2) = option_map (app l1) (upd (i - length l1) x l2).
Lemma upd_last {A} i l (a x : A) : i = length l -> upd i x (l ++ a :: nil) = Some (l ++ x :: nil).
Lemma upd_rev {A} i x (l : list A) : (i < length l)%nat -> upd i x (rev l) = option_map (@rev A) (upd (length l - 1 - i) x l).
Lemma age_by_overflow {A} {_ : ageable A} {JA: Join A} (x : A) n : le (level x) n -> age_by n x = age_by (level x) x.
Lemma age_by_minusminus {A} {_ : ageable A} {JA: Join A} (x : A) n : age_by (level x - (level x - n)) x = age_by n x.
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).
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).
Lemma age_by_joins {A} {JA: Join A} {PA: Perm_alg A} {agA: ageable A} {AgeA: Age_alg A} : forall k x1 x2, joins x1 x2 -> joins (age_by k x1) (age_by k x2).
Lemma age_to_joins {A} {JA: Join A} {PA: Perm_alg A} {agA: ageable A} {AgeA: Age_alg A} : forall k x1 x2, joins x1 x2 -> joins (age_to k x1) (age_to k x2).
Lemma age_to_join_sub {A} {JA: Join A} {PA: Perm_alg A} {agA: ageable A} {AgeA: Age_alg A} : forall k x1 x2, join_sub x1 x2 -> join_sub (age_to k x1) (age_to k x2).
Lemma joinlist_level {A} `{agA : ageable A} {J : Join A} {_ : Perm_alg A} {_ : Age_alg A} (x : A) l Phi : joinlist l Phi -> In x l -> level x = level Phi.
Lemma joinlist_age1' {A} `{agA : ageable A} {J : Join A} {_ : Age_alg A} {_ : Perm_alg A} (l : list A) (x : A) : joinlist l x -> joinlist (map age1' l) (age1' x).
Lemma joinlist_age_to {A} `{agA : ageable A} {J : Join A} {_ : Age_alg A} {_ : Perm_alg A} n (l : list A) (x : A) : joinlist l x -> joinlist (map (age_to n) l) (age_to n x).