Документ взят из кэша поисковой машины. Адрес оригинального документа : http://tex.bog.msu.ru/numtask/maxhelpb.ps
Дата изменения: Sat Feb 7 13:46:35 2004
Дата индексирования: Mon Oct 1 19:41:21 2012
Кодировка: IBM-866
Московский Государственный Университет
физический факультет
В.А.Ильина, П.К.Силаев
Краткое руководство по работе с системой
аналитических вычислений MAXIMA
Москва 2004

Общие сведения о MAXIM'е
MAXIMA | это одна из первых систем аналитических вычислений. К
настоящему времени существует несколько таких систем | это, прежде все-
го, язык аналитических вычислений REDUCE; системы аналитических вычи-
слений MAXIMA, Mathematica и Maple; программы Derive и Eureca (которые
скорее являются игрушками, чем рабочим инструментом) и другие.
Имеет смысл различать язык аналитических вычислений, т.е. минималь-
ный набор синтаксических конструкций, который расширяется библиотечны-
ми функциями (типичный пример | REDUCE), и систему аналитических вы-
числений, в которой изначально определено очень много функций, причем эти
функции как правило избыточны. Система аналитических вычислений стара-
ется "уметь все" и на каждую задачу в ней найдется своя функция (типичные
примеры | MAXIMA и Mathematica).
При выборе системы аналитических вычислений следует учитывать:
Во-первых, насколько удачен замысел системы (естественность синтакси-
са, простота реализации тех или иных действий, автоматическое или прину-
дительное упрощение, полнота набора функций и т.п.).
Во-вторых, насколько удачна ее конкретная реализация (так, "старый"
REDUCE 3.0 компактен, но крайне ограничен и по памяти и по скорости по
сравнению с более "новым" REDUCE 3.4, а оформление REDUCE 5.0 заметно
лучше, чем у всех предыдущих; Mathematica 1.0 | это программа, которая
почти не работает, Mathematica 2.0 и 2.2 работают, но с "причудами", Math-
ematica 3.0 для LINUX (один из вариантов UNIX) работает в 3 раза быстрее,
чем Mathematica 3.0 для Windows 95, если они инсталлированы на идентичных
компьютерах, и т.д.).
Наконец, в-третьих, легальность ее использования (стоимость REDUCE
| 99$, стоимость Mathematic'и под Solaris (один из вариантов UNIX) | 500$,
GNU MAXIMA 5.2 под UNIX | программа общего пользования, ее можно
найти по адресу "www.gnu.ai.mit.edu").
В настоящее время профессионалами используется главным образом RE-
DUCE и MAXIMA. Что касается Mathematic'и, то основные ее идеи и сина-
таксические конструкции позаимствованы у MAXIM'ы. Значительно улучшен
только аппарат подстановок по шаблону, который в MAXIM'е крайне неудо-
бен. Если бы реализация Mathematic'и была удачна, ею вполне можно было
бы пользоваться. К сожалению, Mathematica изначально развивалась как ком-
мерческая программа и была ориентирована на массового пользователя. Так
что конструировалась система, которая "умеет все", но делает это "все" не
1

слишком хорошо. Соответственно, при усовершенствовании системы основ-
ное внимание уделялось оформлению, а не оптимизации работы. Реализация
именно аналитических вычислений в Mathematic'е не очень удачна (медленно
и не экономно по памяти), и при большом объеме выкладок они не могут быть
выполнены за конечное время. Кроме того, она вполне может выдавать невер-
ные ответы (в сущности вся история развития той части Mathematic'и, которая
работает с аналитическими выражениями | это исправление многочисленных
ошибок, на которые указывали пользователи). Самый замечательный пример
такого рода | это способ раскрывания скобок (впоследствии исправленный):
(a+b).(c+d) ) a.c+b.c+a.d+b.d
т.е. в общем случае ответ правильный,
(a+b).(a+b) ) a.a+a.b+b.b
а в этом случае неправильный.
MAXIMA написана на диалекте LISP'а, который называется "Common
LISP", и поддерживается проектом GNU. Регулярный способ установки MAX-
IM'ы на UNIX-машине состоит в том, что следует установить GNU'тый ком-
пилятор "C" | gcc (это полезно и само по себе, т.к. компилятор очень хорош),
затем с его помощью собрать GNU Common LISP | gcl, и затем на его базе
собрать собственно MAXIM'у. Исходники всех трех предметов можно найти
по адресу "www.gnu.ai.mit.edu".
MAXIMA при работе с аналитическими выражениями не старается упро-
стить выражение до некоторой канонической формы, если ее об этом не просят
(в отличие, скажем, от REDUCE, который всегда сводит выражение к канони-
ческому виду, и проводит упрощения до тех пор, пока выражение не перестает
меняться. Единственное, на что может повлиять пользователь REDUCE |
это поменять сам канонический вид с помощью флагов). Она делает в точно-
сти то, о чем ее просит пользователь с помощью тех или иных функций или
флаговых переменных. При этом она не проводит упрощения или преобразова-
ния "до конца" (т.е. до тех пор, пока выражение не перестает меняться), так
что часто повторный вызов той же самой фукнции меняет выражение.
Первоначальные сведения о
работе с MAXIM'ой
Идентификаторы в MAXIM'е составляются из 26 латинских букв (она не
различает строчные и прописные буквы), 10 цифр, символа подчеркивания "_",
процента "%". Как правило с "%" начинаются специальные имена, например
"%i" | это мнимая единица, "%pi" | это , а "%e" | основание натурального
логарифма.
2

