@@ -235,6 +235,28 @@ InstallOtherMethod( RecogNode,
235235 return RecogNode(H, projective, r);
236236 end );
237237
238+ RECOG.SetXNodeForNodeAndString := function (r, s )
239+ if not s = MANDARIN_CRISIS then
240+ ErrorNoReturn(" <s> must be MANDARIN_CRISIS" );
241+ fi ;
242+ return ;
243+ end ;
244+
245+ InstallMethod( SetParentRecogNode,
246+ " for a recognition node and a string" ,
247+ [ IsRecogNode, IsString ] ,
248+ RECOG.SetXNodeForNodeAndString);
249+
250+ InstallMethod( SetImageRecogNode,
251+ " for a recognition node and a string" ,
252+ [ IsRecogNode, IsString ] ,
253+ RECOG.SetXNodeForNodeAndString);
254+
255+ InstallMethod( SetKernelRecogNode,
256+ " for a recognition node and a string" ,
257+ [ IsRecogNode, IsString ] ,
258+ RECOG.SetXNodeForNodeAndString);
259+
238260# Sets the stamp used by RandomElm, RandomElmOrd, and related functions.
239261RECOG.SetPseudoRandomStamp := function (g,st )
240262 if IsBound (g!. pseudorandomfunc) then
@@ -464,9 +486,10 @@ function(ri)
464486 gensNWasEmpty := IsEmpty(gensN(ri));
465487 if gensNWasEmpty then
466488 # This gets reduced during each iteration to a minimal value of 1, to
467- # account for the case where the kernel only has two elements. If the
468- # findgensNmeth discards trivial or already found generators, than in
469- # that case we could never find more than one generator.
489+ # account for the case where the kernel only has two elements. The
490+ # findgensNmeth might discard trivial or duplicate generators. In that
491+ # case we can never find more than one generator, if the kernel has
492+ # size two.
470493 targetNrGensN := 5 ;
471494 else
472495 targetNrGensN := 2 * Length(gensN(ri));
@@ -497,7 +520,7 @@ InstallGlobalFunction( RecogniseGeneric,
497520 local depth, ri, allmethods, s, factorMandarins, y, counter_image, rifac,
498521 kernelGenerationSuccess, l, ll, kernelMandarins, x, z,
499522 mandarinSuccess, immediateVerificationSuccess, N, riker,
500- enlargeKernelSuccess, andarin, i;
523+ enlargeKernelSuccess, i;
501524
502525 depth := Length(depthString);
503526
@@ -513,8 +536,8 @@ InstallGlobalFunction( RecogniseGeneric,
513536 Assert (0 , depth = 0 );
514537 # HACK: We don't want the mandarins to be reused by any computation.
515538 # Since PseudoRandom is hacked, it is important that we generate the
516- # mandarins before calling EmptyRecognitionInfoRecord . Otherwise the
517- # mandarins would be reused by RandomElm and RandomElmOrd.
539+ # mandarins before calling RecogNode . Otherwise the mandarins would be
540+ # reused by RandomElm and RandomElmOrd.
518541 # TODO: enable passing NUM_MANDARINS as optional arg
519542 mandarins := List([ 1 .. NUM_MANDARINS_DEFAULT_VALUE] , i -> PseudoRandom(H));
520543 fi ;
@@ -580,11 +603,16 @@ InstallGlobalFunction( RecogniseGeneric,
580603 fi ;
581604 fi ;
582605
583- # TODO: store the mandarins and their SLPs?
606+ # TODO: store the mandarin SLPs here. Make sure, to only write when succesful.
584607 # check mandarins now
585608 for x in mandarins do
586609 s := SLPforElement(ri, x);
587610 if s = fail then
611+ # TODO: with the master branch rewriting the gens as slps never
612+ # fails. at least we never enter a second iteration of the
613+ # "recognise image" loop.
614+ Info (InfoRecog, 2 ,
615+ " Enter Mandarin crisis (leaf, depth=" , depth, " )." );
588616 return MANDARIN_CRISIS;
589617 fi ;
590618 od ;
@@ -608,6 +636,9 @@ InstallGlobalFunction( RecogniseGeneric,
608636 # fails, then somewhere higher up in the recognition tree, a kernel must
609637 # have been too small.
610638 if ForAny(mandarins, x->not ValidateHomomInput(ri, x)) then
639+ Info (InfoRecog, 2 ,
640+ " Enter Mandarin crisis (depth=" , depth, " ), " ,
641+ " ValidateHomomInput failed." );
611642 return MANDARIN_CRISIS;
612643 fi ;
613644 # Compute the mandarins of the factor
@@ -655,19 +686,22 @@ InstallGlobalFunction( RecogniseGeneric,
655686 factorMandarins,
656687 IsSafeForMandarins(ri));
657688 Remove(depthString);
658- if not IsReady(rifac) then
659- # IsReady was not set, thus abort the whole computation.
660- if InfoLevel(InfoRecog) = 1 and depth = 0 then Print(" \n " ); fi ;
661- return ri;
662- fi ;
689+ PrintTreePos(" F" ,depthString,H);
690+ SetImageRecogNode(ri,rifac);
691+ SetParentRecogNode(rifac,ri);
663692 if rifac = MANDARIN_CRISIS then
664693 # According to the mandarins, somewhere higher up in the recognition
665694 # tree, a kernel must have been too small.
695+ Info (InfoRecog, 2 , " Backtrack to the last safe node." );
666696 return MANDARIN_CRISIS;
667697 fi ;
668- PrintTreePos(" F" ,depthString,H);
669- SetImageRecogNode(ri,rifac);
670- SetParentRecogNode(rifac,ri);
698+ # Check for IsReady after checking for MANDARIN_CRISIS, since
699+ # IsReady(MANDARIN_CRISIS) always is false.
700+ if not IsReady(rifac) then
701+ # IsReady was not set, thus abort the whole computation.
702+ if InfoLevel(InfoRecog) = 1 and depth = 0 then Print(" \n " ); fi ;
703+ return ri;
704+ fi ;
671705
672706 if IsMatrixGroup(H) then
673707 Info (InfoRecog,2 ," Back from image (depth=" ,depth,
@@ -711,23 +745,14 @@ InstallGlobalFunction( RecogniseGeneric,
711745 SetgensN(ri,ll);
712746 fi ;
713747
714- # evaluate mandarins to get kernel mandarins
715- # TODO: something is suuper iffy about the method BlocksModScalars, which
716- # is called by BlockDiagonal.
717- # Apparently its input is neither to be understood as a projective nor as a
718- # matrix group, but rather as a "all block-scalars being trivial" group.
719- # That ofc completely wrecks the mandarins, since they assume the group to
720- # be projective.
748+ # Evaluate mandarins to get kernel mandarins
721749 kernelMandarins := [] ;
722750 for i in [ 1 .. Length(mandarins)] do
723751 x := mandarins[ i] ;
724752 y := factorMandarins[ i] ;
725753 s := SLPforElement(rifac, y);
726- # TODO: these SLPs should be stored when they are computed for the
727- # first time.
728- if s = fail then
729- Error(" TODO: no SLP for factor" );
730- fi ;
754+ # TODO: These SLPs should be stored when they are computed for the
755+ # first time. In particular, they can't be fail.
731756 z := ResultOfStraightLineProgram(s, pregensfac(ri));
732757 if not ri!. isequal(x, z) then
733758 Add( kernelMandarins, x / z );
@@ -739,13 +764,21 @@ InstallGlobalFunction( RecogniseGeneric,
739764 # Special case, for an explanation see the source of the called function.
740765 RECOG_HandleSpecialCaseKernelTrivialAndMarkedForImmediateVerification(ri);
741766 fi ;
742- if IsEmpty(gensN(ri)) and not IsEmpty(kernelMandarins) then
743- # We found out that N is the trivial group, but the mandarins disagree!
767+ if IsEmpty(gensN(ri)) and not IsEmpty(kernelMandarins)
768+ # HACK: something is suuper iffy about the method BlocksModScalars,
769+ # see the comment at handling the "Enter mandarin crisis" non-leaf
770+ # case.
771+ and fhmethsel(ri).successMethod <> " BlocksModScalars" then
772+ Info (InfoRecog, 2 ,
773+ " Enter Mandarin crisis (depth=" , depth, " ), " ,
774+ " kernel can't be trivial." );
744775 # We handle this in the same way as if recognition of the
745776 # kernel returned a MANDARIN_CRISIS.
746777 if not IsSafeForMandarins(ri) then
747778 return MANDARIN_CRISIS;
748779 else
780+ Info (InfoRecog, 2 ,
781+ " Handle the mandarin crisis (depth=" , depth, " )." );
749782 if not TryToEnlargeKernelGeneratingSetAndUpdateSLPsDuringMandarinCrisis(ri) then
750783 # TODO: discard and re-recognise the image.
751784 ErrorNoReturn(" TODO" );
@@ -784,36 +817,38 @@ InstallGlobalFunction( RecogniseGeneric,
784817 kernelMandarins,
785818 # TODO: extend this such that riker can also
786819 # be IsSafeForMandarins, if the responsible
787- # findgensNmeth is guaranteed to feed the
820+ # findgensNmeth is guaranteed to find the
788821 # generators for the whole kernel.
789822 false );
790823 Remove(depthString);
824+ PrintTreePos(" K" ,depthString,H);
825+ SetKernelRecogNode(ri,riker);
826+ SetParentRecogNode(riker,ri);
791827 if riker = MANDARIN_CRISIS then
792828 # According to the mandarins, there was an error in the kernel
793829 # generation of the current node or higher up in the recognition
794830 # tree.
795831 if not IsSafeForMandarins(ri) then
796- # Backtrack to the first safe node on the way to the root.
832+ Info (InfoRecog, 2 ,
833+ " Backtrack to the last safe node (depth=" , depth, " )." );
797834 return MANDARIN_CRISIS;
798835 fi ;
836+ Info (InfoRecog, 2 ,
837+ " Handle the mandarin crisis (depth=" , depth, " )." );
799838 # We are the first safe node on the way to the root and thus need to
800839 # handle the crisis ourselves.
801- enlargeKernelSuccess :=
802- TryToEnlargeKernelGeneratingSetAndUpdateSLPsDuringMandarinCrisis(ri);
803- if not enlargeKernelSuccess then
840+ if not TryToEnlargeKernelGeneratingSetAndUpdateSLPsDuringMandarinCrisis(ri) then
804841 # TODO: discard and re-recognise the image.
805842 ErrorNoReturn(" TODO" );
806843 fi ;
807844 # This restarts the loop, since mandarinSuccess is false.
808845 continue ;
809- else
810- mandarinSuccess := true ;
811846 fi ;
812- PrintTreePos(" K" ,depthString,H);
813- SetKernelRecogNode(ri,riker);
814- SetParentRecogNode(riker,ri);
847+ mandarinSuccess := true ;
815848 Info (InfoRecog,2 ," Back from kernel (depth=" ,depth," )." );
816849
850+ # Check for IsReady after checking for MANDARIN_CRISIS, since
851+ # IsReady(MANDARIN_CRISIS) always is false.
817852 if not IsReady(riker) then
818853 # IsReady is not set, thus the whole computation aborts.
819854 return ri;
@@ -824,29 +859,33 @@ InstallGlobalFunction( RecogniseGeneric,
824859 Info (InfoRecog,2 ," Doing immediate verification (depth=" ,
825860 depth," )." );
826861 immediateVerificationSuccess := ImmediateVerification(ri);
827- if not immediateVerificationSuccess then
828- # Restart the loop since immediateVerificationSuccess is false.
829- continue ;
830- fi ;
831862 fi ;
832- for x in kernelMandarins do
833- if SLPforElement(ri, x) = fail then
834- # We handle this in the same way as if recognition of the
835- # kernel returned a MANDARIN_CRISIS.
836- if not IsSafeForMandarins(ri) then
837- return MANDARIN_CRISIS;
838- fi ;
839- if not TryToEnlargeKernelGeneratingSetAndUpdateSLPsDuringMandarinCrisis(ri) then
840- # TODO: discard and re-recognise the image.
841- ErrorNoReturn(" TODO" );
842- fi ;
843- # This restarts the loop, since mandarinSuccess is false.
844- continue ;
845- fi ;
846- od ;
847863 until mandarinSuccess and immediateVerificationSuccess;
848864
849865 SetNiceGens(ri,Concatenation(pregensfac(ri), NiceGens(riker)));
866+
867+ # Check mandarins now
868+ for x in mandarins do
869+ # TODO: something is suuper iffy about the method BlocksModScalars, which
870+ # is called by BlockDiagonal.
871+ # Apparently its input is neither to be understood as a projective nor as a
872+ # matrix group, but rather as a "all block-scalars being trivial" group.
873+ # That ofc completely wrecks the mandarins, since they assume the group to
874+ # be projective. Currently we don't check here whether the SLP for a
875+ # mandarin evaluates to the mandarin.
876+ # This also has to be considered when doing immediate verification.
877+ # To solve that situation we hacked SLPforElementGeneric.
878+ s := SLPforElement(ri, x);
879+ if s = fail then
880+ # TODO: with the master branch rewriting the gens as slps never
881+ # fails. at least we never enter a second iteration of the
882+ # "recognise image" loop.
883+ Info (InfoRecog, 2 ,
884+ " Enter Mandarin crisis (non-leaf, depth=" , depth, " )." );
885+ return MANDARIN_CRISIS;
886+ fi ;
887+ od ;
888+
850889 if InfoLevel(InfoRecog) = 1 and depth = 0 then Print(" \n " ); fi ;
851890 # StopStoringRandEls(ri);
852891 SetFilterObj(ri,IsReady);
0 commit comments