Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/GAP/pkg/toolsforhomalg/gap/   (Algebra von RWTH Aachen Version 4.15.1©)  Datei vom 2.4.2025 mit Größe 7 kB image not shown  

Quelle  LazyArrays.gi   Sprache: unbekannt

 
# SPDX-License-Identifier: GPL-2.0-or-later
# ToolsForHomalg: Special methods and knowledge propagation tools
#
# Implementations
#

BindGlobal( "TheFamilyOfLazyArrays",
        NewFamily( "TheFamilyOfLazyArrays" ) );

BindGlobal( "TheTypeLazyArray",
        NewType( TheFamilyOfLazyArrays,
                IsLazyArray ) );

DeclareRepresentation( "IsLazyInterval",
        IsLazyArray,
        [ ] );

DeclareRepresentation( "IsLazyConstantArray",
        IsLazyArray,
        [ ] );

DeclareRepresentation( "IsLazyArrayFromList",
        IsLazyArray,
        [ ] );

BindGlobal( "TheTypeLazyInterval",
        NewType( TheFamilyOfLazyArrays,
                IsLazyInterval ) );

BindGlobal( "TheTypeLazyConstantArray",
        NewType( TheFamilyOfLazyArrays,
                IsLazyConstantArray ) );

BindGlobal( "TheTypeLazyArrayFromList",
        NewType( TheFamilyOfLazyArrays,
                 IsLazyArrayFromList ) );

## never use LazyArrayWithValues in the code since CompilerForCAP
## might identify multiple different (mutable) lists (e.g., empty lists),
## which  should be changed in different ways, and we do not want
## to call ShallowCopy here
InstallGlobalFunction( LazyArrayWithValues,
  function( length, func, values, type )
    
    Assert( 0, IsInt( length ) and length >= 0 );
    Assert( 0, IsFunction( func ) );
    
    return ObjectifyWithAttributes(
                   rec( length := length, func := func, values := values ), type );
    
end );

##
InstallMethod( Length,
        [ IsLazyArray ],
        
  function( L )
    
    return L!.length;
    
end );

##
InstallMethod( ShallowCopy,
        [ IsLazyArray ], 100001,
        
  function( L )
    
    return LazyArrayWithValues( L!.length, L!.func, ShallowCopy( L!.values ), TheTypeLazyArray );
    
end );

##
InstallMethod( Iterator,
        [ IsLazyArray ],
        
  function( L )
    
    return IteratorByFunctions(
             rec(
                 pos := -1,
                 len := L!.length,
                 list := L,
                 NextIterator :=
                 function( iter )
                   iter!.pos := iter!.pos + 1;
                   return iter!.list[iter!.pos];
                 end,
                 IsDoneIterator :=
                   function( iter )
                     return iter!.pos = iter!.len - 1;
                 end,
                 ShallowCopy :=
                   function( iter )
                     return
                       rec( pos := iter!.pos,
                            len := iter!.len,
                            list := iter!.list );
                   end ) );
                   
end );

##
InstallGlobalFunction( LazyArray,
  function( length, func )
    
    return LazyArrayWithValues( length, func, [ ], TheTypeLazyArray );
    
end );

##
InstallGlobalFunction( LazyStandardInterval,
  function( length )
    
    return LazyArrayWithValues( length, IdFunc, [ ], TheTypeLazyInterval );
    
end );

##
InstallGlobalFunction( LazyInterval,
  function( length, start )
    
    return LazyArrayWithValues( length, i -> start + i, [ ], TheTypeLazyInterval );
    
end );

##
InstallGlobalFunction( LazyConstantArray,
  function( length, number )
    
    return LazyArrayWithValues( length, i -> number, [ ], TheTypeLazyConstantArray );
    
end );

##
InstallGlobalFunction( LazyArrayFromList,
  function( L )
    
    L := ShallowCopy( L );
    
    return LazyArrayWithValues( Length( L ), i -> L[1 + i], L, TheTypeLazyArrayFromList );
    
end );

##
InstallMethod( \[\],
        [ IsLazyArray, IsInt ],
        
  function( L, i )
    local values;

    ## do not use IsBound( L[i] ) since this will invoke a function call
    if i < 0 or i >= L!.length then
        Error( "the index ", i, " is not in the valid range [ 0 .. ", L!.length, " - 1 ]" );
    fi;
    
    values := L!.values;
    
    if not IsBound( values[1 + i] ) then
        values[1 + i] := L!.func( i );
    else
        Assert( 4, values[1 + i] = L!.func( i ) );
    fi;
    
    return values[1 + i];
    
end );

