Смекни!
smekni.com

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

Начиная с Maple 8, пакет пополнен модулем TypeTools, пять процедур которого служат для расширения списка типов, стандартно прддерживаемых type-функцией. Со своей стороны, еще раньше мы определили процедуру usertype, обеспечивающую ряд массовых операций для работы с пользовательскими типами, поддерживаемых процедурами с именами формата 'type/name', where name – имя пользовательского типа.

Модуль TypeTools может быть использован для расширения стандартной type-функции пакета типами, определенными пользователем, однако его применение приводит к созданию двух непересекающихся систем типизации в среде Maple, а именно: (1) системе типов пользователя, базирующейся на конструкциях вида `type/name`:=proc ... end proc, сохраненных в Maple-библиотеках, и (2) системе, базирующейся на модуле TypeTools.

Процедура usertype может оказаться достаточно полезным средством при организации работы с пользовательскими типами, имена определений которых имеют формат вида `type/name`. Следующий фрагмент представляет исходный текст и примеры применения процедуры usertype.

usertype := proc() local a b c d k j h, , , , , , ; if nargs < 2 then if nargs = 0 then assign67(h = [libname], d = NULL) elif args 1[ ] = 'active' then assign(a = [anames('procedure')], d = [ ]); for k in a do if "" || k[1 .. 5] = "type/"then d := [op(d), "" || "" || [k 6 .. -1]] end if

end do;

return sort(map(convert, d, 'symbol'))

elif type(args 1[ ], {'mlib', 'mla'}) then assign67(h = [args 1[ ]], d = NULL) else error "<%1> is not a Maple library", args 1[ ] end if;

for j in h do assign('a' = march('list', j), 'b' = [ ]); for k in a do c := Search2(k[1], {".m" "type/", }); if c[1] = 1 and c[2] = length(k[1]) − 1 then b := [op(b), cat(``, k[1][6 .. -3])]

end if end do; d := d j, , sort(b)

end do;

d

elif nargs = 2 then if type(args 1[ ], 'symbol') and args 2[ ] = 'code' then try type(a, args 1[ ]) catch "type `%1` does not exist":

error "type `%1` does not exist",args 1[ ] end try ; eval(`type/` || args 1[ ])

elif type(args 1[ ], {'mlib', 'mla'}) and type(eval cat(( `type/`, args 2[ ])), 'boolproc') then UpLib(args 1[ ], [cat(`type/`, args 2[ ])]) end if

elif type(args 1[ ], {'mlib', 'mla'}) and type(eval cat(( `type/`, args 2[ ])), 'boolproc') and args 3[ ] = 'del' then march('delete', args 1[ ], cat(`type/`, args 2[ ]))

else error "factual arguments are invalid", [ args] end if

end proc

> usertype("C:/Program Files/Maple 7/LIB/UserLib");

"C:/Program Files/Maple 7/LIB/UserLib", [Lower, Table, Upper, arity, assignable1, binary, rlb, boolproc, byte, complex1, digit, dir, dirax, file, file1, fpath, heap, letter, libobj, lower, mla, mlib, mod1, nestlist, nonsingular, package, path, plot3dopt, plotopt, realnum, sequent, setset, ssign, upper]

> usertype('active'); ⇒ [dir, mla, mlib]

Требуемая функция процедуры usertype может быть получена использованием ее вызовом на кортеже соответствующих фактических аргументов, а именно:

аргументы отсутствуют – возвращает списки всех имен типов формата `type/name`, на- ходящихся во всех Maple-библиотеках, определяемых предопределенной libname- переменной. Данная функция позволяет получать только имена типов, зарегист- рированных, используя вышеуказанный метод. В частности, она не может исполь- зоваться для получения встроенных типов и созданных на основе TypeTools-моду- ля. Каждый возвращаемый вышеуказанный список предваряется полным путем к Maple-библиотеке, содержащей определения типов, чьи имена находятся в списке; 'active' – возвращает список имен вида `type/name`, активных в текущем сеансе;

L – возвращает список имен типов вида `type/name`, расположенных в Maple- библиотеке, определенной полным путем L к ней. Список предваряется полным путем к Maple-библиотеке, содержащей определения типов; name, 'code' – возвращает исходный текст процедуры `type/name`;

L, name – помещает определение типа `type/name` в Maple-библиотеку, определен- ную полным путем L к ней. Процедура `type/name` должна иметь boolproc- тип. В данном случае вызов процедуры usertype(L,name) выводит соответ- ствующие сообщения;

L, name, 'del' – удаляет определение типа `type/name` из Maple-библиотеки, полный туть к которой определен аргументом L. Никаких сообщений не выводится.

В процессе использования для Maple релизов 6-7 процедура usertype проявила себя достаточно эффективным средством.

