Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  findnormal.gi   Sprache: unbekannt

 
#############################################################################
##
##  This file is part of recog, a package for the GAP computer algebra system
##  which provides a collection of methods for the constructive recognition
##  of groups.
##
##  This files's authors include Max Neunhöffer.
##
##  Copyright of recog belongs to its developers whose names are too numerous
##  to list here. Please refer to the COPYRIGHT file for details.
##
##  SPDX-License-Identifier: GPL-3.0-or-later
##
##
##  Handle the (projective) imprimitive, tensor and tensor-induced cases.
##  This file contains generic methods to find normal subgroups.
##
#############################################################################

BindGlobal( "FINDEVENNORMALOPTS", rec(
  # Try up to this limit random elements to find an involution:
  NonCentInvSearchLimit := 20,
  # Number of random elements for normal closure computation:
  NrGensNormalClosure := 10,
  # Number of odd cases to wait for for computation of involution centraliser:
  NrOddForInvCent := 20,
  # Number of steps after which we give up:
  NrStepsGiveUpForInvCent := 64,
  # Number of random elements to use for GuessProperness:
  NrElsGuessProperness := 20,
  # Number of random elements of G to look at orders:
  NrElsLookAtOrders := 5,
  # Function to determine the order of an element:
  Order := Order,
  # Function to determine equality:
  Eq := EQ,
  # Function to determine whether an element is the identity:
  IsOne := IsOne,
  # Set this to true if you are working with projective groups:
  Projective := false,
  # Set this to true if blind descent should be tried:
  DoBlindDescent := false,
  # The random source to use:
  RandomSource := GlobalMersenneTwister,
  # Up to this size we check all involutions:
  SizeLimitAllInvols := 32,
) );

# InstallGlobalFunction( RECOG_IsNormal,
#   function(g,h,projective)
#     local S,x,y;
#     if HasStoredStabilizerChain(h) and not projective then
#         S := StoredStabilizerChain(h);
#     else
#         S := StabilizerChain(h,rec( Projective := projective ));
#     fi;
#     for x in GeneratorsOfGroup(g) do
#         for y in GeneratorsOfGroup(h) do
#             if not y^x in S then return false; fi;
#         od;
#     od;
#     return true;
#   end );

# InstallMethod( FindEvenNormalSubgroup, "for a group object",
#   [ IsGroup ],
#   function( g ) return FindEvenNormalSubgroup( g, rec() ); end );

# InstallMethod( FindEvenNormalSubgroup, "for a group object and a record",
#   [ IsGroup, IsRecord ],
#   function( g, opt )
#     local AddList,FindNonCentralInvolution,GuessProperness,InvCentDescent,
#           LookAtInvolutions,NormalClosure,TestElement,ggens,ggenso,i,res;

#     Info(InfoFindEvenNormal,1,"FindEvenNormalSubgroup called...");

#     # Some helper function:
#     AddList := function(l,el)
#       if opt.IsOne(el) then return false; fi;
#       for i in [1..Length(l)] do
#           if opt.Eq(l[i],el) then return false; fi;
#       od;
#       Add(l,el);
#       return true;
#     end;

#     FindNonCentralInvolution := function(gens,pr,invols)
#       local count,o,x;
#       if pr = false then
#           pr := ProductReplacer(gens, rec( scramblefactor := 3 ) );
#       fi;
#       # Find a non-central involution:
#       count := 0;
#       repeat
#           x := Next(pr);
#           o := opt.Order(x);
#           if IsEvenInt(o) then
#               if InfoLevel(InfoFindEvenNormal) >= 3 then Print("+\c"); fi;
#               x := x^(o/2);
#               if AddList(invols,x) then
#                   if ForAny(gens,a->not opt.Eq(a*x,x*a)) then
#                       return x;
#                   fi;
#               fi;
#           else
#               if InfoLevel(InfoFindEvenNormal) >= 3 then Print("-\c"); fi;
#           fi;
#           count := count + 1;
#       until count > opt.NonCentInvSearchLimit;
#       return fail;
#     end;

#     NormalClosure := function(prg,Ngens)
#       local i,l,pr;
#       pr := ProductReplacer(Ngens,rec( normalin := prg,
#                                        scramble := 20,
#                                        scramblefactor := 2,
#                                        addslots := 10 ));
#       l := ShallowCopy(Ngens);
#       for i in [1..opt.NrGensNormalClosure] do
#           if InfoLevel(InfoFindEvenNormal) >= 3 then Print("N\c"); fi;
#           AddList(l,Next(pr));
#       od;
#       return rec( Ngens := l, prN := pr, count := opt.NrGensNormalClosure );
#     end;

#     GuessProperness := function( Ngens, prN )
#       # Ngens: generators for N (will be extended)
#       # prN: product replacer producing elements in normal closure
#       local a,i,j,o,stage;
#       o := ShallowCopy(ggenso);
#       for i in [1..Length(Ngens)] do
#           if InfoLevel(InfoFindEvenNormal) >= 3 then Print("G\c"); fi;
#           a := Ngens[i];
#           for j in [1..Length(ggens)] do
#               if o[j] <> 1 then
#                   o[j] := GcdInt(o[j],opt.Order(a*ggens[j]));
#               fi;
#           od;
#           if ForAll(o,k->k = 1) then return false; fi;
#       od;
#       stage := 0;
#       repeat
#           stage := stage + 1;
#           if InfoLevel(InfoFindEvenNormal) >= 3 then Print(stage,"\c"); fi;
#           for i in [1..opt.NrElsGuessProperness] do
#               if InfoLevel(InfoFindEvenNormal) >= 3 then Print("G\c"); fi;
#               a := Next(prN);
#               if AddList(Ngens,a) then
#                   for j in [1..Length(ggens)] do
#                       if o[j] <> 1 then
#                           o[j] := GcdInt(o[j],opt.Order(a*ggens[j]));
#                       fi;
#                   od;
#                   if ForAll(o,k->k = 1) then return false; fi;
#               fi;
#           od;
#       until Number(o,k->k = 1) <= QuoInt(Length(o),2) or stage >= 3;
#       return o;
#     end;

#     TestElement := function(x)
#       local orderests,r;
#       Info(InfoFindEvenNormal,2,"Testing element...");
#       r := NormalClosure(opt.pr,[x]);
#       orderests := GuessProperness(r.Ngens,r.prN);
#       if InfoLevel(InfoFindEvenNormal) >= 3 then Print("\n"); fi;
#       Info(InfoFindEvenNormal,2,"Order estimates: ",orderests);
#       if orderests <> false then
#           return rec( success := true, orderests := orderests,
#                       Ngens := r.Ngens, prN := r.prN, x := x,
#                       msg := "Ngens should generate a proper normal subgroup" );
#       else
#           return fail;
#       fi;
#     end;

#     InvCentDescent := function(hgens,prh,x,centinvols)
#       local blind,c,centgens,count,counteven,countodd,o,prc,r,w,y,z;
#       Info(InfoFindEvenNormal,2,"Descending to involution centraliser...");
#       # We produce generators for the involution centraliser:
#       centgens := Concatenation([x],centinvols);
#       count := 0;
#       counteven := 0;
#       countodd := 0;
#       blind := false;
#       repeat
#           y := Next(prh);
#           c := x * x^y;       # = Comm(x,y) since x is an involution
#           o := opt.Order(c);
#           if IsEvenInt(o) then   # <x,y> is dihedral with order = 0 mod 4
#               if InfoLevel(InfoFindEvenNormal) >= 3 then Print("+\c"); fi;
#               z := c^(o/2);
#               if AddList(centinvols,z) then
#                   AddList(centgens,z);
#                   counteven := counteven + 1;
#                   if opt.DoBlindDescent then
#                       if blind = false then
#                           blind := z;
#                       else
#                           w := blind^-1*z*blind*z;   # = Comm(blind,z)
#                           if not opt.IsOne(w) then
#                               blind := w;
#                           fi;
#                       fi;
#                   fi;
#               fi;
#           else
#               # This is a uniformly distributed random element in C_G(x):
#               if InfoLevel(InfoFindEvenNormal) >= 3 then Print("-\c"); fi;
#               z := y*c^((o-1)/2);
#               AddList(centgens,z);
#               countodd := countodd + 1;
#               o := opt.Order(z);
#               if IsEvenInt(o) then
#                   if AddList(centinvols,z^(o/2)) then
#                       if opt.DoBlindDescent then
#                           if blind = false then
#                               blind := z;
#                           else
#                               w := blind^-1*z*blind*z;   # = Comm(blind,z)
#                               if not opt.IsOne(w) then
#                                   blind := w;
#                               fi;
#                           fi;
#                       fi;
#                   fi;
#               fi;
#           fi;
#           count := count + 1;
#       until countodd >= opt.NrOddForInvCent or
#             count >= opt.NrStepsGiveUpForInvCent;
#       if InfoLevel(InfoFindEvenNormal) >= 3 then Print("\n"); fi;
#       if opt.DoBlindDescent and blind <> false then
#           r := TestElement(blind);
#           if r <> fail then return r; fi;
#       fi;
#       prc := ProductReplacer(centgens,rec( scramblefactor := 3 ) );
#       return LookAtInvolutions(centgens,prc,centinvols);
#     end;

#     LookAtInvolutions := function(hgens,prh,invols)
#       local S,i,invgrp,iter,pr,r,x,y;
#       Info(InfoFindEvenNormal,2,"Looking for non-central involutions...");
#       i := 1;
#       while i <= Length(invols) do
#           if ForAny(hgens,a->not opt.Eq(a*invols[i],invols[i]*a)) then
#               break;
#           fi;
#           i := i + 1;
#       od;
#       if i <= Length(invols) then
#           x := invols[i];
#           if InfoLevel(InfoFindEvenNormal) >= 3 then Print("\n"); fi;
#       else
#           x := FindNonCentralInvolution(hgens,prh,invols);
#           if InfoLevel(InfoFindEvenNormal) >= 3 then Print("\n"); fi;
#           if x = fail then   # suspect that all involutions are central in H!
#               Info(InfoFindEvenNormal,2,"Found ",Length(invols),
#                    " central ones.");
#               if Length(invols) = 0 then
#                   return rec( success := false,
#                               msg := "No central involutions found" );
#               fi;
#               invgrp := Group(invols);
#               S := StabilizerChain(invgrp,rec( Projective := opt.Projective,
#                                                isone := opt.IsOne ) );
#               if Size(S) <= opt.SizeLimitAllInvols then
#                   iter := GroupIteratorByStabilizerChain(S);
#                   Info(InfoFindEvenNormal,2,"Looking through ",Size(S),
#                        " central involutions...");
#                   for y in iter do
#                       if not opt.IsOne(y) then
#                           r := TestElement(y);
#                           if r <> fail then return r; fi;
#                       fi;
#                   od;
#                   return rec( success := false,
#                      msg := "No central involution found normal subgroup" );
#               else
#                   for i in [1..20] do
#                       y := Random(S);
#                       if not opt.IsOne(y) then
#                           r := TestElement(y);
#                           if r <> fail then return r; fi;
#                       fi;
#                   od;
#                   return rec( success := false,
#                      msg := Concatenation("20 out of ",String(Size(S)),
#                                           " random central involutions did ",
#                                           "not find a normal subgroup") );
#               fi;
#           fi;
#           i := Length(invols);
#       fi;
#       # If we get here, we have found a non-central involution and
#       # invols{[1..i-1]} is a list of central ones!
#       return InvCentDescent(hgens,prh,x,invols{[1..i-1]});
#   end;

#   # Here the main routine starts:

#   # Set some defaults:
#   if IsBound(opt.Projective) and opt.Projective then
#       if not IsBound(opt.IsOne) then opt.IsOne := IsOneProjective; fi;
#       if not IsBound(opt.Eq) then opt.Eq := IsEqualProjective; fi;
#       if not IsBound(opt.Order) then opt.Order := RECOG.ProjectiveOrder; fi;
#   fi;
#   GENSS_CopyDefaultOptions( FINDEVENNORMALOPTS, opt );

#   # Initialise a product replacer:
#   if not IsBound(opt.pr) then
#       opt.pr := ProductReplacer(GeneratorsOfGroup(g));
#   fi;

#   # First make sure we have an involution list:
#   if not IsBound(opt.invols) then
#       opt.invols := [];
#   fi;

#   # Some more preparations:
#   ggens := EmptyPlist(opt.NrElsLookAtOrders);
#   for i in [1..opt.NrElsLookAtOrders] do
#       Add(ggens,Next(opt.pr));
#   od;
#   ggenso := List(ggens,opt.Order);

