Организация библиотек пользователя, представленная выше, является достаточно удобной и четко локализует их расположение, обеспечивая их весьма удобную программную обработку. Наряду с этим, данная организация позволяет использовать для поддержки пользовательских библиотек средства пакета, а именно его встроенную функцию march. Процедуры, которые представлены в [103], обеспечивают создание и обновление библиотек пользователя согласно вышеупомянутой файловой организации, а также их логическое соединение с главной Maple-библиотекой, что обеспечивает возможность доступа к средствам, находящимся в них, на уровне стандартных средств. Использование библиотечной организации, поддерживаемой пакетом, существенно упрощает работу с пользовательскими библиотеками.
User_pflM := proc(R::{name, string, symbol}, U::{list(symbol), set(symbol)}) local a b k n G Art, , , , , , W, U_cmd M Q Z P V h BackSlash F MR L T TU TM `0`, , , , , , , , , , , , , , ; RegMW( ), assign(F = cat "",( R), MR = Release ' '( h ), ' 'h = h, L = [op(U)], n = [ ]); try `if`(F[2] = ":", assign('G' = CF(F, 'string')), assign(' 'G = CF(cat(h, "/Lib/", F), 'string'))), [MkDir(G), march '( create G', , `if`(3 ≤ nargs and type(args 3[ ], 'posint'), args 3[ ], 650))] catch "directory exists and is not empty"NULL("Especial situation 1"): catch "there is already an archive in" NULL("Especial situation 2"): end try ; BackSlash := proc(S::{string symbol, }) local a; assign(a = "" ;) seq assign ' '( ( a = cat(a, `if`(convert(S, 'string')[k] = "\", "/", convert(S, 'string')[k]))), k = 1 .. length(S)), a end proc ; U_cmd := proc(S string:: , L::{list set, }) local k Kr, ; Kr := fopen(cat(S, "/maple_U.cmd"), 'APPEND', 'TEXT'); writeline(Kr, cat("$ New user procedures and modules = ", ssystem "date"( )[2][17 .. 30 )),] seq(writeline(Kr, L k[ ]), k = 1 .. nops(L)), fclose(Kr) end proc ; writeline("$Help$", "Help database of the Aladjev's Library * version 2.169 * \ nternational Academy of Noosphere, The Baltic Branch = Tallinn = May 3, 2003"), fclose "$Help$" ;( ) makehelp(Empty `$Help$`, , convert(BackSlash G( ), 'symbol')), fremove("$Help$"); [assign('savelibname' = G Art, = (proc(x k, ) local a; if search(x `/`, ) or search(x `*`, ) or type(x `module`, ) then savelib( )x else a := cat "/$", ,( x cat(`` k, ), `.m`); save ,x cat(h a, ); a |
end if end proc )), seq(assign(' 'n = [op(n), Art(L k[ ], k)]), k = 1 .. nops(L))]; V := subsop seq(`if`(( search(L k[ ], `/`) or search(L k[ ], `*`) or type(L k[ ], `module`), k = NULL, NULL), k = 1 .. nops(L)), L); [assign('W' = march('list', G)), assign('M' = [seq(convert(W[ ]k [1], 'symbol'), k = 1 .. nops(W))])]; seq march( (`if`(member(cat(V k[ ], `.m`), M), 'update', 'add'), G, cat(h, n k[ ]), cat(V k[ ], `.m`)), k = 1 .. nops(V)), U_cmd(G L, ), delf seq(( cat(h, n k[ ]), k = 1 .. nops(n))), map(march, ['pack', 'reindex'], G), assign(Q = cat(CCM( ), "\Maplesys.ini")); assign(' 'Z = readbytes(Q, 'TEXT', ∞)), fclose(Q); assign ' '( Z = cat(Z[searchtext "UserD",( Z) + 14 .. searchtext(" ", Z, searchtext "UserD",( Z) .. length(Z)) + searchtext("UserD", Z) − 2], "/Maple.ini")); assign(TM = cat("libname:=libname,"", BackSlash(G), "":"), TU = cat "libname:="",( BackSlash G( ), "",libname:" );) try assign(P = readbytes(Z, 'TEXT', ∞)), fclose(Z); `if` search( ,( P BackSlash G( )), NULL, [fopen(Z, 'APPEND', 'TEXT'), writeline(Z, `if`(3 ≤ nargs and member(args[3], {"U", "M"}), `if`(args 3[ ] = "U", TU TM, ), `if`( nargs = 4 and member(args 4[ ], {"U" "M", }), `if`(args 4[ ] = "U", TU TM, ), TU)))]) catch "file or directory does not exist"writeline: (Z, `if`( 3 ≤ nargs and member(args[3], {"U", "M"}), `if`(args[3] = "U", TU, TM), `if`(nargs = 4 and member(args 4[ ], {"U" "M", }), `if`(args 4[ ] = "U", TU TM, ), TU))) catch "file or directory, %1, does not exist"writeline: (Z, `if`( 3 ≤ nargs and member(args 3[ ], {"U" "M", }), `if`(args 3[ ] = "U", TU TM, ), `if`(nargs = 4 and member(args[4], {"U", "M"}), `if`(args 4[ ] = "U", TU TM, ), TU))) end try ; (proc() global libname; libname := G libname libname, ; end proc )( ), WARNING ("the User library <%1> has been created/updated", G), fclose(Z) end proc > Art:= () -> `+`(args)/nargs: Kr:= module () option package; export mean; mean:= () -> sqrt(`+`(args)/nargs) end module: Sv:= () -> [nargs, {min(args),max(args)}]: module Vict () export gr; gr:= () -> WARNING("factual arguments %1", [args]) end module: Gal:= proc() Close() end proc: User_pfl("C:/RANS/Tallinn\Grodno\SVEGAL", [Art, Kr, Sv, Vict, Gal],7, "M"); Warning, the user library <c:/rans/tallinn/grodno/svegal> has been created/updated "c:/rans/tallinn/grodno/svegal", "c:/program files/maple 9/lib/userlib", "C:\Program Files\Maple 9/lib" |
Для обеспечения работы с библиотеками пользователя, подобными Maple-библиотеке, нами был создан целый ряд средств, описание которых можно найти в книгах [41,103] и в прилагаемой к ним Библиотеке. Данные средства были созданы еще для Maple 6, тогда как некоторый их аналог в лице модуля LibraryTools появился только в 8-м релизе пакета. Первоначально это был набор из 5 процедур, в Maple 9 – 7 процедур, в Maple 10 – 16 процедур. Однако целый ряд функций по работе с библиотеками так и не был реализован. Наш же набор средств наряду с наиболее массовыми представляет средства для восстановления поврежденных библиотек и средства их оптимизации. Некоторые из них будут представлены и в настоящей главе.
В частности, процедура User_pflM(F,U {, S {, R}}) обеспечивает создание или обновление пользовательских библиотек, структурно аналогичных главной Maple-библиотеке, с их логической связью с главной библиотекой, что обеспечивает доступ к содержащимся в них средствам на уровне стандартных библиотечных средств пакета. Исходный текст процедуры с примерами ее применения представляет предыдущий фрагмент. Первый аргумент F процедуры определяет местоположение пользовательской библиотеки. При этом, если указывается в качестве значения для F, каталог, то процедура рассматривает его как подкаталог каталога LIB. Если же указан полный путь, то по нему и создается/обновляется библиотека пользователя. Во втором случае достигается полная свобода по размещению пользовательских библиотек в файловой системе компьютера.
Второй аргумент U определяет список либо множество имен процедур, модулей и др., чьи определения вычислены в текущем сеансе и которые подлежат сохранению в существующей либо создаваемой библиотеке F. Для сохранения в библиотеке программных модулей в их определениях следует предусмотреть package–опцию.
Третий необязательный аргумент S posint-типа определяет размер создаваемой библиотеки. Значение S рассчитывается из того условия, что для планируемого размещения в библиотеке 2p средств выбирается р. Данное значение не лимитирует число сохраняемых в библиотеке объектов, однако его превышение вызывает создание нового индексного файла «Maple.ind», что не всегда целесообразно. По умолчанию полагается 650.
Если в качестве третьего аргумента закодировано значение {"U", "M"}, то процедура устанавливает приоритет для создаваемой библиотеки: максимальный {путем определения в предопределенной переменной libname цепочки путей к библиотекам - <user library, libname> ("U")} или минимальный {путем определения в предопределенной переменной libname цепочки путей к библиотекам - <libname, user library> ("M")}. По умолчанию полагается "U". Четвертый необязательный аргумент R имеет тот же смысл, что и третий S, допуская те же значения {"U", "M"}. По умолчанию, для данного аргумента полагается значение "U" для вновь создаваемой библиотеки и "M" для обновляемой библиотеки. Успешный вызов процедуры возвращает текущее состояние предопределенной libname-переменной и выводит сообщение по созданной/обновленной библиотеке. После этого пользователь имеет возможность работать с ее средствами аналогично стандантным средствам пакета. Более детально с работой и возможностями процедуры User_pflM и ее модификациями можно ознакомиться в [41,103]. Здесь же мы не ставим целью рассмотрение всех созданных нами средств по работе как с Maple-библиотеками, так и с библиотеками иных организаций, отсылая заинтересованного читателя к [12-14,41,103,108,109], а рассмотрим лишь стандартный подход к созданию Maple-библиотек пользователя.
Этап 1. Прежде всего, предполагается, что у пользователя имеется набор готовых и отлаженных процедур и/или программных модулей, которым он желает наполнить вновь создаваемую библиотеку, подобную Maple-библиотеке пакета. На первом этапе создается пустая библиотека, используя встроенную iolib-функцию (ранее она была на уровне утилиты) march, имеющую следующий формат кодирования для этой цели: march('create', <Полный путь к библиотеке>, <Размер>)
Однако перед дальнейшим рассмотрением целесообразно детализировать понятие «полный путь», уже успользованное выше. Полный путь к искомому файлу/каталогу в файловой системе компьютера, как правило, кодируется в виде значения {string, symbol}-типа и для среды {DOS|Windows} имеет следующий формат кодирования:
<УВВ>:{\|/}<подкаталог_1>{\|/}<подкаталог_2>…{\|/}<подкаталог_n>{\|/}{<файл>} где: УВВ определяет логическое имя устройства (например, жесткий диск, CD-ROM, USB и т.д.), подкаталог_к - подкаталог файловой системы и файл - имя файла в виде <Основное имя> {.<Расширение имени>}. Символ {\|/} служит в качестве разделителя в определении пути и по dirsep-параметру функции kernelopt (обеспечивающей механизм связи между ядром Maple и пользователем) можно получать его значение по умолчанию kernelopts(dirsep); ⇒ "\". Однако его нельзя переопределять. Между тем, Maple допускает в качестве разделителей в определении пути к файлу/каталогу любой из символов {“\”|”/”}, однако их использование в общем случае неэквивалентно, хотя и предоставляет целый ряд дополнительных возможностей, детально рассматриваемых в [103]. Здесь же и ниже будет использоваться любой из указанных разделителей. Если указанная выше цепочка каталогов (полный путь) завершается каталогом, то она определяет путь к последнему каталогу, в противном случае к файлу данных.
Перед созданием библиотеки по march-функции предварительно мы должны создать для нее каталог (если он не был создан ранее), в котором она будет размещаться. Создавать каталог можно либо средствами DOS, Windows, либо в среде самого Maple, для чего существует iolib-функция mkdir, имеющая следующий простой формат кодирования: mkdir(<Путь к каталогу>)