Успешный вызов процедуры SaveMP(F, M) обеспечивает сохранение в файле F средств
(процедур и/или программных модулей), чьи имена задаются списком либо множеством M. Сохранение средств производится в режиме дописывания (APPEND) с выводом соответствующего сообщения. Тогда как вызов SaveMP(F, "list") обеспечивает возврат имен содержащихся в файле F средств с индикацией их типов, как показывает пример ниже.
SaveMP := proc(F::string, M::{set, list, string, set(`module`), list(`module`)}) local d k n m h p t v G z u S Kr Art q r f, , , , , , , , , , , , , , , , , ω, g; `if`( not type( ,F 'file') and args 2[ ] = "list" or not type( ,F 'file') and nargs = 3 and args 3[ ] = "load", ERROR "file <%1> does not exist",( F), `if`(type(F, 'file'), assign(f = F), assign(f = pathtf(F)))); if args 2[ ] = "list" or nargs = 3 and args 3[ ] = "load" then assign(u = [ ], z = [ ], S = "" ;) do assign(' 'h = iolib 2,( f)); if h = 0 then break else `if`(h = "#AVZ_AGN_2003;", [assign(' 'h = readline( )f ), assign(' 'n = searchtext " := ",( h)), `if`(h[n + 4 .. n + 9] = "proc (", assign(' 'u = [op(u), convert(h[1 .. n − 1], 'symbol')]), `if`( h[n + 4 .. n + 12] = "module ()", assign('z' = [op(z), convert(h[1 .. n − 1], 'symbol')]), NULL))], 1) end if end do; g := cat([libname][1][1 .. 2], "\_$Art16_Kr9$_" ;) if args 2[ ] = "list"then RETURN fclose( )( f , `if`(z = [ ] and u = [ ], WARNING("file <%1> does not contain a software", f), `if`(u = [ ], op [( 'modules z', ]), `if`(z = [ ], op(['procedures u', ]), op [( 'procedures u', , 'modules z', ]))))) else assign(' 'q = {op(M)} minus ({op( )z , op(u)} intersect{op(M)})), `if`( q = { }, NULL, WARNING "tools %1 do not exist in file <%2>", ,( q f)); assign(' 'z = {op( )z , op(u)} minus {op(M)}); seq(assign(' 'S = cat(S, z k[ ], ":='", z k[ ], "':")), k = 1 .. nops( )z ); (proc(a b, ) read f; writebytes(a, b); fclose(a); read a; delf(a) end proc )(g S, ), assign(' 'r = {op(M)} minus q), RETURN WARNING(( "tools %1 have been activated", r)) end if else Art := proc( )S local a, b, c, p; [assign(' 'a = S, ' 'b = Search(S, ":= module")), `if`(nops(b) = 1, RETURN(S), assign(' 'b = b[2 .. -1])), seq([ assign(' 'c = searchtext "()",( a, p .. length(a)) + p), `if`( a[p + 8 .. c − 1] = " ", ``, assign('a' = cat(a[1 .. p + 8], a[c − 1 .. length(a)])))], p = b), a][2] end proc end if; `if`(f[-2 .. -1] = ".m" assign67(, ω = f[1 .. -3], delf( )f ), assign(ω = f)), fopen(ω, 'APPEND'); |
for v to nops(M) do assign(' 'n = length cat(( "unprotect('", M v[ ], "'); ")), ' 't = length(M v[ ]), ' 'm = length cat(( "", M v[ ], ":-")), ' 'h = length cat(( " protect('", M v[ ], "');")) + 2); (proc( )x save ,x g end proc )(M v[ ]), assign(' 'G = readbytes(g, 'TEXT', ∞)); `if`(type(M[v], `module`), [`if`(search(G, cat("unprotect('", M[v], "'); ")), assign(' 'G = G[n + 1 .. −h]), G), assign(' 'z = Search(G, cat "",( M v[ ], ":-"))), `if`(z ≠ [ ], [ assign('Kr' = G[1 .. z[1] − 1]), seq( assign('Kr' = cat(Kr, G[z k[ ] + m .. z[k + 1] − 1])), k = 1 .. nops( )z − 1) , assign('Kr' = cat(Kr, G[z[-1] + m .. length(G)]))], assign('Kr' = G)), assign(' 'd = Search(Kr, cat " ",( M v[ ], " "))), `if`(d = [ ], assign(' 'd = "a"), assign(' 'd = op(d)))], assign('Kr' = G)), delf(g), writeline(ω, "#AVZ_AGN_2003;" `if`(, whattype eval(( M v[ ])) ≠ `module` Kr, , `if`(d ≠ "a", Art(cat(Kr[1 .. d − 1], Kr[d + t + 1 .. -1])), Kr))), `if`( not (v = nops(M)), ,0 RETURN( WARNING("tools %1 have been saved in file <%2>", M, ω), close(ω))) end do end proc > f1:=() -> `+`(args)/nargs: f2:=()->add(args[k]^2,k=1..nargs)/nargs: f3:=()->[`+`(args), nargs]: f4:=()->`*`(args)/nargs^2: M1:=module() export Sr; option package; Sr:=()->`+`(args)/nargs end module: module M2() export Kr; option package; Kr:=()-> `*`(args)/nargs end module: > SaveMP("C:\Archive/Tallinn\Book/RANS_IAN.m", [f1, f2, M1, f3, M2, f4]); Warning, tools [f1, f2, M1, f3, M2, f4] have been saved in file <c:\archive\tallinn\book\rans_ian> > SaveMP("C:\Archive/Tallinn\Book/RANS_IAN", "list"); procedures, [f1, f2, f3, f4], modules, [M1, M2] > restart; SaveMP("C:\Archive/Tallinn\Book/RANS_IAN", [f1, Art_Kr, M1], "load"); Warning, tools {Art_Kr} do not exist in file <C:\Archive/Tallinn\Book/RANS_IAN> Warning, tools {f1, M1} have been activated |
Наконец, вызов процедуры SaveMP(F, M, "load") обеспечивает загрузку в текущий сеанс средств файла F, чьи имена определены списком/множеством М. Детальнее с процедурой можно ознакомиться в [41,103]. Данная процедура успешно использовалась для создания простых и эффективных библиотек (архивного уровня) пользователя.
Сохраняя процедуры и программные модули по save-предложению в файлах входного Maple-формата, мы, тем самым, создаем своего рода их простейшие библиотеки, средства которых загружаются в текущий сеанс по read-предложению и сразу же становятся доступными подобно стандартным средствам пакета. Недостатком такой библиотечной организации (наряду с некоторыми другими) является то, что каждое новое обновление входящего в такую библиотеку средства требует обновления всей библиотеки. Поэтому в рамках подобного подхода можно предложить процедуру simplel, полезую в целом ряде приложений. Вызов процедуры simplel(L {, N1, N2, …, Nk}) допускает один или более фактических аргументов, где первый L-аргумент определяет полный путь к файлу входного Maple-формата с сохраняемыми или сохраненными средствам (процедурами и/или программными модулями). Вызов процедуры simplel(L) возвращает список (определяющий содержимое файла, созданного ранее simplel-процедурой) следующего формата:
[<Д1>, [P1, Proc], [M1, Mod], [P2, Proc], [M2, Mod], …, [<Д2>, [PP1, Proc], [MM1, Mod], [PP2,
Proc], [MM2, Mod], …]
где Дj – определяют дату сохранения следующих за ней программных средств, тогда как следующие за ней (до следующей даты, если таковая имеется) 2-элементные подсписки определяют имена и типы сохраненных в файле L программных средств: Proc – процедура и Mod – программный модуль. При попытке загрузить файл, не созданный simplel-процедурой, инициируется ошибочная ситуация с возвратом соответствующей диагностики.
Успешный вызов процедуры simplel(L,N1,N2,…,Nk) возвращает NULL-значение, сохраняя в файле L объекты (процедуры и/или программные модули), имена которых определены фактическими аргументами, начиная со второго. При этом, предварительно определения сохраняемых объектов должны быть вычислены, в противном случае они не сохраняются.
simplel := proc(L::{symbol, string}) local a b c f mkf, , , , ; mkf := proc(f::{symbol string, }) local a b c d cc, , , , ; cc := proc(d::{symbol string, }) local a, b, c, k; assign(a = [ ], b = "" || d, c = 1), `if`( member(b[-1], {"\" "/", }), assign(' 'b = b[1 .. -2]), NULL) ; for k to length(b) do if member(b[k], {"\", "/"}) then a := [op(a), b[c .. k − 1]]; c := k + 1 end if end do; [op(a), b[c .. -1]] end proc ; assign(b = "" || f), `if`(length(b) ≤ 3 or b[2] ≠ ":" ERROR "argume, ( \ nt should be by full path to datafile, but had received <%1>", ),f [assign(' 'b = cc f( )[1 .. -2]), assign(c = b[1])]); try assign ' ',( d fopen ,(f 'READ'), close( )f ), "" || f catch "file or directory does not exist": for a from 2 to nops(b) do c := cat(c, "\", b a[ ]); try mkdir( )c catch "directory exists and is not empty": next end try end do; assign ' ',( d fopen ,(f 'WRITE'), close( )f ), "" || f end try end proc ; |
if nargs = 1 and "" || L[-2 .. -1] = ".m" then error "1st argument should define \ a datafile of the input Maple-format, but had received <%1>", L elif nargs ≠ 1 and "" || L[-2 .. -1] = ".m" then f := "" || L[1 .. -3]; WARNING("target datafile had been redefined as file <%1> of the input\ Maple-format", f) else f := L end if; if nargs = 1 then try open ,(f 'READ'), close( )f , assign(a = [ ], c = 17) catch "file or directory does not exist": error "library <%1> does not exist", f end try ; if readline( )f ≠ "`Software database simplel`:"then close( )f ; error "datafile <%1> had been not created by procedure simplel", f end if; do c := readline( )f ; if c = 0 then close( )f ; break elif c[1] = """ then a := [op(a), c[2 .. -3]] else search(c, ":=" ' ', b ); if type(b, 'symbol') then next else a := [op(a), [`` || c[1 .. b − 1], `if`(c[b + 3 .. b + 6] = "proc", 'Proc', 'Mod')]]; unassign ' '( b ) end if end if end do; a else fopen(mkf f( ), 'APPEND'), writeline ,(f "`Software database simplel`:"), writeline ,(f """ || [ssystem "date /T"( )][1][2][1 .. -3] || """ ":" ; || ) seq `if` type(( ( args[ ]k , {`module`, 'procedure'}), writeline(f, "" || args[k] || ":= " || (convert(eval(args[k]), 'string')) || ":"), NULL), k = 2 .. nargs); close( )f end if end proc > M:=module() export Sr; Sr:= () -> `+`(args)/nargs end module: P:= () -> `*`(args)/`+`(args): > simplel("D:/AVZ\AGN/VSV\Art/Kr/library", P, M); > simplel("D:/AVZ\AGN/VSV\Art/Kr/library", MkDir, came); |
> simplel("D:/AVZ\AGN/VSV\Art/Kr/library"); ["07.10.2006", [P, Proc], [M, Mod], "07.10.2006", [MkDir, Proc], [came, Proc]] > restart; read("D:/AVZ\AGN/VSV\Art/Kr/library"); > eval(P), eval(M), P(42, 47, 67, 89, 96), M:- Sr(64, 59, 39, 10, 17, 44); `*`(args) 1130012352 233 ( ) → , module() export Sr; end module, ,`+` args( ) 341 6 > simplel("D:/AVZ\AGN/VSV\Art/Kr/library.m"); Error, (in simplel) 1st argument should define a datafile of the input Maple-format, but had received <D:/AVZ\AGN/VSV\Art/Kr/library.m> > M1:=module() export Sr; Sr:=() -> `+`(args)/nargs end module: P1:=() -> `*`(args)/`+`(args): > simplel("D:/AVZ\AGN/VSV\Art/Kr/library.m", M1, P1); Warning, target datafile had been redefined as file <D:/AVZ\AGN/VSV\Art/Kr/library> of the input Maple-format > simplel("D:/AVZ\AGN/VSV\Art/Kr/library"); ["07.10.2006", [P, Proc], [M, Mod], "07.10.2006", [MkDir, Proc], [came, Proc], "07.10.2006", [M1, Mod], [P1, Proc]] > simplel("C:/Temp/avz.cmd"); Error, (in simplel) datafile <C:/Temp/avz.cmd> had been not created by procedure simplel |
Сохранение объектов производится в режиме дописывания (APPEND), позволяя сохранять (архивировать) все версии средств с индикацией дат их сохранения. При этом, при последующей загрузке файла L активируются в текущем сеансе только последние сохраненные версии объектов. Процедура позволяет создавать библиотечный файл L в цепочке каталогов любого уровня вложенности, что обеспечивает ее подпроцедура mkf. Процедура simplel обрабатывает основные особые и ошибочные ситуации.