Еще на одном весьма существенном моменте следует акцентировать ваше внимание. В среде пакета вызов type(Х, 'type') тестирует выражение Х на предмет быть допустимым выражением типа, т.е. опознаваемым встроенной type-функцией в качестве типа. При этом, по определению под выражением типа Х понимается такое выражение, для которого успешно выполняется вызов type(<Выражение>, Х), где в качестве первого аргумента выступает произвольное Maple-выражение. В качестве типов допускаются системные типы {integer, float, symbol, string и др.}, типы, определяемые процедурами с именами формата `type/name`, а также типы, определяемые присвоением либо комбинацией типов. Однако, данная проверка не столь корректна, как декларируется. Следующий простой фрагмент подтверждает вышесказанное.

> restart; with(TypeTools); ⇒ [AddType, GetType, GetTypes, RemoveType, Type] > AddType(listodd, L -> type(L, 'list'(odd))); > type([64, 59, 10, 17, 39], 'listodd'), type([59, 17, 39], 'listodd'); ⇒ false, true > type(listodd, 'type'); ⇒ true

> `type/listeven`:= L -> type(L, 'list'('even')): type(listodd, 'type'); ⇒ true

> type([64, 10, 44], 'listeven'), type([59, 17, 39], 'listeven'); ⇒ true, false > `type/neg`:= proc(x::{integer, float, fraction}) if x < 0 then true else false end if end proc: > map(type, [64, -10, 59, -17, 39, -44], 'neg'), type(neg, 'type');

[false, true, false, true, false, true], false

> UpLib("С:/Temp/userlib", [`type/neg`]): restart; libname:= libname, "С:/Temp/userlib":

type(neg, 'type'); ⇒ false

> map(type, [64, -10, 59, -17, 39, -44], 'neg'); ⇒ [false, true, false, true, false, true]

type/Type := proc(x::anything) local a; try type(a x, ) catch "type `%1` does not exist": return false catch : return true end try; true

end proc

> type(neg, 'type'), type(neg, 'Type'); ⇒ false, true

> map(type, [neg, aa, bb, set, mla, dir, file], 'Type'); ⇒ [true, false, false, true, true, true, true]

В первой части производится тестирование типов, определенных средствами TypeToolsмодуля и процедурами с именами вида `type/name`. Оказывается, что во втором случае вызов type(neg, 'type') некорректно тестирует neg-тип. Затем определяется `type/Type`процедура, устраняющая данный недостаток. В заключительной части фрагмента данная процедура проверяется на предмет корректности, демонстрируя, что она решает задачу тестирования типов успешнее стандартного средства, обеспечивая корректное тестирование типов, определенных любым допустимым в Maple способом.

Из представленных в настоящем разделе средств тестирования типов данных, структур данных и выражений в их общем понимании можно уже сделать вполне определенные выводы о возможностях Maple-языка в данном весьма важном аспекте его вычислительных как численных, так и алгебраических средств. Именно поэтому данному разделу возможностей языка было уделено более развернутое внимание в свете существенной ориентации пакета не столько на сугубо численные вычисления, сколько на сугубо алгебраические вычисления и преобразования. Теперь мы переходим к весьма важному разделу средств Maple-языка, обеспечивающих конвертацию выражений одного типа в выражения другого типа.

1.7. Конвертация Maple-выражений из одного типа в другой

Так как многие типы числовых значений взаимно обращаемы, то Maple-язык пакета для конвертации одного типа в другой располагает достаточно развитыми средствами, базирующимися на многоаспектной convert-функции, которая служит не только для конвертации значений из одного типа в другой, но и конвертации выражений в целом из одного типа в другой, при этом понятие типа трактуется существенно более широко, чем мы говорили до сих пор, например, можно конвертировать выражения, содержащие волновые Айри-функции, в выражения с функциями Бесселя и т.д. В общем случае функция convert имеет следующий формат кодирования: convert(<Выражение>, <Формат> {, <Список опций>})

где выражение представляет собственно сам объект конвертации, формат определяет тип конвертации (его в случае столь широкого толкования понятия “тип” вполне допустимо называть более емким понятием “формат“), а необязательный третий аргумент функции составляет Список опций, определяемых спецификой используемого второго Формат-аргумента функции. Язык пакета для convert-функции в качестве значения ее второго аргумента допускает следующие форматы (типы) конвертации:

0F1 1F1 2F1 Abel Abel_RNF abs Airy algebraic and arabic arctrig arctrigh I array base Bessel Bessel_related binary binomial boolean_function boolean_operator bytes Chebyshev compose confrac conversion_table Cylinder D decimal egrees DESol diff dimensions disjcyc Ei_related elementary Elliptic_related equality erf erfc erf_related exp expln expsincos factorial FirstKind float fullparfrac GAMMA function_rules GAMMA_related global Hankel eaviside eun hex hexadecimal Int hypergeom int iupac Kelvin Kummer Legendre linearODE list listlist ln local mathorner Matrix