При реальной работе MAXIMA дублирует ввод и печатает его вперемеж-
ку с выводом, причем все это делается заглавными буквами. Для удобства
чтения мы будем в примерах выделять вывод другим шрифтом и связывать
ввод с выводом стрелочкой. Это позволяет сделать наши примеры абсолютно
непохожими на то, что Вы увидите, непосредственно работая с MAXIM'ой.
Ввод в MAXIM'е завершается одним из двух терминаторов | ";" или "$".
В первом случае результат вычислений печатается, во втором | нет. Ка-
ждый ввод нумеруется с помощью меток "label" | "c1", "c2", "c3", "c4", и
т.д. Каждая из них является переменной, которой присвоено значение, рав-
ное введенной команде. Соответственно, каждый вывод также нумеруется с
помощью меток | "d1", "d2", "d3", "d4", и т.д. Опять-таки, каждая из них
является переменной, которой присвоено значение, равное результату выкла-
док. Существуют метки третьего типа "e1", "e2", и т.д., о которых будет
сказано ниже.
Наличие меток является постоянным источником ошибок, т.к. очень часто
хотелось бы работать со "своей" переменной "c2", "e5" или "d3". Делать это
не рекомендуется, т.к. немедленно окажется, что эта переменная уже равна
чему-нибудь крайне неожиданному.
Переменной "%" по определению присваивается результат последней вы-
кладки.
Основные математические операции в MAXIM'е пишутся обычным обра-
зом | "+", "-", "*", "/"; возведение в степень | это "^" (крышечка), а при-
своение (пожалуй, это довольно неудачная идея) записывается как ":" (двое-
точие). Попытка записать присвоение в виде "=" | постоянная ошибка при
работе с MAXIM'ой.
Переменные могут принимать числовые значения | целые, рациональ-
ные, с плавающей точкой фиксированной (машинной) точности и с плавающей
точкой неограниченной точности:
x:-7;
x:-13/5;
x:77.7777e-5;
x:77.77777777777777777777777777777777b-5;
Кроме того, переменным могут быть присвоены значения в виде аналитиче-
ских выражений
x:a^2+b;
Кроме того, переменным могут быть присвоены значения в виде строковых
переменных
x:"abcdefgh";
и, наконец, логические значения | "true" или "false" ("истина" или "ложь"):
x:false;
3

Знак "::" (два двоеточия подряд) | это присвоение с вычислением левой
части. Значением левой части должен быть объект, которому можно что-либо
присваивать. Так что в результате исполнения
s:2*a+b$
t:b-a$
(s+t)::777$
переменной "a" будет присвоено значение "777". Круглые скобки здесь необ-
ходимы, т.к.
s+t::777$
вызовет сообщение об ошибке.
Знак равенства резервирован для "уравнений" ("equation"). Уравнение
| это левая и правая части равенства, соединенные знаком "=". К уравне-
нию можно что-либо прибавить, из него можно что-либо вычесть, его можно
умножить или поделить на то или иное выражение. Те же операции можно
проделать с двумя уравнениями:
eq1:a=b$
eq1-c; ) a-c = b-c
eq2:x=y$
eq1*eq2; ) a x = b y
Знак ":=" применяется для определения функций, именно, записи
f(x):=x^2+5$
f(a,b):=a^2+3/b$
определяют функции одного и двух аргументов соответственно.
Совершенно аналогично знак "::=" применяется для определения макро-
сов.
f(x)::=x^2+5$
f(a,b)::=a^2+3/b$
Можно считать, что макросы работают так же, как функции. Разницу
между ними мы обсуждать не будем.
Разумеется, определены стандартные математические функции
exp(x) log(x) sqrt(x)
sin(x) cos(x) tan(x) cot(x) csc(x)
sinh(x) cosh(x) tanh(x) coth(x) csch(x)
asin(x) acos(x) atan(x) acot(x) acsc(x)
asinh(x) acosh(x) atanh(x) acoth(x) acsch(x)
atan2(x,y)
При этом MAXIMA знает, что sin( x) = sin(x), cos(0) = 1, log(1) = 0, и
т.д.
Определены операции факториала и двойного факториала:
5!; ) 120
4

