Ltac assoc_destruct :=
    match goal with
    | [ |- context [assoc (assoc_set _ ?k0' _) ?k0 ] ] =>
      destruct (K_eq_dec k0 k0'); [subst k0'; rewrite get_set_same with (k := k0)|
                                   rewrite get_set_diff with (k' := k0) by auto]
    end.Ltac assoc_rewrite :=
    match goal with
    | [  |- context [assoc (assoc_set _ ?k0' _) ?k0 ] ] =>
      first [rewrite get_set_same with (k := k0) by auto |
             rewrite get_set_diff with (k' := k0) by auto ]
    end.

(* Specifications: *)
Lemma assoc_set_assoc_set_diff : forall l (k : K) (v : V) k' v', k <> k' -> a_equiv (assoc_set (assoc_set l k v) k' v') (assoc_set (assoc_set l k' v') k v).
Lemma a_equiv_nil : forall l, a_equiv l [] -> l = [].
Lemma assoc_set_a_equiv : forall l l' (k : K) (v : V), a_equiv l l' -> a_equiv (assoc_set l k v) (assoc_set l' k v).
Lemma assoc_default_a_equiv : forall l l' (k : K) (v : V), a_equiv l l' -> assoc_default l k v = assoc_default l' k v.
Lemma assoc_a_equiv : forall l l' (k : K), a_equiv l l' -> assoc l k = assoc l' k.
Lemma assoc_default_assoc_set_diff : forall (l : list (K * V)) k v k' d, k <> k' -> assoc_default (assoc_set l k' v) k d = assoc_default l k d.