Смекни!
smekni.com

Программирование и разработка приложений в Maple (стр. 124 из 135)

Успешный вызов процедуры 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], "&bsol;_$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:&bsol;Archive/Tallinn&bsol;Book/RANS_IAN.m", [f1, f2, M1, f3, M2, f4]); Warning, tools [f1, f2, M1, f3, M2, f4] have been saved in file

<c:&bsol;archive&bsol;tallinn&bsol;book&bsol;rans_ian>

> SaveMP("C:&bsol;Archive/Tallinn&bsol;Book/RANS_IAN", "list");

procedures, [f1, f2, f3, f4], modules, [M1, M2]

> restart; SaveMP("C:&bsol;Archive/Tallinn&bsol;Book/RANS_IAN", [f1, Art_Kr, M1], "load");

Warning, tools {Art_Kr} do not exist in file <C:&bsol;Archive/Tallinn&bsol;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], {"&bsol;" "/", }), assign(' 'b = b[1 .. -2]), NULL)

; for k to length(b) do if member(b[k], {"&bsol;", "/"}) 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, ( &bsol; 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, "&bsol;", 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 &bsol; 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&bsol;

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&bsol;AGN/VSV&bsol;Art/Kr/library", P, M);

> simplel("D:/AVZ&bsol;AGN/VSV&bsol;Art/Kr/library", MkDir, came);

> simplel("D:/AVZ&bsol;AGN/VSV&bsol;Art/Kr/library");

["07.10.2006", [P, Proc], [M, Mod], "07.10.2006", [MkDir, Proc], [came, Proc]]

> restart; read("D:/AVZ&bsol;AGN/VSV&bsol;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&bsol;AGN/VSV&bsol;Art/Kr/library.m");

Error, (in simplel) 1st argument should define a datafile of the input Maple-format, but had received <D:/AVZ&bsol;AGN/VSV&bsol;Art/Kr/library.m> > M1:=module() export Sr; Sr:=() -> `+`(args)/nargs end module: P1:=() -> `*`(args)/`+`(args):

> simplel("D:/AVZ&bsol;AGN/VSV&bsol;Art/Kr/library.m", M1, P1);

Warning, target datafile had been redefined as file <D:/AVZ&bsol;AGN/VSV&bsol;Art/Kr/library> of the input Maple-format

> simplel("D:/AVZ&bsol;AGN/VSV&bsol;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 обрабатывает основные особые и ошибочные ситуации.