Set Bullet Behavior "Strict Subproofs".
(** * Results on joining lists and the necessary algebras *)
Fixpoint joinlist {A} {JA : Join A} (l : list A) (x : A) :=
match l with
| nil => identity x
| h :: l => exists y, joinlist l y /\ join h y x
end.
Instance Permutation_length' A {JA : Join A} {PA : Perm_alg A} :
Proper (@Permutation A ==> @eq A ==> Logic.iff) joinlist | 10.
(** * Other list functions *)
Fixpoint listoption_inv {A} (l : list (option A)) : list A :=
match l with
| Some x :: l => x :: listoption_inv l
| None :: l => listoption_inv l
| nil => nil
end.
Fixpoint all_but (i : nat) {A} (l : list A) : list A :=
match i with
O => tl l
| S i =>
match l with
nil => nil
| x :: l => x :: all_but i l
end
end.
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 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 - List.length l1) x l2).