Module infotheo.lib.ssr_ext
From Coq Require Import NArith.From mathcomp Require Import all_ssreflect fingroup perm.
From mathcomp Require Import unstable mathcomp_extra.
Require Import Coq.NArith.BinNatDef.
Declare Scope tuple_ext_scope.
Declare Scope vec_ext_scope.
Notation "t '!_' i" := (tnth t i) (at level 9) : tuple_ext_scope.
Reserved Notation "A `* B" (at level 46, left associativity).
Reserved Notation "A :+: B" (at level 52, left associativity).
Set Implicit Arguments.
Set SsrOldRewriteGoalsOrder.
Unset Strict Implicit.
Import Prenex Implicits.
Lemma compfid A B (f : A -> B) : f \o idfun = f
Proof.
Section ssrbool_ext.
Lemma addb_tri_ine (a b c : bool) : a (+) b <= (a (+) c) + (c (+) b).
Proof.
End ssrbool_ext.
Section ssrnat_ext.
Lemma nat_of_pos_not_0 : forall p, nat_of_pos p <> O.
Proof.
contradict H.
rewrite /= NatTrec.doubleE in H.
apply/eqP; rewrite -double_eq0; by apply/eqP.
Qed.
Lemma nat_of_pos_inj : forall i j, nat_of_pos i = nat_of_pos j -> i = j.
Proof.
- move=> j /= [] /eqP.
by rewrite !NatTrec.doubleE -!muln2 eqn_mul2r /= => /eqP/Hi ->.
- move=> j /=.
rewrite !NatTrec.doubleE => Hj.
have absurd : odd ((nat_of_pos j).*2) by rewrite -Hj /= odd_double.
by rewrite odd_double in absurd.
- rewrite /= NatTrec.doubleE.
case => Habsurd.
exfalso.
move: (@nat_of_pos_not_0 i).
by destruct (nat_of_pos i).
- move=> j /=.
rewrite !NatTrec.doubleE => Hj.
have absurd : odd ((nat_of_pos i).*2) by rewrite Hj /= odd_double.
by rewrite odd_double in absurd.
- move=> j /= /eqP.
by rewrite !NatTrec.doubleE -!muln2 eqn_mul2r /= => /eqP/Hi ->.
- rewrite /= NatTrec.doubleE => absurd.
exfalso.
move: (@nat_of_pos_not_0 i).
by destruct (nat_of_pos i).
destruct j => //=;
rewrite NatTrec.doubleE => absurd ;
exfalso ;
move: (@nat_of_pos_not_0 j) => H' ;
by destruct (nat_of_pos j).
Qed.
Lemma bin_of_nat_inj : forall a b, bin_of_nat a = bin_of_nat b -> a = b.
Proof.
have : nat_of_bin (bin_of_nat a) = nat_of_bin (bin_of_nat b) by rewrite X.
by rewrite 2!bin_of_natK.
Qed.
Lemma bin_of_nat_nat_of_pos_not_0 : forall i, bin_of_nat (nat_of_pos i) <> 0%num.
Proof.
Local Lemma nat_of_mul_bin b1 b2 : (b1 * b2)%num = b1 * b2 :> nat.
Proof.
Lemma bin_of_nat_expn2 m : bin_of_nat (expn 2 m.+1) = BinNat.N.mul 2%num (bin_of_nat (expn 2 m)).
Proof.
Lemma Nto_natE x : BinNat.N.to_nat x = nat_of_bin x.
Proof.
Lemma BinPos_nat_of_P_nat_of_pos : forall i, BinPos.nat_of_P i = nat_of_pos i.
Proof.
Lemma nat_of_posK k : bin_of_nat (nat_of_pos k) = BinNat.Npos k.
Proof.
End ssrnat_ext.
Section Flatten.
Variables (A B : eqType) (f : A -> seq B).
Lemma flatten_single x l :
uniq l -> x \in l -> (forall y, y \in l -> y != x -> f y = [::]) ->
flatten (map f l) = f x.
Proof.
move: Hx.
rewrite in_cons => /orP [/eqP|] Hx.
suff ->: flatten (map f l) = [::].
by rewrite cats0 Hx.
apply/nilP; rewrite /nilp size_flatten sumnE !big_map big_seq big1 //.
move=> i Hi; apply/eqP/nilP/Hy.
- by rewrite in_cons Hi orbT.
- by subst x; apply: contra Hal => /eqP <-.
rewrite Hy //=.
- apply: IH => // y Hyl; apply: Hy.
by rewrite in_cons Hyl orbT.
- by apply: mem_head.
- by apply: contra Hal => /eqP ->.
Qed.
Lemma uniq_flatten_map x y l :
has (mem (f x)) (f y) ->
uniq (flatten (map f l)) -> x \in l -> y \in l -> x = y.
Proof.
elim: l => // a l IH.
rewrite !in_cons /= cat_uniq => /andP/proj2/andP[Hun1 Hun2] /orP[] Hx /orP[] Hy.
- by rewrite (eqP Hx) (eqP Hy).
- move/hasP: Hun1; elim.
exists b.
apply/flattenP.
by exists (f y) => //; exact/map_f.
by rewrite -(eqP Hx).
- move/hasP: Hun1; elim.
exists b.
apply/flattenP.
by exists (f x) => //; exact/map_f.
by rewrite -(eqP Hy).
- by apply: IH.
Qed.
Lemma subseq_flatten (f' : A -> seq B) l :
(forall x, x \in l -> subseq (f x) (f' x)) ->
subseq (flatten (map f l)) (flatten (map f' l)).
Proof.
rewrite cat_subseq //.
by apply: Hl; rewrite in_cons eqxx.
by apply: IH => x Hx; apply: Hl; rewrite in_cons Hx orbT.
Qed.
End Flatten.
Section seq_ext.
Variables A B : Type.
Implicit Types l : seq A.
Lemma zip_swap : forall l (k : seq B),
zip l k = map swap (zip k l).
Proof.
Lemma sumn_big_addn s : sumn s = \sum_ ( i <- s ) i.
Proof.
Lemma count_sumn (p : B -> bool) (l : seq B) :
sumn (map (nat_of_bool \o p) l) = count p l.
Proof.
by rewrite IH.
Qed.
Lemma drop_take_iota a b c : a <= b <= c ->
drop a (take b (iota 0 c)) = [seq n <- iota 0 c | a <= n < b].
Proof.
set f := fun n => a <= n < b.
rewrite -(subnKC bc) iotaD take_cat size_iota subnn take0 add0n (ltnn b) cats0 filter_cat.
rewrite (_ : filter f (iota b (c-b)) = [::]) ; last first.
apply/eqP/negPn ; rewrite -has_filter ; apply/hasPn => l.
rewrite mem_iota (subnKC bc) /f negb_and => /andP [bl _].
by rewrite -leqNgt bl orbT.
rewrite cats0 -(subnKC ab) iotaD drop_cat size_iota subnn drop0 add0n (ltnn a) filter_cat.
rewrite (_ : filter f (iota 0 a) = [::]) ; last first.
apply/eqP/negPn ; rewrite -has_filter ; apply/hasPn => l.
rewrite mem_iota /f negb_and add0n => /andP [_ H].
by rewrite -ltnNge H orTb.
rewrite cat0s.
apply/esym/all_filterP/allP => l.
by rewrite mem_iota /f (subnKC ab).
Qed.
Lemma zip_mask : forall bs l (k : seq B),
zip (mask bs l) (mask bs k) = mask bs (zip l k).
Proof.
Variable a : A.
Lemma map_nth_iota_id l : map (nth a l) (iota 0 (size l)) = l.
Proof.
Lemma nseq_S : forall n, nseq n.+1 a = rcons (nseq n a) a.
Proof.
Lemma rev_nseq : forall n, rev (nseq n a) = nseq n a.
Lemma nseq_cat l l' n : l ++ l' = nseq n a -> l' = nseq (n - size l) a.
Proof.
End seq_ext.
Section Pad.
Variables (A : Type) (a : A).
Implicit Types s t : seq A.
Definition
pad_seqR not a defined object.
if size s <= n then s ++ nseq (n - size s) a else take n s.
Lemma size_pad_seqR s n : size (pad_seqR s n) = n.
Proof.
Lemma pad_seqR_size s n : size s = n -> pad_seqR s n = s.
Definition
pad_seqL not a defined object.
if size s <= n then nseq (n - size s) a ++ s else take n s.
Lemma pad_seqL_inj n s t : size s = n -> size t = n ->
pad_seqL s n = pad_seqL t n -> s = t.
Proof.
Lemma size_pad_seqL n s : size (pad_seqL s n) = n.
Proof.
End Pad.
Section seq_eqType_ext.
Lemma eq_in_map_seqs {A B : eqType} (f1 f2 : A -> B) l1 l2 :
l1 = l2 -> {in l1, f1 =1 f2} -> map f1 l1 = map f2 l2.
Proof.
Variables A B : eqType.
Lemma take_index (a : A) s : a \notin take (index a s) s.
Lemma sorted_of_nth (r : rel A) s (r_trans : transitive r) (r_sorted : sorted r s) :
forall x0 a b, a < b < size s -> r (nth x0 s a) (nth x0 s b).
Proof.
set f := nth a0 s.
have Has : a < size s by exact/(leq_ltn_trans _ Hbs)/ltnW.
have H : subseq [:: f a ; f b] s.
rewrite -(map_nth_iota_id a0 s) (_ : [:: f a; f b] = map f [:: a ; b]) //.
apply: map_subseq.
rewrite -(subnK Has) addnC iotaD add0n (_ : [:: a; b] = [::a] ++ [::b]) //.
apply: cat_subseq; rewrite sub1seq mem_iota.
- by rewrite add0n leq0n ltnSn.
- by rewrite Hab subnKC.
by case/andP : (subseq_sorted r_trans H r_sorted).
Qed.
Lemma sorted_cat (l k : seq A) (r : @rel A) :
sorted r l -> sorted r k ->
(forall a, a \in l -> forall b, b \in k -> r a b) ->
sorted r (l ++ k).
Proof.
Lemma sorted_is_flattened leT (Htrans : transitive leT)
(Hanti : antisymmetric leT) (Hrefl : reflexive leT) :
forall n (l k : seq A), n = size l -> uniq l -> sorted leT l ->
sorted leT k -> {subset k <= l} ->
k = flatten (map (fun elt => filter (pred1 elt) k) l).
Proof.
destruct k => //.
exfalso.
move: (H s).
by rewrite !inE eqxx orTb in_nil => /(_ isT).
move=> n0 IH [|hd tl] // v [lst_sz] lst_uniq lst_sorted v_sorted Hincl.
have X1 : v = filter (pred1 hd) v ++ filter (predC (pred1 hd)) v.
apply: (@sorted_eq _ leT) => //.
- apply: sorted_cat.
+ exact: sorted_filter.
+ exact: sorted_filter.
+ move=> a.
rewrite mem_filter => /andP[/= /eqP ?]; subst hd => av b.
rewrite mem_filter => /andP[/= ba /Hincl].
rewrite inE => /orP[|].
* move/eqP => ?; by subst b.
* move=> btl.
rewrite /sorted in lst_sorted.
have /= := @subseq_path _ _ Htrans a [:: b] tl.
rewrite andbT.
by apply => //; rewrite sub1seq.
- by rewrite perm_sym; apply/permEl/perm_filterC.
rewrite {1}X1 {X1} /=.
congr (_ ++ _).
move: lst_uniq => /= /andP[hdtl tl_uniq].
rewrite (IH tl (filter (predC (pred1 hd)) v) lst_sz tl_uniq).
- congr flatten.
apply/eq_in_map => i i_tl.
rewrite -filter_predI.
apply: eq_in_filter => j j_v /=.
case/boolP: (j == i) => ij //=.
apply/negP => /eqP ?; subst j.
move/eqP : ij => ?; subst i.
by rewrite i_tl in hdtl.
- destruct tl => //=.
by case/andP : lst_sorted.
- exact: sorted_filter.
- move=> i.
rewrite mem_filter /= => /andP[ihd] /Hincl.
by rewrite inE => /orP[|//]; rewrite (negbTE ihd).
Qed.
Lemma filter_zip_L m (l : seq A) (k : seq B) a :
size l = m -> size k = m ->
filter (fun x => x.1 == a) (zip l k) =
zip (filter (pred1 a) l) (mask (map (pred1 a) l) k).
Proof.
rewrite filter_mask [in RHS]filter_mask zip_mask; congr mask.
elim: m l k Hl Hk a => [[] // [] //|n ih].
move=> [|a1 a2] // [|b1 b2] // [sza2] [szb2] a /=; by rewrite ih.
Qed.
Lemma filter_zip_R m (l : seq A) (k : seq B) b :
size l = m -> size k = m ->
filter (fun x => x.2 == b) (zip l k) =
zip (mask (map (pred1 b) k) l) (filter (pred1 b) k).
Proof.
rewrite filter_mask [in RHS]filter_mask zip_mask; congr mask.
elim: m l k Hl Hk b => [[] // [] // | n ih].
move=> [|a1 a2] // [|b1 b2] // [sza2] [szb2] b /=; by rewrite ih.
Qed.
Lemma undup_filter (P : pred B) l : undup (filter P l) = filter P (undup l).
Proof.
- case/boolP: (h \in t) => ht.
+ by rewrite mem_filter Ph ht.
+ by rewrite mem_filter (negbTE ht) andbF /= Ph IH.
- rewrite IH; case: ifPn => //= ?; by rewrite (negbTE Ph).
Qed.
Lemma undup_perm (f : A -> B) p h t : undup (map f p) = h :: t ->
exists p1 : seq A, exists p2 : seq A,
perm_eq p (p1 ++ p2) /\ undup (map f p1) = [:: h] /\ undup (map f p2) = t.
Proof.
split.
- apply/permPl => x; rewrite -(perm_filterC (preim f (pred1 h)) p).
apply/permPl : x.
rewrite perm_cat2l (@eq_in_filter _ _ [pred x | f x \in t]) //= => x X.
case/boolP: (f x == h) => [/eqP ->|/negbTE fxh] /=; apply/esym.
+ by have /andP[/negbTE] : uniq (h :: t) by rewrite -p_t; apply: undup_uniq.
+ have : f x \in h :: t by rewrite -p_t mem_undup; apply/mapP; exists x.
rewrite in_cons => /orP[|->//]; by rewrite fxh.
- split.
+ rewrite -filter_map undup_filter p_t /= eqxx; congr cons.
rewrite -(filter_pred0 t); apply: eq_in_filter => i it /=.
apply/negP => /eqP X; subst h.
have : uniq (i :: t) by rewrite -p_t; exact: undup_uniq.
rewrite /= => /andP[]; by rewrite it.
+ rewrite -filter_map undup_filter p_t /= ifF; last first.
apply/negP => X.
have : uniq (h :: t) by rewrite -p_t undup_uniq.
by rewrite /= X.
rewrite -[RHS](filter_predT t); exact: eq_in_filter.
Qed.
End seq_eqType_ext.
Section seq_bool.
Lemma addb_nseq b : forall r v, size v = r ->
[seq x.1 (+) x.2 | x <- zip (nseq r b) v] = map (pred1 (negb b)) v.
Proof.
rewrite {}IH //; move: b h; by case; case.
Qed.
Definition
addb_seq not a defined object.
Lemma addb_seq_com : forall n a b, size a = n -> size b = n ->
addb_seq a b = addb_seq b a.
Proof.
Lemma addb_seq_cat a b c d : size a = size c ->
addb_seq (a ++ b) (c ++ d) = addb_seq a c ++ addb_seq b d.
Lemma addb_seq_map A : forall n (a b : seq A) f,
size a = n -> size b = n ->
addb_seq (map f a) (map f b) = map (fun x => f x.1 (+) f x.2) (zip a b).
Proof.
End seq_bool.
Section finfun_ext.
Lemma inj_card (A B : finType) (f : {ffun A -> B}) :
injective f -> #| A | <= #| B |.
Proof.
End finfun_ext.
Lemma bij_swap A B : bijective (@swap A B).
Arguments bij_swap {A B}.
Section finset_ext.
Implicit Types A B : finType.
Lemma injective_swap (A B : finType) (E : {set A * B}) : {in E &, injective swap}.
Proof.
Lemma set_swap (A B : finType) (P : B -> A -> bool) :
[set h : {: B * A} | P h.1 h.2 ] = swap @: [set h | P h.2 h.1].
Proof.
Lemma setT_bool : [set: bool] = [set true; false].
Proof.
Lemma setDUKl A (E F : {set A}) : (E :|: F) :\: E = F :\: E.
Lemma setDIlW (T : finType) (A B C : {set T}) :
A :&: B :\: C = A :&: B :\: C :&: B.
Lemma setIDACW (T : finType) (A B C : {set T}) :
(A :\: B) :&: C = A :&: C :\: B :&: C.
Lemma setDAC (T : finType) (A B C : {set T}) :
A :\: B :\: C = A :\: C :\: B.
Lemma setU_setUD A (E F : {set A}) : E :|: F = F :|: E :\: F.
Proof.
Lemma seq_index_enum_card A : forall s (E : {set A}) a,
s =i enum E -> uniq s -> a \in E -> index a s < #| E |.
Proof.
exact: enum_rank_subproof aE.
case: ifPn => [_|hi]; first by rewrite card_gt0; apply/set0Pn; exists a.
apply: (@leq_ltn_trans #|E :\ h|); last first.
by rewrite (cardsD1 h E) -mem_enum -htE mem_head add1n.
apply: IH.
- move=> j; case/boolP : (j \in enum (E :\ h)).
+ rewrite mem_enum in_setD1 => /andP[/negbTE H].
by rewrite -mem_enum -htE in_cons H.
+ rewrite mem_enum in_setD1 negb_and negbK => /orP[/eqP ->{j}|].
- by move: uniqht => /= /andP[/negbTE].
- by rewrite -mem_enum -htE inE negb_or => /andP[_ /negbTE].
- move: uniqht; by case/andP.
- apply/setD1P; by rewrite eq_sym.
Qed.
Local Notation "A `* B" := (setX A B).
Lemma setX1 A B (a : A) (b : B) : [set a] `* [set b] = [set (a, b)].
Lemma setX1r (A B : finType) (E : {set A}) (b : B) :
E `* [set b] = [set (a, b) | a in E].
Proof.
Lemma setX0 (A B : finType) (E : {set A}) : E `* set0 = set0 :> {set A * B}.
Proof.
Lemma set0X (A B : finType) (F : {set B}) : set0 `* F = set0 :> {set A * B}.
Proof.
Lemma setIX (A B : finType) (E E' : {set A}) (F F' : {set B}) :
E `* F :&: E' `* F' = (E :&: E') `* (F :&: F').
Proof.
Lemma setCX (A B : finType) (E : {set A}) :
~: E `* setT = ~: (E `* setT) :> {set A * B}.
Lemma setTX (A B : finType) : setT `* setT = setT :> {set A * B}.
Lemma cardsltn1P A (E : {set A}) :
(1 < #| E |) = [exists a, exists b, [&& (a \in E), (b \in E) & (a != b)]].
Proof.
rewrite cards0; apply/esym/negbTE.
rewrite negb_exists; apply/forallP => a.
rewrite negb_exists; apply/forallP => b; by rewrite !inE.
case/boolP : (E :\ a == set0) => [/eqP Ea0 | ].
have -> : E = [set a] by apply/eqP; rewrite -(setD1K Ha) Ea0 setU0.
rewrite cards1; apply/esym/negbTE.
rewrite negb_exists; apply/forallP => b.
rewrite negb_exists; apply/forallP => c.
rewrite 2!in_set1 2!negb_and negbK.
case/boolP : (b == c) => [_|bc]; first by rewrite !orbT.
rewrite orbF.
case/boolP : (b == a) => //= /eqP <-; by rewrite eq_sym.
case/set0Pn => b Hb.
have -> : 1 < #| E | by rewrite (cardsD1 a E) Ha /= (cardsD1 b (E :\ a)) Hb.
apply/esym; apply/existsP; exists a; apply/existsP; exists b.
by rewrite !inE eq_sym andbC in Hb; rewrite Hb Ha.
Qed.
Lemma cards2P (A : finType) (E : {set A}) :
(#| E | == 2) = [exists a, exists b, (E == [set a; b]) && (a != b)].
Proof.
by move/existsP => -[a /existsP[b /andP[/eqP -> ab]]]; rewrite cards2 ab.
move: (s2) => /eqP/esym/eq_leq.
rewrite cardsltn1P => /existsP[a /existsP[b /and3P[aE bE ab]]].
apply/existsP; exists a; apply/existsP; exists b; rewrite ab andbT; apply/eqP.
rewrite -(setD1K aE) -(setD1K bE); apply/setP => i; rewrite !inE.
have [/eqP->{i} //|/= ia] := boolP (i == a).
have [/eqP->{i} //|/= ib] := boolP (i == b).
apply/negbTE/negP => iE.
move/eqP : s2; rewrite (cardsD1 a) aE add1n => -[].
rewrite (cardD1 b) !inE eq_sym ab bE add1n => -[].
by rewrite (cardD1 i) !inE ib ia iE add1n.
Qed.
Lemma set1_set2 A (E : {set A}) a :
a \in E -> E != set1 a -> exists i, (i \in E) && (i != a).
Proof.
Lemma set2_set1 A (E : {set A}) a :
(exists i, (i \in E) && (i != a)) -> E != set1 a.
Definition
fin_img not a defined object.
Lemma fin_img_imset (A B : finType) (f : A -> B) : fin_img f =i f @: A.
Proof.
- by case/existsP => a /eqP ->; rewrite imset_f.
- rewrite negb_exists; move/forallP=> bfx.
case/mapP => a _ bfa.
by move: (bfx a); rewrite bfa => /eqP.
- by case/existsP => a /eqP -> _; apply/mapP; exists a; rewrite // mem_enum.
- rewrite negb_exists; move/forallP=> bfx.
case/imsetP => a _ bfa.
by move: (bfx a); rewrite bfa => /eqP.
Qed.
Lemma imset_preimset (I J : finType) (h : I -> J) (B : {set J}) :
B \subset h @: I -> h @: (h @^-1: B) = B.
Proof.
Section more_preimset.
Context {R : Type}.
Variables (aT1 aT2 aT3 rT1 rT2 rT3 : finType).
Variables (f : aT1 -> rT1) (g : aT2 -> rT2) (h : aT3 -> rT3).
Variables (A : {set rT1}) (B : {set rT2}) (C : {set rT3}).
Local Notation "f × g" :=
(fun xy => (f xy.1, g xy.2)) (at level 10).
Lemma preimsetX : f × g @^-1: (A `* B) = f @^-1: A `* g @^-1: B.
Lemma preimsetX2 :
h × (f × g) @^-1: (C `* (A `* B)) = h @^-1: C `* (f @^-1: A `* g @^-1: B).
Lemma in_preimset x (Y : {set rT1}) : (x \in f @^-1: Y) = (f x \in Y).
Proof.
Lemma in_preimset1 x y : (x \in f @^-1: [set y]) = (f x == y).
Proof.
End more_preimset.
Lemma imsetPn {aT rT : finType} {f : aT -> rT} {D : mem_pred aT} {y : rT} :
reflect (forall x : aT, in_mem x D -> y != f x) (y \notin imset f D).
Proof.
Lemma big_set2 (R : Type) (idx : R) (op : Monoid.com_law idx) (I : finType)
(a b : I) (F : I -> R) :
a != b -> \big[op/idx]_(i in [set a; b]) F i = op (F a) (F b).
Definition
setY : forall {T : Type}, set T -> set T -> set T setY is not universe polymorphic Arguments setY {T}%type_scope (A B)%classical_set_scope _ / The reduction tactics unfold setY when applied to 4 arguments setY is transparent Expands to: Constant mathcomp.classical.classical_sets.setY Declared in library mathcomp.classical.classical_sets, line 371, characters 11-15
Notation "A :+: B" := (setY A B).
Section setY_lemmas.
Variable (T : finType).
Local Notation "+%S" := (@setY T).
Local Notation "-%S" := idfun.
Local Notation "0" := (@set0 T).
Lemma setYA : associative +%S.
Proof.
Lemma set0Y : left_id 0 +%S.
Lemma setNY : left_inverse 0 -%S +%S.
Lemma setIYl : left_distributive (@setI T) +%S.
Lemma setIUY (A B : {set T}) :
(A :+: B) :|: (A :&: B) = A :|: B.
Lemma setIYI_disj (A B : {set T}) :
[disjoint (A :+: B) & (A :&: B)].
Proof.
End setY_lemmas.
End finset_ext.
Notation "A `* B" := (setX A B) : set_scope.
Notation "A :+: B" := (setY A B).
Module Set2.
Section set2.
Variable A : finType.
Hypothesis A2 : #|A| = 2%nat.
Definition
Set2.a not a defined object.
Definition
Set2.b not a defined object.
Lemma enumE : enum A = a :: b :: [::].
Proof.
Lemma a_neq_b : a != b.
Proof.
Lemma neq_a_b x : x != a -> x == b.
Lemma ind (P : A -> Type) : P a -> P b -> forall a, P a.
Lemma E : setT = [set a; b].
Proof.
End set2.
End Set2.
Section tuple_ext.
Variable A : Type.
Local Open Scope tuple_ext_scope.
Lemma tcast2tval m n (H : m = n) :
forall (v : m.-tuple A) (w : n.-tuple A), tcast H v = w -> tval v = tval w.
Proof.
Lemma tcast_take_inj n m k (H : minn n k = m) (nk : n = k) (t v : k.-tuple A) :
tcast H [tuple of take n t] = tcast H [tuple of take n v] -> t = v.
Proof.
Lemma eq_tcast n m (v : m.-tuple A) (H : m = n) : tval (tcast H v) = v.
Proof.
Lemma tnth_zip_1 (B : finType) n (x1 : n.-tuple A) (x2 : n.-tuple B) i:
(tnth [tuple of zip x1 x2] i).1 = tnth x1 i.
Proof.
rewrite nth_zip /=; last by rewrite !size_tuple.
apply: set_nth_default; by rewrite size_tuple.
Qed.
Lemma tnth_zip_2 (B : finType) n (x1 : n.-tuple A) (x2 : n.-tuple B) i:
(tnth [tuple of zip x1 x2] i).2 = tnth x2 i.
Proof.
rewrite nth_zip /=; last by rewrite !size_tuple.
apply: set_nth_default; by rewrite size_tuple.
Qed.
Lemma thead_tuple1 : forall (i : 1.-tuple A), [tuple thead i] = i.
Proof.
Definition
tbehead not a defined object.
Lemma sorted_of_tnth {C : eqType} (r : rel C) k (t : k.-tuple C) :
transitive r -> sorted r t -> forall a b : 'I_k, a < b -> r (t !_ a) (t !_ b).
Proof.
rewrite (tnth_nth t!_b) {2}(tnth_nth t!_b).
apply: sorted_of_nth => //; by rewrite ab size_tuple /=.
Qed.
Lemma sorted_of_tnth_leq (X : finType) (n : nat) (r : rel X) (t : n.-tuple X)
(r_trans : transitive r) (r_refl : reflexive r) (Hx : sorted r t) :
forall (l p : 'I_n), l <= p -> r t!_l t!_p.
Proof.
case/boolP : (l == p) => Hcase.
- move/eqP in Hcase; rewrite Hcase; apply: r_refl.
- apply: sorted_of_tnth => //; by rewrite ltn_neqAle leqlp Hcase.
Qed.
Lemma sort_tuple_subproof (X : eqType) n (r : rel X) (t : n.-tuple X) :
size (sort r t) == n.
Proof.
Definition
sort_tuple : forall [n : nat] [T : Type], rel T -> n.-tuple T -> n.-tuple T sort_tuple is not universe polymorphic Arguments sort_tuple [n]%nat_scope [T]%type_scope r t sort_tuple is transparent Expands to: Constant mathcomp.boot.tuple.sort_tuple Declared in library mathcomp.boot.tuple, line 237, characters 10-20
Tuple (sort_tuple_subproof r t).
Lemma tnth_uniq (T : eqType) n (t : n.-tuple T) (i j : 'I_n) :
uniq t -> (t !_ i == t !_ j) = (i == j).
Proof.
End tuple_ext.
Section bseq_lemmas.
Variables (n : nat) (T : Type).
Lemma bseqval_inj : injective (@bseqval n T).
Proof.
move: Ha Hb; rewrite H => Ha Hb.
by congr Bseq; exact: eq_irrelevance.
Qed.
Lemma leq_take (s : seq T) k : size s <= n -> size (take k s) <= n.
Definition
bseq_take not a defined object.
End bseq_lemmas.
Section ordered_ranks.
Variable X : finType.
Definition
le_rank not a defined object.
Definition
lt_rank not a defined object.
Lemma lt_rank_alt x y : lt_rank x y = (enum_rank x < enum_rank y).
Proof.
Lemma le_rank_trans : transitive le_rank.
Proof.
Lemma le_rank_refl : reflexive le_rank.
Lemma le_rank_asym : antisymmetric le_rank.
Proof.
Lemma le_rank_total : total le_rank.
Lemma lt_le_rank_trans u v w : lt_rank u v -> le_rank v w -> lt_rank u w.
Proof.
rewrite (le_rank_trans uv vw) /=; apply: contra H => /eqP ?.
subst w; by rewrite (@le_rank_asym u v) // uv.
Qed.
Lemma le_lt_rank_trans u v w : le_rank u v -> lt_rank v w -> lt_rank u w.
Proof.
rewrite (le_rank_trans uv vw) /=; apply: contra H => /eqP ?.
subst w. by rewrite (@le_rank_asym u v) // uv.
Qed.
Lemma lt_le_rank_weak u v : lt_rank u v -> le_rank u v.
Lemma lt_neq_rank u v : lt_rank u v -> u != v.
Lemma sorted_enum : sorted le_rank (enum X).
Proof.
move HX : (enum X) => Alst.
destruct Alst => //.
apply/(pathP s) => i Hi.
rewrite /le_rank -HX.
destruct Alst => //.
have iA : i < #|X| by rewrite cardE HX (ltn_trans Hi).
rewrite -(@enum_val_nth X (xpredT) s (Ordinal iA)).
have i1A : i.+1 < #|X| by rewrite cardE HX (leq_ltn_trans Hi).
have -> : (nth s (s0 :: Alst) i) = (nth s (enum X) i.+1) by rewrite /= HX.
by rewrite -(@enum_val_nth X (xpredT) s (Ordinal i1A)) 2!enum_valK leqnSn.
Qed.
End ordered_ranks.
Section perm_tuples.
Local Open Scope tuple_ext_scope.
Variables (A : eqType) (n : nat) (s : 'S_n).
Definition
perm_tuple not a defined object.
End perm_tuples.
Section perm_tuples_prop.
Lemma tuple_exist_perm_sort (T : eqType) n (r : rel T) (t : n.-tuple T) :
exists s : 'S_n, t = perm_tuple s (sort_tuple r t).
Proof.
have : perm_eq t (sort_tuple r t) by rewrite perm_sym perm_sort perm_refl.
case/tuple_permP => u Hu; exists u.
case: t Hu => t /= Ht Hu.
apply: eq_from_tnth => i /=.
rewrite /tnth /= -Hu.
apply: set_nth_default.
move/eqP : {Hu}Ht => ->; by case: i.
Qed.
Variable A : finType.
Lemma perm_tuple_id n (t : n.-tuple A) : perm_tuple 1 t = t.
Proof.
Definition
perm_tuple_set not a defined object.
perm_tuple s @: E.
Lemma perm_tuple_comp n (s1 s2 : 'S_n) (t : n.-tuple A) :
perm_tuple s1 (perm_tuple s2 t) = perm_tuple (s1 * s2) t.
Proof.
Lemma perm_tuple_inj n (s : 'S_n) : injective (@perm_tuple A n s).
Proof.
have : perm_tuple 1 a = perm_tuple 1 b by rewrite -(mulVg s) -!perm_tuple_comp H.
rewrite !perm_tuple_id; apply.
Qed.
Lemma perm_tuple0 (u : 'S_0) (t : 0.-tuple A) : perm_tuple u t = t.
Proof.
Lemma zip_perm_tuple (B : finType) n (a : n.-tuple A) (b : n.-tuple B) (s : 'S_n) :
zip_tuple (perm_tuple s a) (perm_tuple s b) = perm_tuple s (zip_tuple a b).
Proof.
destruct n as [|n] => //.
case=> [Hi | i Hi].
rewrite (tnth_nth (thead a, thead b)) (tnth_nth (thead (zip_tuple a b))).
rewrite /= enum_ordSl /= (tnth_nth (thead a, thead b)) /= nth_zip; last first.
by rewrite (size_tuple a) (size_tuple b).
by rewrite (tnth_nth (thead a)) /= (tnth_nth (thead b)).
rewrite (tnth_nth (thead a, thead b)) (tnth_nth (thead (zip_tuple a b))) /=.
rewrite enum_ordSl /= nth_zip; last by rewrite 4!size_map size_enum_ord.
rewrite [in RHS](nth_map ord0); last by rewrite size_map size_enum_ord.
rewrite [in RHS](tnth_nth (thead a, thead b)) [in RHS]/zip_tuple /=.
rewrite [in RHS]nth_zip; last by rewrite (size_tuple a) (size_tuple b).
rewrite (nth_map ord0); last by rewrite size_map size_enum_ord.
rewrite (nth_map ord0); last by rewrite size_map size_enum_ord.
by rewrite (tnth_nth (thead a)) (tnth_nth (thead b)).
Qed.
End perm_tuples_prop.
Section perm_enum.
Variable n : nat.
Lemma perm_eq_perm (pe : 'S_n) :
perm_eq (enum 'I_n) [seq pe i | i <- enum 'I_n].
Proof.
Lemma perm_filter_enum_ord j :
perm_eq [seq i <- enum 'I_n.+1 | i != j]
[seq lift j i | i <- enum 'I_n].
Proof.
+ by rewrite filter_uniq // enum_uniq.
+ rewrite map_inj_in_uniq ?enum_uniq //.
by move=> x1 x2 _ _; apply: lift_inj.
move=> k.
rewrite mem_filter mem_enum andbT.
symmetry.
case: (unliftP j k) => /= [a|] ->.
rewrite eq_sym neq_lift.
rewrite mem_map. by rewrite mem_enum inE.
by apply: lift_inj.
rewrite eqxx.
apply/mapP => /= -[x Hx].
move/(f_equal (@nat_of_ord _)).
by apply/eqP/neq_lift.
Qed.
Lemma perm_on_Sn (s : 'S_n) : perm_on [set x | x \in enum 'I_n] s.
End perm_enum.
Section fingraph_ext.
Lemma connect_sym1 (D : finType) (r : rel D) : symmetric r ->
forall x y, connect r x y -> connect r y x.
Proof.
case/connectP => s H1 H2; apply/connectP.
elim/last_ind : s H1 H2 => [|h t _ H1 H2].
rewrite /= => _ ?; subst y; by rewrite eqxx in xy.
rewrite last_rcons in H2; subst t.
move: H1; rewrite rcons_path => /andP[H1 H2].
exists (rcons (rev h) x); last by rewrite last_rcons.
apply/(pathP x) => i.
rewrite size_rcons ltnS leq_eqVlt size_rev.
case/orP => [/eqP|] Hi.
case: h => [|h t] in H1 H2 Hi *.
rewrite /= in H2; by rewrite Hi /= rs.
rewrite Hi nth_rcons size_rev ltnn eqxx /= nth_rcons size_rev /= ltnS leqnn.
rewrite nth_rev // subnn rs /=; by case/andP : H1.
rewrite nth_rcons size_rev Hi -cat1s -cats1 catA cats1.
rewrite nth_rcons /= size_rev ltnS (ltnW Hi) nth_rev // -cat1s nth_cat /=.
case: ifPn.
rewrite ltnS leqn0 => /eqP -> /=; by rewrite subn1 nth_last rs.
rewrite -leqNgt => i0.
rewrite subn1 /= rs nth_rev ?(leq_ltn_trans _ Hi) // ?leq_pred // prednK //.
move/pathP : H1 => /(_ x (size h - i)).
rewrite -cat1s nth_cat /= ifF; last first.
apply/negbTE; by rewrite -leqNgt subn_gt0 (leq_trans _ Hi).
rewrite -subnDA addn1; apply.
by rewrite -{2}(subn0 (size h)) ltn_sub2l // (leq_trans _ Hi).
Qed.
Lemma connect_sym (D : finType) (r : rel D) : symmetric r -> connect_sym r.
Proof.
End fingraph_ext.
Section uniq_path.
Variable A : eqType.
Variable g : rel A.
Definition
uniq_path not a defined object.
Lemma cons_uniq_path a b s :
g a b -> a \notin b :: s -> uniq_path b s -> uniq_path a (b :: s).
Lemma rev_path_rcons a b p :
symmetric g ->
path g a (rcons p b) = path g b (rcons (rev p) a).
Proof.
End uniq_path.
Section boolP.
Variables (p : bool) (R : Type) (T : is_true p -> R) (F : is_true (~~ p) -> R).
Lemma boolPT (H : is_true p) :
match boolP p with
| AltTrue HT => T HT
| AltFalse HF => F HF
end = T H.
Proof.
Lemma boolPF (H : is_true (~~ p)) :
match boolP p with
| AltTrue HT => T HT
| AltFalse HF => F HF
end = F H.
Proof.
Section fintype_extra.
Lemma ord1 (i : 'I_1) : i = ord0
Proof.
Lemma ord2 (i : 'I_2) : (i == ord0) || (i == Ordinal (erefl (1 < 2))).
Proof.
Lemma ord3 (i : 'I_3) :
[|| i == ord0, i == Ordinal (erefl (1 < 3)) | i == Ordinal (erefl (2 < 3))].
Proof.
Lemma enum_inord (m : nat) : enum 'I_m.+1 = [seq inord i | i <- iota 0 m.+1].
Proof.
Lemma split_lshift n m (i : 'I_n) : fintype.split (lshift m i) = inl i.
Lemma split_rshift n m (i : 'I_m) : fintype.split (rshift n i) = inr i.
Lemma size_index_enum (T : finType) : size (index_enum T) = #|T|.
Lemma index_enum_cast_ord n m (e : n = m) :
index_enum 'I_m = [seq cast_ord e i | i <- index_enum 'I_n].
Proof.
apply: eq_map=> [[x xlt]].
by rewrite /cast_ord; congr Ordinal; exact: bool_irrelevance.
Qed.
Lemma perm_map_bij [T : finType] [f : T -> T] (s : seq T) : bijective f ->
perm_eq (index_enum T) [seq f i | i <- index_enum T].
Proof.
rewrite /perm_eq -enumT -forallb_tnth; apply/forallP=>i /=.
case: fbij => g fg gf.
rewrite enumT enumP count_map -size_filter (@eq_in_filter _ _
(pred1 (g (tnth (cat_tuple (enum_tuple T) (map_tuple [eta f] (enum_tuple T))) i)))).
by rewrite size_filter enumP.
by move=> x _ /=; apply/eqP/eqP => [/(congr1 g) <-|->//].
Qed.
End fintype_extra.
Section order_extra.
Lemma eqW {disp : Order.disp_t} {T : porderType disp} (x y : T) :
x = y -> (x <= y)%O.
Proof.
End order_extra.