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


Quellcode-Bibliothek permut.gi   Sprache: unbekannt

 
Spracherkennung für: .gi vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]

#############################################################################
##
#W  permut.gi              Permutability GAP library              ABB&ECL&RER
##
##
#Y  Copyright (C)  2000-2018 Adolfo Ballester-Bolinches, Enric Cosme-Ll\'opez
#Y                           and Ramon Esteban-Romero
##
##  This file contains methods for permutability
##

#############################################################################
##
#V  PermutMaxTries
##
##  Maximum number of random attempts of permutability checks before trying
##  general methods
##

PermutMaxTries:=10;


#############################################################################
##
#M  ArePermutableSubgroups( <G>, <U>, <V> ) . . . . for finite groups
##
##  Returns true if <U> and <V> permute, false otherwise.
##

InstallMethod(ArePermutableSubgroups, "with three arguments <G>, <U>, <V>, where <U> and <V> are subgroups of <G>",
        [IsGroup and IsFinite,IsGroup and IsFinite,IsGroup and IsFinite],
        function(G,U,V)
    local bool1, bool2;
    if not IsSubgroup(G,U)
       or not IsSubgroup(G,V)
       then
        Error("<U> and <V> must be subgroups of <G>");
    fi;
    bool1:=HasParent(U) and IsSubgroup(Parent(U),G);
    bool2:=HasParent(V) and IsSubgroup(Parent(V),G);
        #
        # a shortcut when one of the subgroups is normal in its parent
        # 
    if (bool1 and HasIsNormalInParent(U) and IsNormalInParent(U))
       or (bool2 and  HasIsNormalInParent(V) and IsNormalInParent(V))
       then
        return true;
        
        #
        # a shortcut when one of the subgroups is permutable in its parent
        # 
    elif (bool1 and HasIsPermutableInParent(U) and IsPermutableInParent(U))
      or (bool2 and HasIsPermutableInParent(V) and IsPermutableInParent(V))
      then
        return true;
        # 
        # a shortcut when one of the subgroups is contained in the other
        #
    elif IsSubgroup(U,V) or IsSubgroup(V,U)
      then
        return true;
        #
        # the general case
        #
    else
        return Size(U)*Size(V)=Size(Intersection(U,V))*
               Size(Subgroup(G,Union(GeneratorsOfGroup(U),
                       GeneratorsOfGroup(V))));
    fi;
end);

#
## With two parameters, both groups must be subgroups of a common group.
#

InstallOtherMethod(ArePermutableSubgroups, "with two arguments",
        [IsGroup and IsFinite, IsGroup and IsFinite],
        function(U,V)
    local G;
    if IsIdenticalObj(Parent(U), Parent(V))
       then
        return ArePermutableSubgroups(Parent(U),U,V);
    else
        return ArePermutableSubgroups(ClosureGroup(U,V),U,V);
    fi;
end);

#############################################################################
##
#M  Permutizer( <G>, <U> ) . . . . for finite groups
##
##  Computes the permutizer of a subgroup U in G.  This is the
## subgroup generated by all the cyclic subgroups of G which permute with U.
##
InstallMethod(PermutizerOp,"for finite groups", [IsGroup and IsFinite,
        IsGroup and IsFinite],
        function(g,h)
    local ele, llista,z,bool1, n,x;
    if not IsSubgroup(g,h)
       then
        Error("<h> must be a subgroup of <g>");
    fi;
    bool1:=IsSubgroup(Parent(h),g);
    #
    # If h is normal or permutable in g, it is easy to compute the permutizer.
    #
    if bool1 and HasIsNormalInParent(h) and IsNormalInParent(h)
       then
        return g;
    fi;
    if bool1 and HasIsPermutableInParent(h) and IsPermutableInParent(h)
       then
        return g;
    fi;
    if IsNormal(g,h)
       then 
        return g; 
    fi;
    if IsPermutable(g,h)
       then
        return g;
    fi;
    # We start with the normaliser, then we add elements
    n:=Normalizer(g,h);
    for x in g do
        if not x in n and ArePermutableSubgroups(g,h,Subgroup(g,[x]))
           then
            n:=ClosureSubgroup(n,Subgroup(g,[x]));
        fi;
        # if n=g, we stop adding elements.
        if n=g 
           then
            break;
        fi;
    od;
           
    return n;
end);

#############################################################################
##
#M  AllSubnormalSubgroups( <G> ) . . . . for a finite group
##
##  The default method constructs the lattice of subnormal subgroups.
##
InstallMethod(AllSubnormalSubgroups, "for a finite group",
        [IsGroup and IsFinite],
        function(G)
    local sn0,asn,sn1,x;
    sn0:=NormalSubgroups(G);
    asn:=ShallowCopy(sn0);
    repeat
        sn1:=[];
        for x in sn0 
          do
            Append(sn1, Filtered(NormalSubgroups(x), 
                    x-> not x in asn and not x in sn1));
        od;
        sn0:=sn1;
        Append(asn,sn1);
    until sn1=[];
    return asn;
end
);



#############################################################################
##
#F  AllGeneratorsCyclicPGroup( <x>, p ) . . . . for a p-element <x> of a group
##
##  This operation computes all generators of the cyclic group
##  generated by the p-element <x>.
## 
##

InstallGlobalFunction(AllGeneratorsCyclicPGroup,function(x,p)
    local z,t;
    return List(Filtered([1..Order(x)], z->(z mod p)<>0),
                t->x^t);
end
  );

                   

#############################################################################
##
#M  IsPermutable( <G>, <H> ) . . . . for groups
##
##  This operation returns true if H is permutable in G, false otherwise.
##  H is permutable in G when H permutes with all subgroups of G.
##
InstallMethod(IsPermutableOp, "for finite groups",
        [IsGroup and IsFinite, IsGroup and
         IsFinite],
        function(g,h)
    local elg,z,P,hg,epi,g1,h1,h1q,gensh1q,r,gensr,x,y,g1q,q,bool1,bool2,
          ccsg1q,ccsh1q,u,su,i;
    
    if not IsSubgroup(g,h) 
       then
        Error("<h> must be a subgroup of <g>");
    fi;
    #
    # If the Why function has been computed, then use it.
    #
    bool1:=IsSubgroup(Parent(h), g);
    bool2:=IsSubgroup(g, Parent(h));
    if bool1 and HasOneSubgroupNotPermutingWithInParent(h)
       and OneSubgroupNotPermutingWithInParent(h)=fail
       then
        return true;
    elif
      bool2 and HasOneSubgroupNotPermutingWithInParent(h)
      and OneSubgroupNotPermutingWithInParent(h)<>fail
      then
        return false;
    fi;
    
    #
    # immediate methods: permutability is inherited by subgroups
    # and normal subgroups are permutable
    #    
    if bool1
       and ((HasIsNormalInParent(h) and IsNormalInParent(h)) or
            (HasIsPermutableInParent(h) and IsPermutableInParent(h)))
       then
        return true;
    fi;
    if bool2
       and (HasIsPermutableInParent(h) and not IsPermutableInParent(h))
       then
        return false;
    fi;
    
    #
    # permutable subgroups are subnormal, S-permutable, and conjugate-permutable
    #
    if bool1
       then
        if (HasIsSPermutableInParent(h) and  not IsSPermutableInParent(h)) or
           (HasIsConjugatePermutableInParent(h)
            and not IsConjugatePermutableInParent(h))
           then
            return false;
        fi;
    fi;
    #
    # normal subgroups are permutable. This check is cheaper than ours.
    #
    if IsNormal(g,h)
       then
        return true;
    fi;
    #
    # subgroups of Iwasawa nilpotent groups are permutable
    #
    if (IsPGroup(g) and (HasIsPTGroup(g) and IsPTGroup(g) or
               HasIsPTGroup(SylowSubgroup(g,PrimePGroup(g)))
               and IsPTGroup(SylowSubgroup(g,PrimePGroup(g)))))
       or
       (IsNilpotentGroup(g) and HasIsPTGroup(g) and IsPTGroup(g))
       or
       (IsNilpotentGroup(g) and
        ForAll(PrimesDividingSize(g),
               q->HasIsPTGroup(SylowSubgroup(g,q)) and 
               IsPTGroup(SylowSubgroup(g,q))))
       then
        return true;
    fi;
    
    #
    # we check whether the subgroup permute with some random cyclic
    # subgroups
    # 
    
    for i in [1..PermutMaxTries] do
        u:=Random(g);
        su:=Subgroup(g,[u]);
        if not ArePermutableSubgroups(g, su, h)
           then
            if bool1
               then
                SetOneSubgroupNotPermutingWithInParent(h, su);
            fi;
            return false;
        fi;
    od;
    
    
    #
    # permutable subgroups are subnormal
    #
    if not(IsSubnormal(g,h))
       then
        return false;
    fi;
    
    hg:=Core(g,h);
    epi:=NaturalHomomorphismByNormalSubgroup(g,hg);
    g1:=Image(epi);
    h1:=Image(epi,h);
    UseFactorRelation(g,hg,g1);
    
    #
    # permutable subgroups mod core are nilpotent (not difficult to check)
    #
    if not IsNilpotent(h1)
       then
        return false;
    fi;
    # permutable subgroups are hypercentrally embedded;
    # we check that the Sylow q-subgroup of h/h_g centralises
    # the Sylow r-subgroups of g/h_G for r <> q
    for q in PrimesDividingSize(h1)
      do
        h1q:=SylowSubgroup(h1,q);
        g1q:=SylowSubgroup(g1,q);
        UseFactorRelation(SylowSubgroup(g,q),hg,g1q);
        r:=PResidual(g1,q);
        gensh1q:=GeneratorsOfGroup(h1q);
        gensr:=GeneratorsOfGroup(r);
        #        if not ForAll(gensh1q,x->ForAll(gensh1q,y->y^x=y))
                if not ForAll(gensr,x->ForAll(gensh1q,y->y^x=y))
           then 
            return false;
        fi;
    od;
    ### Now we check that the Sylow $p$-subgroups of H/H_G
    ### permute with all cyclic $p$-subgroups of G/H_G
    
    for q in PrimesDividingSize(h1)
      do
        h1q:=SylowSubgroup(h1,q);
        g1q:=SylowSubgroup(g1,q);
        if not (HasIsPTGroup(g1q) and IsPTGroup(g1q)) then
            ccsg1q:=ConjugacyClassSubgroups(g1,g1q);
            ccsh1q:=ConjugacyClassSubgroups(g1,h1q);
            if Size(ccsg1q)<Size(ccsh1q) then
                elg:=Difference(Union(AsList(ccsg1q)),h1q);
                while elg<>[] do
                    x:=elg[1];
                    if not ArePermutableSubgroups(g1,h1q,Subgroup(g1,[x]))
                       then
                        return false;
                    fi;
                    elg:=Difference(elg,AllGeneratorsCyclicPGroup(x,q));
                od;
            else
                elg:=AsList(g1q);
                while elg<>[] do
                    x:=elg[1];
                    if not ForAll(ccsh1q, 
                               zz->ArePermutableSubgroups(g1,
                                       zz,Subgroup(g1,[x])))
                       then
                        return false;
                    fi;
                    elg:=Difference(elg,AllGeneratorsCyclicPGroup(x,q));
                od;
            fi;
        fi;
    od;
    return true;
    
      
end);


#############################################################################
##
#M  OneSubgroupNotPermutingWith( <G>, <H> ) . . . . for groups
##
## This operation finds a subgroup of G which does not permute with H
## if such a subgroup exists, otherwise it returns fail.
##
##
InstallMethod(OneSubgroupNotPermutingWithOp, "for finite groups",
        [IsGroup and IsFinite, IsGroup and IsFinite],
        function(g,h)
    local csg,z,w,bool1,bool2;
    if not IsSubgroup(g,h)
       then
        Error("<h> must be a subgroup of <g>");
    fi;
    bool1:=IsSubgroup(Parent(h),g);
    bool2:=IsSubgroup(g,Parent(h));
    if bool1 and bool2 then
        if HasOneSylowSubgroupNotPermutingWithInParent(h) and
           OneSylowSubgroupNotPermutingWithInParent(h)<>fail
           then
            return OneSylowSubgroupNotPermutingWithInParent(h);
        fi;
        if HasOneConjugateSubgroupNotPermutingWithInParent(h) and
           OneConjugateSubgroupNotPermutingWithInParent(h)<>fail
           then
            return OneConjugateSubgroupNotPermutingWithInParent(h);
        fi;
    fi;
    if bool1 and HasOneSubgroupNotPermutingWithInParent(h)
       and OneSubgroupNotPermutingWithInParent(h)=fail
       then
        SetIsPermutableInParent(h,true);
        return fail;
    fi;
    if bool2 and HasOneSubgroupNotPermutingWithInParent(h)
       and OneSubgroupNotPermutingWithInParent(h)<>fail
       then
        SetIsPermutableInParent(h,false);
        return OneSubgroupNotPermutingWithInParent(h);
    fi;
    
    
    
    w:=First(Zuppos(g),z->not ArePermutableSubgroups(g,h,Subgroup(g,[z])));
    if bool1 and bool2
       then SetIsPermutableInParent(h,w=fail);
    fi;
    if w=fail
       then
        return fail;
    fi;
    return Subgroup(g,[w]);
end);


#############################################################################
##
#M  PrimesDividingSize( <G> ) . . . . for groups
##
##  This attribute gives a list of primes dividing the size of G. It
##  has been borrowed from the GAP manual.
##
InstallMethod(PrimesDividingSize, "for finite groups", [IsGroup and
        IsFinite],
        G -> PrimeDivisors(Size(G)));


#############################################################################
##
#M  OneFSubgroupNotPermutingWith( <G>, <H>, <F> ) . . . . for groups
##
##  This operation returns fail if H permutes with all members of F
##  (a list of subgroups of G); otherwise it returns a member of F which 
##  does not permute with H.
##

InstallGlobalFunction( OneFSubgroupNotPermutingWith, function(g, h, f)
    local t,bool1,bool2,cex;
        if not IsSubgroup(g,h) 
       then
        Error("<h> must be a subgroup of <g>");
    fi;
    
    if not IsList(f) or ForAny(f, t->not IsSubgroup(g,t))
       then
        Error("<f> must be a list of subgroups of <g>");
    fi;
    
    bool1:=IsSubgroup(Parent(h),g);
    if bool1
       and
       (
        (HasIsPermutableInParent(h) and IsPermutableInParent(h))
        or
        (HasOneSubgroupNotPermutingWithInParent(h)
         and OneSubgroupNotPermutingWithInParent(h)=fail)
        )
       then
        return fail;
    fi;
    cex:=First(f, t->not ArePermutableSubgroups(g, h, t));
    bool2:=IsSubgroup(g,Parent(h));
    if cex<>fail and bool2 then
        if not HasIsPermutableInParent(h)
           then
            SetIsPermutableInParent(h,false);
        fi;
        if not HasOneSubgroupNotPermutingWithInParent(h)
           then
            SetOneSubgroupNotPermutingWithInParent(h,cex);
        fi;
    fi;
    return cex;
end
  );

     
#############################################################################
##
#M  IsFPermutable( <G>, <H>, <F> ) . . . . for groups
##
##  This operation returns true if a subgroup H of G permutes
##  with all the members of F, where F is a list of subgroups of G.
##

InstallGlobalFunction( IsFPermutable, function(g,h,f)
    return OneFSubgroupNotPermutingWith(g,h,f)=fail;
end
  );

#############################################################################
##
#M  SylowSubgroups( <G> ) . . . . for groups
##
##  This attribute gives a list of one Sylow subgroup for every prime
##  dividing  the size of G
##

#For soluble groups, we get a Sylow system.
InstallMethod(SylowSubgroups, "for finite soluble groups",
        [IsGroup and IsFinite and IsSolvableGroup],
        function(g)
    return SylowSystem(g);
end);

# Otherwise, we simply compute a Sylow subgroup for each prime
# dividing the order of the group.
InstallMethod(SylowSubgroups, "for finite groups", [IsGroup and
        IsFinite],
        function(g)
    return List(PrimesDividingSize(g),p->SylowSubgroup(g,p));
end);


#############################################################################
##
#M  OneSylowSubgroupNotPermutingWith( <G>, <H> ) . . . . for groups
##
## This operation finds a Sylow subgroup of G which does not permute 
## with H if such a subgroup exists, otherwise it returns false.
##
##
InstallMethod(OneSylowSubgroupNotPermutingWithOp, "for finite groups",
        [IsGroup and IsFinite, IsGroup and IsFinite],
        function(g,h)
    local sylows,z,r,x,y;
    if not IsSubgroup(g,h) 
       then
        Error("<h> must be a subgroup of <g>");
    fi;

    if IsNilpotentGroup(g)
       then
        SetIsPSTGroup(g,true);
        return fail ;
    elif HasIsPSTGroup(g) and IsPSTGroup(g) and IsSubnormal(g,h)
      then
        return fail;
    elif HasIsNormalInParent(h) and IsNormalInParent(h)
      then
        return fail;
    elif IsNormal(g,h)
      then
        return fail;
    elif HasIsPermutableInParent(h) and IsPermutableInParent(h)
      then
        return fail;
    elif IsPGroup(h) # h cannot be trivial at this stage
      then
        r:=PResidual(g,PrimePGroup(h));
        if  ForAll(GeneratorsOfGroup(r),
                   x->ForAll(GeneratorsOfGroup(h),y->y^x in h))
            then
            return fail;
        fi;
    fi;
    sylows:=Union(List(SylowSubgroups(g),z->ConjugateSubgroups(g,z)));
    return First(sylows,z->not ArePermutableSubgroups(g,h,z));
end);

#############################################################################
##
#M  OneSystemNormalizerNotPermutingWith( <G>, <H> ) . . . . for groups
##
##  This operation finds a system normalizer of the soluble groups G
##  which does not permute with H if such a subgroup exists, fail otherwise.
##
##
InstallMethod(OneSystemNormalizerNotPermutingWithOp, "for finite soluble groups",
        [IsGroup and IsFinite and IsSolvableGroup, IsGroup and IsFinite],
        function(g,h)
    local sysnor,sysnors,z,bool1;
    if not IsSubgroup(g,h) 
       then
        Error("<h> must be a subgroup of <g>");
    fi;
    
    bool1:=IsSubset(Parent(h),g);
    if HasIsPermutableInParent(h) and IsPermutableInParent(h) and bool1
       then
        return fail;
    else
 sysnor:=SystemNormalizer(g);
        sysnors:=AsList(ConjugacyClassSubgroups(g,sysnor));
        return First(sysnors,z->not ArePermutableSubgroups(g,h,z));
    fi;
end);

#############################################################################
##
#M  IsSPermutable( <G>, <H> ) . . . . for groups
##
##  This operation returns true if a subgroup H of G is S-permutable,
##  and false otherwise. 
##
InstallMethod(IsSPermutableOp, "for finite groups",
        [IsGroup and IsFinite, IsGroup and
         IsFinite],
        function(g,h)
    local sylows,z,cex,hg,pi,hhg,hp,hghp,p,gens,gensp,gensr,r,y,x;
    if not IsSubgroup(g,h)
       then
        Error("<h> must be a subgroup of <g>");        
    elif not(IsSubnormal(g,h))
       then
        return false;
    fi;
    if IsNormal(g,h)
       then
        return true;
    fi;
    if IsSubgroup(Parent(g),h) and HasIsPermutableInParent(h)
       and IsPermutableInParent(h)
       then
        return true;
    else
        hg:=Core(g,h);
        hhg:=h/hg;
        pi:=PrimesDividingSize(hhg);
        if not IsNilpotent(hhg)
           then
            return false;
        fi;
        for p in pi
          do
            hp:=SylowSubgroup(h,p);
            r:=PResidual(g,p);
            gensr:=GeneratorsOfGroup(r);
            gensp:=GeneratorsOfGroup(hp);
            gens:=Union(GeneratorsOfGroup(hg),gensp);
            hghp:=Subgroup(h,gens);
            if not ForAll(gensp,x->ForAll(gensr,y->x^y in hghp))
               then
                return false;
            fi;
        od;
        return true;
    fi;
end);

#############################################################################
##
#M  IsSNPermutable( <G>, <H> ) . . . . for groups
##
##  This operation returns true a subgroup H of a soluble group G
##  is SN-permutable, and false otherwise. 
##  H is SN-permutable in G when H permutes with all system normalizers of G.
##
InstallMethod(IsSNPermutableOp, "for finite groups",
        [IsGroup and IsFinite, IsGroup and
         IsFinite],
        function(g,h)
    local sylows,z,cex;
    if not IsSolvableGroup(g)
       then
        Error("<g> must be a solvable group");
    fi;
    if not IsSubgroup(g,h)
       then
        Error("<h> must be a subgroup of <g>");
    fi;
    #
    # SN-permutable subgroups are subnormal.
    #
    if not(IsSubnormal(g,h)) then
        return false;
    fi;
    #
    # Permutable subgroups are SN-permutable.
    #
    if HasIsPermutableInParent(g) and IsPermutableInParent(g)
       then
        return true;
    else
        cex:=OneSystemNormalizerNotPermutingWith(g,h);
        return cex=fail;
    fi;
end);


#############################################################################
##
#M  OneConjugateSubgroupNotPermutingWith( <G>, <H> ) . . . . for groups
##
##  This operation finds a conjugate subgroup of H which does not permute
##  with H if such a subgroup exists, otherwise it returns fail.
##

InstallMethod(OneConjugateSubgroupNotPermutingWithOp, "for finite groups",
        [IsGroup and IsFinite, IsGroup and IsFinite],
        function(G,H)
    local z,cex;
    if not IsSubgroup(G,H)
       then
        Error("<h> must be a subgroup of <g>");
        #
        # Permutable subgroups are conjugate-permutable.
        #
    elif HasIsPermutableInParent(H) and IsPermutableInParent(H)
      then
        return fail;
    else
        cex:=First(ConjugateSubgroups(G,H), 
                   z->not ArePermutableSubgroups(G,H,z));
        return cex;
    fi;
end);

#############################################################################
##
#M  IsConjugatePermutable( <G>, <H> ) . . . . for groups
##
##  This operation returns true if the subgroup H of G is
##  conjugate-permutable, and false otherwise.
##  H is conjugate-permutable in G when H permutes with H^g for every g of G.
##

InstallMethod(IsConjugatePermutableOp, "for finite groups",
        [IsGroup and IsFinite, IsGroup and IsFinite],
        function(G,H)
    local z,cex;
    if not IsSubgroup(G,H)
       then
        Error("<H> must be a subgroup of <G>");
        #
        # normal subgroups are conjugate-permutable
        #
    elif HasIsNormalInParent(H) and IsNormalInParent(H)
      then
        return true;
    else
        cex:=OneConjugateSubgroupNotPermutingWith(G,H);
        return cex=fail;
    fi;
end);

#############################################################################
##
#M  OneElementShowingNotWeaklyNormal( <G>, <H> ) . . . . for groups
##
##  This operation finds an element g of G such that H normal <H, H^g>
##  but H not normal in <H,g> if such an element exists, fail otherwise.
##  H is weakly normal in G when H normal in <H,H^g> implies H normal in <H,g>.
##

InstallMethod(OneElementShowingNotWeaklyNormalOp, "for finite groups",
        [IsGroup and IsFinite, IsGroup and IsFinite],
        function(g,h)
    local x,cex,n;
    n:=Normalizer(g,h);
    if not IsSubgroup(g,h) 
       then
        Error("<h> must be a subgroup of <g>");
    fi;
    cex:=First(RightTransversal(g, n), 
               x->IsSubgroup(n, ConjugateSubgroup(h,x))
               and not x in n);
    return cex;
end);
        
#############################################################################
##
#M  IsWeaklyNormal( <G>, <H> ) . . . . for groups
##
##  This operation returns true if a subgroup H of G is
##  weakly normal, false otherwise.
##  H is weakly normal when H^g\le N_G(H) implies g\in N_G(H)
##

InstallMethod(IsWeaklyNormalOp, "for finite groups",
        [IsGroup and IsFinite, IsGroup and IsFinite],
        function(g,h)
    local x,cex;
    cex:=OneElementShowingNotWeaklyNormal(g,h);
    return cex=fail;
end);
        
#############################################################################
##
#M  OneElementShowingNotWeaklySPermutable( <G>, <H> ) . . . . for groups
##
##  This operation finds an element g of G such that H Sper <H, H^g>
##  but H not Sper <H,g> if such an element exists, fail otherwise.
##  H is weakly S-permutable in G when H Sper <H,H^g> implies H Sper <H,g>.
##

InstallMethod(OneElementShowingNotWeaklySPermutableOp, "for finite groups",
        [IsGroup and IsFinite, IsGroup and IsFinite],
        function(g,h)
    local x,cex;
    if not IsSubgroup(g,h) 
       then
        Error("<h> must be a subgroup of <g>");
    fi;
    cex:=First(RightTransversal(g,h),x->
               IsSPermutable(
                       Subgroup(g,
                               Union(
                                     GeneratorsOfGroup(h),
                                     GeneratorsOfGroup(
                                             ConjugateSubgroup(h,x))
                                     )),
                       h
                       )
               and not IsSPermutable(
                       Subgroup(g,Union(GeneratorsOfGroup(h),[x])),
                       h
                       ));
    return cex;
end);

#############################################################################
##
#M  IsWeaklySPermutable( <G>, <H> ) . . . . for groups
##
##  This operation returns true if a subgroup H of G is
##  weakly S-permutable, false otherwise.
##  H is weakly S-permutable in G when H Sper <H,H^g> implies H Sper <H,g>.
##

