From 853b4b437bd3179776d13e615511ccec02b4aabc Mon Sep 17 00:00:00 2001 From: Robbert Krebbers <mail@robbertkrebbers.nl> Date: Thu, 16 Apr 2015 21:21:52 +0200 Subject: [PATCH] Finite maps indexed by the option type. --- theories/optionmap.v | 88 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 theories/optionmap.v diff --git a/theories/optionmap.v b/theories/optionmap.v new file mode 100644 index 00000000..ff464ca0 --- /dev/null +++ b/theories/optionmap.v @@ -0,0 +1,88 @@ +(* Copyright (c) 2012-2015, Robbert Krebbers. *) +(* This file is distributed under the terms of the BSD license. *) +Require Import mapset. +Require Export prelude fin_maps. + +Record optionmap (M : Type → Type) (A : Type) : Type := + OptionMap { optionmap_None : option A; optionmap_Some : M A }. +Arguments optionmap_None {_ _} _. +Arguments optionmap_Some {_ _} _. +Arguments OptionMap {_ _} _ _. +Instance optionmap_eq_dec {M : Type → Type} {A} + `{∀ x y : A, Decision (x = y), ∀ m1 m2 : M A, Decision (m1 = m2)} + (m1 m2 : optionmap M A) : Decision (m1 = m2). +Proof. solve_decision. Defined. + +Section optionmap. +Context `{FinMap K M}. + +Global Instance optionmap_empty {A} : Empty (optionmap M A) := OptionMap None ∅. +Global Opaque optionmap_empty. +Global Instance optionmap_lookup {A} : + Lookup (option K) A (optionmap M A) := λ i m, + match i with + | None => optionmap_None m + | Some k => optionmap_Some m !! k + end. +Global Instance optionmap_partial_alter {A} : + PartialAlter (option K) A (optionmap M A) := λ f i m, + match i, m with + | None, OptionMap o m => OptionMap (f o) m + | Some k, OptionMap o m => OptionMap o (partial_alter f k m) + end. +Global Instance optionmap_to_list {A} : + FinMapToList (option K) A (optionmap M A) := λ m, + match m with + | OptionMap o m => + default [] o (λ x, [(None,x)]) ++ (prod_map Some id <$> map_to_list m) + end. +Global Instance optionmap_omap: OMap (optionmap M) := λ A B f m, + match m with OptionMap o m => OptionMap (o ≫= f) (omap f m) end. +Global Instance optionmap_merge: Merge (optionmap M) := λ A B C f m1 m2, + match m1, m2 with + | OptionMap o1 m1, OptionMap o2 m2 => OptionMap (f o1 o2) (merge f m1 m2) + end. +Global Instance optionmap_fmap: FMap (optionmap M) := λ A B f m, + match m with OptionMap o m => OptionMap (f <$> o) (f <$> m) end. + +Global Instance: FinMap (option K) (optionmap M). +Proof. + split. + * intros ? [??] [??] Hlookup. f_equal; [apply (Hlookup None)|]. + apply map_eq. intros k. apply (Hlookup (Some k)). + * intros ? [?|]. apply (lookup_empty k). done. + * intros ? f [? t] [k|]; simpl; [|done]. apply lookup_partial_alter. + * intros ? f [? t] [k|] [|k']; simpl; try intuition congruence. + intros; apply lookup_partial_alter_ne; congruence. + * intros ??? [??] []; simpl. apply lookup_fmap. done. + * intros ? [[x|] m]; unfold map_to_list; simpl. + + constructor. + - rewrite elem_of_list_fmap. by intros [[??] [??]]. + - by apply (NoDup_fmap _), NoDup_map_to_list. + + apply (NoDup_fmap _), NoDup_map_to_list. + * intros ? m k x. unfold map_to_list. split. + + destruct m as [[y|] m]; simpl. + - rewrite elem_of_cons, elem_of_list_fmap. + intros [? | [[??] [??]]]; simplify_equality'; [done |]. + by apply elem_of_map_to_list. + - rewrite elem_of_list_fmap; intros [[??] [??]]; simplify_equality'. + by apply elem_of_map_to_list. + + destruct m as [[y|] m]; simpl. + - rewrite elem_of_cons, elem_of_list_fmap. + destruct k as [k|]; simpl; [|intuition congruence]. + intros. right. exists (k,x). by rewrite elem_of_map_to_list. + - rewrite elem_of_list_fmap. + destruct k as [k|]; simpl; [|done]. + intros. exists (k,x). by rewrite elem_of_map_to_list. + * intros ?? f [??] [?|]; simpl; [|done]; apply (lookup_omap f). + * intros ??? f ? [??] [??] [?|]; simpl; [|done]; apply (lookup_merge f). +Qed. +End optionmap. + +(** * Finite sets *) +Notation optionset M := (mapset (optionmap M unit)). +Instance optionmap_dom {M : Type → Type} `{∀ A, Empty (M A), Merge M} {A} : + Dom (optionmap M A) (optionset M) := mapset_dom. +Instance optionmap_domspec `{FinMap K M} : + FinMapDom (option K) (optionmap M) (optionset M) := mapset_dom_spec. + -- GitLab