(****************************************************************************** Finite orbit-stabilizer theorem.  Based on proof from Rahbar Virk's notes from the University of Wisconsin (www.math.wisc.edu/~virk/notes/pdf/orphans/orbit-stabilizer_thm.pdf) Copyright 2008 Robert Kam  This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.  This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.  You should have received a copy of the GNU Lesser General Public License along with this program.  If not, see <http://www.gnu.org/licenses/>. ******************************************************************************)
From Algebra Require Export Group_util.
From Algebra Require Export Fpart2.
From Algebra Require Export Parts3.
From Algebra Require Export Fmap.
From LinAlg Require Export seq_set_facts.
From LinAlg Require Export has_n_elements.
From LinAlg Require Export finite_subsets.
Require Export ClassicalDescription.
Fixpoint nsum (n:Nat) {struct n} : seq n Nat -> Nat :=
match n return (seq n Nat -> Nat) with
|O => fun x:seq 0 Nat => 0
|S m => fun x:seq (S m) Nat => (head x) + (nsum m (Seqtl x)) end.
induction n. intros. simpl. auto.
intros. unfold nsum. fold nsum.
assert (HEADHEAD:head f = head f'). unfold head. apply H.
rewrite HEADHEAD.
assert (TLTL:nsum n (Seqtl f) =' nsum n (Seqtl f')). apply IHn.
change (Seqtl f =' Seqtl f' in _). apply Seqtl_comp. exact H.
rewrite TLTL. apply Refl. Qed.
intros. rewrite H. apply Refl. Qed.
intros. induction n. elimtype False; intuition.
unfold nsum in |- *. fold nsum in |- *.
elim (classic (i =' Build_finiteT (lt_O_Sn n) in _)).
intro I_ZERO.
assert (P1 : head (modify_seq v i a) =' a in _).
apply Trans with (head (modify_seq v (Build_finiteT (lt_O_Sn n)) a)).
apply head_comp. apply modify_comp. apply Refl. apply Refl. exact I_ZERO.
apply modify_hd_hd.
rewrite P1.
assert (P2 : nsum n (Seqtl (modify_seq v i a)) =' nsum n (Seqtl v) in _).
apply nsum_comp.
apply Trans with (Seqtl (modify_seq v (Build_finiteT (lt_O_Sn n)) a)).
change (Seqtl (modify_seq v i a)
=' Seqtl (modify_seq v (Build_finiteT (lt_O_Sn n)) a) in _) in |- *.
apply Seqtl_comp. apply modify_comp. apply Refl. apply Refl. exact I_ZERO.
change (Seqtl (modify_seq v (Build_finiteT (lt_O_Sn n)) a)
=' Seqtl v in _) in |- *. apply modify_hd_tl.
rewrite P2.
rewrite H.
assert (P3 : v i =' head v in _).
unfold head in |- *. apply Map_compatible_prf. exact I_ZERO.
rewrite P3.
rewrite plus_comm. rewrite plus_permute. rewrite plus_assoc. apply Refl.
intro I_NZ.
assert (P4 : head (modify_seq v i a) =' head v in _).
destruct i.
assert (H''' : S (pred index) < S n).
induction index. elimtype False; intuition. auto.
apply Trans with (head (modify_seq v (Build_finiteT H''') a)).
apply head_comp. apply modify_comp. apply Refl. apply Refl. simpl in |- *.
induction index. elimtype False; intuition. auto.
apply modify_tl_hd.
rewrite P4.
assert(P10:nsum n (Seqtl(modify_seq v i a)) =' nsum n (Seqtl v)+1 in _).
destruct i.
assert (H' : pred index < n).
induction index. elimtype False; intuition.
simpl in |- *. apply lt_S_n. exact in_range_prf.
assert (H'' : S (pred index) < S n).
apply lt_n_S. exact H'.
apply Trans with (nsum n (Seqtl (modify_seq v (Build_finiteT H'') a))).
apply nsum_comp.
change (Seqtl (modify_seq v (Build_finiteT in_range_prf) a)
=' Seqtl (modify_seq v (Build_finiteT H'') a) in _) in |- *.
apply Seqtl_comp. apply modify_comp. apply Refl. apply Refl. simpl in |- *.
induction index. elimtype False; intuition. auto.
apply Trans with (nsum n (modify_seq (Seqtl v) (Build_finiteT H') a)).
apply nsum_comp. apply modify_tl_tl with (v := v).
apply IHn.
rewrite H. apply pluscomp2. apply Trans with (v (Build_finiteT H'')).
apply Map_compatible_prf. simpl in |- *.
induction index. elimtype False; intuition. auto.
apply Sym.
change (Seqtl v (Build_finiteT H') =' v (Build_finiteT H'') in _) in |- *.
apply Seqtl_to_seq.
rewrite P10. rewrite plus_assoc. apply Refl. Qed.
induction n. intros v Z. simpl. auto.
intros v Z.
apply Trans with (nsum(S n)(v(Build_finiteT(lt_O_Sn n));;Seqtl v)).
apply nsum_comp. apply conseq_hdtl. unfold nsum. fold nsum.
apply Trans with (head v+nsum n(Seqtl(v(Build_finiteT(lt_O_Sn n));;Seqtl v))).
apply pluscomp2. simpl. unfold head. auto.
apply Trans with (0+nsum n(Seqtl(v(Build_finiteT(lt_O_Sn n));;Seqtl v))).
apply pluscomp2. unfold head. apply Z. rewrite plus_0_l.
apply Trans with (nsum n(Seqtl v)). apply nsum_comp.
change (Seqtl(v(Build_finiteT(lt_O_Sn n));;Seqtl v) =' Seqtl v).
apply Seqtl_comp. apply Sym. apply conseq_hdtl.
apply IHn. destruct i.
apply Trans with (v(Build_finiteT(lt_n_S index n in_range_prf))).
apply (Seqtl_to_seq v). apply Z. Qed.
intros. simpl. unfold Map_eq. intro j. destruct i. destruct j.
rename index into i. rename index0 into j.
rename in_range_prf into iH. rename in_range_prf0 into jH.
elim(classic(i=j)). intro H.
apply Trans with (modify_seq(modify_seq Q(Build_finiteT jH)z)
(Build_finiteT jH) (Q(Build_finiteT jH)) (Build_finiteT jH)).
apply modify_comp. apply Map_compatible_prf. auto.
apply modify_comp. apply Refl. apply Refl. auto. auto.
apply modify_seq_defprop. intro H.
apply Trans with
(modify_seq Q(Build_finiteT iH)z(Build_finiteT jH)).
apply modify_seq_modifies_one_elt. auto.
apply modify_seq_modifies_one_elt. auto. Qed.
intros. elim(classic(i_=' j)).
intro H.
assert(gH':in_part g(minus_part(V i_)(subtype_elt(head AH)))).
apply in_part_comp_r with (modify_seq V i_(minus_part(V i_)
(subtype_elt(head AH)))j). exact gH.
apply Trans with (modify_seq V i_(minus_part(V i_)
(subtype_elt(head AH)))i_).
apply Map_compatible_prf. apply Sym. exact H.
apply modify_seq_defprop.
simpl in gH'. elim gH'. intros gH1 gH2. exact gH2.
intro H.
assert(gH':in_part g(V j)).
apply in_part_comp_r with(modify_seq V i_(minus_part(V i_)
(subtype_elt(head AH)))j). exact gH.
apply modify_seq_modifies_one_elt. unfold not. intro H1.
apply H. apply Sym. exact H1.
unfold not. intro gHEAD. apply H.
apply Vc with (g:=g)(i:=i_)(i':=j). apply (Va j). exact gH'.
apply in_part_comp_l with (subtype_elt(head AH)). exact i_H.
exact gHEAD. exact gH'. Qed.
intros. simpl. unfold eq_part. intro x. split.
intro H. assert(HYP:Pred_fun A x). auto.
set(hx:=Build_subtype(P:=A)(subtype_elt:=x)HYP).
set(M:=Map_to_equal_subsets AH' (set_to_full A)).
elim(has_index(M hx)). intros j jH. simpl. exists j.
apply Trans with (subtype_elt(seq_set AH(M hx))).
simpl. apply Refl. apply subtype_elt_comp. exact jH.
intro H. assert(HYP:Pred_fun (seq_set(Map_embed AH)) x). auto.
set(hx:=Build_subtype(P:=seq_set(Map_embed AH))(subtype_elt:=x)HYP).
elim(has_index hx). intros j jH.
apply in_part_comp_l with (Map_embed AH j).
apply Map_embed_prop.
apply Trans with(seq_set(Map_embed AH)hx). simpl. apply Refl.
exact jH. Qed.
intros. apply seq_set_head_or_tail.
2:exact(P4helpr n G A AH AH' AH'' c V Va Vb Vc V' V'a i_ i_H j g gH).
apply in_part_comp_r with A. 2:exact(P4helprr n G A AH AH' AH'').
elim(classic(i_ =' j)).
intro H.
assert(H1:in_part g(minus_part(V i_)(subtype_elt(head AH)))).
apply in_part_comp_r with
(modify_seq V i_(minus_part(V i_)(subtype_elt(head AH)))j).
exact gH. apply Trans with
(modify_seq V i_(minus_part(V i_)(subtype_elt(head AH)))i_).
apply Map_compatible_prf. apply Sym. exact H.
apply modify_seq_defprop. simpl in H1. elim H1. intros H1a H1b.
apply (Va i_). exact H1a.
intro H.
assert(H1:in_part g(V j)). apply in_part_comp_r with
(modify_seq V i_(minus_part(V i_)(subtype_elt(head AH)))j).
exact gH. apply modify_seq_modifies_one_elt. unfold not.
intro H'. apply H. apply Sym. exact H'. apply(Va j). exact H1.
Qed.
intros. assert(HYP:Pred_fun(seq_set(Seqtl(Map_embed AH)))g). auto.
set(hx:=Build_subtype(P:=seq_set(Seqtl(Map_embed AH)))
(subtype_elt:=g)HYP). elim(has_index hx).
intros j jH. apply in_part_comp_l with ((Map_embed(Seqtl AH))j).
apply Map_embed_prop. apply Trans with (Seqtl(Map_embed AH)j).
exact jH. apply Sym. apply Map_embed_Seqtl. Qed.
intros. assert(gH'':in_part g(seq_set(Map_embed(omit AH
(Build_finiteT(lt_O_Sn n)))))).
apply in_part_comp_r with(seq_set(Map_embed(Seqtl AH))).
apply in_part_comp_r with(seq_set(Seqtl(Map_embed AH))).
exact gH. apply seq_set_comp. apply Sym. apply Map_embed_Seqtl.
apply seq_set_comp. change(Map_embed(Seqtl AH) ='
Map_embed(omit AH(Build_finiteT(lt_O_Sn n)))).
apply Map_embed_comp. apply Sym.
change (omit AH(Build_finiteT(lt_O_Sn n)) =' Seqtl AH).
apply omit_head_is_seqtl. elim gH''. intros j2 j2H.
assert(DORA:~omit AH(Build_finiteT(lt_O_Sn n))j2
=' AH(Build_finiteT(lt_O_Sn n))).
apply distinct_omit_removes_all. exact AH''.
unfold not. intro H. apply DORA. Opaque omit.
simpl. unfold subtype_image_equal. apply Trans with g.
apply Sym. exact j2H. exact H. Qed.
Transparent omit.
intros. elim(Vb g(seqtlobv n G A AH g gH)). intros j jH.
elim(classic(i_ =' j)). intro H. exists i_.
apply in_part_comp_r with(minus_part(V i_)(subtype_elt(head AH))).
2:apply Sym. 2:apply modify_seq_defprop.
simpl. split. apply in_part_comp_r with(V j). exact jH.
apply Map_compatible_prf. apply Sym. exact H.
exact (seq_set_head_or_tail_inv n G A AH AH' AH'' g gH).
intro H. exists j. apply in_part_comp_r with (V j). exact jH.
apply Sym. apply modify_seq_modifies_one_elt. unfold not.
intro H'. apply H. apply Sym. exact H'. Qed.

Lemma P6:forall(n:Nat)(G:Setoid)(A:part_set G)
(AH:seq(S n)A)(AH':full A =' seq_set AH)(AH'':distinct AH)
(c:Nat)(V:seq c(part_set G))
(Va:forall(i:fin c)(g:G),in_part g(V i)->in_part g A)
(Vb:forall(g:G)(H:in_part g A),exists i:fin c,in_part g(V i))
(Vc:forall(g:G)(H:in_part g A)(i i':fin c),
in_part g(V i)->in_part g(V i')->i =' i')
(V':seq c Nat)(V'a:forall(i:fin c),has_n_elements(V' i)(V i))
(i_:fin c)(i_H:in_part (subtype_elt(head AH))(V i_)),
forall(g:G)(H:in_part g (seq_set(Seqtl(Map_embed AH)))),
forall(i i':fin c),
in_part g((modify_seq V i_
(minus_part(V i_)(subtype_elt(head AH)))) i)->
in_part g((modify_seq V i_
(minus_part(V i_)(subtype_elt(head AH)))) i')->
i =' i'.