InstallMethod(IsWeaklySPermutableOp, "for finite groups",
        [IsGroup and IsFinite, IsGroup and IsFinite],
        function(g,h)
    local x,cex;
    cex:=OneElementShowingNotWeaklySPermutable(g,h);
    return cex=fail;
end);
        
#############################################################################
##
#M  OneElementShowingNotWeaklyPermutable( <G>, <H> ) . . . . for groups
##
##  This operation find an element g such that H per <H, H^g> but
##  H not per <H, g> if such an element exists, fail otherwise.
##  H is permutable in G when H per <H,H^g> implies H per <H,g>.
##

InstallMethod(OneElementShowingNotWeaklyPermutableOp, "for finite groups", [IsGroup and
        IsFinite, IsGroup and IsFinite],
        function(g,h)
    local x;
    if not IsSubgroup(g,h) 
       then
        Error("<h> must be a subgroup of <g>");
    fi;
    return First(RightTransversal(g,h),x->
                 IsPermutable(
                         Subgroup(g,
                                 Union(
                                       GeneratorsOfGroup(h),
                                       GeneratorsOfGroup(
                                               ConjugateSubgroup(h,x)
                                               )
                                       )
                                 ),
                         h
                         )
                 and not IsPermutable(
                         Subgroup(g,Union(GeneratorsOfGroup(h),[x])),
                         h
                         )
                 );
end);
    
#############################################################################
##
#M  IsWeaklyPermutable( <G>, <H> ) . . . . for groups
##
##  This operation returns true if a subgroup H of G is
##  weakly permutable, false otherwise.
##  H is weakly permutable  in G when H per <H, H^g> implies H per <H, g>.
##

InstallMethod(IsWeaklyPermutableOp, "for finite groups", [IsGroup and
        IsFinite, IsGroup and IsFinite],
        function(g,h)
    local x,cex;
    cex:=OneElementShowingNotWeaklyPermutable(g,h);
    return cex=fail;
end);

#############################################################################
##
#M  OneSubnormalNonPermutableSubgroup( <G> ) . . . . for finite groups
##
##  The default method finds a non conjugate-permutable subnormal subgroup
##  of G if there exists one such subgroup, it returns fail otherwise.
##

InstallMethod(OneSubnormalNonPermutableSubgroup,"for finite PT-groups",
        [IsGroup and IsFinite and IsPTGroup],
        function(G)
    local z;
    return fail;
end);

InstallMethod(OneSubnormalNonPermutableSubgroup, "for finite groups with AllSubnormalSubgroups",
        [IsGroup and IsFinite and HasAllSubnormalSubgroups],
        function(G)
    local x;
    return First(AllSubnormalSubgroups(G),x->not IsPermutable(G,x));
end
  );

# If we do not know whether the group is a PT-group,
# we look for a subnormal subgroup which is not permutable.

InstallMethod(OneSubnormalNonPermutableSubgroup,"for finite groups non PT-groups",
        [IsGroup and IsFinite],
        function(G)
    local z,ex,ns,nsz,sns,t,new,sn1,sn0,w,asn,x;
    if HasOneSubnormalNonSPermutableSubgroup(G) and OneSubnormalNonSPermutableSubgroup(G)<>fail
       then
        return OneSubnormalNonSPermutableSubgroup(G);
    fi;
    if HasOneSubnormalNonConjugatePermutableSubgroup(G) and OneSubnormalNonConjugatePermutableSubgroup(G)<>fail
       then
        return OneSubnormalNonConjugatePermutableSubgroup(G);
    fi;
    sn0:=Set(NormalSubgroups(G));
    asn:=ShallowCopy(sn0);
    repeat
        sn1:=[];
        for x in sn0
          do
            new:=Filtered(NormalSubgroups(x),
                         x->not x in asn and not x in sn1);
            w:=First(new,z->not IsPermutable(G,z));
            if w<>fail
               then
                SetIsPTGroup(G,false);
                SetIsTGroup(G,false);
                return w;
            fi;
            UniteSet(sn1,new);
            
        od;
        sn0:=sn1;
        UniteSet(asn,sn1);
    until sn1=[];
    SetAllSubnormalSubgroups(G,asn);
    SetIsPTGroup(G, true);
    SetIsCPTGroup(G, true);
    SetIsPSTGroup(G, true);
    SetIsPSNTGroup(G, true);
    return fail;
end);

#############################################################################
##
#M  IsAbCp( <G>, <p> ) . . . . for finite groups
##
## Returns true if the group has an abelian Sylow p-subgroup P and every
## subgroup of P is normalised by N_G(P), false otherwise.
##

InstallMethod(IsAbCpOp,
        "generic method for group and prime",
        [IsGroup and IsFinite,IsPosInt],
        function(G,p)
    local gN,P,a,n,c,e,nc,b,r,t,compiscps,pos,i,u;
    # if p does not divide |G|, it is true
    if (Size(G) mod p)<>0 
       then 
        return true;
    fi;
    P:=SylowSubgroup(G,p);
    if not IsAbelian(P)
       then
        return false;
    fi;
    # Now P is abelian. We check if being Cp is stored
    compiscps:=ComputedIsCps(G);
    pos:=Position(compiscps{[1,3..Length(compiscps)-1]},p);
    if pos<>fail
       then
        return IsAbCp(G,p);
    fi;
       
    if p=Minimum(PrimesDividingSize(G))
       then 
        return IsPNilpotent(G,p);
    fi;
    n:=Normalizer(G,P);
    # we enforce this test before computing the discrete logarithm
    if ForAny(GeneratorsOfGroup(P),t->not IsNormal(n,Subgroup(G,[t])))
       then
        return false;
    fi;

    c:=Centralizer(G,P);
    if IsSubgroup(c,n)
       then
        return true;
    fi;    
    e:=NaturalHomomorphismByNormalSubgroup(n,c);
    nc:=Image(e);
    if not IsCyclic(nc)
       then
        return false;
    fi;
    a:=First(GeneratorsOfGroup(P),t->Order(t)=Exponent(P));
    b:=PreImagesRepresentative(e,MinimalGeneratingSet(nc)[1]);
    r:=First([1..Exponent(P)-1],t->a^b=a^t);
    return ForAll(GeneratorsOfGroup(P),t->t^b=t^r);
end
  );



#############################################################################
##
#M  IsDedekindSylow( <G>, <p> ) . . . . for finite groups
##
##  Returns true if a Sylow p-subgroup of G is Dedekind, else returns false
##

InstallGlobalFunction(IsDedekindSylow, function(G,p)
    local P,res,epi,a1,a2,mgs;
    P:=SylowSubgroup(G,p);
    if HasIsTGroup(P)
       then 
        return IsTGroup(P);
    elif p>2 then
        res:=IsAbelian(P);
        SetIsTGroup(P,res);
        return res;
    else
        if IsAbelian(P)
           then
            SetIsTGroup(P,true);
            return true;
        else
            #
            # the group should be a direct product of 
            # an elementary abelian group and a quaternion group
            #
            if Size(FrattiniSubgroup(P))<>2
               then
                SetIsTGroup(P,false);
                return false;
            elif Exponent(Centre(P))>2 or Index(P,Centre(P))<>4
              then
                SetIsTGroup(P,false);
                return false;
            else

                epi:=NaturalHomomorphismByNormalSubgroup(P,Centre(P));
                mgs:=MinimalGeneratingSet(Image(epi));
                a1:=PreImagesRepresentative(epi,mgs[1]);
                a2:=PreImagesRepresentative(epi,mgs[2]);
                if Order(a1)<>4 or Order(a2)<>4  then
                    SetIsTGroup(P,false);
                    return false;
                else
                    SetIsTGroup(P,true);
                    return true;
                fi;
            fi;
            
        fi;
    fi;
end
  );


#############################################################################
##
#M  IsIwasawaSylow( <G>, <p> ) . . . . for finite groups
##
##  Returns true if a Sylow p-subgroup of G is modular, else returns false
##