6!!; ) 48
5!!; ) 15
 Функция max
перебирает свои аргументы и находит максимальное число
max(33,-22,11); ) 33
 Функция min
перебирает свои аргументы и находит минимальное число
min(33,-22,11,44); ) -22
Чтобы можно было реализовывать вывод из сложных синтаксических кон-
струкций типа блоков или циклов, предусмотрены специальные функции вы-
вода.
 Функция disp
печатает значения своих аргументов
x:77$ y:44$ z:11$
(c2) disp(x,y);
77
44
(d2) done
 Функция display
печатает значения своих аргументов вместе с их именем
(c3) display(x,y);
x=77
y=44
(d3) done
 Функция ldisp
печатает значения своих аргументов вместе с метками "e". Эта функция
"сбивает" нумерацию меток "c" и "d".
(с5) ldisp(x,y,z);
(e5) 77
(e6) 44
(e7) 11
(d7) [e5, e6, e7]
(с8) x;
(d8) 77
5

 Функция ldisplay
печатает значения своих аргументов вместе с их именем и метками "e".
Эта функция также "сбивает" нумерацию меток "c" и "d".
(с5) ldisplay(x,y);
(e5) x=77
(e6) y=44
(d6) [e5, e6]
 Функция print
печатает свои аргументы не каждый в отдельной строке, а в одну строку
(c15) print("x is equal to",77,
"or",88," or ",99);
x is equal to 77 or 88 or 99
(d15) 99
Для иллюстрации приведем коротенький пример, иллюстрирующий ввод
и вывод в MAXIM'е.
(c1) 2+3; ) (d1) 5
(c2) %; ) (d2) 5
(c3) exp(x); ) (d3) %e
x
(c4) (a+b)^2/(c+d); ) (d4) (a+b) 2
c+d
(c5) diff(f(x),x); ) (d5) d
dx
(f(x))
(c6) d3; ) (d6) %e
x
(c7) 3+4$ )
(c8) %; ) (d8) 7
В дальнейшем мы как правило будем опускать метки в примерах.
Как видно из приведенного примера, MAXIMA старается нарисовать свою
выдачу "красиво". Способ рисования определяется несколькими переменными,
перечислим некоторые из них.
 Переменная linel
определяет длину строки, в которую должна вписываться выдача. Из-
начально установлена величина "80". Если желательно получить более узкую
страницу (например, 60 позиций для двухколоночной печати), следует присво-
ить переменной "linel" значение "60":
linel:60; ) 60
6

 Переменная display2d
включает или выключает "двумерное" рисование дробей, степеней, и
т.п. Изначально установлено значение "true". При этом дроби рисуются кра-
сиво, но выдача не может быть использована для ввода в MAXIM'у. Если
установить значение "false", то вывод может быть впоследствии использован
как ввод:
(x^2+a)/(y^2+b); ) x 2 +a
y 2 +b
display2d:false$
(x^2+a)/(y^2+b); ) (x^2+a)/(y^2+b)
 Переменная showtime
включает или выключает печать времени, затраченного на каждое дей-
ствие. Изначально установлено значение "false". Если установить значение
"true", то будет печататься, во-первых, "идеальное" процессорное время, в
течение которого выполнялась выкладка, и, во-вторых, "физическое" время,
затраченное на выкладку (в системах с делением времени второе всегда пре-
вышает первое).
showtime:true$
Evaluation took 0.00 seconds (0.00 elapsed)
fun1(a,b,c)$
Evaluation took 4.08 seconds (4.20 elapsed)
 Функция fortran
позволяет получить выдачу, которую можно использовать как фрагмент
фортрановской программы
fortran(sum(x^i,i,0,15));
x**15+x**14+x**13+x**12+x**11+
1 x**10+x**9+x**8+x**7+x**6+x**5+
2 x**4+x**3+x**2+x+1
Работа с файлами
 Функция batch
