From 34e58198fcca6ccdd4fe86ab2940f7f630aaaf36 Mon Sep 17 00:00:00 2001 From: Johannes Kloos <jkloos@mpi-sws.org> Date: Tue, 31 Oct 2017 13:11:39 +0100 Subject: [PATCH] Move fresh element generator to infinite. Also make the instances non-global, to prevent multiple instance problems. --- theories/fin_collections.v | 73 +------------------------------------- theories/infinite.v | 72 +++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 72 deletions(-) diff --git a/theories/fin_collections.v b/theories/fin_collections.v index 03363c28..03c27b65 100644 --- a/theories/fin_collections.v +++ b/theories/fin_collections.v @@ -283,76 +283,5 @@ Proof. refine (cast_if (decide (Exists P (elements X)))); by rewrite set_Exists_elements. Defined. - -(** * Fresh elements *) -Section Fresh. - Context `{Infinite A, ∀ (x: A) (s: C), Decision (x ∈ s)}. - - Lemma subset_difference_in {x: A} {s: C} (inx: x ∈ s): s ∖ {[ x ]} ⊂ s. - Proof. set_solver. Qed. - - Definition fresh_generic_body (s: C) (rec: ∀ s', s' ⊂ s → nat → A) (n: nat) := - let cand := inject n in - match decide (cand ∈ s) with - | left H => rec _ (subset_difference_in H) (S n) - | right _ => cand - end. - Lemma fresh_generic_body_proper s (f g: ∀ y, y ⊂ s → nat → A): - (∀ y Hy Hy', pointwise_relation nat eq (f y Hy) (g y Hy')) → - pointwise_relation nat eq (fresh_generic_body s f) (fresh_generic_body s g). - Proof. - intros relfg i. - unfold fresh_generic_body. - destruct decide. - 2: done. - apply relfg. - Qed. - - Definition fresh_generic_fix := Fix collection_wf (const (nat → A)) fresh_generic_body. - - Lemma fresh_generic_fixpoint_unfold s n: - fresh_generic_fix s n = fresh_generic_body s (λ s' _ n, fresh_generic_fix s' n) n. - Proof. - apply (Fix_unfold_rel collection_wf (const (nat → A)) (const (pointwise_relation nat (=))) - fresh_generic_body fresh_generic_body_proper s n). - Qed. - - Lemma fresh_generic_fixpoint_spec s n: - ∃ m, n ≤ m ∧ fresh_generic_fix s n = inject m ∧ inject m ∉ s ∧ ∀ i, n ≤ i < m → inject i ∈ s. - Proof. - revert n. - induction s as [s IH] using (well_founded_ind collection_wf); intro. - setoid_rewrite fresh_generic_fixpoint_unfold; unfold fresh_generic_body. - destruct decide as [case|case]. - - destruct (IH _ (subset_difference_in case) (S n)) as [m [mbound [eqfix [notin inbelow]]]]. - exists m; repeat split; auto. - + omega. - + rewrite not_elem_of_difference, elem_of_singleton in notin. - destruct notin as [?|?%inject_injective]; auto; omega. - + intros i ibound. - destruct (decide (i = n)) as [<-|neq]; auto. - enough (inject i ∈ s ∖ {[inject n]}) by set_solver. - apply inbelow; omega. - - exists n; repeat split; auto. - intros; omega. - Qed. - - Global Instance fresh_generic: Fresh A C | 20 := λ s, fresh_generic_fix s 0. - - Global Instance fresh_generic_spec: FreshSpec A C. - Proof. - split. - - apply _. - - intros * eqXY. - unfold fresh, fresh_generic. - destruct (fresh_generic_fixpoint_spec X 0) as [mX [_ [-> [notinX belowinX]]]]. - destruct (fresh_generic_fixpoint_spec Y 0) as [mY [_ [-> [notinY belowinY]]]]. - destruct (Nat.lt_trichotomy mX mY) as [case|[->|case]]; auto. - + contradict notinX; rewrite eqXY; apply belowinY; omega. - + contradict notinY; rewrite <- eqXY; apply belowinX; omega. - - intro. - unfold fresh, fresh_generic. - destruct (fresh_generic_fixpoint_spec X 0) as [m [_ [-> [notinX belowinX]]]]; auto. - Qed. -End Fresh. End fin_collection. + diff --git a/theories/infinite.v b/theories/infinite.v index dba8a0b9..6ad44409 100644 --- a/theories/infinite.v +++ b/theories/infinite.v @@ -23,6 +23,78 @@ Proof. rewrite !replicate_length in eqrep; done. Qed. +(** * Fresh elements *) +Section Fresh. + Context `{Infinite A, ∀ (x: A) (s: C), Decision (x ∈ s)}. + + Lemma subset_difference_in {x: A} {s: C} (inx: x ∈ s): s ∖ {[ x ]} ⊂ s. + Proof. set_solver. Qed. + + Definition fresh_generic_body (s: C) (rec: ∀ s', s' ⊂ s → nat → A) (n: nat) := + let cand := inject n in + match decide (cand ∈ s) with + | left H => rec _ (subset_difference_in H) (S n) + | right _ => cand + end. + Lemma fresh_generic_body_proper s (f g: ∀ y, y ⊂ s → nat → A): + (∀ y Hy Hy', pointwise_relation nat eq (f y Hy) (g y Hy')) → + pointwise_relation nat eq (fresh_generic_body s f) (fresh_generic_body s g). + Proof. + intros relfg i. + unfold fresh_generic_body. + destruct decide. + 2: done. + apply relfg. + Qed. + + Definition fresh_generic_fix := Fix collection_wf (const (nat → A)) fresh_generic_body. + + Lemma fresh_generic_fixpoint_unfold s n: + fresh_generic_fix s n = fresh_generic_body s (λ s' _ n, fresh_generic_fix s' n) n. + Proof. + apply (Fix_unfold_rel collection_wf (const (nat → A)) (const (pointwise_relation nat (=))) + fresh_generic_body fresh_generic_body_proper s n). + Qed. + + Lemma fresh_generic_fixpoint_spec s n: + ∃ m, n ≤ m ∧ fresh_generic_fix s n = inject m ∧ inject m ∉ s ∧ ∀ i, n ≤ i < m → inject i ∈ s. + Proof. + revert n. + induction s as [s IH] using (well_founded_ind collection_wf); intro. + setoid_rewrite fresh_generic_fixpoint_unfold; unfold fresh_generic_body. + destruct decide as [case|case]. + - destruct (IH _ (subset_difference_in case) (S n)) as [m [mbound [eqfix [notin inbelow]]]]. + exists m; repeat split; auto. + + omega. + + rewrite not_elem_of_difference, elem_of_singleton in notin. + destruct notin as [?|?%inject_injective]; auto; omega. + + intros i ibound. + destruct (decide (i = n)) as [<-|neq]; auto. + enough (inject i ∈ s ∖ {[inject n]}) by set_solver. + apply inbelow; omega. + - exists n; repeat split; auto. + intros; omega. + Qed. + + Instance fresh_generic: Fresh A C | 20 := λ s, fresh_generic_fix s 0. + + Instance fresh_generic_spec: FreshSpec A C. + Proof. + split. + - apply _. + - intros * eqXY. + unfold fresh, fresh_generic. + destruct (fresh_generic_fixpoint_spec X 0) as [mX [_ [-> [notinX belowinX]]]]. + destruct (fresh_generic_fixpoint_spec Y 0) as [mY [_ [-> [notinY belowinY]]]]. + destruct (Nat.lt_trichotomy mX mY) as [case|[->|case]]; auto. + + contradict notinX; rewrite eqXY; apply belowinY; omega. + + contradict notinY; rewrite <- eqXY; apply belowinX; omega. + - intro. + unfold fresh, fresh_generic. + destruct (fresh_generic_fixpoint_spec X 0) as [m [_ [-> [notinX belowinX]]]]; auto. + Qed. +End Fresh. + (** Derive fresh instances. *) Section StringFresh. Context `{FinCollection string C, ∀ (x: string) (s: C), Decision (x ∈ s)}. -- GitLab