Instance find_elt_compat A dom (m : t A dom) : Proper (X.eq ==> Logic.eq) (fun x => find x m).

(* Specifications: *)
Lemma find_spec : forall A x dom (m : t A dom), (exists v, find x m = Some v) <-> Dom.In x dom.
Lemma domain_spec : forall A dom (m : t A dom), domain m = dom.
Lemma set_same : forall A x v dom (m : t A dom) Hin, find x (@set A dom x v m Hin) = Some v.
Lemma set_other : forall A x y v dom (m : t A dom) Hin, ¬X.eq y x -> find y (@set A dom x v m Hin) = find y m.
Lemma add_same : forall A x v dom (m : t A dom), find x (add x v m) = Some v.
Lemma add_other : forall A x y v dom (m : t A dom), ¬X.eq y x -> find y (add x v m) = find y m.
Lemma singleton_same : forall A x (v : A), find x (singleton x v) = Some v.
Lemma singleton_other : forall A x y (v : A), ¬X.eq y x -> find y (singleton x v) = None.
Lemma remove_same : forall A x dom (m : t A dom), find x (remove x m) = None.
Lemma remove_other : forall A x y dom (m : t A dom), ¬X.eq y x -> find y (remove x m) = find y m.
Lemma constant_aux : forall A v x u l (m : S.t A), NoDupA X.eq l -> S.find x (fold_left (fun a e => S.add e v a) l m) = Some u <-> InA X.eq x l ∧ u = v ∨ ¬InA X.eq x l ∧ S.find x m = Some u.
Lemma constant_Some : forall A dom (v : A) x u, find x (constant dom v) = Some u <-> Dom.In x dom ∧ u = v.
Lemma constant_None : forall A dom (v : A) x, find x (constant dom v) = None <-> ¬Dom.In x dom.
Lemma map_spec : forall A B (f : A -> B) dom (m : t A dom) x v, find x (map f m) = Some v <-> exists u, find x m = Some u ∧ f u = v.
Lemma combine_spec : forall A B C (f : A -> B -> C) g₁ g₂ dom₁ dom₂ (m₁ : t A dom₁) (m₂ : t B dom₂) x v, find x (combine f g₁ g₂ m₁ m₂) = Some v <-> (exists v₁ v₂, find x m₁ = Some v₁ ∧ find x m₂ = Some v₂ ∧ v = f v₁ v₂) ∨ (exists v₁, find x m₁ = Some v₁ ∧ find x m₂ = None ∧ v = g₁ v₁) ∨ (exists v₂, find x m₁ = None ∧ find x m₂ = Some v₂ ∧ v = g₂ v₂).
Lemma cast_spec_find : forall A dom₁ dom₂ (Heq : Dom.eq dom₁ dom₂) (m : t A dom₁) x, find x (cast Heq m) = find x m.
Lemma elements_spec : forall A dom (m : t A dom) xv, InA (X.eq * eq)%signature xv (elements m) <-> find (fst xv) m = Some (snd xv).
Lemma elements_Sorted : forall A dom (m : t A dom), Sorted (X.lt@@1)%signature (elements m).
Lemma pre_from_elements_spec : forall A l (m : S.t A), NoDupA (X.eq@@1)%signature l -> (forall xv, InA (X.eq@@1)%signature xv l -> S.In (fst xv) m -> False) -> forall x v, S.find x (fold_left (fun acc xv => S.add (fst xv) (snd xv) acc) l m) = Some v <-> InA (X.eq * eq)%signature (x, v) l ∨ ¬InA (X.eq@@1)%signature (x, v) l ∧ S.find x m = Some v.
Lemma from_elements_spec : forall A (l : list (key * A)), NoDupA (X.eq@@1)%signature l -> forall x v, find x (from_elements l) = Some v <-> InA (X.eq * eq)%signature (x, v) l.
Lemma fold_spec : forall A B (f : key -> A -> B -> B) dom (m : t A dom) (i : B), fold f m i = List.fold_left (fun acc xv => f (fst xv) (snd xv) acc) (elements m) i.