запускает файл с прогpаммой. Операторы выполняются один за другим
либо до конца файла, либо до синтаксической ошибки, либо до некорректной
операции.
batch("myfile.mxm");
7

 Функция load
загружает тот или иной файл.
load(somefile);
Тип загрузки зависит от типа файла. Именно, можно загружать файл с ма-
кросами, т.е. фактически файл с программой на MAXIMA (типичные расши-
рения имен таких файлов "mxm", "mc" или "mac"), можно загружать файл
с программой на LISP (типичные расширения имен таких файлов "lisp" или
"lsp"), и можно загружать двоичный файл с уже оттранслированными кодами
(типичное расширение имен таких файлов "o").
Как правило эта функция необходима для загрузки того или иного па-
кета, который не загружается автоматически. Интересно, что разные пакеты
хранятся в разных форматах, так что может грузиться и файл в формате MAX-
IMA, и LISP-файл и двоичный файл. Стандартные функций в MAXIMA либо
входят в ядро системы и поэтому доступны изначально, либо являются авто-
загрузочными, т.е. при их первом вызове происходит автоматическая загрузка
необходимого файла, либо требуют явной загрузки того или иного файла | в
этом случае до их вызова необходимо написать "load(packetname)".
При этом для загрузки, например, пакета интегрирования по частям мож-
но написать как
load(bypart);
так и
load("bypart");
и в том и в другом случае загрузится файл "bypart.mc".
 Функция writefile
начинает писать всю выдачу MAXIM'ы в указанный файл. При этом (в
отличие от REDUCE) выдача на терминал не прекращается:
writefile("myoutput.mxm")$
 Функция closefile
прекращает вывод в файл:
closefile()$
8

Функции, преобразующие аналитические
выражения
Функции для выражений общего вида
 Функция ev
| это основная функция, обрабатывающая выражения. Ее синтаксис
довольно разнообразен.
ev(expr);
ev(expr,flag1,flag2,...);
ev(expr,x=a+b,y:c/d,...);
ev(expr,flag1,x=a,y:b,flag2,...);
Можно даже опускать имя функции ev
expr,flag1,flag2,...;
expr,x=val1,y=val2,...;
expr,flag1,x=val1,y=val2,flag2,...;
Следует, однако, иметь в виду, что в то время как записи "ev(expr, ag);" и
"expr, ag;" являются синонимами, записи "expr;" и "ev(expr);" не идентичны,
именно:
v:a+b$ a:7$
v; ) a+b
ev(v); ) b+7
v,expand; ) b+7
На выражение "expr" по умолчанию действует функция упрощения. Если ука-
заны флаги (их имена как правило совпадают с именами других функций,
преобразующих выражения), то с выражением производятся действия в соот-
ветствии с этими флагами. Вот некоторые из флагов:
expand factor trigexpand trigreduce
(на выражение действуют одноименные функции),
pred diff simp
("pred" вызывает вычисление значения логического выражения, "di " вызыва-
ет выполнение "замороженного" дифференцирования, "simp" вызывает выпол-
нение функции упрощения даже в том случае, когда переменная "simp" равна
"false").
Если указаны подстановки (в виде "x=val1" или "x:val2"), то они выпол-
няются.
При этом повторный вызов функции "ev" вполне способен еще раз изме-
нить выражение, т.е. обработка выражения не идет до конца при однократном
вызове функции "ev".
9

ev((a+b)^2,expand); ) a 2
+ 2 a b + b 2
ev((a+b)^2,a=x); ) (x+b) 2
ev((a+b)^2,a=x,expand,b=7);
=) x 2 + 14 x + 49
(a+b)^2,a=x,expand,b=7;
=) x 2
+ 14 x + 49
 Переменная simp
разрешает либо запрещает упрощение выражений. Изначально она рав-
на "true", если установить ее равной "false", то упрощения производиться не
будут:
simp:false$
x+y+x; ) x + y + x
simp:true$
x+y+x; ) y + 2 x
 Функция factor
факторизует выражение.
factor( a*c+b*c+a*d+b*d )
=) (a+b)(c+d)
factor( (x^3+2*x^2*y+y^3)/
(x^2+2*x*y+y^2)+
x^2*y/(x^2+2*x*y+y^2)+
3*x*y^2/(x+y)^2 );
=) x+y
 Функция gfactor
отличается от функции "factor" тем, что умеет работать с мнимой еди-
ницей, т.е. может факторизовать выражения типа x 2 + a 2 и x 2 + 2ixa a 2
factor(x^2+a^2); ) x 2 +a 2
factor(x^2+2*%i*x*a-a^2);
=) x 2
+ 2%ixa - a 2
gfactor(x^2+a^2); ) (x+%ia)(x-%ia)
gfactor(x^2+2*%i*x*a-a^2);
=) (x+%ia) 2
10

 Функция factorsum
