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).
(* 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).
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).