Definition list_prod (T: list Type): Type := fold_right prod unit T.Fixpoint list_prod_gen {A} {F} (gen: forall a: A, F a) (l: list A): list_prod (map F l) :=
  match l as l_PAT return list_prod (map F l_PAT) with
  | nil => tt
  | t :: l0 => (gen t, list_prod_gen gen l0)
  end.Notation sigTT P := (fun tv => match tv with existT t v => P t end).Definition list_prod_sigT_type {A} {P: A -> Type} (l: list (sigT P)): Type :=
  list_prod (map (sigTT P) l).Fixpoint list_prod_sigT_value {A} {P: A -> Type} (l: list (sigT P)): list_prod_sigT_type l :=
  match l as l_PAT return list_prod_sigT_type l_PAT with
  | nil => tt
  | tv :: l0 => (match tv as tv_PAT return sigTT P tv_PAT with | existT t v => v end, list_prod_sigT_value l0)
  end.Definition proj_list_prod {A: Type} {F: A -> Type} (a: A) (l: list A) (v: list_prod (map F l)) (default: F a) (H: forall a b: A, {a = b} + {a <> b}) : F a.Definition upd_list_prod {A} {F} (l: list A) (v: list_prod (map F l)) (a: A) (v0: F a) (H: forall a b: A, {a = b} + {a <> b}) : list_prod (map F l).

(* Specifications: *)
Lemma list_prod_sigT_type_list_prod: forall {A: Type} (f: A -> sigT (fun x => x)) (l: list A), list_prod_sigT_type (map f l) = list_prod (map (fun i => let (t, _) := f i in t) l).
Lemma list_prod_sigT_value_list_prod_gen: forall {A: Type} (f: A -> sigT (fun x => x)) (l: list A) (e : list_prod_sigT_type (map f l) = list_prod (map (fun i => let (t, _) := f i in t) l)), list_prod_sigT_value (map f l) = eq_rect_r (fun x : Type => x) (list_prod_gen (fun i => let (t, v) as tv return (let (t, _) := tv in t) := f i in v) l) e.