InstallGlobalFunction(IsIwasawaSylow,function(G,p)
    local P,z,ex,x,l,l1,l2,res,u,v,gu,gv,i;
    P:=SylowSubgroup(G,p);
    if (HasIsPTGroup(P))
       then
        return IsPTGroup(P);
    elif IsAbelian(P)
      then
        SetIsTGroup(P,true);
        SetIsPTGroup(P,true);
        return true;
    else
        # first we check permutability of a few subgroup pairs
        for i in [1..PermutMaxTries] do
            u:=Random(P);
            v:=Random(P);
            gu:=Subgroup(P,[u]);
            gv:=Subgroup(P,[v]);
            if not ArePermutableSubgroups(P, gu, gv)
               then
                SetIsTGroup(P,false);
                SetIsPTGroup(P,false);
                SetOneSubnormalNonSPermutableSubgroup(P,gu);
                SetOneSubnormalNonPermutableSubgroup(P,gu);
                return false;
            fi;
        od;
        # Now we apply the general method
        res:=IwasawaTriple(P);
        if res=fail
           then
            SetIsTGroup(P, false);
            SetIsPTGroup(P,false);
            return false;
        elif res=[]
          then
            SetIsPTGroup(P,true);
            SetIsTGroup(P,true);
            return true;
        elif p=2
          then
            SetIsTGroup(P,false);
            SetIsPTGroup(P,res[3]<>1);
            return res[3]<>1;
        else
            SetIsTGroup(P,false);
            SetIsPTGroup(P,true);
            return true;
        fi;
    fi;
end
  );


#############################################################################
##
#M  IsCp( <G>, <p> ) . . . . for finite groups
##
## Returns true if every subgroup of a Sylow p-subgroup P of G
## is normalised by N_G(P), false otherwise.
##

InstallMethod(IsCpOp,
        "generic method for a finite group and prime",
        [IsGroup and IsFinite,IsPosInt],
        function(g,p)
    local a,compisabcp,pos,P;
    
    P:=SylowSubgroup(g,p);
    compisabcp:=ComputedIsAbCps(g);
    pos:=Position(compisabcp{[1,3..Length(compisabcp)-1]},p);
    if p<>fail then
        if IsAbCp(g,p)
           then
            return true;
        elif IsAbelian(P)
          then
            return false;
        fi;
    fi;
    return (IsPNilpotent(g,p) and IsDedekindSylow(g,p)) or IsAbCp(g,p);
end
);


#############################################################################
##
#M  IsXp( <G>, <p> ) . . . . for finite groups
##
## Returns true if every subgroup of a Sylow p-subgroup P of G
## is permutable in N_G(P), false otherwise.
##

InstallMethod(IsXpOp,
        "generic method for a finite group and a prime",
        [IsGroup and IsFinite,IsPosInt],
        function(g,p)
    local a,compisabcp,pos,P;
    
    P:=SylowSubgroup(g,p);
    compisabcp:=ComputedIsAbCps(g);
    pos:=Position(compisabcp{[1,3..Length(compisabcp)-1]},p);
    if p<>fail then
        if IsAbCp(g,p)
           then
            return true;
        fi;
    fi;
    return (IsPNilpotent(g,p) and IsIwasawaSylow(g,p)) or IsAbCp(g,p);
end
);

#############################################################################
##
#M  IsYp( <G>, <p> ) . . . . for finite groups
##
## Returns true if for every p-subgroups H and K such that $H\le K$,
## $H$ is S-permutable in N_G(K), false otherwise.
## 
##

InstallMethod(IsYpOp,
        "generic method for group and prime",
        [IsGroup and IsFinite,IsPosInt],
        function(g,p)
    local a,compisabcp,pos,P;
    
    P:=SylowSubgroup(g,p);
    compisabcp:=ComputedIsAbCps(g);
    pos:=Position(compisabcp{[1,3..Length(compisabcp)-1]},p);
    if p<>fail then
        if IsAbCp(g,p)
           then
            return true;
        fi;
    fi;
    return IsPNilpotent(g,p) or IsAbCp(g,p);
end
);

#############################################################################
##
#F  IwasawaTripleWithSubgroup( <G>, <X>, <p> ) . . . . for finite groups
##
##  Returns an Iwasawa triple of the p-group g such that x belongs to it
##  if it exists one, fail otherwise.
##

InstallGlobalFunction(IwasawaTripleWithSubgroup,function(g,x,p)
    local a,b,c,d,e,h,s,t,res;
    ### We make sure that every generator spans a normal subgroup,
    ### otherwise there cannot be an Iwasawa triple
    if ForAny(GeneratorsOfGroup(x),t->not IsNormal(g,Subgroup(g,[t])))
       then 
        return fail;
    fi;
    e:=NaturalHomomorphismByNormalSubgroup(g,x);
    h:=Image(e);
    b:=PreImagesRepresentative(e,MinimalGeneratingSet(h)[1]);
    a:=First(GeneratorsOfGroup(x),t->Order(t)=Exponent(x));
    #    Print("a");
    for c in AllGeneratorsCyclicPGroup(b,p) do
        s:=First([1..Log(Order(a),p)],t->a^c=a^(1+p^t));
        #        Print("#I c=", c,"\ts=",s,"\n");
        if s<>fail
           then 
            res:=ForAll(GeneratorsOfGroup(x),t->t^c=t^(1+p^s));
            if res
               then 
                return [x,c,s];
            fi;
        fi;
    od;
    return fail;
end
  );


#############################################################################
##
#M  IwasawaTriple( <G> ) . . . . for finite groups
##
##  Computes an Iwasawa triple for the p-group G
##


InstallMethod(IwasawaTriple,"for finite p-groups",
        [IsGroup and IsFinite],
        function(P)
    local p,z,ex,x,l,l1,l2,res;
    if not IsPGroup(P) 
       then 
        Error("<P> must be a p-group for a prime p");
    elif IsTrivial(P)
      then
        #
        # We use this arbitrarily chosen value 
        # to avoid an error in the trivial case
        #
        return [P, Identity(P), 3];
    elif HasIsPTGroup(P) and not IsPTGroup(P)
      then
        # If we know that the group is not Iwasawa, there is no such triple
        return fail;
    else
    p:=PrimePGroup(P);
        if IsAbelian(P) 
           then
            return [P,Identity(P),Log(Exponent(P),p)];
        elif not IsAbelian(DerivedSubgroup(P))      # group should be metabelian
          then
            return fail;
        elif p=2 and Exponent(P)=4 
          then 
            if IsTGroup(P) then return []; else return fail; fi;
        else       
            # We apply Iwasawa's theorem by looking
            # for an abelian subgroup with cyclic quotient
            l:=[P];
            repeat
                x:=l[Length(l)];
                Unbind(l[Length(l)]);
                l1:=Filtered(MaximalSubgroups(x),
                            t->IsNormal(P,t) and IsCyclic(P/t));
                l:=Concatenation(l1,l);
                l2:=Filtered(l1,IsAbelian);
                for x in l2
                  do
                    res:=IwasawaTripleWithSubgroup(P,x,p);
                    if res<>fail
                       then
                        return res; 
                    fi;
                od;
            until l=[];
            return fail;
        fi;        
    fi;
end);
    
    
#############################################################################
##
#M  IsPTGroup( <G> ) . . . . for finite groups
##
##  Returns true if the group is a PT-group, else returns false 
##

InstallMethod(IsPTGroup,"for finite solvable groups",
        [IsGroup and IsFinite and IsSolvableGroup],
        function(G)
    local p;

    if HasIsPSTGroup(G) and not IsPSTGroup(G)
       then
        return false;
    elif HasIsCPTGroup(G) and not IsCPTGroup(G)
      then
        return false;
    elif IsSupersolvableGroup(G)
      #
      # for solvable groups, we use the property Yp + modular Sylow
      # subgroups
      #
      then
        return(ForAll(PrimesDividingSize(G),
                      p->(IsPNilpotent(G,p) and IsIwasawaSylow(G,p)) 
                      or IsAbCp(G,p)));
    else
        return false;
    fi;
end);

InstallMethod(IsPTGroup,"for finite groups",
        [IsGroup and IsFinite],
        function(G)
    local p;

    if HasIsPSTGroup(G) and not IsPSTGroup(G)
       then
        return false;
    fi;
    if HasIsCPTGroup(G) and not IsCPTGroup(G)
       then
        return false;
    fi;
    if IsSolvable(G)
       then
        return IsPTGroup(G);
    elif IsSCGroup(G)
      then
        #
        # we use the definition
        #
        return(OneSubnormalNonPermutableSubgroup(G)=fail);
    else 
        return false;
    fi;
end);

#############################################################################
##
#M  OneSubnormalNonSPermutableSubgroup( <G> ) . . . . for finite groups
##
##  The default method finds a non S-permutable subnormal subgroup of G
##  if such a subgroup exists, fail otherwise.
##

# If the group is a PST-group, return fail
InstallMethod(OneSubnormalNonSPermutableSubgroup,"for finite PST-groups",
        [IsGroup and IsFinite and IsPSTGroup],
        function(G)
    local z;
    return fail;
end);

# If we do not know whether the group is a PST-group,
# we try to find a subnormal subgroup of defect 2
# which is not S-permutable.

