Library mathcomp_eulerian.cycles_rec

From mathcomp Require Import all_ssreflect fingroup perm.
From mathcomp_eulerian Require Import ordinal_reindex perm_compress descent cycles.

Set Implicit Arguments.
Unset Strict Implicit.
Unset Printing Implicit Defensive.


Section H1.
Variable n : nat.
Variable s : {perm 'I_n}.

Lemma lift_perm_id_iter i :
  ((perm.lift_perm ord_max ord_max s) ^+ i)%g ord_max = ord_max.
Proof.
elim: i ⇒ [|i IH]; first by rewrite expg0 perm1.
by rewrite expgSr permM IH perm.lift_perm_id.
Qed.

Lemma porbit_lift_perm_id_max :
  porbit (perm.lift_perm ord_max ord_max s) ord_max = [set ord_max].
Proof.
apply/setPy; rewrite !inE.
apply/porbitP/eqP.
- by casei ->; rewrite lift_perm_id_iter.
- by move⇒ ->; 0; rewrite expg0 perm1.
Qed.

Lemma lift_perm_id_iter_lift i (k : 'I_n) :
  ((perm.lift_perm ord_max ord_max s) ^+ i)%g (lift ord_max k)
  = lift ord_max ((s ^+ i)%g k).
Proof.
elim: i k ⇒ [|i IH] k; first by rewrite !expg0 !perm1.
by rewrite !expgSr !permM IH perm.lift_perm_lift.
Qed.

Lemma porbit_lift_perm_id_lift (k : 'I_n) :
  porbit (perm.lift_perm ord_max ord_max s) (lift ord_max k)
  = (lift ord_max) @: (porbit s k).
Proof.
apply/setPy; apply/porbitP/imsetP.
- casei ->; rewrite lift_perm_id_iter_lift.
  by ((s ^+ i)%g k); rewrite // mem_porbit.
- casez /porbitP[i ->] →.
  by i; rewrite lift_perm_id_iter_lift.
Qed.

Lemma porbits_lift_perm_id :
  porbits (perm.lift_perm ord_max ord_max s)
  = ([set [set ord_max] : {set 'I_n.+1}] :|:
     [set (lift ord_max) @: (P : {set 'I_n}) | P in porbits s])%SET.
Proof.
apply/setPP; rewrite !inE.
apply/imsetP/orP.
- casey _ →.
  case: (unliftP ord_max y) ⇒ [k → | ->].
  + right; apply/imsetP.
     (porbit s k); first by apply/imsetP; k.
    by rewrite porbit_lift_perm_id_lift.
  + by left; rewrite porbit_lift_perm_id_max eqxx.
- case.
  + move⇒ /eqP ->; ord_max ⇒ //.
    by rewrite porbit_lift_perm_id_max.
  + case/imsetPQ /imsetP[k _ ->] →.
     (lift ord_max k) ⇒ //.
    by rewrite porbit_lift_perm_id_lift.
Qed.

Lemma cycle_count_lift_perm_id :
  cycle_count (perm.lift_perm ord_max ord_max s) = (cycle_count s).+1.
Proof.
rewrite /cycle_count porbits_lift_perm_id cardsU1.
rewrite (card_imset _ _) /=; last first.
  moveP Q /setP eqfPQ; apply/setPx.
  by have := eqfPQ (lift ord_max x); rewrite !(mem_imset _ _ lift_inj).
have not_in : [set ord_max] \notin
  [set (lift ord_max) @: (P : {set 'I_n}) | P in porbits s].
  apply/imsetP⇒ [[Q QinP /setP HQ]].
  have := HQ ord_max; rewrite inE eqxx /= ⇒ /esym.
  case/imsetPk _ /eqP.
  by rewrite (negbTE (neq_lift _ _)).
by rewrite not_in add1n.
Qed.

End H1.