End square_colouring.
Section cube_colouring.
Definition cube := 'I_6.
Canonical cube_eqType := Eval hnf in [eqType of cube].
Canonical cube_choiceType := Eval hnf in [choiceType of cube].
Canonical cube_countType := Eval hnf in [countType of cube].
Canonical cube_finType := Eval hnf in [finType of cube].
Canonical cube_subType := Eval hnf in [subType of cube].
Canonical cube_subCountType := Eval hnf in [subCountType of cube].
Canonical cube_subFinType := Eval hnf in [subFinType of cube].
Definition mkFcube i : cube := Sub (i %% 6) (ltn_mod i 6).
Definition F0 := mkFcube 0.
Definition F1 := mkFcube 1.
Definition F2 := mkFcube 2.
Definition F3 := mkFcube 3.
Definition F4 := mkFcube 4.
Definition F5 := mkFcube 5.
(* axial symetries*)
Definition S05 := [:: F0; F4; F3; F2; F1; F5].
Definition S05f (sc : cube) : cube := tnth [tuple of S05] sc.
Definition S14 := [:: F5; F1; F3; F2; F4; F0].
Definition S14f (sc : cube) : cube := tnth [tuple of S14] sc.
Definition S23 := [:: F5; F4; F2; F3; F1; F0].
Definition S23f (sc : cube) : cube := tnth [tuple of S23] sc.
(* rotations 90 *)
Definition R05 := [:: F0; F2; F4; F1; F3; F5].
Definition R05f (sc : cube) : cube := tnth [tuple of R05] sc.
Definition R50 := [:: F0; F3; F1; F4; F2; F5].
Definition R50f (sc : cube) : cube := tnth  [tuple of R50] sc.
Definition R14 := [:: F3; F1; F0; F5; F4; F2].
Definition R14f (sc : cube) : cube := tnth [tuple of R14] sc.
Definition R41 := [:: F2; F1; F5; F0; F4; F3].
Definition R41f (sc : cube) : cube := tnth [tuple of R41] sc.
Definition R23 := [:: F1; F5; F2; F3; F0; F4].
Definition R23f (sc : cube) : cube := tnth [tuple of R23] sc.
Definition R32 := [:: F4; F0; F2; F3; F5; F1].
Definition R32f (sc : cube) : cube := tnth [tuple of R32] sc.
(* rotations 120 *)
Definition R024 := [:: F2; F5; F4; F1; F0; F3].
Definition R024f (sc : cube) : cube := tnth [tuple of R024] sc.
Definition R042 := [:: F4; F3; F0; F5; F2; F1].
Definition R042f (sc : cube) : cube := tnth [tuple of R042] sc.
Definition R012 := [:: F1; F2; F0; F5; F3; F4].
Definition R012f (sc : cube) : cube := tnth [tuple of R012] sc.
Definition R021 := [:: F2; F0; F1; F4; F5; F3].
Definition R021f (sc : cube) : cube := tnth [tuple of R021] sc.
Definition R031 := [:: F3; F0; F4; F1; F5; F2].
Definition R031f (sc : cube) : cube := tnth [tuple of R031] sc.
Definition R013 := [:: F1; F3; F5; F0; F2; F4].
Definition R013f (sc : cube) : cube := tnth [tuple of R013] sc.
Definition R043 := [:: F4; F2; F5; F0; F3; F1].
Definition R043f (sc : cube) : cube := tnth [tuple of R043] sc.
Definition R034 := [:: F3; F5; F1; F4; F0; F2].
Definition R034f (sc : cube) : cube := tnth [tuple of R034] sc.
(* last symmetries*)
Definition S1 := [:: F5; F2; F1; F4; F3; F0].
Definition S1f (sc : cube) : cube := tnth [tuple of S1] sc.
Definition S2 := [::  F5; F3; F4; F1; F2; F0].
Definition S2f (sc : cube) : cube := tnth [tuple of S2] sc.
Definition S3 := [::  F1; F0; F3; F2; F5; F4].
Definition S3f  (sc : cube) : cube := tnth [tuple of S3] sc.
Definition S4 := [:: F4; F5; F3; F2; F0; F1].
Definition S4f  (sc : cube) : cube := tnth [tuple of S4] sc.
Definition S5 := [::  F2; F4; F0; F5; F1; F3].
Definition S5f  (sc : cube) : cube := tnth [tuple of S5] sc.
Definition S6 := [::F3; F4; F5; F0; F1; F2].
Definition S6f  (sc : cube) : cube := tnth [tuple of S6] sc.

(* Specifications: *)
Lemma S1_inv : involutive S1f.
Lemma iso3_ndir : forall p, p \in dir_iso3  -> is_iso3 (s0 * p).
Definition sop (p : {perm cube}) : seq cube := val (val (val p)).
Lemma sop_inj : injective sop.
Lemma sop_morph : {morph sop : x y / x * y >-> prod_tuple x y}.
Definition ecubes : seq cube := [:: F0; F1; F2; F3; F4; F5].
Lemma ecubes_def : ecubes = enum (@predT cube).
Lemma Lcorrect : seq_iso_L == map sop [:: id3; s05; s14; s23; r05; r14; r23;
r50; r41; r32; r024; r042; r012; r021; r031; r013; r043; r034;
s1; s2; s3; s4; s5; s6].
Lemma stable : forall x y,
x \in dir_iso3 -> y \in dir_iso3 -> x * y \in dir_iso3.
Lemma iso_eq_F0_F1 : forall r s : {perm cube}, r \in dir_iso3 ->
s \in dir_iso3 -> r F0 = s F0 -> r F1 = s F1 -> r = s.
Lemma ndir_s0p : forall p, p \in dir_iso3 -> s0 * p \notin dir_iso3.
Definition indir_iso3l := map (mulg s0) dir_iso3l.