matrix MeijerG metric MobiusR MobiusX MobiusY mod2 ModifiedMeijerG multiset name NormalForm numericproc octal or package parfrac permlist piecewise polynom PLOT3Doptions PLOToptions polar POLYGONS power pwlist radians radical set rational ratpoly RealRange record relation Riccati roman RootOf SecondKind std

signum sincos sqrfree StandardFunctions stdle string Sum sum surd symbol tan

system table temperature to_special_function trig trigh truefalse units unit_free Vector vector Whittaker windchill xor y_x `*` `+`

Уже из простого перечисления допустимых видов конвертации (в количестве 137 для пакета Maple 10) следуют весьма широкие возможности convert-функции. Многие из них будут достаточно детально рассмотрены в настоящей книге в различных контекстах, с другими можно детально ознакомиться по справочной системе пакета либо по книгам [34,42,56,63,78,96]. В представительном отношении набор допустимых форматов конвертации относительно предыдущих релизов пакета в Maple 10 увеличился, да и в качественном отношении произведено существенное расширение механизма конвертации типов. Данное обстоятельство существенно расширило возможности Maple-языка по преобразованию типов и форматов представления выражений. Следующие довольно распространенные форматы конвертации типов выражений представлены в табл. 6.

Таблица 6

Формат-значение

Конвертация первого аргумента функции в формат:

RootOf

в терминах RootOf-нотации; конвертирует все I и радикалы

radical

в терминах I и радикалов; обратный к предыдущему формату

{and|or}

{and|or}-представления, если аргумент - список/множество

array

структуры типа массив; конвертирует списки, таблицы, массивы; результат возвращается в уплотненном формате

base

из одной системы счисления в другую; имеет две формы

binary

бинарного числового представления

binomial

GAMMA-функции и факториалы в binomial-функцию

bytes

байтов; конвертация списка 16-ричных цифр или строк в байты

confrac

бесконечной дроби; перевод чисел, рядов, алгебраических выражений в бесконечно-дробную аппроксимацию

{`*`|`+`}

{произведения|суммы} всех операндов исходного выражения

decimal

2-, 8- и 16-ричные (в виде строк) числа в 10-ричные

degrees

градусного представления; обратным к нему является radians

double

float-числа двойной точности в другие форматы; поддерживается конвертация между платформами IBM, VAX, MIPS

{equality|lessthan| lessequal}

равенства или отношения; {отношение} →{=|<|≤}

exp

тригонометрические функции в экспоненциальные

expln

элементарные функции в терминах функций {exp, ln}

expsincos

тригонометрические функции в терминах {exp, sin, cos}

Ei

тригонометрические, гиперболические и логарифмические интегралы в экспоненциальные интегралы Ei(x)

factorial

конвертация GAMMA-функции и биномиалов в факториалы

float

float-типа; в значительной мере подобна evalf-функции

fullparfrac

рациональное выражение в полностью линейное рациональное

hex

десятичное неотрицательное число в 16-ричное строчное

horner

полинома в форме Горнера

list

таблицы, векторы или выражения в списочную структуру (в случае выражения элементами списка будут его операнды)

listlist

вложенного списка; конвертируются списки/массивы

ln

обратные тригонометрические функции в логарифмические

mathorner

полином в матричную форму Горнера

matrix

массив или вложенный список в матричную структуру

metric

английскую систему мер в метрическую

mod2

приведения по (mod 2); допустимо вхождение {and, or, not}

multiset

в специальную multiset-форму

{symbol|name}

конвертация в {symbol|name}-тип; symbol - синоним name

numericproc

символьную F(x,y)-функцию в числовую F`(x,y)-функцию

octal

8-ричного представления; допустимо определение точности

parfrac

перевод в частично-дробный формат; расширенные опции

piecewise

в формат кусочно-определенной функции

polar

комплексные числа в полярную форму представления

pwlist

конвертация кусочно-определенной функции в список

radians

перевод из радианной меры в градусную; обратная к degrees

{rational|fraction}

перевод из float-формата в приближенный рациональный вид

set

перевод табличной структуры, массива, выражения в множество

{signum|abs}

замена всех {abs|signum}-функций выражения на {signum|abs}

sincos

тригонометрические функции в {sin, cos, sinh, cosh}

sqrfree

представление полиномов без квадратов

string

конвертация выражения в строчный формат

table

перевод списочной структуры или массива в табличную форму

tan

перевод тригонометрических функций в tan-представление

trig

экспоненциальные и тригонометрические функции в форме выражений из функций {exp, sinh, cosh, tanh, sech, csch, coth}

vector

список или массив в вектор, а в общем случае и в матрицу

В качестве примера использования представленных в табл. 6 значений формат-аргумента функции приведем фрагмент, иллюстрирующий возможности функции по конвертации различных форматов представления выражений из одного в другой: