Skip to content
Snippets Groups Projects
Commit 9f0ae13d authored by Robbert Krebbers's avatar Robbert Krebbers
Browse files

Improve "choosing an element" of a finite collection.

parent c699fda3
No related branches found
No related tags found
No related merge requests found
...@@ -6,6 +6,7 @@ principles on finite collections . *) ...@@ -6,6 +6,7 @@ principles on finite collections . *)
Require Import Permutation ars. Require Import Permutation ars.
Require Export collections numbers listset. Require Export collections numbers listset.
Definition choose `{Elements A C} (X : C) : option A := head (elements X).
Instance collection_size `{Elements A C} : Size C := length elements. Instance collection_size `{Elements A C} : Size C := length elements.
Definition collection_fold `{Elements A C} {B} Definition collection_fold `{Elements A C} {B}
(f : A B B) (b : B) : C B := foldr f b elements. (f : A B B) (b : B) : C B := foldr f b elements.
...@@ -26,9 +27,8 @@ Proof. intros ?? E. apply Permutation_length. by rewrite E. Qed. ...@@ -26,9 +27,8 @@ Proof. intros ?? E. apply Permutation_length. by rewrite E. Qed.
Lemma size_empty : size ( : C) = 0. Lemma size_empty : size ( : C) = 0.
Proof. Proof.
unfold size, collection_size. simpl. unfold size, collection_size. simpl.
rewrite (elem_of_nil_inv (elements )). rewrite (elem_of_nil_inv (elements )); [done |].
* done. intro. rewrite <-elements_spec. solve_elem_of.
* intro. rewrite <-elements_spec. solve_elem_of.
Qed. Qed.
Lemma size_empty_inv (X : C) : size X = 0 X ∅. Lemma size_empty_inv (X : C) : size X = 0 X ∅.
Proof. Proof.
...@@ -52,41 +52,44 @@ Qed. ...@@ -52,41 +52,44 @@ Qed.
Lemma size_singleton_inv X x y : size X = 1 x X y X x = y. Lemma size_singleton_inv X x y : size X = 1 x X y X x = y.
Proof. Proof.
unfold size, collection_size. simpl. rewrite !elements_spec. unfold size, collection_size. simpl. rewrite !elements_spec.
generalize (elements X). intros [|? l]. generalize (elements X). intros [|? l]; intro; simplify_equality.
* done. rewrite (nil_length l), !elem_of_list_singleton by done. congruence.
* injection 1. intro. rewrite (nil_length l) by done.
simpl. rewrite !elem_of_list_singleton. congruence.
Qed. Qed.
Lemma choose_Some X x : choose X = Some x x X.
Proof.
unfold choose. destruct (elements X) eqn:E; intros; simplify_equality.
rewrite elements_spec, E. by left.
Qed.
Lemma choose_None X : choose X = None X ∅.
Proof.
unfold choose. destruct (elements X) eqn:E; intros; simplify_equality.
apply equiv_empty. intros x. by rewrite elements_spec, E, elem_of_nil.
Qed.
Lemma elem_of_or_empty X : ( x, x X) X ∅. Lemma elem_of_or_empty X : ( x, x X) X ∅.
Proof. destruct (choose X) eqn:?; eauto using choose_Some, choose_None. Qed.
Lemma choose_is_Some X : X is_Some (choose X).
Proof. Proof.
destruct (elements X) as [|x xs] eqn:E. rewrite is_Some_alt. destruct (choose X) eqn:?.
* right. apply equiv_empty. intros x Ex. * rewrite elem_of_equiv_empty. split; eauto using choose_Some.
by rewrite elements_spec, E, elem_of_nil in Ex. * split. intros []; eauto using choose_None. by intros [??].
* left. exists x. rewrite elements_spec, E.
by constructor.
Qed. Qed.
Lemma not_elem_of_equiv_empty X : X ( x, x X).
Lemma choose X : X x, x X.
Proof. Proof.
destruct (elem_of_or_empty X) as [[x ?]|?]. destruct (elem_of_or_empty X) as [?|E]; [esolve_elem_of |].
* by exists x. setoid_rewrite E. setoid_rewrite elem_of_empty. naive_solver.
* done.
Qed. Qed.
Lemma size_pos_choose X : 0 < size X x, x X. Lemma size_pos_elem_of X : 0 < size X x, x X.
Proof. Proof.
intros E1. apply choose. intros E1. apply not_elem_of_equiv_empty. intros E2.
intros E2. rewrite E2, size_empty in E1. rewrite E2, size_empty in E1. lia.
by apply (Lt.lt_n_0 0).
Qed. Qed.
Lemma size_1_choose X : size X = 1 x, X {[ x ]}. Lemma size_1_elem_of X : size X = 1 x, X {[ x ]}.
Proof. Proof.
intros E. destruct (size_pos_choose X). intros E. destruct (size_pos_elem_of X); auto with lia.
* rewrite E. auto with arith. exists x. apply elem_of_equiv. split.
* exists x. apply elem_of_equiv. split. * rewrite elem_of_singleton. eauto using size_singleton_inv.
+ intro. rewrite elem_of_singleton. * solve_elem_of.
eauto using size_singleton_inv.
+ solve_elem_of.
Qed. Qed.
Lemma size_union X Y : X Y size (X Y) = size X + size Y. Lemma size_union X Y : X Y size (X Y) = size X + size Y.
...@@ -111,16 +114,12 @@ Global Program Instance collection_subseteq_dec_slow (X Y : C) : ...@@ -111,16 +114,12 @@ Global Program Instance collection_subseteq_dec_slow (X Y : C) :
| right E1 => right _ | right E1 => right _
end. end.
Next Obligation. Next Obligation.
intros x Ex; apply dec_stable; intro. intros x Ex; apply dec_stable; intro. destruct (proj1 (elem_of_empty x)).
destruct (proj1 (elem_of_empty x)). apply (size_empty_inv _ E1). by rewrite elem_of_difference.
apply (size_empty_inv _ E1).
by rewrite elem_of_difference.
Qed. Qed.
Next Obligation. Next Obligation.
intros E2. destruct E1. intros E2. destruct E1. apply size_empty_iff, equiv_empty. intros x.
apply size_empty_iff, equiv_empty. intros x. rewrite elem_of_difference. intros [E3 ?]. by apply E2 in E3.
rewrite elem_of_difference. intros [E3 ?].
by apply E2 in E3.
Qed. Qed.
Lemma size_union_alt X Y : size (X Y) = size X + size (Y X). Lemma size_union_alt X Y : size (X Y) = size X + size (Y X).
...@@ -131,9 +130,7 @@ Proof. ...@@ -131,9 +130,7 @@ Proof.
Qed. Qed.
Lemma subseteq_size X Y : X Y size X size Y. Lemma subseteq_size X Y : X Y size X size Y.
Proof. Proof. intros. rewrite (union_difference X Y), size_union_alt by done. lia. Qed.
intros. rewrite (union_difference X Y), size_union_alt by done. lia.
Qed.
Lemma subset_size X Y : X Y size X < size Y. Lemma subset_size X Y : X Y size X < size Y.
Proof. Proof.
intros. rewrite (union_difference X Y) by solve_elem_of. intros. rewrite (union_difference X Y) by solve_elem_of.
...@@ -147,9 +144,7 @@ Proof. apply well_founded_lt_compat with size, subset_size. Qed. ...@@ -147,9 +144,7 @@ Proof. apply well_founded_lt_compat with size, subset_size. Qed.
Lemma collection_ind (P : C Prop) : Lemma collection_ind (P : C Prop) :
Proper (() ==> iff) P Proper (() ==> iff) P
P P ( x X, x X P X P ({[ x ]} X)) X, P X.
( x X, x X P X P ({[ x ]} X))
X, P X.
Proof. Proof.
intros ? Hemp Hadd. apply well_founded_induction with (). intros ? Hemp Hadd. apply well_founded_induction with ().
{ apply collection_wf. } { apply collection_wf. }
...@@ -180,11 +175,7 @@ Lemma collection_fold_proper {B} (R : relation B) `{!Equivalence R} ...@@ -180,11 +175,7 @@ Lemma collection_fold_proper {B} (R : relation B) `{!Equivalence R}
(f : A B B) (b : B) `{!Proper ((=) ==> R ==> R) f} (f : A B B) (b : B) `{!Proper ((=) ==> R ==> R) f}
(Hf : a1 a2 b, R (f a1 (f a2 b)) (f a2 (f a1 b))) : (Hf : a1 a2 b, R (f a1 (f a2 b)) (f a2 (f a1 b))) :
Proper (() ==> R) (collection_fold f b). Proper (() ==> R) (collection_fold f b).
Proof. Proof. intros ?? E. apply (foldr_permutation R f b); auto. by rewrite E. Qed.
intros ?? E. apply (foldr_permutation R f b).
* auto.
* by rewrite E.
Qed.
Global Instance set_Forall_dec `(P : A Prop) Global Instance set_Forall_dec `(P : A Prop)
`{ x, Decision (P x)} X : Decision (set_Forall P X) | 100. `{ x, Decision (P x)} X : Decision (set_Forall P X) | 100.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment