Смекни!
smekni.com

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

Наконец, третий уровень поддерживается стандартной процедурой savelib, обеспечивающей помещение таблиц, программных модулей и процедур, а в более общем случае определений многих других вычисленных объектов, в разделяемую главную библиотеку пакета. Это дает возможность впоследствии использовать сохраненные объекты на логическом уровне доступа также, как встроенные средства пакета. Реализация данного механизма сохранения обеспечена выполнением в текущем сеансе нескольких шагов, которые достаточно подробно рассмотрены в наших книгах [14,29-33,39,42-46,103]. Для обеспечения обновления главной Maple-библиотеки таблицами, процедурами и программными модулями предназначены две довольно полезные процедуры MapleLib и UpLib. Данные процедуры позволяют также обновлять библиотеки пользователя, аналогичные главной библиотеке пакета. В частности, именно последняя библиотека используется нами наиболее активно для обновления Maple-библиотек пакета. Она рассмотрена выше, тогда как процедура MapleLib представлена ниже.

MapleLib := proc(P::{set(symbol), list(symbol)}) local a b c h r p k l i, , , , , , , , ; assign(r = Release ' '( h ), p = { }, b = { }), `if`(nargs = 1, assign(l = cat(h, "&bsol;lib&bsol;maple.lib"), i = cat(h, "&bsol;lib&bsol;maple.ind" , `if`()) type(args 2[ ], 'mlib'), assign(l = cat(args[2], "&bsol;maple.lib"), i = cat(args[2], "&bsol;maple.ind")), ERROR "library <%1> does not exist",( args 2[ ]))), assign(a = `if`(nargs = 1, cat( ,h "&bsol;lib"), args[2]));

`if`(map(type, {l i, }, 'file') = {true}, NULL, ERROR("library <%1> does not exist or is damaged", a)); seq(assign('p' = {op(p), `if`(type(P[k], {`module`, 'procedure', 'table'}), P[k], assign(' 'b = {op( )b , k}))}), k = 1 .. nops(P)), `if`(p = { },

ERROR "1st argument does not contain procedures, tables or modules", `if`(( ) nops(p) < nops(P), WARNING("arguments with numbers %1 are invalid", b), NULL)); map(F_atr1, [l, i], [ ]), assign(c = interface(warnlevel), 'savelibname' = a), null interface(( warnlevel = 0));

try savelib op( )( p ) catch "unable to save %1 in %2": AtrRW(savelibname ); savelib op(( p)) finally null interface(( warnlevel = c)), AtrRW(savelibname ) end try;

WARNING("tools <%1> have been saved/updated in <%2>", ,p savelibname ), unassign '( savelibname')

end proc

> Art:= proc() `+`(args)/nargs end proc: Kr:= module () export mean; option package; mean:= () -> `+`(args)/nargs end module: MapleLib([Art, Kr]);

Warning, library <C:&bsol;Program Files&bsol;Maple 9&bsol;lib> has received the `READONLY`-attribute

Warning, tools <{Art, Kr}> have been saved/updated in <C:&bsol;Program Files&bsol;Maple 9&bsol;lib>

Успешный вызов процедуры MapleLib(P) обновляет главную Maple-библиотеку процедурами, таблицами и/или модулями, имена которых определены первым фактическим P аргументом (множество или список имен). Если был закодирован второй дополнительный L аргумент, то он определяет полный путь к пользовательской библиотеке, аналогичной главной библиотеке. Процедура всегда выводит соответствующее сообщение о проделанной работе. Процедура обрабатывает основные ошибочные ситуации, связанные с отсутствием либо повреждением обрабатываемой библиотеки, или с отсутствием сохраняемых объектов. При возникновении подобных ситуаций возвращается соответствующая диагностика. Процедура обеспечивает вышеупомянутые функции для библиотек указанного типа для пакета релизов 6 - 10. Более того, библиотеки в Maple релизов 6 и 7 получают readonly-атрибут (в концепции MS DOS) после обновления, тогда как библиотеки в Maple релизов 8 – 10 после обновления получают READONLY-атрибут (в концепции Maple; процедура AtrRW). Процедура AtrRW представлена ниже.

AtrRW := proc(L::path) local a r h p l i, , , , , , ω; assign(r = Release( ), l = cat(L, "&bsol;maple.lib"), i = cat(L, "&bsol;maple.ind"));

`if`(map(type, {l i, }, 'file') = {true}, NULL, ERROR("library <%1> does not exist or is damaged", L)); ω := x → WARNING("library <%1> has received the %2-attribute", L, x); if member ,(r {6, 7}) then assign(a = map(F_atr1, [l i, ])), map(F_atr1, [l i, ], [ ]); if not member(map2(member, "R" {, op( )}a ), {{true}, {true false, }}) then null map(( F_atr1, [l i, ], ["+R"])), ω("`readonly`") else ω("`writable`")

end if

else try filepos ,(l 265), assign(p = (l → filepos ,(l 265))), p l( ) catch "file I/O error" map(: F_atr1, [l i, ], [ ]), filepos( ,l 265), assign(p = (l → filepos(l, 265))), p(l)

catch "permission denied":

map(F_atr1, [l i, ], [ ]);

filepos ,(l 265), assign(p = (l → filepos ,(l 265))), p l( )

end try ; if readbytes(l) = [2] then null(p l( ), writebytes ,(l [1])), close( )l , ω("`READONLY`") else null(p l( ), writebytes ,(l [2])), close( )l , ω("`WRITABLE`") end if

end if

end proc

> AtrRW("C:/program files/maple 7/lib");

Warning, library <C:/program files/maple 7/lib> has received the `readonly`-attribute > AtrRW("C:/program files/maple 9/lib");

Warning, library <C:/program files/maple 9/lib> has received the `READONLY`-attribute

Для пакета Maple релизов 8, 9 и 10 вызов процедуры AtrRW(L) по принципу «переключателя» изменяет атрибут READONLY или WRITABLE (в Maple-концепции) на противоположный для Maple-библиотеки, полный путь к которой определяется аргументом L. Тогда как для Maple релизов 6, 7 вызов процедуры AtrRW(L) по принципу «переключателя» изменяет атрибут readonly или writable (в DOS-концепции) на противоположный для библиотеки, полный путь к которой определяется аргументом L. Успешный вызов процедуры возвращает NULL-значение с выводом сообщения о проделанной работе. С целым рядом других полезных средств для работы с библиотеками пользователя как аналогичными главной Maple-библиотеке, так и нестандартными можно ознакомиться в [109].

8.3. Создание пакетных модулей пользователя

С каждым новым релизом пакета в нем появляются новые пакетные модули, средства которых ориентированы на тот или иной круг приложений. Получать перечень пакетных модулей, имеющихся в текущем релизе пакета Maple, можно оперативно по запросу вида ?index, package. Во многих изданиях и технической документации по пакету Maple такие структурированные наборы средств называются «пакетами», хотя на наш взгляд, это и не вполне правомочно. Более того, по большому счету именно сам Maple является пакетом. Наша мотивировка подобной терминологии представлена, например, в [12,4143,103]. В этом смысле программные и пакетные модули в общем случае являются разными объектами. Модульная организация обеспечивает целый ряд преимуществ, детально не обсуждаемых здесь. В частности, она позволяет вести независимую разработку с ориентацией на конкретный круг приложений, допускает использование одноименных со стандартными средств. Имеются и другие немаловажные преимущества.

M_Type := proc(M::symbol) local a T, , ω ν, , , ;t k assign(a = {anames(procedure )}, ω = interface(warnlevel)), `if`(M = liesymm, RETURN '( Tab'), assign(ν = (h → null interface(( warnlevel = h))))); try t := [exports(M)]; if t = [ ] then RETURN WARNING(( "<%1> is not a module", M)) else unassign '( Fin'); goto(Fin) end if

catch "wrong number (or type) of parameters in function %1":

try ν(0); t := with(M) catch "%1 is not a package": ν ω( ); RETURN WARNING(( "<%1> is not a module", M)) catch "invalid input: %1":

ν ω( );

