home *** CD-ROM | disk | FTP | other *** search
/ Math Solutions 1995 October / Math_Solutions_CD-ROM_Walnut_Creek_October_1995.iso / pc / mac / discrete / doc / domain.tex < prev    next >
Encoding:
Text File  |  1993-05-05  |  39.4 KB  |  818 lines

  1. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2. %%
  3. %A  domain.tex                  GAP documentation            Martin Schoenert
  4. %%
  5. %A  @(#)$Id: domain.tex,v 3.8 1993/02/19 10:48:42 gap Exp $
  6. %%
  7. %Y  Copyright 1990-1992,  Lehrstuhl D fuer Mathematik,  RWTH Aachen,  Germany
  8. %%
  9. %%  This file describes domains, the concept, their functions and operations.
  10. %%
  11. %H  $Log: domain.tex,v $
  12. %H  Revision 3.8  1993/02/19  10:48:42  gap
  13. %H  adjustments in line length and spelling
  14. %H
  15. %H  Revision 3.7  1993/02/18  16:34:21  felsch
  16. %H  another example fixed
  17. %H
  18. %H  Revision 3.6  1993/02/15  09:42:18  felsch
  19. %H  examples fixed
  20. %H
  21. %H  Revision 3.5  1993/02/10  20:48:39  martin
  22. %H  fixed some examples
  23. %H
  24. %H  Revision 3.4  1992/04/30  11:57:09  martin
  25. %H  changed a few sentences to avoid bold non-roman fonts
  26. %H
  27. %H  Revision 3.3  1992/04/06  12:43:02  martin
  28. %H  fixed some more typos
  29. %H
  30. %H  Revision 3.2  1992/04/02  21:06:23  martin
  31. %H  changed *domain functions* to *set theoretic functions*
  32. %H  
  33. %H  Revision 3.1  1992/03/11  11:40:55  martin
  34. %H  changed 'Representative' to 'RepresentativeOperation' in the example
  35. %H
  36. %H  Revision 3.0  1991/12/27  16:10:27  martin
  37. %H  initial revision under RCS
  38. %H
  39. %%
  40. \Chapter{Domains}
  41.  
  42. *Domain* is {\GAP}\'s  name  for structured sets.   The ring  of Gaussian
  43. integers  $Z[I]$  is  an  example  of  a  domain,  the group  $D_{12}$ of
  44. symmetries of a regular hexahedron is another.
  45.  
  46. The {\GAP}  library predefines some   domains.  For example  the  ring of
  47. Gaussian integers is  predefined as 'GaussianIntegers' (see  "Gaussians")
  48. and the   field   of rationals   is predefined  as      'Rationals'  (see
  49. "Rationals").   Most domains  are  constructed  by  functions,  which are
  50. called  *domain   constructors*.   For  example  the    group $D_{12}$ is
  51. constructed by the construction 'Group( (1,2,3,4,5,6), (2,6)(3,5) )' (see
  52. "Group") and  the finite  field  with  16  elements   is constructed   by
  53. 'GaloisField( 16 )' (see "GaloisField").
  54.  
  55. The first place where  you need domains  in {\GAP}  is  the  obvious one.
  56. Sometimes you simply want to talk about a  domain.  For  example  if  you
  57. want to compute the size of the group $D_{12}$, you had better be able to
  58. represent this group in a way that the 'Size' function can understand.
  59.  
  60. The second place where you need domains in {\GAP} is when  you want to be
  61. able to specify that an operation or computation takes place in a certain
  62. domain.   For  example suppose  you want   to factor 10    in the ring of
  63. Gaussian integers.  Saying 'Factors( 10 )' will not do, because this will
  64. return the factorization in  the ring of integers '[  2, 5 ]'.  To  allow
  65. operations and  computations to happen in   a specific domain, 'Factors',
  66. and many other functions  as well, accept  this domain as optional  first
  67. argument.   Thus 'Factors( GaussianIntegers,   10 )'  yields  the desired
  68. result '[ 1+E(4), 1-E(4), 2+E(4), 2-E(4) ]'.
  69.  
  70. Each domain  in  {\GAP} belongs to one  or  more *categories*, which  are
  71. simply sets of domains.  The categories in  which a domain lies determine
  72. the functions  that  are  applicable to   this  domain and  its elements.
  73. Examples  of domains are *rings*  (the  functions applicable to a  domain
  74. that  is a  ring  are  described in "Rings"),  *fields*   (see "Fields"),
  75. *groups*  (see "Groups"), *vector spaces*  (see "Vector  Spaces"), and of
  76. course  the category *domains* that   contains all domains (the functions
  77. applicable to any domain are described in this chapter).
  78.  
  79. This chapter describes how domains are represented in {\GAP} (see "Domain
  80. Records"),  how functions that  can be  applied  to  different  types  of
  81. domains know how  to  solve a  problem  for  each  of  those  types  (see
  82. "Dispatchers", "More about Dispatchers", and "An Example of a Computation
  83. in a Domain"), how domains are compared (see  "Comparisons of  Domains"),
  84. and  the set theoretic  functions that can be  applied to any domain (see
  85. "Elements",   "Membership   Test  for   Domains",   "IsFinite",   "Size",
  86. "IsSubset", "Intersection", "Union", "Difference", "Random").
  87.  
  88. The  functions  described in this  chapter  are implemented in  the  file
  89. 'LIBNAME/\"domain.g\"'.
  90.  
  91. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  92. \Section{Domain Records}
  93.  
  94. Domains are represented by    records (see "Records"), which  are  called
  95. *domain records* in the following.  Which  components need to be present,
  96. which  may, and what   those components hold,  differs  from  category to
  97. category, and,  to a smaller   extent, from  domain  to domain.   It   is
  98. generally possible though to distinguish four types of components.
  99.  
  100. Each  domain record  has  the component 'isDomain',  which  has the value
  101. 'true'.  Furthermore,  most domains also have  a component that specifies
  102. which category this  domain belongs to.  For  example, each group has the
  103. component 'isGroup', holding the   value  'true'.  Those components   are
  104. called  the *category  components* of  the  domain record.  A domain that
  105. only has  the  component  'isDomain' is  a  member  only of the  category
  106. *Domains* and only the functions described in this chapter are applicable
  107. to such a domain.
  108.  
  109. Every domain record also contains enough information to identify uniquely
  110. the domain in the   so called *identification components*.   For example,
  111. for a  group the domain record,  called group record  in this case, has a
  112. component called 'generators' containing a system of generators (and also
  113. a component 'identity' holding the identity element  of the group, needed
  114. if the generator list is empty, as is the case for the trivial group).
  115.  
  116. Next the  domain record  holds all   the knowledge  {\GAP} has  about the
  117. domain, for example the  size of the domain, in  the so called *knowledge
  118. components*.   Of  course, the  knowledge   about a certain  domain  will
  119. usually  increase  as time goes  by.   For example,  a  group  record may
  120. initially hold  only the knowledge that the  group is finite, but may end
  121. holding all kinds of knowledge, for example the derived series, the Sylow
  122. subgroups, etc.
  123.  
  124. Finally  each   domain  record has    a component,  which  is called  its
  125. *operations   record*  (because  it   is   the component  with  the  name
  126. 'operations' and it holds a record), that tells functions like 'Size' how
  127. to  compute this  information  for this domain.   The exact  mechanism is
  128. described later (see "Dispatchers").
  129.  
  130. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  131. \Section{Dispatchers}%
  132. \index{operations record}\index{record!operations}%
  133. \index{dispatcher functions}\index{default functions}
  134.  
  135. In the previous section it was  mentioned that domains are represented by
  136. domain records, and  that each domain record  has  an operations  record.
  137. This operations record  is used by functions like 'Size' to  find out how
  138. to  compute  this information  for  the  domain.   Let  us  discuss  this
  139. mechanism using the example  of 'Size'.  Suppose you  call 'Size'  with a
  140. domain <D>.
  141.  
  142. First 'Size' tests whether  <D> has a  component called 'size',  i.e., if
  143. '<D>.size' is bound.  If it is, 'Size' assumes that  it holds the size of
  144. the domain and returns this value.
  145.  
  146. Let  us suppose that this component has no assigned  value.  Then  'Size'
  147. looks at the component '<D>.operations', which must be a  record.  'Size'
  148. takes  component '<D>.operations.Size' of this  record,  which must  be a
  149. function.  'Size'  calls this  function  passing <D>  as argument.  If  a
  150. domain  record has no 'Size' function in its operations record,  an error
  151. is signalled.
  152.  
  153. Finally 'Size' stores the value returned  by '<D>.operations.Size( <D> )'
  154. in the  component '<D>.size', where it is  available for the next call of
  155. 'Size( <D> )'.
  156.  
  157. Because functions like  'Size' do little  except dispatch to the function
  158. in the operations record they are called *dispatcher functions*.
  159.  
  160. Which function is called through  this mechanism obviously depends on the
  161. domain and its  operations record.  In  principle each  domain could have
  162. its own 'Size' function.  In practice however this is  not the case.  For
  163. example all permutation groups share the operations record 'PermGroupOps'
  164. so they all use the same 'Size' function 'PermGroupOps.Size'.
  165.  
  166. Note that in fact domains of the  same type not only share the functions,
  167. in fact they share the operations record.  So for example all permutation
  168. groups have the same operations record.  This means  that changing such a
  169. function for a domain <D> in the following way '<D>.operations.<function>
  170. \:= <new-function>;' will also change this  function for  all  domains of
  171. the  same type, even those that do not  yet exist at  the  moment  of the
  172. assignment  and will  only  be  constructed  later.  This  is usually not
  173. desirable, since supposedly <new-function> uses  some  special properties
  174. of the domain <D> to  work efficiently.   We suggest  therefore, that you
  175. use the following assignments instead\: \\
  176. '<D>.operations \:= Copy( <D>.operations );'\\
  177. '<D>.operations.<function> \:= <new-function>;'.
  178.  
  179. Some domains do not provide a special 'Size' function,  either because no
  180. efficient method is  known  or because the   author that implemented  the
  181. domain simply was  too  lazy to write  one.   In those cases   the domain
  182. inherits the *default    function*, which   is 'DomainOps.Size'.     Such
  183. inheritance  is uncommon for  the 'Size' function,  but rather common for
  184. the 'Union' function.
  185.  
  186. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  187. \Section{More about Dispatchers}
  188.  
  189. Usually you  need not care about  the mechanism described in the previous
  190. section.  You just call the  dispatcher functions like 'Size'.  They will
  191. call  the   function  in  the   operations   record,  which  is hopefully
  192. implementing an algorithm that is well  suited for their domain, by using
  193. the structure of this domain.
  194.  
  195. There  are three  reasons  why  you  might  want  to  avoid  calling  the
  196. dispatcher function and call the dispatched to function directly.
  197.  
  198. The first reason is efficiency.  The  dispatcher functions don\'t do very
  199. much.   They   only check the types    of their arguments,  check  if the
  200. requested information is already present, and dispatch to the appropriate
  201. function in the  operations record.   But  sometimes, for example  in the
  202. innermost loop of your algorithm, even this little is too much.  In those
  203. cases you can avoid the overhead introduced by the dispatcher function by
  204. calling the function in the operations record directly.  For example, you
  205. would use '<G>.operations.Size(<G>)' instead of 'Size(<G>)'.
  206.  
  207. The second reason is flexibility.  Sometimes you do not want to call  the
  208. function in the operations record, but another function that performs the
  209. same task, using a different algorithm.  In that case you will  call this
  210. different function.  For example, if <G> is a permutation group,  and the
  211. orbit of <p> under <G> is very short, 'GroupOps.Orbit(<G>,<p>)', which is
  212. the  default function to compute an orbit, may be slightly more efficient
  213. than 'Orbit(<G>,<p>)', which calls '<G>.operations.Orbit(<G>,<p>)', which
  214. is the same as 'PermGroupOps.Orbit(<G>,<p>)'.
  215.  
  216. The third has to do with the fact that the dispatcher functions check for
  217. knowledge   components like '<D>.size' or   '<D>.elements' and also store
  218. their result in such components.  For example,  suppose you know that the
  219. result of a computation takes  up quite some space, as  is the case  with
  220. 'Elements(<D>)', and that  you will never  need the value again.  In this
  221. case you would not want the dispatcher function to enter the value in the
  222. domain  record, and therefore  would call  '<D>.operations.Elements(<D>)'
  223. directly.  On  the other hand you  may not want  to use the  value in the
  224. domain record, because you mistrust it.  In this case you should call the
  225. function  in   the operations   record   directly,  e.g., you would   use
  226. '<G>.operations.Size(<G>)' instead of  'Size(<G>)' (and  then compare the
  227. result with '<G>.size').
  228.  
  229. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  230. \Section{An Example of a Computation in a Domain}
  231.  
  232. This section contains an extended example to  show  you how a computation
  233. in a domain may  use default and special  functions to achieve its  goal.
  234. Suppose you defined 'G', 'x', and 'y' as follows.
  235.  
  236. |    gap> G := SymmetricGroup( 8 );;
  237.     gap> x := [ (2,7,4)(3,5), (1,2,6)(4,8) ];;
  238.     gap> y := [ (2,5,7)(4,6), (1,5)(3,8,7) ];; |
  239.  
  240. Now you ask for  an  element of 'G' that   conjugates 'x' to 'y', i.e., a
  241. permutation on 8 points  that takes '(2,7,4)(3,5)' to '(2,5,7)(4,6)'  and
  242. '(1,2,6)(4,8)' to  '(1,5)(3,8,7)'.      This is done    as follows   (see
  243. "RepresentativeOperation" and "Other Operations").
  244.  
  245. |    gap> RepresentativeOperation( G, x, y, OnTuples );
  246.     (1,8)(2,7)(3,4,5,6) |
  247.  
  248. Let    us    look    at    what    happens    step   by    step.    First
  249. 'RepresentativeOperation'  is called.  After  checking  the  arguments it
  250. calls the  function 'G.operations.RepresentativeOperation', which  is the
  251. function    'SymmetricGroupOps.RepresentativeOperation',   passing    the
  252. arguments 'G', 'x', 'y', and 'OnTuples'.
  253.  
  254. 'SymmetricGroupOps.RepresentativeOperation'  handles  a   lot  of   cases
  255. specially, but the operation on tuples of permutations is not among them.
  256. Therefore it delegates  this  problem  to the function that  it overlays,
  257. which is 'PermGroupOps.RepresentativeOperation'.
  258.  
  259. 'PermGroupOps.RepresentativeOperation' also does  not handle this special
  260. case, and delegates the problem  to the function that it  overlays, which
  261. is the default function called 'GroupOps.RepresentativeOperation'.
  262.  
  263. 'GroupOps.RepresentativeOperation' views this problem as a general tuples
  264. problem, i.e., it  does not  care  whether  the  points in the tuples are
  265. integers or permutations, and decides to solve it one step at a time.  So
  266. first it looks for  an element taking '(2,7,4)(3,5)' to '(2,5,7)(4,6)' by
  267. calling 'RepresentativeOperation( G, (2,7,4)(3,5), (2,5,7)(4,6) )'.
  268.  
  269. 'RepresentativeOperation'  calls   'G.operations.RepresentativeOperation'
  270. next, which is the  function 'SymmetricGroupOps.RepresentativeOperation',
  271. passing the arguments 'G', '(2,7,4)(3,5)', and '(2,5,7)(4,6)'.
  272.  
  273. 'SymmetricGroupOps.RepresentativeOperation' can  handle  this  case.   It
  274. *knows*  that 'G' contains every  permutation on 8 points, so it contains
  275. '(3,4,7,5,6)',  which obviously does what we want, namely it takes 'x[1]'
  276. to 'y[1]'.  We will call this element 't'.
  277.  
  278. Now 'GroupOps.RepresentativeOperation'  (see  above) looks  for an 's' in
  279. the stabilizer of 'x[1]' taking 'x[2]' to 'y[2]\^(t\^-1)', since then for
  280. 'r=s\*t'  we have 'x[1]\^r  =  (x[1]\^s)\^t =  x[1]\^t  =  y[1]' and also
  281. 'x[2]\^r =  (x[2]\^s)\^t = (y[2]\^(t\^-1))\^t = y[2]'.   So the next step
  282. is to compute  the  stabilizer  of 'x[1]' in  'G'.  To do this  it  calls
  283. 'Stabilizer( G, (2,7,4)(3,5) )'.
  284.  
  285. 'Stabilizer'    calls     'G.operations.Stabilizer',        which      is
  286. 'SymmetricGroupOps.Stabilizer',  passing  the       arguments   'G'   and
  287. '(2,7,4)(3,5)'.   'SymmetricGroupOps.Stabilizer' detects that  the second
  288. argument  is a permutation, i.e.,  an  element of the   group,  and calls
  289. 'Centralizer( G,  (2,7,4)(3,5)  )'.  'Centralizer'   calls  the  function
  290. 'G.operations.Centralizer',   which is   'SymmetricGroupOps.Centralizer',
  291. again passing the arguments 'G', '(2,7,4)(3,5)'.
  292.  
  293. 'SymmetricGroupOps.Centralizer'   again  *knows*   how  centralizers   in
  294. symmetric   groups  look,   and     after looking  at    the  permutation
  295. '(2,7,4)(3,5)'  sharply  for  a  short  while returns  the centralizer as
  296. 'Subgroup( G,  [ (1,6), (1,6,8), (2,7,4), (3,5)  ] )', which we will call
  297. 'S'.  Note  that  'S'  is of  course not   a symmetric  group,  therefore
  298. 'SymmetricGroupOps.Subgroup' gives it 'PermGroupOps' as operations record
  299. and not 'SymmetricGroupOps'.
  300.  
  301. As explained above 'GroupOps.RepresentativeOperation' needs an element of
  302. 'S' taking 'x[2]'  ('(1,2,6)(4,8)') to 'y[2]\^(t\^-1)'  ('(1,7)(4,6,8)').
  303. So 'RepresentativeOperation( S, (1,2,6)(4,8), (1,7)(4,6,8) )' is  called.
  304. 'RepresentativeOperation'     in     turn     calls     the      function
  305. 'S.operations.RepresentativeOperation',  which   is,  since   'S'   is  a
  306. permutation group,  the function  'PermGroupOps.RepresentativeOperation',
  307. passing the arguments 'S', '(1,2,6)(4,8)', and '(1,7)(4,6,8)'.
  308.  
  309. 'PermGroupOps.RepresentativeOperation'  detects  that  the   points   are
  310. permutations and and  performs a backtrack search through 'S'.   It finds
  311. and returns '(1,8)(2,4,7)(3,5)', which we call 's'.
  312.  
  313. Then   'GroupOps.RepresentativeOperation'    returns   'r    =   s\*t   =
  314. (1,8)(2,7)(3,6)(4,5)', and we are done.
  315.  
  316. In this  example you have seen how functions use the  structure of  their
  317. domain   to   solve   a    problem   most   efficiently,   for    example
  318. 'SymmetricGroupOps.RepresentativeOperation' but also the backtrack search
  319. in 'PermGroupOps.RepresentativeOperation', how they use  other functions,
  320. for example 'SymmetricGroupOps.Stabilizer' called 'Centralizer', and  how
  321. they delegate cases  which they  can not handle  more efficiently back to
  322. the       function        they        overlaid,        for        example
  323. 'SymmetricGroupOps.RepresentativeOperation'         delegated          to
  324. 'PermGroupOps.RepresentativeOperation', which in turn delegated to to the
  325. function 'GroupOps.RepresentativeOperation'.
  326.  
  327. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  328. \Section{Domain}
  329.  
  330. 'Domain( <list> )'
  331.  
  332. 'Domain' returns a domain that  contains all  the elements  in <list> and
  333. that  knows how to  make  the ring,  field, group, or vector  space  that
  334. contains those elements.
  335.  
  336. Note that the domain returned by 'Domain' need in general  not be a ring,
  337. field, group,  or vector space itself.  For  example if passed  a list of
  338. elements of  finite     fields 'Domain'   will     return   the    domain
  339. 'FiniteFieldElements'.  This  domain contains all finite  field elements,
  340. no   matter  of  which  characteristic.  This   domain  has  a   function
  341. 'FiniteFieldElementsOps.Field' that knows how to make a finite field that
  342. contains the elements in <list>.  This  function knows that  all elements
  343. must have the same characteristic for them to lie in a common field.
  344.  
  345. |    gap> D := Domain( [ Z(4), Z(8) ] );
  346.     FiniteFieldElements
  347.     gap> IsField( D );
  348.     false
  349.     gap> D.operations.Field( [ Z(4), Z(8) ] );
  350.     GF(2^6) |
  351.  
  352. 'Domain'  is the only function  in the whole  {\GAP}  library  that knows
  353. about the  various  types  of  elements.   For  example,  when  'Norm' is
  354. confronted by a field element <z>, it does  not know what  to do with it.
  355. So it calls 'F \:= DefaultField( [ <z> ] )' to  get  a field in which <z>
  356. lies, because  this field (more precisely  'F.operations.Norm') will know
  357. better.  However, 'DefaultField' also does not know  what to do with <z>.
  358. So it calls 'D \:= Domain( [ <z> ] )' to get  a domain in which <z> lies,
  359. because it (more precisely 'D.operations.DefaultField') will know  how to
  360. make a default field in which <z> lies.
  361.  
  362. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  363. \Section{Elements}%
  364. \index{elements!of a domain}
  365.  
  366. 'Elements( <D> )'
  367.  
  368. 'Elements'  returns the set of elements  of the  domain  <D>.  The set is
  369. returned  as a new proper  set, i.e., as a  new sorted list without holes
  370. and duplicates (see "Sets").  <D>  may also be  a list, in which case the
  371. set of elements of this list  is returned.  An  error is signalled if <D>
  372. is an infinite domain.
  373.  
  374. |    gap> Elements( GaussianIntegers );
  375.     Error, the ring <R> must be finite to compute its elements
  376.     gap> D12 := Group( (2,6)(3,5), (1,2)(3,6)(4,5) );;
  377.     gap> Elements( D12 );
  378.     [ (), (2,6)(3,5), (1,2)(3,6)(4,5), (1,2,3,4,5,6), (1,3)(4,6),
  379.       (1,3,5)(2,4,6), (1,4)(2,3)(5,6), (1,4)(2,5)(3,6), (1,5)(2,4),
  380.       (1,5,3)(2,6,4), (1,6,5,4,3,2), (1,6)(2,5)(3,4) ] |
  381.  
  382. 'Elements' remembers the set of  elements in the component '<D>.elements'
  383. and will return a shallow copy (see "ShallowCopy") next time it is called
  384. to compute the elements of <D>.  If  you want to  avoid this, for example
  385. for a large domain, for which you know that you will not need the list of
  386. elements in the future,  either  unbind (see "Unbind")  '<D>.elements' or
  387. call '<D>.operation.Elements(<D>)' directly.
  388.  
  389. Since there is no general method to compute the elements  of a domain the
  390. default  function  'DomainOps.Elements'  just  signals  an  error.   This
  391. default function  is  overlaid for each  special finite domain.  In fact,
  392. implementors of domains, *must* implement this function  for new domains,
  393. since it is,  together with 'IsFinite'  (see  "IsFinite")  the most basic
  394. function for domains, used by most of the default functions in the domain
  395. package.
  396.  
  397. In  general functions that  return  a set of   elements are free, in fact
  398. encouraged, to return a  domain instead  of the  proper set of  elements.
  399. For  one  thing this  allows  to  keep the    structure, for  another the
  400. representation   by a  domain record is    usually more space  efficient.
  401. 'Elements' must not do this, its only purpose is to create the proper set
  402. of elements.
  403.  
  404. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  405. \Section{Comparisons of Domains}
  406.  
  407. '<D> = <E>' \\
  408. '<D> \<> <E>'
  409.  
  410. '=' evaluates  to  'true' if the  two  domains <D> and  <E> are equal, to
  411. 'false' otherwise.  '\<>' evaluates  to 'true' if the two domains <D> and
  412. <E> are different and to 'false' if they are equal.
  413.  
  414. Two  domains  are considered  equal  if  and  only if  the  sets of their
  415. elements as computed by 'Elements' (see "Elements") are equal.   Thus, in
  416. general '=' behaves as if each domain operand were replaced by its set of
  417. elements.  Except  that '=' will also sometimes, but not always, work for
  418. infinite domains, for which  it is of course difficult to compute the set
  419. of elements.  Note that this implies that domains belonging  to different
  420. categories may well be equal.  As  a special case of this, either operand
  421. may also be a proper set, i.e., a sorted list without holes or duplicates
  422. (see  "Set"),  and the result will be 'true' if and only  if  the  set of
  423. elements of  the domain  is, as  a set, equal  to  the set.  It  is  also
  424. possible to compare a domain with something else that is not a domain  or
  425. a set, but the result will of course always be 'false' in this case.
  426.  
  427. |    gap> GaussianIntegers = D12;
  428.     false    # {\GAP} knows that those domains cannot be equal because
  429.              # 'GaussianIntegers' is infinite and 'D12' is finite
  430.     gap> GaussianIntegers = Integers;
  431.     false    # {\GAP} knows how to compare those two rings
  432.     gap> GaussianIntegers = Rationals;
  433.     Error, sorry, cannot compare the infinite domains <D> and <E>
  434.     gap> D12 = Group( (2,6)(3,5), (1,2)(3,6)(4,5) );
  435.     true
  436.     gap> D12 = [(),(2,6)(3,5),(1,2)(3,6)(4,5),(1,2,3,4,5,6),(1,3)(4,6),
  437.     >           (1,3,5)(2,4,6),(1,4)(2,3)(5,6),(1,4)(2,5)(3,6),
  438.     >           (1,5)(2,4),(1,5,3)(2,6,4),(1,6,5,4,3,2),(1,6)(2,5)(3,4)];
  439.     true
  440.     gap> D12 = [(1,6,5,4,3,2),(1,6)(2,5)(3,4),(1,5,3)(2,6,4),(1,5)(2,4),
  441.     >           (1,4)(2,5)(3,6),(1,4)(2,3)(5,6),(1,3,5)(2,4,6),(1,3)(4,6),
  442.     >           (1,2,3,4,5,6),(1,2)(3,6)(4,5),(2,6)(3,5),()];
  443.     false    # since the left operand behaves as a set
  444.              # while the right operand is not a set |
  445.  
  446. The  default function  |DomainOps.'='|  checks whether  both domains  are
  447. infinite.  If they are, an error is signalled.  Otherwise, if  one domain
  448. is infinite, 'false'  is returned.  Otherwise  the sizes (see "Size")  of
  449. the domains are compared.  If they are  different,  'false' is  returned.
  450. Finally  the  sets  of   elements  of  both  domains  are  computed  (see
  451. "Elements") and compared.   This  default function  is overlaid  by  more
  452. special functions for other domains.
  453.  
  454. '<D> \<\ <E>' \\
  455. '<D> \<= <E>' \\
  456. '<D>  >  <E>' \\
  457. '<D>  >= <E>'
  458.  
  459. '\<', '\<=', '>', and '>=' evaluate  to 'true' if the  domain <D> is less
  460. than, less than or equal to,  greater than, and greater  than or equal to
  461. the domain <E> and to 'false' otherwise.
  462.  
  463. A domain <D> is considered less than a  domain <E> if and only if the set
  464. of elements of <D> is less than  the set of elements  of the  domain <E>.
  465. Generally you may just imagine  that  each domain operand is  replaced by
  466. the set of its  elements, and that the comparison is performed  on  those
  467. sets (see "Comparisons of Lists").  This  implies that, if you compare  a
  468. domain with an  object that is not a list or a domain,  this other object
  469. will be less than the domain, except if it  is a record, in which case it
  470. is larger than the domain (see "Comparisons").
  471.  
  472. Note that '\<' does *not* test whether the left domain is a subset of the
  473. right  operand,   even  though  it  resembles   the  mathematical  subset
  474. notation.
  475.  
  476. |    gap> GaussianIntegers < Rationals;
  477.     Error, sorry, cannot compare <E> with the infinite domain <D>
  478.     gap> Group( (1,2), (1,2,3,4,5,6) ) < D12;
  479.     true     # since '(5,6)', the second element of the left operand,
  480.              # is less than '(2,6)(3,5)', the second element of 'D12'.
  481.     gap> D12 < [(1,6,5,4,3,2),(1,6)(2,5)(3,4),(1,5,3)(2,6,4),(1,5)(2,4),
  482.     >           (1,4)(2,5)(3,6),(1,4)(2,3)(5,6),(1,3,5)(2,4,6),(1,3)(4,6),
  483.     >           (1,2,3,4,5,6),(1,2)(3,6)(4,5),(2,6)(3,5),()];
  484.     true     # since '()', the first element of 'D12', is less than
  485.              # '(1,6,5,4,3,2)', the first element of the right operand.
  486.     gap> 17 < D12;
  487.     true     # objects that are not lists or records are smaller
  488.              # than domains, which behave as if they were a set |
  489.  
  490. The  default function  |DomainOps.'<'| checks  whether  either  domain is
  491. infinite.   If  one  is,  an error  is signalled.  Otherwise  the sets of
  492. elements  of both  domains  are computed  (see "Elements") and  compared.
  493. This  default  function  is  only  very  seldom overlaid  by more special
  494. functions for other domains.   Thus the  operators '\<', '\<=', '>',  and
  495. '>=' are quite expensive and their use should be avoided if possible.
  496.  
  497. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  498. \Section{Membership Test for Domains}%
  499. \index{in!for domains}\index{membership test!for domains}
  500.  
  501. '<elm> in <D>'
  502.  
  503. 'in' returns 'true' if the element  <elm>, which may  be an object of any
  504. type, lies in the domain <D>, and 'false' otherwise.
  505.  
  506. |    gap> 13 in GaussianIntegers;
  507.     true
  508.     gap> GaussianIntegers in GaussianIntegers;
  509.     false
  510.     gap> (1,2) in D12;
  511.     false
  512.     gap> (1,2)(3,6)(4,5) in D12;
  513.     true |
  514.  
  515. The default  function  for domain membership   tests is |DomainOps.'in'|,
  516. which  computes  the set  of  elements of the  domain   with the function
  517. 'Elements' (see  "Elements") and tests whether   <elm> lies in  this set.
  518. Special   domains usually overlay    this  function with more   efficient
  519. membership tests.
  520.  
  521. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  522. \Section{IsFinite}%
  523. \index{finiteness test!for domains}
  524.  
  525. 'IsFinite( <D> )'
  526.  
  527. 'IsFinite'  returns  'true' if  the   domain <D> is  finite  and  'false'
  528. otherwise.  <D> may also be a proper  set (see "Set"),  in which case the
  529. result is of course always 'true'.
  530.  
  531. |    gap> IsFinite( GaussianIntegers );
  532.     false
  533.     gap> IsFinite( D12 );
  534.     true |
  535.  
  536. The default function 'DomainOps.IsFinite'  just signals  an error,  since
  537. there is no general method to determine  whether  a  domain is  finite or
  538. not.   This  default function is  overlaid  for  each special domain.  In
  539. fact,  implementors  of domains *must*  implement this  function for  new
  540. domains, since it is, together with 'Elements' (see "Elements"), the most
  541. basic function for domains,  used by most of the default functions in the
  542. domain package.
  543.  
  544. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  545. \Section{Size}%
  546. \index{size!of a domain}
  547.  
  548. 'Size( <D> )'
  549.  
  550. 'Size' returns the  size of the domain <D>.   If <D> is  infinite, 'Size'
  551. returns the  string  '\"infinity\"'.  <D> may  also be a proper set  (see
  552. "Set"), in  which  case  the result  is  the length of this list.  'Size'
  553. will, however, signal an error if <D> is a list that is not a proper set,
  554. i.e., that is not sorted, or has holes, or contains duplicates.
  555.  
  556. |    gap> Size( GaussianIntegers );
  557.     "infinity"
  558.     gap> Size( D12 );
  559.     12 |
  560.  
  561. The default function to compute the size of a domain is 'DomainOps.Size',
  562. which  computes the  set of  elements of  the  domain  with  the function
  563. 'Elements' (see "Elements") and  returns the  length  of this  set.  This
  564. default function is overlaid in practically every domain.
  565.  
  566. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  567. \Section{IsSubset}%
  568. \index{subset test!for domains}
  569.  
  570. 'IsSubset( <D>, <E> )'
  571.  
  572. 'IsSubset' returns 'true' if the domain <E> is a subset of the domain <D>
  573. and 'false' otherwise.
  574.  
  575. <E> is considered a subset of <D> if  and only if the  set of elements of
  576. <E> is as a set  a subset of  the set of  elements of <D> (see "Elements"
  577. and  "Set Functions  for  Sets").   That  is  'IsSubset'  behaves  as  if
  578. implemented as 'IsSubsetSet( Elements(<D>), Elements(<E>) )', except that
  579. it  will also sometimes,  but not always,  work for infinite domains, and
  580. that it will usually work much faster than the  above definition.  Either
  581. argument may also be a proper set.
  582.  
  583. |    gap> IsSubset( GaussianIntegers, [1,E(4)] );
  584.     true
  585.     gap> IsSubset( GaussianIntegers, Rationals );
  586.     Error, sorry, cannot compare the infinite domains <D> and <E>
  587.     gap> IsSubset( Group( (1,2), (1,2,3,4,5,6) ), D12 );
  588.     true
  589.     gap> IsSubset( D12, [ (), (1,2)(3,4)(5,6) ] );
  590.     false |
  591.  
  592. The default function 'DomainOps.IsSubset' checks whether both domains are
  593. infinite.   If they are it  signals an  error.   Otherwise if the <E>  is
  594. infinite it returns 'false'.  Otherwise if  <D> is infinite it  tests  if
  595. each element of <E>  is  *in* <D>  (see "Membership  Test  for Domains").
  596. Otherwise it tests whether the proper set  of elements of <E> is a subset
  597. of the  proper set of elements of <D> (see "Elements"  and "Set Functions
  598. for Sets").
  599.  
  600. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  601. \Section{Intersection}%
  602. \index{intersection!of domains}
  603.  
  604. 'Intersection( <D1>, <D2>... )' \\
  605. 'Intersection( <list> )'
  606.  
  607. In the first form 'Intersection' returns the  intersection of the domains
  608. <D1>, <D2>, etc.  In the second form <list> must be a list of domains and
  609. 'Intersection' returns the intersection  of those domains.  Each argument
  610. <D> or  element of <list> respectively may  also be an arbitrary list, in
  611. which case 'Intersection' silently applies 'Set' (see "Set") to it first.
  612.  
  613. The result of 'Intersection' is the set of elements  that lie in every of
  614. the domains <D1>, <D2>, etc.  Functions called by the dispatcher function
  615. 'Intersection'  however,  are  encouraged to  keep  as  much structure as
  616. possible.  So if <D1> and  <D2> are elements  of a common category and if
  617. this   category is  closed  under taking  intersections,  then the result
  618. should be a   domain lying  in  this category  too.  So  for  example the
  619. intersection of permutation groups will again be a permutation group.
  620.  
  621. |    gap> Intersection( CyclotomicField(9), CyclotomicField(12) );
  622.     CF(3)    # 'CF' is a shorthand for 'CyclotomicField'
  623.              # this is one of the rare cases where the intersection
  624.              # of two infinite domains works
  625.     gap> Intersection( GaussianIntegers, Rationals );
  626.     Error, sorry, cannot intersect infinite domains <D> and <E>
  627.     gap> Intersection( D12, Group( (1,2), (1,2,3,4,5) ) );
  628.     Group( (1,5)(2,4) )
  629.     gap> Intersection( D12, [ (1,3)(4,6), (1,2)(3,4) ] );
  630.     [ (1,3)(4,6) ]    # note that the second argument is not a set
  631.     gap> Intersection( D12, [ (), (1,2)(3,4), (1,3)(4,6), (1,4)(5,6) ] );
  632.     [ (), (1,3)(4,6) ]    # although the result is mathematically a
  633.                           # group it is returned as a proper set
  634.                           # because the second argument was not a group
  635.     gap> Intersection( [2,4,6,8,10], [3,6,9,12,15], [5,10,15,20,25] );
  636.     [  ]    # two or more domains or sets as arguments are legal
  637.     gap> Intersection( [ [1,2,4], [2,3,4], [1,3,4] ] );
  638.     [ 4 ]    # or a list of domains or sets
  639.     gap> Intersection( [ ] );
  640.     Error, List Element: <list>[1] must have a value |
  641.  
  642. The  dispatcher function  (see "Dispatchers") 'Intersection' is  slightly
  643. different from other  dispatcher functions.  It does  not simply call the
  644. function in the  operations  record passings  its arguments.   Instead it
  645. loops over its arguments  (or the  list of domains or sets) and calls the
  646. function in  the operations record repeatedly,  and passes each time only
  647. two  domains.   This  obviously  makes  writing  the  function   for  the
  648. operations record simpler.
  649.  
  650. The default function 'DomainOps.Intersection' checks whether both domains
  651. are infinite.  If they are it signals an error.  Otherwise, if one of the
  652. domains is infinite it loops over  the elements of  the other domain, and
  653. tests for each element whether it lies in the  infinite domain.   If both
  654. domains are finite  it computes the proper sets  of elements  of both and
  655. intersects them  (see "Elements" and  "Set Functions  for  Sets").   This
  656. default method is  overlaid  by more special  functions  for  most  other
  657. domains.  Those  functions  usually are faster  and keep the structure of
  658. the domains if possible.
  659.  
  660. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  661. \Section{Union}%
  662. \index{union!of domains}
  663.  
  664. 'Union( <D1>, <D2>... )' \\
  665. 'Union( <list> )'
  666.  
  667. In  the first form  'Union' returns the union of  the domains <D1>, <D2>,
  668. etc.  In the second form  <list> must be  a  list of domains and  'Union'
  669. returns the  union of  those domains.   Each argument  <D> or element  of
  670. <list> respectively may also be an  arbitrary list, in which case 'Union'
  671. silently applies 'Set' (see "Set") to it first.
  672.  
  673. The result of 'Union' is the set of elements that lie  in any the domains
  674. <D1>,   <D2>, etc.  Functions called   by the dispatcher function 'Union'
  675. however, are encouraged to keep as much  structure as possible.  However,
  676. currently  {\GAP} does  not  support any  category  that  is closed under
  677. taking unions except the category of all  domains.  So the only case that
  678. structure will be  kept is when  one  argument <D>  or element of  <list>
  679. respectively is a  superset  of all  the other arguments  or elements  of
  680. <list>.
  681.  
  682. |    gap> Union( GaussianIntegers, Rationals );
  683.     Error, sorry, cannot unite <E> with the infinite domain <D>
  684.     gap> Union( D12, Group( (1,2), (1,2,3) ) );
  685.     [ (), (2,3), (2,6)(3,5), (1,2), (1,2)(3,6)(4,5), (1,2,3),
  686.       (1,2,3,4,5,6), (1,3,2), (1,3), (1,3)(4,6), (1,3,5)(2,4,6),
  687.       (1,4)(2,3)(5,6), (1,4)(2,5)(3,6), (1,5)(2,4), (1,5,3)(2,6,4),
  688.       (1,6,5,4,3,2), (1,6)(2,5)(3,4) ]
  689.     gap> Union( [2,4,6,8,10], [3,6,9,12,15], [5,10,15,20,25] );
  690.     [ 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 20, 25 ]
  691.         # two or more domains or sets as arguments are legal
  692.     gap> Union( [ [1,2,4], [2,3,4], [1,3,4] ] );
  693.     [ 1, 2, 3, 4 ]    # or a list of domains or sets
  694.     gap> Union( [ ] );
  695.     [  ] |
  696.  
  697. The dispatcher function (see "Dispatchers") 'Union' is slightly different
  698. from other dispatcher functions.  It does not simply call the function in
  699. the operations record passings its arguments.  Instead it loops over  its
  700. arguments (or the list of domains or sets) and calls the function  in the
  701. operations  record repeatedly,  and  passes each  time only two  domains.
  702. This  obviously makes  writing  the function  for  the  operations record
  703. simpler.
  704.  
  705. The default function 'DomainOps.Union'  checks  whether either domain  is
  706. infinite.  If one is it signals  an error.  If both domains are finite it
  707. computes  the  proper sets  of  elements  of both and  unites  them  (see
  708. "Elements"  and  "Set Functions  for  Sets").   This  default  method  is
  709. overlaid  by  more special  functions  for  some  other  domains.   Those
  710. functions usually are faster.
  711.  
  712. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  713. \Section{Difference}%
  714. \index{set difference!of domains}
  715.  
  716. 'Difference( <D>, <E> )'
  717.  
  718. 'Difference'  returns the  set difference  of  the domains  <D> and  <E>.
  719. Either argument may also be an arbitrary list, in which case 'Difference'
  720. silently applies 'Set' (see "Set") to it first.
  721.  
  722. The result of 'Difference' is the set of elements that lie in <D> but not
  723. in <E>.  Note that <E> need not be a subset of <D>.  The elements of <E>,
  724. however, that are not element of <D> play no role for the result.
  725.  
  726. |    gap> Difference( D12, [(),(1,2,3,4,5,6),(1,3,5)(2,4,6),
  727.     >                    (1,4)(2,5)(3,6),(1,6,5,4,3,2),(1,5,3)(2,6,4)] );
  728.     [ (2,6)(3,5), (1,2)(3,6)(4,5), (1,3)(4,6), (1,4)(2,3)(5,6),
  729.       (1,5)(2,4), (1,6)(2,5)(3,4) ] |
  730.  
  731. The  default  function  'DomainOps.Difference'  checks  whether  <D>   is
  732. infinite.  If it is it signals an error.  Otherwise 'Difference' computes
  733. the  proper sets of elements of <D> and <E> and returns the difference of
  734. those  sets (see "Elements" and "SubtractSet").  This default function is
  735. currently not overlaid for any domain.
  736.  
  737. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  738. \Section{Representative}
  739. \index{representative!of a domain}
  740.  
  741. 'Representative( <D> )'
  742.  
  743. 'Representative' returns a representative of the domain <D>.
  744.  
  745. The existence of  a representative, and the exact  definition of  what  a
  746. representative  is, depends on the category  of  <D>.  The representative
  747. should be an  element that, within a given context, identifies the domain
  748. <D>.  For example if <D> is a cyclic group, its representative would be a
  749. generator of <D>, or if <D> is  a  coset, its representative  would be an
  750. arbitrary element of the coset.
  751.  
  752. Note that 'Representative' is pretty free in choosing a representative if
  753. there are  several.   It is not  even  guaranteed   that 'Representative'
  754. returns the same  representative if it  is called several  times for  one
  755. domain.  Thus  the main difference  between 'Representative' and 'Random'
  756. (see "Random") is that 'Representative' is free to choose a value that is
  757. cheap  to  compute,  while 'Random'   must  make an  effort  to  randomly
  758. distribute its answers.
  759.  
  760. |    gap> C := Coset( Subgroup( G, [(1,4)(2,5)(3,6)] ), (1,6,5,4,3,2) );;
  761.     gap> Representative( C );
  762.     (1,3,5)(2,4,6) |
  763.  
  764. 'Representative'  first tests whether  the component '<D>.representative'
  765. is  bound.  If the  field is bound it  returns its  value.   Otherwise it
  766. calls  '<D>.operations.Representative(  <D>  )',  remembers the  returned
  767. value in '<D>.representative', and returns it.
  768.  
  769. The default function called this way is 'DomainOps.Representative', which
  770. simply signals  an error,  since  there  is  no  default  way  to  find a
  771. representative.
  772.  
  773. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  774. \Section{Random}%
  775. \index{random element!of a domain}
  776.  
  777. 'Random( <D> )'
  778.  
  779. 'Random' returns a random element of the domain <D>.  The distribution of
  780. elements returned  by 'Random'  depends on  the domain  <D>.  For  finite
  781. domains all  elements are usually  equally likely.   For infinite domains
  782. some reasonable  distribution is used.  See the   chapters of the various
  783. domains to find out which distribution is being used.
  784.  
  785. |    gap> Random( GaussianIntegers );
  786.     1-4*E(4)
  787.     gap> Random( GaussianIntegers );
  788.     1+2*E(4)
  789.     gap> Random( D12 );
  790.     ()
  791.     gap> Random( D12 );
  792.     (1,4)(2,5)(3,6) |
  793.  
  794. The default function for random selection  is  'DomainOps.Random',  which
  795. computes  the  set of  elements  using  'Elements'  and selects  a random
  796. element  of  this  list  using  'RandomList'  (see  "RandomList"   for  a
  797. description of the pseudo random  number generator  used).  This  default
  798. function can of course only be applied to finite domains.  It is overlaid
  799. by other functions for most other domains.
  800.  
  801. All random functions called this way rely on  the low level random number
  802. generator provided by 'RandomList' (see "RandomList").
  803.  
  804. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  805. %%
  806. %E  Emacs . . . . . . . . . . . . . . . . . . . . . local Emacs variables
  807. %%
  808. %%  Local Variables:
  809. %%  mode:               outline
  810. %%  outline-regexp:     "\\\\Chapter\\|\\\\Section"
  811. %%  fill-column:        73
  812. %%  eval:               (hide-body)
  813. %%  End:
  814. %%
  815.  
  816.  
  817.  
  818.