File: domain.tex

package info (click to toggle)
gap 4r4p12-2
  • links: PTS
  • area: main
  • in suites: squeeze, wheezy
  • size: 29,584 kB
  • ctags: 7,113
  • sloc: ansic: 98,786; sh: 3,299; perl: 2,263; makefile: 498; asm: 63; awk: 6
file content (1440 lines) | stat: -rw-r--r-- 57,387 bytes parent folder | download | duplicates (3)
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
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
% This file was created automatically from domain.msk.
% DO NOT EDIT!
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%A  domain.msk                   GAP documentation              Thomas Breuer
%%
%A  @(#)$Id: domain.msk,v 1.29 2002/04/15 10:02:28 sal Exp $
%%
%Y  (C) 1998 School Math and Comp. Sci., University of St.  Andrews, Scotland
%Y  Copyright (C) 2002 The GAP Group
%%
\Chapter{Domains and their Elements}

*Domain* is {\GAP}'s name for structured sets.
The ring of Gaussian integers $Z[i]$ is an example of a domain,
the group $D_{12}$ of symmetries of a regular hexahedron is another.

The {\GAP} library predefines some domains.
For example the ring of Gaussian integers is predefined as
`GaussianIntegers' (see~"Gaussians") and the field of rationals
is predefined as `Rationals' (see~"Rational Numbers").
Most domains are constructed by functions,
which are called *domain constructors* (see~"Constructing Domains").
For example the group $D_{12}$ is constructed by the construction
`Group( (1,2,3,4,5,6), (2,6)(3,5) )' (see~"Group")
and the finite field with 16 elements is constructed by
`GaloisField( 16 )' (see~"GaloisField").

The first place where you need domains in {\GAP} is the obvious one.
Sometimes you simply want to deal with a domain.
For example if you want to compute the size of the group $D_{12}$,
you had better be able to represent this group in a way that the
`Size' function can understand.

The second place where you need domains in {\GAP} is when you want to
be able to specify that an operation or computation takes place in a
certain domain.
For example suppose you want to factor 10 in the ring of Gaussian
integers.
Saying `Factors( 10 )' will not do, because this will return the
factorization `[ 2, 5 ]' in the ring of integers.
To allow operations and computations to happen in a specific domain,
`Factors', and many other functions as well, accept this domain as
optional first argument.
Thus `Factors( GaussianIntegers, 10 )' yields the desired result
`[ 1+E(4), 1-E(4), 2+E(4), 2-E(4) ]'.
(The imaginary unit $\exp( 2 \pi i/4 )$ is written as `E(4)' in {\GAP}.)



The most important facts about domains are stated in Chapter~"tut:Domains"
of the {\GAP} Tutorial.

There are only few *operations* especially for domains
(see~"Operations for Domains"),
operations such as `Intersection' and `Random' are defined for the more
general situation of collections (see Chapter~"Collections").

%%  The fundamental suport for domains in {\GAP} was designed and implemented by
%%  Thomas Breuer.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Section{Operational Structure of Domains}

Domains have an *operational structure*,
that is, a collection of operations under which the domain is closed.
For example, a group is closed under multiplication,
taking the zeroth power of elements, and taking inverses of elements.
The operational structure may be empty,
examples of domains without additional structure are
the underlying relations of general mappings
(see~"Properties and Attributes of (General) Mappings").

The operations under which a domain is closed are a subset of
the operations that the elements of a domain admit.
It is possible that the elements admit more operations.
For example, matrices can be multiplied and added.
But addition plays no role in a group of matrices,
and multiplication plays no role in a vector space of matrices.
In particular, a matrix group is not closed under addition.

Note that the elements of a domain exist independently of this domain,
usually they existed already before the domain was created.
So it makes sense to say that a domain is *generated* by some elements
with respect to certain operations.

Of course, different sets of operations yield different notions of
generation.
For example, the group generated by some matrices is different from
the ring generated by these matrices, and these two will in general be
different from the vector space generated by the same matrices,
over a suitable field.

The other way round,
the same set of elements may be obtained by generation w.r.t.~different
notions of generation.
For example, one can get the group generated by two elements $g$ and $h$
also as the monoid generated by the elements $g$, $g^{-1}$, $h$, $h^{-1}$;
if both $g$ and $h$ have finite order then of course the group generated
by $g$ and $h$ coincides with the monoid generated by $g$ and $h$.

Additionally to the operational structure,
a domain can have properties.
For example, the multiplication of a group is associative,
and the multiplication in a field is commutative.

Note that associativity and commutativity depend on the set of
elements for which one considers the multiplication,
i.e., it depends on the domain.
For example, the multiplication in a full matrix ring over a field
is not commutative, whereas its restriction to the set of diagonal
matrices is commutative.

One important difference between the operational structure and the
properties of a domain is that the operational structure is fixed when
the domain is constructed, whereas properties can be discovered later.
For example, take a domain whose operational structure is given by
closure under multiplication.
If it is discovered that the inverses of all its elements
also do (by chance) lie in this domain,
being closed under taking inverses is *not* added to the operational
structure.
But a domain with operational structure of multiplication,
taking the identity, and taking inverses
will be treated as a group as soon as the multiplication is found out to
be associative for this domain.

The operational structures available in {\GAP} form a hierarchy,
which is explicitly formulated in terms of domain categories,
see~"Domain Categories".


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Section{Equality and Comparison of Domains}

*Equality* and *comparison* of domains are defined as follows.

Two domains are considered *equal* if and only if the sets of their
elements as computed by `AsSSortedList' (see~"AsSSortedList") are equal.
Thus, in general `=' behaves as if each domain operand were replaced by
its set of elements.
Except that `=' will also sometimes, but not always,
work for infinite domains, for which of course {\GAP} cannot compute
the set of elements.
Note that this implies that domains with different algebraic structure
may well be equal.
As a special case of this, either operand of `=' may also be a proper set
(see~"Sorted Lists and Sets"),
i.e., a sorted list without holes or duplicates (see "AsSSortedList"),
and `=' will return `true' if and only if this proper set is equal to
the set of elements of the argument that is a domain.


*No* general *ordering* of arbitrary domains via `\<' is defined in
{\GAP}~4.
This is because a well-defined `\<' for domains or, more general, for
collections, would have to be compatible with `=' and would need to be
transitive and antisymmetric in order to be used to form ordered sets.
In particular, `\<' would have to be independent of the algebraic
structure of its arguments because this holds for `=',
and thus there would be hardly a situation where one could implement
an efficient comparison method.
(Note that in the case that two domains are comparable with `\<',
the result is in general *not* compatible with the set theoretical
subset relation, which can be decided with `IsSubset'.)




%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Section{Constructing Domains}

For several operational structures (see~"Operational Structure of Domains"),
{\GAP} provides functions to construct domains with this structure.
For example, `Group' returns groups, `VectorSpace' returns vector spaces etc.

\>`<Struct>( <arg1>, <arg2>, ... )'{Struct}@{\noexpand<Struct>} F

The syntax of these functions may vary, dependent on the structure in
question.
Usually a domain is constructed as the closure of some elements under the
given operations, that is, the domain is given by its *generators*.
For example, a group can be constructed from a list of generating
permutations or matrices or whatever is admissible as group elements,
and a vector space over a given field $F$ can be constructed from $F$ and
a list of appropriate vectors.

The idea of generation and generators in {\GAP} is that the domain
returned by a function such as `Group', `Algebra', or `FreeLeftModule'
*contains* the given generators.
This implies that the generators of a group must know how they are
multiplied and inverted,
the generators of a module must know how they are added and how scalar
multiplication works, and so on.
Thus one cannot use for example permutations as generators of a vector
space.

The function <Struct> first checks whether the arguments admit
the construction of a domain with the desired structure.
This is done by calling the operation

\>`IsGeneratorsOf<Struct>( [<info>, ]<gens>)'{IsGeneratorsOfStruct}%
@{`IsGeneratorsOf\noexpand<Struct>'} O

where <arglist> is the list of given generators and <info> an argument
of <Struct>, for example the field of scalars in the case that a
vector space shall be constructed.
If the check failed then <Struct> returns `fail',
otherwise it returns the result of `<Struct>ByGenerators' (see below).
(So if one wants to omit the check then one should call
`<Struct>ByGenerators' directly.)

\>`GeneratorsOf<Struct>( <D>)'{GeneratorsOfStruct}%
@{`GeneratorsOf\noexpand<Struct>'} A

For a domain <D> with operational structure corresponding to <Struct>,
the attribute `GeneratorsOf<Struct>' returns a list of corresponding
generators of <D>.
If these generators were not yet stored in <D> then <D> must know *some*
generators if `GeneratorsOf<Struct>' shall have a chance to compute the
desired result;
for example, monoid generators of a group can be computed from known
group generators (and vice versa).
Note that several notions of generation may be meaningful for a given
domain, so it makes no sense to ask for ``the generators of a domain''.
Further note that the generators may depend on other information about <D>.
For example the generators of a vector space depend on the underlying field
of scalars; the vector space generators of a vector space over the field
with four elements need not generate the same vector space when this is
viewed as a space over the field with two elements.

\>`<Struct>ByGenerators( [<info>, ]<gens> )'{StructByGenerators}%
@{`\noexpand<Struct>ByGenerators'} O

Domain construction from generators <gens> is implemented by operations
`<Struct>ByGenerators',
which are called by the simple functions <Struct>;
methods can be installed only for the operations.
Note that additional information <info> may be necessary
to construct the domain;
for example, a vector space needs the underlying field of scalars
in addition to the list of vector space generators.
The `GeneratorsOf<Struct>' value of the returned domain need *not*
be equal to <gens>.
But if a domain <D> is printed as `<Struct>([<a>, <b>, ...])' and if
there is an attribute `GeneratorsOf<Struct>' then the list
`GeneratorsOf<Struct>( <D> )' is guaranteed to be equal to
`[ <a>, <b>, ... ]'.

\>`<Struct>WithGenerators( [<info>, ]<gens> )'{StructWithGenerators}%
@{`\noexpand<Struct>WithGenerators'} O

The only difference between `<Struct>ByGenerators' and
`<Struct>WithGenerators' is that the latter guarantees that the
`GeneratorsOf<Struct>' value of the result is equal to the given
generators <gens>.

\>`Closure<Struct>( <D>, <obj> )'{ClosureStruct}@{`Closure\noexpand<Struct>'} O

For constructing a domain as the closure of a given domain with an
element or another domain, one can use the operation `Closure<Struct>'.
It returns the smallest domain with operational structure corresponding to
<Struct> that contains <D> as a subset and <obj> as an element.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Section{Changing the Structure}

The same set of elements can have different operational structures.
For example, it may happen that a monoid $M$ does in fact contain
the inverses of all of its elements;
if $M$ has not been constructed as a group (see~"Domain Categories")
then it is reasonable to ask for the group that is equal to $M$.

\>`As<Struct>( [<info>, ]<D> )'{AsStruct}@{`As\noexpand<Struct>'} O

If <D> is a domain that is closed under the operational structure
given by <Struct> then `As<Struct>' returns a domain <E> that consists
of the same elements (that is, `<D> = <E>') and that has this
operational structure (that is, `Is<Struct>( <E> )' is `true');
if <D> is not closed under the structure given by <Struct> then
`As<Struct>' returns `fail'.

If additional information besides generators are necessary to define <D>
then the argument <info> describes the value of this information for the
desired domain.
For example, if we want to view <D> as a vector space over the field
with two elements then we may call `AsVectorSpace( GF(2), <D> )';
this allows us to change the underlying field of scalars,
for example if <D> is a vector space over the field with four elements.
Again, if <D> is not equal to a domain with the desired structure and
additional information then `fail' is returned.

In the case that no additional information <info> is related to the
structure given by <Struct>,
the operation `As<Struct>' is in fact an attribute (see~"Attributes").

See the index of the {\GAP} Reference Manual for an overview of the available
`As<Struct>' functions.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Section{Changing the Representation}

Often it is useful to answer questions about a domain via computations in
a different but isomorphic domain.
In the sense that this approach keeps the structure and changes the
underlying set of elements, it can be viewed as a counterpart of keeping the
set of elements and changing its structure (see~"Changing the Structure").

One reason for doing so can be that computations with the elements in the
given domain are not very efficient.
For example, if one is given a solvable matrix group
(see Chapter~"Matrix Groups") then one can compute an isomorphism to a
polycyclicly presented group $G$, say (see Chapter~"Polycyclic Groups");
the multiplication of two matrices --which is essentially determined by
the dimension of the matrices-- is much more expensive than the
multiplication of two elements in $G$ --which is essentially determined by
the composition length of $G$.

\>`Isomorphism<Rep><Struct>( <D> )'{IsomorphismRepStruct}%
@{`Isomorphism\noexpand<Rep>\noexpand<Struct>'} A

If <D> is a domain that is closed under the operational structure
given by <Struct> then `Isomorphism<Rep><Struct>' returns a mapping <hom>
from <D> to a domain $E$ having structure given by <Struct>,
such that <hom> respects the structure <Struct>
and <Rep> describes the representation of the elements in $E$.
If no domain $E$ with the required properties exists then `fail' is
returned.

For example, `IsomorphismPermGroup' (see~"IsomorphismPermGroup") takes a
group as its argument and returns a group homomorphism
(see~"Group Homomorphisms") onto an isomorphic permutation group
(see Chapter~"Permutation Groups") provided the original
group is finite; for infinite groups, `IsomorphismPermGroup' returns `fail'.
Similarly, `IsomorphismPcGroup' (see~"IsomorphismPcGroup") returns a group
homomorphism from its argument to a polycyclicly presented group
(see~"Pc Groups") if the argument is polycyclic, and `fail' otherwise.

See the index of the {\GAP} Reference Manual for an overview of the available
`Isomorphism<Rep><Struct>' functions.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Section{Domain Categories}

As mentioned in~"Operational Structure of Domains",
the operational structure of a domain is fixed when the domain is
constructed.
For example, if <D> was constructed by `Monoid' then <D> is in general not
regarded as a group in {\GAP},
even if <D> is in fact closed under taking inverses.
In this case, `IsGroup' returns `false' for <D>.
The operational structure determines which operations are applicable for
a domain, so for example `SylowSubgroup' is not defined for <D>
and therefore will signal an error.

\>`Is<Struct>( <D> )'{IsStruct}@{`Is\noexpand<Struct>'}

The functions `Is<Struct>' implement the tests whether a domain <D> has the
respective operational structure (upon construction).
`Is<Struct>' is a filter (see~"Types of Objects") that involves certain
categories (see~"Categories")
and usually also certain properties (see~"Properties").
For example, `IsGroup' is equivalent to
`IsMagmaWithInverses and IsAssociative',
the first being a category and the second being a property.

Implications between domain categories describe the hierarchy of
operational structures available in {\GAP}.
Here are some typical examples.

\beginlist%unordered
\item{--}
    `IsDomain' is implied by each domain category,
\item{--}
    `IsMagma' is implied by each category that describes the closure under
    multiplication `\*',
\item{--}
    `IsAdditiveMagma' is implied by each category that describes the closure
    under addition `+',
\item{--}
    `IsMagmaWithOne' implies `IsMagma';
    a *magma-with-one* is a magma such that each element
    (and thus also the magma itself) can be asked for its zeroth power,
\item{--}
    `IsMagmaWithInverses' implies `IsMagmaWithOne';
    a *magma-with-inverses* is a magma such that each element
    can be asked for its inverse;
    important special cases are *groups*,
    which in addition are associative,
\item{--}
    a *ring* is a magma that is also an additive group,
\item{--}
    a *ring-with-one* is a ring that is also a magma-with-one,
\item{--}
    a *division ring* is a ring-with-one that is also closed under taking
    inverses of nonzero elements,
\item{--}
    a *field* is a commutative division ring.
\endlist

Each operational structure <Struct> has associated with it 
a domain category `Is<Struct>',
and operations `<Struct>ByGenerators' for constructing a domain from
generators,
`GeneratorsOf<Struct>' for storing and accessing generators w.r.t.~this
structure,
`Closure<Struct>' for forming the closure,
and `As<Struct>' for getting a domain with the desired structure from one
with weaker operational structure and for testing whether a given domain
can be regarded as a domain with <Struct>.

The functions applicable to domains with the various structures
are described in the corresponding chapters of the Reference Manual.
For example, functions for rings, fields, groups, and vector spaces
are described in Chapters~"Rings", "Fields and Division Rings",
"Groups", and "Vector Spaces", respectively.
More general functions for arbitrary collections can be found in
Chapter~"Collections".


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Section{Parents}

\>Parent( <D> ) F
\>SetParent( <D>, <P> ) O
\>HasParent( <D> ) F

It is possible to assign to a domain <D> one other domain <P> containing
<D> as a subset,
in order to exploit this subset relation between <D> and <P>.
Note that <P> need not have the same operational structure as <D>,
for example <P> may be a magma and <D> a field.

The assignment is done by calling `SetParent',
and <P> is called the *parent* of <D>.
If <D> has already a parent, calls to `SetParent' will be ignored.

If <D> has a parent <P> --this can be checked with `HasParent'--
then <P> can be used to gain information about <D>.
First, the call of `SetParent' causes `UseSubsetRelation'
(see~"UseSubsetRelation") to be called.
Second, for a domain <D> with parent, information relative to the parent
can be stored in <D>;
for example, there is an attribute `NormalizerInParent' for storing
`Normalizer( <P>, <D> )' in the case that <D> is a group.
(More about such parent dependent attributes can be found in
"ext:In Parent Attributes" in ``Extending GAP''.)
Note that because of this relative information,
one cannot change the parent;
that is, one can set the parent only once,
subsequent calls to `SetParent' for the same domain <D> are ignored.
Further note that contrary to `UseSubsetRelation'
(see~"UseSubsetRelation"),
also knowledge about the parent <P> might be used
that is discovered after the `SetParent' call.

A stored parent can be accessed using `Parent'.
If <D> has no parent then `Parent' returns <D> itself,
and `HasParent' will return `false' also after a call to `Parent'.
So `Parent' is *not* an attribute,
the underlying attribute to store the parent is `ParentAttr'.

Certain functions that return domains with parent already set,
for example `Subgroup',
are described in Section~"Constructing Subdomains".
Whenever a function has this property,
the Reference Manual states this explicitly.
Note that these functions *do not guarantee* a certain parent,
for example `DerivedSubgroup' (see~"DerivedSubgroup") for a perfect
group $G$ may return $G$ itself, and if $G$ had already a parent
then this is not replaced by $G$.
As a rule of thumb, {\GAP} avoids to set a domain as its own parent,
which is consistent with the behaviour of `Parent',
at least until a parent is set explicitly with `SetParent'.


\beginexample
gap> g:= Group( (1,2,3), (1,2) );; h:= Group( (1,2) );;
gap> HasParent( g );  HasParent( h );
false
false
gap> SetParent( h, g );
gap> Parent( g );  Parent( h );
Group([ (1,2,3), (1,2) ])
Group([ (1,2,3), (1,2) ])
gap> HasParent( g );  HasParent( h );
false
true
\endexample


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Section{Constructing Subdomains}

\index{Subdomains}

For many domains <D>, there are functions that construct certain subsets <S>
of <D> as domains with parent (see~"Parents") already set to <D>.
For example, if <G> is a group that contains the elements in the list <gens>
then `Subgroup( <G>, <gens> )' returns a group <S> that is generated by the
elements in <gens> and with `Parent( <S> ) = <G>'.

\>`Sub<struct>( <D>, <gens> )'{Substruct}@{`Sub\noexpand<struct>'} F

More general, if <D> is a domain whose algebraic structure is given by the
function <Struct> (for example `Group', `Algebra', `Field')
then the function `Sub<struct>' (for example `Subgroup', `Subalgebra',
`Subfield') returns domains with structure <Struct> and parent set to
the first argument.

\>`Sub<struct>NC( <D>, <gens> )'{SubstructNC}@{`Sub\noexpand<struct>NC'} F

Each function `Sub<struct>' checks that the <Struct> generated by
<gens> is in fact a subset of <D>.
If one wants to omit this check then one can call `Sub<struct>NC' instead;
the suffix `NC' stands for ``no  check''.

\>`AsSub<struct>( <D>, <S> )'{AsSubstruct}@{`AsSub\noexpand<struct>'} F

first constructs `As<struct>( [<info>, ]<S> )',
where <info> depends on <D> and <S>,
and then sets the parent (see~"Parents") of this new domain to <D>.

\>`IsSub<struct>( <D>, <S> )'{IsSubstruct}@{`IsSub\noexpand<struct>'} F

There is no real need for functions that check whether a domain <S> is a
`Sub<struct>' of a domain <D>,
since this is equivalent to the checks whether <S> is a <Struct> and <S>
is a subset of <D>.
Note that in many cases, only the subset relation is what one really wants
to check, and that appropriate methods for the operation `IsSubset'
(see~"IsSubset") are available for many special situations,
such as the test whether a group is contained in another group,
where only generators need to be checked.

If a function `IsSub<struct>' is available in {\GAP} then it is implemented
as first a call to `Is<Struct>' for the second argument and then a call to
`IsSubset' for the two arguments.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Section{Operations for Domains}

For the meaning of the attributes `Characteristic', `One', `Zero'
in the case of a domain argument,
see~"Attributes and Properties of Elements".


\>IsGeneralizedDomain( <D> ) C
\>IsDomain( <D> ) C

For some purposes, it is useful to deal with objects that are similar to
domains but that are not collections in the sense of {\GAP}
because their elements may lie in different families;
such objects are called *generalized domains*.
An instance of generalized domains are ``operation domains'',
for example any $G$-set for a permutation group $G$
consisting of some union of points, sets of points, sets of sets of
points etc., under a suitable action.

`IsDomain' is a synonym for `IsGeneralizedDomain and IsCollection'.


\>GeneratorsOfDomain( <D> ) A

For a domain <D>, `GeneratorsOfDomain' returns a list containing all
elements of <D>, perhaps with repetitions.
Note that if the domain <D> shall be generated by a list of some elements
w.r.t.~the empty operational structure
(see~"Operational Structure of Domains"),
the only possible choice of elements is to take all elements of <D>.
See~"Constructing Domains" and "Changing the Structure" for the concepts
of other notions of generation.



\>Domain( [<Fam>, ]<generators> ) F
\>DomainByGenerators( <Fam>, <generators> ) O

`Domain' returns the domain consisting of the elements
in the homogeneous list <generators>.
If <generators> is empty then a family <Fam> must be entered as first
argument, and the returned (empty) domain lies in the collections
family of <Fam>.

`DomainByGenerators' is the operation called by `Domain'.




%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Section{Attributes and Properties of Elements}

The following attributes and properties for elements and domains
correspond to the operational structure.

\>Characteristic( <obj> ) A

`Characteristic' returns the *characteristic* of <obj>,
where <obj> must either be an additive element, a domain or a family.

For a domain <D>, the characteristic is defined if <D> is closed under
addition and has a zero element `<z> = Zero( <D> )' (see~"Zero");
in this case, `Characteristic( <D> )' is the smallest positive integer
<p> such that `<p> * <x> = <z>' for all elements <x> in <D>,
if such an integer exists, and the integer zero `0' otherwise.

If a family has a characteristic then this means
that all domains of elements in this family have this characteristic.
In this case, also each element in the family has this characteristic.
(Note that also the zero element $z$ of a finite field in characteristic
$p$ has characteristic $p$, although $n \* z = z$ for any integer $n$.)



\>OneImmutable( <obj> ) A
\>OneAttr( <obj> ) AM
\>One( <obj> ) AM
\>Identity( <obj> ) AM
\>OneMutable( <obj> ) O
\>OneOp( <obj> ) O
\>OneSameMutability( <obj> ) O
\>OneSM( <obj> ) O

`OneImmutable', `OneMutable', and `OneSameMutability' return the
multiplicative neutral element of the multiplicative element <obj>.

They differ only w.r.t. the mutability of the result.
`OneImmutable' is an attribute and hence returns an immutable result.
`OneMutable' is guaranteed to return a new *mutable* object whenever
a mutable version of the required element exists in {\GAP}
(see~"IsCopyable").
`OneSameMutability' returns a result that is mutable if <obj> is mutable
and if a mutable version of the required element exists in {\GAP};
for lists, it returns a result of the same immutability level as
the argument. For instance, if the argument is a mutable matrix
with immutable rows, it returns a similar object.

If <obj> is a multiplicative element then `OneSameMutability( <obj> )'
is equivalent to `<obj>^0'.

`OneAttr', `One' and `Identity' are synonyms of `OneImmutable'.
`OneSM' is a synonym of `OneSameMutability'.
`OneOp' is a synonym of `OneMutable'.

If <obj> is a domain or a family then `One' is defined as the identity
element of all elements in <obj>, 
provided that all these elements have the same identity.
For example, the family of all cyclotomics has the identity element `1',
but a collections family (see~"CollectionsFamily") may contain
matrices of all dimensions and then it cannot have a unique identity
element.
Note that `One' is applicable to a domain only if it is a
magma-with-one (see~"IsMagmaWithOne");
use `MultiplicativeNeutralElement' (see~"MultiplicativeNeutralElement")
otherwise.

The identity of an object need not be distinct from its zero,
so for example a ring consisting of a single element can be regarded as a
ring-with-one (see~"Rings").
This is particularly useful in the case of finitely presented algebras,
where any factor of a free algebra-with-one is again an algebra-with-one,
no matter whether or not it is a zero algebra.

The default method of `One' for multiplicative elements calls
`OneMutable' (note that methods for `OneMutable' must *not* delegate to
`One');
so other methods to compute identity elements need to be installed only
for `OneOp' and (in the case of copyable objects) `OneSameMutability'.

For domains, `One' may call `Representative' (see~"Representative"),
but `Representative' is allowed to fetch the identity of a domain <D>
only if `HasOne( <D> )' is `true'.


\>ZeroImmutable( <obj> ) A
\>ZeroAttr( <obj> ) AM
\>Zero( <obj> ) AM
\>ZeroMutable( <obj> ) O
\>ZeroOp( <obj> ) O
\>ZeroSameMutability( <obj> ) O
\>ZeroSM( <obj> ) O

`ZeroImmutable', `ZeroMutable', and `ZeroSameMutability' all
return the additive neutral element of the additive element <obj>.

They differ only w.r.t. the mutability of the result.
`ZeroImmutable' is an attribute and hence returns an immutable result.
`ZeroMutable' is guaranteed to return a new *mutable* object whenever
a mutable version of the required element exists in {\GAP}
(see~"IsCopyable").
`ZeroSameMutability' returns a result that is mutable if <obj> is mutable
and if a mutable version of the required element exists in {\GAP};
for lists, it returns a result of the same immutability level as
the argument. For instance, if the argument is a mutable matrix
with immutable rows, it returns a similar object.

`ZeroSameMutability( <obj> )' is equivalent to `0 \* <obj>'.

`ZeroAttr' and `Zero' are synonyms of `ZeroImmutable'.
`ZeroSM' is a synonym of `ZeroSameMutability'.
`ZeroOp' is a synonym of `ZeroMutable'.

If <obj> is a domain or a family then `Zero' is defined as the zero
element of all elements in <obj>,
provided that all these elements have the same zero.
For example, the family of all cyclotomics has the zero element `0',
but a collections family (see~"CollectionsFamily") may contain
matrices of all dimensions and then it cannot have a unique zero element.
Note that `Zero' is applicable to a domain only if it is an
additive magma-with-zero (see~"IsAdditiveMagmaWithZero");
use `AdditiveNeutralElement' (see~"AdditiveNeutralElement") otherwise.

The default method of `Zero' for additive elements calls `ZeroMutable'
(note that methods for `ZeroMutable' must *not* delegate to `Zero');
so other methods to compute zero elements need to be installed only for
`ZeroMutable' and (in the case of copyable objects) `ZeroSameMutability'.

For domains, `Zero' may call `Representative' (see~"Representative"),
but `Representative' is allowed to fetch the zero of a domain <D>
only if `HasZero( <D> )' is `true'.


\>MultiplicativeZeroOp( <elt> ) O

returns the element $z$ in the family <F> of <elt> with the 
property that $z * m = z = m * z$ holds for all $m \in F$,
if such an element is known.

Families of elements in the category IsMultiplicativeElementWithZero
often arise from adjoining a new zero to an existing magma. 
See~"InjectionZeroMagma" for details.




\>IsOne( <elm> ) P

is `true' if `<elm> = One( <elm> )', and `false' otherwise.


\>IsZero( <elm> ) P

is `true' if `<elm> = Zero( <elm> )', and `false' otherwise.


\>IsIdempotent( <elt> ) P

true iff <elt> is its own square. 
(Even if IsZero(<elt>) is also true.)



\>InverseImmutable( <elm> ) A
\>InverseAttr( <elm> ) AM
\>Inverse( <elm> ) AM
\>InverseMutable( <elm> ) O
\>InverseOp( <elm> ) O
\>InverseSameMutability( <elm> ) O
\>InverseSM( <elm> ) O

`InverseImmutable', `InverseMutable', and `InverseSameMutability'
all return the multiplicative inverse of an element <elm>,
that is, an element <inv> such that
`<elm> * <inv> = <inv> * <elm> = One( <elm> )' holds;
if <elm> is not invertible then `fail' (see~"Fail") is returned.

Note that the above definition implies that a (general) mapping
is invertible in the sense of `Inverse' only if its source equals its
range (see~"Technical Matters Concerning General Mappings").
For a bijective mapping $f$ whose source and range differ,
`InverseGeneralMapping' (see~"InverseGeneralMapping") can be used
to construct a mapping $g$ with the property
that $f `*' g$ is the identity mapping on the source of $f$
and $g `*' f$ is the identity mapping on the range of $f$.

The operations differ only w.r.t. the mutability of the result.
`InverseImmutable' is an attribute and hence returns an immutable result.
`InverseMutable' is guaranteed to return a new *mutable* object whenever
a mutable version of the required element exists in {\GAP}.
`InverseSameMutability' returns a result that is mutable if <elm> is
mutable and if a mutable version of the required element exists in
{\GAP}; for lists, it returns a result of the same immutability level as
the argument. For instance, if the argument is a mutable matrix
with immutable rows, it returns a similar object.

`InverseSameMutability( <elm> )' is equivalent to `<elm>^-1'.

`InverseAttr' and `Inverse' are synonyms of `InverseImmutable'.
`InverseSM' is a synonym of `InverseSameMutability'.
`InverseOp' is a synonym of `InverseMutable'.

The default method of `InverseImmutable' calls `InverseMutable' (note that methods
for `InverseMutable' must *not* delegate to `InverseImmutable');
other methods to compute inverses need to be installed only for
`InverseMutable' and (in the case of copyable objects)
`InverseSameMutability'.


\>AdditiveInverseImmutable( <elm> ) A
\>AdditiveInverseAttr( <elm> ) AM
\>AdditiveInverse( <elm> ) AM
\>AdditiveInverseMutable( <elm> ) O
\>AdditiveInverseOp( <elm> ) O
\>AdditiveInverseSameMutability( <elm> ) O
\>AdditiveInverseSM( <elm> ) O

`AdditiveInverseImmutable', `AdditiveInverseMutable', and 
`AdditiveInverseSameMutability' all return the
additive inverse of <elm>.

They differ only w.r.t. the mutability of the result.
`AdditiveInverseImmutable' is an attribute and hence returns an
immutable result.  `AdditiveInverseMutable' is guaranteed to
return a new *mutable* object whenever a mutable version of the
required element exists in {\GAP} (see~"IsCopyable").
`AdditiveInverseSameMutability' returns a result that is mutable
if <elm> is mutable and if a mutable version of the required
element exists in {\GAP};
for lists, it returns a result of the same immutability level as
the argument. For instance, if the argument is a mutable matrix
with immutable rows, it returns a similar object.

`AdditiveInverseSameMutability( <elm> )' is equivalent to `-<elm>'.

`AdditiveInverseAttr' and `AdditiveInverse' are synonyms of `AdditiveInverseImmutable'.
`AdditiveInverseSM' is a synonym of `AdditiveInverseSameMutability'.
`AdditiveInverseOp' is a synonym of `AdditiveInverseMutable'.

The default method of `AdditiveInverse' calls `AdditiveInverseMutable'
(note that methods for `AdditiveInverseMutable' must *not* delegate to
`AdditiveInverse');
so other methods to compute additive inverses need to be installed only
for `AdditiveInverseMutable' and (in the case of copyable objects)
`AdditiveInverseSameMutability'.



\>Order( <elm> ) A

is the multiplicative order of <elm>.
This is the smallest positive integer <n> such that
`<elm>^<n> = One( <elm> )' if such an integer exists. If the order is
infinite, `Order' may return the value `infinity', but it also might run
into an infinite loop trying to test the order.




%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Section{Comparison Operations for Elements}

Binary comparison operations have been introduced already in "Comparisons".
The underlying operations for which methods can be installed are the
following.

\>`\\=( <left-expr>, <right-expr> )'{equality!operation} O
\>`\\\<( <left-expr>, <right-expr> )'{comparison!operation} O

Note that the comparisons via `\<>', `\<=', `>', and `>=' are delegated to
the operations `\\=' and `\\\<'.

In general, objects in *different* families cannot be compared with `\<'.
For the reason and for exceptions from this rule, see~"Comparisons".

For some objects a ``normal form'' is hard to compute and thus equality of
elements of a domain might be expensive to test. Therefore {\GAP}
provides a (slightly technical) property with which an algorithm can test
whether an efficient equality test is available for elements of a certain
kind.

\>CanEasilyCompareElements( <obj> ) P
\>CanEasilyCompareElementsFamily( <fam> ) F
\>CanEasilySortElements( <obj> ) P
\>CanEasilySortElementsFamily( <fam> ) F

`CanEasilyCompareElements' indicates whether the elements in the family
<fam> of <obj> can be easily compared with `='.
(In some cases element comparisons are very hard, for example in cases
where no normal forms for the elements exist.)

The default method for this property is to ask the family of <obj>,
the default method for the family is to return `false'.

The ability to compare elements may depend on the successful computation
of certain information. (For example for finitely presented groups it
might depend on the knowledge of a faithful permutation representation.)
This information might change over time and thus it might not be a good
idea to store a value `false' too early in a family. Instead the
function `CanEasilyCompareElementsFamily' should be called for the
family of <obj> which returns `false' if the value of
`CanEasilyCompareElements' is not known for the family without computing
it. (This is in fact what the above mentioned family dispatch does.)

If a family knows ab initio that it can compare elements this property
should be set as implied filter *and* filter for the family (the 3rd and
4th argument of `NewFamily' respectively). This guarantees that code
which directly asks the family gets a right answer.

The property `CanEasilySortElements' and the function
`CanEasilySortElementsFamily' behave exactly in the same way, except
that they indicate that objects can be compared via `\<'. This property
implies `CanEasilyCompareElements', as the ordering must be total.



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Section{Arithmetic Operations for Elements}

*Binary* arithmetic operations have been introduced already in
"Arithmetic Operators".
The underlying operations for which methods can be installed are the
following.

\>`\\+( <left-expr>, <right-expr> )'{addition!operation} O
\>`\\\*( <left-expr>, <right-expr> )'{multiplication!operation} O
\>`\\/( <left-expr>, <right-expr> )'{division!operation} O
\>`\\^( <left-expr>, <right-expr> )'{exponentiation!operation} O
\>`\\mod( <left-expr>, <right-expr> )'{remainder!operation} O

For details about special methods for `\\mod', consult the index entries
for ``mod''.

% (no Declaration available for them?)

\>LeftQuotient( <elm1>, <elm2> ) O

returns the product `<elm1>^(-1) \* <elm2>'.
For some types of objects (for example permutations) this product can be
evaluated more efficiently than by first inverting <elm1>
and then forming the product with <elm2>.


\>Comm( <elm1>, <elm2> ) O

returns the *commutator* of <elm1> and <elm2>. The commutator is defined
as the product $<elm1>^{-1} \* <elm2>^{-1} \* <elm1> \* <elm2>$.


\beginexample
gap> a:= (1,3)(4,6);; b:= (1,6,5,4,3,2);;
gap> Comm( a, b );
(1,5,3)(2,6,4)
gap> LeftQuotient( a, b );
(1,2)(3,6)(4,5)
\endexample

\>LieBracket( <elm1>, <elm2> ) O

returns the element `<elm1> \* <elm2> - <elm2> \* <elm1>'.



The addition `\\+' is assumed to be associative but *not* assumed to be
commutative (see~"IsAdditivelyCommutative").
The multiplication `\\\*' is *not* assumed to be commutative or associative
(see~"IsCommutative", "IsAssociative").

\>Sqrt( <obj> ) O

`Sqrt' returns a square root of <obj>, that is, an object $x$ with the
property that $x \cdot x = <obj>$ holds.
If such an $x$ is not unique then the choice of $x$ depends on the type
of <obj>.
For example, `ER' (see~"ER") is the `Sqrt' method for rationals
(see~"IsRat").




% missing facts about the others ...


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Section{Relations Between Domains}

Domains are often constructed relative to other domains.
The probably most usual case is to form a *subset* of a domain,
for example the intersection (see~"Intersection") of two domains,
or a Sylow subgroup of a given group (see~"SylowSubgroup").

In such a situation, the new domain can gain knowledge by exploiting that
several attributes are maintained under taking subsets.
For example, the intersection of an arbitrary domain with a finite domain
is clearly finite, a Sylow subgroup of an abelian group is abelian, too,
and so on.

Since usually the new domain has access to the knowledge of the old domain(s)
only when it is created (see~"Constructing Subdomains" for the exception),
this is the right moment to take advantage of the subset relation.

Analogous relations occur when a *factor structure* is created from a domain
and a subset, and when a domain *isomorphic* to a given one is created.

\>UseSubsetRelation( <super>, <sub> ) O

Methods for this operation transfer possibly useful information from the
domain <super> to its subset <sub>, and vice versa.

`UseSubsetRelation' is designed to be called automatically
whenever substructures of domains are constructed.
So the methods must be *cheap*, and the requirements should be as
sharp as possible!

To achieve that *all* applicable methods are executed, all methods for
this operation except the default method must end with `TryNextMethod()'.
This default method deals with the information that is available by
the calls of `InstallSubsetMaintenance' in the {\GAP} library.


\beginexample
gap> g:= Group( (1,2), (3,4), (5,6) );; h:= Group( (1,2), (3,4) );;
gap> IsAbelian( g );  HasIsAbelian( h );
true
false
gap> UseSubsetRelation( g, h );;  HasIsAbelian( h );  IsAbelian( h );
true
true
\endexample

\>UseIsomorphismRelation( <old>, <new> ) O

Methods for this operation transfer possibly useful information from the
domain <old> to the isomorphic domain <new>.

`UseIsomorphismRelation' is designed to be called automatically
whenever isomorphic structures of domains are constructed.
So the methods must be *cheap*, and the requirements should be as
sharp as possible!

To achieve that *all* applicable methods are executed, all methods for
this operation except the default method must end with `TryNextMethod()'.
This default method deals with the information that is available by
the calls of `InstallIsomorphismMaintenance' in the {\GAP} library.


\beginexample
gap> g:= Group( (1,2) );;  h:= Group( [ [ -1 ] ] );;
gap> Size( g );  HasSize( h );
2
false
gap> UseIsomorphismRelation( g, h );;  HasSize( h );  Size( h );
true
2
\endexample

\>UseFactorRelation( <numer>, <denom>, <factor> ) O

Methods for this operation transfer possibly useful information from the
domain <numer> or its subset <denom> to the domain <factor> that
is isomorphic to the factor of <numer> by <denom>, and vice versa.
<denom> may be `fail', for example if <factor> is just known to be a
factor of <numer> but <denom> is not available as a {\GAP} object;
in this case those factor relations are used that are installed without
special requirements for <denom>.

`UseFactorRelation' is designed to be called automatically
whenever factor structures of domains are constructed.
So the methods must be *cheap*, and the requirements should be as
sharp as possible!

To achieve that *all* applicable methods are executed, all methods for
this operation except the default method must end with `TryNextMethod()'.
This default method deals with the information that is available by
the calls of `InstallFactorMaintenance' in the {\GAP} library.


\beginexample
gap> g:= Group( (1,2,3,4), (1,2) );; h:= Group( (1,2,3), (1,2) );;
gap> IsSolvableGroup( g );  HasIsSolvableGroup( h );
true
false
gap> UseFactorRelation( g, Subgroup( g, [ (1,2)(3,4), (1,3)(2,4) ] ), h );;
gap> HasIsSolvableGroup( h );  IsSolvableGroup( h );
true
true
\endexample

The following functions are used to tell {\GAP} under what conditions
an attribute is maintained under taking subsets,
or forming factor structures or isomorphic domains.
This is used only when a new attribute is created,
see~"prg:Creating Attributes and Properties" in ``Programming in {\GAP}''.
For the attributes already available, such as `IsFinite' and `IsCommutative',
the maintenances are already notified.

\>InstallSubsetMaintenance( <opr>, <super_req>, <sub_req> ) F

<opr> must be a property or an attribute.
The call of `InstallSubsetMaintenance' has the effect that
for a domain <D> in the filter <super_req>, and a domain <S> in the
filter <sub_req>,
the call `UseSubsetRelation( <D>, <S> )' (see~"UseSubsetRelation")
sets a known value of <opr> for <D> as value of <opr> also for <S>.
A typical example for which `InstallSubsetMaintenance' is applied
is given by `<opr> = IsFinite',
`<super_req> = IsCollection and IsFinite',
and `<sub_req> = IsCollection'.

If <opr> is a property and the filter <super_req> lies in the filter
<opr> then we can use also the following inverse implication.
If $D$ is in the filter whose intersection with <opr> is <super_req>
and if $S$ is in the filter <sub_req>, $S$ is a subset of $D$, and
the value of <opr> for $S$ is `false'
then the value of <opr> for $D$ is also `false'.


\>InstallIsomorphismMaintenance( <opr>, <old_req>, <new_req> ) F

<opr> must be a property or an attribute.
The call of `InstallIsomorphismMaintenance' has the effect that
for a domain <D> in the filter <old_req>, and a domain <E> in the
filter <new_req>,
the call `UseIsomorphismRelation( <D>, <E> )'
(see~"UseIsomorphismRelation")
sets a known value of <opr> for <D> as value of <opr> also for <E>.
A typical example for which `InstallIsomorphismMaintenance' is
applied is given by `<opr> = Size',
`<old_req> = IsCollection', and `<new_req> = IsCollection'.


\>InstallFactorMaintenance( <opr>, <numer_req>, <denom_req>, <factor_req> ) F

<opr> must be a property or an attribute.
The call of `InstallFactorMaintenance' has the effect that
for collections <N>, <D>, <F> in the filters <numer_req>, <denom_req>,
and <factor_req>, respectively,
the call `UseFactorRelation( <N>, <D>, <F> )'
(see~"UseFactorRelation")
sets a known value of <opr> for <N> as value of <opr> also for <F>.
A typical example for which `InstallFactorMaintenance' is
applied is given by `<opr> = IsFinite',
`<numer_req> = IsCollection and IsFinite', `<denom_req> = IsCollection',
and `<factor_req> = IsCollection'.

For the other direction, if <numer_req> involves the filter <opr>
then a known `false' value of <opr> for $F$ implies a `false'
value for $D$ provided that $D$ lies in the filter obtained from
<numer_req> by removing <opr>.

Note that an implication of a factor relation holds in particular for the
case of isomorphisms.
So one need *not* install an isomorphism maintained method when
a factor maintained method is already installed.
For example, `UseIsomorphismRelation' (see~"UseIsomorphismRelation")
will transfer a known `IsFinite' value because of the installed factor
maintained method.




%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Section{Useful Categories of Elements}

This section and the following one are rather technical,
and may be interesting only for those {\GAP} users who want to implement
new kinds of elements.

It deals with certain categories of elements that are useful mainly for the
design of elements, from the viewpoint that one wants to form certain domains
of these elements.
For example, a domain closed under multiplication `\*' (a so-called magma,
see Chapter~"Magmas") makes sense only if its elements can be multiplied,
and the latter is indicated by the category `IsMultiplicativeElement'
for each element.
Again note that the underlying idea is that a domain is regarded as
*generated* by given elements, and that these elements carry information
about the desired domain.
For general information on categories and their hierarchies,
see~"Categories".

\>IsExtAElement( <obj> ) C

An *external additive element* is an object that can be added via `+'
with other elements (not necessarily in the same family, see~"Families").


\>IsNearAdditiveElement( <obj> ) C

A *near-additive element* is an object that can be added via `+'
with elements in its family (see~"Families");
this addition is not necessarily commutative.


\>IsAdditiveElement( <obj> ) C

An *additive element* is an object that can be added via `+'
with elements in its family (see~"Families");
this addition is commutative.


\>IsNearAdditiveElementWithZero( <obj> ) C

A *near-additive element-with-zero* is an object that can be added
via `+' with elements in its family (see~"Families"),
and that is an admissible argument for the operation `Zero' (see~"Zero");
this addition is not necessarily commutative.


\>IsAdditiveElementWithZero( <obj> ) C

An *additive element-with-zero* is an object that can be added
via `+' with elements in its family (see~"Families"),
and that is an admissible argument for the operation `Zero' (see~"Zero");
this addition is commutative.


\>IsNearAdditiveElementWithInverse( <obj> ) C

A *near-additive element-with-inverse* is an object that can be
added via `+' with elements in its family (see~"Families"),
and that is an admissible argument for the operations `Zero' (see~"Zero")
and `AdditiveInverse' (see~"AdditiveInverse");
this addition is not necessarily commutative.


\>IsAdditiveElementWithInverse( <obj> ) C

An *additive element-with-inverse* is an object that can be
added via `+' with elements in its family (see~"Families"),
and that is an admissible argument for the operations `Zero' (see~"Zero")
and `AdditiveInverse' (see~"AdditiveInverse");
this addition is commutative.


\>IsExtLElement( <obj> ) C

An *external left element* is an object that can be multiplied from the
left, via `\*', with other elements (not necessarily in the same family,
see~"Families").


\>IsExtRElement( <obj> ) C

An *external right element* is an object that can be multiplied from the
right, via `\*', with other elements (not necessarily in the same family,
see~"Families").


\>IsMultiplicativeElement( <obj> ) C

A *multiplicative element* is an object that can be multiplied via `\*'
with elements in its family (see~"Families").


\>IsMultiplicativeElementWithOne( <obj> ) C

A *multiplicative element-with-one* is an object that can be multiplied
via `\*' with elements in its family (see~"Families"),
and that is an admissible argument for the operation `One' (see~"One").


\>IsMultiplicativeElementWithZero( <elt> ) C

Elements in a family which can be the operands of the 
`\*' and the operation MultiplicativeZero.


\>IsMultiplicativeElementWithInverse( <obj> ) C

A *multiplicative element-with-inverse* is an object that can be
multiplied via `\*' with elements in its family (see~"Families"),
and that is an admissible argument for the operations `One' (see~"One")
and `Inverse' (see~"Inverse"). (Note the word ``admissible'': an
object in this category does not necessarily have an inverse, `Inverse'
may return `fail'.)


\>IsVector( <obj> ) C

A *vector* is an additive-element-with-inverse that can be multiplied
from the left and right with other objects (not necessarily of the same
type).
Examples are cyclotomics, finite field elements,
and of course row vectors (see below).

Note that not all lists of ring elements are regarded as vectors,
for example lists of matrices are not vectors.
This is because although the category `IsAdditiveElementWithInverse' is
implied by the join of its collections category and `IsList',
the family of a list entry may not imply `IsAdditiveElementWithInverse'
for all its elements.


\>IsNearRingElement( <obj> ) C

`IsNearRingElement' is just a synonym for the join of
`IsNearAdditiveElementWithInverse' and `IsMultiplicativeElement'.


\>IsRingElement( <obj> ) C

`IsRingElement' is just a synonym for the join of
`IsAdditiveElementWithInverse' and `IsMultiplicativeElement'.


\>IsNearRingElementWithOne( <obj> ) C

`IsNearRingElementWithOne' is just a synonym for the join of
`IsNearAdditiveElementWithInverse' and `IsMultiplicativeElementWithOne'.


\>IsRingElementWithOne( <obj> ) C

`IsRingElementWithOne' is just a synonym for the join of
`IsAdditiveElementWithInverse' and `IsMultiplicativeElementWithOne'.


\>IsNearRingElementWithInverse( <obj> ) C


\>IsRingElementWithInverse( <obj> ) C
\>IsScalar( <obj> ) C

`IsRingElementWithInverse' and `IsScalar' are just synonyms for the join
of
`IsAdditiveElementWithInverse' and `IsMultiplicativeElementWithInverse'.



More special categories of this kind are described in the contexts where
they arise,
they are `IsRowVector' (see~"IsRowVector"),
`IsMatrix' (see~"IsMatrix"),
`IsOrdinaryMatrix' (see~"IsOrdinaryMatrix"),
and `IsLieMatrix' (see~"IsLieMatrix").


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Section{Useful Categories for all Elements of a Family}

The following categories of elements are to be understood mainly as
categories for all objects in a family,
they are usually used as third argument of `NewFamily'
(see~"prg:Creating Families" in ``Programming in {\GAP}'').
The purpose of each of the following categories is then to guarantee that
each collection of its elements automatically lies in its collections
category (see~"CategoryCollections").

For example, the multiplication of permutations is associative,
and it is stored in the family of permutations that each permutation lies
in `IsAssociativeElement'.
As a consequence, each magma consisting of permutations
(more precisely: each collection that lies in the family
`CollectionsFamily( PermutationsFamily )', see~"CollectionsFamily")
automatically lies in `CategoryCollections( IsAssociativeElement )'.
A magma in this category is always known to be associative, via a logical
implication (see~"prg:Logical Implications" in ``Programming in {\GAP}'').

Similarly, if a family knows that all its elements are in the categories
`IsJacobianElement' and `IsZeroSquaredElement',
then each algebra of these elements is automatically known to be a
Lie algebra (see~"Algebras").

\>IsAssociativeElement( <obj> ) C
\>IsAssociativeElementCollection( <obj> ) C
\>IsAssociativeElementCollColl( <obj> ) C

An element <obj> in the category `IsAssociativeElement' knows
that the multiplication of any elements in the family of <obj>
is associative.
For example, all permutations lie in this category, as well as those
ordinary matrices (see~"IsOrdinaryMatrix") whose entries are also in
`IsAssociativeElement'.


\>IsAdditivelyCommutativeElement( <obj> ) C
\>IsAdditivelyCommutativeElementCollection( <obj> ) C
\>IsAdditivelyCommutativeElementCollColl( <obj> ) C
\>IsAdditivelyCommutativeElementFamily( <obj> ) C

An element <obj> in the category `IsAdditivelyCommutativeElement' knows
that the addition of any elements in the family of <obj>
is commutative.
For example, each finite field element and each rational number lies in
this category.


\>IsCommutativeElement( <obj> ) C
\>IsCommutativeElementCollection( <obj> ) C
\>IsCommutativeElementCollColl( <obj> ) C

An element <obj> in the category `IsCommutativeElement' knows
that the multiplication of any elements in the family of <obj>
is commutative.
For example, each finite field element and each rational number lies in
this category.


\>IsFiniteOrderElement( <obj> ) C
\>IsFiniteOrderElementCollection( <obj> ) C
\>IsFiniteOrderElementCollColl( <obj> ) C

An element <obj> in the category `IsFiniteOrderElement' knows
that it has finite multiplicative order.
For example, each finite field element and each permutation lies in
this category.
However the value may be `false' even if <obj> has finite order,
but if this was not known when <obj> was constructed.

Although it is legal to set this filter for any object with finite order,
this is really useful only in the case that all elements of a family are
known to have finite order.


\>IsJacobianElement( <obj> ) C
\>IsJacobianElementCollection( <obj> ) C
\>IsJacobianElementCollColl( <obj> ) C

An element <obj> in the category `IsJacobianElement' knows
that the multiplication of any elements in the family $F$ of <obj>
satisfies the Jacobi identity, that is,
$x \* y \* z + z \* x \* y + y \* z \* x$ is zero
for all $x$, $y$, $z$ in $F$.

For example, each Lie matrix (see~"IsLieMatrix") lies in this category.


\>IsZeroSquaredElement( <obj> ) C
\>IsZeroSquaredElementCollection( <obj> ) C
\>IsZeroSquaredElementCollColl( <obj> ) C

An element <obj> in the category `IsZeroSquaredElement' knows
that `<obj>^2 = Zero( <obj> )'.
For example, each Lie matrix (see~"IsLieMatrix") lies in this category.

Although it is legal to set this filter for any zero squared object,
this is really useful only in the case that all elements of a family are
known to have square zero.




%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%E