21.18 Ranges

A range is a dense list of integers in arithmetic progression (or degression). This is a list of integers such that the difference between consecutive elements is a nonzero constant. Ranges can be abbreviated with the syntactic construct [ first, second .. last ] or, if the difference between consecutive elements is 1, as [ first .. last ].

If first > last, [first,second..last] is the empty list, which by definition is also a range. If first = last, [first,second..last] is a singleton list, which is a range, too. Note that last - first must be divisible by the increment second - first, otherwise an error is signalled.

Note that a range is just a special case of a list. Thus you can access elements in a range (see List Elements), test for membership etc. You can even assign to such a range if it is mutable (see List Assignment). Of course, unless you assign last + second-first to the entry range[Length(range)+1], the resulting list will no longer be a range.

gap> r := [10..20];
[ 10 .. 20 ]
gap> Length( r );
11
gap> r[3];
12
gap> 17 in r;
true
gap> r[12] := 25;; r;
[ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 25 ]  # is no longer a range
gap> r := [1,3..17];
[ 1, 3 .. 17 ]
gap> Length( r );
9
gap> r[4];
7
gap> r := [0,-1..-9];
[ 0, -1 .. -9 ]
gap> r[5];
-4
gap> r := [ 1, 4 .. 32 ];
Range: <last>-<first> (31) must be divisible by <inc> (3)

Most often ranges are used in connection with the for-loop (see For). Here the construct

for var in [first..last] do statements od

replaces the

for var from first to last do statements od

which is more usual in other programming languages.

gap> s := [];; for i in [10..20] do Add( s, i^2 ); od; s;
[ 100, 121, 144, 169, 196, 225, 256, 289, 324, 361, 400 ]

Note that a range with last >= first is at the same time also a proper set (see Sorted Lists and Sets), because it contains no holes or duplicates and is sorted, and also a row vector (see Row Vectors), because it contains no holes and all elements are integers.

  • IsRange( obj ) C

    tests if obj is a range.

    gap> IsRange( [1,2,3] );  IsRange( [7,5,3,1] );
    true
    true
    gap> IsRange( [1,2,4,5] );  IsRange( [1,,3,,5,,7] );
    false
    false
    gap> IsRange( [] );  IsRange( [1] );
    true
    true
    

  • ConvertToRangeRep( list ) F

    For some lists the GAP kernel knows that they are in fact ranges. Those lists are represented internally in a compact way instead of the ordinary way.

    If list is a range then ConvertToRangeRep changes the representation of list to this compact representation.

    This is important since this representation needs only 12 bytes for the entire range while the ordinary representation needs 4 length bytes.

    Note that a list that is represented in the ordinary way might still be a range. It is just that GAP does not know this. The following rules tell you under which circumstances a range is represented in the compact way, so you can write your program in such a way that you make best use of this compact representation for ranges.

    Lists created by the syntactic construct [ first, second .. last ] are of course known to be ranges and are represented in the compact way.

    If you call ConvertToRangeRep for a list represented the ordinary way that is indeed a range, the representation is changed from the ordinary to the compact representation. A call of ConvertToRangeRep for a list that is not a range is ignored.

    If you change a mutable range that is represented in the compact way, by assignment, Add or Append, the range will be converted to the ordinary representation, even if the change is such that the resulting list is still a proper range.

    Suppose you have built a proper range in such a way that it is represented in the ordinary way and that you now want to convert it to the compact representation to save space. Then you should call ConvertToRangeRep with that list as an argument. You can think of the call to ConvertToRangeRep as a hint to GAP that this list is a proper range.

    gap> r:= [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];
    [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
    gap> ConvertToRangeRep( r );  r;
    [ 1 .. 10 ]
    gap> l:= [ 1, 2, 4, 5 ];;  ConvertToRangeRep( l );  l;
    [ 1, 2, 4, 5 ]
    

    [Top] [Previous] [Up] [Next] [Index]

    GAP 4 manual
    February 2000