frap/Map.v

261 lines
7.5 KiB
Coq
Raw Normal View History

2015-12-31 20:44:34 +00:00
Require Import Classical Sets ClassicalEpsilon FunctionalExtensionality.
Set Implicit Arguments.
Module Type S.
2016-02-09 14:07:37 +00:00
Parameter fmap : Type -> Type -> Type.
2015-12-31 20:44:34 +00:00
2016-02-09 14:07:37 +00:00
Parameter empty : forall A B, fmap A B.
Parameter add : forall A B, fmap A B -> A -> B -> fmap A B.
2016-02-10 03:44:03 +00:00
Parameter remove : forall A B, fmap A B -> A -> fmap A B.
2016-02-09 14:07:37 +00:00
Parameter join : forall A B, fmap A B -> fmap A B -> fmap A B.
Parameter merge : forall A B, (option B -> option B -> option B) -> fmap A B -> fmap A B -> fmap A B.
2016-02-09 14:07:37 +00:00
Parameter lookup : forall A B, fmap A B -> A -> option B.
Parameter includes : forall A B, fmap A B -> fmap A B -> Prop.
2015-12-31 20:44:34 +00:00
Notation "$0" := (empty _ _).
Notation "m $+ ( k , v )" := (add m k v) (at level 50, left associativity).
2016-02-10 03:44:03 +00:00
Infix "$-" := remove (at level 50, left associativity).
2015-12-31 20:44:34 +00:00
Infix "$++" := join (at level 50, left associativity).
Infix "$?" := lookup (at level 50, no associativity).
Infix "$<=" := includes (at level 90).
2016-02-09 14:07:37 +00:00
Parameter dom : forall A B, fmap A B -> set A.
2015-12-31 20:44:34 +00:00
2016-02-09 14:07:37 +00:00
Axiom fmap_ext : forall A B (m1 m2 : fmap A B),
2015-12-31 20:44:34 +00:00
(forall k, m1 $? k = m2 $? k)
-> m1 = m2.
Axiom lookup_empty : forall A B k, empty A B $? k = None.
2016-02-09 14:07:37 +00:00
Axiom includes_lookup : forall A B (m m' : fmap A B) k v,
2015-12-31 20:44:34 +00:00
m $? k = Some v
-> m $<= m'
-> lookup m' k = Some v.
2016-02-09 14:07:37 +00:00
Axiom includes_add : forall A B (m m' : fmap A B) k v,
2015-12-31 20:44:34 +00:00
m $<= m'
-> add m k v $<= add m' k v.
2016-02-09 14:07:37 +00:00
Axiom lookup_add_eq : forall A B (m : fmap A B) k1 k2 v,
2016-02-07 03:09:37 +00:00
k1 = k2
-> add m k1 v $? k2 = Some v.
2015-12-31 20:44:34 +00:00
2016-02-09 14:07:37 +00:00
Axiom lookup_add_ne : forall A B (m : fmap A B) k k' v,
2015-12-31 20:44:34 +00:00
k' <> k
-> add m k v $? k' = m $? k'.
2016-02-10 03:44:03 +00:00
Axiom lookup_remove_eq : forall A B (m : fmap A B) k1 k2,
k1 = k2
-> remove m k1 $? k2 = None.
Axiom lookup_remove_ne : forall A B (m : fmap A B) k k',
k' <> k
-> remove m k $? k' = m $? k'.
2016-02-09 14:07:37 +00:00
Axiom lookup_join1 : forall A B (m1 m2 : fmap A B) k,
2015-12-31 20:44:34 +00:00
k \in dom m1
-> (m1 $++ m2) $? k = m1 $? k.
2016-02-09 14:07:37 +00:00
Axiom lookup_join2 : forall A B (m1 m2 : fmap A B) k,
2015-12-31 20:44:34 +00:00
~k \in dom m1
-> (m1 $++ m2) $? k = m2 $? k.
2016-02-09 14:07:37 +00:00
Axiom join_comm : forall A B (m1 m2 : fmap A B),
2015-12-31 20:44:34 +00:00
dom m1 \cap dom m2 = {}
-> m1 $++ m2 = m2 $++ m1.
2016-02-09 14:07:37 +00:00
Axiom join_assoc : forall A B (m1 m2 m3 : fmap A B),
2015-12-31 20:44:34 +00:00
(m1 $++ m2) $++ m3 = m1 $++ (m2 $++ m3).
Axiom lookup_merge : forall A B f (m1 m2 : fmap A B) k,
merge f m1 m2 $? k = f (m1 $? k) (m2 $? k).
2016-02-09 14:07:37 +00:00
Axiom empty_includes : forall A B (m : fmap A B), empty A B $<= m.
2015-12-31 20:44:34 +00:00
Axiom dom_empty : forall A B, dom (empty A B) = {}.
2016-02-09 14:07:37 +00:00
Axiom dom_add : forall A B (m : fmap A B) (k : A) (v : B),
2015-12-31 20:44:34 +00:00
dom (add m k v) = {k} \cup dom m.
Hint Extern 1 => match goal with
| [ H : lookup (empty _ _) _ = Some _ |- _ ] =>
rewrite lookup_empty in H; discriminate
end.
Hint Resolve includes_lookup includes_add empty_includes.
Hint Rewrite lookup_empty lookup_add_eq lookup_add_ne lookup_remove_eq lookup_remove_ne lookup_merge using congruence.
2015-12-31 20:44:34 +00:00
Ltac maps_equal :=
2016-02-09 14:07:37 +00:00
apply fmap_ext; intros;
2015-12-31 20:44:34 +00:00
repeat (subst; autorewrite with core; try reflexivity;
match goal with
| [ |- context[lookup (add _ ?k _) ?k' ] ] => destruct (classic (k = k')); subst
end).
Hint Extern 3 (_ = _) => maps_equal.
End S.
Module M : S.
2016-02-09 14:07:37 +00:00
Definition fmap (A B : Type) := A -> option B.
2015-12-31 20:44:34 +00:00
2016-02-09 14:07:37 +00:00
Definition empty A B : fmap A B := fun _ => None.
2015-12-31 20:44:34 +00:00
Section decide.
Variable P : Prop.
Lemma decided : inhabited (sum P (~P)).
Proof.
destruct (classic P).
constructor; exact (inl _ H).
constructor; exact (inr _ H).
Qed.
Definition decide : sum P (~P) :=
epsilon decided (fun _ => True).
End decide.
2016-02-09 14:07:37 +00:00
Definition add A B (m : fmap A B) (k : A) (v : B) : fmap A B :=
2015-12-31 20:44:34 +00:00
fun k' => if decide (k' = k) then Some v else m k'.
2016-02-10 03:44:03 +00:00
Definition remove A B (m : fmap A B) (k : A) : fmap A B :=
fun k' => if decide (k' = k) then None else m k'.
2016-02-09 14:07:37 +00:00
Definition join A B (m1 m2 : fmap A B) : fmap A B :=
2015-12-31 20:44:34 +00:00
fun k => match m1 k with
| None => m2 k
| x => x
end.
Definition merge A B f (m1 m2 : fmap A B) : fmap A B :=
fun k => f (m1 k) (m2 k).
2016-02-09 14:07:37 +00:00
Definition lookup A B (m : fmap A B) (k : A) := m k.
Definition includes A B (m1 m2 : fmap A B) :=
2015-12-31 20:44:34 +00:00
forall k v, m1 k = Some v -> m2 k = Some v.
2016-02-09 14:07:37 +00:00
Definition dom A B (m : fmap A B) : set A := fun x => m x <> None.
2015-12-31 20:44:34 +00:00
2016-02-09 14:07:37 +00:00
Theorem fmap_ext : forall A B (m1 m2 : fmap A B),
2015-12-31 20:44:34 +00:00
(forall k, lookup m1 k = lookup m2 k)
-> m1 = m2.
Proof.
intros; extensionality k; auto.
Qed.
Theorem lookup_empty : forall A B (k : A), lookup (empty B) k = None.
Proof.
auto.
Qed.
2016-02-09 14:07:37 +00:00
Theorem includes_lookup : forall A B (m m' : fmap A B) k v,
2015-12-31 20:44:34 +00:00
lookup m k = Some v
-> includes m m'
-> lookup m' k = Some v.
Proof.
auto.
Qed.
2016-02-09 14:07:37 +00:00
Theorem includes_add : forall A B (m m' : fmap A B) k v,
2015-12-31 20:44:34 +00:00
includes m m'
-> includes (add m k v) (add m' k v).
Proof.
unfold includes, add; intuition.
destruct (decide (k0 = k)); auto.
Qed.
2016-02-09 14:07:37 +00:00
Theorem lookup_add_eq : forall A B (m : fmap A B) k1 k2 v,
2016-02-07 03:09:37 +00:00
k1 = k2
-> lookup (add m k1 v) k2 = Some v.
2015-12-31 20:44:34 +00:00
Proof.
unfold lookup, add; intuition.
2016-02-07 03:09:37 +00:00
destruct (decide (k2 = k1)); try tauto.
congruence.
2015-12-31 20:44:34 +00:00
Qed.
2016-02-09 14:07:37 +00:00
Theorem lookup_add_ne : forall A B (m : fmap A B) k k' v,
2015-12-31 20:44:34 +00:00
k' <> k
-> lookup (add m k v) k' = lookup m k'.
Proof.
unfold lookup, add; intuition.
destruct (decide (k' = k)); intuition.
Qed.
2016-02-10 03:44:03 +00:00
Theorem lookup_remove_eq : forall A B (m : fmap A B) k1 k2,
k1 = k2
-> lookup (remove m k1) k2 = None.
Proof.
unfold lookup, remove; intuition.
destruct (decide (k2 = k1)); try tauto.
congruence.
Qed.
Theorem lookup_remove_ne : forall A B (m : fmap A B) k k',
k' <> k
-> lookup (remove m k) k' = lookup m k'.
Proof.
unfold lookup, remove; intuition.
destruct (decide (k' = k)); try tauto.
Qed.
2016-02-09 14:07:37 +00:00
Theorem lookup_join1 : forall A B (m1 m2 : fmap A B) k,
2015-12-31 20:44:34 +00:00
k \in dom m1
-> lookup (join m1 m2) k = lookup m1 k.
Proof.
unfold lookup, join, dom, In; intros.
destruct (m1 k); congruence.
Qed.
2016-02-09 14:07:37 +00:00
Theorem lookup_join2 : forall A B (m1 m2 : fmap A B) k,
2015-12-31 20:44:34 +00:00
~k \in dom m1
-> lookup (join m1 m2) k = lookup m2 k.
Proof.
unfold lookup, join, dom, In; intros.
destruct (m1 k); try congruence.
exfalso; apply H; congruence.
Qed.
2016-02-09 14:07:37 +00:00
Theorem join_comm : forall A B (m1 m2 : fmap A B),
2015-12-31 20:44:34 +00:00
dom m1 \cap dom m2 = {}
-> join m1 m2 = join m2 m1.
Proof.
2016-02-09 14:07:37 +00:00
intros; apply fmap_ext; unfold join, lookup; intros.
2015-12-31 20:44:34 +00:00
apply (f_equal (fun f => f k)) in H.
unfold dom, intersection, constant in H; simpl in H.
destruct (m1 k), (m2 k); auto.
exfalso; rewrite <- H.
intuition congruence.
Qed.
2016-02-09 14:07:37 +00:00
Theorem join_assoc : forall A B (m1 m2 m3 : fmap A B),
2015-12-31 20:44:34 +00:00
join (join m1 m2) m3 = join m1 (join m2 m3).
Proof.
2016-02-09 14:07:37 +00:00
intros; apply fmap_ext; unfold join, lookup; intros.
2015-12-31 20:44:34 +00:00
destruct (m1 k); auto.
Qed.
Theorem lookup_merge : forall A B f (m1 m2 : fmap A B) k,
lookup (merge f m1 m2) k = f (m1 k) (m2 k).
Proof.
auto.
Qed.
2016-02-09 14:07:37 +00:00
Theorem empty_includes : forall A B (m : fmap A B), includes (empty (A := A) B) m.
2015-12-31 20:44:34 +00:00
Proof.
unfold includes, empty; intuition congruence.
Qed.
Theorem dom_empty : forall A B, dom (empty (A := A) B) = {}.
Proof.
unfold dom, empty; intros; sets idtac.
Qed.
2016-02-09 14:07:37 +00:00
Theorem dom_add : forall A B (m : fmap A B) (k : A) (v : B),
2015-12-31 20:44:34 +00:00
dom (add m k v) = {k} \cup dom m.
Proof.
unfold dom, add; simpl; intros.
sets ltac:(simpl in *; try match goal with
| [ _ : context[if ?E then _ else _] |- _ ] => destruct E
end; intuition congruence).
Qed.
End M.
Export M.