608 lines
17 KiB
Plaintext
608 lines
17 KiB
Plaintext
#############################################################################
|
|
##
|
|
#W mlt_search.gi Realizing groups as multiplication groups of loops [loops]
|
|
##
|
|
#H @(#)$Id: mlt_search.gi, v 3.0.0 2015/06/12 gap Exp $
|
|
##
|
|
#Y Copyright (C) 2004, G. P. Nagy (University of Szeged, Hungary),
|
|
#Y P. Vojtechovsky (University of Denver, USA)
|
|
##
|
|
|
|
##########################################################################
|
|
#
|
|
# The following commands look for loops such that the
|
|
# multiplication group is contained in a given group <G>.
|
|
#
|
|
# The resulting loops are given by their right sections.
|
|
#
|
|
# One can speed up the search by setting the argument <depth>
|
|
# higher; the price is much higher memory consumption.
|
|
#
|
|
# <depth> is optimally choosen if in the permutation group <G>
|
|
# there are "not many" permutations fixing <depth> elements.
|
|
#
|
|
# You can omit this argument, or set depth=2 with no harm.
|
|
#
|
|
# The parameter <infolevel> determines the amount of information
|
|
# you get during the search.
|
|
#
|
|
# With infolevel=1, you get the information on timing and hits.
|
|
# With infolevel=2, the results are printed, as well.
|
|
#
|
|
##########################################################################
|
|
#
|
|
# AllLoopTablesInGroup(G[, depth[, infolevel]] )
|
|
# returns all loop tables <T> such that Mlt(T)<=G
|
|
#
|
|
# AllProperLoopTablesInGroup(G[, depth[, infolevel]] )
|
|
# returns all non-associative loop tables <T> such that Mlt(T)<=G
|
|
#
|
|
# OneLoopTableInGroup(G[, depth[, infolevel]] )
|
|
# returns one loop table <T> such that Mlt(T)<=G
|
|
#
|
|
# OneProperLoopTableInGroup(G[, depth[, infolevel]] )
|
|
# returns one non-associative loop table <T> such that Mlt(T)<=G
|
|
#
|
|
# AllLoopsWithMltGroup(G[, depth[, infolevel]] )
|
|
# returns all loop tables <T> such that Mlt(T)=G
|
|
#
|
|
# OneLoopWithMltGroup(G[, depth[, infolevel]] )
|
|
# returns one loop table <T> such that Mlt(T)=G
|
|
#
|
|
##########################################################################
|
|
|
|
# Debugging
|
|
LOOPS_SearchRuntime:=function(tstart)
|
|
return Concatenation("[ ", StringTime(Runtime()-tstart)," ]");
|
|
end;
|
|
|
|
LOOPS_SearchInfo:=NewInfoClass("InfoCayleySearch");
|
|
SetInfoLevel(LOOPS_SearchInfo,1);
|
|
|
|
|
|
# LOOPS_TableSearchNC(G, depth, infolevel, task)
|
|
# restiction in ["", "all", "all proper", "one", "one proper", "all exact", "one exact"]
|
|
# if task="" then task:="all";
|
|
|
|
# auxiliary function
|
|
LOOPS_TableSearchNC:=function(g, ldepth, infolevel, task)
|
|
local
|
|
# task variables
|
|
only_one, only_proper, only_exact, takeit,
|
|
# local external variables
|
|
results, V, hash, row, pi, col_chunks, degree, level, depth,
|
|
# local scanner functions
|
|
move_right, next_node, possible_next_rows,
|
|
# main search loop variables
|
|
fpf_classes, reps, x0, x1, k, i, j, ct, ls, rs,
|
|
# debugging
|
|
old_infolevel,time_start;
|
|
|
|
# setting the local external variables
|
|
results:=[];
|
|
V:=[];
|
|
hash:=[];
|
|
row:=[];
|
|
pi:=[];
|
|
col_chunks:=[];
|
|
degree:=0;
|
|
level:=0;
|
|
depth:=0;
|
|
|
|
# functions
|
|
move_right:=function()
|
|
local i;
|
|
if level=0 then
|
|
return false;
|
|
fi;
|
|
if pi[level]<>[] then
|
|
row[level]:=Remove(pi[level],1);
|
|
for i in [1..degree] do
|
|
col_chunks[i][level]:=i^V[row[level]];
|
|
od;
|
|
return true;
|
|
else
|
|
Unbind(row[level]);
|
|
Unbind(pi[level]);
|
|
for i in [1..degree] do
|
|
Unbind(col_chunks[i][level]);
|
|
od;
|
|
level:=level-1;
|
|
return move_right();
|
|
fi;
|
|
end;
|
|
|
|
# next_node()
|
|
# we call it when
|
|
# a) row[level+1] and pi[level+1] are not defined ---> MOVE RIGHT
|
|
# b) row[level+1] is not defined and pi[level+1] is defined
|
|
# and non empty ---> MOVE DOWN
|
|
next_node:=function()
|
|
local i;
|
|
if IsBound(pi[level+1])
|
|
and (not IsBound(row[level+1]))
|
|
and (pi[level+1]<>[])
|
|
then
|
|
level:=level+1;
|
|
row[level]:=Remove(pi[level],1);
|
|
for i in [1..degree] do
|
|
col_chunks[i][level]:=i^V[row[level]];
|
|
od;
|
|
return true;
|
|
elif (not IsBound(pi[level+1])) and (not IsBound(row[level+1])) then
|
|
return move_right();
|
|
else
|
|
return fail;
|
|
fi;
|
|
end;
|
|
|
|
possible_next_rows:=function()
|
|
local np,vp,dp;
|
|
dp:=Minimum(level, depth);
|
|
np:=List([2..degree],i->Sum([1..dp],j->(col_chunks[i][j]-1)*degree^(dp-j))+1);
|
|
if ForAny(np,i->not(IsBound(hash[dp][i]))) then
|
|
pi[level+1]:=[];
|
|
return false;
|
|
fi;
|
|
np:=List(np,i->[hash[dp][i][1]..hash[dp][i][1]+hash[dp][i][2]]);
|
|
np:=List(np,x->Set(V{x},y->(level+1)^y));
|
|
vp:=List(Cartesian(np{[1..depth-1]}),x->Concatenation([level+1],x));
|
|
vp:=List(vp,x->Sum([1..depth],j->(x[j]-1)*degree^(depth-j))+1);
|
|
vp:=Filtered(vp,i->IsBound(hash[depth][i]));
|
|
vp:=List(vp,i->[hash[depth][i][1]..hash[depth][i][1]+hash[depth][i][2]]);
|
|
vp:=Filtered(Concatenation(vp),x->
|
|
ForAll([2..degree],i->(i^V[x] in np[i-1]) and not(i^V[x] in col_chunks[i]))
|
|
);
|
|
pi[level+1]:=vp;
|
|
return vp<>[];
|
|
end;
|
|
|
|
# main search part
|
|
# printing the task ["", "all", "all proper", "one", "one proper", "all exact", "one exact"]
|
|
|
|
old_infolevel:=InfoLevel(LOOPS_SearchInfo);
|
|
SetInfoLevel(LOOPS_SearchInfo,infolevel);
|
|
|
|
if task="" then task:="all"; fi;
|
|
if task="all" then
|
|
only_one:=false;
|
|
only_proper:=false;
|
|
only_exact:=false;
|
|
Info(LOOPS_SearchInfo, 1, "### Search for all loops in the given group ###");
|
|
elif task="all proper" then
|
|
only_one:=false;
|
|
only_proper:=true;
|
|
only_exact:=false;
|
|
Info(LOOPS_SearchInfo, 1, "### Search for all nonassociative loops in the given group ###");
|
|
elif task="one" then
|
|
only_one:=true;
|
|
only_proper:=false;
|
|
only_exact:=false;
|
|
Info(LOOPS_SearchInfo, 1, "### Search for one loop in the given group ###");
|
|
elif task="one proper" then
|
|
only_one:=true;
|
|
only_proper:=true;
|
|
only_exact:=false;
|
|
Info(LOOPS_SearchInfo, 1, "### Search for one nonassociative loops loops in the given group ###");
|
|
elif task="all exact" then
|
|
only_one:=false;
|
|
only_proper:=false;
|
|
only_exact:=true;
|
|
Info(LOOPS_SearchInfo, 1, "### Search for all loops with given multiplication group ###");
|
|
elif task="one exact" then
|
|
only_one:=true;
|
|
only_proper:=false;
|
|
only_exact:=true;
|
|
Info(LOOPS_SearchInfo, 1, "### Search for one loop with given multiplication group ###");
|
|
else
|
|
SetInfoLevel(LOOPS_SearchInfo,old_infolevel);
|
|
return fail;
|
|
fi;
|
|
|
|
time_start:=Runtime();
|
|
degree:=NrMovedPoints(g);
|
|
depth:=ldepth;
|
|
Info(LOOPS_SearchInfo, 1, "# Size of the input group: ", Size(g));
|
|
Info(LOOPS_SearchInfo, 1, "# Degree of the permutation group: ", degree);
|
|
|
|
# analysis of the fixed point free elements
|
|
fpf_classes:=Filtered(ConjugacyClasses(g),x->NrMovedPoints(Representative(x))=degree);
|
|
if Length(fpf_classes)=1 then
|
|
V:=Elements(fpf_classes[1]);
|
|
else
|
|
V:=Union(fpf_classes);;
|
|
fi;
|
|
MakeImmutable(V);
|
|
reps:=List(fpf_classes,x->Minimum(Elements(x)));
|
|
reps:=Set(reps,x->Position(V,x));
|
|
Info(LOOPS_SearchInfo, 1, "# ", LOOPS_SearchRuntime(time_start), " Search started.");
|
|
|
|
Info(LOOPS_SearchInfo, 1, "# Collected the fixed point free elements." );
|
|
Info(LOOPS_SearchInfo, 1, "# Number of conjugugacy classes = ", Size(reps), "." );
|
|
Info(LOOPS_SearchInfo, 1, "# Number of fixed point free elements = ", Size(V), "." );
|
|
|
|
# hash tables
|
|
hash:=List([1..depth],i->[]);
|
|
x0:=0*[1..depth];
|
|
k:=0*[1..depth];
|
|
for j in [1..Length(V)] do
|
|
x1:=List([1..depth],i->i^V[j]);
|
|
for i in [1..depth] do
|
|
if x0{[1..i]}<>x1{[1..i]} then
|
|
k[i]:=Sum([1..i],t->(x1[t]-1)*degree^(i-t))+1;
|
|
hash[i][k[i]]:=[j,0];
|
|
else
|
|
hash[i][k[i]][2]:=hash[i][k[i]][2]+1;
|
|
fi;
|
|
od;
|
|
x0:=ShallowCopy(x1);
|
|
od;
|
|
MakeImmutable(hash);
|
|
Info(LOOPS_SearchInfo, 1, "# ", LOOPS_SearchRuntime(time_start), " Hash table of depth ", depth, " created." );
|
|
|
|
# initialization
|
|
row:=['*'];
|
|
pi:=[[],ShallowCopy(reps)];
|
|
col_chunks:=List([1..degree],i->[i]);
|
|
level:=1;
|
|
results:=[];
|
|
|
|
while next_node() do
|
|
if level=2 then
|
|
Info(LOOPS_SearchInfo, 1, "# ", LOOPS_SearchRuntime(time_start),
|
|
" We have ", Length(pi[2])+1, " more step(s)." );
|
|
fi;
|
|
if level=degree then
|
|
ct:=List(V{row{[2..degree]}},ListPerm);
|
|
ct:=Concatenation([[1..degree]],ct);
|
|
rs:=Immutable(List(ct,PermList));
|
|
ls:=Immutable(List(TransposedMat(ct),PermList));
|
|
if only_exact then
|
|
takeit:=(Group(Union(ls,rs))=g);
|
|
elif only_proper then
|
|
takeit:=(ForAll(ls,y->y in g) and
|
|
not ForAll(rs,x->ForAll(x*rs,y->y in rs)));
|
|
else
|
|
takeit:=ForAll(ls,y->y in g);
|
|
fi;
|
|
if takeit then
|
|
Add(results, ShallowCopy(row));
|
|
Info(LOOPS_SearchInfo, 2, "##############################");
|
|
Info(LOOPS_SearchInfo, 1, "# ", LOOPS_SearchRuntime(time_start),
|
|
" Hit number ", Length(results));
|
|
Info(LOOPS_SearchInfo, 2, ct);
|
|
if only_one then break; fi;
|
|
fi;
|
|
else
|
|
possible_next_rows();
|
|
if pi[level+1]=[] then Unbind(pi[level+1]); fi;
|
|
fi;
|
|
od;
|
|
|
|
Info(LOOPS_SearchInfo, 1, "##############################");
|
|
Info(LOOPS_SearchInfo, 1, "# ", LOOPS_SearchRuntime(time_start), " Finished. ", Length(results), " loops found." );
|
|
|
|
SetInfoLevel(LOOPS_SearchInfo,old_infolevel);
|
|
return List(results,x->Concatenation([()],V{x{[2..degree]}}));
|
|
end;
|
|
|
|
# auxiliary function
|
|
LOOPS_SearchInputCheck:=function( G, depth, infolevel, task )
|
|
local degree;
|
|
if not IsPermGroup(G) then
|
|
Info( InfoWarning, 1, "<G> must be a permutation group" );
|
|
return false;
|
|
fi;
|
|
degree:=NrMovedPoints(G);
|
|
if MovedPoints(G)<>[1..degree] then
|
|
Info( InfoWarning, 1, "<G> must act transitively on [1..degree]" );
|
|
return false;
|
|
fi;
|
|
if depth=fail then depth:=LogInt(Size(G),degree)-1; fi;
|
|
if not IsInt(depth) or depth<=0 then
|
|
Info( InfoWarning, 1, "<depth> must be a positive integer" );
|
|
return false;
|
|
fi;
|
|
if infolevel=fail then infolevel:=1; fi;
|
|
if not IsInt(infolevel) or infolevel<0 then
|
|
Info( InfoWarning, 1, "<infolevel> must be a positive integer" );
|
|
return false;
|
|
fi;
|
|
if not task in ["", "all", "all proper", "one", "one proper", "all exact", "one exact"] then
|
|
Info( InfoWarning, 1, "<task> must be one of the following:");
|
|
Info( InfoWarning, 1, "\t\"\", \"all\", \"all proper\", \"one\", ",
|
|
"\"one proper\", \"all exact\", \"one exact\"." );
|
|
return false;
|
|
fi;
|
|
return [G,depth,infolevel,task];
|
|
end;
|
|
|
|
#############################################################################
|
|
##
|
|
#O AllLoopTablesInGroup(G[, depth[, infolevel]] )
|
|
##
|
|
## returns all loop tables <T> such that Mlt(T)<=G.
|
|
|
|
InstallMethod( AllLoopTablesInGroup, "for a group",
|
|
[ IsGroup ],
|
|
function( G )
|
|
local depth, infolevel, task, a;
|
|
task:="all";
|
|
depth:=fail;
|
|
infolevel:=fail;
|
|
a:=LOOPS_SearchInputCheck(G,depth,infolevel,task);
|
|
if a<>false then
|
|
return LOOPS_TableSearchNC(a[1],a[2],a[3],a[4]);
|
|
else
|
|
return fail;
|
|
fi;
|
|
end);
|
|
|
|
InstallOtherMethod( AllLoopTablesInGroup, "for a group and integer",
|
|
[ IsGroup, IsInt ],
|
|
function( G, depth )
|
|
local infolevel, task, a;
|
|
task:="all";
|
|
infolevel:=fail;
|
|
a:=LOOPS_SearchInputCheck(G,depth,infolevel,task);
|
|
if a<>false then
|
|
return LOOPS_TableSearchNC(a[1],a[2],a[3],a[4]);
|
|
else
|
|
return fail;
|
|
fi;
|
|
end);
|
|
|
|
InstallOtherMethod( AllLoopTablesInGroup, "for a group and two integers",
|
|
[ IsGroup, IsInt, IsInt ],
|
|
function( G, depth, infolevel )
|
|
local task, a;
|
|
task:="all";
|
|
a:=LOOPS_SearchInputCheck(G,depth,infolevel,task);
|
|
if a<>false then
|
|
return LOOPS_TableSearchNC(a[1],a[2],a[3],a[4]);
|
|
else
|
|
return fail;
|
|
fi;
|
|
end);
|
|
|
|
#############################################################################
|
|
##
|
|
#O AllProperLoopTablesInGroup(G[, depth[, infolevel]] )
|
|
##
|
|
## returns all non-associative loop tables <T> such that Mlt(T)<=G.
|
|
|
|
InstallMethod( AllProperLoopTablesInGroup, "for a group",
|
|
[ IsGroup ],
|
|
function( G )
|
|
local depth, infolevel, task, a;
|
|
task:="all proper";
|
|
depth:=fail;
|
|
infolevel:=fail;
|
|
a:=LOOPS_SearchInputCheck(G,depth,infolevel,task);
|
|
if a<>false then
|
|
return LOOPS_TableSearchNC(a[1],a[2],a[3],a[4]);
|
|
else
|
|
return fail;
|
|
fi;
|
|
end);
|
|
|
|
InstallOtherMethod( AllProperLoopTablesInGroup, "for a group and integer",
|
|
[ IsGroup, IsInt ],
|
|
function( G, depth )
|
|
local infolevel, task, a;
|
|
task:="all proper";
|
|
infolevel:=fail;
|
|
a:=LOOPS_SearchInputCheck(G,depth,infolevel,task);
|
|
if a<>false then
|
|
return LOOPS_TableSearchNC(a[1],a[2],a[3],a[4]);
|
|
else
|
|
return fail;
|
|
fi;
|
|
end);
|
|
|
|
InstallOtherMethod( AllProperLoopTablesInGroup, "for a group and two integers",
|
|
[ IsGroup, IsInt, IsInt ],
|
|
function( G, depth, infolevel )
|
|
local task, a;
|
|
task:="all proper";
|
|
a:=LOOPS_SearchInputCheck(G,depth,infolevel,task);
|
|
if a<>false then
|
|
return LOOPS_TableSearchNC(a[1],a[2],a[3],a[4]);
|
|
else
|
|
return fail;
|
|
fi;
|
|
end);
|
|
|
|
#############################################################################
|
|
##
|
|
#O OneLoopTableInGroup(G[, depth[, infolevel]] )
|
|
##
|
|
## returns one loop table <T> such that Mlt(T)<=G.
|
|
|
|
InstallMethod( OneLoopTableInGroup, "for a group",
|
|
[ IsGroup ],
|
|
function( G )
|
|
local depth, infolevel, task, a;
|
|
task:="one";
|
|
depth:=fail;
|
|
infolevel:=fail;
|
|
a:=LOOPS_SearchInputCheck(G,depth,infolevel,task);
|
|
if a<>false then
|
|
return LOOPS_TableSearchNC(a[1],a[2],a[3],a[4]);
|
|
else
|
|
return fail;
|
|
fi;
|
|
end);
|
|
|
|
InstallOtherMethod( OneLoopTableInGroup, "for a group and integer",
|
|
[ IsGroup, IsInt ],
|
|
function( G, depth )
|
|
local infolevel, task, a;
|
|
task:="one";
|
|
infolevel:=fail;
|
|
a:=LOOPS_SearchInputCheck(G,depth,infolevel,task);
|
|
if a<>false then
|
|
return LOOPS_TableSearchNC(a[1],a[2],a[3],a[4]);
|
|
else
|
|
return fail;
|
|
fi;
|
|
end);
|
|
|
|
InstallOtherMethod( OneLoopTableInGroup, "for a group and two integers",
|
|
[ IsGroup, IsInt, IsInt ],
|
|
function( G, depth, infolevel )
|
|
local task, a;
|
|
task:="one";
|
|
a:=LOOPS_SearchInputCheck(G,depth,infolevel,task);
|
|
if a<>false then
|
|
return LOOPS_TableSearchNC(a[1],a[2],a[3],a[4]);
|
|
else
|
|
return fail;
|
|
fi;
|
|
end);
|
|
|
|
#############################################################################
|
|
##
|
|
#O OneProperLoopTableInGroup(G[, depth[, infolevel]] )
|
|
##
|
|
## returns one non-associative loop table <T> such that Mlt(T)<=G.
|
|
|
|
InstallMethod( OneProperLoopTableInGroup, "for a group",
|
|
[ IsGroup ],
|
|
function( G )
|
|
local depth, infolevel, task, a;
|
|
task:="one proper";
|
|
depth:=fail;
|
|
infolevel:=fail;
|
|
a:=LOOPS_SearchInputCheck(G,depth,infolevel,task);
|
|
if a<>false then
|
|
return LOOPS_TableSearchNC(a[1],a[2],a[3],a[4]);
|
|
else
|
|
return fail;
|
|
fi;
|
|
end);
|
|
|
|
InstallOtherMethod( OneProperLoopTableInGroup, "for a group and integer",
|
|
[ IsGroup, IsInt ],
|
|
function( G, depth )
|
|
local infolevel, task, a;
|
|
task:="one proper";
|
|
infolevel:=fail;
|
|
a:=LOOPS_SearchInputCheck(G,depth,infolevel,task);
|
|
if a<>false then
|
|
return LOOPS_TableSearchNC(a[1],a[2],a[3],a[4]);
|
|
else
|
|
return fail;
|
|
fi;
|
|
end);
|
|
|
|
InstallOtherMethod( OneProperLoopTableInGroup, "for a group and two integers",
|
|
[ IsGroup, IsInt, IsInt ],
|
|
function( G, depth, infolevel )
|
|
local task, a;
|
|
task:="one proper";
|
|
a:=LOOPS_SearchInputCheck(G,depth,infolevel,task);
|
|
if a<>false then
|
|
return LOOPS_TableSearchNC(a[1],a[2],a[3],a[4]);
|
|
else
|
|
return fail;
|
|
fi;
|
|
end);
|
|
|
|
#############################################################################
|
|
##
|
|
#O AllLoopsWithMltGroup(G[, depth[, infolevel]] )
|
|
##
|
|
## returns all loop tables <T> such that Mlt(T)=G.
|
|
|
|
InstallMethod( AllLoopsWithMltGroup, "for a group",
|
|
[ IsGroup ],
|
|
function( G )
|
|
local depth, infolevel, task, a;
|
|
task:="all exact";
|
|
depth:=fail;
|
|
infolevel:=fail;
|
|
a:=LOOPS_SearchInputCheck(G,depth,infolevel,task);
|
|
if a<>false then
|
|
return LOOPS_TableSearchNC(a[1],a[2],a[3],a[4]);
|
|
else
|
|
return fail;
|
|
fi;
|
|
end);
|
|
|
|
InstallOtherMethod( AllLoopsWithMltGroup, "for a group and integer",
|
|
[ IsGroup, IsInt ],
|
|
function( G, depth )
|
|
local infolevel, task, a;
|
|
task:="all exact";
|
|
infolevel:=fail;
|
|
a:=LOOPS_SearchInputCheck(G,depth,infolevel,task);
|
|
if a<>false then
|
|
return LOOPS_TableSearchNC(a[1],a[2],a[3],a[4]);
|
|
else
|
|
return fail;
|
|
fi;
|
|
end);
|
|
|
|
InstallOtherMethod( AllLoopsWithMltGroup, "for a group and two integers",
|
|
[ IsGroup, IsInt, IsInt ],
|
|
function( G, depth, infolevel )
|
|
local task, a;
|
|
task:="all exact";
|
|
a:=LOOPS_SearchInputCheck(G,depth,infolevel,task);
|
|
if a<>false then
|
|
return LOOPS_TableSearchNC(a[1],a[2],a[3],a[4]);
|
|
else
|
|
return fail;
|
|
fi;
|
|
end);
|
|
|
|
#############################################################################
|
|
##
|
|
#O OneLoopWithMltGroup(G[, depth[, infolevel]] )
|
|
##
|
|
## returns one loop table <T> such that Mlt(T)=G.
|
|
|
|
InstallMethod( OneLoopWithMltGroup, "for a group",
|
|
[ IsGroup ],
|
|
function( G )
|
|
local depth, infolevel, task, a;
|
|
task:="one exact";
|
|
depth:=fail;
|
|
infolevel:=fail;
|
|
a:=LOOPS_SearchInputCheck(G,depth,infolevel,task);
|
|
if a<>false then
|
|
return LOOPS_TableSearchNC(a[1],a[2],a[3],a[4]);
|
|
else
|
|
return fail;
|
|
fi;
|
|
end);
|
|
|
|
InstallOtherMethod( OneLoopWithMltGroup, "for a group and integer",
|
|
[ IsGroup, IsInt ],
|
|
function( G, depth )
|
|
local infolevel, task, a;
|
|
task:="one exact";
|
|
infolevel:=fail;
|
|
a:=LOOPS_SearchInputCheck(G,depth,infolevel,task);
|
|
if a<>false then
|
|
return LOOPS_TableSearchNC(a[1],a[2],a[3],a[4]);
|
|
else
|
|
return fail;
|
|
fi;
|
|
end);
|
|
|
|
InstallOtherMethod( OneLoopWithMltGroup, "for a group and two integers",
|
|
[ IsGroup, IsInt, IsInt ],
|
|
function( G, depth, infolevel )
|
|
local task, a;
|
|
task:="one exact";
|
|
a:=LOOPS_SearchInputCheck(G,depth,infolevel,task);
|
|
if a<>false then
|
|
return LOOPS_TableSearchNC(a[1],a[2],a[3],a[4]);
|
|
else
|
|
return fail;
|
|
fi;
|
|
end);
|
|
|