##
InstallMethod( ListOfValues,
        [ IsLazyArray ],
        
  function( L )
    
    Perform( [ 0 .. L!.length - 1 ], i -> L[i] );
    
    return L!.values;
    
end );

##
InstallMethod( \=,
        [ IsLazyArray, IsLazyArray ],
        
  function( L1, L2 )
    
    return L1!.length = L2!.length and
           ( IsIdenticalObj( L1!.func, L2!.func ) or
             ForAll( LazyStandardInterval( L1!.length ), i -> L1[i] = L2[i] ) );
    
end );

##
InstallMethod( ListOp,
        [ IsLazyArray, IsFunction ],
        
  function( L, g )
    
    return LazyArray( L!.length, x -> g( L!.func( x ) ) );
    
end );

##
InstallMethod( IsBound\[\],
        [ IsLazyArray, IsInt ],
        
  function( L, i )
    
    if i >= 0 and i < L!.length then
        return true;
    fi;
    
    return false;
    
end );

##
InstallOtherMethod( Unbind\[\],
        [ IsLazyArray, IsInt ],
        
  function( L, i )
    
    Error( "this operation is not permitted for lazy arrays\n" );
    
end );

##
InstallMethod( Position,
        [ IsLazyArray, IsObject, IsInt ],
        
  function( L, o, start )
    
    return First( [ start .. L!.length - 1 ], i -> L[i] = o );
    
end );

##
InstallMethod( \in,
        [ IsObject, IsLazyArray ],
        
  function( o, L )
    
    return IsInt( Position( L, o ) );
    
end );

##
InstallOtherMethod( \[\]\:\=,
        [ IsLazyArray, IsInt, IsObject ],
        
  function( L, i, o )
    
    L!.values[1 + i] := o;
    
    return o;
    
end );

##
InstallMethod( \{\},
        [ IsLazyArray, IsList ], 100001,
        
  function( L, l )
    
    Error( "not implemented yet\n" );
    
end );

##
InstallOtherMethod( \{\}\:\=,
        [ IsLazyArray, IsList, IsList ],
        
  function( L, l, o )
    
    Error( "not implemented yet\n" );
    
end );

##
InstallOtherMethod( Add,
        [ IsLazyArray, IsObject ],
        
  function( L, o )
    local l, func;
    
    l := L!.length;
    
    L!.length := l + 1;
    
    L!.values[L!.length] := o;
    
    func := ShallowCopy( L!.func );
    
    L!.func :=
      function( i )
        if i = l then
            return o;
        else
            return func( i );
        fi;
    end;
    
end );

##
InstallOtherMethod( Append,
        [ IsLazyArray, IsList ],
        
  function( L, l )
    
    Error( "not implemented yet\n" );
    
end );

##
InstallOtherMethod( Append,
        [ IsLazyArray, IsLazyArray ],
        
  function( L1, L2 )
    local l1, func1, func2, i;
    
    l1 := L1!.length;
    
    func1 := ShallowCopy( L1!.func );
    func2 := ShallowCopy( L2!.func );
    
    L1!.length := l1 + L2!.length;
    
    for i in [ 1 .. Length( L2!.values ) ] do
        if IsBound(  L2!.values[i] ) then
            L1!.values[l1 + i] := L2!.values[i];
        fi;
    od;
    
    L1!.func :=
      function( i )
        if i < l1 then
            return func1( i );
        else
            return func2( i - l1 );
        fi;
    end;
    
end );

##
InstallMethod( SSortedList,
        [ IsLazyArray ],
        
  function( L )
    
    return SSortedList( ListOfValues( L ) );
    
end );

##
InstallMethod( ViewObj,
        [ IsLazyArray ],
        
  function( L )
    
    Print( "LazyArray of length ", L!.length, " and evaluated values: " );
    ViewObj( L!.values );
    
end );

##
InstallMethod( PrintObj,
        [ IsLazyArray ],
        
  function( L )
    local values;
    
    values := L!.values;
    
    PrintObj( values );
    
    if not L!.length = Length( values ) then
        Print( ".?."  );
    fi;
    
end );

##
InstallMethod( PrintObj,
        [ IsLazyInterval ],
        
  function( L )
    
    if Length( L ) < 3 then
        PrintObj( ListOfValues( L ) );
    else
        Print( "[ ", L[0], " .. ", L[Length( L ) - 1 ], " ]" );
    fi;
    
end );

##
InstallMethod( PrintObj,
        [ IsLazyConstantArray ],
        
  function( L )
    
    if Length( L ) < 3 then
        PrintObj( ListOfValues( L ) );
    else
        Print( "[ .. ", L[0], " .. ]"  );
    fi;
    
end );

[ Dauer der Verarbeitung: 0.9 Sekunden  (vorverarbeitet)  ]