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переменной пакета.
Ниже представлен исходный текст процедуры и примеры ее применения на все случаи. Процедура поддерживает десять вышеперечисленных операций с библиотеками пользователя, подобными главной Maple-библиотеке пакета. Кроме операций 8 и 9 (удаление страницы из базы и вывод страницы на экран) вызов процедуры на других допустимых значениях первого аргумента наряду с выполнением соответствующих операций с библиотекой выводит соответствующие предупреждения. Процедура ulibrary обрабатывает основные особые и ошибочные ситуации.
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[ ])); 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 help ( \ on my means located in UserLib. The library has been created 5.10.2\ 006"), 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-ty\( |
pe 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 Maple-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> > 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 Maple-library "c:/program files/maple 8/lib/userlib", "C:\Program Files\Maple 8/lib", "C:/AVZ/AGN\VSV/Art\Kr" |
Между тем, процедура не обеспечена развитой системой обработки ошибочных ситуаций, что требует от пользователя внимательности при кодировании фактических аргументов при ее вызове. Сделано это было в целях упрощения алгоритма процедуры и его большей прозрачности в учебных целях. В то же время данная процедура представляет достаточно простое и эффективное средство при выполнении базовых операций с Mapleбиблиотеками пакета. Рекомендуется обратить внимание на подпроцедуру mkdir1, обеспечивающую создание цепочки каталогов любого уровня вложенности. Она намного проще нашей стандартной (используемой процедурами нашей библиотеки [103]) процедуры MkDir, однако не снабжена развитой системой обработки ошибочных ситуаций.
Достаточно полезной оказывается и процедура, чей вызов Plib(L) возвращает полный путь к Maple-библиотеке, заданной своим именем либо путем L к ней, и которая логически связана с главной библиотекой пакета. При отсутствии такой библиотеки либо логической связи для нее возвращается false-значение. Нижеследующий фрагмент представляет исходный текст процедуры и пример ее применения.
Plib := proc(L::{string, symbol}) local a b c k h p, , , , , , ω; assign(a = [libname], b = cat "/",( Case(L, 'lower')), ω = (( ) → Case(sub_1("\" = "/" args, ))), c = cat "\",( Case(L, 'lower'))), seq(`if`( ω(a k[ ]) = ω(L) or Search1(Case(a k[ ], 'lower'), b, ' 'h ) and h = ['right'] or Search1(Case(a[k], 'lower'), c, 'p') and p = ['right'], RETURN(a[k]), NULL), k = 1 .. nops(a)), false end proc > Plib(userlib), Plib(UserLib), Plib("C:\RANS/Academy/ModProcLib"), Plib(Svetlana); "c:/program files/maple 9/lib/userlib", "c:/program files/maple 9/lib/userlib", "c:/rans/academy/modproclib", false |
Для поддержки разнообразных процедур работы с Maple-библиотеками нами создан целый ряд полезных средств, представленных в книгах [41,42,43,103] и в прилагаемых к ним библиотекам программных средств для пакета Maple релизов 6 – 10. Рассмотрим теперь еще несколько способов организации пользовательских библиотек, которые в ряде случаев оказываются даже эффективнее стандартного подхода, поддерживаемого Maple.
Прежде всего, созданные и отлаженные процедуры и программные модули можно сохранять в текстовых файлах во входном формате Maple-языка. В данном случае они впоследствии читаются read-преложением, корректно загружая в текущий сеанс определения как процедур, так и программных модулей (стандартные средства пакета для модулей не могут обеспечить их корректного сохранения в m-файлах внутреннего Maple-формата). Сохранение процедур и модулей производится в результате выполнения save-предложения следующего формата кодирования:
save N1, N2, …, Nk, <СФ> либо save(N1, N2, …, Nk, <СФ>)
где фактические аргументы Nj определяют идентификаторы сохраняемых процедур и/или модулей, а СФ - спецификатор принимающего файла (имя либо полный путь к файлу). Если имя файла завершается символами “.m”, то принимающий файл СФ будет во внутреннем Maple-формате, который не позволяет корректно сохранять программные модули [12-14,41-43,103,109]. Поэтому, совместное сохранение процедур и модулей следует делать в файле входного 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 корректное выполнение данной операции наряду с другими. Процедура и примеры ее применения представлены ниже.