Structure mixin_of (T : Type) := Mixin {
  defined_op : T -> bool;
  empty_op : T;
  undef_op : T;
  upd_op : K -> V -> T -> T;
  dom_op : T -> seq K;
  dom_eq_op : T -> T -> bool;
  free_op : K -> T -> T;
  find_op : K -> T -> option V;
  union_op : T -> T -> T;
  um_filter_op : pred K -> T -> T;
  empb_op : T -> bool;
  undefb_op : T -> bool;
  pts_op : K -> V -> T;

  from_op : T -> UM.base V p;
  to_op : UM.base V p -> T;
  _ : forall b, from_op (to_op b) = b;
  _ : forall f, to_op (from_op f) = f;
  _ : forall f, defined_op f = UM.valid (from_op f);
  _ : undef_op = to_op (UM.Undef V p);
  _ : empty_op = to_op (UM.empty V p);
  _ : forall k v f, upd_op k v f = to_op (UM.upd k v (from_op f));
  _ : forall f, dom_op f = UM.dom (from_op f);
  _ : forall f1 f2, dom_eq_op f1 f2 = UM.dom_eq (from_op f1) (from_op f2);
  _ : forall k f, free_op k f = to_op (UM.free k (from_op f));
  _ : forall k f, find_op k f = UM.find k (from_op f);
  _ : forall f1 f2, 
        union_op f1 f2 = to_op (UM.union (from_op f1) (from_op f2));
  _ : forall q f, um_filter_op q f = to_op (UM.um_filter q (from_op f));
  _ : forall f, empb_op f = UM.empb (from_op f);
  _ : forall f, undefb_op f = UM.undefb (from_op f);
  _ : forall k v, pts_op k v = to_op (UM.pts p k v)}.Structure mixin_of (T : Type) := Mixin {
  defined_op : T -> bool;
  empty_op : T;
  undef_op : T;
  upd_op : K -> V -> T -> T;
  dom_op : T -> seq K;
  dom_eq_op : T -> T -> bool;
  free_op : K -> T -> T;
  find_op : K -> T -> option V;
  union_op : T -> T -> T;
  um_filter_op : pred K -> T -> T;
  empb_op : T -> bool;
  undefb_op : T -> bool;
  pts_op : K -> V -> T;

  from_op : T -> UM.base V p;
  to_op : UM.base V p -> T;
  _ : forall b, from_op (to_op b) = b;
  _ : forall f, to_op (from_op f) = f;
  _ : forall f, defined_op f = UM.valid (from_op f);
  _ : undef_op = to_op (UM.Undef V p);
  _ : empty_op = to_op (UM.empty V p);
  _ : forall k v f, upd_op k v f = to_op (UM.upd k v (from_op f));
  _ : forall f, dom_op f = UM.dom (from_op f);
  _ : forall f1 f2, dom_eq_op f1 f2 = UM.dom_eq (from_op f1) (from_op f2);
  _ : forall k f, free_op k f = to_op (UM.free k (from_op f));
  _ : forall k f, find_op k f = UM.find k (from_op f);
  _ : forall f1 f2, 
        union_op f1 f2 = to_op (UM.union (from_op f1) (from_op f2));
  _ : forall q f, um_filter_op q f = to_op (UM.um_filter q (from_op f));
  _ : forall f, empb_op f = UM.empb (from_op f);
  _ : forall f, undefb_op f = UM.undefb (from_op f);
  _ : forall k v, pts_op k v = to_op (UM.pts p k v)}.Structure mixin_of (T : Type) := Mixin {
  defined_op : T -> bool;
  empty_op : T;
  undef_op : T;
  upd_op : K -> V -> T -> T;
  dom_op : T -> seq K;
  dom_eq_op : T -> T -> bool;
  free_op : K -> T -> T;
  find_op : K -> T -> option V;
  union_op : T -> T -> T;
  um_filter_op : pred K -> T -> T;
  empb_op : T -> bool;
  undefb_op : T -> bool;
  pts_op : K -> V -> T;

  from_op : T -> UM.base V p;
  to_op : UM.base V p -> T;
  _ : forall b, from_op (to_op b) = b;
  _ : forall f, to_op (from_op f) = f;
  _ : forall f, defined_op f = UM.valid (from_op f);
  _ : undef_op = to_op (UM.Undef V p);
  _ : empty_op = to_op (UM.empty V p);
  _ : forall k v f, upd_op k v f = to_op (UM.upd k v (from_op f));
  _ : forall f, dom_op f = UM.dom (from_op f);
  _ : forall f1 f2, dom_eq_op f1 f2 = UM.dom_eq (from_op f1) (from_op f2);
  _ : forall k f, free_op k f = to_op (UM.free k (from_op f));
  _ : forall k f, find_op k f = UM.find k (from_op f);
  _ : forall f1 f2, 
        union_op f1 f2 = to_op (UM.union (from_op f1) (from_op f2));
  _ : forall q f, um_filter_op q f = to_op (UM.um_filter q (from_op f));
  _ : forall f, empb_op f = UM.empb (from_op f);
  _ : forall f, undefb_op f = UM.undefb (from_op f);
  _ : forall k v, pts_op k v = to_op (UM.pts p k v)}.Structure mixin_of (T : Type) := Mixin {
  defined_op : T -> bool;
  empty_op : T;
  undef_op : T;
  upd_op : K -> V -> T -> T;
  dom_op : T -> seq K;
  dom_eq_op : T -> T -> bool;
  free_op : K -> T -> T;
  find_op : K -> T -> option V;
  union_op : T -> T -> T;
  um_filter_op : pred K -> T -> T;
  empb_op : T -> bool;
  undefb_op : T -> bool;
  pts_op : K -> V -> T;

  from_op : T -> UM.base V p;
  to_op : UM.base V p -> T;
  _ : forall b, from_op (to_op b) = b;
  _ : forall f, to_op (from_op f) = f;
  _ : forall f, defined_op f = UM.valid (from_op f);
  _ : undef_op = to_op (UM.Undef V p);
  _ : empty_op = to_op (UM.empty V p);
  _ : forall k v f, upd_op k v f = to_op (UM.upd k v (from_op f));
  _ : forall f, dom_op f = UM.dom (from_op f);
  _ : forall f1 f2, dom_eq_op f1 f2 = UM.dom_eq (from_op f1) (from_op f2);
  _ : forall k f, free_op k f = to_op (UM.free k (from_op f));
  _ : forall k f, find_op k f = UM.find k (from_op f);
  _ : forall f1 f2, 
        union_op f1 f2 = to_op (UM.union (from_op f1) (from_op f2));
  _ : forall q f, um_filter_op q f = to_op (UM.um_filter q (from_op f));
  _ : forall f, empb_op f = UM.empb (from_op f);
  _ : forall f, undefb_op f = UM.undefb (from_op f);
  _ : forall k v, pts_op k v = to_op (UM.pts p k v)}.Structure mixin_of (T : Type) := Mixin {
  defined_op : T -> bool;
  empty_op : T;
  undef_op : T;
  upd_op : K -> V -> T -> T;
  dom_op : T -> seq K;
  dom_eq_op : T -> T -> bool;
  free_op : K -> T -> T;
  find_op : K -> T -> option V;
  union_op : T -> T -> T;
  um_filter_op : pred K -> T -> T;
  empb_op : T -> bool;
  undefb_op : T -> bool;
  pts_op : K -> V -> T;

  from_op : T -> UM.base V p;
  to_op : UM.base V p -> T;
  _ : forall b, from_op (to_op b) = b;
  _ : forall f, to_op (from_op f) = f;
  _ : forall f, defined_op f = UM.valid (from_op f);
  _ : undef_op = to_op (UM.Undef V p);
  _ : empty_op = to_op (UM.empty V p);
  _ : forall k v f, upd_op k v f = to_op (UM.upd k v (from_op f));
  _ : forall f, dom_op f = UM.dom (from_op f);
  _ : forall f1 f2, dom_eq_op f1 f2 = UM.dom_eq (from_op f1) (from_op f2);
  _ : forall k f, free_op k f = to_op (UM.free k (from_op f));
  _ : forall k f, find_op k f = UM.find k (from_op f);
  _ : forall f1 f2, 
        union_op f1 f2 = to_op (UM.union (from_op f1) (from_op f2));
  _ : forall q f, um_filter_op q f = to_op (UM.um_filter q (from_op f));
  _ : forall f, empb_op f = UM.empb (from_op f);
  _ : forall f, undefb_op f = UM.undefb (from_op f);
  _ : forall k v, pts_op k v = to_op (UM.pts p k v)}.Structure mixin_of (T : Type) := Mixin {
  defined_op : T -> bool;
  empty_op : T;
  undef_op : T;
  upd_op : K -> V -> T -> T;
  dom_op : T -> seq K;
  dom_eq_op : T -> T -> bool;
  free_op : K -> T -> T;
  find_op : K -> T -> option V;
  union_op : T -> T -> T;
  um_filter_op : pred K -> T -> T;
  empb_op : T -> bool;
  undefb_op : T -> bool;
  pts_op : K -> V -> T;

  from_op : T -> UM.base V p;
  to_op : UM.base V p -> T;
  _ : forall b, from_op (to_op b) = b;
  _ : forall f, to_op (from_op f) = f;
  _ : forall f, defined_op f = UM.valid (from_op f);
  _ : undef_op = to_op (UM.Undef V p);
  _ : empty_op = to_op (UM.empty V p);
  _ : forall k v f, upd_op k v f = to_op (UM.upd k v (from_op f));
  _ : forall f, dom_op f = UM.dom (from_op f);
  _ : forall f1 f2, dom_eq_op f1 f2 = UM.dom_eq (from_op f1) (from_op f2);
  _ : forall k f, free_op k f = to_op (UM.free k (from_op f));
  _ : forall k f, find_op k f = UM.find k (from_op f);
  _ : forall f1 f2, 
        union_op f1 f2 = to_op (UM.union (from_op f1) (from_op f2));
  _ : forall q f, um_filter_op q f = to_op (UM.um_filter q (from_op f));
  _ : forall f, empb_op f = UM.empb (from_op f);
  _ : forall f, undefb_op f = UM.undefb (from_op f);
  _ : forall k v, pts_op k v = to_op (UM.pts p k v)}.Structure mixin_of (T : Type) := Mixin {
  defined_op : T -> bool;
  empty_op : T;
  undef_op : T;
  upd_op : K -> V -> T -> T;
  dom_op : T -> seq K;
  dom_eq_op : T -> T -> bool;
  free_op : K -> T -> T;
  find_op : K -> T -> option V;
  union_op : T -> T -> T;
  um_filter_op : pred K -> T -> T;
  empb_op : T -> bool;
  undefb_op : T -> bool;
  pts_op : K -> V -> T;

  from_op : T -> UM.base V p;
  to_op : UM.base V p -> T;
  _ : forall b, from_op (to_op b) = b;
  _ : forall f, to_op (from_op f) = f;
  _ : forall f, defined_op f = UM.valid (from_op f);
  _ : undef_op = to_op (UM.Undef V p);
  _ : empty_op = to_op (UM.empty V p);
  _ : forall k v f, upd_op k v f = to_op (UM.upd k v (from_op f));
  _ : forall f, dom_op f = UM.dom (from_op f);
  _ : forall f1 f2, dom_eq_op f1 f2 = UM.dom_eq (from_op f1) (from_op f2);
  _ : forall k f, free_op k f = to_op (UM.free k (from_op f));
  _ : forall k f, find_op k f = UM.find k (from_op f);
  _ : forall f1 f2, 
        union_op f1 f2 = to_op (UM.union (from_op f1) (from_op f2));
  _ : forall q f, um_filter_op q f = to_op (UM.um_filter q (from_op f));
  _ : forall f, empb_op f = UM.empb (from_op f);
  _ : forall f, undefb_op f = UM.undefb (from_op f);
  _ : forall k v, pts_op k v = to_op (UM.pts p k v)}.Structure mixin_of (T : Type) := Mixin {
  defined_op : T -> bool;
  empty_op : T;
  undef_op : T;
  upd_op : K -> V -> T -> T;
  dom_op : T -> seq K;
  dom_eq_op : T -> T -> bool;
  free_op : K -> T -> T;
  find_op : K -> T -> option V;
  union_op : T -> T -> T;
  um_filter_op : pred K -> T -> T;
  empb_op : T -> bool;
  undefb_op : T -> bool;
  pts_op : K -> V -> T;

  from_op : T -> UM.base V p;
  to_op : UM.base V p -> T;
  _ : forall b, from_op (to_op b) = b;
  _ : forall f, to_op (from_op f) = f;
  _ : forall f, defined_op f = UM.valid (from_op f);
  _ : undef_op = to_op (UM.Undef V p);
  _ : empty_op = to_op (UM.empty V p);
  _ : forall k v f, upd_op k v f = to_op (UM.upd k v (from_op f));
  _ : forall f, dom_op f = UM.dom (from_op f);
  _ : forall f1 f2, dom_eq_op f1 f2 = UM.dom_eq (from_op f1) (from_op f2);
  _ : forall k f, free_op k f = to_op (UM.free k (from_op f));
  _ : forall k f, find_op k f = UM.find k (from_op f);
  _ : forall f1 f2, 
        union_op f1 f2 = to_op (UM.union (from_op f1) (from_op f2));
  _ : forall q f, um_filter_op q f = to_op (UM.um_filter q (from_op f));
  _ : forall f, empb_op f = UM.empb (from_op f);
  _ : forall f, undefb_op f = UM.undefb (from_op f);
  _ : forall k v, pts_op k v = to_op (UM.pts p k v)}.Structure mixin_of (T : Type) := Mixin {
  defined_op : T -> bool;
  empty_op : T;
  undef_op : T;
  upd_op : K -> V -> T -> T;
  dom_op : T -> seq K;
  dom_eq_op : T -> T -> bool;
  free_op : K -> T -> T;
  find_op : K -> T -> option V;
  union_op : T -> T -> T;
  um_filter_op : pred K -> T -> T;
  empb_op : T -> bool;
  undefb_op : T -> bool;
  pts_op : K -> V -> T;

  from_op : T -> UM.base V p;
  to_op : UM.base V p -> T;
  _ : forall b, from_op (to_op b) = b;
  _ : forall f, to_op (from_op f) = f;
  _ : forall f, defined_op f = UM.valid (from_op f);
  _ : undef_op = to_op (UM.Undef V p);
  _ : empty_op = to_op (UM.empty V p);
  _ : forall k v f, upd_op k v f = to_op (UM.upd k v (from_op f));
  _ : forall f, dom_op f = UM.dom (from_op f);
  _ : forall f1 f2, dom_eq_op f1 f2 = UM.dom_eq (from_op f1) (from_op f2);
  _ : forall k f, free_op k f = to_op (UM.free k (from_op f));
  _ : forall k f, find_op k f = UM.find k (from_op f);
  _ : forall f1 f2, 
        union_op f1 f2 = to_op (UM.union (from_op f1) (from_op f2));
  _ : forall q f, um_filter_op q f = to_op (UM.um_filter q (from_op f));
  _ : forall f, empb_op f = UM.empb (from_op f);
  _ : forall f, undefb_op f = UM.undefb (from_op f);
  _ : forall k v, pts_op k v = to_op (UM.pts p k v)}.Structure mixin_of (T : Type) := Mixin {
  defined_op : T -> bool;
  empty_op : T;
  undef_op : T;
  upd_op : K -> V -> T -> T;
  dom_op : T -> seq K;
  dom_eq_op : T -> T -> bool;
  free_op : K -> T -> T;
  find_op : K -> T -> option V;
  union_op : T -> T -> T;
  um_filter_op : pred K -> T -> T;
  empb_op : T -> bool;
  undefb_op : T -> bool;
  pts_op : K -> V -> T;

  from_op : T -> UM.base V p;
  to_op : UM.base V p -> T;
  _ : forall b, from_op (to_op b) = b;
  _ : forall f, to_op (from_op f) = f;
  _ : forall f, defined_op f = UM.valid (from_op f);
  _ : undef_op = to_op (UM.Undef V p);
  _ : empty_op = to_op (UM.empty V p);
  _ : forall k v f, upd_op k v f = to_op (UM.upd k v (from_op f));
  _ : forall f, dom_op f = UM.dom (from_op f);
  _ : forall f1 f2, dom_eq_op f1 f2 = UM.dom_eq (from_op f1) (from_op f2);
  _ : forall k f, free_op k f = to_op (UM.free k (from_op f));
  _ : forall k f, find_op k f = UM.find k (from_op f);
  _ : forall f1 f2, 
        union_op f1 f2 = to_op (UM.union (from_op f1) (from_op f2));
  _ : forall q f, um_filter_op q f = to_op (UM.um_filter q (from_op f));
  _ : forall f, empb_op f = UM.empb (from_op f);
  _ : forall f, undefb_op f = UM.undefb (from_op f);
  _ : forall k v, pts_op k v = to_op (UM.pts p k v)}.Structure mixin_of (T : Type) := Mixin {
  defined_op : T -> bool;
  empty_op : T;
  undef_op : T;
  upd_op : K -> V -> T -> T;
  dom_op : T -> seq K;
  dom_eq_op : T -> T -> bool;
  free_op : K -> T -> T;
  find_op : K -> T -> option V;
  union_op : T -> T -> T;
  um_filter_op : pred K -> T -> T;
  empb_op : T -> bool;
  undefb_op : T -> bool;
  pts_op : K -> V -> T;

  from_op : T -> UM.base V p;
  to_op : UM.base V p -> T;
  _ : forall b, from_op (to_op b) = b;
  _ : forall f, to_op (from_op f) = f;
  _ : forall f, defined_op f = UM.valid (from_op f);
  _ : undef_op = to_op (UM.Undef V p);
  _ : empty_op = to_op (UM.empty V p);
  _ : forall k v f, upd_op k v f = to_op (UM.upd k v (from_op f));
  _ : forall f, dom_op f = UM.dom (from_op f);
  _ : forall f1 f2, dom_eq_op f1 f2 = UM.dom_eq (from_op f1) (from_op f2);
  _ : forall k f, free_op k f = to_op (UM.free k (from_op f));
  _ : forall k f, find_op k f = UM.find k (from_op f);
  _ : forall f1 f2, 
        union_op f1 f2 = to_op (UM.union (from_op f1) (from_op f2));
  _ : forall q f, um_filter_op q f = to_op (UM.um_filter q (from_op f));
  _ : forall f, empb_op f = UM.empb (from_op f);
  _ : forall f, undefb_op f = UM.undefb (from_op f);
  _ : forall k v, pts_op k v = to_op (UM.pts p k v)}.Structure mixin_of (T : Type) := Mixin {
  defined_op : T -> bool;
  empty_op : T;
  undef_op : T;
  upd_op : K -> V -> T -> T;
  dom_op : T -> seq K;
  dom_eq_op : T -> T -> bool;
  free_op : K -> T -> T;
  find_op : K -> T -> option V;
  union_op : T -> T -> T;
  um_filter_op : pred K -> T -> T;
  empb_op : T -> bool;
  undefb_op : T -> bool;
  pts_op : K -> V -> T;

  from_op : T -> UM.base V p;
  to_op : UM.base V p -> T;
  _ : forall b, from_op (to_op b) = b;
  _ : forall f, to_op (from_op f) = f;
  _ : forall f, defined_op f = UM.valid (from_op f);
  _ : undef_op = to_op (UM.Undef V p);
  _ : empty_op = to_op (UM.empty V p);
  _ : forall k v f, upd_op k v f = to_op (UM.upd k v (from_op f));
  _ : forall f, dom_op f = UM.dom (from_op f);
  _ : forall f1 f2, dom_eq_op f1 f2 = UM.dom_eq (from_op f1) (from_op f2);
  _ : forall k f, free_op k f = to_op (UM.free k (from_op f));
  _ : forall k f, find_op k f = UM.find k (from_op f);
  _ : forall f1 f2, 
        union_op f1 f2 = to_op (UM.union (from_op f1) (from_op f2));
  _ : forall q f, um_filter_op q f = to_op (UM.um_filter q (from_op f));
  _ : forall f, empb_op f = UM.empb (from_op f);
  _ : forall f, undefb_op f = UM.undefb (from_op f);
  _ : forall k v, pts_op k v = to_op (UM.pts p k v)}.Structure mixin_of (T : Type) := Mixin {
  defined_op : T -> bool;
  empty_op : T;
  undef_op : T;
  upd_op : K -> V -> T -> T;
  dom_op : T -> seq K;
  dom_eq_op : T -> T -> bool;
  free_op : K -> T -> T;
  find_op : K -> T -> option V;
  union_op : T -> T -> T;
  um_filter_op : pred K -> T -> T;
  empb_op : T -> bool;
  undefb_op : T -> bool;
  pts_op : K -> V -> T;

  from_op : T -> UM.base V p;
  to_op : UM.base V p -> T;
  _ : forall b, from_op (to_op b) = b;
  _ : forall f, to_op (from_op f) = f;
  _ : forall f, defined_op f = UM.valid (from_op f);
  _ : undef_op = to_op (UM.Undef V p);
  _ : empty_op = to_op (UM.empty V p);
  _ : forall k v f, upd_op k v f = to_op (UM.upd k v (from_op f));
  _ : forall f, dom_op f = UM.dom (from_op f);
  _ : forall f1 f2, dom_eq_op f1 f2 = UM.dom_eq (from_op f1) (from_op f2);
  _ : forall k f, free_op k f = to_op (UM.free k (from_op f));
  _ : forall k f, find_op k f = UM.find k (from_op f);
  _ : forall f1 f2, 
        union_op f1 f2 = to_op (UM.union (from_op f1) (from_op f2));
  _ : forall q f, um_filter_op q f = to_op (UM.um_filter q (from_op f));
  _ : forall f, empb_op f = UM.empb (from_op f);
  _ : forall f, undefb_op f = UM.undefb (from_op f);
  _ : forall k v, pts_op k v = to_op (UM.pts p k v)}.Structure mixin_of (T : Type) := Mixin {
  defined_op : T -> bool;
  empty_op : T;
  undef_op : T;
  upd_op : K -> V -> T -> T;
  dom_op : T -> seq K;
  dom_eq_op : T -> T -> bool;
  free_op : K -> T -> T;
  find_op : K -> T -> option V;
  union_op : T -> T -> T;
  um_filter_op : pred K -> T -> T;
  empb_op : T -> bool;
  undefb_op : T -> bool;
  pts_op : K -> V -> T;

  from_op : T -> UM.base V p;
  to_op : UM.base V p -> T;
  _ : forall b, from_op (to_op b) = b;
  _ : forall f, to_op (from_op f) = f;
  _ : forall f, defined_op f = UM.valid (from_op f);
  _ : undef_op = to_op (UM.Undef V p);
  _ : empty_op = to_op (UM.empty V p);
  _ : forall k v f, upd_op k v f = to_op (UM.upd k v (from_op f));
  _ : forall f, dom_op f = UM.dom (from_op f);
  _ : forall f1 f2, dom_eq_op f1 f2 = UM.dom_eq (from_op f1) (from_op f2);
  _ : forall k f, free_op k f = to_op (UM.free k (from_op f));
  _ : forall k f, find_op k f = UM.find k (from_op f);
  _ : forall f1 f2, 
        union_op f1 f2 = to_op (UM.union (from_op f1) (from_op f2));
  _ : forall q f, um_filter_op q f = to_op (UM.um_filter q (from_op f));
  _ : forall f, empb_op f = UM.empb (from_op f);
  _ : forall f, undefb_op f = UM.undefb (from_op f);
  _ : forall k v, pts_op k v = to_op (UM.pts p k v)}.Structure mixin_of (T : Type) := Mixin {
  defined_op : T -> bool;
  empty_op : T;
  undef_op : T;
  upd_op : K -> V -> T -> T;
  dom_op : T -> seq K;
  dom_eq_op : T -> T -> bool;
  free_op : K -> T -> T;
  find_op : K -> T -> option V;
  union_op : T -> T -> T;
  um_filter_op : pred K -> T -> T;
  empb_op : T -> bool;
  undefb_op : T -> bool;
  pts_op : K -> V -> T;

  from_op : T -> UM.base V p;
  to_op : UM.base V p -> T;
  _ : forall b, from_op (to_op b) = b;
  _ : forall f, to_op (from_op f) = f;
  _ : forall f, defined_op f = UM.valid (from_op f);
  _ : undef_op = to_op (UM.Undef V p);
  _ : empty_op = to_op (UM.empty V p);
  _ : forall k v f, upd_op k v f = to_op (UM.upd k v (from_op f));
  _ : forall f, dom_op f = UM.dom (from_op f);
  _ : forall f1 f2, dom_eq_op f1 f2 = UM.dom_eq (from_op f1) (from_op f2);
  _ : forall k f, free_op k f = to_op (UM.free k (from_op f));
  _ : forall k f, find_op k f = UM.find k (from_op f);
  _ : forall f1 f2, 
        union_op f1 f2 = to_op (UM.union (from_op f1) (from_op f2));
  _ : forall q f, um_filter_op q f = to_op (UM.um_filter q (from_op f));
  _ : forall f, empb_op f = UM.empb (from_op f);
  _ : forall f, undefb_op f = UM.undefb (from_op f);
  _ : forall k v, pts_op k v = to_op (UM.pts p k v)}.Structure mixin_of (T : Type) := Mixin {
  defined_op : T -> bool;
  empty_op : T;
  undef_op : T;
  upd_op : K -> V -> T -> T;
  dom_op : T -> seq K;
  dom_eq_op : T -> T -> bool;
  free_op : K -> T -> T;
  find_op : K -> T -> option V;
  union_op : T -> T -> T;
  um_filter_op : pred K -> T -> T;
  empb_op : T -> bool;
  undefb_op : T -> bool;
  pts_op : K -> V -> T;

  from_op : T -> UM.base V p;
  to_op : UM.base V p -> T;
  _ : forall b, from_op (to_op b) = b;
  _ : forall f, to_op (from_op f) = f;
  _ : forall f, defined_op f = UM.valid (from_op f);
  _ : undef_op = to_op (UM.Undef V p);
  _ : empty_op = to_op (UM.empty V p);
  _ : forall k v f, upd_op k v f = to_op (UM.upd k v (from_op f));
  _ : forall f, dom_op f = UM.dom (from_op f);
  _ : forall f1 f2, dom_eq_op f1 f2 = UM.dom_eq (from_op f1) (from_op f2);
  _ : forall k f, free_op k f = to_op (UM.free k (from_op f));
  _ : forall k f, find_op k f = UM.find k (from_op f);
  _ : forall f1 f2, 
        union_op f1 f2 = to_op (UM.union (from_op f1) (from_op f2));
  _ : forall q f, um_filter_op q f = to_op (UM.um_filter q (from_op f));
  _ : forall f, empb_op f = UM.empb (from_op f);
  _ : forall f, undefb_op f = UM.undefb (from_op f);
  _ : forall k v, pts_op k v = to_op (UM.pts p k v)}.Structure mixin_of (T : Type) := Mixin {
  defined_op : T -> bool;
  empty_op : T;
  undef_op : T;
  upd_op : K -> V -> T -> T;
  dom_op : T -> seq K;
  dom_eq_op : T -> T -> bool;
  free_op : K -> T -> T;
  find_op : K -> T -> option V;
  union_op : T -> T -> T;
  um_filter_op : pred K -> T -> T;
  empb_op : T -> bool;
  undefb_op : T -> bool;
  pts_op : K -> V -> T;

  from_op : T -> UM.base V p;
  to_op : UM.base V p -> T;
  _ : forall b, from_op (to_op b) = b;
  _ : forall f, to_op (from_op f) = f;
  _ : forall f, defined_op f = UM.valid (from_op f);
  _ : undef_op = to_op (UM.Undef V p);
  _ : empty_op = to_op (UM.empty V p);
  _ : forall k v f, upd_op k v f = to_op (UM.upd k v (from_op f));
  _ : forall f, dom_op f = UM.dom (from_op f);
  _ : forall f1 f2, dom_eq_op f1 f2 = UM.dom_eq (from_op f1) (from_op f2);
  _ : forall k f, free_op k f = to_op (UM.free k (from_op f));
  _ : forall k f, find_op k f = UM.find k (from_op f);
  _ : forall f1 f2, 
        union_op f1 f2 = to_op (UM.union (from_op f1) (from_op f2));
  _ : forall q f, um_filter_op q f = to_op (UM.um_filter q (from_op f));
  _ : forall f, empb_op f = UM.empb (from_op f);
  _ : forall f, undefb_op f = UM.undefb (from_op f);
  _ : forall k v, pts_op k v = to_op (UM.pts p k v)}.(* I used to package K and V into the class. I did that to get cond
function over keys to work without supplying the type parameter. I.e.,
with K and V out, I have to write cond U k, where U : union_map_class
K V. But the complication wasn't worth it. One has to frequently
reorder arguments to various operations in a "less-ad-hoc" style, to
get the types to be inferred properly. While fun, it's just an
unnecessary hassle, since cond is not used that much. The condition p
can be kept in the structure, however, since no types depend on it. *)