InstallMethod(OneSubnormalNonSPermutableSubgroup,"for finite groups non PST-groups",
        [IsGroup and IsFinite],
        function(G)
    local z,ex,ns,nsz,t;
    ns:=NormalSubgroups(G);
    for z in ns
      do
        nsz:=NormalSubgroups(z);
        ex:=First(nsz,t->not IsSPermutable(G,t));
        if ex<>fail
           then 
            SetIsPTGroup(G, false);
            SetIsTGroup(G, false);
            SetIsPSTGroup(G, false);
            return ex;
        fi;
    od;
    SetIsPSTGroup(G, true);
    return fail;
end);


#############################################################################
##
#M  OneSubnormalNonSNPermutableSubgroup( <G> ) . . . . for finite groups
##
##  The default method finds a non SN-permutable subnormal
## (permutable with all system normalisers) subgroup 
##  of the soluble group G if such a subgroup exists, fail otherwise.
##

# If the group is a PSNT-group, return fail.

InstallMethod(OneSubnormalNonSNPermutableSubgroup,"for finite PSNT-groups",
        [IsGroup and IsFinite and IsSolvableGroup and IsPSNTGroup],
        function(G)
    local z;
    return fail;
end);


# If we do not know whether the group is a PSNT-group,
# we try to find a subnormal subgroup
# which is not S-permutable.

InstallMethod(OneSubnormalNonSNPermutableSubgroup,"for finite groups",
        [IsGroup and IsFinite],
        function(G)
    local z,ex,ns,nsz,sns,d,t;
    if not IsSolvableGroup(G)
       then
        Error("<G> must be a solvable group");
    fi;
    sns:=AllSubnormalSubgroups(G);
    d:=SystemNormalizer(G);
    ex:=First(sns,t->not ArePermutableSubgroups(G,d,t));
    if ex<>fail
       then
        SetIsPSNTGroup(G, false);
    else
     SetIsPSNTGroup(G, true);
    fi;
    return ex;

end);




#############################################################################
##
#M  IsPSTGroup( <G> ) . . . . for finite groups
##
##  Returns true if the group is a PST-group, else returns false 
##


InstallMethod(IsPSTGroup,"for finite solvable groups",
        [IsGroup and IsFinite and IsSupersolvableGroup],
        function(G)
    local p;
    #
    # For finite soluble groups, we characterise it via Yp for all primes p:
    # p-nilpotent or abelian with Cp
    #
    return ForAll(PrimesDividingSize(G),
                  p->IsPNilpotent(G,p) or IsAbCp(G,p));
end);

InstallMethod(IsPSTGroup,"for finite groups",
        [IsGroup and IsFinite],
        function(G)
    local p;
    #
    # For finite soluble groups, we characterise it via Yp for all primes p:
    # p-nilpotent or abelian with Cp
    #
    if IsSolvable(G)
       then
        if not IsSupersolvableGroup(G)
           then
            return false;
        else
            return IsPSTGroup(G);
        fi;
    else
        if not IsSCGroup(G)
           then
            return false;
        else
            #
            # For non-solvable groups, we use the definition
            #
            return (OneSubnormalNonSPermutableSubgroup(G)=fail);
        fi;
    fi;
end);

#############################################################################
##
#M  IsPSNTGroup( <G> ) . . . . for finite groups
##
##  Returns true if the soluble group is a PSNT-group, else returns false 
##  A soluble group is a PSNT-group if permutability with system
##  normalisers is transitive.
##



InstallMethod(IsPSNTGroup, "for finite groups",
        [IsGroup and IsFinite],
        function(G)
    if IsSolvableGroup(G)
       then
        return (OneSubnormalNonSNPermutableSubgroup(G)=fail);
    else
        Error("<G> must be a solvable group");
    fi;
end
  );


#############################################################################
##
#M  OneSubnormalNonConjugatePermutableSubgroup( <G> ) . . . . for finite groups
##
##  The default method finds a non conjugate-permutable subnormal subgroup
##  of G if such a subgroup exists, fail otherwise.
##

# If the group is CPT, then return fail
InstallMethod(OneSubnormalNonConjugatePermutableSubgroup,"for finite CPT-groups",
        [IsGroup and IsFinite and IsCPTGroup],
        function(G)
    local z;
    return fail;
end);

# If we do not know whether the group is CPT, the same check would be valid
InstallMethod(OneSubnormalNonConjugatePermutableSubgroup,"for finite groups with AllSubnormalSubgroups",
        [IsGroup and IsFinite and HasAllSubnormalSubgroups],
        function(G)
    local z,ex;
    
    ex:=First(AllSubnormalSubgroups(G),z->not IsConjugatePermutable(G,z));
# Now it is easy to know whether the group is CPT
    if (ex=fail)
       then
        SetIsCPTGroup(G,true);
    else
        SetIsCPTGroup(G,false);
    fi;
    return ex;
end);

# If we do not know whether the group is a CPT-group,
# we look for a subnormal subgroup which is not conjugate-permutable.

InstallMethod(OneSubnormalNonConjugatePermutableSubgroup,"for finite groups non CPT-groups",
        [IsGroup and IsFinite],
        function(G)
    local z,ex,ns,nsz,sns,t,new,sn1,sn0,w,asn,x;
    
    sn0:=Set(NormalSubgroups(G));
    asn:=ShallowCopy(sn0);
    repeat
        sn1:=[];
        for x in sn0
          do
            new:=Filtered(NormalSubgroups(x),
                         x->not x in asn and not x in sn1);
            w:=First(new,z->not IsConjugatePermutable(G,z));
            if w<>fail
               then
                SetIsCPTGroup(G,false);
                SetIsPTGroup(G,false);
                SetIsTGroup(G,false);
                SetOneSubnormalNonPermutableSubgroup(G,w);
                SetOneSubnormalNonNormalSubgroup(G,w);
                return w;
            fi;
            UniteSet(sn1,new);
            
        od;
        sn0:=sn1;
        UniteSet(asn,sn1);
    until sn1=[];
    SetAllSubnormalSubgroups(G,asn);
    SetIsCPTGroup(G, true);
    return fail;
end);


#############################################################################
##
#M  IsCPTGroup( <G> ) . . . . for finite groups
##
##  Returns true if the group is a CPT-group (every subnormal subgroup
##  is conjugate-permutable), else returns false 
##


# For finite groups in general, we use the definition
InstallMethod(IsCPTGroup,"for finite groups",
        [IsGroup and IsFinite],
        function(G)
    local z,ex;
    ex:=OneSubnormalNonConjugatePermutableSubgroup(G);
    return (ex=fail);
end);

#############################################################################
##
#M  OneSubnormalNonNormalSubgroup( <G> ) . . . . for finite groups
##
##  The default method finds a non-normal subnormal subgroup of G 
##  if such a subgroup exists, otherwise returns false.
##

InstallMethod(OneSubnormalNonNormalSubgroup, "for finite groups with AllSubnormalSubgroups",
        [IsGroup and IsFinite and HasAllSubnormalSubgroups],
        function(G)
    local x;
    return Difference(AllSubnormalSubgroups(G),NormalSubgroups(G))=[];
end
  );

InstallMethod(OneSubnormalNonNormalSubgroup,"for finite groups non T-groups",
        [IsGroup and IsFinite],
        function(G)
    local z,ex,ns,nsz,t;
    ns:=NormalSubgroups(G);
    for z in ns
      do
        nsz:=NormalSubgroups(z);
        ex:=First(nsz,t->not IsNormal(G,t));
        if ex<>fail
           then 
            SetIsTGroup(G, false);
            return ex;
        fi;
    od;
    SetIsTGroup(G, true);
    return fail;
end);


#############################################################################
##
#M  IsTGroup( <G> ) . . . . for finite groups
##
##  Returns true if the group is a T-group, else returns false 
##

InstallMethod(IsTGroup,"for finite solvable groups",
        [IsGroup and IsFinite and IsSolvableGroup],
        function(G)
    local p;
    #
    # For finite soluble groups, we characterise it via Cp for all primes p:
    # p-nilpotent or abelian with Cp + Sylow Dedekind
    #
    if IsSupersolvableGroup(G)
       then
        return ForAll(PrimesDividingSize(G),
##                      p->(IsPERMUTPNilpotent(G,p) and IsDedekindSylow(G,p))
                      p->(IsPNilpotent(G,p) and IsDedekindSylow(G,p))
                      or IsAbCp(G,p));
    else
        return false;
    fi;
end);