факторизует отдельные слагаемые в выражении.
factorsum( a^3+3*a^2*b+3*a*b^2+b^3
+x^2+2*x*y+y^2 ) (y+x) 2 +(b+a) 3
 Функция gfactorsum
отличается от "factorsum" тем же, чем "gfactor" отличается от "factor":
gfactorsum( a^3+3*a^2*b+3*a*b^2+b^3
+x^2+y^2 ) (y+%ix)(y-%ix)+(b+a) 3
 Функция expand
раскрывает скобки.
expand( (a+b)*(c+d) );
=) a c + b c + a d + b d
expand( (x^3+2*x^2*y+y^3)/
(x^2+2*x*y+y^2)+
x^2*y/(x^2+2*x*y+y^2)+
3*x*y^2/(x+y)^2 );
=) x 3
x 2 +2xy+y 2
+ 3x 2
y
x 2 +2xy+y 2
+ 3xy 2
x 2 +2xy+y 2
+ y 3
x 2 +2xy+y 2
 Функция combine
объединяет слагаемые с идентичным знаменателем
combine( x^3/(x^2+2*x*y+y^2)+
3*x^2*y/(x^2+2*x*y+y^2)+
3*x*y^2/(x^2+2*x*y+y^2)+
y^3/(x^2+2*x*y+y^2)+
a/(c+d)+b/(c+d)
=) x 3
+3x 2
y+ 3xy 2
+y 3
x 2 +2xy+y 2
+ a+b
c+d
 Функция xthru
приводит выражение к общему знаменателю, не раскрывая скобок и не
пытаясь факторизовать слагаемые
xthru(1/(x+y)^10+1/(x+y)^12
11

=) (x+y) 2
+ 1
(x+y) 12
xthru( m/(x^2+2*x*y+y^2)+
n/(x+y)^4);
=) m(x+y 4
) + n(x 2
+ 2xy + y 2
)
(x 2 + 2xy + y 2 )(x+y) 4
Разумеется, в последнем случае разумнее сначала факторизовать каждое
слагаемое, а уж потом применять "xthru". Применить функцию "factor" к
отдельным слагаемым выражения можно с помощью функции "map".
 Функция multthru
умножает каждое слагаемое в сумме на множитель, причем при умно-
жении скобки в выражении не раскрываются. Она допускает два варианта
синтаксиса
multthru(mult,sum);
multthru(mult*sum);
(порядок сомножителей в последнем варианте не существенен).
multthru((x+y)^2,(x+y)^5
+1/(x+y)^7+(x+y)^2);
=) (x+y) 7 + (x+y) 4 + 1
(x+y) 5
multthru( ((x+y)^5+1/(x+y)^7
+(x+y)^2)*(x+y)^2);
=) (x+y) 7 + (x+y) 4 + 1
(x+y) 5
multthru( ((x^3+2*x^2*y+y^3)/
(x^2+2*x*y+y^2)+
x^2*y/(x^2+2*x*y+y^2)+
3*x*y^2/(x+y)^2 )*
(x^2+2*x*y+y^2)*
(m+n)/(x+y) );
=) (n+m)(x 3 + 2x 2 y + y 3 )
x+y +
3(n+m)xy 2
(x 2
+ 2xy + y 2
)
(x+y) 3
+ (n+m)x 2
y
x+y
12

Функции для рациональных выражений
Хотя функции, преобразующие выражения, не приводят их к канониче-
ской форме (в отличие от REDUCE), каноническое представление (CRE) су-
ществует | это каноническая форма для дробно-рациональных выражений.
Выражение, приведенное к CRE, снабжается меткой /R/ сразу после метки
"d". Дальнейшая работа с ним идет быстрее, а вероятность его упрощения
выше, чем для выражения общего вида.
 Функция rat
