Ob := Set(G); Gseq := [x : x in G]; Mor := CartesianProduct(Set(G),Set(M)); invert := map< Mor -> Mor | x :-> >; MFP,xi := FPGroup(M); numb0 := map<{-1,0,1} -> {1,2} | [<-1,1>,<0,2>,<1,2>]>; numb := map< Integers() -> {1,2} | z :-> Sign(z)@numb0 >; m_seq := function(m) return ElementToSequence(m@@xi); end function; nog := NumberOfGenerators(MFP); M_gen := [(MFP.i)@xi : i in [1..nog]]; Mor_gen := CartesianProduct(Set(G),{1..nog}); Mf := Image(f); Kf := Kernel(f); Tr0 := Transversal(G,Mf); Tr := [x^-1 : x in Tr0]; // Linksnebenklassenrepräsentanten TrRep := map Tr | g :-> [x : x in Tr | g^-1 * x in Mf][1]>; MfRep := map Mf | g :-> Mf!((g@TrRep)^-1 * g)>; sect := map M | n :-> [m : m in M | m@f eq n][1]>; STr := SymmetricGroup(Set(Tr)); phi := Action(GSet(STr)); SMf := SymmetricGroup(Set(Mf)); psi := Action(GSet(SMf)); DPSMf := CartesianProduct([SMf : i in [1..#Tr]]); SKf := SymmetricGroup(Set(Kf)); eta := Action(GSet(SKf)); DPSKf_inner := CartesianProduct([SKf : i in [1..nog]]); DPSKf_outer := CartesianProduct([DPSKf_inner : i in [1..#G]]); DPKf := CartesianProduct([Kf : i in [1..#G]]); STr_list := [x : x in STr]; DPSMf_list := [x : x in DPSMf]; DPSKf_outer_list := [x : x in DPSKf_outer]; STr_length := #STr_list; DPSMf_length := #DPSMf_list; DPSKf_outer_length := #DPSKf_outer_list; i := 1; // in [1..STr_length] j := 1; // in [1..DPSMf_length] k_start := 1; k_end := 300; // Intervall in [1..DPSKf_outer_length] s := STr_list[i]; smftup := DPSMf_list[j]; SymmetricCrossedModule_stepwise := function(M,G,alpha,f,s,smftup,DPSKf_outer_list,k_start,k_end); // e.g. SCM_stepwise := SymmetricCrossedModule_stepwise(M,G,alpha,f,s,smftup,DPSKf_outer_list,k_start,k_end); Ob := Set(G); ListOfAutofunctors := []; ListOfIsotrafos := []; F_Ob := map Ob | g :-> @phi * @psi> ; SetOfAttempts := {}; for k in [k_start..k_end] do print "spy k =", k; skftup := DPSKf_outer_list[k]; sk := map< Mor_gen -> SKf | x :-> skftup[Index(Gseq,x[1])][x[2]] >; F_Mor_gen_plus := map< Mor_gen -> Mor | x :-> < x[1]@F_Ob , ( (x[1]@F_Ob)^-1 * (x[1] * M_gen[x[2]]@f)@F_Ob )@sect * < Kf!((M_gen[x[2]]@f@sect)^-1 * M_gen[x[2]]), x@sk >@eta > >; F_Mor_gen_plus_list := { : x in Mor_gen}; if not F_Mor_gen_plus_list in SetOfAttempts then SetOfAttempts join:= { F_Mor_gen_plus_list }; F_Mor_gen_minus := map< Mor_gen -> Mor | x :-> < x[1] * (M_gen[x[2]]@f)^-1 , x[2] >@F_Mor_gen_plus@invert >; F_Mor_gen := [F_Mor_gen_minus,F_Mor_gen_plus]; F_Mor := map< Mor -> Mor | x :-> < x[1]@F_Ob , &*([Id(M)] cat [(< x[1] * &*([Id(M)] cat [ M_gen[Abs(i)]^Sign(i) where i is (x[2]@m_seq)[j] : j in [1..l-1]])@f , Abs((x[2]@m_seq)[l]) >@F_Mor_gen[(x[2]@m_seq)[l]@numb])[2] : l in [1..#(x[2]@m_seq)]]) > >; is_functor := true; for y in CartesianProduct([G,M,M]) do if not (@F_Mor)[2] eq (@F_Mor)[2] * (@F_Mor)[2] then is_functor := false; break y; end if; end for; if is_functor and #[x@F_Mor : x in Mor] eq #{x@F_Mor : x in Mor} then print "spy autofunctor"; ListOfAutofunctors cat:= []; if s eq Id(STr) then for k_tup in DPKf do candidate_trafo := map Mor | g :-> < g, (Mf!(g^-1 * g@F_Ob))@sect * k_tup[Index(Gseq,g)]> >; // so this candidate trafo at g actually has value g@candidate_trafo is_trafo := true; for z in Mor do if not (z[1]@candidate_trafo)[2] * (z@F_Mor)[2] eq z[2] * ((z[1]*(z[2]@f))@candidate_trafo)[2] then is_trafo := false; break z; end if; end for; if is_trafo then print "spy isotrafo"; ListOfIsotrafos cat:= [>]; end if; end for; end if; end if; end if; end for; return ; end function;