(**  Notations for pair/conjunction projections  **)
Notation "p .1" := (fst p) : pair_scope.Notation "p .2" := (snd p) : pair_scope.Coercion pair_of_and P Q (PandQ : P /\ Q) := (proj1 PandQ, proj2 PandQ).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)).Definition lift aT rT (f : aT -> rT) := fun x => Some (f x).Notation oapp := Option.apply.Notation odflt := Option.default.Notation obind := Option.bind.Notation omap := Option.map.Notation olift := Option.lift.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.