Смекни!
smekni.com

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

> [match(19.89*sin(x) + x^57 - 10*y = a*sin(x) + x^b + c, x, 'h'), h]; ⇒ [false, h]

> [match(convert(19.89*sin(x) + x^57 - 10*y, 'rational') = a*sin(x) + x^b + c, x, 'h'), h];

true, {a = 1989100 , c = −10 y, b = 57} 

Во избежание подобной ситуации выражения, содержащие числовые значения, рекомендуется предварительно конвертировать в эквивалентные выражения rational-типа.

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

! * + . < <= <> = @ @@ abstract_rootof algebraic algext algfun algnum algnumext And and anyfunc anyindex anything appliable applied arctrig Array array assignable atomic attributed boolean BooleanOpt builtin cubic character ClosedIdeal CommAlgebra complex complexcons

composition const constant cx_infinity dependent dictionary dimension

disjcyc cx_zero filedesc embedded_axis embedded_imaginary embedded_real

equation even evenfunc xpanded extended_numeric extended_rational facint filename finite float float[] form fraction freeof function global hfarray

identical imaginary implies in indexable indexed indexedfun infinity integer intersect last_name_eval laurent linear list listlist literal local logical mathfunc

Matrix matrix minus module moduledefinition monomial MonomialOrder MVIndex name negative negint negzero neg_infinity NONNEGATIVE nonnegative nonnegint nonposint nonpositive nonreal Not not nothing numeric odd oddfunc operator Or or OreAlgebra package patfunc patindex patlist Point point polynom posint positive poszero pos_infinity prime procedure property protected quadratic quartic Queue radalgfun radalgnum radext radfun radfunext radical radnum radnumext Range range rational ratpoly ratseq

realcons real_infinity relation RootOf rtable satisfies scalar SDMPolynom sequential SERIES series set sfloat ShortMonomialOrder SkewAlgebra SkewParamAlgebra SkewPolynomial specfunc specified_rootof Stack specindex sqrt stack std stdlib string subset suffixed symbol SymbolicInfinity symmfunc table tabular taylor TEXT trig trigh truefalse type typefunc

typeindex undefined uneval union unit unit_name Vector vector verification verify xor with_unit zppoly ^ ||

Данные идентификаторы используются в качестве фактического значения второго аргумента {type|typematch}-функции либо возвращаются whattype-процедурой в результате тестирования Maple-выражений. Часть данных типов рассматривалась выше, многие из оставшихся типов будут рассмотрены ниже при обсуждении соответствующих вопросов Maple-языка. В представленном списке количество типов больше, чем в предыдущих релизах пакета и, как правило, с ростом номера релиза количество поддерживаемых им типов также растет.

В качестве типов, отличных от базовых (представляемых единым идентификатором, принадлежащим приведенному выше списку, например: integer, trig, list, set, float и др.), Maple-язык поддерживает структурные типы, формальный синтаксис которых может описывать основную структуру тестируемых выражений. Maple-язык допускает структурные типы двух видов: простые и функциональные. Простые структурные типы имеют следующий синтаксис: <Тип_1>#<Тип_2>, где два базовых типа соединены знаком оператора (#); в качестве основных язык для них допускает следующие: `=` `<>` `<` `<=` `>` `>=` `..` and or not &+ &* `^` `.`. А также: '<Тип>', [<Тип>], name[<Тип>] и fcntype, определяющие соответственно невычисленное выражение, список, индексированную ссылку указанного типа и функцию специального типа. В качестве функционального структурного типа Mapleязык допускает следующие основные синтаксически корректные конструкции:

set(<Тип>) – множество элементов заданного типа; list(<Тип>) – список элементов заданного типа;

`&+`(<Тип>) – сумма термов заданного типа;

`&*`(<Тип>) – произведение сомножителей заданного типа; identical(<Выражение>) – выражение, идентичное заданному; anyfunc(<Тип>) – произвольная функция заданного типа, кроме exprseq; function(<Тип>) – произвольная функция с аргументами заданного типа; specfunc(<Тип>, F) – функция F с аргументами заданного типа.

Наряду с рассмотренным выше механизмом шаблонов Maple-язык поддерживает и механизм типированных шаблонов, базирующийся на структурных типах, typematch-функции и (::)-операторе типизации. По (::)-оператору, имеющему максимальный приоритет, конструкция вида Id::<Тип> приписывает Id-идентификатору заданный тип, который может быть как базовым, так и структурным. Рассмотренная в общих чертах typematchфункция имеет формат кодирования следующего вида: typematch(<Выражение>, <Типированный шаблон> {, '<Id>'})

В рамках первых двух аргументов typematch-функция совпадает с type-функцией и возвращает true-значение в случае соответствия типированной структуры тестируемого выражения заданному вторым аргументом типированному шаблону, определяемому базовым либо структурным типом, иначе возвращается false-значение.

