Notation "@ 'idfun' T " := (@id_head T explicit_id_key)
  (at level 10, T at level 8, format "@ 'idfun'  T") : fun_scope.Notation "p .2" := (snd p)
  (at level 2, left associativity, format "p .2") : pair_scope.Coercion pair_of_and P Q (PandQ : P /\ Q) := (proj1 PandQ, proj2 PandQ).Definition all_pair I T U (w : forall i : I, T i * U i) :=
  (fun i => (w i).1, fun i => (w i).2).Definition apply aT rT (f : aT -> rT) x u := if u is Some y then f y else x.Definition default T := apply (fun x : T => x).Definition bind aT rT (f : aT -> option rT) := apply f None.Definition map aT rT (f : aT -> rT) := bind (fun x => Some (f x)).Notation oapp := Option.apply.Notation odflt := Option.default.Notation obind := Option.bind.Notation omap := Option.map.Notation some := (@Some _) (only parsing).(* Shorthand for some basic equality lemmas. *)

Notation erefl := refl_equal.Notation ecast i T e x := (let: erefl in _ = i := e return T in x).Definition esym := sym_eq.Definition nesym := sym_not_eq.Definition etrans := trans_eq.Definition congr1 := f_equal.Definition congr2 := f_equal2.(* A predicate for singleton types.                                           *)
Definition all_equal_to T (x0 : T) := forall x, unkeyed x = x0.

Lemma unitE : all_equal_to tt.