####################################################################### ## #F MakeHalfInfList( <start>, <direction>, <typeWithArgs>, <callback>, <repeatifyCallback> ) ## ## Creates a IsHalfInfList with start index <start>, <direction> is ## -1 for negative or 1 for positive, <typeWithArgs> is a list of either ## two or three arguments describing the nature of the infinite list ## (see the documentation), and <callback> is a function which is called ## whenever a new list element is computed. ##
InstallGlobalFunction( MakeHalfInfList, function( start, direction, typeWithArgs, callback, repeatifyCallback )
local type, repeatingList, func, initialValue, storeValues, data, list,
repeatify;
type := typeWithArgs[ 1 ]; if type = "next/repeat"then
type := "next";
repeatify := true; else
repeatify := false; fi; if type = "repeat"then
repeatingList := typeWithArgs[ 2 ];
func := fail;
storeValues := false; else
repeatingList := fail;
func := typeWithArgs[ 2 ];
storeValues := true; fi;
initialValue := fail; if type = "next"then
initialValue := typeWithArgs[ 3 ]; elif type = "pos" and Length( typeWithArgs ) = 3then
storeValues := typeWithArgs[ 3 ]; fi;
list := Objectify( NewType( NewFamily( "HalfInfListsFamily" ),
IsHalfInfList and IsHalfInfListDefaultRep ),
data );
return list;
end );
####################################################################### ## #M StartPosition( <list> ) ## ## Returns the start position of a IsHalfInfList <list>. ##
InstallMethod( StartPosition,
[ IsHalfInfList ], function( list )
return list!.start; end );
####################################################################### ## #M Direction( <list> ) ## ## Returns the direction of a IsHalfInfList <list>. ##
InstallMethod( Direction,
[ IsHalfInfList ], function( list )
return list!.direction; end );
####################################################################### ## #M InfListType( <list> ) ## ## Returns the type of a IsHalfInfList <list>. ##
InstallMethod( InfListType,
[ IsHalfInfList ], function( list )
return list!.type; end );
####################################################################### ## #M RepeatingList( <list> ) ## ## Returns the repeatingList of a IsHalfInfList <list>. ##
InstallMethod( RepeatingList,
[ IsHalfInfList ], function( list )
return list!.repeatingList; end );
####################################################################### ## #M ElementFunction( <list> ) ## ## Returns the element-function of a IsHalfInfList <list>. ##
InstallMethod( ElementFunction,
[ IsHalfInfList ], function( list )
return list!.func; end );
####################################################################### ## #M IsStoringValues( <list> ) ## ## Returns the value of the (boolean) storingValues of a ## IsHalfInfList <list>. ##
InstallMethod( IsStoringValues,
[ IsHalfInfList ], function( list )
return list!.storingValues; end );
####################################################################### ## #M NewValueCallback( <list> ) ## ## Returns the callback function of a IsHalfInfList <list>. ##
InstallMethod( NewValueCallback,
[ IsHalfInfList ], function( list )
return list!.callback; end );
####################################################################### ## #M IsRepeating( <list> ) ## ## Returns true if the type of the IsHalfInfList <list> is "repeat", ## false otherwise. ##
InstallMethod( IsRepeating,
[ IsHalfInfList ], function( list )
return list!.type = "repeat"; end );
####################################################################### ## #M InitialValue( <list> ) ## ## Returns the initial value of a IsHalfInfList <list>. ##
InstallMethod( InitialValue,
[ IsHalfInfList ], function( list )
return list!.initialValue; end );
####################################################################### ## #M \^( <list>, <pos> ) ## ## Returns the stored value at index <pos> in the IsHalfInfList ## <list>. ##
InstallMethod( \^,
[ IsHalfInfList and IsHalfInfListDefaultRep, IsInt ], function( list, pos )
local index, i, callCallbackFunction, r;
index := (pos - StartPosition( list )) * Direction( list );
if index < 0then
Error( "illegal half inf list position ", pos, "\n" ); fi;
callCallbackFunction := function( index )
local pos, cb;
pos := StartPosition( list ) + index * Direction( list );
cb := NewValueCallback( list ); if IsFunction( cb ) then
cb( pos, Direction( list ), InfListType( list ) ); fi; end;
if InfListType( list ) = "repeat"then
index := index mod Length( RepeatingList( list ) );
return RepeatingList( list )[ index + 1 ]; elif InfListType( list ) = "next"then if Length( list!.values ) = 0then
list!.values[ 1 ] := ElementFunction( list )( InitialValue( list ) );
callCallbackFunction( 0 ); fi; for i in [ Length( list!.values ) .. index ] do
list!.values[ i + 1 ] := ElementFunction( list )( list!.values[ i ] );
callCallbackFunction( i ); if list!.repeatify and i mod 2 = 0then if list!.values[ i / 2 + 1 ] = list!.values[ i + 1 ] then
r := MakeRepeatingList( list, i / 2 + 1, i + 1 );
list!.repeatifyCallback( r[ 1 ], r[ 2 ] );
list!.repeatify := false;
return r[ 2 ]^pos; fi; fi;
od;
return list!.values[ index + 1 ]; elif InfListType( list ) = "pos"then if IsStoringValues( list ) then for i in [ Length( list!.values ) .. index ] do
list!.values[ i + 1 ]
:= ElementFunction( list )( StartPosition( list )
+ i * Direction( list ) );
callCallbackFunction( i );
od;
return list!.values[ index + 1 ]; else
return ElementFunction( list )( pos ); fi; fi;
end );
InstallMethod( MakeRepeatingList,
[ IsHalfInfList, IsPosInt, IsPosInt ], function( list, collisionIndex1, collisionIndex2 )
local values, i1, i2, i, repeatStartIndex, repeatEndIndex,
tail, repeatedList, newList;
values := list!.values;
i1 := collisionIndex1;
i2 := collisionIndex2; while i1 > 0 and values[ i1 ] = values[ i2 ] do
i1 := i1 - 1;
i2 := i2 - 1;
od;
repeatStartIndex := i1 + 1;
i := repeatStartIndex + 1; while values[ i ] <> values[ repeatStartIndex ] do
i := i + 1;
od;
repeatEndIndex := i - 1;
tail := values{ [ 1 .. ( repeatStartIndex - 1 ) ] }; if Direction( list ) = -1then
tail := Reversed( tail ); fi;
repeatedList := values{ [ repeatStartIndex .. repeatEndIndex ] };
newList := MakeHalfInfList( StartPosition( list ) + ( repeatStartIndex - 1 ) * Direction( list ),
Direction( list ),
[ "repeat", repeatedList ],
false, false );
return [ tail, newList ]; end );
####################################################################### ## #M LowestKnownPosition( <list> ) ## ## Returns the lowest index of the list where the value is known ## without computation. ##
InstallMethod( LowestKnownPosition,
[ IsHalfInfList ], function( list ) if Direction( list ) = 1then if Length( list!.values ) = 0 and InfListType( list ) <> "repeat"then
return "none"; else
return StartPosition( list ); fi; else if InfListType( list ) = "repeat"then
return -infinity; elif Length( list!.values ) = 0 and InfListType( list ) <> "repeat"then
return "none"; else
return StartPosition( list ) - (Length( list!.values ) - 1); fi; fi; end );
####################################################################### ## #M HighestKnownPosition( <list> ) ## ## Returns the highest index of the list where the value is known ## without computation. ##
InstallMethod( HighestKnownPosition,
[ IsHalfInfList ], function( list ) if Direction( list ) = -1then if Length( list!.values ) = 0 and InfListType( list ) <> "repeat"then
return "none"; else
return StartPosition( list ); fi; else if InfListType( list ) = "repeat"then
return infinity; elif Length( list!.values ) = 0 and InfListType( list ) <> "repeat"then
return "none"; else
return StartPosition( list ) + (Length( list!.values ) - 1); fi; fi; end );
####################################################################### ## #F MakeInfList( <basePosition>, <middle>, <positive>, <negative>, ## <callback> ) ## ## Creates an IsInfList object. <basePostition> tells in which index ## the values should be put, <middle> is a list of known values, ## <positive> is a list describing the positive part of the infinite ## list, and <negative> part is a list describing the negative part ## of the list. <callback> is a function to be called whenever a ## new value of the infinite list is computed. ##
InstallGlobalFunction( MakeInfList, function( basePosition, middle, positive, negative, callback )
local list, posList, negList, posRepeatify, negRepeatify;
# TODO: automatic initialValue for "next" parts if middle is nonempty
list := MakeInfListFromHalfInfLists( basePosition, middle, posList, negList );
return list;
end );
####################################################################### ## #F MakeInfListFromHalfInfLists( <basePosition>, <middle>, <positive>, ## <negative> ) ## ## Creates an IsInfList from a middle part (a list) and two IsHalfInfLists ## <positive> and <negative>. ##
InstallGlobalFunction( MakeInfListFromHalfInfLists, function( basePosition, middle, positive, negative )
local list;
if negative <> fail and basePosition <> StartPosition( negative ) + 1then
Error( "negative list starts at incorrect position" ); fi; if positive <> fail and basePosition + Length( middle ) <> StartPosition( positive ) then
Error( "positive list starts at incorrect position" ); fi;
####################################################################### ## #F FunctionInfList( <func> ) ## ## Creates an IsInfList where all list entries are described by a ## function. ##
InstallGlobalFunction( FunctionInfList, function( func )
local positiveNegativeList;
positiveNegativeList := [ "pos", func, false ];
return MakeInfList( 0, [], positiveNegativeList, positiveNegativeList, false ); end );
####################################################################### ## #F ConstantInfList( <value> ) ## ## Creates an IsInfList with <value> in each position. ##
InstallGlobalFunction( ConstantInfList, function( value )
return MakeInfList( 0, [], [ "repeat", [ value ] ], [ "repeat", [ value ] ], false ); end );
####################################################################### ## #F FiniteInfList( <basePosition>, <list> ) ## ## Creates an IsInfList which is finite. Only indexes in the interval ## [basePostition, basePosition + length(<list>) - 1] is allowed. ##
InstallGlobalFunction( FiniteInfList, function( basePosition, list )
return MakeInfListFromHalfInfLists( basePosition, list, fail, fail ); end );
####################################################################### ## #M MiddleStart( <list> ) ## ## Returns the first index of the middle part, or the basePosition, ## of the IsInfList <list>. ##
InstallMethod( MiddleStart,
[ IsInfList ], function( list )
return list!.basePosition; end );
####################################################################### ## #M MiddleEnd( <list> ) ## ## Returns the last index of the middle part of the IsInfList <list>. ##
InstallMethod( MiddleEnd,
[ IsInfList ], function( list )
return list!.basePosition + Length( list!.middle ) - 1; end );
####################################################################### ## #M MiddlePart( <list> ) ## ## Returns the middle part of the IsInfList <list>, as a list. ##
InstallMethod( MiddlePart,
[ IsInfList ], function( list )
return list!.middle; end );
####################################################################### ## #M PositivePart( <list> ) ## ## Returns the positive part of the IsInfList <list>, as an IsHalfInfList. ##
InstallMethod( PositivePart,
[ IsInfList ], function( list )
return list!.positive; end );
####################################################################### ## #M NegativePart( <list> ) ## ## Returns the negative part of the IsInfList <list>, as an IsHalfInfList. ##
InstallMethod( NegativePart,
[ IsInfList ], function( list )
return list!.negative; end );
####################################################################### ## #M LowestKnownPosition( <list> ) ## ## Returns the lowest index where the value of the IsInfList <list> ## is computed or otherwise known. ##
InstallMethod( LowestKnownPosition,
[ IsInfList ], function( list ) if NegativePart( list ) <> fail
and LowestKnownPosition( NegativePart( list ) ) <> "none"then
return LowestKnownPosition( NegativePart( list ) ); elif Length( MiddlePart( list ) ) > 0then
return MiddleStart( list ); else
return LowestKnownPosition( PositivePart( list ) ); fi; end );
####################################################################### ## #M HighestKnownPosition( <list> ) ## ## Returns the highest index where the value of the IsInfList <list> ## is computed or otherwise known. ##
InstallMethod( HighestKnownPosition,
[ IsInfList ], function( list ) if PositivePart( list ) <> fail
and HighestKnownPosition( PositivePart( list ) ) <> "none"then
return HighestKnownPosition( PositivePart( list ) ); elif Length( MiddlePart( list ) ) > 0then
return MiddleEnd( list ); else
return HighestKnownPosition( NegativePart( list ) ); fi; end );
####################################################################### ## #M UpperBound( <list> ) ## ## Returns the highest index where the value of the IsInfList <list> ## exists (but is not necessarily known). ##
InstallMethod( UpperBound,
[ IsInfList ], function( list ) if PositivePart( list ) <> fail then
return infinity; elif Length( MiddlePart( list ) ) > 0then
return MiddleEnd( list ); elif NegativePart( list ) <> fail then
return StartPosition( NegativePart( list ) ); else
return -infinity; fi; end );
####################################################################### ## #M LowerBound( <list> ) ## ## Returns the smallest index where the value of the IsInfList <list> ## exists (but is not necessarily known). ##
InstallMethod( LowerBound,
[ IsInfList ], function( list ) if NegativePart( list ) <> fail then
return -infinity; elif Length( MiddlePart( list ) ) > 0then
return MiddleStart( list ); elif PositivePart( list ) <> fail then
return StartPosition( PositivePart( list ) ); else
return infinity; fi; end );
####################################################################### ## #M \^( <list>, <pos> ) ## ## Returns the value of the IsInfList <list> at the index <pos>. ##
InstallMethod( \^,
[ IsInfList, IsInt ], function( list, pos )
local positive, negative;
positive := PositivePart( list );
negative := NegativePart( list ); if pos >= MiddleStart( list ) and pos <= MiddleEnd( list ) then
return MiddlePart( list )[ pos - MiddleStart( list ) + 1 ]; elif positive <> fail and pos >= StartPosition( positive ) then
return positive^pos; elif negative <> fail and pos <= StartPosition( negative ) then
return negative^pos; else
Error( "position ", pos, " outside index range of inflist ", list, "\n" ); fi; end );
####################################################################### ## #M Shift( <list>, <shift> ) ## ## <list> is an IsHalfInfList. The method shifts the list <shift> ## positions; to the right if <shift> is positive or to the left if ## <shift> is negative. ##
InstallMethod( Shift,
[ IsHalfInfList, IsInt ], function( list, shift )
if IsRepeating( list ) then
return MakeHalfInfList( StartPosition( list ) - shift, Direction( list ),
[ "repeat", RepeatingList( list ) ], false, false ); else
return MakeHalfInfList( StartPosition( list ) - shift, Direction( list ),
[ "pos", i -> list^(i + shift) ], false, false ); fi;
end );
####################################################################### ## #M Shift( <list>, <shift> ) ## ## <list> is an IsInfList. The method shifts the list <shift> ## positions; to the right if <shift> is positive or to the left if ## <shift> is negative. ##
InstallMethod( Shift,
[ IsInfList and IsInfListDefaultRep, IsInt ], function( list, shift )
return MakeInfListFromHalfInfLists
( MiddleStart( list ) - shift,
MiddlePart( list ),
Shift( PositivePart( list ), shift ),
Shift( NegativePart( list ), shift ) ); end );
####################################################################### ## #M FinitePartAsList( <list>, <startPos>, <endPos> ) ## ## <list> is an IsInfList. The part of the list starting at index ## <startPos> and ending at index <endPos> is returned as a list. ## Note that <endPos> > <startPos>. ##
InstallMethod( FinitePartAsList,
[ IsInfList, IsInt, IsInt ], function( list, startPos, endPos )
return List( [ startPos .. endPos ], i -> list^i ); end );
####################################################################### ## #M Cut( <list>, <pos> ) ## ## Returns a new IsHalfInfList which the old IsHalfInfList except ## that the positions with indices smaller than <pos> is removed. ##
InstallMethod( Cut,
[ IsHalfInfList, IsInt ], function( list, pos )
local middle, half, middleLength, middlePositions, newStartPos;
if Direction( list ) = 1 and pos < StartPosition( list )
or Direction( list ) = -1 and pos > StartPosition( list ) then
Error( "position outside range of list" ); fi; if pos = StartPosition( list ) then
middle := [];
half := list; elif InfListType( list ) = "repeat"then
middleLength := ((StartPosition( list ) - pos) * Direction( list ))
mod Length( RepeatingList( list ) ); if Direction( list ) = 1then
middlePositions := [ pos .. pos + middleLength - 1 ]; else
middlePositions := [ pos - middleLength + 1 .. pos ]; fi;
middle := List( middlePositions, i -> list^i );
newStartPos := pos + middleLength * Direction( list );
half := Shift( list, StartPosition( list ) - newStartPos ); else
middle := [];
half := MakeHalfInfList( pos, Direction( list ),
[ "pos", i -> list^i ],
false, false ); fi;
####################################################################### ## #M PositivePartFrom( <list>, <pos> ) ## ## Returns a new IsInfList with only the positions with indices ## greater than or equal to <pos>. ##
InstallMethod( PositivePartFrom,
[ IsInfList, IsInt ], function( list, pos )
local middle, positiveStart;
positiveStart := StartPosition( PositivePart( list ) ); if pos >= positiveStart then
return Cut( PositivePart( list ), pos ); else
middle := FinitePartAsList( list, pos, positiveStart - 1 );
return MakeInfListFromHalfInfLists( pos, middle, PositivePart( list ), fail ); fi;
end );
####################################################################### ## #M NegativePartFrom( <list>, <pos> ) ## ## Returns a new IsInfList with only the positions with indices ## smaller than or equal to <pos>. ##
InstallMethod( NegativePartFrom,
[ IsInfList, IsInt ], function( list, pos )
local middle, negativeStart;
negativeStart := StartPosition( NegativePart( list ) ); if pos <= negativeStart then
return Cut( NegativePart( list ), pos ); else
middle := FinitePartAsList( list, negativeStart + 1, pos );
return MakeInfListFromHalfInfLists( negativeStart + 1, middle, fail,
NegativePart( list ) ); fi;
end );
####################################################################### ## #M Splice( <positiveList>, <negativeList>, <joinPosition> ) ## ## Returns a new IsInfList which is identical to <positiveList> for ## indices greater than <joinPosition> and identical to <negativeList> ## for indices smaller than or equal to <joinPosition>. ##
InstallMethod( Splice,
[ IsInfList, IsInfList, IsInt ], function( positiveList, negativeList, joinPosition )
local positiveCut, negativeCut, middle;
####################################################################### ## #F InfConcatenation( <arg> ) ## ## <arg> is a list of IsInfLists. The method creates a new IsInfList ## where the middle part is the middle parts of the respective lists ## of <arg>, the positive part is the positive part of the first list ## and the negative part is the negative part of the last list. ##
InstallGlobalFunction( InfConcatenation, function( arg )
local middle, basePosition, positive, negative;
####################################################################### ## #M InfList( <list>, <func> ) ## ## <list> is an InfList and <func> is a function which can take ## elements of <list> as argument. The method returns a new list ## where the elements are the elements of <list> with <func> applied ## to them. ##
InstallMethod( InfList,
[ IsInfList, IsFunction ], function( list, func )
return MakeInfListFromHalfInfLists
( MiddleStart( list ),
List( MiddlePart( list ), func ),
HalfInfList( PositivePart( list ), func ),
HalfInfList( NegativePart( list ), func ) );
end );
####################################################################### ## #M HalfInfList( <list>, <func> ) ## ## <list> is a HalfInfList and <func> is a function which can take ## elements of <list> as argument. The method returns a new list ## where the elements are the elements of <list> with <func> applied ## to them. ##
InstallMethod( HalfInfList,
[ IsHalfInfList, IsFunction ], function( list, func )
if IsRepeating( list ) then
return MakeHalfInfList( StartPosition( list ), Direction( list ),
[ "repeat", List( RepeatingList( list ), func ) ],
false, false ); else
return MakeHalfInfList( StartPosition( list ), Direction( list ),
[ "pos", i -> func( list^i ) ],
false, false ); fi;
end );
####################################################################### ## #V IntegersList ## ## An IsInfList with the integer i at position i. ##
BindGlobal( "IntegersList", FunctionInfList( IdFunc ) );
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.31 Sekunden
(vorverarbeitet am 2026-10-13)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.