Section assoc.
Fixpoint assoc {A B : Type}(eq : A -> A -> bool)(x : A)(l : list (A * B)) : option B :=
match l with
| nil => None
| (x', y) :: l' => if eq x x' then Some y else assoc eq x l'
end.
Definition assoc_default {A B : Type}
(eqA : A -> A -> bool) (d : B) (l : list (A * B)) (x : A) : B :=
match assoc eqA x l with
| None => d
| Some b => b
end.

(* Specifications: *)
Lemma assoc_in {A B:Type} beq k (l: list (A * B)) {v}:
(∀ a b:A, beq a b = true ↔ a=b) →
assoc beq k l = Some v → (k,v) ∈ l.
Lemma assoc_None_not_in {A B:Type} beq k (l:list (A*B)):
(∀ a b : A, beq a b = true ↔ a = b) →
assoc beq k l = None ↔ ¬ k ∈ map fst l.
Lemma in_assoc_neq_None (A B: Type) (beq: A -> A -> bool) (k: A) (l: list (A * B)):
(forall a b:A, a = b -> beq a b = true) ->
In k (map (@fst _ _) l) ->
assoc beq k l <> None.
Lemma assoc_in_Some {A B:Type} (beq:A→A→bool) (k:A) (l: list (A*B)):
(∀ a b, beq a b = true ↔ a=b) →
k ∈ map fst l ↔ ∃ v, v ∈ map snd l ∧ assoc beq k l = Some v.
Lemma assoc_in_Some_simple {A B:Type} beq k (l: list (A*B)):
(∀ a b:A, beq a b = true ↔ a = b) →
k ∈ map fst l ↔ (∃ v, assoc beq k l = Some v).
Lemma assoc_app_eq_None (A B:Type) (eq: A -> A -> bool) (x: A) (l1 l2: list (A * B)) :
assoc eq x (l1 ++ l2) = None <-> (assoc eq x l1 = None /\ assoc eq x l2 = None).
Lemma assoc_app_neq_None (A B:Type) (eq: A -> A -> bool) (x: A) (l1 l2: list (A * B)) :
assoc eq x (l1 ++ l2) <> None <-> (assoc eq x l1 <> None \/ assoc eq x l2 <> None).
Lemma assoc_app_eq_Some (A B:Type) (eq: A -> A -> bool) (x: A) (v : B) (l1 l2: list (A * B)) :
assoc eq x (l1 ++ l2) = Some v <->
(assoc eq x l1 = Some v \/ (assoc eq x l1 = None /\ assoc eq x l2 = Some v)).
Lemma assoc_app_in {K V:Type} beq k (l1 l2: list (K*V)):
(∀ a b : K, beq a b = true ↔ a = b) →
k ∈ map fst l1 → assoc beq k (l1++l2) = assoc beq k l1.
Lemma assoc_app_out {K V:Type} beq k (l1 l2: list (K*V)):
(∀ a b : K, beq a b = true ↔ a = b) →
¬ k ∈ map fst l1 → assoc beq k (l1++l2) = assoc beq k l2.
Lemma assoc_in_concat {K V:Type} beq (k:K) ll (v:V):
assoc beq k (concat ll) = Some v →
∃ l : list (K * V), l ∈ ll ∧ assoc beq k l = Some v.