diff options
| author | Cyril Cohen | 2019-03-21 00:21:09 +0100 |
|---|---|---|
| committer | Cyril Cohen | 2019-06-04 15:20:39 +0200 |
| commit | 3e850fa6f1c37656b8ce019a0ffbed63663557d2 (patch) | |
| tree | 8a0d88d2d22aa4c798a6b8ac9e93c52824215fd1 | |
| parent | bd4300d26ecbb43f7170e8da7eaaff1a13cc70b1 (diff) | |
Fixpoint theorems in finset
| -rw-r--r-- | CHANGELOG_UNRELEASED.md | 5 | ||||
| -rw-r--r-- | mathcomp/ssreflect/finset.v | 138 | ||||
| -rw-r--r-- | mathcomp/ssreflect/ssrnat.v | 3 |
3 files changed, 146 insertions, 0 deletions
diff --git a/CHANGELOG_UNRELEASED.md b/CHANGELOG_UNRELEASED.md index 2826491..26a214d 100644 --- a/CHANGELOG_UNRELEASED.md +++ b/CHANGELOG_UNRELEASED.md @@ -8,6 +8,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## [Unreleased] +### Added + +- Added fixpoint and cofixpoint constructions to `finset`: `fixset`, + `cofixset` and `fix_order`, with a few theorems about them + ### Changed - `eqVneq` lemma is changed from `{x = y} + {x != y}` to diff --git a/mathcomp/ssreflect/finset.v b/mathcomp/ssreflect/finset.v index c01fb39..beac009 100644 --- a/mathcomp/ssreflect/finset.v +++ b/mathcomp/ssreflect/finset.v @@ -72,6 +72,16 @@ From mathcomp Require Import choice fintype finfun bigop. (* comprehension as Coq parsing confuses [x | P] and [E | x]. *) (* minset p A == A is a minimal set satisfying p. *) (* maxset p A == A is a maximal set satisfying p. *) +(* Provided a monotonous function F : {set T} -> {set T}, we get fixpoints *) +(* fixset F := iter #|T| F set0 *) +(* == the least fixpoint of F *) +(* == the minimal set such that F X == X *) +(* fix_order F x == the minimum number of iterations so that *) +(* x is in iter (fix_order F x) F set0 *) +(* funsetC F := fun X => ~: F (~: X) *) +(* cofixset F == the greatest fixpoint of F *) +(* == the maximal set such that F X == X *) +(* := ~: fixset (funsetC F) *) (* We also provide notations A :=: B, A :<>: B, A :==: B, A :!=: B, A :=P: B *) (* that specialize A = B, A <> B, A == B, etc., to {set _}. This is useful *) (* for subtypes of {set T}, such as {group T}, that coerce to {set T}. *) @@ -2213,3 +2223,131 @@ Arguments setCK {T}. Arguments minsetP {T P A}. Arguments maxsetP {T P A}. Prenex Implicits minset maxset. + +Section SetFixpoint. + +Section Least. +Variables (T : finType) (F : {set T} -> {set T}). +Hypothesis (F_mono : {homo F : X Y / X \subset Y}). + +Let n := #|T|. +Let iterF i := iter i F set0. + +Lemma subset_iterS i : iterF i \subset iterF i.+1. +Proof. by elim: i => [| i IHi]; rewrite /= ?sub0set ?F_mono. Qed. + +Lemma subset_iter : {homo iterF : i j / i <= j >-> i \subset j}. +Proof. +by apply: homo_leq => //[? ? ?|]; [apply: subset_trans|apply: subset_iterS]. +Qed. + +Definition fixset := iterF n. + +Lemma fixsetK : F fixset = fixset. +Proof. +suff /'exists_eqP[x /= e]: [exists k : 'I_n.+1, iterF k == iterF k.+1]. + by rewrite /fixset -(subnK (leq_ord x)) /iterF iter_add iter_fix. +apply: contraT; rewrite negb_exists => /forallP /(_ (Ordinal _)) /= neq_iter. +suff iter_big k : k <= n.+1 -> k <= #|iter k F set0|. + by have := iter_big _ (leqnn _); rewrite ltnNge max_card. +elim: k => [|k IHk] k_lt //=; apply: (leq_ltn_trans (IHk (ltnW k_lt))). +by rewrite proper_card// properEneq// subset_iterS neq_iter. +Qed. +Hint Resolve fixsetK. + +Lemma minset_fix : minset [pred X | F X == X] fixset. +Proof. +apply/minsetP; rewrite inE fixsetK eqxx; split=> // X /eqP FXeqX Xsubfix. +apply/eqP; rewrite eqEsubset Xsubfix/=. +suff: fixset \subset iter n F X by rewrite iter_fix. +by rewrite /fixset; elim: n => //= [|m IHm]; rewrite ?sub0set ?F_mono. +Qed. + +Lemma fixsetKn k : iter k F fixset = fixset. +Proof. by rewrite iter_fix. Qed. + +Lemma iter_sub_fix k : iterF k \subset fixset. +Proof. +have [/subset_iter //|/ltnW/subnK<-] := leqP k n; +by rewrite /iterF iter_add fixsetKn. +Qed. + +Lemma fix_order_proof x : x \in fixset -> exists n, x \in iterF n. +Proof. by move=> x_fix; exists n. Qed. + +Definition fix_order (x : T) := + if (x \in fixset) =P true isn't ReflectT x_fix then 0 + else (ex_minn (fix_order_proof x_fix)). + +Lemma fix_order_le_max (x : T) : fix_order x <= n. +Proof. +rewrite /fix_order; case: eqP => //= x_in. +by case: ex_minnP => //= ? ?; apply. +Qed. + +Lemma in_iter_fix_orderE (x : T) : + (x \in iterF (fix_order x)) = (x \in fixset). +Proof. +rewrite /fix_order; case: eqP; last by move=>/negP/negPf->; rewrite inE. +by move=> x_in; case: ex_minnP => m ->; rewrite x_in. +Qed. + +Lemma fix_order_gt0 (x : T) : (fix_order x > 0) = (x \in fixset). +Proof. +rewrite /fix_order; case: eqP => [x_in|/negP/negPf->//]. +by rewrite x_in; case: ex_minnP => -[|m]; rewrite ?inE//= => _; apply. +Qed. + +Lemma fix_order_eq0 (x : T) : (fix_order x == 0) = (x \notin fixset). +Proof. by rewrite -fix_order_gt0 -ltnNge ltnS leqn0. Qed. + +Lemma in_iter_fixE (x : T) k : (x \in iterF k) = (0 < fix_order x <= k). +Proof. +rewrite /fix_order; case: eqP => //= [x_in|/negP xNin]; last first. + by apply: contraNF xNin; apply/subsetP/iter_sub_fix. +case: ex_minnP => -[|m]; rewrite ?inE// => xm mP. +by apply/idP/idP=> [/mP//|lt_mk]; apply: subsetP xm; apply: subset_iter. +Qed. + +Lemma in_iter (x : T) k : x \in fixset -> fix_order x <= k -> x \in iterF k. +Proof. by move=> x_in xk; rewrite in_iter_fixE fix_order_gt0 x_in xk. Qed. + +Lemma notin_iter (x : T) k : k < fix_order x -> x \notin iterF k. +Proof. by move=> k_le; rewrite in_iter_fixE negb_and orbC -ltnNge k_le. Qed. + +Lemma fix_order_small x k : x \in iterF k -> fix_order x <= k. +Proof. by rewrite in_iter_fixE => /andP[]. Qed. + +Lemma fix_order_big x k : x \in fixset -> x \notin iterF k -> fix_order x > k. +Proof. by move=> x_in; rewrite in_iter_fixE fix_order_gt0 x_in /= -ltnNge. Qed. + +Lemma le_fix_order (x y : T) : y \in iterF (fix_order x) -> + fix_order y <= fix_order x. +Proof. exact: fix_order_small. Qed. + +End Least. + +Section Greatest. +Variables (T : finType) (F : {set T} -> {set T}). +Hypothesis (F_mono : {homo F : X Y / X \subset Y}). + +Definition funsetC X := ~: (F (~: X)). +Lemma funsetC_mono : {homo funsetC : X Y / X \subset Y}. +Proof. by move=> *; rewrite subCset setCK F_mono// subCset setCK. Qed. +Hint Resolve funsetC_mono. + +Definition cofixset := ~: fixset funsetC. + +Lemma cofixsetK : F cofixset = cofixset. +Proof. by rewrite /cofixset -[in RHS]fixsetK ?setCK. Qed. + +Lemma maxset_cofix : maxset [pred X | F X == X] cofixset. +Proof. +rewrite maxminset setCK. +rewrite (@minset_eq _ _ [pred X | funsetC X == X]) ?minset_fix//. +by move=> X /=; rewrite (can2_eq setCK setCK). +Qed. + +End Greatest. + +End SetFixpoint. diff --git a/mathcomp/ssreflect/ssrnat.v b/mathcomp/ssreflect/ssrnat.v index ad44d3b..5b667f0 100644 --- a/mathcomp/ssreflect/ssrnat.v +++ b/mathcomp/ssreflect/ssrnat.v @@ -826,6 +826,9 @@ Proof. by elim: n => //= n ->. Qed. Lemma eq_iter f f' : f =1 f' -> forall n, iter n f =1 iter n f'. Proof. by move=> eq_f n x; elim: n => //= n ->; rewrite eq_f. Qed. +Lemma iter_fix n f x : f x = x -> iter n f x = x. +Proof. by move=> fixf; elim: n => //= n ->. Qed. + Lemma eq_iteri f f' : f =2 f' -> forall n, iteri n f =1 iteri n f'. Proof. by move=> eq_f n x; elim: n => //= n ->; rewrite eq_f. Qed. |
