Record mixin_of (T : Type) := Mixin {
    valid_op : T -> bool;
    join_op : T -> T -> T;
    unit_op : T;
    _ : commutative join_op;
    _ : associative join_op;
    _ : left_id unit_op join_op;
    (* monotonicity of valid *)
    _ : forall x y, valid_op (join_op x y) -> valid_op x; 
    (* unit is valid *)
    _ : valid_op unit_op}.Record mixin_of (T : Type) := Mixin {
    valid_op : T -> bool;
    join_op : T -> T -> T;
    unit_op : T;
    _ : commutative join_op;
    _ : associative join_op;
    _ : left_id unit_op join_op;
    (* monotonicity of valid *)
    _ : forall x y, valid_op (join_op x y) -> valid_op x; 
    (* unit is valid *)
    _ : valid_op unit_op}.Record mixin_of (T : Type) := Mixin {
    valid_op : T -> bool;
    join_op : T -> T -> T;
    unit_op : T;
    _ : commutative join_op;
    _ : associative join_op;
    _ : left_id unit_op join_op;
    (* monotonicity of valid *)
    _ : forall x y, valid_op (join_op x y) -> valid_op x; 
    (* unit is valid *)
    _ : valid_op unit_op}.Record mixin_of (T : Type) := Mixin {
    valid_op : T -> bool;
    join_op : T -> T -> T;
    unit_op : T;
    _ : commutative join_op;
    _ : associative join_op;
    _ : left_id unit_op join_op;
    (* monotonicity of valid *)
    _ : forall x y, valid_op (join_op x y) -> valid_op x; 
    (* unit is valid *)
    _ : valid_op unit_op}.Record mixin_of (T : Type) := Mixin {
    valid_op : T -> bool;
    join_op : T -> T -> T;
    unit_op : T;
    _ : commutative join_op;
    _ : associative join_op;
    _ : left_id unit_op join_op;
    (* monotonicity of valid *)
    _ : forall x y, valid_op (join_op x y) -> valid_op x; 
    (* unit is valid *)
    _ : valid_op unit_op}.Notation class_of := mixin_of (only parsing).Structure type : Type := Pack {sort : Type; _ : class_of sort}.Structure type : Type := Pack {sort : Type; _ : class_of sort}.Structure type : Type := Pack {sort : Type; _ : class_of sort}.Definition class := let: Pack _ c as cT' := cT return class_of cT' in c.Definition pack c := @Pack T c.Definition clone := fun c & cT -> T & phant_id (pack c) cT => pack c.Definition valid := valid_op class.Definition join := join_op class.Definition unit := unit_op class.Notation pcm := type.Notation PCMMixin := Mixin.Notation PCM T m := (@pack T m).Notation "[ 'pcmMixin' 'of' T ]" := (class _ : mixin_of T)
  (at level 0, format "[ 'pcmMixin'  'of'  T ]") : pcm_scope.Notation "[ 'pcm' 'of' T 'for' C ]" := (@clone T C _ idfun id)
  (at level 0, format "[ 'pcm'  'of'  T  'for'  C ]") : pcm_scope.Notation "[ 'pcm' 'of' T ]" := (@clone T _ _ id id)
  (at level 0, format "[ 'pcm'  'of'  T ]") : pcm_scope.Notation "x \+ y" := (join x y) 
  (at level 43, left associativity) : pcm_scope.Notation valid := valid.Notation Unit := unit.

(* Specifications: *)
Lemma valid_unit : valid (@Unit U).
Lemma pcm_validE (x : U) : valid x = valid_op (class U) x.
Lemma pcm_unitE : unit = unit_op (class U).