diff --git a/theories/gmultiset.v b/theories/gmultiset.v index 0fab06bc05343dfdbd8759b4e2b3e607c75649b0..ff921f8768b7500b5e162b960b317c2435270664 100644 --- a/theories/gmultiset.v +++ b/theories/gmultiset.v @@ -73,18 +73,6 @@ Proof. repeat case_match; naive_solver. Qed. -Global Instance gmultiset_po : PartialOrder (@subseteq (gmultiset A) _). -Proof. - split; [split|]. - - by intros X x. - - intros X Y Z HXY HYZ x. by trans (multiplicity x Y). - - intros X Y HXY HYX; apply gmultiset_eq; intros x. by apply (anti_symm (≤)). -Qed. - -Lemma gmultiset_subset_subseteq X Y : X ⊂ Y → X ⊆ Y. -Proof. by intros [??]. Qed. -Hint Resolve gmultiset_subset_subseteq. - (* Multiplicity *) Lemma multiplicity_empty x : multiplicity x ∅ = 0. Proof. done. Qed. @@ -145,24 +133,10 @@ Qed. Global Instance gmultiset_union_inj_2 X : Inj (=) (=) (∪ X). Proof. intros Y1 Y2. rewrite <-!(comm_L _ X). apply (inj _). Qed. -Lemma gmultiset_union_difference X Y : X ⊆ Y → Y = X ∪ Y ∖ X. -Proof. - intros HXY. apply gmultiset_eq; intros x; specialize (HXY x). - rewrite multiplicity_union, multiplicity_difference; omega. -Qed. -Lemma non_empty_difference X Y : X ⊂ Y → Y ∖ X ≠∅. +Lemma gmultiset_non_empty_singleton x : {[ x ]} ≠(∅ : gmultiset A). Proof. - intros [_ HXY2] Hdiff; destruct HXY2; intros x. - generalize (f_equal (multiplicity x) Hdiff). - rewrite multiplicity_difference, multiplicity_empty; omega. -Qed. - -(* Order stuff *) -Lemma gmultiset_elem_of_subseteq x X : x ∈ X → {[ x ]} ⊆ X. -Proof. - rewrite elem_of_multiplicity. intros Hx y; destruct (decide (x = y)) as [->|]. - - rewrite multiplicity_singleton; omega. - - rewrite multiplicity_singleton_ne by done; omega. + rewrite gmultiset_eq. intros Hx; generalize (Hx x). + by rewrite multiplicity_singleton, multiplicity_empty. Qed. (* Properties of the elements operation *) @@ -204,11 +178,6 @@ Proof. by (by rewrite ?lookup_union_with, ?HX, ?HY). by rewrite <-(assoc_L (++)), <-IH. Qed. -Lemma gmultiset_elements_contains X Y : X ⊆ Y → elements X `contains` elements Y. -Proof. - intros ->%gmultiset_union_difference. rewrite gmultiset_elements_union. - by apply contains_inserts_r. -Qed. Lemma gmultiset_elem_of_elements x X : x ∈ elements X ↔ x ∈ X. Proof. destruct X as [X]. unfold elements, gmultiset_elements. @@ -260,20 +229,93 @@ Proof. unfold size, gmultiset_size; simpl. by rewrite gmultiset_elements_union, app_length. Qed. + +(* Order stuff *) +Global Instance gmultiset_po : PartialOrder (@subseteq (gmultiset A) _). +Proof. + split; [split|]. + - by intros X x. + - intros X Y Z HXY HYZ x. by trans (multiplicity x Y). + - intros X Y HXY HYX; apply gmultiset_eq; intros x. by apply (anti_symm (≤)). +Qed. + +Lemma gmultiset_subset_subseteq X Y : X ⊂ Y → X ⊆ Y. +Proof. apply strict_include. Qed. +Hint Resolve gmultiset_subset_subseteq. + +Lemma gmultiset_empty_subseteq X : ∅ ⊆ X. +Proof. intros x. rewrite multiplicity_empty. omega. Qed. + +Lemma gmultiset_union_subseteq_l X Y : X ⊆ X ∪ Y. +Proof. intros x. rewrite multiplicity_union. omega. Qed. +Lemma gmultiset_union_subseteq_r X Y : Y ⊆ X ∪ Y. +Proof. intros x. rewrite multiplicity_union. omega. Qed. +Lemma gmultiset_union_preserving X1 X2 Y1 Y2 : X1 ⊆ X2 → Y1 ⊆ Y2 → X1 ∪ Y1 ⊆ X2 ∪ Y2. +Proof. intros ?? x. rewrite !multiplicity_union. by apply Nat.add_le_mono. Qed. +Lemma gmultiset_union_preserving_l X Y1 Y2 : Y1 ⊆ Y2 → X ∪ Y1 ⊆ X ∪ Y2. +Proof. intros. by apply gmultiset_union_preserving. Qed. +Lemma gmultiset_union_preserving_r X1 X2 Y : X1 ⊆ X2 → X1 ∪ Y ⊆ X2 ∪ Y. +Proof. intros. by apply gmultiset_union_preserving. Qed. + +Lemma gmultiset_subset X Y : X ⊆ Y → size X < size Y → X ⊂ Y. +Proof. intros. apply strict_spec_alt; split; naive_solver auto with omega. Qed. +Lemma gmultiset_union_subset_l X Y : Y ≠∅ → X ⊂ X ∪ Y. +Proof. + intros HY%gmultiset_size_non_empty_iff. + apply gmultiset_subset; auto using gmultiset_union_subseteq_l. + rewrite gmultiset_size_union; omega. +Qed. +Lemma gmultiset_union_subset_r X Y : X ≠∅ → Y ⊂ X ∪ Y. +Proof. rewrite (comm_L (∪)). apply gmultiset_union_subset_l. Qed. + +Lemma gmultiset_elem_of_subseteq x X : x ∈ X → {[ x ]} ⊆ X. +Proof. + rewrite elem_of_multiplicity. intros Hx y; destruct (decide (x = y)) as [->|]. + - rewrite multiplicity_singleton; omega. + - rewrite multiplicity_singleton_ne by done; omega. +Qed. + +Lemma gmultiset_union_difference X Y : X ⊆ Y → Y = X ∪ Y ∖ X. +Proof. + intros HXY. apply gmultiset_eq; intros x; specialize (HXY x). + rewrite multiplicity_union, multiplicity_difference; omega. +Qed. +Lemma gmultiset_union_difference' x Y : x ∈ Y → Y = {[ x ]} ∪ Y ∖ {[ x ]}. +Proof. auto using gmultiset_union_difference, gmultiset_elem_of_subseteq. Qed. + Lemma gmultiset_size_difference X Y : Y ⊆ X → size (X ∖ Y) = size X - size Y. Proof. intros HX%gmultiset_union_difference. rewrite HX at 2; rewrite gmultiset_size_union. omega. Qed. +Lemma gmultiset_non_empty_difference X Y : X ⊂ Y → Y ∖ X ≠∅. +Proof. + intros [_ HXY2] Hdiff; destruct HXY2; intros x. + generalize (f_equal (multiplicity x) Hdiff). + rewrite multiplicity_difference, multiplicity_empty; omega. +Qed. + +Lemma gmultiset_difference_subset X Y : X ≠∅ → X ⊆ Y → Y ∖ X ⊂ Y. +Proof. + intros. eapply strict_transitive_l; [by apply gmultiset_union_subset_r|]. + by rewrite <-(gmultiset_union_difference X Y). +Qed. + (* Mononicity *) +Lemma gmultiset_elements_contains X Y : X ⊆ Y → elements X `contains` elements Y. +Proof. + intros ->%gmultiset_union_difference. rewrite gmultiset_elements_union. + by apply contains_inserts_r. +Qed. + Lemma gmultiset_subseteq_size X Y : X ⊆ Y → size X ≤ size Y. Proof. intros. by apply contains_length, gmultiset_elements_contains. Qed. Lemma gmultiset_subset_size X Y : X ⊂ Y → size X < size Y. Proof. intros HXY. assert (size (Y ∖ X) ≠0). - { by apply gmultiset_size_non_empty_iff, non_empty_difference. } + { by apply gmultiset_size_non_empty_iff, gmultiset_non_empty_difference. } rewrite (gmultiset_union_difference X Y), gmultiset_size_union by auto. lia. Qed. @@ -282,4 +324,14 @@ Lemma gmultiset_wf : wf (strict (@subseteq (gmultiset A) _)). Proof. apply (wf_projected (<) size); auto using gmultiset_subset_size, lt_wf. Qed. + +Lemma gmultiset_ind (P : gmultiset A → Prop) : + P ∅ → (∀ x X, P X → P ({[ x ]} ∪ X)) → ∀ X, P X. +Proof. + intros Hemp Hinsert X. induction (gmultiset_wf X) as [X _ IH]. + destruct (gmultiset_choose_or_empty X) as [[x Hx]| ->]; auto. + rewrite (gmultiset_union_difference' x X) by done. + apply Hinsert, IH, gmultiset_difference_subset; + auto using gmultiset_elem_of_subseteq, gmultiset_non_empty_singleton. +Qed. End lemmas.