Skip to content

Commit

Permalink
Fix Mandarins
Browse files Browse the repository at this point in the history
  • Loading branch information
ssiccha committed Jan 19, 2022
1 parent 22122b3 commit 903f8f3
Showing 1 changed file with 77 additions and 47 deletions.
124 changes: 77 additions & 47 deletions gap/base/recognition.gi
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,28 @@ InstallOtherMethod( RecogNode,
return RecogNode(H, projective, r);
end);

RECOG.SetXNodeForNodeAndString := function(r, s)
if not s = MANDARIN_CRISIS then
ErrorNoReturn("<s> must be MANDARIN_CRISIS");
fi;
return;
end;

InstallMethod( SetParentRecogNode,
"for a recognition node and a string",
[ IsRecogNode, IsString ],
RECOG.SetXNodeForNodeAndString);

InstallMethod( SetImageRecogNode,
"for a recognition node and a string",
[ IsRecogNode, IsString ],
RECOG.SetXNodeForNodeAndString);

InstallMethod( SetKernelRecogNode,
"for a recognition node and a string",
[ IsRecogNode, IsString ],
RECOG.SetXNodeForNodeAndString);

# Sets the stamp used by RandomElm, RandomElmOrd, and related functions.
RECOG.SetPseudoRandomStamp := function(g,st)
if IsBound(g!.pseudorandomfunc) then
Expand Down Expand Up @@ -464,9 +486,10 @@ function(ri)
gensNWasEmpty := IsEmpty(gensN(ri));
if gensNWasEmpty then
# This gets reduced during each iteration to a minimal value of 1, to
# account for the case where the kernel only has two elements. If the
# findgensNmeth discards trivial or already found generators, than in
# that case we could never find more than one generator.
# account for the case where the kernel only has two elements. The
# findgensNmeth might discard trivial or duplicate generators. In that
# case we can never find more than one generator, if the kernel has
# size two.
targetNrGensN := 5;
else
targetNrGensN := 2 * Length(gensN(ri));
Expand Down Expand Up @@ -580,11 +603,16 @@ InstallGlobalFunction( RecogniseGeneric,
fi;
fi;

# TODO: store the mandarins and their SLPs?
# TODO: store the mandarin SLPs here. Make sure, to only write when succesful.
# check mandarins now
for x in mandarins do
s := SLPforElement(ri, x);
if s = fail then
# TODO: with the master branch rewriting the gens as slps never
# fails. at least we never enter a second iteration of the
# "recognise image" loop.
Info(InfoRecog, 2,
"Enter Mandarin crisis (leaf, depth=", depth, ").");
return MANDARIN_CRISIS;
fi;
od;
Expand All @@ -608,6 +636,9 @@ InstallGlobalFunction( RecogniseGeneric,
# fails, then somewhere higher up in the recognition tree, a kernel must
# have been too small.
if ForAny(mandarins, x->not ValidateHomomInput(ri, x)) then
Info(InfoRecog, 2,
"Enter Mandarin crisis (depth=", depth, "), ",
"ValidateHomomInput failed.");
return MANDARIN_CRISIS;
fi;
# Compute the mandarins of the factor
Expand Down Expand Up @@ -655,19 +686,22 @@ InstallGlobalFunction( RecogniseGeneric,
factorMandarins,
IsSafeForMandarins(ri));
Remove(depthString);
if not IsReady(rifac) then
# IsReady was not set, thus abort the whole computation.
if InfoLevel(InfoRecog) = 1 and depth = 0 then Print("\n"); fi;
return ri;
fi;
PrintTreePos("F",depthString,H);
SetImageRecogNode(ri,rifac);
SetParentRecogNode(rifac,ri);
if rifac = MANDARIN_CRISIS then
# According to the mandarins, somewhere higher up in the recognition
# tree, a kernel must have been too small.
Info(InfoRecog, 2, "Backtrack to the last safe node.");
return MANDARIN_CRISIS;
fi;
PrintTreePos("F",depthString,H);
SetImageRecogNode(ri,rifac);
SetParentRecogNode(rifac,ri);
# Check for IsReady after checking for MANDARIN_CRISIS, since
# IsReady(MANDARIN_CRISIS) always is false.
if not IsReady(rifac) then
# IsReady was not set, thus abort the whole computation.
if InfoLevel(InfoRecog) = 1 and depth = 0 then Print("\n"); fi;
return ri;
fi;

if IsMatrixGroup(H) then
Info(InfoRecog,2,"Back from image (depth=",depth,
Expand Down Expand Up @@ -723,11 +757,8 @@ InstallGlobalFunction( RecogniseGeneric,
x := mandarins[i];
y := factorMandarins[i];
s := SLPforElement(rifac, y);
# TODO: these SLPs should be stored when they are computed for the
# first time.
if s = fail then
Error("TODO: no SLP for factor");
fi;
# TODO: These SLPs should be stored when they are computed for the
# first time. In particular, they can't be fail.
z := ResultOfStraightLineProgram(s, pregensfac(ri));
if not ri!.isequal(x, z) then
Add( kernelMandarins, x / z );
Expand All @@ -740,12 +771,16 @@ InstallGlobalFunction( RecogniseGeneric,
RECOG_HandleSpecialCaseKernelTrivialAndMarkedForImmediateVerification(ri);
fi;
if IsEmpty(gensN(ri)) and not IsEmpty(kernelMandarins) then
# We found out that N is the trivial group, but the mandarins disagree!
Info(InfoRecog, 2,
"Enter Mandarin crisis (depth=", depth, "), ",
"kernel can't be trivial.");
# We handle this in the same way as if recognition of the
# kernel returned a MANDARIN_CRISIS.
if not IsSafeForMandarins(ri) then
return MANDARIN_CRISIS;
else
Info(InfoRecog, 2,
"Handle the mandarin crisis (depth=", depth, ").");
if not TryToEnlargeKernelGeneratingSetAndUpdateSLPsDuringMandarinCrisis(ri) then
# TODO: discard and re-recognise the image.
ErrorNoReturn("TODO");
Expand Down Expand Up @@ -784,34 +819,34 @@ InstallGlobalFunction( RecogniseGeneric,
kernelMandarins,
# TODO: extend this such that riker can also
# be IsSafeForMandarins, if the responsible
# findgensNmeth is guaranteed to feed the
# findgensNmeth is guaranteed to find the
# generators for the whole kernel.
false);
Remove(depthString);
PrintTreePos("K",depthString,H);
SetKernelRecogNode(ri,riker);
SetParentRecogNode(riker,ri);
if riker = MANDARIN_CRISIS then
# According to the mandarins, there was an error in the kernel
# generation of the current node or higher up in the recognition
# tree.
if not IsSafeForMandarins(ri) then
# Backtrack to the first safe node on the way to the root.
Info(InfoRecog, 2,
"Backtrack to the last safe node (depth=", depth, ").");
return MANDARIN_CRISIS;
fi;
Info(InfoRecog, 2,
"Handle the mandarin crisis (depth=", depth, ").");
# We are the first safe node on the way to the root and thus need to
# handle the crisis ourselves.
enlargeKernelSuccess :=
TryToEnlargeKernelGeneratingSetAndUpdateSLPsDuringMandarinCrisis(ri);
if not enlargeKernelSuccess then
if not TryToEnlargeKernelGeneratingSetAndUpdateSLPsDuringMandarinCrisis(ri) then
# TODO: discard and re-recognise the image.
ErrorNoReturn("TODO");
fi;
# This restarts the loop, since mandarinSuccess is false.
continue;
else
mandarinSuccess := true;
fi;
PrintTreePos("K",depthString,H);
SetKernelRecogNode(ri,riker);
SetParentRecogNode(riker,ri);
mandarinSuccess := true;
Info(InfoRecog,2,"Back from kernel (depth=",depth,").");

if not IsReady(riker) then
Expand All @@ -824,29 +859,24 @@ InstallGlobalFunction( RecogniseGeneric,
Info(InfoRecog,2,"Doing immediate verification (depth=",
depth,").");
immediateVerificationSuccess := ImmediateVerification(ri);
if not immediateVerificationSuccess then
# Restart the loop since immediateVerificationSuccess is false.
continue;
fi;
fi;
for x in kernelMandarins do
if SLPforElement(ri, x) = fail then
# We handle this in the same way as if recognition of the
# kernel returned a MANDARIN_CRISIS.
if not IsSafeForMandarins(ri) then
return MANDARIN_CRISIS;
fi;
if not TryToEnlargeKernelGeneratingSetAndUpdateSLPsDuringMandarinCrisis(ri) then
# TODO: discard and re-recognise the image.
ErrorNoReturn("TODO");
fi;
# This restarts the loop, since mandarinSuccess is false.
continue;
fi;
od;
until mandarinSuccess and immediateVerificationSuccess;

SetNiceGens(ri,Concatenation(pregensfac(ri), NiceGens(riker)));

# check mandarins now
for x in mandarins do
s := SLPforElement(ri, x);
if s = fail then
# TODO: with the master branch rewriting the gens as slps never
# fails. at least we never enter a second iteration of the
# "recognise image" loop.
Info(InfoRecog, 2,
"Enter Mandarin crisis (non-leaf, depth=", depth, ").");
return MANDARIN_CRISIS;
fi;
od;

if InfoLevel(InfoRecog) = 1 and depth = 0 then Print("\n"); fi;
# StopStoringRandEls(ri);
SetFilterObj(ri,IsReady);
Expand Down

0 comments on commit 903f8f3

Please sign in to comment.