Третий же ее необязательный 'Id'-аргумент определяет невычисленную переменную и в сочетании с (::)-оператором типирования позволяет существенно расширять механизм типированных шаблонов. Суть расширения данного механизма сводится в общих чертах к следующему: в типированный шаблон, определяемый в качестве второго фактического аргумента typematch-функции, каждому типу посредством (::)-оператора приписывается некоторая переменная (типированная) и в случае возврата функцией true-значения в переменную, определяемую третьим фактическим аргументом, помещается список конкретных значений типированных переменных шаблона, на которых тестируемое выражение, определяемое первым фактическим аргументом функции, обеспечивает возврат true-значения. Следующий несложный фрагмент иллюстрирует ряд примеров применения тестирующих функций {type, typematch}:

> [typematch((99-42)..(99), a::integer..b::integer, 'h'), h]; ⇒ [true, [a = 57, b = 99]]

> [typematch(sin(x)^exp(x), a::trig^b::function, 'h'), h]; ⇒ [true, [a = sin(x), b = exp(x)]]

> type([sin(x), exp(y), ln(z)], list(function)); ⇒ true

> [typematch([sin(x),exp(y),ln(z)],list(L::function), 'h'), h];

[true, [L=sin(x), L=exp(y), L=ln(z)]]

> [typematch(sin(x)^19.99, b::trig^f::float, 'h'), h]; ⇒ [true, [b = sin(x), f = 19.99]]

> [typematch(x + y, `&+`(n::name, b::name), 'h'), h]; ⇒ [true, [n = x, b = y]]

> type(Art + Kr^(1/3) + 99,`&+`(name, radical, integer)); ⇒ true

> type({sin(x), cos(y), tan(z)}, set(trig)); ⇒ true

> [typematch({sin(x), cos(y), tan(z)}, set(L::trig), 'h'), h];

[true, [L=sin(x), L=cos(y), L=tan(z)]]

> type(F(57/180,47/99,10/89,32/67),function(rational)); ⇒ true

> [typematch(F(57/180, 47/99, 10/89, 3/96), f::function(G::rational), 'h'), h];

true, G = 1960, G = 4799, G = 1089, G = 321 , f = F1960, 4799, 1089, 321 

> [typematch(A||V||Z*abs(I^2), k::identical(AVZ), 'h'), h]; ⇒ [true, [k = AVZ]] > [typematch(F(x)*G(x) = 57, a::`*`=b::integer, 'h'), h];

[true, [a = F(x) G(x), b = 57]]

> [typematch(F(x) <> 19.99, a::function <> b::float, 'h'), h]; ⇒ [true, [a = F(x), b = 19.99]]

> typematch((Art + 17)*(Kr + 10),`&+`(p::name, h::odd)&*`&+`(t::name, s::even)); ⇒ true > [typematch((tan(x)*sin(x))^(64/59), (a::trig &* b::trig)^c::rational, 'h'), h];

true, a = tan( )x , b = sin( )x , c = 6459

> [typematch(sin(x)*cos(x)^(V*G), a::trig &* b::trig^(c::name &* d::name), 'h'), h];

[true, [a = sin(x), b = cos(x), c = V, d = G]]

> typematch(Raadiku(64, 59, 39, 17, 10, 44, 95, 99), specfunc(integer, Raadiku)); ⇒ true

С учетом сказанного приведенный фрагмент достаточно прозрачен и каких-либо особых пояснений не требует. Вместе с тем, механизмы шаблонов, поддерживаемые Mapleязыком требуют для хорошего усвоения определенной наработки по их использованию, т. к. содержат целый ряд особенностей, здесь не рассматриваемых (см. прилож. 1 [12]).

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

Вместе с тем, для обеспечения структурного типированного анализа выражений весьма полезной представляется patmatch-процедура, имеющая формат кодирования: patmatch(<Выражение>, <Шаблон> {, 'h'})

где первый фактический аргумент определяет тестируемое выражение, а второй – тестирующий шаблон, т.е. шаблон, на соответствие которому проверяется исходное выражение.

Шаблон представляет собой типированное (::)-оператором алгебраическое выражение от ведущих переменных исходного выражения, на соответствие которому оно и проверяется. Процедура patmatch возвращает true-значение, если устанавливается структурно-типированное соответствие тестируемого выражения заданному шаблону, и false-значение в противном случае. В первом случае необязательной h-переменной присваивается список уравнений таких, что имеет место соотношение subs(h, <Шаблон>) = <Выражение>, во втором – h-переменная возвращается невычисленной (неопределенной). При этом, patmatch-процедура допускает использование и специального ключевого слова conditional, обеспечивающего возможность определения для шаблона дополнительных условий. Такие условия кодируются в одном из следующих двух форматах, а именно: conditional(<Шаблон>, <Условие>) и conditional(<Шаблон> = <B>, <Условие>)