Fact list_injective_map X Y (f : X -> Y) ll :
       (forall x y, f x = f y -> x = y) -> list_injective ll -> list_injective (map f ll).Fixpoint iter x n :=
    match n with
      | 0   => x
      | S n => iter (f x) n
    end.Fact iter_plus x a b : iter x (a+b) = iter (iter x a) b.Fact iter_swap x n : iter (f x) n = f (iter x n).Fixpoint list_repeat X (x : X) n :=
  match n with
    | 0   => nil
    | S n => x::list_repeat x n
  end.Fact list_repeat_plus X x a b : @list_repeat X x (a+b) = list_repeat x a ++ list_repeat x b.Fact list_repeat_length X x n : length (@list_repeat X x n) = n.Fact In_list_repeat X (x y : X) n : In y (list_repeat x n) -> x = y /\ 0 < n.Fact map_list_repeat X Y f x n : @map X Y f (list_repeat x n) = list_repeat (f x) n.Fact map_cst_repeat X Y (y : Y) ll : map (fun _ : X => y) ll = list_repeat y (length ll).Fact map_cst_snoc X Y (y : Y) ll mm : y :: map (fun _ : X => y) ll++mm = map (fun _ => y) ll ++ y::mm.Fact map_cst_rev  X Y (y : Y) ll : map (fun _ : X => y) (rev ll) = map (fun _ => y) ll.Fact list_app_eq_inv X (l1 l2 r1 r2 : list X) :
       l1++r1 = l2++r2 -> { m | l1++m = l2 /\ r1 = m++r2 } 
                        + { m | l2++m = l1 /\ r2 = m++r1 }.Fact list_app_cons_eq_inv X (l1 l2 r1 r2 : list X) x :
       l1++r1 = l2++x::r2 -> { m | l1++m = l2 /\ r1 = m++x::r2 } 
                           + { m | l2++x::m = l1 /\ r2 = m++r1 }.Fact list_cons_app_cons_eq_inv X (l2 r1 r2 : list X) x y :
       x::r1 = l2++y::r2 -> (l2 = nil /\ x = y /\ r1 = r2) 
                          + { m | l2 = x::m /\ r1 = m++y::r2 }.Fact list_app_inj X (l1 l2 r1 r2 : list X) : length l1 = length l2 -> l1++r1 = l2++r2 -> l1 = l2 /\ r1 = r2.Fact list_split_length X (ll : list X) k : k <= length ll -> { l : _ & { r | ll = l++r /\ length l = k } }.Fact list_pick X (ll : list X) k : k < length ll -> { x : _ & { l : _ & { r | ll = l++x::r /\ length l = k } } }.Fact list_split_middle X l1 (x1 : X) r1 l2 x2 r2 : 
       ~ In x1 l2 -> ~ In x2 l1 -> l1++x1::r1 = l2++x2::r2 -> l1 = l2 /\ x1 = x2 /\ r1 = r2.Fact flat_map_app l1 l2 : flat_map f (l1++l2) = flat_map f l1 ++ flat_map f l2.Fact flat_map_app_inv l r1 y r2 : flat_map f l = r1++y::r2 -> exists l1 m1 x m2 l2, l = l1++x::l2 /\ f x = m1++y::m2 
                                                                  /\ r1 = flat_map f l1++m1 /\ r2 = m2++flat_map f l2.Definition prefix X (l ll : list X) := exists r, ll = l++r.Fact in_prefix_0 ll : nil <p ll.Fact in_prefix_1 x l ll : l <p ll -> x::l <p x::ll.Fact prefix_length l m : l <p m -> length l <= length m.Fact prefix_app_lft l r1 r2 : r1 <p r2 -> l++r1 <p l++r2.Fact prefix_inv x y l ll : x::l <p y::ll -> x = y /\ l <p ll.Fact prefix_list_inv l r rr : l++r <p l++rr -> r <p rr.Fact prefix_refl l : l <p l.Fact prefix_trans l1 l2 l3 : l1 <p l2 -> l2 <p l3 -> l1 <p l3.Definition prefix_rect l ll : prefix l ll -> P l ll.Fact prefix_app_inv l1 l2 r1 r2 : l1++l2 <p r1++r2 -> { l1 <p r1 } + { r1 <p l1 }.Definition prefix_spec X (l ll : list X) : l <p ll -> { r | ll = l ++ r }.Fact prefix_app_lft_inv X (l1 l2 m : list X) : l1++l2 <p m -> { m2 | m = l1++m2 /\ l2 <p m2 }.Fixpoint list_assoc x l : option Y :=
    match l with 
      | nil  => None
      | (y,a)::l => if eq_X_dec x y then Some a else list_assoc x l
    end.Fact list_assoc_eq x y l x' : x = x' -> list_assoc x' ((x,y)::l) = Some y.Fact list_assoc_neq x y l x' : x <> x' -> list_assoc x' ((x,y)::l) = list_assoc x' l.Fact list_assoc_In x l : 
    match list_assoc x l with 
      | None   => ~ In x (map fst l)
      | Some y => In (x,y) l
    end.Fact In_list_assoc x l : In x (map fst l) -> { y | list_assoc x l = Some y /\ In (x,y) l }.Fact not_In_list_assoc x l : ~ In x (map fst l) -> list_assoc x l = None.Fact list_assoc_app x ll mm : list_assoc x (ll++mm) 
                              = match list_assoc x ll with
                                  | None   => list_assoc x mm
                                  | Some y => Some y
                                end.

Theorem list_choose_dec ll : { l : _ & { x : _ & { r | ll = l++x::r /\ P x /\ forall y, In y l -> ~ P y } } } + { forall x, In x ll -> ~ P x }.