Structure class_of (T : Type) := Class {
  p : pred K;
  mixin : mixin_of V p T}.(* I used to package K and V into the class. I did that to get cond
function over keys to work without supplying the type parameter. I.e.,
with K and V out, I have to write cond U k, where U : union_map_class
K V. But the complication wasn't worth it. One has to frequently
reorder arguments to various operations in a "less-ad-hoc" style, to
get the types to be inferred properly. While fun, it's just an
unnecessary hassle, since cond is not used that much. The condition p
can be kept in the structure, however, since no types depend on it. *)

Structure class_of (T : Type) := Class {
  p : pred K;
  mixin : mixin_of V p T}.(* I used to package K and V into the class. I did that to get cond
function over keys to work without supplying the type parameter. I.e.,
with K and V out, I have to write cond U k, where U : union_map_class
K V. But the complication wasn't worth it. One has to frequently
reorder arguments to various operations in a "less-ad-hoc" style, to
get the types to be inferred properly. While fun, it's just an
unnecessary hassle, since cond is not used that much. The condition p
can be kept in the structure, however, since no types depend on it. *)

Structure class_of (T : Type) := Class {
  p : pred K;
  mixin : mixin_of V p T}.(* I used to package K and V into the class. I did that to get cond
function over keys to work without supplying the type parameter. I.e.,
with K and V out, I have to write cond U k, where U : union_map_class
K V. But the complication wasn't worth it. One has to frequently
reorder arguments to various operations in a "less-ad-hoc" style, to
get the types to be inferred properly. While fun, it's just an
unnecessary hassle, since cond is not used that much. The condition p
can be kept in the structure, however, since no types depend on it. *)

Structure class_of (T : Type) := Class {
  p : pred K;
  mixin : mixin_of V p T}.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 clone c of phant_id class c := @Pack T c.Definition pack p (m : @mixin_of K V p T) := 
  @Pack T (@Class T p m).(* Definition cond : pred K := @p _ class. *)
Definition cond := [pred x : K | @p _ class x].Definition from := from_op (mixin class).Definition to := to_op (mixin class).Definition defined := defined_op (mixin class).Definition um_undef := undef_op (mixin class).Definition empty := empty_op (mixin class).Definition upd : K -> V -> cT -> cT := upd_op (mixin class).Definition dom : cT -> seq K := dom_op (mixin class).Definition dom_eq := dom_eq_op (mixin class).Definition free : K -> cT -> cT := free_op (mixin class).Definition find : K -> cT -> option V := find_op (mixin class).Definition union := union_op (mixin class).Definition um_filter : pred K -> cT -> cT := um_filter_op (mixin class).Definition empb := empb_op (mixin class).Definition undefb := undefb_op (mixin class).Definition pts : K -> V -> cT := pts_op (mixin class).Implicit Type f : U.

Lemma unionE f1 f2 : union f1 f2 = to (UM.union (from f1) (from f2)).