приводит выражение к каноническому представлению и снабжает его
меткой /R/. Она упрощает любое выражение, рассматривая его как дробно-
рациональную функцию, т.е. работает с операциями "+", "-", "*", "/" и с
возведением в целую степень. Нецелые степени она не упрощает, т.е. она не
знает, что (x a=2 ) 2 = x a . При этом вид ответа зависит от того, какие пере-
менные она считает более главными, а какие менее главными. Упорядочение
сначала идет по степеням самой главной переменной, внутри коэффициентов
при этих степенях | по степеням менее главной переменной, и т.д. Изна-
чально переменные упорядочены в алфавитном порядке и от начала к концу
"главность" возрастает. Этот порядок можно откорректировать, добавив в
аргументы функции имена переменных в порядке возрастания главности.
(c11) rat( (x^3+2*x^2*y+y^3)/
(x^2+2*x*y+y^2)+
x^2*y/(x^2+2*x*y+y^2)+
3*x*y^2/(x+y)^2 );
=) d(11) /r/ x+y
(c12) v1:m/(a+b)+n/(x+y)$
=)
(c13) rat(v1);
=) (d13) /r/
my+mx+(b+a)n
(b+a)y+(b+a)x
(c14) rat(v1,y,x,n,m,b,a);
=) (d14) /r/
na+nb+(x+y)m
(x+y)a+(x+y)b
(c15) rat(v1,m,n,a,b,x,y);
=) (d15) /r/ my+mx+nb+na
(b+a)y+(b+a)x
(c16) rat(v1,m,n);
=) (d16) /r/ (b+a)n+(y+x)n
(b+a)y+(b+a)x
13

(c17) rat( (x^(a/2)-1)^2*
(x^(a/2)+1)^2 )/(x^a-1);
=) (d17) /r/ (x a/2
) 4
- 2(x a/2
) 2
+ 1
x a
- 1
 Функция ratvars
позволяет изменить алфавитный порядок "главности" переменных, при-
нятый по умолчанию.
ratvars(z,y,x,w,v,u,t,s,r,q,p,o,n,m,l,k,j,i,h,g,f,e,d,c,b,a)$
меняет порядок главности в точности на обратный, а
ratvars(m,n,a,b)$
упорядочивает переменные "m,n,a,b" в порядке возрастания "главности", и
делает их более главными, чем все остальные переменные.
 Переменная ratfac
включает или выключает частичную факторизацию выражений при све-
дении их к CRE. Изначально установлено значение "false". Если установить
значение "true", то будет производиться частичная факторизация.
(c4) v2:m/(a+b)^2+n/(x+y)^2$
=)
(c5) rat(v2);
=) (d5) /r/ (my 2 +2mxy+mx 2 +
(b 2 +2ab+a 2 )n) / ((b 2 +2ab+a 2 )y 2 +
(2b 2 +4ab+2a 2 )xy + (b 2 +2ab+a 2 )x 2 )
(c6) ratfac:true$ )
(c7) rat(v1); ) (d7) /r/
my+mx+(b+a)n
(b+a)(y+x)
(c8) rat(v2);
=) (d8) /r/
my 2 +2mxy+mx 2 + (b 2 +2ab+a 2 )n
(my 2
+2mxy+mx 2
) (b 2
+2ab+a 2
)
 Функция ratsimp
приводит все куски (в том числе аргументы функций) выражения, ко-
торое не является дробно-рациональной функцией, к каноническому предста-
влению, производя упрощения, которые не делает функция "rat". Не снабжает
выражение меткой /R/. Повторный вызов функции может изменить результат,
т.е. упрощение не идет до конца.
14

(c77) ratsimp( (x^(a/2)-1)^2*
(x^(a/2)+1)^2 )/(x^a-1);
=) (d77) x 2a
- 2x a
+ 1
x a
- 1
(c78) ratsimp(%); ) (d78) x a
- 1
 Функция fullratsimp
вызывает функцию "ratsimp" до тех пор, пока выражение не перестанет
меняться.
fullratsimp( (x^(a/2)-1)^2*
(x^(a/2)+1)^2 )/(x^a-1);
=) x a
- 1
 Переменная ratsimpexpons
управляет упрощением показателей степени в выражениях. Изначально
установлено значение "false". Забавно, что при этом аргумент любой функции
упрощается:
fullratsimp( sin( (x^(a/2)-1)^2*
(x^(a/2)+1)^2)/(x^a-1));
=) sin(x a
- 1)
а показатель степени (в том числе показатель экспоненты) | нет:
fullratsimp( exp( (x^(a/2)-1)^2*
(x^(a/2)+1)^2)/(x^a-1));
=) %e
x 2a
x a
-1
-
2x a
x a
-1
+
1
x a
-1
Если установить значение "true", то показатели степени начнут упрощаться:
ratsimpexpons:true$
fullratsimp( exp( (x^(a/2)-1)^2*
(x^(a/2)+1)^2)/(x^a-1));
=) %e
x a
- 1
 Функция ratexpand
раскрывает скобки в выражении. Не снабжает выражение меткой /R/.
Отличается от функции "expand" тем, что приводит выражение к канониче-
ской форме, поэтому ответ может оказаться короче, чем при применении "ex-
pand":
15

ratexpand( (x^3+2*x^2*y+y^3)/
(x^2+2*x*y+y^2)+
x^2*y/(x^2+2*x*y+y^2)+
3*x*y^2/(x+y)^2 );
=) x+y
(см. выше аналогичный пример с "expand").
Функции для тригонометрических выражений
 Функция trigexpand
раскладывает все тригонометрические функции от сумм в суммы про-
изведений тригонометрических функций
trigexpand(sin(x+y));
=) sin(x)cos(y)+sin(y)cos(x)
 Переменная trigexpand
управляет работой функции "trigexpand". Изначально переменная "trig-
expand" равняется "false", это приводит к тому, что функция "trigexpand" не
работает до конца, т.е. ее повторный вызов может изменить выражение. Если
переменная "trigexpand" будет равна "true", то функция "trigexpand" будет
работать до тех пор, пока выражение не перестанет меняться.
trigexpand(sin(2*x+y));
=) cos(2x)sin(y) + sin(2x)cos(y)
trigexpand(%); ) (cos 2
(x)-sin 2
(x))sin(y) +
2 cos(x) sin(x) cos(y)
trigexpand:true; ) true
trigexpand(sin(2*x+y));
=) (cos 2 (x)-sin 2 (x))sin(y) +
2 cos(x) sin(x) cos(y)
 Функция trigreduce
свертывает все произведения тригонометрических функций в тригоно-
метрические функции от сумм. Функция работает не до конца, так что по-
вторный вызов может изменить выражение
trigreduce((cos(x)^2-
sin(x)^2)*sin(y) +
2*cos(x)*sin(x)*cos(y) );
=) sin(y+2x)
2 -
sin(y-2x)
2 + cos(2x)sin(y)
16

trigreduce(%); ) sin(y+2x)
 Функция trigsimp
вовсе не упрощает выражение , а применяет к нему правило sin 2 (x) +
cos 2 (x) = 1:
trigsimp((cos(x)^2-
sin(x)^2)*sin(y) +
2*cos(x)*sin(x)*cos(y) );
=) (2cos 2
(x)-1)sin(y) + 2 cos(x) sin(x) cos(y)
 Функция trirat
пытается свести выражение с тригонометрическими функциями к неко-
му универсальному каноническому виду (в общем, пытается упростить выра-
жение). Как правило существенно упрощает выражение, но иногда работает
очень долго (иногда бесконечно долго).
trigrat((cos(x)^2-
sin(x)^2)*sin(y) +
2*cos(x)*sin(x)*cos(y) );
=) sin(y+2x)
Функции для выражений со степенями и логарифмами
 Функция radcan
упрощает выражения со вложенными степенями и логарифмами:
radcan( log( x^3*exp(4*y)*
exp(5*log(w))/z^6 ) );
=) -6log(z) + 4y + 3log(x) + 5log(w)
radcan( (x^(a/2)-1)^2*
(x^(a/2)+1)^2 )/(x^a-1);
=) x a
- 1
 Функция rootscontract
компактифицирует возведения в степень в данном выражении
rootscontract( x^(1/6)*
y^(1/12)*z^(1/30) );
=) (x sqrt(y) z 1/5 ) 1/6
rootscontract( x^(1/2)*y^(1/2)*
z^(1/4) ); ) sqrt(x y sqrt(z))
17

 Функция logcontract
компактифицирует логарифмы в данном выражении
logcontract( a*log(x)+
3*log(y)-4*log(x) );
=) a log(x) + log(
y 3
x 4 )
Логические выражения и база данных
Логические выражения образуются из операций сравнения
> < >= <= = #
(символ # означает "не равно", а запись "a=b" имеет синоним "equal(a,b)").
Странноватой особенностью операций сравнения является то, что если их по-
ставить в качестве условий в циклах и условных выражениях, то они будут
вычислены, но взятые сами по себе, они не вычисляются:
3>2; ) 3>2
equal(3,2); ) equal(3,2)
3#2; ) 3#2
Флаг "pred" в функции "ev" вызывает вычисление логических выражений:
ev(3#2,pred); ) true
 Функция is
инициирует вычисление логического выражения
is(3>2); ) true
is(3=2); ) false
is(equal(3,2)); ) false
is(3#2); ) true
Кроме того, определены встроенные логические функции, перечислим не-
которые из них.
 Функция atom
возвращает "true", если аргумент не имеет структуры, т.е. составных
частей (например, число или переменная не имеют структуры).
 Функция zeroequiv
возвращает "true", если аргумент равен нулю
18

 Функция freeof
возвращает "true", если второй ее аргумент не содержит ("свободен от")
первого
freeof(x,f(x+g(y))); ) false
freeof(g,f(x+g(y))); ) false
freeof(z,f(x+g(y))); ) true
 Функция symbolp