InstallMethod(IsTGroup,"for finite groups",
        [IsGroup and IsFinite],
        function(G)
    local p;
    #
    # For finite soluble groups, we characterise it via Cp for all primes p:
    # p-nilpotent or abelian with Cp + Sylow Dedekind
    #
    if IsSolvable(G)
       then
        return IsPSTGroup(G);
    elif IsSCGroup(G)
      then
        
        #
        # For non-solvable groups, we use the definition
        #
        return (OneSubnormalNonNormalSubgroup(G)=fail);
    else
        return false;
    fi;
end);


#############################################################################
#############################################################################
##
#M  IsSCGroup( <G> ) . . . . for finite groups
##
##  Returns true if the group is an SC-group, and false otherwise.
##  A group is an SC-group if all its chief factors are simple.
##
##

InstallMethod(IsSCGroup, "for finite solvable groups",
        [IsGroup and IsFinite and IsSolvableGroup],
        function(g)
    return IsSupersolvableGroup(g);
end
  );

InstallMethod(IsSCGroup, "for finite groups with chief series",
        [IsGroup and IsFinite and HasChiefSeries],
        function(g)
    local cs,j,fact;
    cs:=ChiefSeries(g);
    fact:=List([1..Length(cs)-1],j->cs[j]/cs[j+1]);
    return ForAll(fact,IsSimple);
end
  );

InstallMethod(IsSCGroup, "generic method for a finite group",
        [IsGroup and IsFinite],
        function(g)
    local cs;
    if IsSolvable(g)
       then
        return IsSupersolvableGroup(g);
    else
        cs:=ChiefSeries(g);
        return IsSCGroup(g);
    fi;
end
  );

#############################################################################
##
#M  OneSubgroupInWhichSubnormalNotNormal( <G>, <H> ) . . . . for groups
##
##  This operation finds a subgroup K of G such that H is subnormal in K,
##  but H is not normal in K if such a subgroup exists, it returns fail otherwise.
##  H satisfies the subnormalizer condition in G when H subnormal in K
##  implies that H is normal in K.
##
                
InstallMethod(OneSubgroupInWhichSubnormalNotNormalOp, "for finite groups",
        [IsGroup and IsFinite, IsGroup and IsFinite ],
        function(g,h)
    local x,int,t,cex,bool1,bool2;
    if not IsSubgroup(g,h)
       then
        Error("<h> must be a subgroup of <g>");
    fi;
    
    bool1:=IsSubgroup(Parent(h),g);
    if 
       (bool1 and HasIsWithSubnormalizerConditionInParent(h) and
        IsWithSubnormalizerConditionInParent(h))
       then
        return fail;
    fi;
    if IsNormal(g,h)
    then
        return fail;
    fi;
    
    if IsSubnormal(g,h) then
        #
        # it cannot be normal in g
        #
        return g;
    fi;
                  
    bool2:=IsSubgroup(g,Parent(h));
    if (bool2 and HasOneSubgroupInWhichSubnormalNotNormalInParent(h)
        and OneSubgroupInWhichSubnormalNotNormalInParent(h)<>fail)
       then
        return OneSubgroupInWhichSubnormalNotNormalInParent(h);
    fi;
    int:=IntermediateSubgroups(g,h);
    cex:=First(int.subgroups, t->not IsNormal(t,h) and IsSubnormal(t,h));
    if  bool1 and bool2 then
        if cex=fail
           then
            SetIsWithSubnormalizerConditionInParent(h,true);
            SetIsWithSubpermutizerConditionInParent(h,true);
            SetIsWithSSubpermutizerConditionInParent(h,true);
        fi;
    fi;
    return cex;

end
  );

#############################################################################
##
#M  IsWithSubnormalizerCondition( <G>, <H> ) . . . . for groups
##
##  
##  This operation returns true if H satisfies the subnormaliser
##  condition in G, false otherwise.
##  H satisfies the subnormalizer condition in G when H subnormal in K
##  implies that H is normal in K.
##

InstallMethod(IsWithSubnormalizerConditionOp, "for finite groups",
        [IsGroup and IsFinite, IsGroup and IsFinite],
        function(g,h)
    local bool1,bool2;
    if not IsSubgroup(g,h)
       then
        Error("<h> must be a subgroup of <g>");
    fi;
    bool1:=IsSubgroup(Parent(h),g);
    if bool1 and
       (
        (HasOneSubgroupInWhichSubnormalNotNormalInParent(h) and
         OneSubgroupInWhichSubnormalNotNormalInParent(h)=fail)
        or
        (HasIsWithSubnormalizerConditionInParent(h) and
         IsWithSubnormalizerConditionInParent(h))
        )       
       then
        return true;
    fi;
    bool2:=IsSubgroup(g,Parent(h));
    if bool2 and 
       (
        (HasOneSubgroupInWhichSubnormalNotNormalInParent(h) and
         OneSubgroupInWhichSubnormalNotNormalInParent(h)<>fail)
        or
        (HasOneSubgroupInWhichSubnormalNotPermutableInParent(h) and
         OneSubgroupInWhichSubnormalNotPermutableInParent(h)<>fail)
        or
        (HasOneSubgroupInWhichSubnormalNotSPermutableInParent(h) and
         OneSubgroupInWhichSubnormalNotSPermutableInParent(h)<>fail)
        or
        (HasIsWithSubnormalizerConditionInParent(h) and
         not IsWithSubnormalizerConditionInParent(h))
        or
        (HasIsWithSubpermutizerConditionInParent(h) and
         not IsWithSubpermutizerConditionInParent(h))
        or
        (HasIsWithSSubpermutizerConditionInParent(h) and
         not IsWithSSubpermutizerConditionInParent(h))
        )
       then
        return false;
    fi;
    return OneSubgroupInWhichSubnormalNotNormal(g,h)=fail;
end
  );

#############################################################################
##
#M  OneSubgroupInWhichSubnormalNotPermutable( <G>, <H> ) . . . . for groups
##
##  This operation finds a subgroup K of G such that H is subnormal in K,
##  but H is not permutable in K if such a subgroup exists,
##  otherwise it returns fail.
##  H satisfies the subpermutizer condition in G when H subnormal in K
##  implies that H is permutable in K.
##
                
InstallMethod(OneSubgroupInWhichSubnormalNotPermutableOp, "for finite groups",
        [IsGroup and IsFinite, IsGroup and IsFinite ],
        function(g,h)
    local x,int,t,cex,bool1,bool2;
            
            if not IsSubgroup(g,h)
       then
        Error("<h> must be a subgroup of <g>");
    fi;    
    bool1:=IsSubgroup(Parent(h),g);
    if bool1 and
       (
        (HasIsWithSubnormalizerConditionInParent(h) and
         IsWithSubnormalizerConditionInParent(h))
        or
        (HasIsWithSubpermutizerConditionInParent(h) and
         IsWithSubpermutizerConditionInParent(h))
        )
       then
        return fail;
    fi;
    if IsNormal(g,h) or
       IsPermutable(g,h)
    then
        return fail;
    fi;
    
    if IsSubnormal(g,h) then
        #
        # h cannot be permutable in g
        #
        return g;
    fi;
    bool2:=IsSubgroup(g,Parent(h));
    if bool2 then
        if       
          (HasOneSubgroupInWhichSubnormalNotPermutableInParent(h)
           and OneSubgroupInWhichSubnormalNotPermutableInParent(h)<>fail)
        then
            
            return OneSubgroupInWhichSubnormalNotPermutableInParent(h);
        elif
          (HasOneSubgroupInWhichSubnormalNotSPermutableInParent(h)
           and OneSubgroupInWhichSubnormalNotSPermutableInParent(h)<>fail)
        then
            
            return OneSubgroupInWhichSubnormalNotSPermutableInParent(h);
        fi;
    fi;
    
    int:=IntermediateSubgroups(g,h);
    
    cex:=First(int.subgroups, t->not IsNormal(t,h) and IsSubnormal(t,h));
    if bool1 and bool2 then
        if cex=fail 
           then
            SetIsWithSubpermutizerConditionInParent(h,true);
            SetIsWithSSubpermutizerConditionInParent(h,true);
        else
            SetIsWithSubpermutizerConditionInParent(h,false);
            SetIsWithSubnormalizerConditionInParent(h,false);
        fi;
    fi;
    return cex;

end
  );

#############################################################################
##
#M  IsWithSubpermutizerCondition( <G>, <H> ) . . . . for groups
##
##  
##  This operation returns true if H satisfies the subpermutiser condition
##  in G, otherwise it returns false.
##  H satisfies the subpermutizer condition in G when H subnormal in K
##  implies that H is permutable in K.
##

