По вызову процедуры trigsubs(<Уравнение>), где уравнение должно быть строго тригонометрическим, определяется факт его вхождения в trig-таблицу. В зависимости от {наличия|отсутствия} уравнения в таблице возвращается символьное значение {`found`|`not found`}. Процедура trigsubs работает с таблицей `trigsubs/TAB`, содержимое которой для текущего релиза можно получать по вызову eval(`trigsubs/TAB`).
По вызову процедуры trigsubs(<уравнение>, <выражение>) в случае принадлежности уравнения, заданного первым аргументом функции, trig-таблице производится подстановка его в заданное вторым аргументом выражение и возвращается результат такого редактирования; в противном случае выводится соответствующее диагностическое сообщение с рекомендациями. Следующий простой фрагмент иллюстрирует вышесказанное:
> trigsubs(cot(Pi + a*x)); cot(a x −cot(−a x), 12 cotcot a x2a x22 − 1, cossin((a xa x)), 1 + sin 2cos(2( a xa x) ), 1 − sin 2cos(2( a xa x) ),), 2 1 − tan a x 1 , − 1 , 1 22 , 1 cot a x2 − 21 tan a x2 , tan(a x) tan(−a x) 2 tan a x 2 ( ) (e a x I + e(−I a x)) I sin 2( a x) , ,(a x I) (−I a x) 1 − cos(2 a x) ((e )(1 + cos(2 a x)) − (e )(1 + cos(2 a x))) sin 2( a x) csc 2( a x) + cot 2( a x) > map(trigsubs, [sec(x)^2 = 1 + tan(x)^2, sin(x)^2 = 1 - cos(x)^2]); ⇒ [`found`, `found`] > map(trigsubs, [sin(x) = tan(x)*cos(x), cos(x) = cot(x)*sin(x)]); [`not found`, `not found`] > trigsubs(sin(2*t) = 2*cos(t)*sin(t), sin(2*t)*t + tan(t)); ⇒ 2 cos(t) sin(t) t + tan(t) > trigsubs(cos(x + y) = cos(x)*cos(y) - sin(x)*sin(y), cos(x + y)*t - 57*cos(x + y) + 2006); Error, (in trigsubs) not found in table - use subs to over ride |
Как видно из приведенного фрагмента, в случае невозможности выполнить преобразование выводится сообщение с рекомендацией воспользоваться subs-функцией.
Относительно использования eval-функции, имеющей простой формат кодирования: eval(<Выражение> {, n})
следует сделать отдельное пояснение. Под вычислением понимается подстановка вместо идентификатора приписанного ему значения, а каждый шаг в данном процессе определяет отдельный вычислительный уровень. По функции eval производится вычисление определенного ее первым фактическим аргументом выражения на его n-ом вычислительном уровне или полное вычисление выражения, если второй аргумент отсутствует. В интерактивном режиме с пакетом при вводе выражений производится их полное вычисление, как если бы к входящим в них идентификаторам применялась eval-функция. Иная ситуация имеет место, в частности, для Maple-процедур, для которых локальные переменные вычисляются только на первом уровне, как это иллюстрирует следующий весьма наглядный пример:
> Proc:=proc() local a, b, c; a:= b; b:= c; c:= d: a*b*c end proc: Proc(), eval(Proc()); ⇒ b c d, d3
Из приведенного примера видно, что при вызове Proc-процедуры вычисление локальных переменных {a, b, c} производится на первом уровне, о чем свидетельствует возвращаемый процедурой результат. Тогда как применение к вызову процедуры eval-функции обеспечивает полное вычисление процедуры. При этом, следует иметь в виду, что для полного вычисления локальных переменных могут потребоваться достаточно длинные цепочки присвоений, требующих затрат основных ресурсов ПК.
По subs-функции можно эффективно производить модифицирующие подстановки и в процедуры либо функции, однако данный механизм действует только на подвыражения тела процедуры, не содержащие локальных переменных, как это иллюстрирует следующий достаточно простой фрагмент:
> Proc:= proc(x, y) local a, b, c; sqrt(a*x^2 + b*y^2 + c)*sin(a*x) + cos(b*y) + 2006 end proc: > Proc1:=proc(x, y) global a,b,c; sqrt(a*x^2 + b*y^2 + c)*sin(a*x) + cos(b*y) + 2006 end proc: > subs([a=Pi, b=sigma, c=gamma], Proc1(x, y)); ⇒ π x2 + σ y2 + γ sin(π x) + cos(σ y) + 2006> subs([a=Pi, b=sigma, c=gamma], Proc(x, y)); ⇒ a x2 + b y2 + c sin(a x) + cos(b y) + 2006 > subs([a=sin(z),b=x*Pi], (x,y) -> sqrt(a*x+b*y)+a*b); ⇒ (x y, ) → sin( )z x + π x y + sin( )z π x |
Данная возможность позволяет использовать subs-функцию, а также рассматриваемые ниже другие средства подстановок, для целого ряда весьма полезных динамических модификаций процедур в прикладных задачах (при данном подходе базовое определение продедуры остается неизменым, модифицируясь только в точке ее вызова), для чего входящие в состав модифицируемых компонент идентификаторы при определении процедур следует указывать глобальными.
По вызову процедуры applyrule(R, V) обеспечивается применение к V-выражению правил подстановки, определяемых ее первым фактическим R-аргументом (одно правило либо их список) до тех пор, пока они допустимы. При этом, правила подстановки можно определять как уравнениями, так и в форме сложных шаблонов, допускаемых patmatchпроцедурой. Процедура applyrule эффективнее средств {subs, algsubs}, однако подобно algsubs-процедуре не производит математических преобразований обрабатываемого выражения, требуя для этих целей eval-функции. Следующий фрагмент иллюстрирует применение applyrule-процедуры для преобразования выражений:
> applyrule(x*h(x) = a*x^2 + b*x^2, x*h(x)+b*(d + x*h(x))); ⇒ a x2 + b x2 + b (d + a x2 + b x2) > algsubs(x*h(x)=a*x, x*h(x)); Error, (in algsubs) cannot compute degree of pattern in x > applyrule((a::float*x+b::integer*y)/c::function=Avz(h), (10.17*x+64*y)/sin(x)); ⇒ Avz(h) > applyrule((a::float*x + b::integer*y)/c::function = 4, sqrt((10.17*x + 64*y)/G(x))); ⇒ 4> applyrule([a=b, b=c, c=d, d=e, e=f,f=g,g=h], sqrt(Art^a+Kr^b+V*c)); ⇒ Arth + Krh + V h > T:= function: applyrule([a=b, b=a], a); ⇐ Прерванный бесконечный цикл Warning, computation interrupted > applyrule([a^2+b^2=Art+Kr, c::function =W(t)], sqrt(a^2+b^2)*G(x)); ⇒ Art + Kr W( )t> applyrule([a::T^b::T = Art(x), c::T/d::T = Kr(t)], S(x)^G(y) + V(x)/H(y)); ⇒ Art(x) + Kr(t) |
Для исключения зацикливаний, следует уделять особое внимание определению правил подстановок. Один из примеров фрагмента иллюстрирует простую ситуацию по зацикливанию вызова applyrule-процедуры. Вместе с тем, совместное использование средств subs, applyrule, asubs, powsubs и algsubs в сочетании с рядом других функциональных средств позволяют достаточно эффективно производить весьма интересные и важные символьные преобразования различного типа выражений.
Функциональные конструкции Maple-языка. Под функцией в Maple-языке понимается невычисляемая конструкция следующего общего вида:
<Идентификатор>(<Последовательность формальных аргументов>)
где идентификатор определяет уникальное имя функции, а последовательность допустимых Maple-выражений – список ее формальных аргументов. Примерами функций являются exp(x), sin(x), sqrt(x), AGN(x, y, z) и др. Maple-язык в качестве функций понимает любую из конструкций указанного типа, независимо от того, является ли она определенной. Рассмотренная выше функция type(<Выражение>, function) тестирует произвольное выражение Maple на предмет отношения его к типу “функция”. Как видно уже из следующего весьма простого примера:
> map(type, [F(x,y,z), sin(x), H(x, G(y), z)], 'function'); ⇒ [true, true, true] к данному (функциональному) типу Maple-язык относит как процедуру sin, так и неопределенную в его среде конструкцию указанного формата. Наряду с этим, тестирующая type-функция позволяет идентифицировать не только собственно функциональный тип выражения, указанного ее первым фактическим аргументом, но и детализировать математический тип выражения-функции согласно значению ее второго фактического аргумента, а именно:
algfun – алгебраическая функция; допускается тестировать по типу коэффициентов и ве- дущим переменным;
{arctrig|arctrigh} – обратная {тригонометрическая|гиперболическая} функция; допускается тестирование по ведущим переменным;
{evenfunc|oddfunc} – {четная|нечетная} функция; допускается тестировать по ведущим переменным;
radalgfun – алгебраическая функция, определенная в терминах RootOf и радикалов; до- пускается тестирование по ведущим переменным и типам коэффициентов; radfunextn – алгебраическое функциональное расширение в терминах радикалов; radfun – радикальная функция; допускается тестирование по ведущим переменным и ти- пам коэффициентов;
mathfunc – математическая функция; тестируется любая функция из приложения 8 [12]; {trig|trigh} – {тригонометрическая|гиперболическая} функция; допускается тестирование по ведущим переменным.
При этом, алгебраическим полагается Maple-выражение одного из следующих типов:
integer fraction float string indexed `+` `*` `^` `**` series function `!` `.` uneval
а под ведущей xj-переменной произвольной F(x1, ..., xn)-функции такая переменная, на которой имеет место следующее определяющее соотношение:
(∃x`j) (∃x``j) (x`j≠x``j → F(x1, ..., x`j , ..., xn) ≠ F(x1, ..., x``j ,..., xn)) (j = 1 .. n)
Следующий фрагмент иллюстрирует применение этих значений в качестве 2-го аргумента type-функции для тестирования типов функций, указанных ее 1-м аргументом: