Error, illegal use of an object as a name
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
к режиму параллельного сервера, когда все загруженные документы являются независимыми. Режим параллельного сервера детально рассмотрен в [9-12]. При этом, определение считается сделанным только после его реального вычисления. После перезагрузки пакета все определения переменных и пользовательских функций/процедур (отсутствующих в библиотеках,
логически сцепленных с главной библиотекой пакета) теряются, требуя нового переопределения. Без перезагрузки пакета этого можно добиться по restart-предложению, приводящего все установки ядра пакета в исходное состояние (очистка РОП, отмена всех сделанных ранее определений, выгрузка всех загруженных модулей и т.д.), либо присвоением идентификаторам переменных невычисленных значений вида Id:= ‘Id’. Следующий простой фрагмент иллюстрирует вышесказанное:
> x:= 19.42: y:= 30.175: Grodno:= sin(x) + cos(y); Grodno := 0.8639257079 > restart; Grodno:= sin(x) + cos(y); Grodno := sin(x) + cos(y)
> G:= proc() nargs end proc: G(42, 47, 67, 62, 89, 96); 6 > G:= ‘G’: G(42, 47, 67, 62, 89, 96); G(42, 47, 67, 62, 89, 96)
Из фрагмента хорошо видно, что ранее сделанное определение Grodno-переменной отменяется после выполнения restart-предложения. Выполнение restart-предложения следует лишь на внешнем уровне ТД и не рекомендуется внутри ряда его конструкций (процедуры, функ— ции и др.) во избежание возникновения особых и аварийных ситуаций, включая “зависание” пакета, требующее перезагрузки ПК. При этом, следует иметь в виду, что освобождаемая в этом случае память не возвращается операционной среде, а присоединяется к собственному пулу свободной памяти пакета. Поэтому при необходимости получения максимально возможной памяти для решения больших задач пользователю рекомендуется все же производить перезагрузку пакета в Windows-среде. Тогда как второй способ отмены определенности для переменных более универсален. В книге [103] и прилагаемой к ней библиотеке представлены средства, обеспечивающие возможность восстановления из процедур исходного состояния объектов. Например, вызов процедуры prestart() очищает все переменные, определенные в текущем сеансе, исключая пакетные переменные.
Предложение присвоения. Идентификатору может быть присвоено любое допустимое Maple— выражение, делающее его определенным; в противном случае идентификатор называется неопределенным, результатом вычисления которого является символьное представление самого идентификатора, что весьма прозрачно иллюстрирует следующий простой пример:
>macro(Salcombe = Vasco): Eesti:= 19.95: Vasco:= Noosphere: Tallinn:= 20.06:
>TRG:= sqrt(Lasnamae*(Eesti + Tallinn)/(Salcombe + Vasco)) + `Baltic Branch`;
TRG := 4.472694937 |
Lasnamae |
+ Baltic Branch |
|
Noosphere |
|||
Присвоение идентификатору определенного или неопределенного значения производится посредством традиционного (:=)-оператора присвоения вида А:= В, присваивающего левой А-части В-значение. При этом, в качестве левой А-части могут выступать простой идентификатор, индексированный идентификатор или идентификатор функции с аргументами. Точнее, присвоение А-части В-значения корректно, если A имеет assignable-тип, т.е. type(A, ‘assignable’); true. Вычисленное (или упрощенное) значение В-части присваивается идентификатору А-части.
Оператор присваивания допускает возможность множественного присваивания и определяется конструкциями следующего простого вида:
Id1, Id2, …, Idn:= <Выражение_1>, <Выражение_2>, …, <Выражение_n>
При этом, при равном количестве компонент правой и левой частей присвоения производятся на основе взаимно-однозначного соответствия. В противном случае инициируются ошибочные ситуации «Error, ambiguous multiple assignment» либо «Error, cannot split rhs for multiple assignment«. Следующий фрагмент иллюстрирует случаи множественного присваивания:
31
> A, B, C:= 64, 59:
Error, ambiguous multiple assignment
> V, G, S, Art, Kr, Arn:= 64, 59, 39, 17, 10, 44: [V, G, S, Art, Kr, Arn];
[64, 59, 39, 17, 10, 44]
> x, y, z, t, h:= 2006: [x, y, z, t, h];
Error, cannot split rhs for multiple assignment
[x, y, z, t, h]
Примеры фрагмента достаточно прозрачны и особых пояснений не требуют. Сам принцип реализации множественного присваивания также достаточно прост. Вместе с тем, языком не поддерживаются уже достаточно простые конструкции множественного присваивания, что иллюстрируют первый и последний примеры фрагмента.
Между тем, в ряде случаев возникает необходимость назначения того же самого выражения достаточно длинной последовательности имен или запросов функций. Данная проблема решается оператором &ma, который имеет идентичный с оператором `:=` приоритет. Оператор &ma имеет два формата кодирования, а именно: процедурный и операторный форматы:
&ma(‘x’, ‘y’, ‘z’, …, <rhs>) |
и |
(‘x’, ‘y’, ‘z’, …) &ma (<rhs>) |
В общем случае, в обоих случаях в конструкции lhs &ma rhs элементы lhs должны быть закодированы в невычисленном формате, т.е. в апострофах (‘). Исключение составляет лишь первый случай присвоения. Кроме того, в операторном формате, левая часть lhs должна быть закодирована в скобках. Кроме того, если правая часть rhs удовлетворяет условию type(rhs, {‘..’, ‘<‘, ` <= `, ‘.’, ‘*’, ‘^’, ‘+’, ‘=’}) = true, то правая часть должна также кодироваться в скобках. Наконец, если необходимо присвоить NULL-значение (т. е. ничего) элементам левой части lhs, то в качестве правой части rhs кодируется _NULL-значение. Успешный вызов процедуры &ma или применения оператора &ma возвращает NULL-значение, т. е. ничего с выполнением указанных присвоений. В целом ряде приложений оператор/процедура &ma представляются достаточно полезными [103]. Ниже приведен ряд примеров на применение оператора &ma:
Процедурный формат
> &ma(h(x), g(y), v(z), r(g), w(h), (a + b)/(c — d)); h(x), g(y), v(z), r(g), w(h);
a + b a + b a + b a + b a + b |
|||||||||
, |
, |
, |
, |
||||||
c − d |
c − d |
c − d |
c − d |
c − d |
|||||
> &ma(‘x’, ‘y’, ‘z’, ‘g’, ‘h’, «(a + b)/(c — d)»); |
x, y, z, g, h; |
«(a+b)/(c-d)», «(a+b)/(c-d)», «(a+b)/(c-d)», «(a+b)/(c-d)», «(a+b)/(c-d)»
> &ma(‘x’, ‘y’, ‘z’, ‘g’, ‘h’, _NULL); x, y, z, g, h;
> &ma’x’, ‘y’, ‘z’, ‘g’, ‘h’, 2006); x, y, z, g, h; |
2006, 2006, 2006, 2006, 2006 |
|||||||||||
> &ma(‘x’, ‘y’, ‘z’, ‘g’, ‘h’, sin(a)*cos(b)); x, y, z, g, h; |
||||||||||||
sin(a) cos(b), sin(a) cos(b), sin(a) cos(b), sin(a) cos(b), sin(a) cos(b) |
||||||||||||
Операторный формат |
||||||||||||
> (‘x’, ‘y’, ‘z’, ‘g’, ‘h’) |
&ma |
_NULL; x, y, z, g, h; |
||||||||||
> (‘x’, ‘y’, ‘z’, ‘g’, ‘h’) |
&ma |
2006; x, y, z, g, h; 2006, 2006, 2006, 2006, 2006 |
||||||||||
> (‘x’, ‘y’, ‘z’, ‘g’, ‘h’) |
&ma |
(sin(a)*cos(b)); |
x, y, z, g, h; |
|||||||||
sin(a) cos(b), sin(a) cos(b), sin(a) cos(b), sin(a) cos(b), sin(a) cos(b) |
||||||||||||
> (‘x’, ‘y’, ‘z’, ‘g’, ‘h’) |
&ma |
((a + b)/(c — d)); |
x, y, z, g, h; |
|||||||||
a + b a + b a + b a + b a + b |
||||||||||||
, |
, |
, |
, |
|||||||||
c − d |
c − d |
c − d |
c − d |
c − d |
Для проверки идентификатора на предмет его определенности используется встроенная функция assigned языка, кодируемая в виде assigned(Идентификатор) и возвращающая значение true в случае определенности идентификатора (простого, индексированного или вызова функции/процедуры), и false-значение в противном случае. При этом, следует иметь в виду, что определенным идентификатор полагается тогда, когда он был использован в качестве левой части (:=)-оператора присвоения, даже если его правая часть являлась неопределенной. Ли-
32
бо он получил присвоение по аssign-процедуре. Следующий простой фрагмент иллюстрирует вышесказанное:
> agn:= 1947: avz:= grodno: assign(vsv=1967, art=kr): seq(assigned(k), k= [agn, avz, vsv, art]); true, true, true, true
> map(type,[agn, avz, vsv, art],’assignable’);
[false, true, false, true]
> map(assigned, [agn, avz, vsv, art]);
Error, illegal use of an object as a name
С другой стороны, по конструкции type(Id, ‘assignable’) можно тестировать допустимость присвоения Id–переменной (простой, индексированной или вызова функции/процедуры) выражения: возврат true-значения говорит о такой возможности, false – нет. Следует обратить внимание на последний пример фрагмента, иллюстрирующий некорректность использования встроенной функции map при попытке организации простого цикла.
Вызов функции indets(W {, <Тип>}) возвращает множество всех идентификаторов заданного его первым фактическим W-аргументом Maple-выражения. При этом, W-выражение рассматривается функцией рациональным, т.е. образованным посредством {+, —, *, /}-операций. Поэтому в качестве результата могут возвращаться не только простые идентификаторы W-выра- жения, но и неопределенные его подвыражения. В случае кодирования второго необязательного аргумента, он определяет тип возвращаемых идентификаторов, являясь своего рода фильтром. В качестве второго фактического аргумента могут выступать как отдельный тип, так и их множество в соответствии с типами, распознаваемыми тестирующей type-функцией языка, рассматриваемой детально ниже. Следующий фрагмент иллюстрирует применение indets-функции для выделения идентификаторов переменных:
> indets(x^3 + 57*y — 99*x*y + (z + sin(t))/(a + b + c) = G);
{sin(t), x, y, z, t, a, b, c, G}
> indets(x^3 + 57*y — 99*x*y + (z + sin(t))/(a + b + c) = G, function);
{sin(t)}
> indets(x^3 + z/y — 99*x*y + sin(t), {integer, name});
{-99, -1, 3, x, y, z, t}
> indets(x^3 + z/y — 99*x*y + sin(t), {integer, name, `*`, `+`});
{-99, -1, 3, x3 + yz − 99 x y + sin(t ), yz , −99 x y, x, y, z, t }
> indets(x^3 + z/y — 99*x*y + sin(t), {algnum, trig});
{-99, -1, 3, sin(t)}
Из приведенного фрагмента, в частности, следует, что по indets-функции можно получать не только неопределенные идентификаторы, но и числовые компоненты тестируемого выражения, а также совокупности комбинаций составляющих его компонент. Таким образом, indets-функция несет существенно более развитую смысловую нагрузку, чем определение простых идентификаторов. По своим возможностям она представляется достаточно эффективным средством при решении задач символьных обработки и анализа выражений, а также в целом ряде других важных задач.
Для возможности использования произвольного А-выражения в качестве объекта, которому могут присваиваться значения, Maple-язык располагает evaln-функцией, кодируемой в виде evaln(A) и возвращающей имя выражения. В качестве А-выражения допускаются: простой идентификатор, индексированный идентификатор, вызов функции/процедуры или конкатенация символов. В результате применения к А-выражению evaln-функции оно становится доступным для присвоения ему значений, однако если ему не было сделано реального присвоения, то применение к нему assigned-функции возвращает значение false, т.е. А-выраже- ние остается неопределенным. Таким образом, по конструкции Id:= evaln(Id) производится
33
отмена присвоенного Id-идентификатору значения, делая его неопределенным, как это иллюстрирует следующий простой фрагмент:
> Asv:= 32: assigned(Asv); Asv:= evaln(Asv): Asv, assigned(Asv); true
Asv, false
> Asv:= 67: assigned(Asv); Asv:= ‘Asv’: Asv, assigned(Asv); true
Asv, false
Из приведенного фрагмента непосредственно следует, что первоначальное присвоение Asv— идентификатору значения делает его определенным, на что указывает и результат вызова assigned-функции. Тогда как последующее вычисление предложения Asv:=evaln(Asv) делает Asv-идентификатор вновь неопределенным. Вторым способом приведения идентификатора к неопределенному состоянию является использование конструкции вида Id:= ‘Id’, как это иллюстрирует второй пример фрагмента.
Для выполнения присвоений можно воспользоваться и assign-процедурой, допускающей в общем случае три формата кодирования, а именно: assign({A, B|A = B|C}), где А – идентификатор, В — любое допустимое выражение и С — список, множество или последовательность уравнений. В первых двух случаях применение assign-процедуры эквивалентно применению (:=)-оператора присвоения, тогда как третий случай применяется для обеспечения присвоения левой части каждого элемента списка, множества или последовательности уравнений. Простой фрагмент иллюстрирует вышесказанное:
>assign(AGn, 59); assign(AVz=64); assign([xx=1, yy=2, zz=3, h=cos(y)*tan(z)]);
>assign({xx1=4, yy1=5, zz1=6, y=x*sin(x)}); [AGn, AVz, xx, yy, zz, xx1, yy1, zz1, y, h];
[59, 64, 1, 2, 3, 4, 5, 6, x sin(x), cos(x sin(x)) tan(z)]
> assign(‘x’, assign(‘y’, assign(‘z’, 64))); [x, y, z]; |
# Maple 7 и выше |
[64] |
|
> assign(‘x’, assign(‘y’, assign(‘z’, 64))); [x, y, z]; |
# Maple 6 и ниже |
Error, (in assign) invalid arguments
> `if`(type(AV, ‘symbol’) = true, assign(AV, 64), false); AV;
64
> GS:= op([57*sin(19.95), assign(‘VG’, 52)]) + VG*cos(19.99);
GS := 72.50422598
Успешное выполнение assign-процедуры производит указанные присвоения и возвращает NULL-значение, в противном случае инициируется соответствующая ошибочная ситуация. Данная ситуация, в частности, возникает при попытке рекурсивного вызова assign-процеду- ры для релизов 6 и ниже, тогда как в более старших релизах подобного ограничения нет. По отношению к процедуре assign релизы пакета характеризуются весьма существенной несовместимостью, что стимулировало нас к созданию аналога стандартной процедуры, который не только устраняет указанную несовместимость, но и расширяет функциональные возможности [31,39,41-43,45,46,103]. Это и другие наши средства рассмотрены детально в книге [103] и представлены в прилагаемой к ней библиотеке программных средств.
При этом, следует отметить, что в целом ряде случаев assign-процедура является единственно возможным способом присвоения значений, например, внутри выражений, как это иллюстрирует последний пример фрагмента, который содержит структуры и функции, рассматриваемые ниже. Механизм assign-процедуры достаточно эффективен в различных вычислительных констукциях, многочисленные примеры применения которого приводятся ниже при рассмотрении различных аспектов Maple-языка, а также в нашей библиотеке [103].
Обратной к assign-процедуре является unassign-процедура с форматом кодирования:
unassign(<Идентификатор_1>, <Идентификатор_2>, …)
34
отменяющая определения для указанных последовательностью ее фактических аргументов идентификаторов. Успешный вызов процедуры unassign выполняет отмену назначений, возвращая NULL-значение. Однако, процедура не действует на идентификаторы с protected-ат- рибутом, инициируя ошибочную ситуацию с выводом соответствующей диагностики. Приведем простые примеры на использование unassign-процедуры.
> AS:= 39: AV:= 64: AG:= 59: Kr:= 10: Art:= 17: AS, AV, AG, Kr, Art;
39, 64, 59, 10, 17
> unassign(AS, AV, AG, Kr, Art);
Error, (in unassign) cannot unassign ’39’ (argument must be assignable)
> unassign(‘AS’, ‘AV’, ‘AG’, ‘Kr’, ‘Art’); AS, AV, AG, Kr, Art;
AS, AV, AG, Kr, Art
> `if`(type(AV, ‘symbol’)=true, assign(AV, 64), unassign(‘AV’)); AV;
64
Вприведенном фрагменте пяти переменным присваиваются целочисленные значения, а затем по unassign-процедуре делается попытка отменить сделанные назначения. Попытка вызывает ошибочную ситуацию, обусловленную тем, что в точке вызова unassign-процедуре передаются не сами идентификаторы, а их значения (кстати, именно данная ситуация одна из наиболее типичных при ошибочных вызовах assign—процедуры). Для устранения ее идентификаторы следует кодировать в невычисленном формате (кодируя в апострофах), что и иллюстрирует повторный вызов unassign-процедуры. Последний пример иллюстрирует применение процедур assign и unassign в условном if-предложении языка, по которому AV-переменной присваивается целочисленное значение, если она была неопределенной, и отменяется ее определение в противном случае.
Вцелях защиты идентификаторов от возможных модификаций их определений (назначений) им присваивается protected-атрибут, делающий невозможной какую-либо модификацию указанного типа. Большинство пакетных идентификаторов имеют protected-атрибут, в чем легко убедиться, применяя к ним attributes-функцию, кодируемую в следующем формате:
attributes(<Идентификатор>)
и возвращающую значения атрибутов заданного идентификатора, в частности protected-ат- рибута. Если идентификатору не приписано атрибутов, то вызов на нем attributes-функции возвращает NULL-значение, т.е. ничего. Для защиты от модификации либо снятия защиты используются процедуры protect и unprotect языка Maple соответственно, кодируемые в следующем простом формате:
{protect|unprotect}(<Идентификатор_1>, <Идентификатор_2>, …)
Следующий весьма простой фрагмент Maple-документа иллюстрирует вышесказанное:
>protect(AV_42); attributes(AV_42); protected
>unassign(AV_42);
Error, (in assign) attempting to assign to `AV_42` which is protected
> AV_42:= 64:
Error, attempting to assign to `AV_42` which is protected
> unprotect(AV_42); attributes(AV_42); AV_42:= 64;
AV_42 := 64
Следует при этом отметить, что действие protect-процедуры не распространяется на глобаль— ные предопределенные переменные Maple, значения которых можно модифицировать согласно условиям пользователя. Такая попытка вызывает ошибочную ситуацию:
> map(attributes,[Digits,Order,printlevel]);protect(‘Digits’);protect(‘Order’);protect(‘printlevel’);
[]
Error, (in protect) an Environment variable cannot be protected Error, (in protect) an Environment variable cannot be protected Error, (in protect) an Environment variable cannot be protected
35
Хотя по unprotect-процедуре отменяется protected-атрибут любого идентификатора, однако для пакетных идентификаторов этого (по целому ряду причин, здесь не рассматриваемых) не рекомендуется делать.
В целом ряде случаев в качестве весьма полезных средств могут выступать две встроенные функции со следующими форматами кодирования: unames() и anames({ |<Тип>}), возвращающие последовательности соответственно неопределенных и определенных идентификаторов (как пользовательских, так и пакетных), приписанных текущему Maple-сеансу. При этом, для случая anames-функции можно получать выборку определенных идентификаторов, значения которых имеют указанный Тип. Следующий фрагмент иллюстрирует результат вызова указанных выше функций:
> restart; unames();
identical, anyfunc, equation, positive, Integer, restart, radical, And, gamma, neg_infinity, none, default, nonposint, relation, odd, infolevel, indexable, algebraic, SFloat, RootOf, TABLE, float, real_to_complex, embedded_real, vector, _syslib, realcons, name, assign, INTERFACE_GET, …
> restart: SV:= 39: GS:= 82: Art:= sin(17): Kr:= sqrt(10): AV:= 64: anames();
sqrt/primes, type/interfaceargs, GS, sqrt, AV, csgn, interface, type/SymbolicInfinity, Art, sin, SV, Kr
> anames(‘integer’); # Maple 8
sqrt/primes, GS, Digits, printlevel, Order, AV, SV
> anames(‘environment’);
Testzero, UseHardwareFloats, Rounding, %, %%%, Digits, index/newtable, mod, %%, Order, printlevel, Normalizer, NumericEventHandlers
> SV:= 39: GS:= 82: `Art/Kr`:= sin(17): Kr:= sqrt(10): _AV:= 64: anames(‘user’); # Maple 10
Kr, SV, GS
> anames(‘alluser’);
Kr, SV, GS, _AV, Art/Kr
При этом, unames-функция была вызвана в самом начале сеанса работы с пакетом и возвращаемый ею результат представлен только начальным отрезком достаточно длинной последовательности пакетных идентификаторов. Что касается anames-функции, то она в качестве второго необязательного аргумента допускает тип, идентификаторы с которым будут ею возвращаться. При этом, дополнительно к типу и в зависимости от релиза в качестве второго аргумента допускается использование таких ключевых слов как environment, user, alluser, с назначением которых можно ознакомиться по справочной базе пакета.
36
1.3. Средства Maple-языка для определения свойств
переменных
Важным средством управления вычислениями и преобразованиями в среде Maple-языка является assume-процедура и ряд сопутствующих ей средств. Процедура имеет следующие три формата кодирования:
assume(x1, p1, x2, p2, …) assume(x1::p1, x2::p2, …) assume(x1p1, x2p2, …)
и позволяет наделять идентификаторы (переменные) или допустимые Maple-выражения xj заданными свойствами pj, т.е. устанавливать определенные свойства и соотношения между ними. Третий формат процедуры определяет соотношения, налагающие свойство pj на выражение xj. Например, простейшие, но весьма часто используемые вызовы assume(x >= 0) процедуры, определяют для некоторой х-переменной свойство быть неотрицательной действительной константой. Наделяемое по assume-процедуре свойство не является пассивным и соответствующим образом обрабатывается Maple-языком пакета при выполнении вычислений либо преобразований выражений, содержащих переменные, наделенные подобными свойствами. Тестировать наличие приписанного х-переменной свойства можно по вызову процедуры about(x), тогда как наделять х-переменную дополнительными свойствами можно по вызову процедуры additionally(x, Свойство). Следующий фрагмент иллюстрирует сказанное:
> assume(x >= 0): map(about, [x, y, z]); [ ]
Originally x, renamed x~: is assumed to be: RealRange(0, infinity) y: nothing known about this object
z: nothing known about this object |
||
> assume(a >= 0): A:= sqrt(-a): assume(a <= 0): B:= sqrt(-a): [A, B]; |
[ a~ I, −a~ ] |
|
> simplify(map(sqrt, [x^2*a, y^2*a, z^2*a])); [x~ |
−a~ I, y2 a~ , |
z2 a~ ] |
> additionally(x, ‘odd’): about(x); |
||
Originally x, renamed x~: is assumed to be: |
||
AndProp(RealRange(0, infinity), LinearProp(2, integer, 1)) |
||
> map(is, [x, y, z], ‘odd’, ‘posint’); [true, false, false] |
||
> assume(y, ‘natural’): map(is, [x, y], ‘nonnegative’); |
[true, true] |
|
> unassign(‘x’): about(x); |
||
x: nothing known about this object |
> assume(y, {y >= 0, y < 64, ‘odd’}): about(y);
Originally y, renamed y~: is assumed to be: {LinearProp(2,integer,1), 0 <= y, y < 64}
> hasassumptions(y); true
Из примеров данного фрагмента, в частности, следует, что переменная с приписанным ей свойством выводится помеченной символом тильды ( ), а по about-процедуре выводится информация о всех приписанных переменной свойствах либо об их отсутствии. Один из примеров фрагмента иллюстрирует влияние наличия свойства положительной определенности переменной на результат упрощения содержащего ее выражения. В другом примере фрагмента иллюстрируется возможность определения для переменной множественности свойств, определяемых как поддерживаемыми языком стандартными свойствами, так и допустимыми отношениями для переменной. Вызов процедуры hasassumptions(x) возвращает true, если на x-выражение было наложено какое-либо соотношение, и false в противном случае.
Режим идентификации assume-переменных определяется showassumed-параметром interface— процедуры, принимающим значение {0|1 (по умолчанию)|2}: 0 — отсутствует идентификация, 1 — переменные сопровождаются знаком тильды и 2 — все такие переменные перечисляются в конце выражений, как это иллюстрирует следующий весьма простой фрагмент:
> assume(V >= 64): assume(G >= 59): S:= V+G; interface(showassumed=0); V + G;
S := V~ + G~
37
V + G
> assume(Art >= 17, Kr >= 10): interface(showassumed=2): S^2 + (Art + Kr)^2;
S2 + (Art + Kr)2
with assumptions on Art and Kr
> assume(x, ‘odd’, y::integer, z >= 0), is(x + y, ‘integer’); true
> x:= ‘x’: unassign(‘y’), map(is, [x, y], ‘integer’), is(z, ‘nonnegative’); [false, false], true
До 7-го релиза включительно оперативно переопределять режим идентификации assume-пе- ременных можно было переключателями функции Assumed Variables группы Options GUI.
По тестирующей процедуре is(x, Свойство) возвращается true-значение, если х-переменная обладает указанным вторым фактическим аргументом свойством, и значение false в противном случае. При невозможности идентифицировать для х-переменной свойство (например,
если она по assume—процедуре свойствами не наделялась) возвращается FAIL-значение. Наконец, отменять приписанные х-переменной свойства можно посредством выполнения простой конструкции x:= ‘x’ либо вызовом unassign(‘x’); сказанное иллюстрируют последние примеры предыдущего фрагмента. При этом, проверять можно как конкретную отдельную переменную, так и выражение по нескольким ведущим переменным и набору искомых свойств.
Maple-язык поддерживает работу со свойствами шести основных групп, а именно:
1) имя свойства, например, continuous, unary;
2) большинство имен типов, например, integer, float, odd, even;
3) числовые диапазоны, например, RealRange(a, b), RealRange(-infinity, b), RealRange( a, infinity), где a и b могут быть или числовыми значениями или Open(a), где a – числовое значение
4) AndProp(a, b, …) – and-выражение свойств <a and b and …>, где a, b, … – свойства, определенные выше
5) OrProp(a, b, …) – or- выражение свойств, где объект может удовлетворять любому из a, b, …
свойств
6) диапазон свойств p1 .. p2, где p1 и p2 свойства. Данное свойство означает, что объект удовлетворяет по меньшей мере p2, но не более, чем p1; например, integer .. rational удовлетворяется integers/2.
За более детальной информацией по поддерживаемым Maple-языком свойствам остальных групп можно обращаться либо к справке по пакету, либо к книгам [8-14,78-86,88,103,105].
Механизм свойств, определяемый assume и сопутствующей ей группой процедур coulditbe, additionally, is, about, hasassumptions и addproperty, использует специальную глобальную
_EnvTry-переменную для определения режима как идентификации у переменных приписанных им свойств, так и их обработки. При этом, данная переменная допускает только два значения: normal (по умолчанию) и hard, из которых указание второго значения может потребовать при вычислениях существенных временных затрат. В текущих реализациях пакета значение глобальной _EnvTry-переменной, определяющей режим обработки переменных, наделенных assume-свойствами, не определено, что иллюстрирует следующий достаточно прозрачный фрагмент:
>_EnvTry, about(_EnvTry); _EnvTry
_EnvTry: nothing known about this object
>assume(V >= 64): about(V);
Originally V, renamed V~: is assumed to be: RealRange(64, infinity)
> `if`(is(V, RealRange(64, infinity)), ln(V) + 42, sqrt(Art + Kr)); ln(V~) + 42
> assume(47 <= G, G <= 59): about(G); |
|
Originally G, renamed G~: is assumed to be: RealRange(47, 59) |
|
> `if`(is(G, RealRange(47, 59)), [10, 17, Sv, Art, Kr], Family(x, y, z)); |
[10, 17, Sv, Art, Kr] |
> assume(x >= 0), simplify(sqrt(x^2)), simplify(sqrt(y^2)); x~, csgn(y) y |
|
> sqrt(a*b), sqrt(a^2), assume(a >= 0, b <= 0), sqrt(a*b), sqrt(a^2); |
a b, a2 , −a~ b~ I, a~ |
38
Механизм приписанных свойств является достаточно развитым и мощным средством как чи— словых вычислений, так и символьных вычислений и преобразований. Использование его оказывается весьма эффективным при программировании целого ряда важных задач во многих приложениях. Последние примеры предыдущего фрагмента иллюстрируют некоторые простые элементы его использования в конкретном программировании. Тогда как конкретный assume-механизм базируется на алгоритмах Т. Вейбеля и Г. Гоннета. С интересным обсуждением принципов его применения, реализации и ограничений можно довольно детально ознакомиться в интересных работах указанных авторов, цитируемых в конце справки по пакету (см. ?assume), и цитируемых в них многочисленных источниках различного назначения.
39
1.4. Типы числовых и символьных данных Maple-языка
Средства Maple-языка поддерживают работу как с простыми, так и сложными типами данных числового или символьного (алгебраического) характера. В первую очередь рассмотрим типы простых данных числового характера, предварив краткой информацией по очень важным встроенным функциям nops и op, непосредственно связанных со структурной организацией Maple-выражений. Первая функция возвращает число операндов выражения, заданного ее единственным фактическим аргументом. Тогда как вторая имеет более сложный формат кодирования следующего вида:
op({ |n,|n..m,|<Список>,} <Выражение>)
где первый необязательный фактический аргумент определяет возврат соответственно: n-го операнда, с n-го по m-й операнды либо операнды согласно Списка их позиций в порядке возрастания уровней вложенности Выражения. При этом, при n=0 возвращается тип самого выражения, а в случае отсутствия указанного первым аргументом операнда инициируется ошибочная ситуация. Для случая n < 0 выполняется соотношение op(n,V) ≡ op(nops(V)+n+1,V), где V — выражение, а для неопределенного Id-идентификатора имеют место соотношения: op(0, Id) symbol и op(1, Id) Id. Отсутствие первого аргумента op-функции аналогично вызову вида op(1..nops(V),V). Для вывода структурной организации произвольного выражения может оказаться полезной конструкция вида:
op(‘k’, <Выражение>) $’k’=0 .. nops(<Выражение>)
вычисление которой возвращает последовательность типа и всех операндов первого уровня вложенности указанного выражения, как это иллюстрирует следующий простой пример:
> Art:= 3*sin(x) + 10*cos(y)/AV + sqrt(AG^2 + AS^2)*TRG: op(‘k’, Art)$’k’=0 .. nops(Art);
+, 3 sin(x), |
5 |
cos(y), AG2 + AS2 |
TRG |
||
32 |
|||||
Ниже будет рассмотрено достаточно средств Maple-языка, ориентированных на задачи символьной обработки выражений, включая и те, которые базируются на их структурном анализе. Целый ряд средств для решения подобных задач предоставляет и наша Библиотека [103]. Нам же для дальнейшего будет пока вполне достаточно информации по nops и op.
• Целые (integer); представляют собой цепочки из одной или более цифр, максимальная длина которых определяется используемой платформой ЭВМ: для 32-битной она не превышает 524280 цифр, а для 64-битной — 38654705646 цифр. Целые могут быть со знаком и без: 1999, — 57, 140642. На числах данного типа функции op и nops возвращают соответственно значение числа и значение 1, тогда как функция type идентифицирует их тип как integer, например:
> op(429957123456789), nops(429957123456789); 429957123456789, 1 > type(429957123456789, ‘integer’); true
• Действительные (float) с плавающей точкой; представляют собой цепочки из десятичных цифр с десятичной точкой в {начале|середине|конце} цепочки; числа данного типа допускают следующие два основных формата кодирования:
[<знак>]{<целое>.<целое>|.<целое>|<целое>.} Float([<знак>]<мантисса>, [<знак>]<экспонента>) ≡ [<знак>]<мантисса>.{E|e}[<знак>]<экспонента>
В качестве мантиссы и экспоненты используются целые со знаком или без; при этом, мантисса может иметь любую длину, но экспонента ограничивается длиной машинного слова: для 32битной платформы значение экспоненты не превышает целого 2147483647, а для 64-битной платформы – целого значения 9223372036854775807. Тогда как максимальное допустимое число цифр мантиссы аналогично максимальному допустимому числу цифр целого (integer) числа. Число цифр мантиссы, участвующих в операциях арифметики с плавающей точкой,
40
Соседние файлы в папке Books
- #
- #
18.03.201519.23 Mб35Дьяконов_maple_9.5-10.djvu
0 / 0 / 0
Регистрация: 30.03.2017
Сообщений: 7
1
Не работает процедура
03.05.2020, 11:44. Показов 646. Ответов 1
Добрый день!
Решала задачи по методичке 15_04_2020.pdf, но на этапе процедуры Maple стал выдавать ошибку.
Проверяла данный код в Maple 13 и 2016, пыталась самостоятельно определить ошибку, но так ни к чему и не пришла.
Сама процедура:
Код
p:=proc(k) global t_och1,t_och2,t_och3,sm_t_obs,post,otk,obsl: local t1,t_okon,t,rn_post,och,per: t_och1:=0:t_och2:=0:t_och3:=0:post:=0:otk:=0:obsl:=0:t_okon:=0:sm_t_obs:=0:och:=0:rn_post:=rand(1..1200): for t from 1 by 1 to k do t1:=rn_post(): if och=1 then t_och1:=t_och1+1 fi: if och=2 then t_och2:=t_och2+1 fi: if och=3 then t_och3:=t_och3+1 fi: if t1>=1 and t1<=17 and t_okon=0 and och>=0 and och<=3 then per:=1 fi: if t1>=1 and t1<=17 and t_okon>0 and och>=0 and och<3 then per:=2 fi: if t1>=1 and t1<=17 and t_okon>0 and och=3 then per:=3 fi: if t1>17 and t_okon>0 then per:=4 fi: if t1>17 and t_okon=0 and och>0 then per:=5 fi: if per=1 then t_okon:=stats[random,poisson[65]](): sm_t_obs:=sm_t_obs+t_okon:obsl:=obsl+1:post:=post+1 fi: if per=2 then t_okon:=t_okon-1:obsl:=obsl+1:och:=och+1:post:=post+1 fi: if per=3 then t_okon:=t_okon-1:otk:=otk+1:post:=post+1 fi: if per=4 then t_okon:=t_okon-1 fi: if per=5 then t_okon:=stats[random,poisson[65]](): sm_t_obs:=sm_t_obs+t_okon:och:=och-1 fi od end:
Ошибка следующая:
Error, illegal use of an object as a name
Подскажите, пожалуйста, в чем проблема?
Спасибо!
__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь
0
restart;
Gauss := proc(A::Matrix, c::Vector)
local a, i, k, j, m, n, p;
n := linalg[rowdim](A);
m := linalg[coldim](A);
if m <> n then
print("matrice doit etre caree");
else
a := `<|>`(A, c);
for k to n-1 do
for i from k+1 to n do
if a[i, i] = 0 then
a := linalg[swaprow](a, k, i);
else
p := a[i, k]/a[k, k];
for j from k to n+1 do
a[i, j] := a[i, j]-p*a[k, j];
end do;
end if;
end do;
end do;
end if;
return a;
end proc:
c := Vector([2, 3, 4]);
A := Matrix(3, 3, [4, 1, 2, 3, 6, 5, 2, 1, 9]);
Gauss(A, c);
LinearAlgebra:-LUDecomposition(<A|c>, output=U);
There were quite a few mistakes, so let’s hope I get most of them.
I didn’t bother doing 7. You should do it.
- You cannot use
with
inside a procedure. - Your code uses commands from the
linalg
package, not theMTM
package. - Ideally you’d use Matrix&Vector&LinearAlgebra
(instead of your mix of matrix&Vector&linalg(. - Your procedure has
n
as one of its
parameters, but inside it you also try to
assign a value ton
, the argument for which
you passed in as the number 3. That’s where
your error message is coming from. You can’t
do that. - Several of you lines have just
=
instead of
:=
for assignments. The=
does nothing. - The test against
det(A)=0
is wrong is wrong
in several ways. I’ll just say that it doesn’t
actually test whether theA
is square.
Compare the row & column dimensions if you
want to test thatA
is square. - You should be using
LinearAlgebra
equivalents instead of thelinalg
commands
commandsswaprow
,coldim
. - You forgot to have your procedure actually
return the Matrixa
. - When your code calls
swaprow
is was not
actually updatinga
. It was just throwing
way the result. - It’s a sin to not indent your code. It will
lead you to overlook mistakes.