возвращает "true", если ее аргумент является символом:
symbolp(f(x)); ) false
symbolp(3); ) false
symbolp(f); ) true
 Функция scalarp
возвращает "true", если ее аргумент является константой:
scalarp(f); ) false
scalarp(sin(1/3)); ) true
scalarp(f(1/3)); ) false
scalarp(1/3); ) true
 Функция listp
возвращает "true", если ее аргумент является списком.
 Функция matrixp
возвращает "true", если ее аргумент является матрицей.
 Функция numberp
возвращает "true", если ее аргумент является числом:
numberp(sin(1/3)); ) false
numberp(1/3); ) true
numberp(1.3b22); ) true
 Функция integerp
возвращает "true", если ее аргумент является целым числом.
 Функция oddp
возвращает "true", если ее аргумент является целым нечетным числом.
 Функция evenp
возвращает "true", если ее аргумент является целым четным числом.
19

 Функция primep
возвращает "true", если ее аргумент является целым простым числом.
 Функция floatp
возвращает "true", если ее аргумент является действительным числом
машинной точности.
 Функция bfloatp
возвращает "true", если ее аргумент является действительным числом
неограниченной точности.
Кроме того, логическими выражениями являются запросы из базы данных:
is(a>3);
Следует подчеркнуть, что речь идет не о значении переменной "a" (которое
неизвестно), а об информации, в какой области эта переменная может менять-
ся.
 Функция assume
вводит информацию о переменной в базу данных.
assume(n>4); ) [n>4]
После этого можно вводить запрос типа
is(n>1); ) true
Однако, запросы типа
is(n<7);
is(n>7);
вызовут сообщение об ошибке, т.к. в базе данных такой информации нет.
Точно так же вызовет сообщение об ошибке более сложный запрос (который в
принципе должен был бы дать значение "true"):
is(n^2+n>19);
Повторное применение функции "assume" проверяется на противоречи-
вость и на избыточность. В случае, если новая информация не противоречит
предыдущим данным и не вытекает из них, она аддитивно добавляется к базе
данных. К сожалению, предыдущие условия не проверяются на избыточность
при появлении новых условий:
assume(n>3); ) [redundant]
assume(n<3); ) [inconsistent]
assume(n>10); ) [n>10]
assume(n<30); ) [n<30]
is(n<9); ) false
is(n>31); ) false
20

 Функция properties
печатает свойства переменной и, тем самым, позволяет выяснить, какая
именно информация содержится в базе данных о данной переменной
properties(n);
=) [database info,n>4,n>10,n<30]
(новое условие n > 10 не отменило избыточное теперь условие n > 4).
Из приведенных примеров видно, что поменять свойство переменной на
противоположное с помощью функции "assume" невозможно:
assume(x>0)$
assume(x<0); ) [inconsistent]
is(x>0); ) true
 Функция forget
отменяет сведение, введенное в базу данных. Это позволяет поменять
свойство переменной на противоположное.
forget(n<30); ) [n<30]
properties(n); ) [database info,n>4,n>10]
Забавно, что после всех этих манипуляций можно присвоить переменной
"n" значение, которое будет противоречить информации из базы данных:
n:-77; ) -77
is(n>0); ) false
properties(n);
=) [value,database info,n>4,n>10]
 Функция kill
уничтожает всю информацию об объекте. Это позволяет за один раз
ликвидировать всю ранее введенную информацию о переменной "n".
kill(n); ) done
properties(n); ) [ ]
Составные логические выражения формируются с помощью логических
операций "and", "or", "not".
is( 3>1 and -1>=-3 and
2#1 and not(equal(2,1)) )
=) true
is( 3<1 or -1<=-3 or
not 2#1 or 2=1 )
=) false
21

Условные выражения и циклы
Синтаксис условного выражения может быть проиллюстрирован приме-
ром
a:1$
if a>3 then x:1 else x:-1;
=) -1
x; ) -1
if a<3 then x:x+1 else x:x-1;
=) 0
x; ) 0
Как обычно, часть с else можно опустить
if a>3 then x:1; ) false
if a<3 then x:1; ) 1
Синтаксис цикла допускает три варианта
(c5) for i:1 thru 3 step 2 do disp(i);
1
3
(d5) done
(c6)