Definition from_elements A (l : list (key * A))
: t A (List.fold_left (fun acc xv => Dom.add (fst xv) acc) l Dom.empty) :=
exist (OK (List.fold_left (fun acc xv => Dom.add (fst xv) acc) l Dom.empty))
(List.fold_left (fun acc xv => S.add (fst xv) (snd xv) acc) l (@S.empty A))
(from_elements_OK l).
(** ***  Specifications  **)

(* Specifications: *)
Lemma empty_spec : forall A x, find x (@empty A) = None.
Lemma mem_spec : forall A x dom (m : t A dom), mem x m = true <-> exists v, find x m = Some v.
Instance find_elt_compat A dom (m : t A dom) : Proper (X.eq ==> Logic.eq) (fun x => find x m).
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 add_same : forall A x v dom (m : t A dom), find x (add x v m) = Some v.
Lemma singleton_same : forall A x (v : A), find x (singleton x v) = Some v.
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_Sorted : forall A dom (m : t A dom), Sorted (X.lt@@1)%signature (elements m).
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.