#   res := LookAtInvolutions(GeneratorsOfGroup(g),opt.pr,opt.invols);
#   if IsRecord(res) and res.success then
#       Info(InfoFindEvenNormal,1,"FindEvenNormalSubgroup:  SUCCESS!");
#   else
#       Info(InfoFindEvenNormal,1,"FindEvenNormalSubgroup:  FAILURE!");
#   fi;
#   return res;
# end );

# All powers that can be done with at most 5 multiplications/inversion:
RECOG.MYRANDOMSUBPRODUCTPOWERS :=
  [1,2,3,4,5,6,7,8,9,10,11,12,13,14,16,17,18,20,24,32,
   -1,-2,-3,-4,-5,-6,-7,-8,-9,-10,-12,-16];
  # (without undue and unimplemented tricks)!

RECOG.RandomSubproduct := function(a,opt)
    local allone,dopowers,g,isone,power,prod,rs;

    if IsBound(opt.RandomSource) then
        rs := opt.RandomSource;
    else
        rs := GlobalMersenneTwister;
    fi;
    if IsBound(opt.DoPowers) then
        dopowers := opt.DoPowers;
    else
        dopowers := false;
    fi;
    if IsBound(opt.IsOne) then
        isone := opt.IsOne;
    else
        isone := IsOne;
    fi;

    prod := One(a[1]);
    allone := true;
    repeat
        for g in a do
            if not isone(g) then
                allone := false;
                if Random( rs, [ true, false ] )  then
                    if dopowers then
                        power := Random(rs,RECOG.RANDOMSUBPRODUCTPOWERS);
                    else
                        power := 1;
                    fi;
                    if Random( rs, [ true, false ] )  then
                        prod := prod * g^power;
                    else
                        prod := g^power * prod;
                    fi;
                fi;
            fi;
        od;
    until allone or not isone(prod);
    return prod;
end;

RECOG.BlindDescentStep := function(G,x,y,opt)
  # If either x or y are in a proper normal subgroup, then the result will
  # be and it will be nontrivial:
  # Only use for non-abelian groups and for non-trivial x and y!

  local c,i,isone,l,usepseudo,xx;

  if IsBound(opt.IsOne) then
      isone := opt.IsOne;
  else
      isone := IsOne;
  fi;
  if IsBound(opt.UsePseudoRandom) then
      usepseudo := opt.UsePseudoRandom;
  else
      usepseudo := false;
  fi;

  c := Comm(x,y);
  if not isone(c) then
      return rec( el := c, Ngens := [c], Nready := false, central := false,
                  isknownproper := false );
  fi;
  # y could be central in G:
  if ForAll(GeneratorsOfGroup(G),g->isone(Comm(g,y))) then
      return rec( el := y, central := true, Ngens := [y], Nready := true,
                  isknownproper := true );  # G was not abelian!
  fi;
  # Now try generators for the normal closure of x:
  l := [x];
  for i in [1..18] do
    if usepseudo then
        xx := RECOG.RandomSubproduct(l,opt)^PseudoRandom(G);
    else
        xx := RECOG.RandomSubproduct(l,opt)^
              RECOG.RandomSubproduct(GeneratorsOfGroup(G),opt);
    fi;
    Add(l,xx);
    c := Comm(xx,y);
    if not isone(c) then
        return rec( el := c, central := false, Ngens := l, Nready := false,
                    isknownproper := false );
    fi;
  od;
  # Now y seems to commute with <x^G> but not with all of G, thus <x^G>
  # is a proper normal subgroup:
  return rec( el := x, central := false, Ngens := l, Nready := true,
              isknownproper := true );
end;

InstallMethod( FindElmOfEvenNormalSubgroup, "for a group object",
  [ IsGroup ],
  function( g ) return FindElmOfEvenNormalSubgroup( g, rec() ); end );

InstallMethod( FindElmOfEvenNormalSubgroup, "for a group object and a record",
  [ IsGroup, IsRecord ],
  function( g, opt )
    local AddList,FindNonCentralInvolution,InvCentDescent,LookAtInvolutions,
          UseElement,abelian,blind,blindr,gens,i,invols,j,pos,res;

    Info(InfoFindEvenNormal,1,"FindElmOfEvenNormalSubgroup called...");

    # Some helper function:
    AddList := function(l,el)
      if opt.IsOne(el) then
          return false;
      fi;
      for i in [1..Length(l)] do
          if opt.Eq(l[i],el) then
              return false;
          fi;
      od;
      Add(l,el);
      return true;
    end;

    FindNonCentralInvolution := function(h,invols)
      # Find a non-central involution:
      local count,o,x;
      count := 0;
      repeat
          x := PseudoRandom(h);
          o := opt.Order(x);
          if IsEvenInt(o) then
              if InfoLevel(InfoFindEvenNormal) >= 3 then Print("+\c"); fi;
              x := x^(o/2);
              if AddList(invols,x) then
                  if ForAny(GeneratorsOfGroup(h),a->not opt.Eq(a*x,x*a)) then
                      return x;
                  fi;
              fi;
          else
              if InfoLevel(InfoFindEvenNormal) >= 3 then Print("-\c"); fi;
          fi;
          count := count + 1;
      until count > opt.NonCentInvSearchLimit;
      return fail;
    end;

    UseElement := function(y)
      # This does a blind descent step possibly ending everything!
      # It refers to the outer variables g, blind, blindr and opt!
      blindr := RECOG.BlindDescentStep(g,blind,y,opt);
      if blindr.isknownproper then
          blindr.success := true;
          if blindr.central then
              blindr.msg := "Found central element";
          else
              blindr.msg := "Normal closure almost certainly proper";
          fi;
      fi;
      blind := blindr.el;
    end;

    InvCentDescent := function(h,x,centinvols)
      local c,centgens,count,counteven,countodd,o,prc,y,z;
      Info(InfoFindEvenNormal,2,"Descending to involution centraliser...");
      # We produce generators for the involution centraliser:
      centgens := Concatenation([x],centinvols);
      count := 0;
      counteven := 0;
      countodd := 0;

      repeat
          y := PseudoRandom(h);
          c := x * x^y;       # = Comm(x,y) since x is an involution
          o := opt.Order(c);
          if IsEvenInt(o) then   # <x,y> is dihedral with order = 0 mod 4
              if InfoLevel(InfoFindEvenNormal) >= 3 then Print("+\c"); fi;
              z := c^(o/2);
              if AddList(centinvols,z) then
                  AddList(centgens,z);
                  counteven := counteven + 1;
                  UseElement(z);
                  if blindr.isknownproper then
                      if InfoLevel(InfoFindEvenNormal)>=3 then Print("\n"); fi;
                      return blindr;
                  fi;
              fi;
              z := (x * x^(y^-1))^(o/2);
              if AddList(centinvols,z) then
                  AddList(centgens,z);
                  counteven := counteven + 1;
                  UseElement(z);
                  if blindr.isknownproper then
                      if InfoLevel(InfoFindEvenNormal)>=3 then Print("\n"); fi;
                      return blindr;
                  fi;
              fi;
          else
              # This is a uniformly distributed random element in C_G(x):
              if InfoLevel(InfoFindEvenNormal) >= 3 then Print("-\c"); fi;
              z := y*c^((o-1)/2);
              AddList(centgens,z);
              countodd := countodd + 1;
              o := opt.Order(z);
              if IsEvenInt(o) then
                  z := z^(o/2);
                  if AddList(centinvols,z^(o/2)) then
                      UseElement(z);
                      if blindr.isknownproper then
                      if InfoLevel(InfoFindEvenNormal)>=3 then Print("\n"); fi;
                          return blindr;
                      fi;
                  fi;
              fi;
          fi;
          count := count + 1;
      until countodd >= opt.NrOddForInvCent or
            count >= opt.NrStepsGiveUpForInvCent;
      if InfoLevel(InfoFindEvenNormal) >= 3 then Print("\n"); fi;
      c := GroupWithGenerators(centgens);
      prc := ProductReplacer(c,rec( scramblefactor := 3 ) );
      c!.pseudorandomfunc := [rec( func := Next, args := [prc] )];
      return LookAtInvolutions(c,centinvols);
    end;

    LookAtInvolutions := function(h,invols)
      local S,i,invgrp,iter,x,y;
      Info(InfoFindEvenNormal,2,"Looking for non-central involutions...");
      i := 1;
      while i <= Length(invols) do
          if ForAny(GeneratorsOfGroup(h),
                    a->not opt.Eq(a*invols[i],invols[i]*a)) then
              break;
          fi;
          i := i + 1;
      od;
      if i <= Length(invols) then
          x := invols[i];
          if InfoLevel(InfoFindEvenNormal) >= 3 then Print("\n"); fi;
      else
          x := FindNonCentralInvolution(h,invols);
          if InfoLevel(InfoFindEvenNormal) >= 3 then Print("\n"); fi;
          if x = fail then   # suspect that all involutions are central in H!
              Info(InfoFindEvenNormal,2,"Found ",Length(invols),
                   " central ones.");
              if Length(invols) = 0 then
                  return rec( success := fail,
                              msg := "No central involutions found" );
              fi;
              invgrp := GroupWithGenerators(invols);
              Info(InfoFindEvenNormal,3,"Computing stabiliser chain...");
              S := StabilizerChain(invgrp,
                         rec( Projective := opt.Projective,
                              IsOne := opt.IsOne,
                              OrbitLengthLimit := 1000,
                              FailInsteadOfError := true ) );
              if IsString(S) then
                  Info(InfoFindEvenNormal,3,"...failed.");
              else
                  Info(InfoFindEvenNormal,3,"...done, size is ",Size(S),".");
              fi;
              if not IsString(S) and Size(S) <= opt.SizeLimitAllInvols then
                  iter := GroupIteratorByStabilizerChain(S);
                  Info(InfoFindEvenNormal,2,"Looking through ",Size(S),
                       " central involutions...");
                  for y in iter do
                      if not opt.IsOne(y) then
                          UseElement(y);
                          if blindr.isknownproper then
                              return blindr;
                          fi;
                      fi;
                  od;
                  blindr.msg :=
  "If at all possible, we found an element of an even proper normal subgroup.";
                  blindr.success := true;
                  return blindr;
              else
                  for i in [1..20] do
                      if IsString(S) then
                          y := RandomSubproduct(invols);
                      else
                          y := Random(S);
                      fi;
                      if not opt.IsOne(y) then
                          UseElement(y);
                          if blindr.isknownproper then
                              return blindr;
                          fi;
                      fi;
                  od;
                  blindr.msg :=
  "We could have found an element of an even proper normal subgroup.";
                  blindr.success := "Perhaps";
                  return blindr;
              fi;
          fi;
          i := Length(invols);
      fi;
      # If we get here, we have found a non-central involution and
      # invols{[1..i-1]} is a list of central ones!
      return InvCentDescent(h,x,invols{[1..i-1]});
  end;

  # Here the main routine starts:

  # Set some defaults:
  if IsBound(opt.Projective) and opt.Projective then
      if not IsBound(opt.IsOne) then opt.IsOne := IsOneProjective; fi;
      if not IsBound(opt.Eq) then opt.Eq := IsEqualProjective; fi;
      if not IsBound(opt.Order) then opt.Order := RECOG.ProjectiveOrder; fi;
  fi;
  GENSS_CopyDefaultOptions( FINDEVENNORMALOPTS, opt );

  # First test whether or not we are abelian:
  if not IsBound(opt.SkipTrivAbelian) then
      gens := GeneratorsOfGroup(g);
      pos := First([1..Length(gens)],i->not opt.IsOne(gens[i]));
      if pos = fail then
          res := rec( success := fail, msg := "Group is trivial" );
      fi;
      i := 1;
      abelian := true;
      while abelian and i < Length(gens) do
          j := i+1;
          while abelian and j <= Length(gens) do
              if not opt.Eq(gens[i]*gens[j],gens[j]*gens[i]) then
                  abelian := false;
              fi;
              j := j + 1;
          od;
          i := i + 1;
      od;
      if abelian then
          res := rec( success := true, msg := "Group is abelian",
                      el := gens[pos] );
      fi;
  fi;

  opt.UsePseudoRandom := true;   # This is for the blind descent

  # First make sure we have an involution list:
  if IsBound(opt.invols) then
      invols := opt.invols;
  else
      invols := [];
  fi;

  blind := PseudoRandom(g);
  blindr := rec();    # will be overwritten in UseElement
  res := LookAtInvolutions(g,invols);
  Info(InfoFindEvenNormal,1,"FindElmOfEvenNormalSubgroup: ",res.success,"!");
  return res;
end );

