(** Variant of simpl_pred specialised to the membership operator. **)

Variant mem_pred T := Mem of pred T.(** Variant of simpl_pred specialised to the membership operator. **)

Variant mem_pred T := Mem of pred T.(**
  We mainly declare pred_of_mem as a coercion so that it is not displayed.
  Similarly to pred_of_simpl, it will usually not be inserted by type
  inference, as all mem_pred mp =~= pred_sort ?pT unification problems will
  be solve by the memPredType instance below; pred_of_mem will however
  be used if a mem_pred T is used as a {pred T}, which is desirable as it
  will avoid a redundant mem in a collective, e.g., passing (mem A) to a lemma
  exception a generic collective predicate p : {pred T} and premise x \in P
  will display a subgoal x \in A rather than x \in mem A.
    Conversely, pred_of_mem will _not_ if it is used id (mem A) is used
  applicatively or as a pred T; there the simpl_of_mem coercion defined below
  will be used, resulting in a subgoal that displays as mem A x by simplifies
  to x \in A.
 **)
Coercion pred_of_mem {T} mp : {pred T} := let: Mem p := mp in [eta p].Canonical memPredType T := PredType (@pred_of_mem T).Definition in_mem {T} (x : T) mp := pred_of_mem mp x.Definition eq_mem {T} mp1 mp2 := forall x : T, in_mem x mp1 = in_mem x mp2.Definition sub_mem {T} mp1 mp2 := forall x : T, in_mem x mp1 -> in_mem x mp2.(** The [simpl_of_mem; pred_of_simpl] path provides a new mem_pred >-> pred
  coercion, but does _not_ override the pred_of_mem : mem_pred >-> pred_sort
  explicit coercion declaration above.
 **)
Coercion simpl_of_mem {T} mp := SimplPred (fun x : T => in_mem x mp).

(* Specifications: *)
Lemma sub_refl T (mp : mem_pred T) : sub_mem mp mp.