Skip to content

Commit

Permalink
doc: document IsRangeRep, improve doc of ...
Browse files Browse the repository at this point in the history
... `ConvertToRangeRep`, `IsRange`, and the section `Ranges`.

Documents `IsRangeRep`.

Restructures `ConvertToRangeRep`:
- remove some redundant statements
- move some explanations to the `IsRangeRep` doc

Adds examples to `IsRange` and the info that assigning to a range turns it
into a plain list.

Improves the example in the introduction of the `Ranges` section,
  • Loading branch information
ssiccha committed May 24, 2019
1 parent 4437e09 commit 552d0c5
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 40 deletions.
14 changes: 12 additions & 2 deletions doc/ref/lists.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1738,6 +1738,8 @@ Of course, unless you assign
<C><A>last</A> + <A>second</A> - <A>first</A></C> to the entry
<C><A>range</A>[ Length( <A>range</A> ) + 1 ]</C>,
the resulting list will no longer be a range.
Note that in any case assigning to <A>range</A> will convert it back into
a plain list.
<P/>
<Example><![CDATA[
gap> r := [10..20];
Expand All @@ -1748,8 +1750,15 @@ gap> r[3];
12
gap> 17 in r;
true
gap> r[12] := 25;; r; # r is no longer a range
[ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 25 ]
gap> # r still is a range but is now represented as a plain list
gap> r[1] := 10;; r;
[ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 ]
gap> IsRange(r);
true
gap> # r is no longer a range
gap> r[12] := 25;;
gap> IsRange(r);
false
gap> r := [1,3..17];
[ 1, 3 .. 17 ]
gap> Length( r );
Expand Down Expand Up @@ -1789,6 +1798,7 @@ and also a row vector (see&nbsp;<Ref Chap="Row Vectors"/>),
because it contains no holes and all elements are integers.
<P/>
<#Include Label="IsRange">
<#Include Label="IsRangeRep">
<#Include Label="ConvertToRangeRep">

</Section>
Expand Down
82 changes: 44 additions & 38 deletions lib/list.g
Original file line number Diff line number Diff line change
Expand Up @@ -345,11 +345,12 @@ InstallMethod( ASS_LIST,
## tests if the object <A>obj</A> is a range, i.e. is a dense list of
## integers that is also a range
## (see&nbsp;<Ref Sect="Ranges"/> for a definition of <Q>range</Q>).
## <!-- shouldn't this better be a property?-->
## <Example><![CDATA[
## gap> IsRange( [1,2,3] ); IsRange( [7,5,3,1] );
## true
## true
## gap> IsRange( [1 .. 3] );
## true
## gap> IsRange( [1,2,4,5] ); IsRange( [1,,3,,5,,7] );
## false
## false
Expand All @@ -369,14 +370,40 @@ DeclareCategoryKernel( "IsRange",
##
#R IsRangeRep( <obj> )
##
## <#GAPDoc Label="IsRangeRep">
## <ManSection>
## <Filt Name="IsRangeRep" Arg='obj' Type='Representation'/>
##
## <Description>
## For internally represented ranges, there is a special representation
## which requires only a small amount of memory.
## Tests whether <A>obj</A> is represented as a range,
## that is by internally storing only the first value, the in- or decrement,
## and the last value of the range.
## <P/>
## To test whether a list is an arithmetic pro- or degression in the
## mathematical sense see <Ref Filt="IsRange"/>.
## <P/>
## Lists created by the syntactic construct
## <C>[ <A>first</A>, <A>second</A> .. <A>last</A> ]</C>,
## see <Ref Sect="Ranges"/> , are in <Ref Filt="IsRangeRep"/>.
## <P/>
## Note that if you change <Ref Filt="IsRangeRep"/> object by assignment,
## <Ref Oper="Add"/> or <Ref Oper="Append"/>,
## the range will be converted into a plain list, even if the resulting list
## is still a range.
## <P/>
## <Example><![CDATA[
## gap> IsRangeRep( [1 .. 3] );
## true
## gap> IsRangeRep( [1, 2, 3] );
## false
## gap> l := [1..3];;
## gap> l[1] := 1;;
## gap> l;
## [ 1, 2, 3 ]
## ]]></Example>
## </Description>
## </ManSection>
## <#/GAPDoc>
##
DeclareRepresentationKernel( "IsRangeRep",
IsInternalRep, [], IS_OBJECT, IS_RANGE_REP );
Expand All @@ -392,53 +419,32 @@ DeclareRepresentationKernel( "IsRangeRep",
##
## <Description>
## 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.
## Those lists are represented internally in a compact way,
## namely in <Ref Filt="IsRangeRep"/>, instead of as plain lists.
## A list that is represented as a plain list might still be a
## range but &GAP; may not know this.
## <P/>
## If <A>list</A> is a range then <Ref Func="ConvertToRangeRep"/> changes
## the representation of <A>list</A> to this compact representation.
## <P/>
## This is important since this representation needs only 12 bytes for
## the entire range while the ordinary representation needs <M>4 length</M>
## bytes.
## <P/>
## 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.
## <P/>
## Lists created by the syntactic construct
## <C>[ <A>first</A>, <A>second</A> .. <A>last</A> ]</C> are of course
## known to be ranges and are represented in the compact way.
## <P/>
## If you call <Ref Func="ConvertToRangeRep"/> for a list represented the
## ordinary way that is indeed a range,
## the representation is changed from the ordinary to the compact
## representation.
## the representation of <A>list</A> to <Ref Filt="IsRangeRep"/>.
## A call of <Ref Func="ConvertToRangeRep"/> for a list that is not a range
## is ignored.
## <P/>
## If you change a mutable range that is represented in the compact way,
## by assignment, <Ref Oper="Add"/> or <Ref Oper="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.
## Note that in general it is safer to directly construct <A>list</A> as a
## range via the
## <C>[ <A>first</A>, <A>second</A> .. <A>last</A> ]</C> syntax.
## <P/>
## 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 <Ref Func="ConvertToRangeRep"/> with that list as an
## argument.
## You can think of the call to <Ref Func="ConvertToRangeRep"/> as a hint
## to &GAP; that this list is a proper range.
## Note that if you change a range in <Ref Filt="IsRangeRep"/> by assignment,
## <Ref Oper="Add"/> or <Ref Oper="Append"/>,
## the range will be converted into a plain list, even if the
## resulting list is still a range.
## <P/>
## <Example><![CDATA[
## 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> r[1] := 1;; r;
## [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
## gap> l:= [ 1, 2, 4, 5 ];; ConvertToRangeRep( l ); l;
## [ 1, 2, 4, 5 ]
## ]]></Example>
Expand Down

0 comments on commit 552d0c5

Please sign in to comment.