Implicit Types (x : T) (p : pred T) (sp : simpl_pred T) (pp : pT).(* Bespoke structures that provide fine-grained control over matching the     *)
(* various forms of the \in predicate; note in particular the different forms *)
(* of hoisting that are used. We had to work around several bugs in the       *)
(* implementation of unification, notably improper expansion of telescope     *)
(* projections and overwriting of a variable assignment by a later            *)
(* unification (probably due to conversion cache cross-talk).                 *)
Structure manifest_applicative_pred p := ManifestApplicativePred {
  manifest_applicative_pred_value :> pred T;
  _ : manifest_applicative_pred_value = p
}.(* Bespoke structures that provide fine-grained control over matching the     *)
(* various forms of the \in predicate; note in particular the different forms *)
(* of hoisting that are used. We had to work around several bugs in the       *)
(* implementation of unification, notably improper expansion of telescope     *)
(* projections and overwriting of a variable assignment by a later            *)
(* unification (probably due to conversion cache cross-talk).                 *)
Structure manifest_applicative_pred p := ManifestApplicativePred {
  manifest_applicative_pred_value :> pred T;
  _ : manifest_applicative_pred_value = p
}.(* Bespoke structures that provide fine-grained control over matching the     *)
(* various forms of the \in predicate; note in particular the different forms *)
(* of hoisting that are used. We had to work around several bugs in the       *)
(* implementation of unification, notably improper expansion of telescope     *)
(* projections and overwriting of a variable assignment by a later            *)
(* unification (probably due to conversion cache cross-talk).                 *)
Structure manifest_applicative_pred p := ManifestApplicativePred {
  manifest_applicative_pred_value :> pred T;
  _ : manifest_applicative_pred_value = p
}.Definition ApplicativePred p := ManifestApplicativePred (erefl p).Canonical applicative_pred_applicative sp :=
  ApplicativePred (applicative_pred_of_simpl sp).Structure manifest_simpl_pred p := ManifestSimplPred {
  manifest_simpl_pred_value :> simpl_pred T;
  _ : manifest_simpl_pred_value = SimplPred p
}.Structure manifest_simpl_pred p := ManifestSimplPred {
  manifest_simpl_pred_value :> simpl_pred T;
  _ : manifest_simpl_pred_value = SimplPred p
}.Structure manifest_simpl_pred p := ManifestSimplPred {
  manifest_simpl_pred_value :> simpl_pred T;
  _ : manifest_simpl_pred_value = SimplPred p
}.Canonical expose_simpl_pred p := ManifestSimplPred (erefl (SimplPred p)).Canonical expose_mem_pred p :=  @ManifestMemPred p _ (erefl _).Structure applicative_mem_pred p :=
  ApplicativeMemPred {applicative_mem_pred_value :> manifest_mem_pred p}.Structure applicative_mem_pred p :=
  ApplicativeMemPred {applicative_mem_pred_value :> manifest_mem_pred p}.Structure applicative_mem_pred p :=
  ApplicativeMemPred {applicative_mem_pred_value :> manifest_mem_pred p}.Canonical check_applicative_mem_pred p (ap : manifest_applicative_pred p) mp :=
  @ApplicativeMemPred ap mp.

(* Specifications: *)
Lemma mem_topred (pp : pT) : mem (topred pp) = mem pp.
Lemma topredE x (pp : pT) : topred pp x = (x \in pp).
Lemma app_predE x p (ap : manifest_applicative_pred p) : ap x = (x \in p).
Lemma in_applicative x p (amp : applicative_mem_pred p) : in_mem x amp = p x.
Lemma in_collective x p (msp : manifest_simpl_pred p) : (x \in collective_pred_of_simpl msp) = p x.
Lemma simpl_predE p : SimplPred p =1 p.