InstallMethod(IsWithSubpermutizerConditionOp, "for finite groups",
        [IsGroup and IsFinite, IsGroup and IsFinite],
        function(g,h)
    local bool1,bool2;
    if not IsSubgroup(g,h)
       then
        Error("<h> must be a subgroup of <g>");
    fi;
    
    bool1:=IsSubgroup(Parent(h),g);
    if bool1 and
       (
        (HasOneSubgroupInWhichSubnormalNotNormalInParent(h) and
         OneSubgroupInWhichSubnormalNotNormalInParent(h)=fail)
        or
        (HasIsWithSubnormalizerConditionInParent(h) and
         IsWithSubnormalizerConditionInParent(h))
        or
        (HasOneSubgroupInWhichSubnormalNotPermutableInParent(h) and
         OneSubgroupInWhichSubnormalNotPermutableInParent(h)=fail)
        or
        (HasIsWithSubpermutizerConditionInParent(h) and
         IsWithSubpermutizerConditionInParent(h))
        )       
       then
        return true;
    fi;
    bool2:=IsSubgroup(g,Parent(h));
    if bool2 and 
       (
        (HasOneSubgroupInWhichSubnormalNotPermutableInParent(h) and
         OneSubgroupInWhichSubnormalNotPermutableInParent(h)<>fail)
        or
        (HasOneSubgroupInWhichSubnormalNotSPermutableInParent(h) and
         OneSubgroupInWhichSubnormalNotSPermutableInParent(h)<>fail)
        or
        (HasIsWithSubpermutizerConditionInParent(h) and
         not IsWithSubpermutizerConditionInParent(h))
        or
        (HasIsWithSSubpermutizerConditionInParent(h) and
         not IsWithSSubpermutizerConditionInParent(h))
        )
       then
        return false;
    fi;
    return OneSubgroupInWhichSubnormalNotPermutable(g,h)=fail;
end
  );

#############################################################################
##
#M  OneSubgroupInWhichSubnormalNotSPermutable( <G>, <H> ) . . . . for groups
##
##  This operation finds a subgroup K of G such that H is subnormal in K,
##  but H is not S-permutable in K if such a subgroup exists, 
##  otherwise it returns fail.
##  H satisfies the S-subpermutizer condition in G when H subnormal in K
##  implies that H is S-permutable in K.
##
                
InstallMethod(OneSubgroupInWhichSubnormalNotSPermutableOp, "for finite groups",
        [IsGroup and IsFinite, IsGroup and IsFinite ],
        function(g,h)
    local x,int,t,cex,bool1,bool2;
    if not IsSubgroup(g,h)
       then
        Error("<h> must be a subgroup of <g>");
    fi;
    
    bool1:=IsSubgroup(Parent(h),g);
    if bool1 and
       (
        (HasIsWithSubnormalizerConditionInParent(h) and
         IsWithSubnormalizerConditionInParent(h))
        or
        (HasIsWithSubpermutizerConditionInParent(h) and
         IsWithSubpermutizerConditionInParent(h))
        or
        (HasIsWithSSubpermutizerConditionInParent(h) and
         IsWithSSubpermutizerConditionInParent(h))
        or
        IsSPermutable(g,h)
       )
       then
        return fail;
    fi;
    if IsNormal(g,h) or
       IsSPermutable(g,h)
    then
        return fail;
    fi;
    
    if IsSubnormal(g,h) then
        #
        # h cannot be S-permutable in g
        #
        return g;
    fi;
    bool2:=IsSubgroup(g,Parent(h));
    if bool2 then
        if       
          (HasOneSubgroupInWhichSubnormalNotPermutableInParent(h)
           and OneSubgroupInWhichSubnormalNotPermutableInParent(h)<>fail)
          then 
            return OneSubgroupInWhichSubnormalNotPermutableInParent(h);
        elif
          (HasOneSubgroupInWhichSubnormalNotSPermutableInParent(h)
           and OneSubgroupInWhichSubnormalNotSPermutableInParent(h)<>fail)
          then
            return OneSubgroupInWhichSubnormalNotSPermutableInParent(h);
        fi;
    fi;
    int:=IntermediateSubgroups(g,h);
    cex:=First(int.subgroups, t->not IsNormal(t,h) and IsSubnormal(t,h));
    if bool1 and bool2 then
        if cex=fail 
           then
            SetIsWithSSubpermutizerConditionInParent(h,true);
        else
            SetIsWithSSubpermutizerConditionInParent(h,false);
            SetIsWithSubpermutizerConditionInParent(h,false);
            SetIsWithSubnormalizerConditionInParent(h,false);
            
        fi;
    fi;
    return cex;

end
  );

#############################################################################
##
#M  IsWithSSubpermutizerCondition( <G>, <H> ) . . . . for groups
##
##  
##  This operation returns true if H satisfies the S-subpermutiser
##  condition in G, otherwise it returns false.
##  H satisfies the S-subpermutiser condition in G when H subnormal in K
##  implies that H is S-permutable in K.
##

InstallMethod(IsWithSSubpermutizerConditionOp, "for finite groups",
        [IsGroup and IsFinite, IsGroup and IsFinite],
        function(g,h)
    local bool1,bool2;
    if not IsSubgroup(g,h)
       then
        Error("<h> must be a subgroup of <g>");
    fi;
    
    bool1:=IsSubgroup(Parent(h),g);
    if bool1 and
       (
        (HasOneSubgroupInWhichSubnormalNotNormalInParent(h) and
         OneSubgroupInWhichSubnormalNotNormalInParent(h)=fail)
        or
        (HasIsWithSubnormalizerConditionInParent(h) and
         IsWithSubnormalizerConditionInParent(h))
        or
        (HasOneSubgroupInWhichSubnormalNotPermutableInParent(h) and
         OneSubgroupInWhichSubnormalNotPermutableInParent(h)=fail)
        or
        (HasIsWithSubpermutizerConditionInParent(h) and
         IsWithSubpermutizerConditionInParent(h))
        or
        (HasOneSubgroupInWhichSubnormalNotSPermutableInParent(h) and
         OneSubgroupInWhichSubnormalNotSPermutableInParent(h)=fail)
        or
        (HasIsWithSSubpermutizerConditionInParent(h) and
         IsWithSSubpermutizerConditionInParent(h))
        )       
       then
        return true;
    fi;
    bool2:=IsSubgroup(g,Parent(h));
    if bool2 and 
       (
        (HasIsWithSSubpermutizerConditionInParent(h) and
         not IsWithSSubpermutizerConditionInParent(h))
        or
        (HasOneSubgroupInWhichSubnormalNotSPermutableInParent(h) and
         not OneSubgroupInWhichSubnormalNotSPermutableInParent(h)<>fail)
        )
         then
        return false;
    fi;
    return OneSubgroupInWhichSubnormalNotSPermutable(g,h)=fail;
end
  );

#############################################################################
##
#M  AreMutuallyPermutableSubgroups( <G>, <U>, <V> ) . . . . for finite groups
#M  AreMutuallyPermutableSubgroups( <U>, <V> )
##
##  This operation returns true if <U> and <V> are mutually permutable,
##  otherwise it returns false.
##  Two subgroups <U> and <V> are mutually permutable
##  if <U> permutes with all subgroups of <V>
##  and <V> permutes with all subgroups of <U>.
##

InstallMethod(AreMutuallyPermutableSubgroups, "with three arguments",
        [IsGroup and IsFinite, IsGroup and IsFinite, IsGroup and IsFinite],
        function(G, A, B)
    local t;
    if not (IsSubgroup(G,A) and IsSubgroup(G,B))
       then
        Error("<A> and <B> must be subgroups of <G>");
    fi;
   
    if not ArePermutableSubgroups(G,A,B)
       then
        return false;
    else
        if IsNormal(G,A) and IsNormal(G,B)
           then 
            return true;
        fi;
        return (IsNormal(G,B) or
                ForAll(Zuppos(A),
                       t->ArePermutableSubgroups(G,Subgroup(G,[t]),B)))
               and
               (IsNormal(G,A) or
                ForAll(Zuppos(B),
                       t->ArePermutableSubgroups(G,A,Subgroup(G,[t]))));
    fi;
end
  );

InstallOtherMethod(AreMutuallyPermutableSubgroups, "with two arguments",
        [IsGroup and IsFinite, IsGroup and IsFinite],
        function(A, B)
    local t,G;
    if not ArePermutableSubgroups(A,B)
       then
        return false;
    else
        if IsIdenticalObj(Parent(A),Parent(B))
           then
            G:=Parent(A);
        else
            G:=ClosureGroup(A,B);
        fi;
        if IsNormal(G,A) and IsNormal(G,B)
           then
            return true;
        fi;
        return (IsNormal(G,B) or
                ForAll(Zuppos(A),
--> --------------------

--> maximum size reached

--> --------------------

[ 0.92Quellennavigators  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


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