This file is indexed.

/usr/share/gap/pkg/AtlasRep/gap/bbox.gd is in gap-atlasrep 1.5.1-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
#############################################################################
##
#W  bbox.gd              GAP 4 package AtlasRep                 Thomas Breuer
#W                                                            Simon Nickerson
##
#Y  Copyright (C)  2005,  Lehrstuhl D fuer Mathematik,  RWTH Aachen,  Germany
##
##  This file contains the declarations of the operations
##  for black box programs and straight line decisions.
##
##  1. Functions for black box algorithms
##  2. Functions for straight line decisions
##


#############################################################################
##
##  1. Functions for black box algorithms
##
##  <#GAPDoc Label="BBoxIntro">
##  <E>Black box programs</E> formalize the idea that one takes some group
##  elements, forms arithmetic expressions in terms of them, tests properties
##  of these expressions,
##  executes conditional statements (including jumps inside the program)
##  depending on the results of these tests,
##  and eventually returns some result.
##  <P/>
##  A specification of the language can be found in <Cite Key="Nic06"/>,
##  see also
##  <P/>
##  <URL>http://brauer.maths.qmul.ac.uk/Atlas/info/blackbox.html</URL>.
##  <P/>
##  The <E>inputs</E> of a black box program may be explicit group elements,
##  and the program may also ask for random elements from a given group.
##  The <E>program steps</E> form products, inverses, conjugates,
##  commutators, etc. of known elements,
##  <E>tests</E> concern essentially the orders of elements,
##  and the <E>result</E> is a list of group elements or <K>true</K> or
##  <K>false</K> or <K>fail</K>.
##  <P/>
##  Examples that can be modeled by black box programs are
##  <P/>
##  <List>
##  <Mark><E>straight line programs</E>,</Mark>
##  <Item>
##    which require a fixed number of input elements and form arithmetic
##    expressions of elements but do not use random elements, tests,
##    conditional statements and jumps;
##    the return value is always a list of elements;
##    these programs are described
##    in Section <Ref Sect="Straight Line Programs" BookName="ref"/>.
##  </Item>
##  <Mark><E>straight line decisions</E>,</Mark>
##  <Item>
##    which differ from straight line programs only in the sense that also
##    order tests are admissible,
##    and that the return value is <K>true</K> if all these tests are
##    satisfied, and <K>false</K> as soon as the first such test fails;
##    they are described
##    in Section <Ref Sect="sect:Straight Line Decisions"/>.
##  </Item>
##  <Mark><E>scripts for finding standard generators</E>,</Mark>
##  <Item>
##    which take a group and a function to generate a random element in this
##    group but no explicit input elements,
##    admit all control structures, and return either a list of standard
##    generators or <K>fail</K>;
##    see <Ref Func="ResultOfBBoxProgram"/> for examples.
##  </Item>
##  </List>
##  <P/>
##  In the case of general black box programs, currently &GAP; provides only
##  the possibility to read an existing program via
##  <Ref Func="ScanBBoxProgram"/>,
##  and to run the program using <Ref Func="RunBBoxProgram"/>.
##  It is not our aim to write such programs in &GAP;.
##  <P/>
##  The special case of the <Q>find</Q> scripts mentioned above is also
##  admissible as an argument of <Ref Func="ResultOfBBoxProgram"/>,
##  which returns either the set of generators or <K>fail</K>.
##  <P/>
##  Contrary to the general situation,
##  more support is provided for straight line programs and straight line
##  decisions in &GAP;,
##  see Section <Ref Sect="Straight Line Programs" BookName="ref"/>
##  for functions that manipulate them (compose, restrict etc.).
##  <P/>
##  The functions <Ref Func="AsStraightLineProgram"/> and
##  <Ref Func="AsStraightLineDecision"/> can be used to transform a general
##  black box program object into a straight line program or a straight line
##  decision if this is possible.
##  <P/>
##  Conversely, one can create an equivalent general black box program from
##  a straight line program or from a straight line decision with
##  <Ref Func="AsBBoxProgram"/>.
##  <P/>
##  (Computing a straight line program related to a given straight line
##  decision is supported in the sense of
##  <Ref Func="StraightLineProgramFromStraightLineDecision"/>.)
##  <P/>
##  Note that none of these three kinds of objects is a special case of
##  another:
##  Running a black box program with <Ref Func="RunBBoxProgram"/> yields a
##  record,
##  running a straight line program with
##  <Ref Func="ResultOfStraightLineProgram" BookName="ref"/> yields a list of
##  elements,
##  and running a straight line decision with
##  <Ref Func="ResultOfStraightLineDecision"/> yields <K>true</K> or
##  <K>false</K>.
##  <#/GAPDoc>
##


#############################################################################
##
#V  InfoBBox
##
##  <#GAPDoc Label="InfoBBox">
##  <ManSection>
##  <InfoClass Name="InfoBBox"/>
##
##  <Description>
##  If the info level of <Ref InfoClass="InfoBBox"/> is at least <M>1</M>
##  then information about <K>fail</K> results of functions dealing with
##  black box programs (see Section <Ref Sect="sect:Black Box Programs"/>)
##  is printed.
##  The default level is <M>0</M>, no information is printed on this level.
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareInfoClass( "InfoBBox" );


#############################################################################
##
#C  IsBBoxProgram( <obj> )
##
##  <#GAPDoc Label="IsBBoxProgram">
##  <ManSection>
##  <Filt Name="IsBBoxProgram" Arg='obj' Type="Category"/>
##
##  <Description>
##  Each black box program in &GAP; lies in the filter
##  <Ref Func="IsBBoxProgram"/>.
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareCategory( "IsBBoxProgram", IsObject );


#############################################################################
##
#A  LinesOfBBoxProgram( <prog> )
##
##  Since no black box program can be a straight line program,
##  we (ab)use the available attribute.
##
DeclareSynonymAttr( "LinesOfBBoxProgram", LinesOfStraightLineProgram );


#############################################################################
##
#F  ScanBBoxProgram( <string> )
##
##  <#GAPDoc Label="ScanBBoxProgram">
##  <ManSection>
##  <Func Name="ScanBBoxProgram" Arg='string'/>
##
##  <Returns>
##  a record containing the black box program encoded by the input string,
##  or <K>fail</K>.
##  </Returns>
##  <Description>
##  For a string <A>string</A> that describes a black box program, e.g.,
##  the return value of <Ref Func="StringFile" BookName="gapdoc"/>,
##  <Ref Func="ScanBBoxProgram"/> computes this black box program.
##  If this is successful then the return value is a record containing as the
##  value of its component <C>program</C> the corresponding &GAP; object
##  that represents the program,
##  otherwise <K>fail</K> is returned.
##  <P/>
##  As the first example, we construct a black box program that tries to find
##  standard generators for the alternating group <M>A_5</M>;
##  these standard generators are any pair of elements of the orders <M>2</M>
##  and <M>3</M>, respectively, such that their product has order <M>5</M>.
##  <P/>
##  <Example><![CDATA[
##  gap> findstr:= "\
##  >   set V 0\n\
##  > lbl START1\n\
##  >   rand 1\n\
##  >   ord 1 A\n\
##  >   incr V\n\
##  >   if V gt 100 then timeout\n\
##  >   if A notin 1 2 3 5 then fail\n\
##  >   if A noteq 2 then jmp START1\n\
##  > lbl START2\n\
##  >   rand 2\n\
##  >   ord 2 B\n\
##  >   incr V\n\
##  >   if V gt 100 then timeout\n\
##  >   if B notin 1 2 3 5 then fail\n\
##  >   if B noteq 3 then jmp START2\n\
##  >   # The elements 1 and 2 have the orders 2 and 3, respectively.\n\
##  >   set X 0\n\
##  > lbl CONJ\n\
##  >   incr X\n\
##  >   if X gt 100 then timeout\n\
##  >   rand 3\n\
##  >   cjr 2 3\n\
##  >   mu 1 2 4   # ab\n\
##  >   ord 4 C\n\
##  >   if C notin 2 3 5 then fail\n\
##  >   if C noteq 5 then jmp CONJ\n\
##  >   oup 2 1 2";;
##  gap> find:= ScanBBoxProgram( findstr );
##  rec( program := <black box program> )
##  ]]></Example>
##  <P/>
##  The second example is a black box program that checks whether its two
##  inputs are standard generators for <M>A_5</M>.
##  <P/>
##  <Example><![CDATA[
##  gap> checkstr:= "\
##  > chor 1 2\n\
##  > chor 2 3\n\
##  > mu 1 2 3\n\
##  > chor 3 5";;
##  gap> check:= ScanBBoxProgram( checkstr );
##  rec( program := <black box program> )
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareGlobalFunction( "ScanBBoxProgram" );


#############################################################################
##
#F  BBoxPerformInstruction( fullline, ins, G, ans, gpelts, ctr, options )
##
##  local utility (but recursive, therefore we declare it here)
##
DeclareGlobalFunction( "BBoxPerformInstruction" );


#############################################################################
##
#F  RunBBoxProgram( <prog>, <G>, <input>, <options> )
##
##  <#GAPDoc Label="RunBBoxProgram">
##  <ManSection>
##  <Func Name="RunBBoxProgram" Arg='prog, G, input, options'/>
##
##  <Returns>
##  a record describing the result and the statistics of running the
##  black box program <A>prog</A>, or <K>fail</K>,
##  or the string <C>"timeout"</C>.
##  </Returns>
##  <Description>
##  For a black box program <A>prog</A>, a group <A>G</A>,
##  a list <A>input</A> of group elements,
##  and a record <A>options</A>,
##  <Ref Func="RunBBoxProgram"/> applies <A>prog</A> to <A>input</A>,
##  where <A>G</A> is used only to compute random elements.
##  <P/>
##  The return value is <K>fail</K> if a syntax error or
##  an explicit <C>fail</C> statement is reached at runtime,
##  and the string <C>"timeout"</C> if a <C>timeout</C> statement is reached.
##  (The latter might mean that the random choices were unlucky.)
##  Otherwise a record with the following components is returned.
##  <P/>
##  <List>
##  <Mark><C>gens</C></Mark>
##  <Item>
##    a list of group elements, bound if an <C>oup</C> statement was reached,
##  </Item>
##  <Mark><C>result</C></Mark>
##  <Item>
##    <K>true</K> if a <C>true</C> statement was reached,
##    <K>false</K> if either a <C>false</C> statement or a failed order check
##    was reached,
##  </Item>
##  </List>
##  <P/>
##  The other components serve as statistical information about the numbers
##  of the various operations (<C>multiply</C>, <C>invert</C>, <C>power</C>,
##  <C>order</C>, <C>random</C>, <C>conjugate</C>, <C>conjugateinplace</C>,
##  <C>commutator</C>), and the runtime in milliseconds (<C>timetaken</C>).
##  <P/>
##  The following components of <A>options</A> are supported.
##  <P/>
##  <List>
##  <Mark><C>randomfunction</C></Mark>
##  <Item>
##    the function called with argument <A>G</A> in order to compute a
##    random element of <A>G</A>
##    (default <Ref Oper="PseudoRandom" BookName="ref"/>)
##  </Item>
##  <Mark><C>orderfunction</C></Mark>
##  <Item>
##    the function for computing element orders
##    (the default is <Ref Oper="Order" BookName="ref"/>),
##  </Item>
##  <Mark><C>quiet</C></Mark>
##  <Item>
##    if <K>true</K> then ignore <C>echo</C> statements
##    (default <K>false</K>),
##  </Item>
##  <Mark><C>verbose</C></Mark>
##  <Item>
##    if <K>true</K> then print information about the line that is currently
##    processed, and about order checks (default <K>false</K>),
##  </Item>
##  <Mark><C>allowbreaks</C></Mark>
##  <Item>
##    if <K>true</K> then call <Ref Func="Error" BookName="ref"/> when a
##    <C>break</C> statement is reached, otherwise ignore <C>break</C>
##    statements (default <K>true</K>).
##  </Item>
##  </List>
##  <P/>
##  As an example, we run the black box programs constructed in the example
##  for <Ref Func="ScanBBoxProgram"/>.
##  <P/>
##  <Example><![CDATA[
##  gap> g:= AlternatingGroup( 5 );;
##  gap> res:= RunBBoxProgram( find.program, g, [], rec() );;
##  gap> IsBound( res.gens );  IsBound( res.result );
##  true
##  false
##  gap> List( res.gens, Order );
##  [ 2, 3 ]
##  gap> Order( Product( res.gens ) );
##  5
##  gap> res:= RunBBoxProgram( check.program, "dummy", res.gens, rec() );;
##  gap> IsBound( res.gens );  IsBound( res.result );
##  false
##  true
##  gap> res.result;
##  true
##  gap> othergens:= GeneratorsOfGroup( g );;
##  gap> res:= RunBBoxProgram( check.program, "dummy", othergens, rec() );;
##  gap> res.result;
##  false
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareGlobalFunction( "RunBBoxProgram" );


#############################################################################
##
#F  ResultOfBBoxProgram( <prog>, <G> )
#F  ResultOfBBoxProgram( <prog>, <gens> )
##
##  <#GAPDoc Label="ResultOfBBoxProgram">
##  <ManSection>
##  <Func Name="ResultOfBBoxProgram" Arg='prog, G'/>
##
##  <Returns>
##  a list of group elements or <K>true</K>, <K>false</K>, <K>fail</K>,
##  or the string <C>"timeout"</C>.
##  </Returns>
##  <Description>
##  This function calls <Ref Func="RunBBoxProgram"/>
##  with the black box program <A>prog</A> and second argument either a group
##  or a list of group elements; the default options are assumed.
##  The return value is <K>fail</K> if this call yields <K>fail</K>,
##  otherwise the <C>gens</C> component of the result, if bound,
##  or the <C>result</C> component if not.
##  <P/>
##  As an example, we run the black box programs constructed in the example
##  for <Ref Func="ScanBBoxProgram"/>.
##  <P/>
##  <Example><![CDATA[
##  gap> g:= AlternatingGroup( 5 );;
##  gap> res:= ResultOfBBoxProgram( find.program, g );;
##  gap> List( res, Order );
##  [ 2, 3 ]
##  gap> Order( Product( res ) );
##  5
##  gap> res:= ResultOfBBoxProgram( check.program, res );
##  true
##  gap> othergens:= GeneratorsOfGroup( g );;
##  gap> res:= ResultOfBBoxProgram( check.program, othergens );
##  false
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareGlobalFunction( "ResultOfBBoxProgram" );


#############################################################################
##
##  2. Functions for straight line decisions
##


#############################################################################
##
##  <#GAPDoc Label="StraightLineDecisionIntro">
##  <E>Straight line decisions</E> are similar to straight line programs
##  (see Section&nbsp;<Ref Sect="Straight Line Programs" BookName="ref"/>)
##  but return <K>true</K> or <K>false</K>.
##  A straight line decisions checks a property for its inputs.
##  An important example is to check whether a given list of group generators
##  is in fact a list of standard generators
##  (cf.&nbsp;Section<Ref Sect="sect:Standard Generators Used in AtlasRep"/>)
##  for this group.
##  <P/>
##  A straight line decision in &GAP; is represented by an object in the
##  filter <Ref Filt="IsStraightLineDecision"/>
##  that stores a list of <Q>lines</Q>
##  each of which has one of the following three forms.
##  <P/>
##  <Enum>
##  <Item>
##      a nonempty dense list <M>l</M> of integers,
##  </Item>
##  <Item>
##      a pair <M>[ l, i ]</M> where
##      <M>l</M> is a list of form 1. and <M>i</M> is a positive integer,
##  </Item>
##  <Item>
##      a list <M>[ </M><C>"Order"</C><M>, i, n ]</M>
##      where <M>i</M> and <M>n</M> are positive integers.
##  </Item>
##  </Enum>
##  <P/>
##  The first two forms have the same meaning as for straight line programs
##  (see Section&nbsp;<Ref Sect="Straight Line Programs" BookName="ref"/>),
##  the last form means a check whether the element stored at the label
##  <M>i</M>-th has the order <M>n</M>.
##  <P/>
##  For the meaning of the list of lines, see
##  <Ref Oper="ResultOfStraightLineDecision"/>.
##  <P/>
##  Straight line decisions can be constructed using
##  <Ref Func="StraightLineDecision"/>,
##  defining attributes for straight line decisions are
##  <Ref Func="NrInputsOfStraightLineDecision"/> and
##  <Ref Func="LinesOfStraightLineDecision"/>,
##  an operation for straight line decisions is
##  <Ref Func="ResultOfStraightLineDecision"/>.
##  <P/>
##  Special methods applicable to straight line decisions are installed for
##  the operations <Ref Func="Display" BookName="ref"/>,
##  <Ref Func="IsInternallyConsistent" BookName="ref"/>,
##  <Ref Func="PrintObj" BookName="ref"/>,
##  and <Ref Func="ViewObj" BookName="ref"/>.
##  <P/>
##  For a straight line decision <A>prog</A>,
##  the default <Ref Func="Display" BookName="ref"/> method prints
##  the interpretation of <A>prog</A> as a sequence of assignments
##  of associative words and of order checks;
##  a record with components <C>gensnames</C> (with value a list of strings)
##  and <C>listname</C> (a string) may be entered as second argument of
##  <Ref Func="Display" BookName="ref"/>,
##  in this case these names are used, the default for <C>gensnames</C> is
##  <C>[ g1, g2, </C><M>\ldots</M><C> ]</C>,
##  the default for <A>listname</A> is <M>r</M>.
##  <#/GAPDoc>
##


#############################################################################
##
#C  IsStraightLineDecision( <obj> )
##
##  <#GAPDoc Label="IsStraightLineDecision">
##  <ManSection>
##  <Filt Name="IsStraightLineDecision" Arg='obj' Type="Category"/>
##
##  <Description>
##  Each straight line decision in &GAP; lies in the filter
##  <Ref Func="IsStraightLineDecision"/>.
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareCategory( "IsStraightLineDecision", IsObject );


#############################################################################
##
#F  StraightLineDecision( <lines>[, <nrgens>] )
#F  StraightLineDecisionNC( <lines>[, <nrgens>] )
##
##  <#GAPDoc Label="StraightLineDecision">
##  <ManSection>
##  <Func Name="StraightLineDecision" Arg='lines[, nrgens]'/>
##  <Func Name="StraightLineDecisionNC" Arg='lines[, nrgens]'/>
##
##  <Returns>
##  the straight line decision given by the list of lines.
##  </Returns>
##  <Description>
##  Let <A>lines</A> be a list of lists that defines a unique
##  straight line decision (see&nbsp;<Ref Func="IsStraightLineDecision"/>);
##  in this case <Ref Func="StraightLineDecision"/> returns this program,
##  otherwise an error is signalled.
##  The optional argument <A>nrgens</A> specifies the number of
##  input generators of the program;
##  if a list of integers (a line of form 1. in the definition above) occurs
##  in <A>lines</A> then this number is not determined by <A>lines</A>
##  and therefore <E>must</E> be specified by the argument <A>nrgens</A>;
##  if not then <Ref Func="StraightLineDecision"/> returns <K>fail</K>.
##  <P/>
##  <Ref Func="StraightLineDecisionNC"/> does the same as
##  <Ref Func="StraightLineDecision"/>,
##  except that the internal consistency of the program is not checked.
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareGlobalFunction( "StraightLineDecision" );

DeclareGlobalFunction( "StraightLineDecisionNC" );


#############################################################################
##
#A  LinesOfStraightLineDecision( <prog> )
##
##  <#GAPDoc Label="LinesOfStraightLineDecision">
##  <ManSection>
##  <Oper Name="LinesOfStraightLineDecision" Arg='prog'/>
##
##  <Returns>
##  the list of lines that define the straight line decision.
##  </Returns>
##  <Description>
##  This defining attribute for the straight line decision <A>prog</A>
##  (see <Ref Func="IsStraightLineDecision"/>) corresponds to
##  <Ref Attr="LinesOfStraightLineProgram" BookName="ref"/>
##  for straight line programs.
##  <P/>
##  <Example><![CDATA[
##  gap> dec:= StraightLineDecision( [ [ [ 1, 1, 2, 1 ], 3 ],
##  > [ "Order", 1, 2 ], [ "Order", 2, 3 ], [ "Order", 3, 5 ] ] );
##  <straight line decision>
##  gap> LinesOfStraightLineDecision( dec );
##  [ [ [ 1, 1, 2, 1 ], 3 ], [ "Order", 1, 2 ], [ "Order", 2, 3 ], 
##    [ "Order", 3, 5 ] ]
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareAttribute( "LinesOfStraightLineDecision", IsStraightLineDecision );


#############################################################################
##
#A  NrInputsOfStraightLineDecision( <prog> )
##
##  <#GAPDoc Label="NrInputsOfStraightLineDecision">
##  <ManSection>
##  <Oper Name="NrInputsOfStraightLineDecision" Arg='prog'/>
##
##  <Returns>
##  the number of inputs required for the straight line decision.
##  </Returns>
##  <Description>
##  This defining attribute corresponds to
##  <Ref Attr="NrInputsOfStraightLineProgram" BookName="ref"/>.
##  <P/>
##  <Example><![CDATA[
##  gap> NrInputsOfStraightLineDecision( dec );
##  2
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareAttribute( "NrInputsOfStraightLineDecision", IsStraightLineDecision );


#############################################################################
##
#O  ResultOfStraightLineDecision( <prog>, <gens>[, <orderfunc>] )
##
##  <#GAPDoc Label="ResultOfStraightLineDecision">
##  <ManSection>
##  <Oper Name="ResultOfStraightLineDecision" Arg='prog, gens[, orderfunc]'/>
##
##  <Returns>
##  <K>true</K> if all checks succeed, otherwise <K>false</K>.
##  </Returns>
##  <Description>
##  <Ref Oper="ResultOfStraightLineDecision"/> evaluates the straight line
##  decision (see&nbsp;<Ref Func="IsStraightLineDecision"/>) <A>prog</A>
##  at the group elements in the list <A>gens</A>.
##  <P/>
##  The function for computing the order of a group element can be given as
##  the optional argument <A>orderfunc</A>.
##  For example, this may be a function that gives up at a certain limit
##  if one has to be aware of extremely huge orders in failure cases.
##  <P/>
##  The <E>result</E> of a straight line decision with lines
##  <M>p_1, p_2, \ldots, p_k</M>
##  when applied to <A>gens</A> is defined as follows.
##  <P/>
##  <List>
##  <Mark>(a)</Mark>
##  <Item>
##      First a list <M>r</M> of intermediate values is initialized
##      with a shallow copy of <A>gens</A>.
##  </Item>
##  <Mark>(b)</Mark>
##  <Item>
##      For <M>i \leq k</M>, before the <M>i</M>-th step,
##      let <M>r</M> be of length <M>n</M>.
##      If <M>p_i</M> is the external representation of an associative word
##      in the first <M>n</M> generators then the image of this word
##      under the homomorphism that is given by mapping <M>r</M>
##      to these first <M>n</M> generators is added to <M>r</M>.
##      If <M>p_i</M> is a pair <M>[ l, j ]</M>, for a list <M>l</M>,
##      then the same element is computed,
##      but instead of being added to <M>r</M>,
##      it replaces the <M>j</M>-th entry of <M>r</M>.
##      If <M>p_i</M> is a triple <M>[ </M><C>"Order"</C><M>, i, n ]</M>
##      then it is checked whether the order of <M>r[i]</M> is <M>n</M>;
##      if not then <K>false</K> is returned immediately.
##  </Item>
##  <Mark>(c)</Mark>
##  <Item>
##      If all <M>k</M> lines have been processed and no order check
##      has failed then <K>true</K> is returned.
##  </Item>
##  </List>
##  <P/>
##  Here are some examples.
##  <P/>
##  <Example><![CDATA[
##  gap> dec:= StraightLineDecision( [ ], 1 );
##  <straight line decision>
##  gap> ResultOfStraightLineDecision( dec, [ () ] );
##  true
##  ]]></Example>
##  <P/>
##  The above straight line decision <C>dec</C> returns <K>true</K>
##  &ndash;for <E>any</E> input of the right length.
##  <P/>
##  <Example><![CDATA[
##  gap> dec:= StraightLineDecision( [ [ [ 1, 1, 2, 1 ], 3 ],
##  >       [ "Order", 1, 2 ], [ "Order", 2, 3 ], [ "Order", 3, 5 ] ] );
##  <straight line decision>
##  gap> LinesOfStraightLineDecision( dec );
##  [ [ [ 1, 1, 2, 1 ], 3 ], [ "Order", 1, 2 ], [ "Order", 2, 3 ], 
##    [ "Order", 3, 5 ] ]
##  gap> ResultOfStraightLineDecision( dec, [ (), () ] );
##  false
##  gap> ResultOfStraightLineDecision( dec, [ (1,2)(3,4), (1,4,5) ] );
##  true
##  ]]></Example>
##  <P/>
##  The above straight line decision admits two inputs;
##  it tests whether the orders of the inputs are <M>2</M> and <M>3</M>,
##  and the order of their product is <M>5</M>.
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareOperation( "ResultOfStraightLineDecision",
    [ IsStraightLineDecision, IsHomogeneousList ] );

DeclareOperation( "ResultOfStraightLineDecision",
    [ IsStraightLineDecision, IsHomogeneousList, IsFunction ] );


#############################################################################
##
##  <#GAPDoc Label="Semi-Presentations">
##  <Subsection Label="Semi-Presentations and Presentations">
##  <Heading>Semi-Presentations and Presentations</Heading>
##
##  <Index>semi-presentation</Index>
##  We can associate a <E>finitely presented group</E> <M>F / R</M>
##  to each straight line decision <A>dec</A>, say, as follows.
##  The free generators of the free group <M>F</M> are in bijection
##  with the inputs, and the defining relators generating <M>R</M> as a
##  normal subgroup of <M>F</M> are given by those words <M>w^k</M>
##  for which <A>dec</A> contains a check whether the order of <M>w</M>
##  equals <M>k</M>.
##  <P/>
##  So if <A>dec</A> returns <K>true</K> for the input list
##  <M>[ g_1, g_2, \ldots, g_n ]</M> then mapping the free generators of
##  <M>F</M> to the inputs defines an epimorphism <M>\Phi</M> from <M>F</M>
##  to the group <M>G</M>, say, that is generated by these inputs,
##  such that <M>R</M> is contained in the kernel of <M>\Phi</M>.
##  <P/>
##  (Note that <Q>satisfying <A>dec</A></Q> is a stronger property than
##  <Q>satisfying a presentation</Q>.<Index>presentation</Index>
##  For example, <M>\langle x \mid x^2 = x^3 = 1 \rangle</M>
##  is a presentation for the trivial group, but the straight line decision
##  that checks whether the order of <M>x</M> is both <M>2</M> and <M>3</M>
##  clearly always returns <K>false</K>.)
##  <P/>
##  The &ATLAS; of Group Representations contains the following two kinds of
##  straight line decisions.
##  <P/>
##  <List>
##  <Item>
##    A <E>presentation</E> is a straight line decision <A>dec</A>
##    that is defined for a set of standard generators of a group <M>G</M>
##    and that returns <K>true</K> if and only if the list of inputs is
##    in fact a sequence of such standard generators for <M>G</M>.
##    In other words, the relators derived from the order checks in the way
##    described above are defining relators for <M>G</M>,
##    and moreover these relators are words in terms of standard generators.
##    (In particular the kernel of the map <M>\Phi</M> equals <M>R</M>
##    whenever <A>dec</A> returns <K>true</K>.)
##  </Item>
##  <Item>
##    A <E>semi-presentation</E> is a straight line decision <A>dec</A>
##    that is defined for a set of standard generators of a group <M>G</M>
##    and that returns <K>true</K> for a list of inputs <E>that is known to
##    generate a group isomorphic with <M>G</M></E> if and only if
##    these inputs form in fact a sequence of standard generators for
##    <M>G</M>.
##    In other words, the relators derived from the order checks in the way
##    described above are <E>not necessarily defining relators</E>
##    for <M>G</M>, but if we assume that the <M>g_i</M> generate <M>G</M>
##    then they are standard generators.
##    (In particular, <M>F / R</M> may be a larger group than <M>G</M>
##    but in this case <M>\Phi</M> maps the free generators of <M>F</M>
##    to standard generators of <M>G</M>.)
##    <P/>
##    More about semi-presentations can be found in <Cite Key="NW05"/>.
##  </Item>
##  </List>
##  <P/>
##  Available presentations and semi-presentations are listed by
##  <Ref Func="DisplayAtlasInfo"/>,
##  they can be accessed via <Ref Func="AtlasProgram"/>.
##  (Clearly each presentation is also a semi-presentation.
##  So a semi-presentation for some standard generators of a group is
##  regarded as available whenever a presentation for these standard
##  generators and this group is available.)
##  <P/>
##  Note that different groups can have the same semi-presentation.
##  We illustrate this with an example that is mentioned in
##  <Cite Key="NW05"/>.
##  The groups <M>L_2(7) \cong L_3(2)</M> and <M>L_2(8)</M> are generated by
##  elements of the orders <M>2</M> and <M>3</M> such that their product has
##  order <M>7</M>, and no further conditions are necessary to define
##  standard generators.
##  <P/>
##  <Example><![CDATA[
##  gap> check:= AtlasProgram( "L2(8)", "check" );
##  rec( groupname := "L2(8)", 
##    identifier := [ "L2(8)", "L28G1-check1", 1, 1 ], 
##    program := <straight line decision>, standardization := 1 )
##  gap> gens:= AtlasGenerators( "L2(8)", 1 );
##  rec( charactername := "1a+8a", 
##    generators := [ (1,2)(3,4)(6,7)(8,9), (1,3,2)(4,5,6)(7,8,9) ], 
##    groupname := "L2(8)", id := "", 
##    identifier := [ "L2(8)", [ "L28G1-p9B0.m1", "L28G1-p9B0.m2" ], 1, 9 
##       ], isPrimitive := true, maxnr := 1, p := 9, rankAction := 2, 
##    repname := "L28G1-p9B0", repnr := 1, size := 504, 
##    stabilizer := "2^3:7", standardization := 1, transitivity := 3, 
##    type := "perm" )
##  gap> ResultOfStraightLineDecision( check.program, gens.generators );
##  true
##  gap> gens:= AtlasGenerators( "L3(2)", 1 );
##  rec( generators := [ (2,4)(3,5), (1,2,3)(5,6,7) ], 
##    groupname := "L3(2)", id := "a", 
##    identifier := [ "L3(2)", [ "L27G1-p7aB0.m1", "L27G1-p7aB0.m2" ], 1, 
##        7 ], isPrimitive := true, maxnr := 1, p := 7, rankAction := 2, 
##    repname := "L27G1-p7aB0", repnr := 1, size := 168, 
##    stabilizer := "S4", standardization := 1, transitivity := 2, 
##    type := "perm" )
##  gap> ResultOfStraightLineDecision( check.program, gens.generators );
##  true
##  ]]></Example>
##  </Subsection>
##  <#/GAPDoc>
##


#############################################################################
##
#O  StraightLineProgramFromStraightLineDecision( <dec> )
##
##  <#GAPDoc Label="StraightLineProgramFromStraightLineDecision">
##  <ManSection>
##  <Oper Name="StraightLineProgramFromStraightLineDecision" Arg='dec'/>
##
##  <Returns>
##  the straight line program associated to the given straight line decision.
##  </Returns>
##  <Description>
##  For a straight line decision <A>dec</A>
##  (see <Ref Func="IsStraightLineDecision"/>,
##  <Ref Oper="StraightLineProgramFromStraightLineDecision"/> returns the
##  straight line program
##  (see <Ref Func="IsStraightLineProgram" BookName="ref"/> obtained by
##  replacing each line of type 3. (i.e, each order check) by an
##  assignment of the power in question to a new slot,
##  and by declaring the list of these elements as the return value.
##  <P/>
##  This means that the return value describes exactly the defining relators
##  of the presentation that is associated to the straight line decision,
##  see <Ref Subsect="Semi-Presentations and Presentations"/>.
##  <P/>
##  For example, one can use the return value for printing the relators with
##  <Ref Func="StringOfResultOfStraightLineProgram" BookName="ref"/>,
##  or for explicitly constructing the relators as words in terms of free
##  generators,
##  by applying <Ref Func="ResultOfStraightLineProgram" BookName="ref"/>
##  to the program and to these generators.
##  <P/>
##  <Example><![CDATA[
##  gap> dec:= StraightLineDecision( [ [ [ 1, 1, 2, 1 ], 3 ],
##  > [ "Order", 1, 2 ], [ "Order", 2, 3 ], [ "Order", 3, 5 ] ] );
##  <straight line decision>
##  gap> prog:= StraightLineProgramFromStraightLineDecision( dec );
##  <straight line program>
##  gap> Display( prog );
##  # input:
##  r:= [ g1, g2 ];
##  # program:
##  r[3]:= r[1]*r[2];
##  r[4]:= r[1]^2;
##  r[5]:= r[2]^3;
##  r[6]:= r[3]^5;
##  # return values:
##  [ r[4], r[5], r[6] ]
##  gap> StringOfResultOfStraightLineProgram( prog, [ "a", "b" ] );
##  "[ a^2, b^3, (ab)^5 ]"
##  gap> gens:= GeneratorsOfGroup( FreeGroup( "a", "b" ) );
##  [ a, b ]
##  gap> ResultOfStraightLineProgram( prog, gens );
##  [ a^2, b^3, (a*b)^5 ]
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareOperation( "StraightLineProgramFromStraightLineDecision",
    [ IsStraightLineDecision ] );


#############################################################################
##
#A  AsBBoxProgram( <slp> )
#A  AsBBoxProgram( <dec> )
##
##  <#GAPDoc Label="AsBBoxProgram">
##  <ManSection>
##  <Attr Name="AsBBoxProgram" Arg='slp'/>
##
##  <Returns>
##  an equivalent black box program for the given straight line program
##  or straight line decision.
##  </Returns>
##  <Description>
##  Let <A>slp</A> be a straight line program
##  (see <Ref Func="IsStraightLineProgram" BookName="ref"/>)
##  or a straight line decision (see <Ref Func="IsStraightLineDecision"/>).
##  Then <Ref Attr="AsBBoxProgram"/> returns a black box program <A>bbox</A>
##  (see <Ref Func="IsBBoxProgram"/>) with the <Q>same</Q> output as
##  <A>slp</A>,
##  in the sense that <Ref Func="ResultOfBBoxProgram"/> yields the same
##  result for <A>bbox</A>
##  as <Ref Func="ResultOfStraightLineProgram" BookName="ref"/> or
##  <Ref Func="ResultOfStraightLineDecision"/>, respectively, for <A>slp</A>.
##  <P/>
##  <Example><![CDATA[
##  gap> f:= FreeGroup( "x", "y" );;  gens:= GeneratorsOfGroup( f );;
##  gap> slp:= StraightLineProgram( [ [1,2,2,3], [3,-1] ], 2 );
##  <straight line program>
##  gap> ResultOfStraightLineProgram( slp, gens );
##  y^-3*x^-2
##  gap> bboxslp:= AsBBoxProgram( slp );
##  <black box program>
##  gap> ResultOfBBoxProgram( bboxslp, gens );
##  [ y^-3*x^-2 ]
##  gap> lines:= [ [ "Order", 1, 2 ], [ "Order", 2, 3 ],
##  >              [ [ 1, 1, 2, 1 ], 3 ], [ "Order", 3, 5 ] ];;
##  gap> dec:= StraightLineDecision( lines, 2 );
##  <straight line decision>
##  gap> ResultOfStraightLineDecision( dec, [ (1,2)(3,4), (1,3,5) ] );
##  true
##  gap> ResultOfStraightLineDecision( dec, [ (1,2)(3,4), (1,3,4) ] );
##  false
##  gap> bboxdec:= AsBBoxProgram( dec );
##  <black box program>
##  gap> ResultOfBBoxProgram( bboxdec, [ (1,2)(3,4), (1,3,5) ] );
##  true
##  gap> ResultOfBBoxProgram( bboxdec, [ (1,2)(3,4), (1,3,4) ] );
##  false
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareAttribute( "AsBBoxProgram", IsStraightLineProgram );

DeclareAttribute( "AsBBoxProgram", IsStraightLineDecision );


#############################################################################
##
#A  AsStraightLineProgram( <bbox> )
##
##  <#GAPDoc Label="AsStraightLineProgram">
##  <ManSection>
##  <Attr Name="AsStraightLineProgram" Arg='bbox'/>
##
##  <Returns>
##  an equivalent straight line program for the given black box program,
##  or <K>fail</K>.
##  </Returns>
##  <Description>
##  For a black box program (see <Ref Attr="AsBBoxProgram"/>) <A>bbox</A>,
##  <Ref Func="AsStraightLineProgram"/> returns a straight line program
##  (see <Ref Func="IsStraightLineProgram" BookName="ref"/>) with the same
##  output as <A>bbox</A> if such a straight line program exists,
##  and <K>fail</K> otherwise.
##  <P/>
##  <Example><![CDATA[
##  gap> Display( AsStraightLineProgram( bboxslp ) );
##  # input:
##  r:= [ g1, g2 ];
##  # program:
##  r[3]:= r[1]^2;
##  r[4]:= r[2]^3;
##  r[5]:= r[3]*r[4];
##  r[3]:= r[5]^-1;
##  # return values:
##  [ r[3] ]
##  gap> AsStraightLineProgram( bboxdec );
##  fail
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareAttribute( "AsStraightLineProgram", IsBBoxProgram );


#############################################################################
##
#A  AsStraightLineDecision( <bbox> )
##
##  <#GAPDoc Label="AsStraightLineDecision">
##  <ManSection>
##  <Attr Name="AsStraightLineDecision" Arg='bbox'/>
##
##  <Returns>
##  an equivalent straight line decision for the given black box program,
##  or <K>fail</K>.
##  </Returns>
##  <Description>
##  For a black box program (see <Ref Func="IsBBoxProgram"/>) <A>bbox</A>,
##  <Ref Func="AsStraightLineDecision"/> returns a straight line decision
##  (see <Ref Func="IsStraightLineDecision"/>) with the same
##  output as <A>bbox</A>, in the sense of <Ref Attr="AsBBoxProgram"/>,
##  if such a straight line decision exists,
##  and <K>fail</K> otherwise.
##  <P/>
##  <Example><![CDATA[
##  gap> lines:= [ [ "Order", 1, 2 ], [ "Order", 2, 3 ],
##  >              [ [ 1, 1, 2, 1 ], 3 ], [ "Order", 3, 5 ] ];;
##  gap> dec:= StraightLineDecision( lines, 2 );
##  <straight line decision>
##  gap> bboxdec:= AsBBoxProgram( dec );
##  <black box program>
##  gap> asdec:= AsStraightLineDecision( bboxdec );
##  <straight line decision>
##  gap> LinesOfStraightLineDecision( asdec );
##  [ [ "Order", 1, 2 ], [ "Order", 2, 3 ], [ [ 1, 1, 2, 1 ], 3 ], 
##    [ "Order", 3, 5 ] ]
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareAttribute( "AsStraightLineDecision", IsBBoxProgram );


#############################################################################
##
#E