QRC1.Preamble
From mathcomp Require Import all_ssreflect finmap.
Set Implicit Arguments.
Unset Strict Implicit.
Unset Printing Implicit Defensive.
Section bigop.
Variables (T : eqType) (F : T -> nat) (w : seq T).
Lemma leq_bigmax_list (j : T) : j \in w -> F j <= \max_(i <- w) F i.
Proof. by move=> /seq_tnthP [n ->]; rewrite big_tnth leq_bigmax. Qed.
Lemma bigmax_leqP_list (m : nat) :
reflect {in w, forall i, F i <= m} (\max_(i <- w) F i <= m).
Proof.
rewrite big_tnth; apply: (iffP idP).
by move=> /bigmax_leqP => /= H x /seq_tnthP [i ->]; apply: H.
move=> H; apply/bigmax_leqP => /= i _.
by have /H := mem_tnth i (in_tuple w).
Qed.
End bigop.
Section finmap.
Open Scope fset.
Variables (T K V : choiceType) (f : K -> V).
Lemma fset_seq1 (A : T) :
[fset A] = [:: A] :> seq T.
Proof.
apply: perm_small_eq => //.
apply: uniq_perm => //.
by move=> B; rewrite 2!inE.
Qed.
Lemma fsetmap1 (k : K) : [fset f k' | k' in [fset k]] = [fset f k].
Proof.
apply/fsetP => k'; apply/imfsetP/fset1P => /=.
by move=> [k'' /fset1P ->].
by move=> ->; exists k; rewrite ?in_fsetE.
Qed.
Lemma fsetmapU (K1 K2 : {fset K}) :
[fset f k | k in K1 `|` K2] = [fset f k | k in K1] `|` [fset f k | k in K2].
Proof.
apply/fsetP => v; apply/imfsetP/fsetUP => /=.
move=> [k /fsetUP [kinK1 -> | kinK2 ->]].
by left; apply/imfsetP; exists k.
by right; apply/imfsetP; exists k.
move=> [|] /imfsetP /= [k].
by move=> kinK1 ->; exists k => //; rewrite inE kinK1.
by move=> kinK2 ->; exists k => //; rewrite inE kinK2 orbT.
Qed.
Lemma fsetmap2 (k1 k2 : K) :
[fset f k' | k' in [fset k1; k2]] = [fset f k1; f k2].
Proof. by rewrite fsetmapU 2!fsetmap1. Qed.
Lemma fsetmap_bigfcup (F : T -> {fset K}) (ts : {fset T}) :
[fset f k | k in \bigcup_(t <- ts) F t] =
\bigcup_(t <- ts) [fset f k | k in F t].
Proof.
apply/fsetP => v.
apply/imfsetP/bigfcupP => /=.
move=> [k /bigfcupP [t tintsT kinFt] ->].
exists t => //.
by apply/imfsetP => /=; exists k.
move=> [t tintsT /imfsetP /= [k kinFt ->]].
exists k => //=.
by apply/bigfcupP; exists t.
Qed.
End finmap.
Open Scope fset.
Lemma all_fsetU {T : choiceType} a (A B : {fset T}) :
all a (A `|` B) = (all a A) && (all a B).
Proof.
apply/allP/andP.
move=> allAUB; split; apply/allP.
by move=> x xinA; apply: allAUB; rewrite inE xinA.
by move=> x xinB; apply: allAUB; rewrite inE xinB orbT.
move=> [/allP allA /allP allB] x /fsetUP [xinA | xinB].
by apply: allA.
by apply: allB.
Qed.
Close Scope fset.
Section BigComFSet.
Variable (R : Type) (idx : R) (op : Monoid.com_law idx).
Variable (I J : choiceType).
Local Open Scope fset.
Lemma big_fsetU (A B : {fset I}) (F : I -> R) : idempotent op ->
\big[op/idx]_(i <- (A `|` B)) F i
= op (\big[op/idx]_(i <- A) F i) (\big[op/idx]_(i <- B) F i).
Proof.
move=> idop.
rewrite eq_big_imfset //= big_map.
rewrite big_undup //.
by rewrite big_cat.
Qed.
End BigComFSet.
Set Implicit Arguments.
Unset Strict Implicit.
Unset Printing Implicit Defensive.
Section bigop.
Variables (T : eqType) (F : T -> nat) (w : seq T).
Lemma leq_bigmax_list (j : T) : j \in w -> F j <= \max_(i <- w) F i.
Proof. by move=> /seq_tnthP [n ->]; rewrite big_tnth leq_bigmax. Qed.
Lemma bigmax_leqP_list (m : nat) :
reflect {in w, forall i, F i <= m} (\max_(i <- w) F i <= m).
Proof.
rewrite big_tnth; apply: (iffP idP).
by move=> /bigmax_leqP => /= H x /seq_tnthP [i ->]; apply: H.
move=> H; apply/bigmax_leqP => /= i _.
by have /H := mem_tnth i (in_tuple w).
Qed.
End bigop.
Section finmap.
Open Scope fset.
Variables (T K V : choiceType) (f : K -> V).
Lemma fset_seq1 (A : T) :
[fset A] = [:: A] :> seq T.
Proof.
apply: perm_small_eq => //.
apply: uniq_perm => //.
by move=> B; rewrite 2!inE.
Qed.
Lemma fsetmap1 (k : K) : [fset f k' | k' in [fset k]] = [fset f k].
Proof.
apply/fsetP => k'; apply/imfsetP/fset1P => /=.
by move=> [k'' /fset1P ->].
by move=> ->; exists k; rewrite ?in_fsetE.
Qed.
Lemma fsetmapU (K1 K2 : {fset K}) :
[fset f k | k in K1 `|` K2] = [fset f k | k in K1] `|` [fset f k | k in K2].
Proof.
apply/fsetP => v; apply/imfsetP/fsetUP => /=.
move=> [k /fsetUP [kinK1 -> | kinK2 ->]].
by left; apply/imfsetP; exists k.
by right; apply/imfsetP; exists k.
move=> [|] /imfsetP /= [k].
by move=> kinK1 ->; exists k => //; rewrite inE kinK1.
by move=> kinK2 ->; exists k => //; rewrite inE kinK2 orbT.
Qed.
Lemma fsetmap2 (k1 k2 : K) :
[fset f k' | k' in [fset k1; k2]] = [fset f k1; f k2].
Proof. by rewrite fsetmapU 2!fsetmap1. Qed.
Lemma fsetmap_bigfcup (F : T -> {fset K}) (ts : {fset T}) :
[fset f k | k in \bigcup_(t <- ts) F t] =
\bigcup_(t <- ts) [fset f k | k in F t].
Proof.
apply/fsetP => v.
apply/imfsetP/bigfcupP => /=.
move=> [k /bigfcupP [t tintsT kinFt] ->].
exists t => //.
by apply/imfsetP => /=; exists k.
move=> [t tintsT /imfsetP /= [k kinFt ->]].
exists k => //=.
by apply/bigfcupP; exists t.
Qed.
End finmap.
Open Scope fset.
Lemma all_fsetU {T : choiceType} a (A B : {fset T}) :
all a (A `|` B) = (all a A) && (all a B).
Proof.
apply/allP/andP.
move=> allAUB; split; apply/allP.
by move=> x xinA; apply: allAUB; rewrite inE xinA.
by move=> x xinB; apply: allAUB; rewrite inE xinB orbT.
move=> [/allP allA /allP allB] x /fsetUP [xinA | xinB].
by apply: allA.
by apply: allB.
Qed.
Close Scope fset.
Section BigComFSet.
Variable (R : Type) (idx : R) (op : Monoid.com_law idx).
Variable (I J : choiceType).
Local Open Scope fset.
Lemma big_fsetU (A B : {fset I}) (F : I -> R) : idempotent op ->
\big[op/idx]_(i <- (A `|` B)) F i
= op (\big[op/idx]_(i <- A) F i) (\big[op/idx]_(i <- B) F i).
Proof.
move=> idop.
rewrite eq_big_imfset //= big_map.
rewrite big_undup //.
by rewrite big_cat.
Qed.
End BigComFSet.