Variant mem_pred := Mem of pred T.Variant mem_pred := Mem of pred T.Structure predType := PredType {
  pred_sort :> Type;
  topred : pred_sort -> pred T;
  _ : {mem | isMem topred mem}
}.Structure predType := PredType {
  pred_sort :> Type;
  topred : pred_sort -> pred T;
  _ : {mem | isMem topred mem}
}.Structure predType := PredType {
  pred_sort :> Type;
  topred : pred_sort -> pred T;
  _ : {mem | isMem topred mem}
}.Structure predType := PredType {
  pred_sort :> Type;
  topred : pred_sort -> pred T;
  _ : {mem | isMem topred mem}
}.Definition mkPredType pT toP := PredType (exist (@isMem pT toP) _ (erefl _)).Canonical predPredType := Eval hnf in @mkPredType (pred T) id.Canonical simplPredType := Eval hnf in mkPredType pred_of_simpl.Canonical boolfunPredType := Eval hnf in @mkPredType (T -> bool) id.Canonical memPredType := Eval hnf in mkPredType pred_of_mem.Notation "[ 'mem' A ]" := (pred_of_simpl (pred_of_mem_pred (mem A)))
  (at level 0, only parsing) : fun_scope.Notation "[ 'qualify' 'an' x : T | P ]" := (Qualifier 2 (fun x : T => P%B))
  (at level 0, x at level 99, only parsing) : form_scope.(* This redundant coercion lets us "inherit" the simpl_predType canonical    *)
(* instance by declaring a coercion to simpl_pred. This hack is the only way *)
(* to put a predType structure on a predArgType. We use simpl_pred rather    *)
(* than pred to ensure that /= removes the identity coercion. Note that the  *)
(* coercion will never be used directly for simpl_pred, since the canonical  *)
(* instance should always be resolved.                                       *)

Notation pred_class := (pred_sort (predPredType _)).Coercion sort_of_simpl_pred T (p : simpl_pred T) : pred_class := p : pred T.(* This lets us use some types as a synonym for their universal predicate.    *)
(* Unfortunately, this won't work for existing types like bool, unless we     *)
(* redefine bool, true, false and all bool ops.                               *)
Definition predArgType := Type.Identity Coercion sort_of_predArgType : predArgType >-> Sortclass.Coercion pred_of_argType (T : predArgType) : simpl_pred T := predT.Definition in_mem T x mp := nosimpl pred_of_mem T mp x.Definition eq_mem T p1 p2 := forall x : T, in_mem x p1 = in_mem x p2.Definition sub_mem T p1 p2 := forall x : T, in_mem x p1 -> in_mem x p2.

Lemma sub_refl T (p : mem_pred T) : sub_mem p p.