GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
############################################################################# ## ## IO.gi HomalgToCAS package Mohamed Barakat ## ## Copyright 2007-2009 Lehrstuhl B für Mathematik, RWTH Aachen ## ## Implementation stuff to launch and terminate external CASystems. ## ############################################################################# #################################### # # install global functions: # #################################### ## InstallGlobalFunction( TerminateCAS, function( arg ) local nargs, container, weak_pointers, l, pids, i, R, streams, s; nargs := Length( arg ); if nargs = 0 and IsBound( HOMALG_MATRICES.ContainerForWeakPointersOnHomalgExternalRings ) then container := HOMALG_MATRICES.ContainerForWeakPointersOnHomalgExternalRings; weak_pointers := container!.weak_pointers; l := container!.counter; pids := [ ]; for i in [ 1 .. l ] do R := ElmWPObj( weak_pointers, i ); if R <> fail then Add( pids, homalgExternalCASystemPID( R ) ); fi; od; pids := DuplicateFreeList( pids ); streams := container!.streams; l := Length( streams ); for i in [ 1 .. l ] do if not streams[i].pid in pids then TerminateCAS( streams[i] ); Unbind( streams[i] ); fi; od; ## don't replace the following by DuplicateFreeList since ## it runs into a "no method found"-error when comparing subobjects: pids := [ ]; l := [ ]; for s in streams do if not s.pid in pids then Add( l, s ); Add( pids, s.pid ); fi; od; container!.streams := l; elif nargs > 0 then if IsRecord( arg[1] ) and IsBound( arg[1].lines ) then s := arg[1]; if IsBound( s.TerminateCAS ) and IsFunction( s.TerminateCAS ) then s.TerminateCAS( s ); if IsBound( arg[1].pid ) then Print( "terminated the external CAS ", s.name, " with pid ", s.pid, "\n" ); else Print( "terminated the external CAS ", s.name, "\n" ); fi; else Print( "the stream does not contain a TerminateCAS process\n" ); fi; else TerminateCAS( homalgStream( arg[1] ) ); fi; fi; end ); ## InstallGlobalFunction( LaunchCAS, function( arg ) local nargs, HOMALG_IO_CAS, executables, e, s; nargs := Length( arg ); HOMALG_IO_CAS := arg[1]; if IsString( HOMALG_IO_CAS ) then HOMALG_IO_CAS := ValueGlobal( HOMALG_IO_CAS ); else Error( "for security reasons LaunchCAS only accepts a string (as a first argument) which points to a HOMALG_IO_CAS record\n" ); fi; if IsBound( HOMALG_IO_CAS.LaunchCAS ) then s := CallFuncList( HOMALG_IO_CAS.LaunchCAS, arg ); if s = fail then Error( "the alternative launcher returned fail\n" ); fi; else if LoadPackage( "IO_ForHomalg" ) <> true then Error( "the package IO_ForHomalg failed to load\n" ); fi; s := CallFuncList( LaunchCAS_IO_ForHomalg, Concatenation( [ HOMALG_IO_CAS ], arg{[ 2 .. nargs ]} ) ); fi; for e in NamesOfComponents( HOMALG_IO_CAS ) do if not IsBound( s.( e ) ) then s.( e ) := HOMALG_IO_CAS.( e ); fi; od; if not IsBound( s.variable_name ) then s.variable_name := HOMALG_IO.variable_name; fi; if IsBound( HOMALG_IO.color_display ) and HOMALG_IO.color_display = true and IsBound( s.display_color ) then s.color_display := s.display_color; fi; if IsBound( HOMALG_IO.DeletePeriod ) and ( IsPosInt( HOMALG_IO.DeletePeriod ) or IsBool( HOMALG_IO.DeletePeriod ) ) then s.DeletePeriod := HOMALG_IO.DeletePeriod; fi; s.StatisticsObject := NewStatisticsObject( rec( LookupTable := "HOMALG_IO.Pictograms", summary := rec( HomalgExternalCallCounter := 0, HomalgExternalVariableCounter := 0, HomalgExternalCommandCounter := 0, HomalgExternalOutputCounter := 0, HomalgBackStreamMaximumLength := 0, HomalgExternalWarningsCounter := 0 ) ), TheTypeStatisticsObjectForStreams ); s.homalgExternalObjectsPointingToVariables := ContainerForWeakPointers( TheTypeContainerForWeakPointersOnHomalgExternalObjects ); s.homalgExternalObjectsPointingToVariables!.assignments_pending := [ ]; s.homalgExternalObjectsPointingToVariables!.assignments_failed := [ ]; s.homalgExternalObjectsPointingToVariables!.processes := [ ]; if IsBound( s.InitialSendBlockingToCAS ) then s.InitialSendBlockingToCAS( s, "\n" ); else s.SendBlockingToCAS( s, "\n" ); fi; if ( not ( IsBound( HOMALG_IO.show_banners ) and HOMALG_IO.show_banners = false ) and not ( IsBound( s.show_banner ) and s.show_banner = false ) ) and ( ( IsBound( s.banner ) and ( IsString( s.banner ) or IsFunction( s.banner ) ) ) or Length( s.lines ) > 0 ) then Print( "================================================================\n" ); if IsBound( s.color_display ) then Print( s.color_display ); fi; if IsBound( s.banner ) and IsString( s.banner ) then Print( s.banner ); elif IsBound( s.banner ) and IsFunction( s.banner ) then s.banner( s ); else Print( s.lines ); fi; Print( "\033[0m\n================================================================\n" ); fi; return s; end ); ## InstallGlobalFunction( InitializeMacros, function( macros, stream ) local names, component, macros_names; if not IsRecord( macros ) then Error( "the second argument must be a record\n" ); fi; names := NamesOfComponents( macros ); if IsBound( macros._order ) and IsList( macros._order ) and ForAll( macros._order, IsString ) then names := Concatenation( macros._order, Difference( names, macros._order ) ); fi; macros_names := [ ]; for component in names do if component[1] = '!' then if IsFunction( macros.(component) ) then macros.(component)( stream ); else homalgSendBlocking( macros.(component), "need_command", stream, HOMALG_IO.Pictograms.initialize ); fi; fi; od; for component in names do if not component[1] in [ '_', '!' ] then if component[1] = '$' then homalgSendBlocking( macros.(component), "need_command", stream, HOMALG_IO.Pictograms.initialize ); else homalgSendBlocking( macros.(component), "need_command", stream, HOMALG_IO.Pictograms.define ); Add( macros_names, component ); fi; fi; od; return macros_names; end ); ## InstallGlobalFunction( UpdateMacrosOfCAS, function( macros, CASmacros ) local component; if IsBound( macros._Identifier ) then if IsBound( CASmacros._included_packages ) then if IsBound( CASmacros._included_packages.(macros._Identifier) ) and CASmacros._included_packages.(macros._Identifier) = true then ## get out return; fi; else CASmacros._included_packages := rec( ); fi; fi; CASmacros._included_packages.(macros._Identifier) := true; for component in NamesOfComponents( macros ) do if component[1] <> '_' then CASmacros.(component) := macros.(component); fi; od; end ); ## InstallGlobalFunction( UpdateMacrosOfLaunchedCAS, function( macros, stream ) local send, send_orig; if IsBound( macros._Identifier ) then if IsBound( stream.activated_packages ) then if IsBound( stream.activated_packages.(macros._Identifier) ) and stream.activated_packages.(macros._Identifier) = true then ## get out return; fi; else stream.activated_packages := rec( ); fi; fi; stream.activated_packages.(macros._Identifier) := true; ## save the original stream communicator send := stream!.SendBlockingToCAS; if IsBound( stream!.SendBlockingToCAS_original ) then send_orig := stream!.SendBlockingToCAS_original; else send_orig := send; fi; ## this is a way to avoid branching in the time critical homalgSendBlocking stream!.SendBlockingToCAS := function( arg ) local container, assignments_pending; ## set back the original stream communicator stream!.SendBlockingToCAS := send; ## GAP is wonderful ## save the current pending assignments container := stream.homalgExternalObjectsPointingToVariables; assignments_pending := container!.assignments_pending; container!.assignments_pending := [ ]; ## level 3: print the pictogram only Info( InfoHomalgToCAS, 3, "\033[1;31;40m", "blocked the previous command which will be executed later and\033[0m" ); Info( InfoHomalgToCAS, 3, "\033[1;31;40m", "locked the stream to START initializing the ", macros._Identifier, "-macros\033[0m\n" ); if IsBound( stream.InitializeMacros ) then stream.InitializeMacros( macros, stream ); else InitializeMacros( macros, stream ); fi; Info( InfoHomalgToCAS, 3, "\033[1;32;40mCOMPLETED initializing the ", macros._Identifier, "-macros, unlocked the stream,\033[0m" ); Info( InfoHomalgToCAS, 3, "\033[1;32;40m", "and about to execute the previous command which has been blocked\033[0m\n" ); ## the command in arg might depend on the above initialization ## so do not move this line higher container!.assignments_pending := assignments_pending; CallFuncList( send_orig, arg ); end; end ); ## InstallGlobalFunction( UpdateMacrosOfLaunchedCASs, function( macros ) local name, streams, stream; if not IsBound( macros._CAS_name ) then return; fi; name := macros._CAS_name; if not IsBound( HOMALG_MATRICES.ContainerForWeakPointersOnHomalgExternalRings ) then return; fi; streams := HOMALG_MATRICES.ContainerForWeakPointersOnHomalgExternalRings!.streams; for stream in streams do if IsBound( stream.name ) and stream.name = name then UpdateMacrosOfLaunchedCAS( macros, stream ); fi; od; end );