Module Exports.
Coercion sort : type >-> Sortclass.
Notation eqType := type.
Notation EqMixin := Mixin.
Notation EqType T m := (@Pack T m).
Notation "[ 'eqMixin' 'of' T ]" := (class _ : mixin_of T)
(at level 0, format "[ 'eqMixin'  'of'  T ]") : form_scope.
Notation "[ 'eqType' 'of' T 'for' C ]" := (@clone T C _ idfun id)
(at level 0, format "[ 'eqType'  'of'  T  'for'  C ]") : form_scope.
Notation "[ 'eqType' 'of' T ]" := (@clone T _ _ id id)
(at level 0, format "[ 'eqType'  'of'  T ]") : form_scope.
End Exports.
End Equality.
Export Equality.Exports.
Definition eq_op T := Equality.op (Equality.class T).
End Theory.
End SubType.
Arguments SubType {T P} sub_sort val Sub rec SubK.
Arguments val {T P sT} u : rename.
Arguments Sub {T P sT} x Px : rename.
Arguments vrefl {T P} x Px.
Arguments vrefl_rect {T P} x Px.
Arguments clone_subType [T P] U v [sT] _ [c Urec cK].
Arguments insub {T P sT} x.
Arguments insubd {T P sT} u0 x.
Arguments insubT [T] P [sT x].
Arguments val_inj {T P sT} [u1 u2] eq_u12 : rename.
Arguments valK {T P sT} u : rename.
Arguments valKd {T P sT} u0 u : rename.
Arguments insubK {T P} sT x.
Arguments insubdK {T P sT} u0 [x] Px.
Local Notation inlined_sub_rect :=
(fun K K_S u => let (x, Px) as u return K u := u in K_S x Px).
Local Notation inlined_new_rect :=
(fun K K_S u => let (x) as u return K u := u in K_S x).
Reserved Notation "[ 'subType' 'for' v ]"
(at level 0, format "[ 'subType'  'for'  v ]").
Notation "[ 'subType' 'for' v ]" := (SubType _ v _ inlined_sub_rect vrefl_rect)
(only parsing) : form_scope.
Notation "[ 'subType' 'for' v ]" := (SubType _ v _ _ vrefl_rect)
(only printing) : form_scope.
Notation "[ 'subType' 'for' v 'by' rec ]" := (SubType _ v _ rec vrefl)
(at level 0, format "[ 'subType'  'for'  v  'by'  rec ]") : form_scope.
Notation "[ 'subType' 'of' U 'for' v ]" := (clone_subType U v id idfun)
(at level 0, format "[ 'subType'  'of'  U  'for'  v ]") : form_scope.
Notation "[ 'subType' 'of' U ]" := (clone_subType U _ id id)
(at level 0, format "[ 'subType'  'of'  U ]") : form_scope.
Definition NewType T U v c Urec :=
let Urec' P IH := Urec P (fun x : T => IH x isT : P _) in
SubType U v (fun x _ => c x) Urec'.
Arguments NewType [T U].
Reserved Notation "[ 'newType' 'for' v ]" (at level 0, format "[ 'newType'  'for'  v ]").
Notation "[ 'newType' 'for' v ]" := (NewType v _ inlined_new_rect vrefl_rect)
(only parsing) : form_scope.
Notation "[ 'newType' 'for' v ]" := (NewType v _ _ vrefl_rect)
(only printing) : form_scope.
Notation "[ 'newType' 'for' v 'by' rec ]" := (NewType v _ rec vrefl)
(at level 0, format "[ 'newType'  'for'  v  'by'  rec ]") : form_scope.
Definition innew T nT x := @Sub T predT nT x (erefl true).
Arguments innew {T nT}.
Canonical prod_eqMixin := EqMixin pair_eqP.
Canonical prod_eqType := Eval hnf in EqType (T1 * T2) prod_eqMixin.

Lemma xpair_eqE (x1 y1 : T1) (x2 y2 : T2) :
((x1, x2) == (y1, y2)) = ((x1 == y1) && (x2 == y2)).