Lvc.Constr.MapAgreeSet

Require Export Setoid Coq.Classes.Morphisms.
Require Import EqDec Computable Util AutoIndTac.
Require Export CSet Containers.SetDecide.
Require Export MapBasics MapLookup MapAgreement.

Set Implicit Arguments.

Section MapAgreeSet.
  Variable X : Type.
  Context `{OrderedType X}.
  Variable Y : Type.
  Context `{OrderedType Y}.

  Definition agree_set (lv:set X) (m :XY) : set X
    := filter (fun xif [m x === x] then true else false) lv.

  Lemma agree_set_spec (lv:set X) (m : XY) x
        `{Proper _ (respectful _eq _eq) m} `{Proper _ (respectful _eq _eq) }
  : x agree_set lv m x lv m x === x.

  Lemma agree_on_agree_set_eq
        (lv:set X) (D :XY)
        `{Proper _ (respectful _eq _eq) D} `{Proper _ (respectful _eq _eq) }
  : agree_on _eq lv D agree_set lv D [=] lv.

  Lemma agree_set_agree_on Z `{OrderedType Z}
        (lv:set X) (D :XY) (E : XZ)
        `{Proper _ (respectful _eq _eq) D} `{Proper _ (respectful _eq _eq) }
  : agree_on _eq lv D agree_on _eq (agree_set lv D ) E
    → agree_on _eq lv E .

  Lemma agree_on_agree_set (lv:set X) (D D´´: XY)
        `{Proper _ (respectful _eq _eq) D}
        `{Proper _ (respectful _eq _eq) }
        `{Proper _ (respectful _eq _eq) D´´}
  : agree_on _eq lv D agree_set lv D D´´ agree_set lv D´´.

  Lemma agree_set_incl (lv:set X) (D : XY)
        `{Proper _ (respectful _eq _eq) D}
        `{Proper _ (respectful _eq _eq) }
  : (agree_set lv D ) lv.

  Lemma agree_set_incl_both (lv´ lv:set X) (D :XY)
        `{Proper _ (respectful _eq _eq) D}
        `{Proper _ (respectful _eq _eq) }
  : lv´ lvagree_set lv´ D agree_set lv D .

End MapAgreeSet.


Global Instance eq_cset_agree_set_morphism X `{OrderedType X} Y `{OrderedType Y}
  : Proper (SetInterface.Equal ==> (@fpeq X Y _eq H H0) ==> (@fpeq X Y _eq _ _) ==> SetInterface.Equal) (@agree_set X _ Y _ ).

Add Parametric Morphism {X} `{OrderedType X} {Y} `{OrderedType Y} : (@lookup_set X _ Y _)
  with signature (@fpeq X Y _eq _ _) ==> SetInterface.Equal ==> SetInterface.Equal
    as eq_cset_lookup_set_morphism.

Add Parametric Morphism {X} `{OrderedType X} {Y} `{OrderedType Y}
  : (@lookup_set X _ Y _)
  with signature (@fpeq X Y _eq _ _) ==> Subset ==> Subset
    as incl_lookup_set_morphism.

Lemma agree_set_minus X `{OrderedType X} Y `{OrderedType Y} lv lv´ (D : XY)
      `{Proper _ (_eq ==> _eq) D} `{Proper _ (_eq ==> _eq) }
: agree_set lv D \ lv´ [=] agree_set (lv \ lv´) D .