|
| 1 | +From Coq Require Import |
| 2 | + FMapInterface |
| 3 | + FMapAVL |
| 4 | + OrderedType |
| 5 | + OrderedTypeEx |
| 6 | + ZArith. |
| 7 | + |
| 8 | +Require Import Classes. |
| 9 | + |
| 10 | +Module Type Make (E : OrderedType). |
| 11 | + Include FMapAVL.Make E. |
| 12 | + |
| 13 | + Parameter dec_eq_is_eq : forall a b, E.eq a b <-> a = b. |
| 14 | + |
| 15 | + Lemma fmap_new_empty {ValT : Type} k : find k (@empty ValT) = None. |
| 16 | + Proof. |
| 17 | + remember (find k (empty ValT)) as maybe_v. |
| 18 | + destruct maybe_v as [v|]. |
| 19 | + - exfalso. |
| 20 | + specialize (@empty_1 ValT k v) as H. |
| 21 | + symmetry in Heqmaybe_v. now apply find_2 in Heqmaybe_v. |
| 22 | + - reflexivity. |
| 23 | + Qed. |
| 24 | + |
| 25 | + Lemma fmap_keep {ValT : Type} s k (v : ValT) : find k (add k v s) = Some v. |
| 26 | + Proof. |
| 27 | + specialize (@add_1 ValT s k k v (E.eq_refl k)) as H. |
| 28 | + now apply find_1. |
| 29 | + Qed. |
| 30 | + |
| 31 | + Lemma fmap_distinct {ValT : Type} s k1 k2 (v2 : ValT) : |
| 32 | + k1 <> k2 -> |
| 33 | + find k1 s = find k1 (add k2 v2 s). |
| 34 | + Proof. |
| 35 | + intros Hk. |
| 36 | + assert (Hk' : ~E.eq k2 k1). { |
| 37 | + intros Habsurd. |
| 38 | + apply not_eq_sym in Hk. |
| 39 | + now apply dec_eq_is_eq in Habsurd. |
| 40 | + } |
| 41 | + apply Raw.Proofs.find_find. |
| 42 | + intros v. split. |
| 43 | + - intros H. |
| 44 | + apply find_1. |
| 45 | + apply find_2 in H. |
| 46 | + now apply add_2. |
| 47 | + - intros H. |
| 48 | + apply find_1. |
| 49 | + apply find_2 in H. |
| 50 | + eapply add_3; eauto. |
| 51 | + Qed. |
| 52 | + |
| 53 | + Lemma fmap_delete_keep {ValT : Type} s k: |
| 54 | + @find ValT k (remove k s) = None. |
| 55 | + Proof. |
| 56 | + specialize (@remove_1 ValT s k k (E.eq_refl k)) as H. |
| 57 | + remember (remove (elt:=ValT) k s) as s'. |
| 58 | + unfold find, remove, In in H. |
| 59 | + destruct s' as [s' bst']. |
| 60 | + apply Raw.Proofs.not_find_iff. |
| 61 | + - assumption. |
| 62 | + - now rewrite Raw.Proofs.In_alt in H. |
| 63 | + Qed. |
| 64 | + |
| 65 | + Lemma fmap_delete_distinct {ValT : Type} (s : t ValT) k1 k2 : |
| 66 | + k1 <> k2 -> |
| 67 | + find k1 s = find k1 (remove k2 s). |
| 68 | + Proof. |
| 69 | + intros Hk. |
| 70 | + assert (Hk' : ~E.eq k2 k1). { |
| 71 | + intros Habsurd. |
| 72 | + apply not_eq_sym in Hk. |
| 73 | + now apply dec_eq_is_eq in Habsurd. |
| 74 | + } |
| 75 | + apply Raw.Proofs.find_find. |
| 76 | + intros v1. split. |
| 77 | + - intros H. |
| 78 | + apply find_1. |
| 79 | + apply find_2 in H. |
| 80 | + now apply remove_2. |
| 81 | + - intros H. |
| 82 | + apply find_1. |
| 83 | + apply find_2 in H. |
| 84 | + eapply remove_3; eauto. |
| 85 | + Qed. |
| 86 | + |
| 87 | + Global Instance fmapStorage {Val : Type} : @Storage E.t Val (t Val) := |
| 88 | + {| |
| 89 | + new := @empty Val; |
| 90 | + get := @find Val; |
| 91 | + put := @add Val; |
| 92 | + delete := @remove Val; |
| 93 | + new_empty := @fmap_new_empty Val; |
| 94 | + keep := @fmap_keep Val; |
| 95 | + distinct := @fmap_distinct Val; |
| 96 | + delete_keep := @fmap_delete_keep Val; |
| 97 | + delete_distinct := @fmap_delete_distinct Val; |
| 98 | + |}. |
| 99 | +End Make. |
0 commit comments