# FindHomMethodsProjective.FindEvenNormal := function(ri,G)
#   local count,r,rr,f,m,mm,res;
#   r := FindEvenNormalSubgroup(G,
#           rec( Projective := true, DoBlindDescent := true));
#   if r.success then
#       f := ri!.field;
#       m := GModuleByMats(r.Ngens,f);
#       if not MTX.IsIrreducible(m) then
#           Info(InfoRecog,2,
#                "FindEvenNormal: Found reducible proper normal subgroup!");
#           return RECOG.SortOutReducibleNormalSubgroup(ri,G,r.Ngens,m);
#       else
#           Info(InfoRecog,2,
#                "FindEvenNormal: Found irreducible proper normal subgroup!");
#           count := 0;
#           repeat
#               count := count + 1;
#               rr := FindEvenNormalSubgroup(Group(r.Ngens),
#                            rec( Projective:=true, DoBlindDescent := true ));
#               if rr.success then
#                   mm := GModuleByMats(rr.Ngens,f);
#                   if MTX.IsIrreducible(mm) then
#                       Info(InfoRecog,2,
#             "FindEvenNormal: Second normal subgroup was not reducible.");
#                       return fail; # FIXME: fail = TemporaryFailure here really correct?
#                   fi;
#                   res := RECOG.SortOutReducibleSecondNormalSubgroup(ri,G,
#                                     rr.Ngens,mm);
#                   if res = true then return Success; fi;
#                   r := rr;
#               else
#                   return fail; # FIXME: fail = TemporaryFailure here really correct?
#               fi;
#           until count >= 2;
#       fi;
#   fi;
#   return fail; # FIXME: fail = TemporaryFailure here really correct?
# end;

