

helpman := proc (
R::symbol, L::{string , symbol}, N::{string , symbol, dir, list({string , symbol})}) local k, a, b, c, d, f, g, h, p, n, m;
global libname;
`if`( not member(R, {'display', 'delete', 'insert '}), ERROR("the 1st argume\
nt should be {insert, display, delete}, but has received <%1> , R), `if`( Path(L) = Path(cat(CDM( ), "\LIB")) and R ≠ 'display',
ERROR("access prohibition to the main Maple library" ), `if`(
not type(L, 'dir'), ERROR("path to library <%1> does not exist" , L), assign(c = cat(L, "\maple.txt" ), d = cat(L, "\maple.hdb" )))));
if not type(d, 'file') then
WARNING(
"Help database for library <%1> does not exist; it has been created" , L);
if N = [ ] then writeline(c, "Empty Help database for your library" ),
close(c), makehelp(Empty, ``|| c, ``|| L), fremove(c), RETURN( WARNING(
"Empty Help database for library <%1> has been created" , L))
else writeline(c, ""), close(c), makehelp(Empty, ``|| c, ``|| L), fremove(c), procname(args)
end if end if ;
if R = 'display' then
if type(N, 'symbol') then return eval((proc () libname := libname, L;
parse(cat("INTERFACE_HELP('display','topic'= , convert(N, 'string1 '), ")"))
end proc )( ))
else error "third argument should has type 'symbol', but has received t \ ype <%1>", whattype(N)
end if end if ;
if R = 'delete' then
if type(N, 'symbol') then return (proc (N, L)
eval(parse(cat("INTERFACE_HELP('delete', 'topic'=",
convert(N, 'string1 '), ",'library'="", convert(L, 'string '), "")")))
end proc )(N, L)
else error "third argument %1 is invalid", [N] end if
end if ;
`if`(R = 'insert ' and nargs = 4 and type(N, 'list'({'symbol', 'string '})) and type(args[4], 'list'({'symbol', 'string '})), `if`(nops(N) = nops(args[4]), assign('b' = 14), ERROR(
"mismatching of quantities of names and mws-files: %1<>%2" , nops(N), nops(args[4]))), NULL );
261

if b = 14 then
for k to nops(N) do
try makehelp(convert(N[k], 'symbol'), convert(args[4][k], 'symbol'), convert(L, 'symbol'))
catch "file or directory does not exist":
WARNING("file <%1> does not exist, the operation with it \ has been ignored", args[4][k]);
next
catch "file or directory, %1, does not exist":
WARNING("file <%1> does not exist, the operation with it \
has been ignored" , args[4][k]);
next end try
end do ;
RETURN(WARNING("Work has been done!" ))
elif R = 'insert ' and type(N, 'dir') then
[assign(n = [ ], m = [ ]), writeto(f), Dir(N), writeto('terminal')]; do
h := readline(f);
if h = 0 then fremove(f); break
else
h := SLD(h, " ");
`if`(cat("aaa", h[-1])[-4 .. -1] = ".mws", assign('p' = [op(p), h[-1]]), NULL )
end if
end do end if ;
if p ≠ [ ] then
for k to nops(p) do
n := [op(n), p[k][1 .. -5]]; m := [op(m), cat(Path(N), "\", p[k])]
end do ;
RETURN(procname(R, L, n, m)) else RETURN(
WARNING("mws-files have not been saved in Help database" )) end if ;
WARNING("Work has not been done, mistakes at the call encoding: %1 , 'procname(args)')
end proc
>helpman(insert, "С:\\program files/maple 8/LIB/userlib", ["DoF1"], ["С:\\temp/dof1.mws"]);
#вставка справочного раздела по процедуре DoF1 в справочную базу библиотеки UserLib Warning, Work has been done!
>helpman(insert, "C:/Program Files/maple 8/LIB/UserLib", ["AFdes", `a,b`], ["C:\\Temp\\AFdes.mws", "C:\\Temp/RANS\\IAN\\a,b.mws"]);
Warning, file <C:/Temp/RANS\IAN/a,b.mws> does not exist, the operation with it has been ignored
Warning, Work has been done!
262

> helpman(insert, "С:/program files/maple 8/LIB/userlib", "С:/temp\\"); # вставка справочного
раздела в справочную базу библиотеки UserLib на основе mws-файлов каталога “C:\\Temp” Warning, Work has been done!
> helpman(display, "С:\\program files\\maple 8/LIB/userlib", "AFdes"); # вывод справочного раздела по процедуре AFdes
> helpman(delete, libname[1], Art_Kr); # удаление справочного раздела Art_Kr из справочной базы библиотеки, путь к которой находится в начале цепочки библиотек libname-переменной
Выше представлен исходный текст процедуры и примеры ее применения. Именно данной процедуре, зарекомендовавшей свои эксплуатационные качества, мы отдаем предпочтение при работу со справочными базами своих Maple-библиотек.
Таким образом, нами представлены достаточно простые пути создания и основных функций ведения пользовательских библиотек, аналогичных главной Maple-библиотеке. Для резюмирования рассмотренного материала создадим на его основе простую процедуру, обеспечивающую базовые функции ведения пользовательских библиотек указанного типа.
Процедура ulibrary имеет два формальных аргумента, но допускает любое число дополнительных в зависимости от значения первого О-аргумента, получающего значения из диапазона 1..10 и определяющего тип запроса на обработку библиотеки, определенной именем или полным путем к ней L. Аргумент О определяет следующие типы обработки библиотеки L:
1 – создание новой библиотеки, определенной L-аргументом; может определяться именем или полным путем, во втором случае допускается любой уровень вложенности каталогов
2 – сохранение в библиотеке L объектов с именами, определяемыми фактическими аргументами, начиная с 3-го; неопределенное имя в библиотеке не сохраняется
3 – удаление из библиотеки L объектов с именами, определяемыми фактическими аргументами, начиная с 3-го
4 – упаковка библиотеки L после удаления из нее ненужных объектов 5 – возврат списка объектов, содержащихся в библиотеке L
6 – создание пустой справочной базы для библиотеки L
7 – обновление справочной базы библиотеки L новой страницей (разделом); все аргументы при вызове процедуры должны иметь symbol-тип; обновление производится на основе mws-фай- ла, находящегося по адресу, указанному четвертым фактическим аргументом, тогда как третий фактический аргумент определяет имя сохраняемой страницы (раздела)
8 – удаление из справочной базы библиотеки L страницы (раздела), указанной третьим фактическим аргументом; этот аргумент при вызове процедуры должен иметь symbol-тип;
9 – вывод на экран справки по странице (разделу) справочной базы библиотеки L с именем, определяемым третьим фактическим аргументом; при этом, производится логическое сцепление библиотеки L с главной Maple-библиотекой при наименьшем приоритете первой
10 – создание логического сцепления библиотеки L с главной Maple-библиотекой; данное сцепление действует до переопределения libname-переменной, до restart-предложения или до перезагрузки пакета. Вызов процедуры возвращает текущее состояние libname-переменной.
Ниже представлен исходный текст процедуры и примеры ее применения на все случаи:
> ulibrary:= proc(O::{1,2,3,4,5,6,7,8,9,10}, L::{symbol, string}) local a, b, c, mkdir1; global libname; mkdir1:= proc(L::{string, symbol}) local a, b, c; assign(a = "", b = ""), [seq(`if`(c = "\\" or c = "/", assign(('a') = cat(a, "\",\"")), assign(('a') = cat(a,c))), c = cat("",L))]; for c in parse(cat("[\"", a, "\"]")) while true do b := cat(b,c,"\\"); try mkdir(b) catch "directory exists and is not empty": next catch "file I/O error": next catch "permission denied": next end try end do end proc;
if O = 1 then mkdir1(L); march('create', L, `if`(nargs = 3 and type(args[3], 'posint'), args[3], 65)); WARNING("library <%1> has been created", L)
elif O = 2 then assign('savelibname' = L), savelib(`if`(nargs = 2, ERROR("no names specified to save"), args[3..-1])); WARNING("names %1 have been saved in library <%2>", [args[3 .. -1]], L)
263

elif O = 3 then march('delete',L,`if`(nargs=2, ERROR("no names specified to delete"), args[3..- 1])); WARNING("names %1 have been deleted out of library <%2>",[args[3..-1]], L)
elif O = 4 then march('pack', L); WARNING("library <%1> has been packed", L) elif O = 5 then WARNING("content of library <%1> is:", L); march('list', L)
elif O = 6 then WARNING("Help database for library <%1> has been created", L); INTERFACE_HELP('insert', topic = "UserLib", text = TEXT("The help on my means located in UserLib. The library has been created 5.10.2006"), library = L);
elif O = 7 then makehelp(`if`(nargs = 4 and map(type, {args[3..4]}, 'symbol') = {true}, args[3..4], ERROR("3rd and 4th arguments should have symbol-type and represent topic name and mwsfile accordingly")), L); WARNING("topic <%1> had been added to the help database of library <%2>", args[3], L)
elif O = 8 then INTERFACE_HELP('delete',topic=`if`(nargs=3 and type(args[3], 'symbol'), args[3], ERROR("topic specified to delete is missing")), library = L);
elif O = 9 then libname:= libname, L; INTERFACE_HELP('display', topic = `if`(nargs = 3 and type(args[3], 'symbol'), args[3], ERROR("topic specified to display is missing")));
elif O = 10 then libname:= libname, L; WARNING("library <%1> has been logically connected with main Maple-library", L); libname
end if end proc;
ulibrary := proc (O::{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, L::{string , symbol}) local a, b, c, mkdir1;
global libname;
mkdir1 := proc (L::{string , symbol}) local a, b, c;
assign(a = "", b = ""), [seq(`if`(c = "\" or c = "/", assign('a' = cat(a, "","")), assign('a' = cat(a, c))), c = cat("", L))];
for c in parse(cat("["", a, ""]")) do b := cat(b, c, "\");
try mkdir(b)
catch "directory exists and is not empty" : next catch "file I/O error": next
catch "permission denied": next end try
end do end proc ;
if O = 1 then mkdir1(L);
march('create', L, `if`(nargs = 3 and type(args[3], 'posint '), args[3], 65))
;
WARNING("library <%1> has been created", L) elif O = 2 then
assign('savelibname' = L), savelib(
`if`(nargs = 2, ERROR("no names specified to save" ), args[3 .. -1]))
264

;
WARNING("names %1 have been saved in library <%2>" , [args[3 .. -1]],
L) elif O = 3 then
march('delete', L, `if`(nargs = 2, ERROR("no names specified to delete" ),
args[3 .. -1]));
WARNING("names %1 have been deleted out of library <%2>" , [args[3 .. -1]], L)
elif O = 4 then
march('pack', L); WARNING("library <%1> has been packed", L)
elif O = 5 then WARNING("content of library <%1> is:" , L); march('list', L) elif O = 6 then
WARNING("Help database for library <%1> has been created" , L); INTERFACE_HELP('insert ', topic = "UserLib", text = TEXT("The he\
lp on my means located in UserLib. The library has been created \
5.10.2006"), library = L) elif O = 7 then
makehelp(`if`(
nargs = 4 and map(type, {args[3 .. 4]}, 'symbol') = {true }, args[3 .. 4], ERROR("3rd and 4th arguments should have symbo \
l-type and represent topic name and mws-file accordingly )), L); WARNING(
"topic <%1> had been added to the help database of library <%2>" , args[3], L)
elif O = 8 then INTERFACE_HELP('delete', topic = `if`(
nargs = 3 and type(args[3], 'symbol'), args[3],
ERROR("topic specified to delete is missing" )), library = L) elif O = 9 then
libname := libname, L; INTERFACE_HELP('display', topic = `if`(
nargs = 3 and type(args[3], 'symbol'), args[3], ERROR("topic specified to display is missing" )))
elif O = 10 then
libname := libname, L;
WARNING("library <%1> has been logically connected with main M\
aple-library", L); libname
end if end proc
>P:= () -> `+`(args)/nargs: P1:= () -> `*`(args): M:= module() export x; x:=() -> `+`(args) end module:
>ulibrary(1, `C:/AVZ/AGN\\VSV/Art\\Kr`);
Warning, library <C:/AVZ/AGN\VSV/Art\Kr> has been created
>ulibrary(2, `C:/AVZ/AGN\\VSV/Art\\Kr`);
Error, (in ulibrary) no names specified to save
>ulibrary(2, `C:/AVZ/AGN\\VSV/Art\\Kr`, P, P1, M, Sv);
Warning, names [P, P1, M, Sv] have been saved in library <C:/AVZ/AGN\VSV/Art\Kr>
265

> ulibrary(5, `C:/AVZ/AGN\\VSV/Art\\Kr`);
Warning, content of library <C:/AVZ/AGN\VSV/Art\Kr> is:
[[":-1.m", %1, 1215, 75], ["P.m", %1, 1024, 65], ["P1.m", %1, 1089, 56], ["M.m", %1, 1145, 70]] %1 := [2006, 10, 5, 10, 0, 44]
>ulibrary(3, `C:/AVZ/AGN\\VSV/Art\\Kr`, P, AVZ);
Warning, member "AVZ" not found in archive, skipping
Warning, names [P, AVZ] have been deleted out of library <C:/AVZ/AGN\VSV/Art\Kr>
>ulibrary(4, `C:/AVZ/AGN\\VSV/Art\\Kr`);
Warning, library <C:/AVZ/AGN\VSV/Art\Kr> has been packed
> ulibrary(5, `C:/AVZ/AGN\\VSV/Art\\Kr`);
Warning, content of library <C:/AVZ/AGN\VSV/Art\Kr> is:
[[":-1.m", [2006, 10, 5, 10, 0, 44], 1024, 75], ["P1.m", [2006, 10, 5, 10, 0, 44], 1099, 56], ["M.m", [2006, 10, 5, 10, 0, 44], 1155, 70]]
> ulibrary(6, "C:/AVZ/AGN\\VSV/Art\\Kr");
Warning, Help database for library <C:/AVZ/AGN\VSV/Art\Kr> has been created
> ulibrary(7, `C:/AVZ/AGN\\VSV/Art\\Kr`, MKDIR, `D:/Academy/UserLib6789/Common/HelpBase/MkDir.mws`);
Warning, topic <MKDIR> had been added to the help database of library <C:/AVZ/AGN\VSV/Art\Kr>
>ulibrary(9, `C:/AVZ/AGN\\VSV/Art\\Kr`, P1);
Error, Could not find any help on "P1"
>ulibrary(9, `C:/AVZ/AGN\\VSV/Art\\Kr`, MKDIR); # Вывод справки по MKDIR на экран
>ulibrary(8, `C:/AVZ/AGN\\VSV/Art\\Kr`, MKDIR);
>ulibrary(9, `C:/AVZ/AGN\\VSV/Art\\Kr`, MKDIR);
Error, Could not find any help on "MKDIR"
> ulibrary(10, `C:/AVZ/AGN\\VSV/Art\\Kr`);
Warning, library <C:/AVZ/AGN\VSV/Art\Kr> has been logically connected with main Maplelibrary
"c:/program files/maple 8/lib/userlib", "C:\Program Files\Maple 8/lib", "C:/AVZ/AGN\VSV/Art\Kr"
Процедура поддерживает десять вышеперечисленных операций с библиотеками пользователя, подобными главной Maple-библиотеке пакета. Кроме операций 8 и 9 (удаление страницы из базы и вывод страницы на экран) вызов процедуры на других допустимых значениях первого аргумента наряду с выполнением соответствующих операций с библиотекой выводит соответствующие предупреждения. Процедура ulibrary обрабатывает основные особые и ошибочные ситуации. Между тем, процедура не обеспечена развитой системой обработки ошибочных ситуаций, что требует от пользователя внимательности при кодировании фактических аргументов при ее вызове. Сделано это было в целях упрощения алгоритма процедуры и его большей прозрачности в учебных целях. В то же время данная процедура представляет достаточно простое и эффективное средство при выполнении базовых операций с Maple-библиотека- ми пакета. Рекомендуется обратить внимание на подпроцедуру mkdir1, обеспечивающую создание цепочки каталогов любого уровня вложенности. Она намного проще нашей стандартной (используемой процедурами нашей библиотеки [103]) процедуры MkDir, однако не снабжена развитой системой обработки ошибочных ситуаций.
Для поддержки разнообразных процедур работы с Maple-библиотеками нами создан целый ряд полезных средств, представленных в книгах [41,42,43,103] и в прилагаемых к ним библиотекам программных средств для пакета Maple релизов 6 – 10. Рассмотрим теперь еще несколько способов организации пользовательских библиотек, которые в ряде случаев оказываются даже эффективнее стандартного подхода, поддерживаемого пакетом Maple.
266

6.2. Специальные способы создания библиотек в среде
Maple
Прежде всего, созданные и отлаженные процедуры и программные модули можно сохранять в текстовых файлах во входном формате Maple-языка. В этом случае они впоследствии читаются read-преложением, корректно загружая в текущий сеанс определения как процедур, так и программных модулей (стандартные средства пакета для модулей не могут обеспечить их корректного сохранения в m-файлах внутреннего Maple-формата). Сохранение процедур и модулей производится в результате выполнения save-предложения следующего формата:
save N1, N2, …, Nk, <СФ> либо save(N1, N2, …, Nk, <СФ>)
где фактические аргументы Nj определяют идентификаторы сохраняемых процедур и/или модулей, а СФ - спецификатор принимающего файла (имя или полный путь к файлу). Если имя файла завершается символами “.m”, то принимающий файл СФ будет во внутреннем Maple- формате, который не позволяет корректно сохранять программные модули [12-14,41-43,103]. Поэтому, совместное сохранение процедур и модулей следует делать в файле входного Maple- формата, для чего имя принимающего файла достаточно кодировать без завершающих его символов “.m”. Загрузка сохраненных процедур и модулей производится по предложению read <СФ> {read(<СФ>)}, в результате чего определение процедур и модулей, находящихся в файле СФ, вычисляется и они становятся доступными текущему сеансу. Следующий весьма простой фрагмент иллюстрирует вышесказанное:
>G:= () -> `+`(args)/nargs: S:= module() export Sr; Sr:= () -> `+`(args)/nargs end module:
>save(G, S, "C:/Temp/File.lib");
>restart; read "C:/Temp/File.lib": 5*G(42, 47, 67, 85, 96), with(S), 5*S:- Sr(42, 47, 67, 85, 96);
337, [Sr], 337
Суть фрагмента сводится к следующему. Определяются простая G-процедура, возвращающая сумму значений передаваемых ей фактических аргументов, и программный модуль S с единственным экспортом Sr, и производится их вычисление с последующим сохранением по save- предложению в файле входного Maple-формата. По restart-предложению восстанавливается исходное состояние текущего сеанса. После этого по read-предложению производится загрузка из файла G-процедуры и S-модуля с последующим вызовом процедуры и Sr-экспорта модуля S, завершившиеся вполне корректно.
Таким образом, по save-предложению можно создавать файлы входного Maple-языка, содержащие корректные определения сохраненных в них объектов (процедуры, модули и т.д.). В случае же внутреннего Maple-формата (m-файлы) программные модули сохраняются некорректно, без их тела. Данная проблематика детально рассмотрена в наших книгах [13,14,41-43,103] и там же представлен целый ряд средств по устранению данной ситуации. В частности, в целях устранения данного недостатка нами была создана процедура SaveMP, обеспечивающая для пакета релизов 6 -10 корректное выполнение данной операции наряду с другими.
Сохраняя процедуры и программные модули по save-предложению в файлах входного Maple- формата, мы, тем самым, создаем своего рода их простейшие библиотеки, средства которых загружаются в текущий сеанс и сразу же становятся доступными подобно стандартным средствам пакета по read-предложению. Недостатком такой библиотечной организации (наряду с некоторыми другими) является то, что каждое новое обновление входящего в такую библиотеку средства требует обновления всей библиотеки. Поэтому в рамках подобного подхода можно предложить полезную процедуру simplel, полезую в целом ряде приложений.
Вызов процедуры simplel(L {, N1, N2, …, Nk}) допускает один или более фактических аргументов, где первый L-аргумент определяет полный путь к файлу входного Maple-формата с сохраняемыми или сохраненными программными средствам (процедурами и/или программными мо-
267

дулями). Вызов процедуры 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 объекты (процедуры и/или программные модули), имена которых определены фактическими аргументами, начиная со второго. При этом, предварительно определения сохраняемых объектов должны быть вычислены, в противном случае они не сохраняются. Сохранение
объектов производится в режиме дописывания (APPEND), позволяя сохранять (архивировать) все
версии программных средств с индикацией дат их сохранения. При этом, при последующей
загрузке файла L активируются в текущем сеансе только последние сохраненные версии объектов. Процедура позволяет создавать библиотечный файл L в цепочке каталогов любого уровня вло- женности, что обеспечивает ее подпроцедура mkf. Процедура simplel обрабатывает основные особые и ошибочные ситуации.
> simplel:= proc(L::{string, symbol}) local a, b, c, f, mkf; mkf:=proc (f::{string, symbol}) local a, b, c, d, cc; cc:= proc(d::{string, symbol}) 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("argument 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;
simplel := proc (L::{string , symbol}) local a, b, c, f, mkf;
mkf := proc (f::{string , symbol}) local a, b, c, d, cc;
cc := proc (d::{string , symbol})
local a, b, c, k;
assign(a = [ ], b = "" || d, c = 17), `if`(
member(b[-1], {"\", "/"}), assign('b' = b[1 .. -2]),
NULL );
for k to length(b) do
268

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("argu\ ment 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 def \ ine 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 inp\
ut 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 simpel , 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
269

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) |
, module () export Sr; |
end module |
, |
1130012352 |
, |
233 |
|
`+`(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/Maple_u.cmd");
Error, (in simplel) datafile <C:/Temp/Maple_u.cmd> had been not created by procedure simplel
Представленный выше фрагмент содержит исходный текст и примеры применения процедуры simplel. Представленная процедура может оказаться полезным средством при организации простых библиотек пользователя, несущих черты и архива программных средств. Данная процедура может быть расширена новыми функциональными возможностями, которые оставляем читателю в качестве достаточно полезного упражнения. С более общими средствами поддержки ведения простых библиотек пользователя, отличных от Maple-библиотек, можно познакомиться в наших книгах [13,14,41-43,103] и в прилагаемых к ним библиотеках.
Для организации простых библиотек пользователя можно использовать еще один в ряде случаев полезный прием. В основу его ложится табличная структура, входами которой являются имена процедур и программных модулей, тогда как выходами их определения. При этом, если для процедуры определение кодируется в чистом виде, то для программного модуля оно кодируется в следующем формате:
'parse("module <Имя> () export ... end module")'
270