@@ -228,6 +228,28 @@ InstallOtherMethod( RecogNode,
228228 return RecogNode(H, projective, rec ());
229229 end );
230230
231+ RECOG.SetXNodeForNodeAndString := function (r, s )
232+ if not s = MANDARIN_CRISIS then
233+ ErrorNoReturn(" <s> must be MANDARIN_CRISIS" );
234+ fi ;
235+ return ;
236+ end ;
237+
238+ InstallMethod( SetParentRecogNode,
239+ " for a recognition node and a string" ,
240+ [ IsRecogNode, IsString ] ,
241+ RECOG.SetXNodeForNodeAndString);
242+
243+ InstallMethod( SetImageRecogNode,
244+ " for a recognition node and a string" ,
245+ [ IsRecogNode, IsString ] ,
246+ RECOG.SetXNodeForNodeAndString);
247+
248+ InstallMethod( SetKernelRecogNode,
249+ " for a recognition node and a string" ,
250+ [ IsRecogNode, IsString ] ,
251+ RECOG.SetXNodeForNodeAndString);
252+
231253# Sets the stamp used by RandomElm, RandomElmOrd, and related functions.
232254RECOG.SetPseudoRandomStamp := function (g,st )
233255 if IsBound (g!. pseudorandomfunc) then
@@ -457,9 +479,10 @@ function(ri)
457479 gensNWasEmpty := IsEmpty(gensN(ri));
458480 if gensNWasEmpty then
459481 # This gets reduced during each iteration to a minimal value of 1, to
460- # account for the case where the kernel only has two elements. If the
461- # findgensNmeth discards trivial or already found generators, than in
462- # that case we could never find more than one generator.
482+ # account for the case where the kernel only has two elements. The
483+ # findgensNmeth might discard trivial or duplicate generators. In that
484+ # case we can never find more than one generator, if the kernel has
485+ # size two.
463486 targetNrGensN := 5 ;
464487 else
465488 targetNrGensN := 2 * Length(gensN(ri));
@@ -490,7 +513,7 @@ InstallGlobalFunction( RecogniseGeneric,
490513 local depth, ri, allmethods, s, factorMandarins, y, counter_image, rifac,
491514 kernelGenerationSuccess, l, ll, kernelMandarins, x, z,
492515 mandarinSuccess, immediateVerificationSuccess, N, riker,
493- enlargeKernelSuccess, andarin, i;
516+ enlargeKernelSuccess, i;
494517
495518 depth := Length(depthString);
496519
@@ -506,18 +529,18 @@ InstallGlobalFunction( RecogniseGeneric,
506529 Assert (0 , depth = 0 );
507530 # HACK: We don't want the mandarins to be reused by any computation.
508531 # Since PseudoRandom is hacked, it is important that we generate the
509- # mandarins before calling EmptyRecognitionInfoRecord . Otherwise the
510- # mandarins would be reused by RandomElm and RandomElmOrd.
532+ # mandarins before calling RecogNode . Otherwise the mandarins would be
533+ # reused by RandomElm and RandomElmOrd.
511534 # TODO: enable passing NUM_MANDARINS as optional arg
512535 mandarins := List([ 1 .. NUM_MANDARINS_DEFAULT_VALUE] , i -> PseudoRandom(H));
513536 fi ;
514537
515538
516539 # Set up the record and the group object:
517540 ri := RecogNode(
518- knowledge,
519541 H,
520- IsIdenticalObj( methoddb, FindHomDbProjective )
542+ IsIdenticalObj( methoddb, FindHomDbProjective ),
543+ knowledge
521544 );
522545 if isSafeForMandarins then
523546 SetFilterObj(ri, IsSafeForMandarins);
@@ -573,11 +596,16 @@ InstallGlobalFunction( RecogniseGeneric,
573596 fi ;
574597 fi ;
575598
576- # TODO: store the mandarins and their SLPs?
599+ # TODO: store the mandarin SLPs here. Make sure, to only write when succesful.
577600 # check mandarins now
578601 for x in mandarins do
579602 s := SLPforElement(ri, x);
580603 if s = fail then
604+ # TODO: with the master branch rewriting the gens as slps never
605+ # fails. at least we never enter a second iteration of the
606+ # "recognise image" loop.
607+ Info (InfoRecog, 2 ,
608+ " Enter Mandarin crisis (leaf, depth=" , depth, " )." );
581609 return MANDARIN_CRISIS;
582610 fi ;
583611 od ;
@@ -601,6 +629,9 @@ InstallGlobalFunction( RecogniseGeneric,
601629 # fails, then somewhere higher up in the recognition tree, a kernel must
602630 # have been too small.
603631 if ForAny(mandarins, x->not ValidateHomomInput(ri, x)) then
632+ Info (InfoRecog, 2 ,
633+ " Enter Mandarin crisis (depth=" , depth, " ), " ,
634+ " ValidateHomomInput failed." );
604635 return MANDARIN_CRISIS;
605636 fi ;
606637 # Compute the mandarins of the factor
@@ -648,19 +679,22 @@ InstallGlobalFunction( RecogniseGeneric,
648679 factorMandarins,
649680 IsSafeForMandarins(ri));
650681 Remove(depthString);
651- if not IsReady(rifac) then
652- # IsReady was not set, thus abort the whole computation.
653- if InfoLevel(InfoRecog) = 1 and depth = 0 then Print(" \n " ); fi ;
654- return ri;
655- fi ;
682+ PrintTreePos(" F" ,depthString,H);
683+ SetImageRecogNode(ri,rifac);
684+ SetParentRecogNode(rifac,ri);
656685 if rifac = MANDARIN_CRISIS then
657686 # According to the mandarins, somewhere higher up in the recognition
658687 # tree, a kernel must have been too small.
688+ Info (InfoRecog, 2 , " Backtrack to the last safe node." );
659689 return MANDARIN_CRISIS;
660690 fi ;
661- PrintTreePos(" F" ,depthString,H);
662- SetImageRecogNode(ri,rifac);
663- SetParentRecogNode(rifac,ri);
691+ # Check for IsReady after checking for MANDARIN_CRISIS, since
692+ # IsReady(MANDARIN_CRISIS) always is false.
693+ if not IsReady(rifac) then
694+ # IsReady was not set, thus abort the whole computation.
695+ if InfoLevel(InfoRecog) = 1 and depth = 0 then Print(" \n " ); fi ;
696+ return ri;
697+ fi ;
664698
665699 if IsMatrixGroup(H) then
666700 Info (InfoRecog,2 ," Back from image (depth=" ,depth,
@@ -704,23 +738,14 @@ InstallGlobalFunction( RecogniseGeneric,
704738 SetgensN(ri,ll);
705739 fi ;
706740
707- # evaluate mandarins to get kernel mandarins
708- # TODO: something is suuper iffy about the method BlocksModScalars, which
709- # is called by BlockDiagonal.
710- # Apparently its input is neither to be understood as a projective nor as a
711- # matrix group, but rather as a "all block-scalars being trivial" group.
712- # That ofc completely wrecks the mandarins, since they assume the group to
713- # be projective.
741+ # Evaluate mandarins to get kernel mandarins
714742 kernelMandarins := [] ;
715743 for i in [ 1 .. Length(mandarins)] do
716744 x := mandarins[ i] ;
717745 y := factorMandarins[ i] ;
718746 s := SLPforElement(rifac, y);
719- # TODO: these SLPs should be stored when they are computed for the
720- # first time.
721- if s = fail then
722- Error(" TODO: no SLP for factor" );
723- fi ;
747+ # TODO: These SLPs should be stored when they are computed for the
748+ # first time. In particular, they can't be fail.
724749 z := ResultOfStraightLineProgram(s, pregensfac(ri));
725750 if not ri!. isequal(x, z) then
726751 Add( kernelMandarins, x / z );
@@ -732,13 +757,21 @@ InstallGlobalFunction( RecogniseGeneric,
732757 # Special case, for an explanation see the source of the called function.
733758 RECOG_HandleSpecialCaseKernelTrivialAndMarkedForImmediateVerification(ri);
734759 fi ;
735- if IsEmpty(gensN(ri)) and not IsEmpty(kernelMandarins) then
736- # We found out that N is the trivial group, but the mandarins disagree!
760+ if IsEmpty(gensN(ri)) and not IsEmpty(kernelMandarins)
761+ # HACK: something is suuper iffy about the method BlocksModScalars,
762+ # see the comment at handling the "Enter mandarin crisis" non-leaf
763+ # case.
764+ and fhmethsel(ri).successMethod <> " BlocksModScalars" then
765+ Info (InfoRecog, 2 ,
766+ " Enter Mandarin crisis (depth=" , depth, " ), " ,
767+ " kernel can't be trivial." );
737768 # We handle this in the same way as if recognition of the
738769 # kernel returned a MANDARIN_CRISIS.
739770 if not IsSafeForMandarins(ri) then
740771 return MANDARIN_CRISIS;
741772 else
773+ Info (InfoRecog, 2 ,
774+ " Handle the mandarin crisis (depth=" , depth, " )." );
742775 if not TryToEnlargeKernelGeneratingSetAndUpdateSLPsDuringMandarinCrisis(ri) then
743776 # TODO: discard and re-recognise the image.
744777 ErrorNoReturn(" TODO" );
@@ -777,36 +810,38 @@ InstallGlobalFunction( RecogniseGeneric,
777810 kernelMandarins,
778811 # TODO: extend this such that riker can also
779812 # be IsSafeForMandarins, if the responsible
780- # findgensNmeth is guaranteed to feed the
813+ # findgensNmeth is guaranteed to find the
781814 # generators for the whole kernel.
782815 false );
783816 Remove(depthString);
817+ PrintTreePos(" K" ,depthString,H);
818+ SetKernelRecogNode(ri,riker);
819+ SetParentRecogNode(riker,ri);
784820 if riker = MANDARIN_CRISIS then
785821 # According to the mandarins, there was an error in the kernel
786822 # generation of the current node or higher up in the recognition
787823 # tree.
788824 if not IsSafeForMandarins(ri) then
789- # Backtrack to the first safe node on the way to the root.
825+ Info (InfoRecog, 2 ,
826+ " Backtrack to the last safe node (depth=" , depth, " )." );
790827 return MANDARIN_CRISIS;
791828 fi ;
829+ Info (InfoRecog, 2 ,
830+ " Handle the mandarin crisis (depth=" , depth, " )." );
792831 # We are the first safe node on the way to the root and thus need to
793832 # handle the crisis ourselves.
794- enlargeKernelSuccess :=
795- TryToEnlargeKernelGeneratingSetAndUpdateSLPsDuringMandarinCrisis(ri);
796- if not enlargeKernelSuccess then
833+ if not TryToEnlargeKernelGeneratingSetAndUpdateSLPsDuringMandarinCrisis(ri) then
797834 # TODO: discard and re-recognise the image.
798835 ErrorNoReturn(" TODO" );
799836 fi ;
800837 # This restarts the loop, since mandarinSuccess is false.
801838 continue ;
802- else
803- mandarinSuccess := true ;
804839 fi ;
805- PrintTreePos(" K" ,depthString,H);
806- SetKernelRecogNode(ri,riker);
807- SetParentRecogNode(riker,ri);
840+ mandarinSuccess := true ;
808841 Info (InfoRecog,2 ," Back from kernel (depth=" ,depth," )." );
809842
843+ # Check for IsReady after checking for MANDARIN_CRISIS, since
844+ # IsReady(MANDARIN_CRISIS) always is false.
810845 if not IsReady(riker) then
811846 # IsReady is not set, thus the whole computation aborts.
812847 return ri;
@@ -817,29 +852,33 @@ InstallGlobalFunction( RecogniseGeneric,
817852 Info (InfoRecog,2 ," Doing immediate verification (depth=" ,
818853 depth," )." );
819854 immediateVerificationSuccess := ImmediateVerification(ri);
820- if not immediateVerificationSuccess then
821- # Restart the loop since immediateVerificationSuccess is false.
822- continue ;
823- fi ;
824855 fi ;
825- for x in kernelMandarins do
826- if SLPforElement(ri, x) = fail then
827- # We handle this in the same way as if recognition of the
828- # kernel returned a MANDARIN_CRISIS.
829- if not IsSafeForMandarins(ri) then
830- return MANDARIN_CRISIS;
831- fi ;
832- if not TryToEnlargeKernelGeneratingSetAndUpdateSLPsDuringMandarinCrisis(ri) then
833- # TODO: discard and re-recognise the image.
834- ErrorNoReturn(" TODO" );
835- fi ;
836- # This restarts the loop, since mandarinSuccess is false.
837- continue ;
838- fi ;
839- od ;
840856 until mandarinSuccess and immediateVerificationSuccess;
841857
842858 SetNiceGens(ri,Concatenation(pregensfac(ri), NiceGens(riker)));
859+
860+ # Check mandarins now
861+ for x in mandarins do
862+ # TODO: something is suuper iffy about the method BlocksModScalars, which
863+ # is called by BlockDiagonal.
864+ # Apparently its input is neither to be understood as a projective nor as a
865+ # matrix group, but rather as a "all block-scalars being trivial" group.
866+ # That ofc completely wrecks the mandarins, since they assume the group to
867+ # be projective. Currently we don't check here whether the SLP for a
868+ # mandarin evaluates to the mandarin.
869+ # This also has to be considered when doing immediate verification.
870+ # To solve that situation we hacked SLPforElementGeneric.
871+ s := SLPforElement(ri, x);
872+ if s = fail then
873+ # TODO: with the master branch rewriting the gens as slps never
874+ # fails. at least we never enter a second iteration of the
875+ # "recognise image" loop.
876+ Info (InfoRecog, 2 ,
877+ " Enter Mandarin crisis (non-leaf, depth=" , depth, " )." );
878+ return MANDARIN_CRISIS;
879+ fi ;
880+ od ;
881+
843882 if InfoLevel(InfoRecog) = 1 and depth = 0 then Print(" \n " ); fi ;
844883 # StopStoringRandEls(ri);
845884 SetFilterObj(ri,IsReady);
0 commit comments