#! @BeginChunk FindElmOfEvenNormal
#! TODO
#! @EndChunk
BindRecogMethod(FindHomMethodsProjective, "FindElmOfEvenNormal",
"find D2, D4 or D7 by finding an element of an even normal subgroup",
function(ri,G)
  local cf,count,f,m,mm,r,res,rr;
  RECOG.SetPseudoRandomStamp(G,"FindElmOfEvenNormal");
  r := FindElmOfEvenNormalSubgroup(G,
          rec( Projective := true, SkipTrivAbelian := true ));
  if r.success = fail then # FIXME: fail = TemporaryFailure here really correct?
      return fail; # FIXME: fail = TemporaryFailure here really correct?
  fi;
  if not IsBound(r.Nready) or not r.Nready then
      r.Ngens := FastNormalClosure(G,[r.el],20);
  fi;
  f := ri!.field;
  m := GModuleByMats(r.Ngens,f);
  if not MTX.IsIrreducible(m) then
      Info(InfoRecog,2,
           "FindElmOfEvenNormal: Found reducible proper normal subgroup!");
      return RECOG.SortOutReducibleNormalSubgroup(ri,G,r.Ngens,m);
  else
      Info(InfoRecog,2,
           "FindElmOfEvenNormal: Could be irreducible proper normal subgroup!");
      # First find out whether or not the dimension is a proper power:
      cf := RECOG.IsPower(ri!.dimension);
      if Length(cf) = 0 then
          Info(InfoRecog,2,"Dimension no proper power, so this is not D7.");
      else
          count := 0;
          repeat
              count := count + 1;
              rr := FindElmOfEvenNormalSubgroup(Group(r.Ngens),
                           rec( Projective:=true, SkipTrivAbelian := true ));
              if rr.success = fail then continue; fi;
              if not IsBound(rr.Nready) or not rr.Nready then
                  rr.Ngens := FastNormalClosure(r.Ngens,[rr.el],20);
              fi;
              mm := GModuleByMats(rr.Ngens,f);
              if MTX.IsIrreducible(mm) then
                  Info(InfoRecog,2,
           "FindElmOfEvenNormal: Second normal subgroup was not reducible.");
                  return fail; # FIXME: fail = TemporaryFailure here really correct?
              fi;
              res := RECOG.SortOutReducibleSecondNormalSubgroup(
                                      ri,G,rr.Ngens,mm);
              if res = true then
                  return Success;
              fi;
              r := rr;
          until count >= 2;
      fi;
  fi;
  return fail; # FIXME: fail = TemporaryFailure here really correct?
end);

[ Dauer der Verarbeitung: 0.4 Sekunden  (vorverarbeitet)  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge