Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
| Download
GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
Project: cocalc-sagemath-dev-slelievre
Views: 418346<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->1<!-- %% -->2<!-- %W lists.tex GAP documentation Thomas Breuer -->3<!-- %W & Frank Celler -->4<!-- %W & Martin Schönert -->5<!-- %W & Heiko Theißen -->6<!-- %% -->7<!-- %H @(#)<M>Id: lists.tex,v 4.34 2002/10/04 12:04:17 gap Exp </M> -->8<!-- %% -->9<!-- %Y Copyright 1997, Lehrstuhl D für Mathematik, RWTH Aachen, Germany -->10<!-- %% -->11<!-- %% This file contains a tutorial introduction to lists and records. -->12<!-- %% -->13<P/>1415<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->16<Chapter Label="Lists and Records">17<Heading>Lists and Records</Heading>1819<Index>arrays, see lists</Index>20Modern mathematics, especially algebra, is based on set theory. When sets21are represented in a computer, they inadvertently turn into lists. That's22why we start our survey of the various objects &GAP; can handle with a23description of lists and their manipulation. &GAP; regards sets as a24special kind of lists, namely as lists without holes or duplicates whose25entries are ordered with respect to the precedence relation <C><</C>.26<P/>27After the introduction of the basic manipulations with lists28in <Ref Sect="Plain Lists"/>,29some difficulties concerning identity and mutability of lists are30discussed in <Ref Sect="Identical Lists"/>31and <Ref Sect="Immutability"/>.32Sets, ranges, row vectors, and matrices are introduced as special kinds33of lists in <Ref Sect="Sets"/>, <Ref Sect="Ranges"/>,34<Ref Sect="Vectors and Matrices"/>.35Handy list operations are shown in <Ref Sect="List Operations"/>.36Finally we explain how to use records in <Ref Sect="Plain Records"/>.373839<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->40<Section Label="Plain Lists">41<Heading>Plain Lists</Heading>4243<Index Subkey="plain">lists</Index>44A <E>list</E> is a collection of objects separated by commas and enclosed in45brackets. Let us for example construct the list <C>primes</C> of the first46ten prime numbers.47<P/>48<Example><![CDATA[49gap> primes:= [2, 3, 5, 7, 11, 13, 17, 19, 23, 29];50[ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29 ]51]]></Example>52<P/>53The next two primes are 31 and 37. They may be appended to the existing54list by the function <C>Append</C> which takes the existing list as its first55and another list as a second argument. The second argument is appended56to the list <C>primes</C> and no value is returned. Note that by appending57another list the object <C>primes</C> is changed.58<P/>59<Example><![CDATA[60gap> Append(primes, [31, 37]);61gap> primes;62[ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37 ]63]]></Example>64<P/>65You can as well add single new elements to existing lists by the function66<C>Add</C> which takes the existing list as its first argument and a new67element as its second argument. The new element is added to the list68<C>primes</C> and again no value is returned but the list <C>primes</C> is changed.69<P/>70<Example><![CDATA[71gap> Add(primes, 41);72gap> primes;73[ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41 ]74]]></Example>75<P/>76Single elements of a list are referred to by their position in the list.77To get the value of the seventh prime, that is the seventh entry in our78list <C>primes</C>, you simply type79<P/>80<Example><![CDATA[81gap> primes[7];821783]]></Example>84<P/>85This value can be handled like any other value, for example multiplied by 286or assigned to a variable. On the other hand this mechanism allows one to87assign a value to a position in a list. So the next prime 43 may be88inserted in the list directly after the last occupied position of89<C>primes</C>. This last occupied position is returned by the function90<C>Length</C>.91<P/>92<Example><![CDATA[93gap> Length(primes);941395gap> primes[14]:= 43;964397gap> primes;98[ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43 ]99]]></Example>100<P/>101Note that this operation again has changed the object <C>primes</C>. The102next position after the end of a list is not the only position capable103of taking a new value. If you know that 71 is the 20th prime, you can104enter it right now in the 20th position of <C>primes</C>. This will result105in a list with holes which is however still a list and now has length10620.107<P/>108<Example><![CDATA[109gap> primes[20]:= 71;11071111gap> primes;112[ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43,,,,,, 71 ]113gap> Length(primes);11420115]]></Example>116<P/>117The list itself however must exist before a value can be assigned to a118position of the list. This list may be the empty list <C>[ ]</C>.119<P/>120<Log><![CDATA[121gap> lll[1]:= 2;122Error, Variable: 'lll' must have a value123124125gap> lll:= []; lll[1]:= 2;126[ ]1272128]]></Log>129<P/>130Of course existing entries of a list can be changed by this mechanism,131too. We will not do it here because <C>primes</C> then may no longer be a list132of primes. Try for yourself to change the 17 in the list into a 9.133<P/>134To get the position of 17 in the list <C>primes</C> use the function135<Ref Func="Position" BookName="ref"/> which takes the list as its136first argument and the element as137its second argument and returns the position of the first occurrence of138the element 17 in the list <C>primes</C>.139If the element is not contained in the list then140<Ref Func="Position" BookName="ref"/> will return the special object141<K>fail</K>.142<P/>143<Example><![CDATA[144gap> Position(primes, 17);1457146gap> Position(primes, 20);147fail148]]></Example>149<P/>150In all of the above changes to the list <C>primes</C>, the list has been151automatically resized. There is no need for you to tell &GAP; how big152you want a list to be. This is all done dynamically.153<P/>154It is not necessary for the objects collected in a list to be of the same155type.156<P/>157<Example><![CDATA[158gap> lll:= [true, "This is a String",,, 3];159[ true, "This is a String",,, 3 ]160]]></Example>161<P/>162In the same way a list may be part of another list.163<P/>164<Example><![CDATA[165gap> lll[3]:= [4,5,6];; lll;166[ true, "This is a String", [ 4, 5, 6 ],, 3 ]167]]></Example>168<P/>169A list may even be part of itself.170<P/>171<Log><![CDATA[172gap> lll[4]:= lll;173[ true, "This is a String", [ 4, 5, 6 ], ~, 3 ]174]]></Log>175<P/>176Now the tilde in the fourth position of <C>lll</C> denotes the object that is177currently printed. Note that the result of the last operation is the178actual value of the object <C>lll</C> on the right hand side of the179assignment. In fact it is identical to the value of the whole list180<C>lll</C> on the left hand side of the assignment.181<P/>182<Index>strings</Index>183<Index Subkey="dense">lists</Index>184A <E>string</E> is a special type of list,185namely a dense list of <E>characters</E>, where <E>dense</E> means that the list has186no holes. Here, <E>characters</E> are special &GAP; objects representing an187element of the character set of the operating system. The input of printable188characters is by enclosing them in single quotes <C>'</C>. A string literal189can either be entered as the list of characters or by writing the characters190between doublequotes <C>"</C>. Strings are handled specially by191<Ref Func="Print" BookName="ref"/>.192You can learn much more about strings in the reference manual.193<P/>194<Example><![CDATA[195gap> s1 := ['H','a','l','l','o',' ','w','o','r','l','d','.'];196"Hallo world."197gap> s1 = "Hallo world.";198true199gap> s1[7];200'w'201]]></Example>202<P/>203Sublists of lists can easily be extracted and assigned using the operator204<C><A>list</A>{ <A>positions</A> }</C>.205<P/>206<Example><![CDATA[207gap> sl := lll{ [ 1, 2, 3 ] };208[ true, "This is a String", [ 4, 5, 6 ] ]209gap> sl{ [ 2, 3 ] } := [ "New String", false ];210[ "New String", false ]211gap> sl;212[ true, "New String", false ]213]]></Example>214<P/>215This way you get a new list whose <M>i</M>-th entry is that element of the216original list whose position is the <M>i</M>-th entry of the argument in the217curly braces.218219</Section>220221222<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->223<Section Label="Identical Lists">224<Heading>Identical Lists</Heading>225226<Index Subkey="identical">lists</Index>227This second section about lists is dedicated to the subtle difference228between <E>equality</E> and <E>identity</E> of lists. It is really important to229understand this difference in order to understand how complex data230structures are realized in &GAP;. This section applies to all &GAP;231objects that have subobjects, e.g., to lists and to records. After232reading the section <Ref Sect="Plain Records"/> about records you should return to233this section and translate it into the record context.234<P/>235Two lists are <E>equal</E> if all their entries are equal. This means that the236equality operator <C>=</C> returns <K>true</K> for the comparison of two lists if237and only if these two lists are of the same length and for each position238the values in the respective lists are equal.239<P/>240<Example><![CDATA[241gap> numbers := primes;; numbers = primes;242true243]]></Example>244<P/>245We assigned the list <C>primes</C> to the variable <C>numbers</C> and, of course246they are equal as they have both the same length and the same entries.247Now we will change the third number to 4 and compare the result again248with <C>primes</C>.249<P/>250<Example><![CDATA[251gap> numbers[3]:= 4;; numbers = primes;252true253]]></Example>254<P/>255You see that <C>numbers</C> and <C>primes</C> are still equal, check this by256printing the value of <C>primes</C>. The list <C>primes</C> is no longer a list of257primes! What has happened? The truth is that the lists <C>primes</C> and258<C>numbers</C> are not only equal but they are also <E>identical</E>. <C>primes</C> and259<C>numbers</C> are two variables pointing to the same list. If you change the260value of the subobject <C>numbers[3]</C> of <C>numbers</C> this will also change261<C>primes</C>. Variables do <E>not</E> point to a certain block of storage memory262but they do point to an object that occupies storage memory. So the263assignment <C>numbers := primes</C> did <E>not</E> create a new list in a different264place of memory but only created the new name <C>numbers</C> for the same old265list of primes.266<P/>267From this we see that <E>the same object can have several names.</E>268<P/>269If you want to change a list with the contents of <C>primes</C> independently270from <C>primes</C> you will have to make a copy of <C>primes</C> by the function271<C>ShallowCopy</C> which takes an object as its argument and returns a copy of272the argument. (We will first restore the old value of <C>primes</C>.)273<P/>274<Example><![CDATA[275gap> primes[3]:= 5;; primes;276[ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43,,,,,, 71 ]277gap> numbers:= ShallowCopy(primes);; numbers = primes;278true279gap> numbers[3]:= 4;; numbers = primes;280false281]]></Example>282<P/>283Now <C>numbers</C> is no longer equal to <C>primes</C> and <C>primes</C> still is a list284of primes. Check this by printing the values of <C>numbers</C> and <C>primes</C>.285<P/>286Lists and records can be changed this way because &GAP; objects of these287types have subobjects.288To clarify this statement consider the following assignments.289<P/>290<Example><![CDATA[291gap> i:= 1;; j:= i;; i:= i+1;;292]]></Example>293<P/>294By adding 1 to <C>i</C> the value of <C>i</C> has changed. What happens to <C>j</C>?295After the second statement <C>j</C> points to the same object as <C>i</C>, namely296to the integer 1. The addition does <E>not</E> change the object <C>1</C> but297creates a new object according to the instruction <C>i+1</C>. It is actually298the assignment that changes the value of <C>i</C>. Therefore <C>j</C> still points299to the object <C>1</C>. Integers (like permutations and booleans) have no300subobjects. Objects of these types cannot be changed but can only be301replaced by other objects. And a replacement does not change the values302of other variables. In the above example an assignment of a new value to303the variable <C>numbers</C> would also not change the value of <C>primes</C>.304<P/>305Finally try the following examples and explain the results.306<P/>307<Log><![CDATA[308gap> l:= [];; l:= [l];309[ [ ] ]310gap> l[1]:= l;311[ ~ ]312]]></Log>313<P/>314Now return to Section <Ref Sect="Plain Lists"/> and find out whether315the functions <Ref Func="Add" BookName="ref"/> and316<Ref Func="Append" BookName="ref"/> change their arguments.317318</Section>319320321<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->322<Section Label="Immutability">323<Heading>Immutability</Heading>324325&GAP; has a mechanism that protects lists against changes like the ones326that have bothered us in Section <Ref Sect="Identical Lists"/>.327The function <Ref Func="Immutable" BookName="ref"/> takes as argument a list328and returns an immutable copy of it,329i.e., a list which looks exactly like the old one, but has two extra330properties:331(1) The new list is immutable, i.e., the list itself and its subobjects332cannot be changed.333(2) In constructing the copy, every part of the list that can be changed334has been copied, so that changes to the old list will not affect the335new one. In other words, the new list has no mutable subobjects in336common with the old list.337<P/>338<Log><![CDATA[339gap> list := [ 1, 2, "three", [ 4 ] ];; copy := Immutable( list );;340gap> list[3][5] := 'w';; list; copy;341[ 1, 2, "threw", [ 4 ] ]342[ 1, 2, "three", [ 4 ] ]343gap> copy[3][5] := 'w';344Lists Assignment: <list> must be a mutable list345not in any function346Entering break read-eval-print loop ...347you can 'quit;' to quit to outer loop, or348you can 'return;' and ignore the assignment to continue349brk> quit;350]]></Log>351<P/>352As a consequence of these rules, in the immutable copy of a list which353contains an already immutable list as subobject, this immutable subobject354need not be copied, because it is unchangeable. Immutable lists are355useful in many complex &GAP; objects, for example as generator lists of356groups. By making them immutable, &GAP; ensures that no generators can357be added to the list, removed or exchanged. Such changes would of course358lead to serious inconsistencies with other knowledge that may already359have been calculated for the group.360<P/>361A converse function to <Ref Func="Immutable" BookName="ref"/> is362<Ref Func="ShallowCopy" BookName="ref"/>, which produces a363new mutable list whose <M>i</M>-th entry is the <M>i</M>-th entry of the old364list. The single entries are not copied, they are just placed in the365new list. If the old list is immutable, and hence the list entries366are immutable themselves,367the result of <Ref Func="ShallowCopy" BookName="ref"/> is mutable only368on the top level.369<P/>370It should be noted that also other objects than lists can appear in371mutable or immutable form.372Records (see Section <Ref Sect="Plain Records"/>) provide another example.373374</Section>375376377<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->378<Section Label="Sets">379<Heading>Sets</Heading>380381<Index Subkey="strictly sorted">lists</Index>382<Index>family</Index>383&GAP; knows several special kinds of lists. A <E>set</E> in &GAP; is a384list that contains no holes (such a list is called <E>dense</E>) and whose385elements are strictly sorted w.r.t. <C><</C>; in particular, a set cannot386contain duplicates. (More precisely, the elements of a set in &GAP;387are required to lie in the same <E>family</E>, but roughly this means that388they can be compared using the <C><</C> operator.)389<P/>390This provides a natural model for mathematical sets whose elements are391given by an explicit enumeration.392<P/>393&GAP; also calls a set a <E>strictly sorted list</E>,394and the function <Ref Func="IsSSortedList" BookName="ref"/> tests395whether a given list is a set. It returns a396boolean value. For almost any list whose elements are contained in397the same family, there exists a corresponding set. This set is398constructed by the function <Ref Func="Set" BookName="ref"/>399which takes the list as its argument400and returns a set obtained from this list by ignoring holes and401duplicates and by sorting the elements.402<P/>403The elements of the sets used in the examples of this section are404strings.405<P/>406<Example><![CDATA[407gap> fruits:= ["apple", "strawberry", "cherry", "plum"];408[ "apple", "strawberry", "cherry", "plum" ]409gap> IsSSortedList(fruits);410false411gap> fruits:= Set(fruits);412[ "apple", "cherry", "plum", "strawberry" ]413]]></Example>414<P/>415Note that the original list <C>fruits</C> is not changed by the function416<Ref Func="Set" BookName="ref"/>.417We have to make a new assignment to the variable <C>fruits</C> in418order to make it a set.419<P/>420The operator <K>in</K> is used to test whether an object is an element of a421set. It returns a boolean value <K>true</K> or <K>false</K>.422<P/>423<Example><![CDATA[424gap> "apple" in fruits;425true426gap> "banana" in fruits;427false428]]></Example>429<P/>430The operator <K>in</K> can also be applied to ordinary lists. It is however431much faster to perform a membership test for sets since sets are432always sorted and a binary search can be used instead of a linear433search. New elements may be added to a set by the function434<Ref Func="AddSet" BookName="ref"/>435which takes the set <C>fruits</C> as its first argument and an element as436its second argument and adds the element to the set if it wasn't437already there. Note that the object <C>fruits</C> is changed.438<P/>439<Example><![CDATA[440gap> AddSet(fruits, "banana");441gap> fruits; # The banana is inserted in the right place.442[ "apple", "banana", "cherry", "plum", "strawberry" ]443gap> AddSet(fruits, "apple");444gap> fruits; # fruits has not changed.445[ "apple", "banana", "cherry", "plum", "strawberry" ]446]]></Example>447<P/>448Note that inserting new elements into a set with449<Ref Func="AddSet" BookName="ref"/> is usually more450expensive than simply adding new elements at the end of a list.451<P/>452Sets can be intersected by the function453<Ref Func="Intersection" BookName="ref"/> and united by the454function <Ref Func="Union" BookName="ref"/> which both take two sets455as their arguments and return456the intersection resp. union of the two sets as a new object.457<P/>458<Example><![CDATA[459gap> breakfast:= ["tea", "apple", "egg"];460[ "tea", "apple", "egg" ]461gap> Intersection(breakfast, fruits);462[ "apple" ]463]]></Example>464<P/>465The arguments of the functions <Ref Func="Intersection" BookName="ref"/>466and <Ref Func="Union" BookName="ref"/> could be467ordinary lists, while their result is always a set. Note that in the468preceding example at least one argument of469<Ref Func="Intersection" BookName="ref"/> was not a set.470The functions <Ref Func="IntersectSet" BookName="ref"/> and471<Ref Func="UniteSet" BookName="ref"/> also form the472intersection resp. union of two sets. They will however not return the473result but change their first argument to be the result. Try them474carefully.475476</Section>477478479<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->480<Section Label="Ranges">481<Heading>Ranges</Heading>482483A <E>range</E> is a finite arithmetic progression of integers. This is another484special kind of list. A range is described by the first two values and the last485value of the arithmetic progression which are given in the form486<C>[<A>first</A>,<A>second</A>..<A>last</A>]</C>.487In the usual case of an ascending list of488consecutive integers the second entry may be omitted.489<P/>490<Example><![CDATA[491gap> [1..999999]; # a range of almost a million numbers492[ 1 .. 999999 ]493gap> [1, 2..999999]; # this is equivalent494[ 1 .. 999999 ]495gap> [1, 3..999999]; # here the step is 2496[ 1, 3 .. 999999 ]497gap> Length( last );498500000499gap> [ 999999, 999997 .. 1 ];500[ 999999, 999997 .. 1 ]501]]></Example>502<P/>503This compact printed representation of a fairly long list corresponds to504a compact internal representation.505The function <Ref Func="IsRange" BookName="ref"/> tests506whether an object is a range,507the function <Ref Func="ConvertToRangeRep" BookName="ref"/> changes508the representation of a list509that is in fact a range to this compact internal representation.510<P/>511<Example><![CDATA[512gap> a:= [-2,-1,0,1,2,3,4,5];513[ -2, -1, 0, 1, 2, 3, 4, 5 ]514gap> IsRange( a );515true516gap> ConvertToRangeRep( a );; a;517[ -2 .. 5 ]518gap> a[1]:= 0;; IsRange( a );519false520]]></Example>521<P/>522Note that this change of representation does <E>not</E> change the value of523the list <C>a</C>. The list <C>a</C> still behaves in any context in the same way524as it would have in the long representation.525526</Section>527528529<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->530<Section Label="For and While Loops">531<Heading>For and While Loops</Heading>532533<Index Key="loops" Subkey="for">loop</Index>534<Index Key="loops" Subkey="while">loop</Index>535<P/>536Given a list <C>pp</C> of permutations we can form their product by means of a537<K>for</K> loop instead of writing down the product explicitly.538<P/>539<Example><![CDATA[540gap> pp:= [ (1,3,2,6,8)(4,5,9), (1,6)(2,7,8), (1,5,7)(2,3,8,6),541> (1,8,9)(2,3,5,6,4), (1,9,8,6,3,4,7,2)];;542gap> prod:= ();543()544gap> for p in pp do545> prod:= prod*p;546> od;547gap> prod;548(1,8,4,2,3,6,5,9)549]]></Example>550<P/>551First a new variable <C>prod</C> is initialized to the identity permutation552<C>()</C>. Then the loop variable <C>p</C> takes as its value one permutation after553the other from the list <C>pp</C> and is multiplied with the present value of554<C>prod</C> resulting in a new value which is then assigned to <C>prod</C>.555<P/>556The <K>for</K> loop has the following syntax557<P/>558<K>for</K> <A>var</A> <K>in</K> <A>list</A> <K>do</K> <A>statements</A> <K>od</K><C>;</C>559<P/>560The effect of the <K>for</K> loop is to execute the <A>statements</A> for every561element of the <A>list</A>. A <K>for</K> loop is a statement and therefore562terminated by a semicolon. The list of <A>statements</A> is enclosed by the563keywords <K>do</K> and <K>od</K> (reverse <K>do</K>). A <K>for</K> loop returns no value.564Therefore we had to ask explicitly for the value of <C>prod</C> in the565preceding example.566<P/>567The <K>for</K> loop can loop over any kind of list, even a list with holes.568In many programming languages the <K>for</K> loop has the form569<P/>570<C>for <A>var</A> from <A>first</A> to <A>last</A> do <A>statements</A> od;</C>571<P/>572In &GAP; this is merely a special case of the general <K>for</K> loop as defined573above where the <A>list</A> in the loop body is a range (see <Ref Sect="Ranges"/>):574<P/>575<K>for</K> <A>var</A> <K>in</K> <C>[<A>first</A>..<A>last</A>]</C> <K>do</K> <A>statements</A> <K>od</K><C>;</C>576<P/>577You can for instance loop over a range to compute the factorial <M>15!</M>578of the number <M>15</M> in the following way.579<P/>580<Example><![CDATA[581gap> ff:= 1;5821583gap> for i in [1..15] do584> ff:= ff * i;585> od;586gap> ff;5871307674368000588]]></Example>589<P/>590The <K>while</K> loop has the following syntax591<P/>592<K>while</K> <A>condition</A> <K>do</K> <A>statements</A> <K>od</K><C>;</C>593<P/>594The <K>while</K> loop loops over the <A>statements</A> as long as the595<A>condition</A> evaluates to <K>true</K>. Like the <K>for</K> loop the <K>while</K> loop596is terminated by the keyword <K>od</K> followed by a semicolon.597<P/>598We can use our list <C>primes</C> to perform a very simple factorization. We599begin by initializing a list <C>factors</C> to the empty list. In this list600we want to collect the prime factors of the number 1333. Remember that a601list has to exist before any values can be assigned to positions of the602list. Then we will loop over the list <C>primes</C> and test for each prime603whether it divides the number. If it does we will divide the number by604that prime, add it to the list <C>factors</C> and continue.605<P/>606<Example><![CDATA[607gap> n:= 1333;;608gap> factors:= [];;609gap> for p in primes do610> while n mod p = 0 do611> n:= n/p;612> Add(factors, p);613> od;614> od;615gap> factors;616[ 31, 43 ]617gap> n;6181619]]></Example>620<P/>621As <C>n</C> now has the value 1 all prime factors of 1333 have been found and622<C>factors</C> contains a complete factorization of 1333. This can of course623be verified by multiplying 31 and 43.624<P/>625This loop may be applied to arbitrary numbers in order to find prime626factors. But as <C>primes</C> is not a complete list of all primes this loop627may fail to find all prime factors of a number greater than 2000, say.628You can try to improve it in such a way that new primes are added to the629list <C>primes</C> if needed.630<P/>631You have already seen that list objects may be changed. This of632course also holds for the list in a loop body. In most cases you have to be633careful not to change this list, but there are situations where this is634quite useful. The following example shows a quick way to determine the635primes smaller than 1000 by a sieve method. Here we will make use of the636function <C>Unbind</C> to delete entries from a list, and the <C>if</C>637statement covered in <Ref Sect="If Statements"/>.638<P/>639<Example><![CDATA[640gap> primes:= [];;641gap> numbers:= [2..1000];;642gap> for p in numbers do643> Add(primes, p);644> for n in numbers do645> if n mod p = 0 then646> Unbind(numbers[n-1]);647> fi;648> od;649> od;650]]></Example>651<P/>652The inner loop removes all entries from <C>numbers</C> that are divisible by653the last detected prime <C>p</C>. This is done by the function <C>Unbind</C> which654deletes the binding of the list position <C>numbers[n-1]</C> to the value <C>n</C>655so that afterwards <C>numbers[n-1]</C> no longer has an assigned value. The656next element encountered in <C>numbers</C> by the outer loop necessarily is657the next prime.658<P/>659In a similar way it is possible to enlarge the list which is looped over.660This yields a nice and short orbit algorithm for the action of a group,661for example.662<P/>663More about <K>for</K> and <K>while</K> loops can be found in the664sections <Ref Sect="While" BookName="ref"/> and <Ref Sect="For" BookName="ref"/>.665666</Section>667668669<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->670<Section Label="List Operations">671<Heading>List Operations</Heading>672673There is a more comfortable way than that given in the previous section to674compute the product of a list of numbers or permutations.675<P/>676<Example><![CDATA[677gap> Product([1..15]);6781307674368000679gap> Product(pp);680(1,8,4,2,3,6,5,9)681]]></Example>682<P/>683The function <Ref Func="Product" BookName="ref"/> takes a list684as its argument and computes the685product of the elements of the list. This is possible whenever a686multiplication of the elements of the list is defined.687So <Ref Func="Product" BookName="ref"/>688executes a loop over all elements of the list.689<P/>690There are other often used loops available as functions.691Guess what the function <Ref Func="Sum" BookName="ref"/> does.692The function <Ref Func="List" BookName="ref"/> may take a list and a function693as its arguments. It will then apply the function to each element of the694list and return the corresponding list of results. A list of cubes is695produced as follows with the function <C>cubed</C> from696Section <Ref Chap="Functions"/>.697<P/>698<Example><![CDATA[699gap> cubed:= x -> x^3;;700gap> List([2..10], cubed);701[ 8, 27, 64, 125, 216, 343, 512, 729, 1000 ]702]]></Example>703<P/>704To add all these cubes we might apply the function705<Ref Func="Sum" BookName="ref"/> to the last list.706But we may as well give the function <C>cubed</C> to707<Ref Func="Sum" BookName="ref"/> as an additional argument.708<P/>709<Example><![CDATA[710gap> Sum(last) = Sum([2..10], cubed);711true712]]></Example>713<P/>714The primes less than 30 can be retrieved out of the list <C>primes</C> from715Section <Ref Sect="Plain Lists"/> by the function716<Ref Func="Filtered" BookName="ref"/>. This function takes the717list <C>primes</C> and a property as its arguments and will return the list of718those elements of <C>primes</C> which have this property. Such a property will719be represented by a function that returns a boolean value. In this720example the property of being less than 30 can be represented by the721function <C>x -> x < 30</C> since <C>x < 30</C> will evaluate to <K>true</K> for722values <C>x</C> less than 30 and to <K>false</K> otherwise.723<P/>724<Example><![CDATA[725gap> Filtered(primes, x -> x < 30);726[ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29 ]727]]></Example>728<P/>729We have already mentioned the operator <C>{ }</C> that forms sublists. It730takes a list of positions as its argument and will return the list of731elements from the original list corresponding to these positions.732<P/>733<Example><![CDATA[734gap> primes{ [1 .. 10] };735[ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29 ]736]]></Example>737<P/>738Finally we mention the function <Ref Func="ForAll" BookName="ref"/>739that checks whether a property740holds for all elements of a list. It takes as its arguments a list and a741function that returns a boolean value.742<Ref Func="ForAll" BookName="ref"/> checks whether the743function returns <K>true</K> for all elements of the list.744<P/>745<Example><![CDATA[746gap> list:= [ 1, 2, 3, 4 ];;747gap> ForAll( list, x -> x > 0 );748true749gap> ForAll( list, x -> x in primes );750false751]]></Example>752<P/>753You will find more predefined <K>for</K> loops in754chapter <Ref Chap="Lists" BookName="ref"/>.755756</Section>757758759<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->760<Section Label="Vectors and Matrices">761<Heading>Vectors and Matrices</Heading>762763<Index Subkey="row">vectors</Index>764<Index>matrices</Index>765This section describes how &GAP; uses lists to represent row vectors and766matrices. A <E>row vector</E> is a dense list of elements from a common field.767A <E>matrix</E> is a dense list of row vectors over a common field and of768equal length.769<P/>770<Example><![CDATA[771gap> v:= [3, 6, 2, 5/2];; IsRowVector(v);772true773]]></Example>774<P/>775Row vectors may be added and multiplied by scalars from their field.776Multiplication of row vectors of equal length results in their scalar777product.778<P/>779<Example><![CDATA[780gap> 2 * v; v * 1/3;781[ 6, 12, 4, 5 ]782[ 1, 2, 2/3, 5/6 ]783gap> v * v; # the scalar product of `v' with itself784221/4785]]></Example>786<P/>787Note that the expression <C>v * 1/3</C> is actually evaluated by first788multiplying <C>v</C> by 1 (which yields again <C>v</C>) and by then dividing by 3.789This is also an allowed scalar operation. The expression <C>v/3</C> would790result in the same value.791<P/>792Such arithmetical operations (if the results are again vectors)793result in <E>mutable</E> vectors except if the operation is binary794and both operands are immutable;795thus the vectors shown in the examples above are all mutable.796<P/>797So if you want to produce a mutable list with 100 entries equal to 25,798you can simply say <C>25 + 0 * [ 1 .. 100 ]</C>.799Note that ranges are also vectors (over the rationals),800and that <C>[ 1 .. 100 ]</C> is mutable.801<P/>802A matrix is a dense list of row vectors of equal length.803<P/>804<Example><![CDATA[805gap> m:= [[1,-1, 1],806> [2, 0,-1],807> [1, 1, 1]];808[ [ 1, -1, 1 ], [ 2, 0, -1 ], [ 1, 1, 1 ] ]809gap> m[2][1];8102811]]></Example>812<P/>813Syntactically a matrix is a list of lists. So the number 2 in the second814row and the first column of the matrix <C>m</C> is referred to as the first815element of the second element of the list <C>m</C> via <C>m[2][1]</C>.816<P/>817A matrix may be multiplied by scalars, row vectors and other matrices.818(If the row vectors and matrices involved in such a multiplication do not819have suitable dimensions then the <Q>missing</Q> entries are treated as zeros,820so the results may look unexpectedly in such cases.)821<P/>822<Example><![CDATA[823gap> [1, 0, 0] * m;824[ 1, -1, 1 ]825gap> [1, 0, 0, 2] * m;826[ 1, -1, 1 ]827gap> m * [1, 0, 0];828[ 1, 2, 1 ]829gap> m * [1, 0, 0, 2];830[ 1, 2, 1 ]831]]></Example>832<P/>833Note that multiplication of a row vector with a matrix will result in a834linear combination of the rows of the matrix, while multiplication of a835matrix with a row vector results in a linear combination of the columns836of the matrix. In the latter case the row vector is considered as a837column vector.838<P/>839A vector or matrix of integers can also be multiplied840with a finite field scalar and vice versa.841Such products result in a matrix over the finite field with the integers842mapped into the finite field in the obvious way.843Finite field matrices are nicer to read when they are <C>Display</C>ed rather844than <C>Print</C>ed.845(Here we write <C>Z(q)</C> to denote a primitive root of the finite field846with <C>q</C> elements.)847<P/>848<Example><![CDATA[849gap> Display( m * One( GF(5) ) );8501 4 18512 . 48521 1 1853gap> Display( m^2 * Z(2) + m * Z(4) );854z = Z(4)855z^1 z^1 z^28561 1 z^2857z^1 z^1 z^2858]]></Example>859<P/>860Submatrices can easily be extracted using the expression861<C><A>mat</A>{<A>rows</A>}{<A>columns</A>}</C>. They can also be assigned to, provided862the big matrix is mutable (which it is not if it is the result of an863arithmetical operation, see above).864<P/>865<Example><![CDATA[866gap> sm := m{ [ 1, 2 ] }{ [ 2, 3 ] };867[ [ -1, 1 ], [ 0, -1 ] ]868gap> sm{ [ 1, 2 ] }{ [2] } := [[-2],[0]];; sm;869[ [ -1, -2 ], [ 0, 0 ] ]870]]></Example>871<P/>872The first curly brackets contain the selection of rows,873the second that of columns.874<P/>875Matrices appear not only in linear algebra, but also as group elements,876provided they are invertible.877Here we have the opportunity to meet a group-theoretical function,878namely <Ref Func="Order" BookName="ref"/>,879which computes the order of a group element.880<P/>881<Example><![CDATA[882gap> Order( m * One( GF(5) ) );8838884gap> Order( m );885infinity886]]></Example>887<P/>888For matrices whose entries are more complex objects, for example rational889functions, &GAP;'s <Ref Func="Order" BookName="ref"/> methods might not be890able to prove that the891matrix has infinite order, and one gets the following warning.892<Log><![CDATA[893#I Order: warning, order of <mat> might be infinite894]]></Log>895In such a case, if the order of the matrix really is infinite, you will896have to interrupt &GAP; by pressing <C><A>ctl</A>-C</C> (followed by <C><A>ctl</A>-D</C> or897<C>quit;</C> to leave the break loop).898<P/>899To prove that the order of <C>m</C> is infinite, we also could look at the900minimal polynomial of <C>m</C> over the rationals.901<P/>902<Example><![CDATA[903gap> f:= MinimalPolynomial( Rationals, m );; Factors( f );904[ x_1-2, x_1^2+3 ]905]]></Example>906<P/>907<Ref Func="Factors" BookName="ref"/> returns a list of irreducible factors908of the polynomial <C>f</C>.909The first irreducible factor <M>X-2</M> reveals that 2 is an eigenvalue of910<C>m</C>, hence its order cannot be finite.911912</Section>913914915<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->916<Section Label="Plain Records">917<Heading>Plain Records</Heading>918919A record provides another way to build new data structures. Like a list920a record contains subobjects.921In a record the elements, the so-called <E>record components</E>,922are not indexed by numbers but by names.923<P/>924In this section you will see how to define and how to use records.925Records are changed by assignments to record components926or by unbinding record components.927<P/>928Initially a record is defined as a comma separated list of assignments to929its record components.930<P/>931<Example><![CDATA[932gap> date:= rec(year:= 1997,933> month:= "Jul",934> day:= 14);935rec( day := 14, month := "Jul", year := 1997 )936]]></Example>937<P/>938The value of a record component is accessible by the record name and the939record component name separated by one dot as the record component940selector.941<P/>942<Example><![CDATA[943gap> date.year;9441997945]]></Example>946<P/>947Assignments to new record components are possible in the same way. The948record is automatically resized to hold the new component.949<P/>950<Example><![CDATA[951gap> date.time:= rec(hour:= 19, minute:= 23, second:= 12);952rec( hour := 19, minute := 23, second := 12 )953gap> date;954rec( day := 14, month := "Jul",955time := rec( hour := 19, minute := 23, second := 12 ), year := 1997 )956]]></Example>957<P/>958Records are objects that may be changed. An assignment to a record959component changes the original object.960The remarks made in Sections <Ref Sect="Identical Lists"/> and <Ref Sect="Immutability"/>961about identity and mutability of lists are also true for records.962<P/>963Sometimes it is interesting to know which components of a certain record964are bound. This information is available from the function965<Ref Func="RecNames" BookName="ref"/>,966which takes a record as its argument and returns a list of names of967all bound components of this record as a list of strings.968<P/>969<Example><![CDATA[970gap> RecNames(date);971[ "time", "year", "month", "day" ]972]]></Example>973<P/>974Now return to Sections <Ref Sect="Identical Lists"/> and <Ref Sect="Immutability"/> and find out975what these sections mean for records.976977</Section>978979980<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->981<Section Label="Further Information about Lists">982<Heading>Further Information about Lists</Heading>983984(The following cross-references point to the &GAP; Reference Manual.)985<P/>986<!-- % In this chapter you have encountered the fundamental concept of a list. -->987<!-- % You have seen how to construct lists, how to extend them and how to refer -->988<!-- % to single elements of a list. -->989<!-- % Moreover you have seen that lists may contain elements of different -->990<!-- % types, even holes (unbound entries), -->991<!-- % and that a list may be an entry of itself or of one of its entries. -->992<!-- % -->993<!-- % You have seen the difference between equal lists and identical lists. -->994<!-- % Since lists are objects that have subobjects, they can be mutable or -->995<!-- % immutable, and mutable lists can be changed. -->996<!-- % Changing an object will change the values of all variables that point to -->997<!-- % that object. -->998<!-- % Be careful, since one object can have several names. -->999<!-- % The function <C>ShallowCopy</C> creates a shallow copy of a list which is then -->1000<!-- % a new object. -->1001<!-- % -->1002You will find more about lists, sets, and ranges in Chapter <Ref Chap="Lists" BookName="ref"/>,1003in particular more about identical lists in Section <Ref Sect="Identical Lists" BookName="ref"/>.1004<!-- % -->1005<!-- % You have seen that sets are a special kind of list. -->1006<!-- % There are functions to expand sets, intersect or unite sets, and there is -->1007<!-- % the membership test with the <C>in</C> operator. -->1008<!-- % Sets are described in more detail in Chapter <Ref Sect="Sets" BookName="ref"/>. -->1009<!-- % -->1010<!-- % You have seen that finite arithmetic progressions of integers can be -->1011<!-- % represented in a compact way as ranges. -->1012<!-- % Chapter <Ref Sect="Ranges" BookName="ref"/> contains a detailed description of ranges. -->1013<!-- % -->1014A more detailed description of strings is contained in1015Chapter <Ref Chap="Strings and Characters" BookName="ref"/>.1016<!-- % -->1017<!-- % You have met row vectors and matrices as special lists, -->1018<!-- % and you have seen how to refer to entries of a matrix and how to multiply -->1019<!-- % scalars, row vectors, and matrices. -->1020<!-- % -->1021Fields are described in Chapter <Ref Chap="Fields and Division Rings" BookName="ref"/>,1022some known fields in &GAP; are described in Chapters <Ref Chap="Rational Numbers" BookName="ref"/>,1023<Ref Chap="Abelian Number Fields" BookName="ref"/>,1024and <Ref Chap="Finite Fields" BookName="ref"/>.1025Row vectors and matrices are described in more detail in Chapters <Ref Chap="Row Vectors" BookName="ref"/>1026and <Ref Chap="Matrices" BookName="ref"/>.1027Vector spaces are described in Chapter <Ref Chap="Vector Spaces" BookName="ref"/>,1028further matrix related structures are described in Chapters <Ref Chap="Matrix Groups" BookName="ref"/>,1029<Ref Chap="Algebras" BookName="ref"/>,1030and <Ref Chap="Lie Algebras" BookName="ref"/>.1031<!-- % -->1032<!-- % You have learned how to loop over a list by the <K>for</K> loop and how to -->1033<!-- % loop with respect to a logical condition with the <K>while</K> loop. -->1034<!-- % You have seen that even the list in the loop body can be changed. -->1035<P/>1036<!-- % -->1037<!-- % You have seen some functions which implement often used <K>for</K> loops. -->1038<!-- % There are functions like <C>Product</C> to form the product of the elements of -->1039<!-- % a list. -->1040<!-- % The function <C>List</C> can apply a function to all elements of a list -->1041<!-- % and the function <C>Filtered</C> creates a sublist of a given list. -->1042You will find more list operations in Chapter <Ref Chap="Lists" BookName="ref"/>.1043<P/>1044Records and functions for records are described in detail1045in Chapter <Ref Chap="Records" BookName="ref"/>.10461047</Section>1048</Chapter>10491050<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->1051<!-- %% -->1052<!-- %E -->1053105410551056