Commit d0bd6f44 by Robbert Krebbers

### More properties about the order on finite maps.

parent 2aa844c9
 ... @@ -205,14 +205,15 @@ Proof. ... @@ -205,14 +205,15 @@ Proof. unfold subseteq, map_subseteq, map_relation. split; intros Hm i; unfold subseteq, map_subseteq, map_relation. split; intros Hm i; specialize (Hm i); destruct (m1 !! i), (m2 !! i); naive_solver. specialize (Hm i); destruct (m1 !! i), (m2 !! i); naive_solver. Qed. Qed. Global Instance: ∀ {A} (R : relation A), PreOrder R → PreOrder (map_included R). Global Instance map_included_preorder {A} (R : relation A) : PreOrder R → PreOrder (map_included R). Proof. Proof. split; [intros m i; by destruct (m !! i); simpl|]. split; [intros m i; by destruct (m !! i); simpl|]. intros m1 m2 m3 Hm12 Hm23 i; specialize (Hm12 i); specialize (Hm23 i). intros m1 m2 m3 Hm12 Hm23 i; specialize (Hm12 i); specialize (Hm23 i). destruct (m1 !! i), (m2 !! i), (m3 !! i); simplify_eq/=; destruct (m1 !! i), (m2 !! i), (m3 !! i); simplify_eq/=; done || etrans; eauto. done || etrans; eauto. Qed. Qed. Global Instance: PartialOrder ((⊆) : relation (M A)). Global Instance map_subseteq_po : PartialOrder ((⊆) : relation (M A)). Proof. Proof. split; [apply _|]. split; [apply _|]. intros m1 m2; rewrite !map_subseteq_spec. intros m1 m2; rewrite !map_subseteq_spec. ... @@ -248,6 +249,22 @@ Qed. ... @@ -248,6 +249,22 @@ Qed. Lemma map_fmap_empty {A B} (f : A → B) : f <\$> (∅ : M A) = ∅. Lemma map_fmap_empty {A B} (f : A → B) : f <\$> (∅ : M A) = ∅. Proof. by apply map_eq; intros i; rewrite lookup_fmap, !lookup_empty. Qed. Proof. by apply map_eq; intros i; rewrite lookup_fmap, !lookup_empty. Qed. Lemma map_subset_alt {A} (m1 m2 : M A) : m1 ⊂ m2 ↔ m1 ⊆ m2 ∧ ∃ i, m1 !! i = None ∧ is_Some (m2 !! i). Proof. rewrite strict_spec_alt. split. - intros [? Heq]; split; [done|]. destruct (decide (Exists (λ '(i,_), m1 !! i = None) (map_to_list m2))) as [[[i x] [?%elem_of_map_to_list ?]]%Exists_exists |Hm%(not_Exists_Forall _)]; [eauto|]. destruct Heq; apply (anti_symm _), map_subseteq_spec; [done|intros i x Hi]. assert (is_Some (m1 !! i)) as [x' ?]. { by apply not_eq_None_Some, (proj1 (Forall_forall _ _) Hm (i,x)), elem_of_map_to_list. } by rewrite <-(lookup_weaken_inv m1 m2 i x' x). - intros [? (i&?&x&?)]; split; [done|]. congruence. Qed. (** ** Properties of the [partial_alter] operation *) (** ** Properties of the [partial_alter] operation *) Lemma partial_alter_ext {A} (f g : option A → option A) (m : M A) i : Lemma partial_alter_ext {A} (f g : option A → option A) (m : M A) i : (∀ x, m !! i = x → f x = g x) → partial_alter f i m = partial_alter g i m. (∀ x, m !! i = x → f x = g x) → partial_alter f i m = partial_alter g i m. ... @@ -290,20 +307,18 @@ Qed. ... @@ -290,20 +307,18 @@ Qed. Lemma partial_alter_subset {A} f (m : M A) i : Lemma partial_alter_subset {A} f (m : M A) i : m !! i = None → is_Some (f (m !! i)) → m ⊂ partial_alter f i m. m !! i = None → is_Some (f (m !! i)) → m ⊂ partial_alter f i m. Proof. Proof. intros Hi Hfi. split; [by apply partial_alter_subseteq|]. intros Hi Hfi. apply map_subset_alt; split; [by apply partial_alter_subseteq|]. rewrite !map_subseteq_spec. inversion Hfi as [x Hx]. intros Hm. exists i. by rewrite lookup_partial_alter. apply (Some_ne_None x). rewrite <-(Hm i x); [done|]. by rewrite lookup_partial_alter. Qed. Qed. (** ** Properties of the [alter] operation *) (** ** Properties of the [alter] operation *) Lemma alter_ext {A} (f g : A → A) (m : M A) i : (∀ x, m !! i = Some x → f x = g x) → alter f i m = alter g i m. Proof. intro. apply partial_alter_ext. intros [x|] ?; f_equal/=; auto. Qed. Lemma lookup_alter {A} (f : A → A) m i : alter f i m !! i = f <\$> m !! i. Lemma lookup_alter {A} (f : A → A) m i : alter f i m !! i = f <\$> m !! i. Proof. unfold alter. apply lookup_partial_alter. Qed. Proof. unfold alter. apply lookup_partial_alter. Qed. Lemma lookup_alter_ne {A} (f : A → A) m i j : i ≠ j → alter f i m !! j = m !! j. Lemma lookup_alter_ne {A} (f : A → A) m i j : i ≠ j → alter f i m !! j = m !! j. Proof. unfold alter. apply lookup_partial_alter_ne. Qed. Proof. unfold alter. apply lookup_partial_alter_ne. Qed. Lemma alter_ext {A} (f g : A → A) (m : M A) i : (∀ x, m !! i = Some x → f x = g x) → alter f i m = alter g i m. Proof. intro. apply partial_alter_ext. intros [x|] ?; f_equal/=; auto. Qed. Lemma alter_compose {A} (f g : A → A) (m : M A) i: Lemma alter_compose {A} (f g : A → A) (m : M A) i: alter (f ∘ g) i m = alter f i (alter g i m). alter (f ∘ g) i m = alter f i (alter g i m). Proof. Proof. ... @@ -327,6 +342,9 @@ Proof. ... @@ -327,6 +342,9 @@ Proof. by destruct (decide (i = j)) as [->|?]; by destruct (decide (i = j)) as [->|?]; rewrite ?lookup_alter, ?fmap_None, ?lookup_alter_ne. rewrite ?lookup_alter, ?fmap_None, ?lookup_alter_ne. Qed. Qed. Lemma lookup_alter_is_Some {A} (f : A → A) m i j : is_Some (alter f i m !! j) ↔ is_Some (m !! j). Proof. by rewrite <-!not_eq_None_Some, lookup_alter_None. Qed. Lemma alter_id {A} (f : A → A) m i : Lemma alter_id {A} (f : A → A) m i : (∀ x, m !! i = Some x → f x = x) → alter f i m = m. (∀ x, m !! i = Some x → f x = x) → alter f i m = m. Proof. Proof. ... @@ -334,6 +352,18 @@ Proof. ... @@ -334,6 +352,18 @@ Proof. { rewrite lookup_alter; destruct (m !! j); f_equal/=; auto. } { rewrite lookup_alter; destruct (m !! j); f_equal/=; auto. } by rewrite lookup_alter_ne by done. by rewrite lookup_alter_ne by done. Qed. Qed. Lemma alter_mono {A} f (m1 m2 : M A) i : m1 ⊆ m2 → alter f i m1 ⊆ alter f i m2. Proof. rewrite !map_subseteq_spec. intros ? j x. rewrite !lookup_alter_Some. naive_solver. Qed. Lemma alter_strict_mono {A} f (m1 m2 : M A) i : m1 ⊂ m2 → alter f i m1 ⊂ alter f i m2. Proof. rewrite !map_subset_alt. intros [? (j&?&?)]; split; auto using alter_mono. exists j. by rewrite lookup_alter_None, lookup_alter_is_Some. Qed. (** ** Properties of the [delete] operation *) (** ** Properties of the [delete] operation *) Lemma lookup_delete {A} (m : M A) i : delete i m !! i = None. Lemma lookup_delete {A} (m : M A) i : delete i m !! i = None. ... @@ -387,20 +417,16 @@ Lemma delete_subseteq {A} (m : M A) i : delete i m ⊆ m. ... @@ -387,20 +417,16 @@ Lemma delete_subseteq {A} (m : M A) i : delete i m ⊆ m. Proof. Proof. rewrite !map_subseteq_spec. intros j x. rewrite lookup_delete_Some. tauto. rewrite !map_subseteq_spec. intros j x. rewrite lookup_delete_Some. tauto. Qed. Qed. Lemma delete_subseteq_compat {A} (m1 m2 : M A) i : Lemma delete_subset {A} (m : M A) i : is_Some (m !! i) → delete i m ⊂ m. m1 ⊆ m2 → delete i m1 ⊆ delete i m2. Proof. Proof. rewrite !map_subseteq_spec. intros ? j x. intros [x ?]; apply map_subset_alt; split; [apply delete_subseteq|]. rewrite !lookup_delete_Some. intuition eauto. exists i. rewrite lookup_delete; eauto. Qed. Qed. Lemma delete_subset_alt {A} (m : M A) i x : m !! i = Some x → delete i m ⊂ m. Lemma delete_mono {A} (m1 m2 : M A) i : m1 ⊆ m2 → delete i m1 ⊆ delete i m2. Proof. Proof. split; [apply delete_subseteq|]. rewrite !map_subseteq_spec. intros ? j x. rewrite !map_subseteq_spec. intros Hi. apply (None_ne_Some x). rewrite !lookup_delete_Some. intuition eauto. by rewrite <-(lookup_delete m i), (Hi i x). Qed. Qed. Lemma delete_subset {A} (m : M A) i : is_Some (m !! i) → delete i m ⊂ m. Proof. inversion 1. eauto using delete_subset_alt. Qed. (** ** Properties of the [insert] operation *) (** ** Properties of the [insert] operation *) Lemma lookup_insert {A} (m : M A) i x : <[i:=x]>m !! i = Some x. Lemma lookup_insert {A} (m : M A) i x : <[i:=x]>m !! i = Some x. ... @@ -447,17 +473,28 @@ Proof. ... @@ -447,17 +473,28 @@ Proof. - rewrite lookup_insert. destruct (m !! j); simpl; eauto. - rewrite lookup_insert. destruct (m !! j); simpl; eauto. - rewrite lookup_insert_ne by done. by destruct (m !! j); simpl. - rewrite lookup_insert_ne by done. by destruct (m !! j); simpl. Qed. Qed. Lemma insert_empty {A} i (x : A) : <[i:=x]>∅ = {[i := x]}. Proof. done. Qed. Lemma insert_non_empty {A} (m : M A) i x : <[i:=x]>m ≠ ∅. Proof. intros Hi%(f_equal (!! i)). by rewrite lookup_insert, lookup_empty in Hi. Qed. Lemma insert_subseteq {A} (m : M A) i x : m !! i = None → m ⊆ <[i:=x]>m. Lemma insert_subseteq {A} (m : M A) i x : m !! i = None → m ⊆ <[i:=x]>m. Proof. apply partial_alter_subseteq. Qed. Proof. apply partial_alter_subseteq. Qed. Lemma insert_subset {A} (m : M A) i x : m !! i = None → m ⊂ <[i:=x]>m. Lemma insert_subset {A} (m : M A) i x : m !! i = None → m ⊂ <[i:=x]>m. Proof. intro. apply partial_alter_subset; eauto. Qed. Proof. intro. apply partial_alter_subset; eauto. Qed. Lemma insert_mono {A} (m1 m2 : M A) i x : m1 ⊆ m2 → <[i:=x]> m1 ⊆ <[i:=x]>m2. Proof. rewrite !map_subseteq_spec. intros Hm j y. rewrite !lookup_insert_Some. naive_solver. Qed. Lemma insert_subseteq_r {A} (m1 m2 : M A) i x : Lemma insert_subseteq_r {A} (m1 m2 : M A) i x : m1 !! i = None → m1 ⊆ m2 → m1 ⊆ <[i:=x]>m2. m1 !! i = None → m1 ⊆ m2 → m1 ⊆ <[i:=x]>m2. Proof. Proof. rewrite !map_subseteq_spec. intros ?? j ?. intros. trans (<[i:=x]> m1); eauto using insert_subseteq, insert_mono. destruct (decide (j = i)) as [->|?]; [congruence|]. rewrite lookup_insert_ne; auto. Qed. Qed. Lemma insert_delete_subseteq {A} (m1 m2 : M A) i x : Lemma insert_delete_subseteq {A} (m1 m2 : M A) i x : m1 !! i = None → <[i:=x]> m1 ⊆ m2 → m1 ⊆ delete i m2. m1 !! i = None → <[i:=x]> m1 ⊆ m2 → m1 ⊆ delete i m2. Proof. Proof. ... @@ -491,12 +528,6 @@ Proof. ... @@ -491,12 +528,6 @@ Proof. - eauto using insert_delete_subset. - eauto using insert_delete_subset. - by rewrite lookup_delete. - by rewrite lookup_delete. Qed. Qed. Lemma insert_empty {A} i (x : A) : <[i:=x]>∅ = {[i := x]}. Proof. done. Qed. Lemma insert_non_empty {A} (m : M A) i x : <[i:=x]>m ≠ ∅. Proof. intros Hi%(f_equal (!! i)). by rewrite lookup_insert, lookup_empty in Hi. Qed. (** ** Properties of the singleton maps *) (** ** Properties of the singleton maps *) Lemma lookup_singleton_Some {A} i j (x y : A) : Lemma lookup_singleton_Some {A} i j (x y : A) : ... @@ -593,6 +624,26 @@ Proof. ... @@ -593,6 +624,26 @@ Proof. by destruct (m !! i) eqn:?; simpl; erewrite ?Hi by eauto. by destruct (m !! i) eqn:?; simpl; erewrite ?Hi by eauto. Qed. Qed. Lemma map_fmap_mono {A B} (f : A → B) (m1 m2 : M A) : m1 ⊆ m2 → f <\$> m1 ⊆ f <\$> m2. Proof. rewrite !map_subseteq_spec; intros Hm i x. rewrite !lookup_fmap, !fmap_Some. naive_solver. Qed. Lemma map_fmap_strict_mono {A B} (f : A → B) (m1 m2 : M A) : m1 ⊂ m2 → f <\$> m1 ⊂ f <\$> m2. Proof. rewrite !map_subset_alt. intros [? (j&?&?)]; split; auto using map_fmap_mono. exists j. by rewrite !lookup_fmap, fmap_None, fmap_is_Some. Qed. Lemma map_omap_mono {A B} (f : A → option B) (m1 m2 : M A) : m1 ⊆ m2 → omap f m1 ⊆ omap f m2. Proof. rewrite !map_subseteq_spec; intros Hm i x. rewrite !lookup_omap, !bind_Some. naive_solver. Qed. (** ** Properties of conversion to lists *) (** ** Properties of conversion to lists *) Lemma elem_of_map_to_list' {A} (m : M A) ix : Lemma elem_of_map_to_list' {A} (m : M A) ix : ix ∈ map_to_list m ↔ m !! ix.1 = Some (ix.2). ix ∈ map_to_list m ↔ m !! ix.1 = Some (ix.2). ... ...
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!