Commit 44b18f4d by Robbert Krebbers

### Shorter names for common math notions.

`Also do some minor clean up.`
parent 7ebc1859
 ... ... @@ -514,71 +514,71 @@ Arguments insertE _ _ _ _ _ _ !_ _ !_ / : simpl nomatch. (** ** Common properties *) (** These operational type classes allow us to refer to common mathematical properties in a generic way. For example, for injectivity of [(k ++)] it allows us to write [injective (k ++)] instead of [app_inv_head k]. *) Class Injective {A B} (R : relation A) (S : relation B) (f : A → B) : Prop := injective: ∀ x y, S (f x) (f y) → R x y. Class Injective2 {A B C} (R1 : relation A) (R2 : relation B) allows us to write [inj (k ++)] instead of [app_inv_head k]. *) Class Inj {A B} (R : relation A) (S : relation B) (f : A → B) : Prop := inj x y : S (f x) (f y) → R x y. Class Inj2 {A B C} (R1 : relation A) (R2 : relation B) (S : relation C) (f : A → B → C) : Prop := injective2: ∀ x1 x2 y1 y2, S (f x1 x2) (f y1 y2) → R1 x1 y1 ∧ R2 x2 y2. inj2 x1 x2 y1 y2 : S (f x1 x2) (f y1 y2) → R1 x1 y1 ∧ R2 x2 y2. Class Cancel {A B} (S : relation B) (f : A → B) (g : B → A) : Prop := cancel: ∀ x, S (f (g x)) x. Class Surjective {A B} (R : relation B) (f : A → B) := surjective : ∀ y, ∃ x, R (f x) y. Class Idempotent {A} (R : relation A) (f : A → A → A) : Prop := idempotent: ∀ x, R (f x x) x. Class Commutative {A B} (R : relation A) (f : B → B → A) : Prop := commutative: ∀ x y, R (f x y) (f y x). cancel : ∀ x, S (f (g x)) x. Class Surj {A B} (R : relation B) (f : A → B) := surj y : ∃ x, R (f x) y. Class IdemP {A} (R : relation A) (f : A → A → A) : Prop := idemp x : R (f x x) x. Class Comm {A B} (R : relation A) (f : B → B → A) : Prop := comm x y : R (f x y) (f y x). Class LeftId {A} (R : relation A) (i : A) (f : A → A → A) : Prop := left_id: ∀ x, R (f i x) x. left_id x : R (f i x) x. Class RightId {A} (R : relation A) (i : A) (f : A → A → A) : Prop := right_id: ∀ x, R (f x i) x. Class Associative {A} (R : relation A) (f : A → A → A) : Prop := associative: ∀ x y z, R (f x (f y z)) (f (f x y) z). right_id x : R (f x i) x. Class Assoc {A} (R : relation A) (f : A → A → A) : Prop := assoc x y z : R (f x (f y z)) (f (f x y) z). Class LeftAbsorb {A} (R : relation A) (i : A) (f : A → A → A) : Prop := left_absorb: ∀ x, R (f i x) i. left_absorb x : R (f i x) i. Class RightAbsorb {A} (R : relation A) (i : A) (f : A → A → A) : Prop := right_absorb: ∀ x, R (f x i) i. Class AntiSymmetric {A} (R S : relation A) : Prop := anti_symmetric: ∀ x y, S x y → S y x → R x y. right_absorb x : R (f x i) i. Class AntiSymm {A} (R S : relation A) : Prop := anti_symm x y : S x y → S y x → R x y. Class Total {A} (R : relation A) := total x y : R x y ∨ R y x. Class Trichotomy {A} (R : relation A) := trichotomy : ∀ x y, R x y ∨ x = y ∨ R y x. trichotomy x y : R x y ∨ x = y ∨ R y x. Class TrichotomyT {A} (R : relation A) := trichotomyT : ∀ x y, {R x y} + {x = y} + {R y x}. trichotomyT x y : {R x y} + {x = y} + {R y x}. Arguments irreflexivity {_} _ {_} _ _. Arguments injective {_ _ _ _} _ {_} _ _ _. Arguments injective2 {_ _ _ _ _ _} _ {_} _ _ _ _ _. Arguments inj {_ _ _ _} _ {_} _ _ _. Arguments inj2 {_ _ _ _ _ _} _ {_} _ _ _ _ _. Arguments cancel {_ _ _} _ _ {_} _. Arguments surjective {_ _ _} _ {_} _. Arguments idempotent {_ _} _ {_} _. Arguments commutative {_ _ _} _ {_} _ _. Arguments surj {_ _ _} _ {_} _. Arguments idemp {_ _} _ {_} _. Arguments comm {_ _ _} _ {_} _ _. Arguments left_id {_ _} _ _ {_} _. Arguments right_id {_ _} _ _ {_} _. Arguments associative {_ _} _ {_} _ _ _. Arguments assoc {_ _} _ {_} _ _ _. Arguments left_absorb {_ _} _ _ {_} _. Arguments right_absorb {_ _} _ _ {_} _. Arguments anti_symmetric {_ _} _ {_} _ _ _ _. Arguments anti_symm {_ _} _ {_} _ _ _ _. Arguments total {_} _ {_} _ _. Arguments trichotomy {_} _ {_} _ _. Arguments trichotomyT {_} _ {_} _ _. Instance id_injective {A} : Injective (=) (=) (@id A). Instance id_inj {A} : Inj (=) (=) (@id A). Proof. intros ??; auto. Qed. (** The following lemmas are specific versions of the projections of the above type classes for Leibniz equality. These lemmas allow us to enforce Coq not to use the setoid rewriting mechanism. *) Lemma idempotent_L {A} (f : A → A → A) `{!Idempotent (=) f} x : f x x = x. Lemma idemp_L {A} (f : A → A → A) `{!IdemP (=) f} x : f x x = x. Proof. auto. Qed. Lemma commutative_L {A B} (f : B → B → A) `{!Commutative (=) f} x y : Lemma comm_L {A B} (f : B → B → A) `{!Comm (=) f} x y : f x y = f y x. Proof. auto. Qed. Lemma left_id_L {A} (i : A) (f : A → A → A) `{!LeftId (=) i f} x : f i x = x. Proof. auto. Qed. Lemma right_id_L {A} (i : A) (f : A → A → A) `{!RightId (=) i f} x : f x i = x. Proof. auto. Qed. Lemma associative_L {A} (f : A → A → A) `{!Associative (=) f} x y z : Lemma assoc_L {A} (f : A → A → A) `{!Assoc (=) f} x y z : f x (f y z) = f (f x y) z. Proof. auto. Qed. Lemma left_absorb_L {A} (i : A) (f : A → A → A) `{!LeftAbsorb (=) i f} x : ... ... @@ -593,7 +593,7 @@ Proof. auto. Qed. relation [R] instead of [⊆] to support multiple orders on the same type. *) Class PartialOrder {A} (R : relation A) : Prop := { partial_order_pre :> PreOrder R; partial_order_anti_symmetric :> AntiSymmetric (=) R partial_order_anti_symm :> AntiSymm (=) R }. Class TotalOrder {A} (R : relation A) : Prop := { total_order_partial :> PartialOrder R; ... ... @@ -746,31 +746,17 @@ Proof. intuition. Qed. Lemma symmetry_iff `(R : relation A) `{!Symmetric R} x y : R x y ↔ R y x. Proof. intuition. Qed. (** ** Pointwise relations *) (** These instances are in Coq trunk since revision 15455, but are not in Coq 8.4 yet. *) Instance pointwise_reflexive {A} `{R : relation B} : Reflexive R → Reflexive (pointwise_relation A R) | 9. Proof. firstorder. Qed. Instance pointwise_symmetric {A} `{R : relation B} : Symmetric R → Symmetric (pointwise_relation A R) | 9. Proof. firstorder. Qed. Instance pointwise_transitive {A} `{R : relation B} : Transitive R → Transitive (pointwise_relation A R) | 9. Proof. firstorder. Qed. (** ** Unit *) Instance unit_equiv : Equiv unit := λ _ _, True. Instance unit_equivalence : Equivalence (@equiv unit _). Proof. repeat split. Qed. (** ** Products *) Instance prod_map_injective {A A' B B'} (f : A → A') (g : B → B') : Injective (=) (=) f → Injective (=) (=) g → Injective (=) (=) (prod_map f g). Instance prod_map_inj {A A' B B'} (f : A → A') (g : B → B') : Inj (=) (=) f → Inj (=) (=) g → Inj (=) (=) (prod_map f g). Proof. intros ?? [??] [??] ?; simpl in *; f_equal; [apply (injective f)|apply (injective g)]; congruence. [apply (inj f)|apply (inj g)]; congruence. Qed. Definition prod_relation {A B} (R1 : relation A) (R2 : relation B) : ... ... @@ -815,17 +801,17 @@ Lemma and_wlog_l (P Q : Prop) : (Q → P) → Q → (P ∧ Q). Proof. tauto. Qed. Lemma and_wlog_r (P Q : Prop) : P → (P → Q) → (P ∧ Q). Proof. tauto. Qed. Instance: ∀ A B (x : B), Commutative (=) (λ _ _ : A, x). Instance: ∀ A B (x : B), Comm (=) (λ _ _ : A, x). Proof. red. trivial. Qed. Instance: ∀ A (x : A), Associative (=) (λ _ _ : A, x). Instance: ∀ A (x : A), Assoc (=) (λ _ _ : A, x). Proof. red. trivial. Qed. Instance: ∀ A, Associative (=) (λ x _ : A, x). Instance: ∀ A, Assoc (=) (λ x _ : A, x). Proof. red. trivial. Qed. Instance: ∀ A, Associative (=) (λ _ x : A, x). Instance: ∀ A, Assoc (=) (λ _ x : A, x). Proof. red. trivial. Qed. Instance: ∀ A, Idempotent (=) (λ x _ : A, x). Instance: ∀ A, IdemP (=) (λ x _ : A, x). Proof. red. trivial. Qed. Instance: ∀ A, Idempotent (=) (λ _ x : A, x). Instance: ∀ A, IdemP (=) (λ _ x : A, x). Proof. red. trivial. Qed. Instance left_id_propholds {A} (R : relation A) i f : ... ... @@ -841,7 +827,7 @@ Instance right_absorb_propholds {A} (R : relation A) i f : RightAbsorb R i f → ∀ x, PropHolds (R (f x i) i). Proof. red. trivial. Qed. Instance idem_propholds {A} (R : relation A) f : Idempotent R f → ∀ x, PropHolds (R (f x x) x). IdemP R f → ∀ x, PropHolds (R (f x x) x). Proof. red. trivial. Qed. Instance: ∀ `{R1 : relation A, R2 : relation B} (x : B), ... ... @@ -849,47 +835,47 @@ Instance: ∀ `{R1 : relation A, R2 : relation B} (x : B), Proof. intros A R1 B R2 x ? y1 y2; reflexivity. Qed. Instance: @PreOrder A (=). Proof. split; repeat intro; congruence. Qed. Lemma injective_iff {A B} {R : relation A} {S : relation B} (f : A → B) `{!Injective R S f} `{!Proper (R ==> S) f} x y : S (f x) (f y) ↔ R x y. Lemma inj_iff {A B} {R : relation A} {S : relation B} (f : A → B) `{!Inj R S f} `{!Proper (R ==> S) f} x y : S (f x) (f y) ↔ R x y. Proof. firstorder. Qed. Instance: Injective (=) (=) (@inl A B). Instance: Inj (=) (=) (@inl A B). Proof. injection 1; auto. Qed. Instance: Injective (=) (=) (@inr A B). Instance: Inj (=) (=) (@inr A B). Proof. injection 1; auto. Qed. Instance: Injective2 (=) (=) (=) (@pair A B). Instance: Inj2 (=) (=) (=) (@pair A B). Proof. injection 1; auto. Qed. Instance: ∀ `{Injective2 A B C R1 R2 R3 f} y, Injective R1 R3 (λ x, f x y). Proof. repeat intro; edestruct (injective2 f); eauto. Qed. Instance: ∀ `{Injective2 A B C R1 R2 R3 f} x, Injective R2 R3 (f x). Proof. repeat intro; edestruct (injective2 f); eauto. Qed. Instance: ∀ `{Inj2 A B C R1 R2 R3 f} y, Inj R1 R3 (λ x, f x y). Proof. repeat intro; edestruct (inj2 f); eauto. Qed. Instance: ∀ `{Inj2 A B C R1 R2 R3 f} x, Inj R2 R3 (f x). Proof. repeat intro; edestruct (inj2 f); eauto. Qed. Lemma cancel_injective `{Cancel A B R1 f g} `{!Equivalence R1} `{!Proper (R2 ==> R1) f} : Injective R1 R2 g. Lemma cancel_inj `{Cancel A B R1 f g} `{!Equivalence R1} `{!Proper (R2 ==> R1) f} : Inj R1 R2 g. Proof. intros x y E. rewrite <-(cancel f g x), <-(cancel f g y), E. reflexivity. Qed. Lemma cancel_surjective `{Cancel A B R1 f g} : Surjective R1 f. Lemma cancel_surj `{Cancel A B R1 f g} : Surj R1 f. Proof. intros y. exists (g y). auto. Qed. Lemma impl_transitive (P Q R : Prop) : (P → Q) → (Q → R) → (P → R). Proof. tauto. Qed. Instance: Commutative (↔) (@eq A). Instance: Comm (↔) (@eq A). Proof. red; intuition. Qed. Instance: Commutative (↔) (λ x y, @eq A y x). Instance: Comm (↔) (λ x y, @eq A y x). Proof. red; intuition. Qed. Instance: Commutative (↔) (↔). Instance: Comm (↔) (↔). Proof. red; intuition. Qed. Instance: Commutative (↔) (∧). Instance: Comm (↔) (∧). Proof. red; intuition. Qed. Instance: Associative (↔) (∧). Instance: Assoc (↔) (∧). Proof. red; intuition. Qed. Instance: Idempotent (↔) (∧). Instance: IdemP (↔) (∧). Proof. red; intuition. Qed. Instance: Commutative (↔) (∨). Instance: Comm (↔) (∨). Proof. red; intuition. Qed. Instance: Associative (↔) (∨). Instance: Assoc (↔) (∨). Proof. red; intuition. Qed. Instance: Idempotent (↔) (∨). Instance: IdemP (↔) (∨). Proof. red; intuition. Qed. Instance: LeftId (↔) True (∧). Proof. red; intuition. Qed. ... ... @@ -911,26 +897,26 @@ Instance: LeftId (↔) True impl. Proof. unfold impl. red; intuition. Qed. Instance: RightAbsorb (↔) True impl. Proof. unfold impl. red; intuition. Qed. Lemma not_injective `{Injective A B R R' f} x y : ¬R x y → ¬R' (f x) (f y). Lemma not_inj `{Inj A B R R' f} x y : ¬R x y → ¬R' (f x) (f y). Proof. intuition. Qed. Instance injective_compose {A B C} R1 R2 R3 (f : A → B) (g : B → C) : Injective R1 R2 f → Injective R2 R3 g → Injective R1 R3 (g ∘ f). Instance inj_compose {A B C} R1 R2 R3 (f : A → B) (g : B → C) : Inj R1 R2 f → Inj R2 R3 g → Inj R1 R3 (g ∘ f). Proof. red; intuition. Qed. Instance surjective_compose {A B C} R (f : A → B) (g : B → C) : Surjective (=) f → Surjective R g → Surjective R (g ∘ f). Instance surj_compose {A B C} R (f : A → B) (g : B → C) : Surj (=) f → Surj R g → Surj R (g ∘ f). Proof. intros ?? x. unfold compose. destruct (surjective g x) as [y ?]. destruct (surjective f y) as [z ?]. exists z. congruence. intros ?? x. unfold compose. destruct (surj g x) as [y ?]. destruct (surj f y) as [z ?]. exists z. congruence. Qed. Section sig_map. Context `{P : A → Prop} `{Q : B → Prop} (f : A → B) (Hf : ∀ x, P x → Q (f x)). Definition sig_map (x : sig P) : sig Q := f (`x) ↾ Hf _ (proj2_sig x). Global Instance sig_map_injective: (∀ x, ProofIrrel (P x)) → Injective (=) (=) f → Injective (=) (=) sig_map. Global Instance sig_map_inj: (∀ x, ProofIrrel (P x)) → Inj (=) (=) f → Inj (=) (=) sig_map. Proof. intros ?? [x Hx] [y Hy]. injection 1. intros Hxy. apply (injective f) in Hxy; subst. rewrite (proof_irrel _ Hy). auto. apply (inj f) in Hxy; subst. rewrite (proof_irrel _ Hy). auto. Qed. End sig_map. Arguments sig_map _ _ _ _ _ _ !_ /.
 ... ... @@ -15,13 +15,13 @@ Definition encode_nat `{Countable A} (x : A) : nat := pred (Pos.to_nat (encode x)). Definition decode_nat `{Countable A} (i : nat) : option A := decode (Pos.of_nat (S i)). Instance encode_injective `{Countable A} : Injective (=) (=) encode. Instance encode_inj `{Countable A} : Inj (=) (=) encode. Proof. intros x y Hxy; apply (injective Some). intros x y Hxy; apply (inj Some). by rewrite <-(decode_encode x), Hxy, decode_encode. Qed. Instance encode_nat_injective `{Countable A} : Injective (=) (=) encode_nat. Proof. unfold encode_nat; intros x y Hxy; apply (injective encode); lia. Qed. Instance encode_nat_inj `{Countable A} : Inj (=) (=) encode_nat. Proof. unfold encode_nat; intros x y Hxy; apply (inj encode); lia. Qed. Lemma decode_encode_nat `{Countable A} x : decode_nat (encode_nat x) = Some x. Proof. pose proof (Pos2Nat.is_pos (encode x)). ... ... @@ -70,11 +70,11 @@ Section choice. Definition choice (HA : ∃ x, P x) : { x | P x } := _↾choose_correct HA. End choice. Lemma surjective_cancel `{Countable A} `{∀ x y : B, Decision (x = y)} (f : A → B) `{!Surjective (=) f} : { g : B → A & Cancel (=) f g }. Lemma surj_cancel `{Countable A} `{∀ x y : B, Decision (x = y)} (f : A → B) `{!Surj (=) f} : { g : B → A & Cancel (=) f g }. Proof. exists (λ y, choose (λ x, f x = y) (surjective f y)). intros y. by rewrite (choose_correct (λ x, f x = y) (surjective f y)). exists (λ y, choose (λ x, f x = y) (surj f y)). intros y. by rewrite (choose_correct (λ x, f x = y) (surj f y)). Qed. (** * Instances *) ... ... @@ -197,7 +197,7 @@ Lemma list_encode_app' `{Countable A} (l1 l2 : list A) acc : Proof. revert acc; induction l1; simpl; auto. induction l2 as [|x l IH]; intros acc; simpl; [by rewrite ?(left_id_L _ _)|]. by rewrite !(IH (Nat.iter _ _ _)), (associative_L _), x0_iter_x1. by rewrite !(IH (Nat.iter _ _ _)), (assoc_L _), x0_iter_x1. Qed. Program Instance list_countable `{Countable A} : Countable (list A) := {| encode := list_encode 1; decode := list_decode [] 0 |}. ... ... @@ -211,7 +211,7 @@ Next Obligation. { by intros help l; rewrite help, (right_id_L _ _). } induction l as [|x l IH] using @rev_ind; intros acc; [done|]. rewrite list_encode_app'; simpl; rewrite <-x0_iter_x1, decode_iter; simpl. by rewrite decode_encode_nat; simpl; rewrite IH, <-(associative_L _). by rewrite decode_encode_nat; simpl; rewrite IH, <-(assoc_L _). Qed. Lemma list_encode_app `{Countable A} (l1 l2 : list A) : encode (l1 ++ l2)%list = encode l1 ++ encode l2. ... ...
 ... ... @@ -12,7 +12,7 @@ Proof. firstorder. Qed. Lemma Is_true_reflect (b : bool) : reflect b b. Proof. destruct b. by left. right. intros []. Qed. Instance: Injective (=) (↔) Is_true. Instance: Inj (=) (↔) Is_true. Proof. intros [] []; simpl; intuition. Qed. (** We introduce [decide_rel] to avoid inefficienct computation due to eager ... ...
 ... ... @@ -47,7 +47,7 @@ Lemma error_fmap_bind {S E A B C} (f : A → B) (g : B → error S E C) x s : ((f <\$> x) ≫= g) s = (x ≫= g ∘ f) s. Proof. by compute; destruct (x s) as [|[??]]. Qed. Lemma error_associative {S E A B C} (f : A → error S E B) (g : B → error S E C) x s : Lemma error_assoc {S E A B C} (f : A → error S E B) (g : B → error S E C) x s : ((x ≫= f) ≫= g) s = (a ← x; f a ≫= g) s. Proof. by compute; destruct (x s) as [|[??]]. Qed. Lemma error_of_option_bind {S E A B} (f : A → option B) o e : ... ... @@ -114,7 +114,7 @@ Tactic Notation "error_proceed" := | H : (gets _ ≫= _) _ = _ |- _ => rewrite error_left_gets in H | H : (modify _ ≫= _) _ = _ |- _ => rewrite error_left_modify in H | H : ((_ <\$> _) ≫= _) _ = _ |- _ => rewrite error_fmap_bind in H | H : ((_ ≫= _) ≫= _) _ = _ |- _ => rewrite error_associative in H | H : ((_ ≫= _) ≫= _) _ = _ |- _ => rewrite error_assoc in H | H : (error_guard _ _ _) _ = _ |- _ => let H' := fresh in apply error_guard_ret in H; destruct H as [H' H] | _ => progress simplify_equality' ... ...
 ... ... @@ -108,7 +108,7 @@ Lemma size_union_alt X Y : size (X ∪ Y) = size X + size (Y ∖ X). Proof. rewrite <-size_union by solve_elem_of. setoid_replace (Y ∖ X) with ((Y ∪ X) ∖ X) by solve_elem_of. rewrite <-union_difference, (commutative (∪)); solve_elem_of. rewrite <-union_difference, (comm (∪)); solve_elem_of. Qed. Lemma subseteq_size X Y : X ⊆ Y → size X ≤ size Y. Proof. intros. rewrite (union_difference X Y), size_union_alt by done. lia. Qed. ... ...
 ... ... @@ -820,28 +820,28 @@ Proof. intros ??. apply map_eq. intros. by rewrite !(lookup_merge f), lookup_empty, (right_id_L None f). Qed. Lemma merge_commutative m1 m2 : Lemma merge_comm m1 m2 : (∀ i, f (m1 !! i) (m2 !! i) = f (m2 !! i) (m1 !! i)) → merge f m1 m2 = merge f m2 m1. Proof. intros. apply map_eq. intros. by rewrite !(lookup_merge f). Qed. Global Instance: Commutative (=) f → Commutative (=) (merge f). Global Instance: Comm (=) f → Comm (=) (merge f). Proof. intros ???. apply merge_commutative. intros. by apply (commutative f). intros ???. apply merge_comm. intros. by apply (comm f). Qed. Lemma merge_associative m1 m2 m3 : Lemma merge_assoc m1 m2 m3 : (∀ i, f (m1 !! i) (f (m2 !! i) (m3 !! i)) = f (f (m1 !! i) (m2 !! i)) (m3 !! i)) → merge f m1 (merge f m2 m3) = merge f (merge f m1 m2) m3. Proof. intros. apply map_eq. intros. by rewrite !(lookup_merge f). Qed. Global Instance: Associative (=) f → Associative (=) (merge f). Global Instance: Assoc (=) f → Assoc (=) (merge f). Proof. intros ????. apply merge_associative. intros. by apply (associative_L f). intros ????. apply merge_assoc. intros. by apply (assoc_L f). Qed. Lemma merge_idempotent m1 : Lemma merge_idemp m1 : (∀ i, f (m1 !! i) (m1 !! i) = m1 !! i) → merge f m1 m1 = m1. Proof. intros. apply map_eq. intros. by rewrite !(lookup_merge f). Qed. Global Instance: Idempotent (=) f → Idempotent (=) (merge f). Proof. intros ??. apply merge_idempotent. intros. by apply (idempotent f). Qed. Global Instance: IdemP (=) f → IdemP (=) (merge f). Proof. intros ??. apply merge_idemp. intros. by apply (idemp f). Qed. End merge. Section more_merge. ... ... @@ -1033,19 +1033,19 @@ Global Instance: LeftId (@eq (M A)) ∅ (union_with f). Proof. unfold union_with, map_union_with. apply _. Qed. Global Instance: RightId (@eq (M A)) ∅ (union_with f). Proof. unfold union_with, map_union_with. apply _. Qed. Lemma union_with_commutative m1 m2 : Lemma union_with_comm m1 m2 : (∀ i x y, m1 !! i = Some x → m2 !! i = Some y → f x y = f y x) → union_with f m1 m2 = union_with f m2 m1. Proof. intros. apply (merge_commutative _). intros i. intros. apply (merge_comm _). intros i. destruct (m1 !! i) eqn:?, (m2 !! i) eqn:?; simpl; eauto. Qed. Global Instance: Commutative (=) f → Commutative (@eq (M A)) (union_with f). Proof. intros ???. apply union_with_commutative. eauto. Qed. Lemma union_with_idempotent m : Global Instance: Comm (=) f → Comm (@eq (M A)) (union_with f). Proof. intros ???. apply union_with_comm. eauto. Qed. Lemma union_with_idemp m : (∀ i x, m !! i = Some x → f x x = Some x) → union_with f m m = m. Proof. intros. apply (merge_idempotent _). intros i. intros. apply (merge_idemp _). intros i. destruct (m !! i) eqn:?; simpl; eauto. Qed. Lemma alter_union_with (g : A → A) m1 m2 i : ... ... @@ -1100,14 +1100,14 @@ End union_with. (** ** Properties of the [union] operation *) Global Instance: LeftId (@eq (M A)) ∅ (∪) := _. Global Instance: RightId (@eq (M A)) ∅ (∪) := _. Global Instance: Associative (@eq (M A)) (∪). Global Instance: Assoc (@eq (M A)) (∪). Proof. intros A m1 m2 m3. unfold union, map_union, union_with, map_union_with. apply (merge_associative _). intros i. apply (merge_assoc _). intros i. by destruct (m1 !! i), (m2 !! i), (m3 !! i). Qed. Global Instance: Idempotent (@eq (M A)) (∪). Proof. intros A ?. by apply union_with_idempotent. Qed. Global Instance: IdemP (@eq (M A)) (∪). Proof. intros A ?. by apply union_with_idemp. Qed. Lemma lookup_union_Some_raw {A} (m1 m2 : M A) i x : (m1 ∪ m2) !! i = Some x ↔ m1 !! i = Some x ∨ (m1 !! i = None ∧ m2 !! i = Some x). ... ... @@ -1140,9 +1140,9 @@ Proof. intro. rewrite lookup_union_Some_raw; intuition. Qed. Lemma lookup_union_Some_r {A} (m1 m2 : M A) i x : m1 ⊥ₘ m2 → m2 !! i = Some x → (m1 ∪ m2) !! i = Some x. Proof. intro. rewrite lookup_union_Some; intuition. Qed. Lemma map_union_commutative {A} (m1 m2 : M A) : m1 ⊥ₘ m2 → m1 ∪ m2 = m2 ∪ m1. Lemma map_union_comm {A} (m1 m2 : M A) : m1 ⊥ₘ m2 → m1 ∪ m2 = m2 ∪ m1. Proof. intros Hdisjoint. apply (merge_commutative (union_with (λ x _, Some x))). intros Hdisjoint. apply (merge_comm (union_with (λ x _, Some x))). intros i. specialize (Hdisjoint i). destruct (m1 !! i), (m2 !! i); compute; naive_solver. Qed. ... ... @@ -1160,7 +1160,7 @@ Proof. Qed. Lemma map_union_subseteq_r {A} (m1 m2 : M A) : m1 ⊥ₘ m2 → m2 ⊆ m1 ∪ m2. Proof. intros. rewrite map_union_commutative by done. by apply map_union_subseteq_l. intros. rewrite map_union_comm by done. by apply map_union_subseteq_l. Qed. Lemma map_union_subseteq_l_alt {A} (m1 m2 m3 : M A) : m1 ⊆ m2 → m1 ⊆ m2 ∪ m3. Proof. intros. transitivity m2; auto using map_union_subseteq_l. Qed. ... ... @@ -1175,7 +1175,7 @@ Qed. Lemma map_union_preserving_r {A} (m1 m2 m3 : M A) : m2 ⊥ₘ m3 → m1 ⊆ m2 → m1 ∪ m3 ⊆ m2 ∪ m3. Proof. intros. rewrite !(map_union_commutative _ m3) intros. rewrite !(map_union_comm _ m3) by eauto using map_disjoint_weaken_l. by apply map_union_preserving_l. Qed. ... ... @@ -1189,19 +1189,19 @@ Qed. Lemma map_union_reflecting_r {A} (m1 m2 m3 : M A) : m1 ⊥ₘ m3 → m2 ⊥ₘ m3 → m1 ∪ m3 ⊆ m2 ∪ m3 → m1 ⊆ m2. Proof. intros ??. rewrite !(map_union_commutative _ m3) by done. intros ??. rewrite !(map_union_comm _ m3) by done. by apply map_union_reflecting_l. Qed. Lemma map_union_cancel_l {A} (m1 m2 m3 : M A) : m1 ⊥ₘ m3 → m2 ⊥ₘ m3 → m3 ∪ m1 = m3 ∪ m2 → m1 = m2. Proof. intros. apply (anti_symmetric (⊆)); intros. apply (anti_symm (⊆)); apply map_union_reflecting_l with m3; auto using (reflexive_eq (R:=(⊆))). Qed. Lemma map_union_cancel_r {A} (m1 m2 m3 : M A) : m1 ⊥ₘ m3 → m2 ⊥ₘ m3 → m1 ∪ m3 = m2 ∪ m3 → m1 = m2. Proof. intros. apply (anti_symmetric (⊆)); intros. apply (anti_symm (⊆)); apply map_union_reflecting_r with m3; auto using (reflexive_eq (R:=(⊆))). Qed. Lemma map_disjoint_union_l {A} (m1 m2 m3 : M A) : ... ... @@ -1231,7 +1231,7 @@ Qed. Lemma insert_union_singleton_r {A} (m : M A) i x : m !! i = None → <[i:=x]>m = m ∪ {[i ↦ x]}. Proof. intro. rewrite insert_union_singleton_l, map_union_commutative; [done |]. intro. rewrite insert_union_singleton_l, map_union_comm; [done |]. by apply map_disjoint_singleton_l. Qed. Lemma map_disjoint_insert_l {A} (m1 m2 : M A) i x : ... ... @@ -1254,12 +1254,12 @@ Lemma map_disjoint_insert_r_2 {A} (m1 m2 : M A) i x : Proof. by rewrite map_disjoint_insert_r. Qed. Lemma insert_union_l {A} (m1 m2 : M A) i x : <[i:=x]>(m1 ∪ m2) = <[i:=x]>m1 ∪ m2. Proof. by rewrite !insert_union_singleton_l, (associative_L (∪)). Qed. Proof. by rewrite !insert_union_singleton_l, (assoc_L (∪)). Qed. Lemma insert_union_r {A} (m1 m2 : M A) i x : m1 !! i = None → <[i:=x]>(m1 ∪ m2) = m1 ∪ <[i:=x]>m2. Proof. intro. rewrite !insert_union_singleton_l, !(associative_L (∪)). rewrite (map_union_commutative m1); [done |]. intro. rewrite !insert_union_singleton_l, !(assoc_L (∪)). rewrite (map_union_comm m1); [done |]. by apply map_disjoint_singleton_r. Qed. Lemma foldr_insert_union {A} (m : M A) l : ... ...
 ... ... @@ -71,27 +71,27 @@ Proof. unfold card; intros. destruct finA as [[|x ?] ??]; simpl in *; [exfalso;lia|]. constructor; exact x. Qed. Lemma finite_injective_contains `{finA: Finite A} `{finB: Finite B} (f: A → B) `{!Injective (=) (=) f} : f <\$> enum A `contains` enum B. Lemma finite_inj_contains `{finA: Finite A} `{finB: Finite B} (f: A → B) `{!Inj (=) (=) f} : f <\$> enum A `contains` enum B. Proof. intros. destruct finA, finB. apply NoDup_contains; auto using NoDup_fmap_2. Qed. Lemma finite_injective_Permutation `{Finite A} `{Finite B} (f : A → B) `{!Injective (=) (=) f} : card A = card B → f <\$> enum A ≡ₚ enum B. Lemma finite_inj_Permutation `{Finite A} `{Finite B} (f : A → B) `{!Inj (=) (=) f} : card A = card B → f <\$> enum A ≡ₚ enum B. Proof. intros. apply contains_Permutation_length_eq. * by rewrite fmap_length. * by apply finite_injective_contains. * by apply finite_inj_contains. Qed. Lemma finite_injective_surjective `{Finite A} `{Finite B} (f : A → B) `{!Injective (=) (=) f} : card A = card B → Surjective (=) f. Lemma finite_inj_surj `{Finite A} `{Finite B} (f : A → B) <