RETURN(

WARNING("<%1> is not a module or can't be initialised", M)) catch "system level initialisation for": ν ω( );

RETURN WARNING(( "module <%1> cannot be initialised", M))

end try

end try ;

for k in t do if member(k a, ) then next else unprotect( )k ; unassign( )k end if end do;

Fin;

ν(ω), assign(T = convert(eval(M), 'string')), `if`( searchtext "table",( T, 1 .. 5) = 1, 'Tab', `if`( searchtext "module",( T, 1 .. 6) = 1, 'Mod', `if`(searchtext "proc",( T, 1 .. 4) = 1, 'Proc NULL', ))) end proc

> map(M_Type, [PolynomialTools, ExternalCalling, LinearFunctionalSystems,

MatrixPolynomialAlgebra, ScientificErrorAnalysis, CodeGeneration, LinearOperators,

CurveFitting, Sockets, Maplets, Student, Matlab, Slode, LibraryTools, Spread, codegen, context, finance, genfunc, LinearAlgebra, geom3d, group, linalg, padic, plots, process, simplex, student, tensor, MathML, Units,DEtools, diffalg, Domains, stats,

GaussInt,Groebner, LREtools, PDEtools, Ore_algebra, algcurves, orthopoly, combinat, combstruct, difforms, geometry, inttrans, networks, numapprox, numtheory, plottools, powseries, sumtools, ListTools, RandomTools, RealDomain, SolveTools, StringTools,

XMLTools, SumTools, TypeTools, Worksheet, OrthogonalSeries, FileTools,

RationalNormalForms, ScientificConstants, VariationalCalculus]); # Maple 10

[Mod, Mod, Mod, Mod, Mod, Mod, Mod, Mod, Mod, Mod, Mod, Mod, Tab, Mod, Mod, Mod, Tab,

Mod, Mod, Mod, Mod, Mod, Mod, Mod, Tab, Mod, Tab, Tab, Tab, Mod, Mod, Tab, Tab, Mod, Proc,

Mod, Mod, Tab, Tab, Mod, Tab, Tab, Mod, Tab, Tab, Mod, Tab, Tab, Mod, Mod, Mod, Mod, Mod, Mod, Mod, Mod, Mod, Mod, Mod, Mod, Mod, Mod, Mod, Mod, Mod, Mod, Mod] > Mulel(%); ⇒ [[Proc, 35, 1], [Tab, 13, 16], [Mod, 1, 50]]

Организационно пакетные модули в настоящее время бывают трех типов – процедуры, программные модули (как правило, второго типа) и таблицы. С помощью нашей процедуры M_Type [103,109] можно проверять тип пакетного модуля; ее применение в среде пакета Maple 10 дает результат, представленный предыдущим фрагментом.

Таким образом, Maple 10 располагает 16 модулями табличного типа (Tab), 50 модулями модульного типа (Mod) и только одним модулем процедурного типа (Proc). Распределение пакетных модулей по типам их организации зависит от релиза пакета и для Maple 6, например, типы распределились следующим образом: Proc – 1, Tab – 34 и Mod – 2, т.е. явно превалирует табличная организация. Выше были рассмотрены основные вопросы создания процедур и программных модулей, поэтому останавливаться на этом не имеет смысла. Напомним лишь, что при создании пакетного модуля процедурного либо модульного типа в его разделе option необходимо кодировать опцию package, что позволит после сохранения его в Maple-библиотеке в последующем обращаться к содержащимся в нем средствам принятыми в Maple способами.

Здесь же мы рассмотрим лишь создание пакетного модуля табличного типа, как первого наиболее массового типа модулей в среде ранних релизов Maple. Как можно будет впоследствии заметить, именно основные методы доступа к пакетным модулям определяются форматом, используемым при обращении к табличным объектам. Общая схема создания пакетного модуля табличного весьма проста и состоит в следующем. На первом этапе производятся тщательные тестирование, апробация и отладка процедур, предназначенных к включению в создаваемый пакетный модуль. Затем готовые процедуры погружаются в табличную структуру, в качестве входов которой являются имена процедур и выходов – их определения, т.е. создается таблица следующего вида: