source("eng_lang_setup.R")
## === knitr, reticulate, eng_lang are go. ===
Maxima は数式処理言語で,シンボリック処理言語,記号処理言語のひとつである.
Maxima 言語は次の9つの構成要素(オブジェクト)からなる.
Maxima オブジェクト : 以下の9種類のオブジェクトからなる.
1) シンボル: 定数,変数,関数,リスト,配列,スペシャルシンボル(inf,等)
を識別する名前
例: x^2+%pi=f(y) のシンボルは x, %pi, f, y
2) 関数: ゼロまたは1個以上の引数を受け付け,なんらかの計算を実行し,
結果を返すプロシジャをいう.
例: diff(f(x),x,k)
3) スペシャルフォーム: 関数と似ているが,引数の評価方法が,関数は呼
び出し時に行われるのに対して,スペシャルフォームでは引数評価を行わない.
例: decalre('a_1, 'f_1, ..., 'a_n, 'f_n)
4) 演算子: スタイル化された関数,またはスペシャルフォームをいう.
演算子を宣言する関数にはには 1) infix, 2) matchfix, 3) postfix,
4) prefix, 5) nary, 6) nofix, 7) special の7タイプがある.
5) 環境変数: 1つまたは複数の関数,スペシャルフォーム,等の挙動
をコントロールする.
例: exponentialize: true
6) システム変数: システム値を調べる変数
例: values 値が設定されている変数をリスト表示する
7) プロパティ: 各シンボルに付加される属性をいう.
シンボルにプロパティを付加する機能は
1) declare, (featurep, remove) による方法
2) put, (get, remove) による方法
がある.
例: declare("~", alphabetic)$
declare(oc,constant)$
declare([oo,oc,co,cc],constant)$
lr:oc, constantp(lr)$ -> true
8) キーワード: 関数またはスペシャルフォームにおいて認識され,それら
の動作を変えるオプション引数をいう.
例: ev(exp,nouns) の nouns は関数 ev 専用キーワード
9) キーワードフォーム: キーワードと同様であるが,2個以上の引数からなる点が異なる.
例: derivlist(var_1,...,var_n) : var_1,...,var_n についてのみ微分する
数,文字列,変数(と付値),添字付き変数,リスト,行列
アトミックな変数:添字無しの変数をいう
シンボルは,定数,変数,関数,リスト,配列(添字付き変数,行列)等を表すのに使用される. ひとつのシンボルは,アルファベット,パーセント記号(%),アンダースコア(_)および数字を含む文字列で 記述される.シンボルは,型(データタイプ,データ構造)をその属性としてもつ.
変数や関数といったシンボルに何らかのプロパティ(性質)を付与し,そのシンボルの属性とする行為を考える. 例えば,ある変数に,「正の数である」,「整数である」といったプロパティを付与し,その変数の属性とする 場合や,ある関数に「対称関数である」プロパティを付与し,その関数の属性とする行為を指す. また,2つの変数 x, y の間に「 x > y」といった関係をプロパティとして定義することも考える. そのような行為は,まず,プロパティ(性質)を定義し,そのプロパティをシンボルに付与する(結び付ける)ことで 行われる.また,Maxima では,プロパティをデータベース(リレーショナルデータベース)で管理し,シンボル間に 定義された関係も制御する.Maxima には,事前に定義された多くの標準的なプロパティ()が用意されている. それら以外に,ユーザによるプロパティの定義も設定できる.それらのプロパティの定義,表示,削除や, シンボルへの付与,付与されたプロパティの表示,その解除といった操作が用意されている.
1. プロパティの定義,表示,削除 delcare,featurep,remove, properties
2.プロパティの種類 (数学的,特性リスト,演算子,非数学的,リレーショナル)
3.プロパティの付与,付与の解除
4.コンテクスト
内部簡約化の流れ
1.式の全てのサブ式を並べ替える.
2.変数をaからzまでアルファベット順に並べる.
3.定数(%e, %pi, %i),ユーザ定義定数を変数の前に出す.
4.数を前に出す.
例: y+2*a*x-%pi ---> (plus (times -1 %pi) (times 2 a x) y)
部分式の抽出と置換(subst, ratsubst)
パターンの定義,照合(照合のタイミング)と置換
matchdeclare(patternvar, predicate,...) パターン変数の定義
tellsimp, tellsimpafter 内部評価の前後で機能する
defmatch 検出パターンを照合する関数
defrule, apply1, remrule
let, letrat:false, letrules, remlet, letsimp
プロパティをテストする述語
コマンドラインから投入された「式」の受ける処理
「式」:数,変数,関数呼び出し,演算子から構成される表現
1.構文解析 -> Lisp翻訳 -> 入力ラインへ表示
2.式の評価,簡約化 (評価,簡約化を総じて評価と呼ぶ)
1) 名前の評価:代入値があれば代入値を返し,なければ名前を返す
2) 関数の評価:関数の引数を評価し,次に関数値を評価する.
名詞型関数では関数定義式を返す.(再考)
スペシャルフォーム ev と ev 用キーワード
(noeval,infeval,pred,nouns,expand,derivlist,var:expression,
var=expression, f(args) := body)
関数の定義方法
f(x) := body body の評価は関数の適用時に行う.
define(f(x), body) body の評価は define の評価時に行う.
関数の評価の流れ(引数の評価,関数値の評価)
関数が関数を呼び出す例,不定個の引数をもつ関数,無名関数
関数の配列 f[k](x),引数を評価しない関数,関数の引数としての利用
apply を用いた関数利用, 関数を評価せず定義式を返す(funmake)
関数への引数の写像(map)
関数とマクロ
マクロでは適用時に引数の評価を行わないで結果をフォームで返し,
その評価はインタプリターに任せる.
条件文 if (condition) then (exp_1) else (exp_2)
関係演算子(>, <, >=, <=, #, =) 論理演算子 (or, and, not) <--- equal(exp1,exp2)
複合文 (exp_1, exp_2, ... , exp_k)
プログラムブロック block([var_1,...,var_k],st_1,...,st_k)
返り go(tag) return(exp), catch(exp1,...,expk) and throw(exp)
繰り返し文 for var:var_0 step d {thru|while|unless} do (st_1,...,st_k)
for var:var_0 next d {thru|while|unless} do (st_1,...,st_k)
型の宣言 declare と輪郭の開始点( :=, block, do, lambda)
ff(x,y) := (mode_declare([x,y],float),
block([ans],
mode_declare(ans,float),
ans : x + y,
return(ans)
))$
fa(x,y) := (mode_declare([x,y],any),
block([ans],
mode_declare(ans,any),
ans : x + y,
return(ans)
))$
トランスレート(Maxima コードから Lisp コードに変換)
(%i1) translate_file("ex-translate.mx");
Translation begun on ex-translate.mx.
(%o1) [ex-translate.mx, ex-translate.LISP, ex-translate.UNLISP]
(%i2) load("ex-translate.LISP");
(%o2) ex-translate.LISP
コンパイル(Maxima コードから Lisp コードに変換し,機械コードに変換)
(%i1) compile_file("ex-translate.mx");
Translation begun on ex-translate.mx.
;; Compiling file /home/inoue/Max-ex/ex-translate.LISP ...
;; Wrote file /home/inoue/Max-ex/ex-translate.fas
0 errors, 0 warnings
(%o1) [ex-translate.mx, ex-translate.LISP, ex-translate.UNLISP,
/home/inoue/Max-ex/ex-translate.fas]
(%i2) load("ex-translate.fas");
(%o2) ex-translate.fas
(%i1) load("ex-translate.lib");
(%o1) ex-translate.lib
(%i2) fa(a,b);
この章では,Maxima が構成要素として区分している9つのオブジェクトについて概説し,次にMaxima が扱う基本的な型(データタイプ)とその取扱い方について整理する.
Maxima オブジェクト : 以下の9種類のオブジェクトからなる.
1) シンボル: 定数名,変数名,関数名,スペシャルシンボル(inf,等)
例: x^2+%pi=f(y) のシンボルは x, %pi, f, y
2) 関数: ゼロまたは1個以上の引数を受け付け,なんらかの計算を実行し,
結果を返すプロシジャをいう.
例: diff(f(x),x,k)
3) スペシャルフォーム: 関数と似ているが,引数の評価方法が,関数は呼
び出し時に行われるのに対して,スペシャルフォームでは引数評価を行わない.
例: decalre('a_1, 'f_1, ..., 'a_n, 'f_n)
4) 演算子: スタイル化された関数,またはスペシャルフォームをいう.
演算子を宣言する関数には 1) infix, 2) matchfix, 3) postfix,
4) prefix, 5) nary, 6) nofix, 7) special の7タイプがある.
5) 環境変数: 1つまたは複数の関数,スペシャルフォーム,等の挙動
をコントロールする.
例: exponentialize: true
6) システム変数: システム値を調べる変数
例: values 値が設定されている変数をリスト表示する
7) プロパティ: 各シンボルに付加される属性をいう.
シンボルにプロパティを付加する機能は
1) declare, (featurep, remove) による方法
2) put, (get, remove) による方法
がある.
例: declare("~", alphabetic)$
8) キーワード: 関数またはスペシャルフォームにおいて認識され,それら
の動作を変えるオプション引数をいう.
例: ev(exp,nouns) の nouns は関数 ev 専用キーワード
9) キーワードフォーム: キーワードと同様であるが,2個以上の引数からな
る点が異なる.
例: derivlist(var_1,...,var_n) : var_1,...,var_n についてのみ微分する
このうち,「シンボル」で命名された変数,関数が「プロパティ」で宣言された性質をその属性として持ち,その属性情報をデータベースとして参照しながらさまざまな評価を行う.
Maxima が扱う基本的なデータタイプ(型)について整理する. まず,データタイプの1つと見なされる,数と文字列について説明し,次にシンボルで命名される変数,関数, 配列,等のデータ構造について説明する. シンボルは,変数,関数,配列等のデータ構造を表すのに使用される.ひとつのシンボルは,アルファベット, パーセント記号(%),アンダースコア(_)および数字を含む文字列で記述される.
Maxima で扱える「数」には,整数,有理数,浮動小点数と複素数がある.その他に,代数的整数があるが 最小多項式として扱う.
Maximaに予約されている定数には,%e(自然対数の底 \(\doteq 2.718\)), %gamma(オイラー定数 \(\doteq 0.577\)),%phi (\(\frac{1+\sqrt{2}}{2} \doteq 1.618\)), %pi(円周率 \(\doteq 3.14\)),true(真),false (偽),inf(正の実無限大, minf(負の実無限大),infnity(複素無限大:任意の偏角で絶対値無限大)がある. 数に関連する問い合わせ関数としては,numberp(), bfloatp(), floatnump(), integerp(), evenp(), oddp(), constantp() があり,結果は true, false を返す. その他の数関連関数を以下にまとめる.
Maxima の文字列は配列の一種として取り扱う.文字列は”abc”のように記述する.
● concat(arg_1,…,arg_k)
引数を評価し, その値を結合したものを文字列として返す.
引数に割当てられた値はアトムである必要がある.
/home/inoue/bin/go tmp_lang/chunk-1.mx > tmp_lang/chunk-1.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-1.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-1.mx
a1:128
128
out:concat(1,a1,2)+1
11282 + 1
/var/www/html/LANG/tmp_lang/chunk-1.mx
● sconcat(arg_1,…,arg_k)
引数を評価し文字列に結合する.concat とは違い,
引数に割当てられた値がアトムである必要はない. 結果は Common LISP
の文字列となる.
/home/inoue/bin/go tmp_lang/chunk-2.mx > tmp_lang/chunk-2.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-2.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-2.mx
eq1:x^2+1 = 0
2
x + 1 = 0
out:sconcat(eq1,"<->","x=[-%i,%i]")
x^2+1 = 0<->x=[-%i,%i]
/var/www/html/LANG/tmp_lang/chunk-2.mx
● string(eq)
式 eq を文字列に変換する.
/home/inoue/bin/go tmp_lang/chunk-3.mx > tmp_lang/chunk-3.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-3.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-3.mx
eq1:x^2+1 = 0
2
x + 1 = 0
str1:string(eq1)
x^2+1 = 0
/var/www/html/LANG/tmp_lang/chunk-3.mx
外部パッケージ eval_string や stringproc を用いると,高機能な文字列処理を行える.
● load(“eval_string”)$
eval_string(string)
● load(“stringproc”)$
charat(str,n) strのn文字目を取り出す charat("Lisp",1) -> L
charlist(str) strをリストに展開する charlist("Lisp") -> [L,i,s,p]
pasetoken(str) strから数値を取り出す parsetoken("1.23") -> 1.23
sconc(exp_1,...) 文字列の連結 sconc("a[",1,"]") ---> a[1]
scopy(str) strの複写
sdowncase(str,[start,end]) <---> supcase(str,[start,end])
sequal(str_1,str_2) 文字列(文字数と文字)の比較
sequalignore(str_1,str_2)
sexplode(str) charlist(str)の別名 sexplode("Lisp") -> [L,i,s,p]
simplode(list,delim) listにdelimを付けて文字列化
simplode([L,i,s,t],"*") ---> L*i*s*t
sinsert(seq,str,pos) 文字列seqを文字列strの位置posに挿入する
sinvertcase(str,[start,end]) strの大文字、小文字を反転する
slength(str) 文字数
smake(num,char) char を num 回繰り返した文字列を返す
smismatch(str_1,str_2) str_1とstr_2の不一致位置を返す
split(str,[delim,multiple]) 文字列をdelimを用いて分割リスト化する
split("e1;;e2;e3",";") -> [e1,e2,e3]
split("e1;;e2;e3",";",false) -> [e1, ,e2,e3]
sposition(char,str) str内の初出のchar位置を返す
sremove(seq,str,[test,start,end]) strからseqを削除する
sremovefirst(seq,str,[test,start,end]) strから初出のseqを削除する
sreverse(str) strの逆順文字列を返す sreverse("abc") ---> cba
ssearch(seq,str,[test,start,end]) strからseqを検索し,その位置を返す
---> Ver. 5.15 では機能しない
ssort(str,[test]) strを文字単位でソートする
ssubst(new,old,str,[test,start,end]) 文字列の置換
ssubstfirst(new,old,str,[test,start,end]) 初出の文字列の置換
strim(seq,str) strからseqを削除
striml(seq,str) strから左端seqを削除 strimr(seq,str) strから右端seqを削除
substring(str,start,[end]) 部分文字列
tokens(str,[test]) strのリスト化
tokens("20 Oct. 1951"); ---> [20, Oct., 1951]
tokens("05-10-20", 'digitcharp); ---> [05, 10, 20]
map(parsetoken, %) ---> [5, 10, 20]
◆ 実行例
/home/inoue/bin/go tmp_lang/chunk-4.mx > tmp_lang/chunk-4.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-4.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-4.mx
batchload("/home/inoue/.maxima/max-init.mac")
file_search1: /home/inoue/.maxima/max-init.mac not found in file_search_maxima.
-- an error. To debug this try: debugmode(true);
/var/www/html/LANG/tmp_lang/chunk-4.mx
値と関係付けられるシンボルは変数と呼ばれる.添字付き変数も含める.添字のない変数を特にアトミック変数と いう.変数への付値は x:3 のように行う.
◆ 実行例1.変数への付値
/home/inoue/bin/go tmp_lang/chunk-5.mx > tmp_lang/chunk-5.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-5.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-5.mx
x:3
y:x
y
3
x:5
5
y
3
"/* a <-b <- c <- 1+z の付値(代入)を一括して行う */"
a:b:c:z+1
z + 1
a
z + 1
b
z + 1
c
z + 1
/var/www/html/LANG/tmp_lang/chunk-5.mx
変数への付値は付値行為のときのみである点に注意する.
◆ 実行例2.変数への付値
/home/inoue/bin/go tmp_lang/chunk-6.mx > tmp_lang/chunk-6.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-6.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-6.mx
a:1
b:2
c:a
1
"/* c <- a <- 1 が評価されている */"
y:x
x
x:10
10
y
x
"/* y <- x, x <- 10 では,y は x のままである */"
/var/www/html/LANG/tmp_lang/chunk-6.mx
◆ 実行例3.変数への付値(間接指定的付値)
/home/inoue/bin/go tmp_lang/chunk-7.mx > tmp_lang/chunk-7.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-7.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-7.mx
a:1
y:x
"/* 下記の付値機能に注目 */"
y::a
1
a
1
x
1
y
x
values
[a, y, x]
/var/www/html/LANG/tmp_lang/chunk-7.mx
a <- 1, y <- x の状態で y :: a を実行すると, 「a の値 1 が y の値 x にセットされる」 (%o6) に注目. Maximaでは,変数は,基本的に環境変数となり,通常は型や属性を持たない. この変数に,特定の型や初期値を設定するには,関数 mode_declare(),define_vriable() を用いる. それらは,トランスレート,コンパイルで重要な意味をもつ.
型 | mode_declare 関数で利用可能な表記 | 概要 |
---|---|---|
float | float,real,floatp,flonum,floatnum | 浮動小数点数 |
fixnum | fixp,fixnum,integer | 整数 |
rational | rational, rat | 有理数 |
number | number, bignum, big | 任意精度の数 |
complex | complex | 複素数 |
boolean | boolean, bool | Boolean |
list | list, listp | リスト |
any | any, none, any_check | 任意の型 |
◆ 実行例a.(変数の型宣言と型検証関数の使用注意)
/home/inoue/bin/go tmp_lang/chunk-8.mx > tmp_lang/chunk-8.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-8.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-8.mx
mode_declare(x1,integer)
[x1]
x1:123
123
mode_identity(integer,x1)
123
x1:123.456
123.456
"/* 上記のように,型宣言された型以外の付値行為を許している */"
mode_identity(integer,x1)
translator: x1 was declared with mode fixnum, but it has value: 123.456
123.456
mode_identity(float,x1)
123.456
/var/www/html/LANG/tmp_lang/chunk-8.mx
関数 mode_declare() で宣言された型以外の値を変数に付値すること は可能で,関数 mode_identity() も,変数x1 が第1引数で指 定された型にあっているかを判定するだけであることに注意する.変数の型の 検証に関する環境変数として以下のものがある.
● mode_checkp:true (環境変数) trueの場合,mode_declare() で宣言された型と,新たに宣言する型が 矛盾しないかを検証し,矛盾する場合はエラーを返す.
● mode_checkp_errorp:false (環境変数) trueの場合,異なる型で変数の宣言を行う場合にエラーを返す.
● mode_checkp_warnp:true (環境変数) trueの場合,関数 mode_identity() が警告を返す.
添字付き変数は配列を用いて利用される.配列は5次元まで有効で,添字は0から始まる.
◆ 実行例4.
/home/inoue/bin/go tmp_lang/chunk-9.mx > tmp_lang/chunk-9.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-9.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-9.mx
display2d:false
"/* a[n] を定義する */"
a[n]:=n*a[n-1]
a[0]:1
1
a[5]
120
"/* a[n] を再定義する */"
a[n]:=n
a[6]
6
a[10]
10
a[5]
120
"/* a[5] は最初の定義による値である! */"
a[4]
24
"/* 添字付き変数 a を消去する */"
remarray(a)
a[n]:=n-1
a[5]
4
"/var/www/html/LANG/tmp_lang/chunk-9.mx"
a[0] から a[5] までは第1式の定義が使われ,a[6], a[10] は第2式の定義が 使われている.配列要素の値は1度セットされると再計算は行われない. うまく利用すると処理時間の短縮が望める. 再定義の場合は remarray(a) のように既存の配列を削除する必要がある.
● makelist(exp,i,i0,i1)
● makelist(exp,x,list)
第1表現では,生成されるリストの第j成分が ev(exp, i=i0+j-1)
であるリストを返す.第2表現では, 第j成分が ev(exp, x=list[j])
であるリストを返す.
/home/inoue/bin/go tmp_lang/chunk-10.mx > tmp_lang/chunk-10.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-10.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-10.mx
display2d:false
makelist(concat(x,i),i,1,6)
[x1,x2,x3,x4,x5,x6]
(xmin:-3,xmax:3,n:5)
x[i]:=float(xmin+((xmax-xmin)*i)/n)
xl:makelist(x[i],i,0,n)
[-3.0,-1.8,-0.6,0.6,1.8,3.0]
yl:makelist(float(erf(x)),x,xl)
[-0.9999779095030014,-0.9890905016357308,-0.6038560908479259,
0.6038560908479259,0.9890905016357308,0.9999779095030014]
"/var/www/html/LANG/tmp_lang/chunk-10.mx"
順に並べられた要素の集まり[e1,e2,…,ek]をリストという. また,リストは
[e1,e2,[e3,e4],[e5,[e6]]] のように入れ子にしてもよい.
リストは変数と見なせる.
Maxima
の多くの関数はその内部でリスト表現化されている.したがって,一見してリスト処理専用関数であっても,Maxima
の多くの関数や式に利用可能なことが多くある.
◆ 実行例5-1.リストの生成
/home/inoue/bin/go tmp_lang/chunk-11.mx > tmp_lang/chunk-11.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-11.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-11.mx
"/* リストの生成, 結合 */"
L1:[l11,l12]
[l11, l12]
L2:[l21,l22,l23]
[l21, l22, l23]
append(L1,L2)
[l11, l12, l21, l22, l23]
flatten([L1,L2])
[l11, l12, l21, l22, l23]
"/* 空リスト, 先頭追加, 末尾追加 */"
L:[]
[]
L:[e0]
[e0]
cons(e1,L)
[e1, e0]
endcons(e1,L)
[e0, e1]
"/* リストの生成 */"
L0:makelist(i,i,0,5)
[0, 1, 2, 3, 4, 5]
/var/www/html/LANG/tmp_lang/chunk-11.mx
リスト処理に影響を与える環境変数として以下のものがある.
● listarith:true (環境変数)
trueであれば,算術演算子によるリスト評価を実行する.
● inflag:false (環境変数)
trueであれば,要素を取り出すリスト処理関数は,与えられた式の内部表現に対して処理を行う.
簡約化は式の並び換えを行うことに注意する必要がある. 例えば,first(x+y)
は,inflag:true であれば,x を返し,inflag:false であれば, y
を返す点に注意する.オプション変数
inflagに影響を受ける関数には以下のものがある.
関数 | 概要 |
---|---|
part | 式の成分を取り出す関数 |
substpart | 式の成分の代入を行う関数 |
first | リストの先頭の成分を取り出す関数 |
rest | リストの残りを取り出す関数 |
last | リストの末尾の成分を取り出す関数 |
length | リストの長さを返す関数 |
for x in [e1,e2,…] | リストを用いるループ文 |
map | リストの成分に関数を作用させる関数 |
● atom(var)
varがアトムであるときtrueを返す.
● listp(var)
varがリストであるときtrueを返す.この判定は内部表現の影響を受けない.
● member(exp_1,exp_2)
式 exp_1が式 exp_2に含まれているときtrueを返す.
◆ 実行例5.リストのメンバ
/home/inoue/bin/go tmp_lang/chunk-12.mx > tmp_lang/chunk-12.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-12.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-12.mx
member(sin(x),[cos(x),sin(x),x+1])
true
member(sin(x),cos(x)+sin(x)+x+1)
true
member(sin(x),[cos(x)+sin(x)+x+1])
false
member(sin(x),f(cos(x),sin(x),x+1))
true
member(sin(x),f(cos(x),sin(x)+x+1))
false
/var/www/html/LANG/tmp_lang/chunk-12.mx
● length(exp)
引数 exp がリストの場合は,リストの長さ(要素の個数)を返し,引数 exp
が式の場合は,それを
リスト構造(内部表現)で表したリストの長さを返す.
◆ 実行例6.リストの長さ
/home/inoue/bin/go tmp_lang/chunk-13.mx > tmp_lang/chunk-13.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-13.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-13.mx
length([e1,e2,e3])
3
length([e1,e2,[e1,e2,[e3,e4,e5]]])
3
length(x+y+z)
3
length(x+y*z)
2
/var/www/html/LANG/tmp_lang/chunk-13.mx
● copylist(list)
リスト list の複製を作る.L2 : copylist(L1) のように用いる.
● reverse(list)
リスト list の並びを逆にしたリストを返す.引数が式の場合は内部
リスト表現に基づく処理を行う.
● append(L_1,L_2,…)
複数個のリスト L_1,L_2,… の結合リストを返す.
● cons(exp,L)
式 exp をリスト L の先頭に追加する.
● endcons(exp,L)
式 exp をリスト L の最後に追加する.
● delete(exp,L,n)
式 exp をリスト L から n 個削除する.引数 n
を省略すると全てを削除する.
● first(exp) <—> last(exp)
リスト exp から先頭要素,最終要素を返す.引数 exp が式の
場合は内部リスト形式に基づく処理を行う.(inflag の影響を受ける.)
● rest(exp,n)
引数 n が正数のときは,リスト exp の先頭のn個の要
素を取り除いたリストを返し,引数 n が負数のときは,リスト exp
の最後からn個の要素を取り除いたリストを返す. 引数 exp
が式の場合は内部リスト形式に基づく処理を行う.
● sort(list, pred) リストのソート(並び換え)を行う.第2引数 pred を用いてソート手順を指定できる.
◆ 実行例
/home/inoue/bin/go tmp_lang/chunk-14.mx > tmp_lang/chunk-14.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-14.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-14.mx
sort([a,c,b,d,a])
[a, a, b, c, d]
sort([a,c,b,d,a],ordergreatp)
[d, c, b, a, a]
"/* 注1: 次の例では数値と変数が混在する例 */"
sort([1,-7,2.0b0,7.5,3,b+a,9*c])
[- 7, 1, 3, 7.5, 2.0b0, b + a, 9 c]
sort([1,-7,2.0b0,7.5,3,b+a,9*c],ordergreatp)
[9 c, b + a, 2.0b0, 7.5, 3, 1, - 7]
"/* 注2: 次の例では文字型定数はアルファベット順にソートされる */"
sort([%pi,3,4,%e,%gamma])
[3, 4, %e, %gamma, %pi]
"/* 注3: 次の例では文字型定数は数値順にソートされる */"
sort([%pi,3,4,%e,%gamma],"<")
[%gamma, %e, 3, %pi, 4]
mshow(float(%gamma),float(%e),float(%pi))
"/* 注4: 応用例 */"
my_list:[[aa,hh,uu],[ee,cc],[zz,xx,mm,cc],[%pi,%e]]
sort(my_list)
[[%pi, %e], [aa, hh, uu], [ee, cc], [zz, xx, mm, cc]]
sort(my_list,lambda([a,b],orderlessp(reverse(a),reverse(b))))
[[%pi, %e], [ee, cc], [zz, xx, mm, cc], [aa, hh, uu]]
/var/www/html/LANG/tmp_lang/chunk-14.mx
● sublist(list,func)
リストlist から述語関数func が true
を返す要素を抜き出したリストを返す.
/home/inoue/bin/go tmp_lang/chunk-15.mx > tmp_lang/chunk-15.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-15.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-15.mx
display2d:false
sublist([1,2,3,4,5],evenp)
[2,4]
chk(e):=if e > 3 then true
sublist([1,2,3,4,5],chk)
[4,5]
L:[e1,e2,e1,e3,e1,e2,e4,e1,e5]
"/* 重複要素を切り詰める関数への利用 */"
cutdup(L):=block([outL:L],chkdup(e):=if e # 'same then true,
if length(outL) = 1 then return(L)
else (for i thru length(outL)-1 do
(for j from i+1 thru length(outL) do
if outL[j] = outL[i] then outL[j]:'same)),
outL:sublist(outL,chkdup),return(outL))
cutdup(L)
[e1,e2,e3,e4,e5]
cutdup([e1])
[e1]
"/var/www/html/LANG/tmp_lang/chunk-15.mx"
● substpart(new,exp,n_1,n_2,…,n_k)
式 exp の n_1,n_2,…,n_k で指定した成分new で置き換 える.引数 new
は,式,アトム,演算子を指定できる.
◆ 実行例7.
/home/inoue/bin/go tmp_lang/chunk-16.mx > tmp_lang/chunk-16.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-16.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-16.mx
display2d:false
L:[e1,e2,e3]
"/* 注:リストの問合せ関数*/"
listp(L)
true
L[2]+L[3]
e3+e2
length(L)
3
L[length(L)]
e3
first(L)
e1
last(L)
e3
"/* 注:リストに要素を追加する */"
cons(a,L)
[a,e1,e2,e3]
endcons(a,L)
[e1,e2,e3,a]
L:[e1,e0,e1,e2,e0,e0,e1,e2]
"/* 注:リストから要素を削除する */"
delete(e0,L)
[e1,e1,e2,e1,e2]
delete(e0,L,1)
[e1,e1,e2,e0,e0,e1,e2]
delete(e0,L,2)
[e1,e1,e2,e0,e1,e2]
"/* 注:リストメンバの照合 */"
member(e0,L)
true
member(e5,L)
false
"/* 注:複数リストの結合 */"
append([e1,e2,e3],[f1,f2],[g1,g2])
[e1,e2,e3,f1,f2,g1,g2]
L:[e1,e2,e3,e4,e5]
"/* 注:リストの一部を取り出す */"
rest(L,2)
[e3,e4,e5]
"/* 注:先頭から2個を取った残りが返されている */"
rest(L,-2)
[e1,e2,e3]
"/* 注:最後から2個を取った残りが返されている */"
sublist([1,2,3,4,5],evenp)
[2,4]
"/* 注:以下は方程式の解を操作する場合に有効 */"
ans:[[x = a1],[x = a2]]
ans[2]
[x = a2]
ans[2][1]
x = a2
rhs(ans[2][1])
a2
"/var/www/html/LANG/tmp_lang/chunk-16.mx"
上記のリスト操作は関数の引数に対しても適用できる.
◆ 実行例8.関数引数に対するリスト関数の使用例
/home/inoue/bin/go tmp_lang/chunk-17.mx > tmp_lang/chunk-17.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-17.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-17.mx
display2d:false
"/* 注:次は関数の引数を追加する */"
append(f(a,b),f(c,d,e))
f(a,b,c,d,e)
cons(a,f(b,c,d))
f(a,b,c,d)
endcons(d,f(a,b,c))
f(a,b,c,d)
"/* 注:次は関数の引数への問合せ */"
member(a,f(a,b,c))
true
reverse(f(a,b,c,d))
f(d,c,b,a)
"/* 注:次は演算子をシンボル化関数と見なし,披演算子を引数と見なした処理 */"
rest(x+y+z,2)
x
rest(x+y+z,-2)
z
"/* 注:次の2例は,リストの第2部分をxに置換する */"
substpart(x,[e1,e2,e3,e4],2)
[e1,x,e3,e4]
substpart(x,[e1,[e2,e3],e4],2)
[e1,x,e4]
substpart(x,[e1,[e2,e3],e4],2,2)
[e1,[e2,x],e4]
"/* 注:次は,第1部分 cos(x) を sin(x) に置換する */"
substpart(sin(x),(x+a)*(x+b)+cos(x),1)
sin(x)+(x+a)*(x+b)
"/* 注:次は,第2部分(x+a)*(x+b)の第2部分(x+b)が置換対象 */"
substpart(sin(x),(x+a)*(x+b)+cos(x),2,2)
(x+a)*sin(x)+cos(x)
"/* 注:次は,第2部分(x+a)*(x+b)の第0部分 * が置換対象 */"
substpart("+",(x+a)*(x+b)+cos(x),2,0)
cos(x)+2*x+b+a
"/var/www/html/LANG/tmp_lang/chunk-17.mx"
substpart での式は入力表現とは異なるパート指定が必要となる.
map関数は,関数をリストに作用させる.
● map(func, exp_1,exp_2,…,exp_k)
関数 func を式 exp_1,exp_2,…,exp_k
のリスト構造(の第1層)に適用する.
● maplist(func, exp_1,exp_2,…,exp_k)
map() と同様であるが,主演算子をリストに変更する.
◆ 実行例9.
/home/inoue/bin/go tmp_lang/chunk-18.mx > tmp_lang/chunk-18.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-18.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-18.mx
"/* 注1:次は,式の第1層の演算子+の披演算子(各要素)にfを作用する */"
map(f,x+a*y+b*z)
f(b z) + f(a y) + f(x)
"/* 注2:次は,式の各項に無名関数を作用させる */"
map(lambda([u],partfrac(u,x)),x+1/(x^3+4*x^2+5*x+2))
1 1 1
----- - ----- + -------- + x
x + 2 x + 1 2
(x + 1)
"/* 注3:次は,式の各項に関数 ratsimp() を作用させる */"
map(ratsimp,x/(x^2+x)+(y^2+y)/y)
1
y + ----- + 1
x + 1
"/* 注4:次は,リストの各要素にシンボル化関数 = を作用させる */"
map("=",[a,b],[-0.5,3])
[a = - 0.5, b = 3]
map(sin,x*y)
sin(x) sin(y)
map(sin,x*y+z)
sin(z) + sin(x y)
map(lambda([x,y],x*y),x+y,s+t)
t y + s x
out1:map(sin,factor(x*y+y))
sin(x + 1) sin(y)
out2:maplist(sin,factor(x*y+y))
[sin(x + 1), sin(y)]
/var/www/html/LANG/tmp_lang/chunk-18.mx
● maperror:true (環境変数)
map(), maplist() は引数exp_1,..,exp_k に対して,同一の主演
算子をもち,かつ,その演算子に対する項の個数も同じであることを要請する.
すなわち,関数map(), maplist()は引数exp_1,..,exp_kから
k個の成分を取り出し,このk個の成分を引数とする関数
funcを作用させた結果を返す.
この条件を満たさないときの振る舞いを,maperrorが制御する.
◆ 実行例10.
/home/inoue/bin/go tmp_lang/chunk-19.mx > tmp_lang/chunk-19.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-19.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-19.mx
maperror:false
map(lambda([x,y],x*y),x+y+a,s+t)
map: truncating one or more arguments. t y + s x
/var/www/html/LANG/tmp_lang/chunk-19.mx
maperror:true の下で上記を実行するとエラーを返し,終了する.
● mapatom(exp) 式 exp がmap()関数によってアトムとみなされるときにtrueを返す.
● scanmap(func,exp)
関数 func を式 exp の内部リスト表現にトップダウン式に再
帰的適用する.
● scanmap(func,exp,bottomup)
◆ 実行例11.scanmap の使用例
/home/inoue/bin/go tmp_lang/chunk-20.mx > tmp_lang/chunk-20.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-20.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-20.mx
exp:(a^2+2*a+1)*y+x^2
"/* 注:式の内部リスト表現に対して関数factor()を再帰的に作用する */"
scanmap(factor,exp)
2 2
(a + 1) y + x
scanmap(factor,expand(exp))
2 2
a y + 2 a y + y + x
scanmap(factor,expand(exp),bottomup)
2 2
a y + 2 a y + y + x
/var/www/html/LANG/tmp_lang/chunk-20.mx
Maximaでは,リスト以外に配列を扱うことができる.配列の生成は, array() 関数を用いて配列を宣言する方法と,配列要素を具体的に与 えていく方法がある.配列の最大次元数は5に制限されている.
● array(name,dim_1,…,dim_k)
● array(name,type,dim_1,…,dim_k)
● array([name_1,…,name_m],dim_1,…,dim_k)
aray()関数の引数 type には,flonum(浮動小数点数),
fixnum(整数),function(関数型),complete (その他) が指定できる.
● make_array(name,type,dim_1,…,dim_k)
● make_array(functional,func,type,dim_1,…,dim_k)
make_aray()関数の引数 type には, ’any, ’flonum, ’fixnum, ’hashed,
’functional が指定できる.
● listarray(name)
配列要素を表示する.
● arrayinfo(name)
配列の型と大きさを表示する.
● array:[] (環境変数)
生成した配列名を記録されるリスト
● use_fast_array:false (環境変数)
trueの場合,make_array()関数は’any 型の配列を生成する.
falseの場合には,指定した型の配列を生成する.
● fillarray(array,list)
第1引数の配列 array に第2引数listで指定したリスト(配列
も可)の値を入れる.第1引数の要素数が第2引数の要素数より大きい場合は,
第2引数の最後の要素が繰り返し代入される.第1,2引数の要素の型は同じで
なければならない.
● arrayapply(array,[arg_1,…,arg_k])
配列から指定した要素を取り出す.
● rearray(array,dim_1,…,dim_k)
配列のサイズを変更する.
● remarray(array_1,…,array_k)
● remarray(all) 配列を削除する.
◆ 実行例12.配列操作
/home/inoue/bin/go tmp_lang/chunk-21.mx > tmp_lang/chunk-21.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-21.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-21.mx
display2d:false
"/* 注1:配列要素を直接与える配列の定義例*/"
a1[1,2]:10
a1[0,3]:1
"/* 注2:配列の型を指定した配列の定義例*/"
array(a2,fixnum,3)
a2
listarray(a1)
[1,10]
arrayinfo(a1)
[hashed,2,[0,3],[1,2]]
listarray(a2)
[0,0,0,0]
arrayinfo(a2)
[complete,1,[3]]
a3:make_array('hashed,5)
"{Lisp Array: #<hash-table 0000000001ae4ef0>}"
listarray(a3)
[]
arrayinfo(a3)
[hash_table,1]
a4:make_array('any,5)
"{Lisp Array: #(NIL NIL NIL NIL NIL)}"
arrays
[a1,a2]
a4[4]:c1
c1
listarray(a4)
[false,false,false,false,c1]
arrayapply(a4,[4])
c1
a5:make_array('functional,'sin,flonum,3)
"{Lisp Array: #(-1.7976931348623157E308 -1.7976931348623157E308
-1.7976931348623157E308)}"
arrayinfo(a5)
[declared,1,[2]]
"/var/www/html/LANG/tmp_lang/chunk-21.mx"
行列は同一の長さをもつリストを行にもつ2次元の要素の集まりで構成される.
A : matrix([a11,a12],[a21,a22]) 行列に対する演算子 +, -, *, /
は行列の要素単位で演算が行われる. 行列の乗算 A B は A . B で, A A は
‘A^^2’, 逆行列 ‘A^-1’ は ‘A^^-1’ で記述する.
◆ 実行例13.行列の基本演算
/home/inoue/bin/go tmp_lang/chunk-22.mx > tmp_lang/chunk-22.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-22.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-22.mx
A:matrix([a11,a12],[a21,a22])
B:matrix([b11,b12],[b21,b22])
"/* 注1:行列の足し算 A + B */"
A+B
[ b11 + a11 b12 + a12 ]
[ ]
[ b21 + a21 b22 + a22 ]
"/* 注2:行列の可換積(要素間の積) A * B /"
A*B
[ a11 b11 a12 b12 ]
[ ]
[ a21 b21 a22 b22 ]
"/* 注3:行列の掛算(非可換積) A . B */"
A . B
[ a12 b21 + a11 b11 a12 b22 + a11 b12 ]
[ ]
[ a22 b21 + a21 b11 a22 b22 + a21 b12 ]
"/* 注4:行列の巾 A^^2 = A . A */"
A^^2
[ 2 ]
[ a12 a21 + a11 a12 a22 + a11 a12 ]
[ ]
[ 2 ]
[ a21 a22 + a11 a21 a22 + a12 a21 ]
"/* 注5:逆行列 A^^-1 = invert(A) */"
A^^(-1)
[ a22 a12 ]
[ ----------------- - ----------------- ]
[ a11 a22 - a12 a21 a11 a22 - a12 a21 ]
[ ]
[ a21 a11 ]
[ - ----------------- ----------------- ]
[ a11 a22 - a12 a21 a11 a22 - a12 a21 ]
/var/www/html/LANG/tmp_lang/chunk-22.mx
Maxima の演算子には,「内挿」,「前置」,「後置」,「無引数」,「囲み」の5種類がある.
それらの演算子の多くはMaximaに事前定義されているが,その定義属性を変更したり,新たな演算子を その属性とともに定義することが可能である.演算子の定義属性としては,「演算子と左右の引数との結合力, 「演算子の左右の引数の型」「演算結果の型」がある.
なお,演算子宣言の関数を用いて演算子を宣言する際に,型を指定しなければ,左右の披演算子と演算結果の型は 「 any」 が仮定される.
演算子 | (意味) | 左結合力 | 右結合力 | 左引数型 | 右引数型 | 結果の型 |
---|---|---|---|---|---|---|
\(+\) | (和) | 100 | 100 | 不要 | exp | exp |
\(-\) | (差) | 100 | 134 | 不要 | exp | exp |
\(*\) | (積) | 120 | 不要 | exp | 不要 | exp |
\(/\) | (商) | 120 | 120 | exp | exp | exp |
^ | (巾) | 140 | 139 | exp | exp | exp |
\(**\) | (巾) | 140 | 139 | exp | exp | exp |
\(.\) | (非可換積) | 130 | 129 | exp | exp | exp |
^^ | (非可換巾) | 140 | 139 | exp | exp | exp |
演算子 | (意味) | 左結合力 | 右結合力 | 左引数型 | 右引数型 | 結果の型 |
---|---|---|---|---|---|---|
\(!\) | (階乗) | 160 | exp | exp | ||
\(!!\) | (2差階乗) | 160 |
演算子 | (意味) | 左結合力 | 右結合力 | 左引数型 | 右引数型 | 結果の型 |
---|---|---|---|---|---|---|
not | (否定) | 70 | clause | clause | clause | |
and | (論理積) | 65 | clause | clause | ||
or | (論理和) | 60 | clause | clause | ||
= | (等*) | 80 | 80 | exp | exp | exp |
# | (非等*) | 80 | 80 | exp | exp | exp |
>= | (以上) | 80 | 80 | exp | exp | exp |
> | (より大) | 80 | 80 | exp | exp | exp |
<= | (以下) | 80 | 80 | exp | exp | exp |
< | (より小) | 80 | 80 | exp | exp | exp |
演算子 | (意味) | 左結合力 | 右結合力 | 左引数型 | 右引数型 | 結果の型 |
---|---|---|---|---|---|---|
: | (付置) | 180 | 20 | any | any | any |
:: | (付置) | 180 | 20 | any | any | any |
::= | (マクロ定義) | 180 | 20 | any | any | any |
:= | (関数定義) | 180 | 20 | any | any | any |
演算子 | (意味) | 左結合力 | 右結合力 | 左引数型 | 右引数型 | 結果の型 |
---|---|---|---|---|---|---|
] | 5 | |||||
[ | 200 | any | any | |||
) | 5 | |||||
( | 200 | |||||
’ | 190 | |||||
’’ | 190 | |||||
, | 10 | any | any |
演算子 | (意味) | 左結合力 | 右結合力 | 左引数型 | 右引数型 | 結果の型 |
---|---|---|---|---|---|---|
if | 45 | clause | any | |||
then | 5 | 25 | ||||
else | 5 | 25 | ||||
elseif | 5 | 45 | clause | any |
演算子 | (意味) | 左結合力 | 右結合力 | 左引数型 | 右引数型 | 結果の型 |
---|---|---|---|---|---|---|
for | 25 | 200 | any | any | ||
from | 25 | 95 | any | any | ||
step | 25 | 95 | exp | any | ||
next | 25 | 45 | any | any | ||
thru | 25 | 95 | exp | any | ||
unless | 25 | 45 | clause | any | ||
while | 25 | 45 | clause | any | ||
do | 25 | 25 | any | any |
● infix(a)
● infix(a,lbp,rbp)
● infix(a,lbp,rbp,lpos,rpos,pos) 文字列 a を内挿演算子として定義する.引数 lbp,rbp はそれぞれ,左結合力,右結合力を表し, 引数 lpos,rpos,pos はそれぞれ,左引数の型,右引数の型,演算結果の型を表す.
● prefix(a)
● prefix(a,rbp)
● prefix(a,rbp,rpos,pos)
文字列 a を前置演算子として定義する.
● postfix(a)
● postfix(a,lbp)
● postfix(a,lbp,lpos,pos)
文字列 a を後置演算子として定義する.
● nofix(a)
● nofix(a,pos)
文字列 a を無引数演算子として定義する.
● nary(a)
● nary(a,bp)
● nary(a,bp,argpos,pos)
文字列 a を内挿演算子として定義する.引数 bp は左右の結合力を表し,引数
argpos,pos はそれぞれ, 左右引数の型,演算結果の型を表す.nary()
関数は,左右の引数結合力が同じでよい内挿演算子を宣言する
ときに用いられる.引数 bp を省略した場合には 180 が設定される.
● matchfix(a,b)
● matchfix(a,b,argpos,pos)
式を文字列 a と 文字列 b で囲む演算子として定義する.引数 bp
は左右の結合力を表し,引数 argpos, pos
はそれぞれ,左右引数の型,演算結果の型を表す.
演算子 | (意味) | 左結合力 | 右結合力 | 左引数型 | 右引数型 | 結果の型 |
---|---|---|---|---|---|---|
infix | (内挿) | 180 | 180 | any | any | |
prefix | (前置) | 180 | any | any | ||
postfix | (後置) | 180 | any | any | ||
nofix | (無引数) | any | ||||
nary | (内挿) | (180) | (180) | any | any | any |
matchfix | (囲み) | any | any | any |
◆ 実行例1.演算子「-」の属性を調べる
/home/inoue/bin/go tmp_lang/chunk-23.mx > tmp_lang/chunk-23.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-23.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-23.mx
print(":lisp (get '$- 'lbp);")
:lisp (get '$- 'lbp);
100
print(":lisp (get '$- 'rbp);")
:lisp (get '$- 'rbp);
134
print(":lisp (get '$- 'lpos);")
:lisp (get '$- 'lpos);
NIL
print(":lisp (get '$- 'rpos);")
:lisp (get '$- 'rpos);
$EXPR
print(":lisp (get '$- 'pos);")
:lisp (get '$- 'pos);
$EXPR
print()
out0:a-b-c
print(":lisp $out0;")
:lisp $out0;
((MPLUS SIMP) $A ((MTIMES SIMP) -1 $B) ((MTIMES SIMP) -1 $C))
print()
out1:(a-b)-c
(- c) - b + a
print(":lisp $out1;")
:lisp $out1;
((MPLUS SIMP) $A ((MTIMES SIMP) -1 $B) ((MTIMES SIMP) -1 $C))
print()
out2:a-(b-c)
c - b + a
print(":lisp $out2;")
:lisp $out2;
((MPLUS SIMP) $A ((MTIMES SIMP) -1 $B) $C)
print()
/var/www/html/LANG/tmp_lang/chunk-23.mx
◆ 実行例2.内挿演算子の定義と引数結合
/home/inoue/bin/go tmp_lang/chunk-24.mx > tmp_lang/chunk-24.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-24.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-24.mx
infix("><",100,120)
><
(a >< b):=a^b
b
(a >< b) := a
a >< b >< c
b c
(a )
print("--- a >< b >< c --- 100 >< 120 , 100 >< 120 --- (a >< b) >< c")
--- a >< b >< c --- 100 >< 120 , 100 >< 120 --- (a >< b) >< c
print("Ex.2")
Ex.2
infix("><",120,100)
><
a >< b >< c
c
b
a
print("--- a >< b >< c --- 120 >< 100 , 120 >< 100 --- a >< (b >< c")
--- a >< b >< c --- 120 >< 100 , 120 >< 100 --- a >< (b >< c
print(":lisp (get '$>< 'lbp);")
:lisp (get '$>< 'lbp);
120
print(":lisp (get '$>< 'rbp);")
:lisp (get '$>< 'rbp);
100
print()
/var/www/html/LANG/tmp_lang/chunk-24.mx
◆ 実行例3.内挿演算子の定義
/home/inoue/bin/go tmp_lang/chunk-25.mx > tmp_lang/chunk-25.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-25.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-25.mx
nary("C")
(n C k):=n!/(k!*(n-k)!)
5 C 2
10
/var/www/html/LANG/tmp_lang/chunk-25.mx
◆ 実行例4.囲み演算子の定義
/home/inoue/bin/go tmp_lang/chunk-26.mx > tmp_lang/chunk-26.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-26.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-26.mx
matchfix("@-","-@")
@-a,b,c,d-@:=a*b-c*d
@-1,2,3,d-@
2 - 3 d
dispfun("@-")
(%t5) @-a, b, c, d-@ := a b - c d
[%t5]
properties("@-")
[function, operator, noun]
remove("@-",op)
done
properties("@-")
[]
kill("@-")
done
properties("@-")
[]
/var/www/html/LANG/tmp_lang/chunk-26.mx
Maxima の変数や項の順序は以下のルールで定まれている.
Maxima定数 | \(<\) | 宣言された定数 | \(<\) | 宣言されたスカラー | \(<\) |
---|---|---|---|---|---|
orderless の第1引数 | \(<<\) | orderless の最終引数 | \(<\) | aで始まる変数 | \(<<\) |
zで始まる変数 | \(<\) | Aで始まる変数 | \(<<\) | Zで始まる変数 | \(<\) |
ordergreat の最終引数 | \(<<\) | ordergreat の第1引数 | \(<\) | 宣言された主変数 |
x + y ---> (+ x y)
x + y + z ---> (+ x (y + z)) ---> (+ x (+ y z))
通常の多項式に加えて,exp や sin 等の初等関数にも同様の順序が入る.基本的に,主変数よりも初等関数が 大となる.なお,関数 ordergreat() や orderless() を用いた順序変更宣言は先の処理まで考慮した上で 慎重に行うべきである.また,順序変更宣言の取消,および,変更は,関数unorder() を用いて行う.
文字列として与えられたデータから,演算子を抽出し,演算子の属性から決まる規則を用いて式としての表現を 構成する.まず,加法演算子「+」を例にとる.
x + y ---> (+ x y)
x + y + z ---> (+ x (y + y)) ---> (+ x (+ y z))
上記の最後の表記は木構造に対応する.
+
x +
y z
次に演算子「+」の属性 (可換性,結合律) に着目すると以下の表現を得る.
演算子「+」の属性
可換性 : a + b = b + a ---> (+ a b) = (+ b a)
結合律 : (a + b) + c = a + (b + c) ---> (+ (+ a b) c) = (+ a (+ b c))
(+ (+ a b) c) = (+ a (+ b c)) ---> (+ a b c)
同様にして,演算子「+」,「−」,「*」,「/」,「^」(巾)の表現を以下のように与える.
演算子「 + 」の表現
a + b + c ---> (+ a b c)
演算子「 * 」の表現
a * b * c ---> (* a b c)
演算子「−」の表現
a - b ---> a + (-b) ---> (+ a -b)
演算子「 / 」の表現
a / b ---> a * (1/b) ---> (* a 1/b)
演算子「^」の表現
a^b ---> (^ a b)
これらの演算子を含む式の表現例を示す.
1 + x + (y-1)/(z^3 + 2*x*y)
---> (+ 1 x (/ (+ y -1) (+ (^ z 3) (* 2 z y))))
---> (+ 1 x (* (+ y -1) 1/(+ (^ z 3) (* 2 z y))))
このような式の表現を前置表現または一般表現と呼ぶ.
次のような単変数多項式に着目し,これに,新たな表現法(正準表現:CRE表現)を定める.
3*x^2 -1 ---> 3*x^2 + (-1)*x^0
---> (+ (* 3 (^ x 2)) -1) : 前置表現(一般表現)
---> (x (2 3) (0 -1)) ---> (x 2 3 0 -1) : 正準表現(CRE表現)
● 単変数多項式の正準表現:
(変数,次数1,係数1,次数2,係数2,...)
● 多変数多項式の正準表現:
(変数,次数1,(係数多項式の正準表現1),次数2,(係数多項式の正準表現2),...)
以下に2変数多項式の正準表現を「x の多項式」と見なした場合と,「yの多項式」と見なした場合の結果を示す.
y*x + 2*x*y^3 - 3
---> (2*y^3 + y)*x - 3 ---> (x 1 (y 3 2 1 1) 0 -3) (x の多項式)
---> 2*x*y^3 + x*y - 3 ---> (y 3 (x 1 2) 1 (x 1 1) 0 -1) (y の多項式)
Maximaは式の表現形式として,「一般表現(前置表現)」と「正準表現(CRE表現)」を併用する. 以下に,それらの内部表現を見る(デバック時に有効となる).
● 単項式と多項式の一般表現
単項式: ((mtimes simp) 数値 変数1の巾,...変数kの巾)
多項式: ((mplus simp) 項1,...,項k)
● 多項式の正準有理式表現(CRE (Cannonical Rational Expression)
表現)
単変数多項式のCRE表現
(変数,次数1,係数1,次数2,係数2,...)
x + y ---> ((MPLUS SIMP) $X $Y)
x - y ---> ((MPLUS SIMP) $X ((MTIMES SIMP) -1 $Y))
x * y ---> ((MTIMES SIMP) $X $Y)
x / y ---> ((MTIMES SIMP) $X ((MEXPT SIMP) $Y -1))
x^y ---> ((MEXPT SIMP) $X $Y)
out : x y$ :lisp $out; で上記の内部表現を得る.
◆ 実行例1
(%i1) out1 : 3*x^2 -1;
2
(%o1) 3 x - 1
(%i2) :lisp $out1;
((MPLUS SIMP) -1 ((MTIMES SIMP) 3 ((MEXPT SIMP) $X 2)))
---> (+ -1 (* 3 (^ x 2)))
(%i2) rat1 : rat(out1);
2
(%o2)/R/ 3 x - 1
(%i3) :lisp $rat1;
((MRAT SIMP ($X) (X15849)) (X15849 2 3 0 -1) . 1)
---> (x 2 3 0 -1) 上記の最後の 「. 1」は分母が1であることを示す.
(%i3) out2 : y*x + 2*x*y^3 - 3;
3
(%o3) 2 x y + x y - 3
(%i4) :lisp $out2;
((MPLUS SIMP) -3 ((MTIMES SIMP) $X $Y)
((MTIMES SIMP) 2 $X ((MEXPT SIMP) $Y 3)))
---> (+ -3 (* x y) (* 2 x (^ y 3)))
(%i4) rat2 : rat(out2);
3
(%o4)/R/ 2 x y + x y - 3
(%i5) :lisp $rat2;
((MRAT SIMP ($X $Y) (X15850 X15849))
(X15849 3 (X15850 1 2) 1 (X15850 1 1) 0 -3) . 1)
---> (y 3 (x 1 2) 1 (x 1 1) 0 -3)
(%i5)
(%i5) rat3 : rat(out2,x);
3
(%o5)/R/ (2 y + y) x - 3
(%i6) :lisp $rat3;
((MRAT SIMP ($Y $X) (X15850 X15849)) (X15849 1 (X15850 3 2 1 1) 0 -3) . 1)
---> (x 1 (y 3 2 1 1) 0 -3)
(%i6) out4 : (y*x + 2*x*y^3 - 3)/(3*x^2 -1);
3
2 x y + x y - 3
(%o6) ----------------
2
3 x - 1
(%i7) :lisp $out4;
((MTIMES SIMP)
((MEXPT SIMP) ((MPLUS SIMP) -1 ((MTIMES SIMP) 3 ((MEXPT SIMP) $X 2))) -1)
((MPLUS SIMP) -3 ((MTIMES SIMP) $X $Y)
((MTIMES SIMP) 2 $X ((MEXPT SIMP) $Y 3))))
---> (*
(^ (+ -1 (* 3 (^ x 2))) -1) <--- 分母
(+ -3 (* x y) (* 2 x (^ y 3)))) <--- 分子
(%i7) rat4 : rat(out4);
3
2 x y + x y - 3
(%o7)/R/ ----------------
2
3 x - 1
(%i8) :lisp $rat4;
((MRAT SIMP ($X $Y) (X15850 X15849))
(X15849 3 (X15850 1 2) 1 (X15850 1 1) 0 -3) X15850 2 3 0 -1)
---> ((y 3 (x 1 2) 1 (x 1 1) 0 -3) x 2 3 0 -1)
<--- 分子 -----------------> <-- 分母 -->
以下に例を示す.
◆ 実行例2
(%i1) out : taylor(exp(x),x,0,5);
2 3 4 5
x x x x
(%o1)/T/ 1 + x + -- + -- + -- + --- + . . .
2 6 24 120
(%i2) :lisp $out;
((MRAT SIMP (((MEXPT SIMP) $%E $X) $X) (%e^x15851 X15852)
(($X ((5 . 1)) 0 NIL X15852 . 2)) TRUNC) PS (X15852 . 2)
((5 . 1)) ((0 . 1) 1 . 1) ((1 . 1) 1 . 1) ((2 . 1) 1 . 2)
((3 . 1) 1 . 6) ((4 . 1) 1 . 24) ((5 . 1) 1 . 120))
式の内部表現の詳細は,横田(p.257—) を参照.
変数や関数といったシンボルに何らかのプロパティ(性質)を付与し,そのシンボルの属性とする行為を考える. 例えば,ある変数に,「正の数である」,「整数である」といったプロパティを付与し,その変数の属性とする 場合や,ある関数に「対称関数である」といったプロパティを付与し,その関数の属性とする行為を指す. また,2つの変数 x, y の間に「 x > y」といった関係をプロパティとして定義することも考える. そのような行為は,まず,プロパティ(性質)を定義し,そのプロパティをシンボルに付与する(結び付ける)ことで 行われる.Maxima では,プロパティをデータベース(リレーショナルデータベース)で管理し,シンボル間に 定義された関係も制御する.Maxima には,事前に定義された多くの標準的なプロパティが用意されている. それら以外に,ユーザによるプロパティの定義も設定できる.それらのプロパティの定義,表示,削除や, シンボルへの付与,付与されたプロパティの表示,その解除といった操作が用意されている.
/home/inoue/bin/go tmp_lang/chunk-27.mx > tmp_lang/chunk-27.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-27.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-27.mx
display2d:false
(-1)^n
(-1)^n
declare(n,odd)
(-1)^n
-1
properties(n)
["database info",kind(n,odd)]
remove(n,odd)
properties(n)
[]
"/var/www/html/LANG/tmp_lang/chunk-27.mx"
odd は変数(オブジェクト)のプロバティである.オブジェクトのプロバティは feature(特徴)と呼ばれる.
/home/inoue/bin/go tmp_lang/chunk-28.mx > tmp_lang/chunk-28.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-28.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-28.mx
display2d:false
sqrt(x^2)
abs(x)
assume(x < 0)
sqrt(x^2)
-x
facts(x)
[0 > x]
forget(x < 0)
facts(x)
[]
"/var/www/html/LANG/tmp_lang/chunk-28.mx"
assume(x<0) によってシンボル間に関係を定義している.ステートメント述語フォーム「x<0」は 変数xと数字0との関係を記述している.
Maxima ではシステムプロバティに関する操作は制限または機能しない. ほとんどのタイプのプロバティには,そのプロバティのインジケータとなる名前である.
gradef(f(x), sin(x))
では, f に lambda([x],sin(x)) の gradef プロバティをリンクするが,インジケータは gradef であり,プロバティは lambda 式である. プロバティの中には,その存在がインジケータの存在のみにより示され,それ以外の情報を必要 としないものがある.それらはフラグと呼ばれる.例えば, %i は constant フラグと関係づけ られる.また, constant が %i のプロバティと解釈できる.
事前定義されたプロバティは,Maxima 内蔵のプロバティである.ユーザ定義のプロバティに関しては 次節を参照.
● declare(’a_1,’f_1,…,’a_k,’f_k) アトム ai にプロバティ fi
を関連づける.
declare(f,incresing) は f を増加関数として宣言する. a_i, f_i
はともにリストを用いることができる. declare([a1,a2],f1)
● remove(’a1,’f1,…,’ak,’fk) アトム ai にプロバティ fi
を削除する.
現在使用されているプロバティを知るには,システム変数 infolists が返す
リスト要素について表示できる.
◆ 実行例:プロパティの表示
/home/inoue/bin/go tmp_lang/chunk-29.mx > tmp_lang/chunk-29.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-29.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-29.mx
linel:70
infolists
[labels, values, functions, macros, arrays, myoptions, props,
aliases, rules, gradefs, dependencies, let_rule_packages, structures]
macros
[]
rules
[]
/var/www/html/LANG/tmp_lang/chunk-29.mx
● featurep(exp,feature) シンボル exp が特徴 feature をもっているかをテストする.
/home/inoue/bin/go tmp_lang/chunk-30.mx > tmp_lang/chunk-30.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-30.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-30.mx
declare(j,even)
done
featurep(j,integer)
true
/var/www/html/LANG/tmp_lang/chunk-30.mx
● props:[ システム変数
● propvars(prop)
● arrayinfo(’arrayname)
● properties(symbol)
● printpropos(’atom,’indicator) スペシャルフォーム
/home/inoue/bin/go tmp_lang/chunk-31.mx > tmp_lang/chunk-31.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-31.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-31.mx
linel:70
properties(%e)
[database info, numer]
properties(integrate)
[transfun, outative, limit function, noun, rule]
declare(const1,constant)
done
properties(const1)
[database info, kind(const1, constant)]
/var/www/html/LANG/tmp_lang/chunk-31.mx
アトムはプロバティを属性として持つことができる.
● put(atom,property,indicator)
アトム atom にインジケータ indicator をもつプロバティ property
を関係付ける.
● qput(’atom,’property,’indicator)
引数が非明示的に引用される.
● get(atom,indicator)
アトム atom から indicator
で指定されたプロバティを引き出す.存在しないときは false を返す.
● rem(atom,indicator) アトム atom から indicator で指定されたプロバティを削除する.
● numerval(var_1,exp_1,…,var_k,exp_k) var_iがexp_iという数値をもつと宣言する.環境変数numer:trueのとき数式の中でその変数が現れると評価される.
/home/inoue/bin/go tmp_lang/chunk-32.mx > tmp_lang/chunk-32.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-32.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-32.mx
put(foo,(a+b)^5,exp)
5
(b + a)
put(foo,"Hello",str)
Hello
properties(foo)
[[user properties, str, exp]]
get(foo,exp)
5
(b + a)
get(foo,str)
Hello
rem(foo,exp)
done
properties(foo)
[[user properties, str]]
numerval(v1,10)
[v1]
ev(v1,numer:true)
10
float(v1)
10
/var/www/html/LANG/tmp_lang/chunk-32.mx
変数と関数に対して以下の数学的プロバティを認識する.
● features システム変数
● opproperties システム変数
/home/inoue/bin/go tmp_lang/chunk-33.mx > tmp_lang/chunk-33.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-33.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-33.mx
linel:70
features
[integer, noninteger, even, odd, rational, irrational, real,
imaginary, complex, analytic, increasing, decreasing, oddfun,
evenfun, posfun, constant, commutative, lassociative, rassociative,
symmetric, antisymmetric, integervalued]
opproperties
[linear, additive, multiplicative, outative, evenfun, oddfun,
commutative, symmetric, antisymmetric, nary, lassociative,
rassociative]
/var/www/html/LANG/tmp_lang/chunk-33.mx
/home/inoue/bin/go tmp_lang/chunk-34.mx > tmp_lang/chunk-34.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-34.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-34.mx
sin(n*%pi)
sin(%pi n)
declare(n,integer)
done
sin(n*%pi)
0
properties(n)
[database info, kind(n, integer)]
featurep(n,integer)
true
remove(n,integer)
done
properties(n)
[]
/var/www/html/LANG/tmp_lang/chunk-34.mx
以下のプロバティは,declare で宣言し,remove で宣言解除, featurep(exp,integer) のように調べることができる.
noun 名詞形(noun) (自動的に評価されないように宣言する) declare(atom,noun)
alphabetic declare(“&”, alphabetic)$ は文字 & を名前に使えるようにする.
evfun declare(function,evfun) はfunction を ev に認識させ,その名前が現れたときに ev が適用できるようになる.
evflag declare(atom,evflag) は atom を ev に認識させ,その名前が挙げられている場合は ev 実行中だけそれに true を付値するようになる.
mainvar declare(symbol,mainvar) は symbol を
mainvar(主変数)にする.このプロパティはデフォルトの変数順序に影響を与える.以下の順序規則に従う.(使わない方が無難!!)
( numbers < constants < scalar < other variables <
mainvars)
bindtest declare(symbol, bindtest) は symbol が未付値の状態で参照されたときにエラーを返す.ただし,グローバルな場合に限る.
feature declare(symbol, feature) は delcare および remove で認識されるプロパティリストに symbol を加える. このプロパティは remove で削除でき,properties で参照できる.
operator infix(atom) は atom をインフィックス演算子にする.このプロパティは remove で削除でき,properties で参照できる.
Maxima には,簡単なリレーショナルデータベースが用意されており,その中 では assume を用いて事実(fact)を宣言できる.関数 assume により宣言され た述語(predicates)は is を用いてテストでき,forget を用いて削除できる. 関数 declare を用いて宣言された特性は featurep を用いてテストでき, remove を用いて削除できる.
● assume(pred_1,…,pred_k)
複数の述語(pred)を引数にとり、まず現在のデータベースとの比較で冗長と一
致を調べる.この述語が一致し冗長でないならば,この述語をデータベースに
追加する.冗長である場合は,アクションは何も発生しない.assume は入力
がデータベースに追加された述語,および適用可能な場所で入力が冗
長であるかあるいは一致していないアトムからなるリストを返す.assume に
よってデータベースにいかなる事実であれ事実が設定されたならば,関係する
変数はデータベースの性質を付与される.
『注意』:演算子”=“は,2つの式が,’構文的に同一’であるときに限,その2式
間で当てはまる関係を示す.それは,数学的な比較ではない.従って,
is((x+1)2=x2+2x+1); はfalseを返すことになる.一方, equal
における関係は,2つの引数の間の’数学的な関係’である. equal
を含む述語は,equal の引数同士が現行のデータベース
からして数学的に同値であるときに限ってtrueを返す.従って,
is(equal((x+1)^2, x^2+2x+1)); はtrueを返す. >, >=, <,
<= もまた数学的な比較を行う.
● assume_pos:false 環境変数
● assume_pos_pred:false 環境変数
● forget(pred_1,…,pred_k)
● is(pred) 述語(pred)が真のときtrueを返し,偽のときはfalseを返す.それ以外の場合 は,環境変数 prederror:true に依存し,trueのときはERRORと なり,falseのとき UNKNOWN となる.
● maybe(pred) 述語(pred)が真のときtrueを返し,偽のときはfalseを返す.それ以外の場合 はUNKNOWNを返す.
● sign(exp) 述語の符号(正負)を調べ,結果を
pos(+), neg(-), zero(0), pz(非負), nz(非正), pn(+ or -), pnz(+ or - or 0)
で返す.関数 sign は意図的に保存された非アトム的式に対しても適用できる.例えば, assume(a+b>0); sign(a+b); は POS を返す.
/home/inoue/bin/go tmp_lang/chunk-35.mx > tmp_lang/chunk-35.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-35.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-35.mx
display2d:false
assume(a >= b,b >= c,c >= d,d >= a)
[a >= b,b >= c,c >= d,d >= a]
"/* 注:上の仮定の最後に注目 */"
L:facts(a)
[a >= b,d >= a]
forget(L)
[[a >= b,d >= a]]
facts()
[b >= c,c >= d]
kill(a,b,c,d)
done
"/* 仮定の表示と仮定内の変数の削除 */"
sign(b-c)
pz
declare(k,integer,m,odd,f,increasing)
assume(x > 0)
[x > 0]
x0:x+3*y^(1+24*k+m)
3*y^(m+24*k+1)+x
sign(f(x0)-f(0))
pos
assume(a > 0,b > 0)
[a > 0,b > 0]
is(a+b > 0)
true
sign(p:(y+10)^2+1)
pos
"/var/www/html/LANG/tmp_lang/chunk-35.mx"
● asksign(exp) exp の符号(正,負,ゼロ)を判定する.判定できないときには必要な質問を行 う.質問への回答内容はデータベースに記録される.
● askexp:false 環境変数
● askinteger(exp, [option_arg]) exp が整数(偶数,奇数)か否かを判定する.オプション引数には integer, even, odd が指定できる.
/home/inoue/bin/go tmp_lang/chunk-36.mx > tmp_lang/chunk-36.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-36.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-36.mx
declare(x,integer)
askinteger(x+3,integer)
yes
askinteger(1+3,odd)
no
/var/www/html/LANG/tmp_lang/chunk-36.mx
● domain:real 環境変数 domain:complex と指定すると sqrt(x^2); は abs(x) ではなく sqrt(x^2) を返す.
● zeroequiv(exp, var) 式 exp を変数 var の単変数関数と見なして解析し,ZERO と 見なせるか否かを判定する.結果を true,false,unknown で返す.
/home/inoue/bin/go tmp_lang/chunk-37.mx > tmp_lang/chunk-37.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-37.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-37.mx
zeroequiv(sin(2*x)-2*sin(x)*cos(x),x)
true
zeroequiv(%e^x+x,x)
false
"/* 注:式を単変数関数と見なせる場合にしか有効な結果を返さない */"
zeroequiv(log(a*b)-log(a)-log(b),a)
dontknow
assume(a > 0,b > 0)
zeroequiv(log(a*b)-log(a)-log(b),a)
dontknow
zeroequiv(log(a*2)-log(a)-log(2),a)
true
/var/www/html/LANG/tmp_lang/chunk-37.mx
コンテクスト機能は1個のコンテクスト名の下でユーザが想定している事実 (facts)のセットを集めることができる.コンテクストの名前を参照し簡約化 しながら,グループとして想定されている事実(facts)の各名前の付けられた セットを起動したり解除したりすることができる.各データベース・コンテク ストはコンテクストの名前を参照することによってグループとして起動したり, それを解除することが可能な事実の集合体である.特定のコンテクストが存在 しない場合は,newcontext に呼び出しをかけることによって作成され る.現在のコンテクストは変数コンテクストの値としてその名前を割り当てる ことによって設定される.あるコンテクストが現在(current)のコンテクスト である場合
式を簡約化する際に現在のコンテクスト内の全ての仮定が適用される.しかしながら,現 在のコンテクストの名前はリスト activecontexts に付加されない.
assume( または forget) で追加 ( 削除 ) された新しい事実は現在のコンテクストに追加される.
コマンド facts(); は現在のコンテクストの事実を表示する.
コンテクストはコマンド activate を用いて起動し, deactivate により解除する.コンテクス トが活動状態になると
コンテクストの名前がリスト activecontexts に付加される.
活動状態 (active) のコンテクストの全ての仮定は簡約化に適用される.
assume( または forget) で追加 ( 削除 ) された新しい事実は現在のコンテクストに追加さ れる.活動状態にあるコンテクスト ( 複数個のコンテクストがありうる ) に追加されるわけではない.
コマンド facts(); は現在のコンテクストの事実を表示する.活動状態にあるコンテクスト (複数個のコンテクストがありうる)の事実ではない. (注意:活動状態のコンテクストの中の仮定は簡約化に 影響をあたえるが,リスト facts の中には現れない点に注意すること)
複数のコンテクストが同時に活動状態になることは可能であるが,同時に2個
の現在(current)コンテクストは存在しない.
コンテクストに含まれる事実は次のことが発生するまで保存される.すなわ
ち,このコンテクストが現在コンテクストにされたのち forget を用
いて個別に事実を削除するか,killcontext を用いてグループとして
のコンテクスト内の全事実を削除するまでである.killcontext を用
いて削除する前にはコンテクストを非活動状態する deactive を実行
する必要がある.
手つかずのMaximaが開始されたとき,ユーザはinitialと呼ば
れるコンテクストの中にいる.これにはglobalと呼ばれるサブコンテ
クストがある.コンテクストは形式的な階層上に存在していて,そのルートに
は常にコンテクストglobalがあり,Maximaのある機能が必要と
する情報を含んでいる.コマンドsupcontextを用いてより小さなコン
テクストを含むより大きなコンテクストが定義される.
● facts(item) item がコンテクスト名のとき,事実のリストを返す.facts() のときは現在(current)のコンテクストの事実を返す.
● newcontext(name) コンテクスト名がnameである,新しい空のコンテクストを作成する. 新コンテクストにはただ1つのサブコンテクストglobalを持っている. 新コンテクストは現在活動状態のコンテクストになる.
● supcontext(name, context) コンテクスト名がnameであり,サブコンテクスト context で ある新しい空のコンテクストを作成する.context が指定されない場 合は現在コンテクストが対応し,指定される場合はcontext が存在す る必要がある.
● context:initial 環境変数 assume, forget によって定義/削除された事実を管理するコンテクス ト名を表示する.本変数を用いてコンテクストの切替えを行う.
● contexts:[initial, global] 環境変数 現在存在しているコンテクスト(活動しているコンテクスト名を含む)のリスト を返す.
● killcontext(context_1,…,context_k)
● active(context_1,…,context_k)
● deactive(context_1,…,context_k)
● activecontexts: システム変数
/home/inoue/bin/go tmp_lang/chunk-38.mx > tmp_lang/chunk-38.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-38.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-38.mx
"/* 注1:文脈con1を設定する */"
context:con1
declare(m,integer)
featurep(m,integer)
true
facts(m)
[kind(m, integer)]
"/* 注2:文脈con2に切替える */"
context:con2
featurep(m,integer)
false
declare(n,integer)
done
"/* 注3:文脈con1に切替える */"
context:con1
featurep(m,integer)
true
featurep(n,integer)
false
"/* 注4:文脈con2に切替える */"
activeate(con2)
featurep(n,integer)
false
"/* 注5:文脈一覧を表示する */"
contexts
[con2, con1, initial, global]
/var/www/html/LANG/tmp_lang/chunk-38.mx
● local(var_1,…,var_k)
block で囲まれている間では,オブジェクト var_1,…,var_k
に関する情報を無視させる.local はblock内 (すなわち,関数
定義内,lambda式内,関数ev内) でのみ用いられる.
/home/inoue/bin/go tmp_lang/chunk-39.mx > tmp_lang/chunk-39.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-39.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-39.mx
declare(p,integer)
test():=block(local(p),print(featurep(p,integer)),declare(p,irrational),
print(featurep(p,irrational)))
featurep(p,integer)
true
test()
false
true
true
featurep(p,irrational)
false
/var/www/html/LANG/tmp_lang/chunk-39.mx
この章では,Maxima が標準的に行う式の簡約化について概観し,その上で,式から部分式を抽出(検出)したり, 抽出した部分式を他の式に置換するといったユーザレベルの操作について説明する.
簡約化の流れ
1.式の全てのサブ式を並べ替える.
2.変数をaからzまでアルファベット順に並べる.
3.定数(%e, %pi, %i),ユーザ定義定数を変数の前に出す.
4.数を前に出す.
例: y+2*a*x-%pi ---> (plus (times -1 %pi) (times 2 a x) y)
● simp:true (環境変数) 簡約化は環境変数 simp (デフォルト true) によってコントロールできる.true の場合,簡約化は自動的に 行われる.このオプション変数はローカルな使用において用いられる.
● unknown(exp)
expの中に簡約子が認識できない演算子や関数が含まれるときにtrueを返す.
● part(exp,p_1,…,p_k)
式 exp の引数 p_1,…,p_k で指定される部分を抽出する. exp
のパートp_1を見付け,次にパートp_1の中からパー
トp2を見付ける.指定された部分が存在しないときはERRORを
返す.この動作は環境変数partswitchの指定で制御できる.
partは抽出部分をシステム変数pieceに付値される.
partはinflagの設定に影響される. また,キーワードフォーム
allbut(arg_1,…,arg_k) で制御される.
/home/inoue/bin/go tmp_lang/chunk-40.mx > tmp_lang/chunk-40.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-40.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-40.mx
display2d:false
ex1:x+y/z^2
part(ex1,1,2,2)
2
ex2:'integrate(f(x),x,a,b)+x
part(ex2,1,1)
f(x)
piece
f(x)
part(x+y+z,[1,3])
z+x
"/var/www/html/LANG/tmp_lang/chunk-40.mx"
● op(exp)
式 exp の演算子を返す.op(exp) は part(exp,0) と 同じ結果を返す.inflag
の影響を受ける.
/home/inoue/bin/go tmp_lang/chunk-41.mx > tmp_lang/chunk-41.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-41.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-41.mx
display2d:false
ex1:x+y/z^2
op(ex1)
"+"
part(ex1,0)
"+"
op(sin(x+y))
sin
op('f(x))
f
op([e1,e2,e3])
"["
"/var/www/html/LANG/tmp_lang/chunk-41.mx"
● partswitch:false 環境変数
trueに設定すると,式の抽出部分が存在しないときにENDを返す.
この環境変数に影響される関数は part, inpart, substpart, substinpart,
dpart, lpart であ る.
● inpart(exp, p_1,…,p_k)
関数 part と同じであるが,表示フォームではなく,内部表記に対し
て作用する.
/home/inoue/bin/go tmp_lang/chunk-42.mx > tmp_lang/chunk-42.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-42.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-42.mx
ex1:x+y+w*z
inpart(ex1,3,2)
z
part(ex1,1,2)
z
/var/www/html/LANG/tmp_lang/chunk-42.mx
● rempart(exp,n)
式 exp から n 番目のパートを削除する.
● inflag:false (環境変数)
true に設定すると,部分抽出関数が exp の内部的なフォームに作用する.
trueに設定した下でのpart, substpart 関数を呼び出すことは,inpart,
substinpart を 呼び出すことと同じ結果を返す.
この環境変数をグローバルにtrueと設定するのは望まれない. ブロック内で
block([inflag:true],…) の様に用いるべきである.
● allbut(arg_1,…,arg_n) キーワードフォーム
part, inpart, substpart, substinpart, dpart, lpart および kill
に影響する.
/home/inoue/bin/go tmp_lang/chunk-43.mx > tmp_lang/chunk-43.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-43.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-43.mx
ex1:a+b+c+d+e
part(ex1,[2,5])
d + a
part(ex1,allbut(2,5))
e + c + b
/var/www/html/LANG/tmp_lang/chunk-43.mx
● args(exp)
exp の引数を返す.exp が関数であるときは,その関数の引数
をリストで返す.また,exp が式であるときは,第1層の演算子をスタ
イル化された関数とみなし,その引数(披演算子)を要素とするリストを返す.
/home/inoue/bin/go tmp_lang/chunk-44.mx > tmp_lang/chunk-44.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-44.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-44.mx
ex1:a+b*c
args(ex1)
[b c, a]
substpart("[",ex1,0)
[b c, a]
args(sin(x+y))
[y + x]
args(sin(x)+y)
[y, sin(x)]
args(f(x,y,z))
[x, y, z]
out:args(c1*f(x,y,z)+c2*g(x,y))
[c1 f(x, y, z), c2 g(x, y)]
map(args,out)
[[c1, f(x, y, z)], [c2, g(x, y)]]
/var/www/html/LANG/tmp_lang/chunk-44.mx
● dispform(exp)
exp をその中心の演算子に関して表した外部的な表記を返す.
/home/inoue/bin/go tmp_lang/chunk-45.mx > tmp_lang/chunk-45.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-45.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-45.mx
ex1:-a
dispform(ex1)
- a
ex2:a+b*c
dispform(ex2)
b c + a
ex3:sin(sqrt(x))
dispform(ex3)
sin(sqrt(x))
/var/www/html/LANG/tmp_lang/chunk-45.mx
● nounify(function_name)
関数名 function_name の名詞フォームを返す.動詞関数の名前を名詞として
参照したいときに必要となる.
● verbify(function_name)
関数名 function_name の動詞フォームを返す.
/home/inoue/bin/go tmp_lang/chunk-46.mx > tmp_lang/chunk-46.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-46.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-46.mx
ex1:'limit(f(x)^g(x),x,0,minus)
nounify('limit)
limit
is(inpart(ex1,0) = nounify('limit))
true
verbify('limit)
limit
/var/www/html/LANG/tmp_lang/chunk-46.mx
● listofvars(exp)
式 exp に含まれる変数のリストを返す.
/home/inoue/bin/go tmp_lang/chunk-47.mx > tmp_lang/chunk-47.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-47.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-47.mx
listofvars(f(x,y,z))
[x, y, z]
listofvars(c1*f(x,y,z)+c2*g(x,y))
[c2, x, y, c1, z]
/var/www/html/LANG/tmp_lang/chunk-47.mx
● listconsvars:false 環境変数
true のとき,システム定数(%e,%pi,%i),ユーザ定義の定数を listofvars
の対象に加える.
● listdummyvars:true 環境変数
false のとき,ダミー変数をlistofvars の対象に加えない. 「ダミー変数」は
総和関数,定積分に現れる積分変数,等をいう.
/home/inoue/bin/go tmp_lang/chunk-48.mx > tmp_lang/chunk-48.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-48.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-48.mx
display2d:false
ex1:f(x[1]+y)/g(2+a)
listofvars(ex1)
[a,x[1],y]
ex2:'sum(f(i),i,0,n)
listofvars(ex2)
[i,n]
listdummyvars:false
listofvars(ex2)
[n]
"/var/www/html/LANG/tmp_lang/chunk-48.mx"
● coeff(exp,var,n)
式 exp における var^n の係数を返す.引数 n は 1 のとき省略できる.var
には exp 内のアトム, または x, sin(x), a[i+1],x+y
などの完全なサブ式を指定できる.式 (x+y)*(a+b+c) において, x+y
は完全サブ式であるが a+b は完全サブ式ではない.ratcoef を参照.
/home/inoue/bin/go tmp_lang/chunk-49.mx > tmp_lang/chunk-49.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-49.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-49.mx
display2d:false
ex1:(x+y)*(a+b+c)
(c+b+a)*(y+x)
coeff(ex1,x+y)
c+b+a
coeff(ex1,a+b)
0
coeff(2*a*tan(x)+tan(x)+b = 5*tan(x)+3,tan(x))
2*a+1 = 5
coeff(y+x*%e^x+1,x,0)
y+1
"/var/www/html/LANG/tmp_lang/chunk-49.mx"
● ratcoef(exp,var,n)
式 exp における var^n の係数を返す.ただし,exp
を有理的に展開,簡約化を行ってから var^n の 係数を返す.
/home/inoue/bin/go tmp_lang/chunk-50.mx > tmp_lang/chunk-50.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-50.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-50.mx
display2d:false
coeff((x+1)/y+x,x)
1
ratcoef((x+1)/y+x,x)
(y+1)/y
ratcoef(a*x+b*x,a+b)
x
"/var/www/html/LANG/tmp_lang/chunk-50.mx"
\(x + \frac{x+1}{y} = \frac{y+1}{y}\,x + \frac{1}{y}\) と 上記の結果を比較する.
● bothcoef(exp,var)
結果をリストで返す.リストの第1要素は式 exp における var
の係数を,第2要素は残り部分を返す. ただし,exp
が一般表現の場合は,coeff が,CRE表現の場合は ratcoef
が返すものとなる.
/home/inoue/bin/go tmp_lang/chunk-51.mx > tmp_lang/chunk-51.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-51.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-51.mx
display2d:false
bothcoef(a*x+b,x)
[a,b]
"/* 注:次の2例を比較する */"
bothcoef((x+1)/y+x,x)
[1,(x+1)/y]
bothcoef(rat((x+1)/y+x),x)
[(y+1)/y,1/y]
bothcoef(a*x+b*x,a)
[x,b*x]
"/var/www/html/LANG/tmp_lang/chunk-51.mx"
● pickapart(exp,depth)
式 exp において,指定された整数の深度までの全てのサブ式をtラインに示す.
この関数は inflag の影響を受ける.
/home/inoue/bin/go tmp_lang/chunk-52.mx > tmp_lang/chunk-52.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-52.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-52.mx
display2d:false
exp:(a+b)/2+sin(x^2)/3-log(1+sqrt(x+1))
(-log(sqrt(x+1)+1))+sin(x^2)/3+(b+a)/2
pickapart(exp,1)
-log(sqrt(x+1)+1)
sin(x^2)/3
(b+a)/2
%t6+%t5+%t4
"/var/www/html/LANG/tmp_lang/chunk-52.mx"
● numfactor(exp)
式 exp に乗算されている数値的因数を返す.式 exp
は単一の項でなければならない.
● hipow(exp,var) <—> lopow(exp,var)
hipow(exp,var) は,式 exp の var
に関する’明示的な’最高次の次数を返す.
lopow(exp,var) は,式 exp の var
に関する’明示的な’最低次の次数を返す.
● lhs(eq) <—> rhs(eq)
lhs(eq) は方程式 eq の左辺を返し,rhs(eq)は方程式 eq の右辺を返す.
● first(exp) <—> last(exp)
exp の1番目の部分,最後の部分を返す.
● rest(exp,n)
n が正ならば,exp から先頭の n 個の部分を取り除いた残りを返し, n
が負ならば,exp から最後の n 個の部分を取り除いた残りを返す. n = 1
のときは省略できる.exp にはリスト,行列などの式を指定できる.
inflag:true のときは,exp の内部表現が使われる.
● partition(exp,var)
以下の2つの式からなるリストを返す. 第1要素:var を含まない exp
の中の因数(exp が積の場合),exp の項(exp が和の場合), exp
のサブリスト(exp がリストの場合)を返す. 第2要素:var を含む exp
の中の因数(exp が積の場合),exp の項(exp が和の場合),exp の
サブリスト(exp がリストの場合)を返す.
/home/inoue/bin/go tmp_lang/chunk-53.mx > tmp_lang/chunk-53.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-53.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-53.mx
display2d:false
partition(2*a*x*f(x),x)
[2*a,x*f(x)]
partition(a+b,x)
[b+a,0]
partition([a,b,f(a),c],a)
[[b,c],[a,f(a)]]
"/var/www/html/LANG/tmp_lang/chunk-53.mx"
● delete(exp_1, exp_2)
exp_2 に現れる exp_1 の部分をすべて削除する.exp_1 は exp_2
が和ならばその項, 積ならばその因数とする.
/home/inoue/bin/go tmp_lang/chunk-54.mx > tmp_lang/chunk-54.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-54.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-54.mx
delete(sin(x),x+sin(x)+y)
y + x
/var/www/html/LANG/tmp_lang/chunk-54.mx
● delete(exp_1, exp_2, n)
exp_2 に現れる exp_1 の部分を n 個だけ削除する.exp_1 の部分が n
個以下のときはすべて取り除く.
● rempart(exp,n)
n が length(exp) 以下の整数のときは,n 番目の部分を消去した exp を返す.
n の部分がリスト [l,m] の場合は l 番目から m
番目の部分を消去した残りを返す.
● length(exp)
exp
の外部的なフォームにおける部分の個数を返す.リストの場合は要素の個数,行列の場合は行数,
和の場合は項数,積の場合は因数を返す.inflag:true のときは,exp
の内部表現が使われる.
/home/inoue/bin/go tmp_lang/chunk-55.mx > tmp_lang/chunk-55.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-55.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-55.mx
display2d:false
inflag:false
length(a/(b*c))
2
inflag:true
length(a/(b*c))
3
"/var/www/html/LANG/tmp_lang/chunk-55.mx"
● nterms(exp)
exp
が完全展開され,どのような縮約の項の結合も行われていない状態での項数を返す.
Maxima の置換機能は次の3グループに分かれる.
本節では,上記 1, 2 を扱う.
● subst(new,old,exp)
exp に現れる old をすべて new に置換する. old は exp
のアトムか完全なサブ式でなければならない.例 えば,2*(x+y+z)/w
において,x+y+z は完全なサブ式であるが x+y はそうではない. 引数 new,
old には演算子を” で囲んだものや関数名も指定で
きる.導関数フォームにおける独立変数の置換は at を用いること. old
が完全サブ式でない場合の置換は substpart, ratsubst が使える. (ratsubst
を参照.)
/home/inoue/bin/go tmp_lang/chunk-56.mx > tmp_lang/chunk-56.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-56.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-56.mx
display2d:false
subst(a,x+y+z,(2*(x+y+z))/w)
(2*a)/w
subst(a,x+y,(2*(x+y+z))/w)
(2*(z+y+x))/w
subst(a^f,e^(1/f),z+e^(1/f))
z+a^f
subst(a*f,e/f,z+e/f)
z+a*f
subst(a,sqrt(x),1/sqrt(x))
1/a
subst(a,x+y,x+(x+y)^2+y)
y+x+a^2
subst(-%i,%i,a+b*%i)
a-%i*b
"/var/www/html/LANG/tmp_lang/chunk-56.mx"
● subst(eq,exp)
● subst([eq_1,…,eq_k],exp)
eq は置換規則を示す方程式であり,方程式の左辺を右辺の内容に置換する.
リストによる置換規則ではリストの左から右に向かって逐次置換される.
● opsubst(operator_1,operator_2,exp)
exp における 演算子 operator_2 を 演算子 operator_1 に置換する.
演算子 operator_2 はシンボリックなアトムでなければならない.
例えば,opsubst(a,b[1],b1] はサポートされていない.
/home/inoue/bin/go tmp_lang/chunk-57.mx > tmp_lang/chunk-57.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-57.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-57.mx
load("opsubst")
display2d:false
opsubst(f,g,g(g(x)))
f(f(x))
opsubst(g[x],f,f(z))
g[x](z)
opsubst(tan,sin,sin(sin))
tan(sin)
opsubst([f = g,g = h],f(x))
h(x)
opsubst("+","-",a-b)
a-b
opsubst(g[5],f,f(x))
g[5](x)
opsubst([cot = lambda([x],cos(x)/sin(x)),tan = lambda([x],sin(x)/cos(x))],
cot(tan)+tan(b))
cos(tan)/sin(tan)+sin(b)/cos(b)
"/var/www/html/LANG/tmp_lang/chunk-57.mx"
● opsubst(eq,exp)
● opsubst([eq_1,…,eq_k],exp)
● derivsubst:false 環境変数
/home/inoue/bin/go tmp_lang/chunk-58.mx > tmp_lang/chunk-58.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-58.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-58.mx
derivsubst:true
display2d:false
subst(x,'diff(y,t),'diff(y,t,2))
'diff(x,t,1)
"/var/www/html/LANG/tmp_lang/chunk-58.mx"
● exptsubst:false 環境変数
true であるとき,指数部の置換を行う.
/home/inoue/bin/go tmp_lang/chunk-59.mx > tmp_lang/chunk-59.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-59.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-59.mx
exptsubst:true
subst(y,a^x,a^(k*x))
k
y
/var/www/html/LANG/tmp_lang/chunk-59.mx
● opsubst:true 環境変数
false であるとき,subst が式の演算子の中まで置換を持ち込
まなくなる.
/home/inoue/bin/go tmp_lang/chunk-60.mx > tmp_lang/chunk-60.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-60.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-60.mx
display2d:false
subst(x^2,r,r+r[0])
x^2+(x^2)[0]
opsubst:false
subst(x^2,r,r+r[0])
x^2+r[0]
"/var/www/html/LANG/tmp_lang/chunk-60.mx"
● substpart(x,exp,n_1,…,n_k)
part の場合と同様に,式 exp の パート n_1,…,n_k を x に置換する.
/home/inoue/bin/go tmp_lang/chunk-61.mx > tmp_lang/chunk-61.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-61.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-61.mx
display2d:false
ex1:1/(x^2+2)
substpart(3/2,ex1,2,1,2)
1/(x^(3/2)+2)
ex2:a*x+f(b,y)
substpart("+",ex2,1,0)
x+f(b,y)+a
"/var/www/html/LANG/tmp_lang/chunk-61.mx"
● substinpart(x,exp,n_1,…,n_k)
substpart において,exp の内部表現に適用される.
/home/inoue/bin/go tmp_lang/chunk-62.mx > tmp_lang/chunk-62.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-62.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-62.mx
display2d:false
ex1:x . 'diff(f(x),x,2)
x . 'diff(f(x),x,2)
substinpart(d^2,ex1,2)
x . d^2
substinpart(f1,f[1](x+1),0)
f1(x+1)
"/var/www/html/LANG/tmp_lang/chunk-62.mx"
● sublis(list,exp)
1つの式 exp において複数の置換を並行して行う.リスト list は
[sym_1=exp_1,sym_2=exp_2,…] の形式を取り,sym_i はシンボル
である必要がある.該当部分がない場合は元の表現 exp を返す.
/home/inoue/bin/go tmp_lang/chunk-63.mx > tmp_lang/chunk-63.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-63.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-63.mx
display2d:false
sublis([a = b,b = a],sin(a)+cos(b))
sin(b)+cos(a)
sublis([a = b],c+d)
d+c
"/var/www/html/LANG/tmp_lang/chunk-63.mx"
● sublis_apply_lambda:true 環境変数
lambda の置換を sublis 実行後の簡約化においても適用し続 けるか,もしくは
ev を使わなければこの適用が起こらないようにす るかを制御する.true
は適用の継続を意味する.
● ratsubst(new,old,exp)
式 exp における old を new に置換する.old
には,和,積,べき指数などを指定できる.
式の内容を考慮した置換を行う.
/home/inoue/bin/go tmp_lang/chunk-64.mx > tmp_lang/chunk-64.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-64.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-64.mx
display2d:false
"/* 注1:subst()とratsubst()の比較 */"
subst(a,x+y,x+y+z)
z+y+x
ratsubst(a,x+y,x+y+z)
z+a
"/* 注2:ratsubst()の使用例 */"
ratsubst(a,x*y^2,x^4*y^3+x^4*y^8)
a*x^3*y+a^4
ex:cos(x)^4+cos(x)^3+cos(x)^2+cos(x)+1
ratsubst(1-sin(x)^2,cos(x)^2,ex)
sin(x)^4-3*sin(x)^2+cos(x)*(2-sin(x)^2)+3
"/* 注3:radsubstflag の比較 */"
radsubstflag:false
ratsubst(u,sqrt(x),x)
x
radsubstflag:true
ratsubst(u,sqrt(x),x)
u^2
"/var/www/html/LANG/tmp_lang/chunk-64.mx"
● lratsubst(list_of_equations, exp)
ratsubst における置換規則の部分をリストで表記する.リストの置換規則は
左から右に評価される.
/home/inoue/bin/go tmp_lang/chunk-65.mx > tmp_lang/chunk-65.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-65.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-65.mx
display2d:false
load(lrats)
"/usr/share/maxima/5.46.0/share/simplification/lrats.mac"
"/* 注1: 下では規則 a->x, b->y を適用している */"
subst([a = x,b = y],a+b)
y+x
"/* 注2: 下では式の展開後に規則 a^2->x, b^2->y を適用している */"
lratsubst([a^2 = x,b^2 = y],(a+b)^2)
y+x+2*a*b
lratsubst(a^2 = x,a^3)
a*x
"/var/www/html/LANG/tmp_lang/chunk-65.mx"
● fullratsubst(new,old,exp)
ratsubst と同じであるが,結果において再帰的呼び出しを行い,結果がそれ
以上変化しなくなるまで適用される.
/home/inoue/bin/go tmp_lang/chunk-66.mx > tmp_lang/chunk-66.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-66.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-66.mx
display2d:false
load(lrats)
"/usr/share/maxima/5.46.0/share/simplification/lrats.mac"
ratsubst(a*b,a^2,a^3)
a^2*b
"/* 注1:上では,a^3 -> a^2*a -> (a*b)*a -> a^2*b */"
fullratsubst(a*b,a^2,a^3)
a*b^2
"/* 注2:上では,a^3 -> a^2*a -> (a*b)*a -> a^2*b -> (a*b)*b -> a*b^2 */"
fullratsubst([a^2 = b,b^2 = c,c^2 = a],a^3*b*c)
a^2
fullratsubst(a^2 = b*a,a^3)
a^2*b
"/var/www/html/LANG/tmp_lang/chunk-66.mx"
errcatch (fullratsubst (b*a^2, a^2, a^3)); では エラー ‘「*** - Lisp stack overflow. RESET」’ が出るので注意する.
● atvalue(form,list_of_equations,value)
list_of_equations で指定される点において,境界値 value を form
に代入する.form は関数 f(var1,…,vark)
または関数の引数が明示されている導関数 diff(f(var1,…,vark),
var1,n1,…,vark,nk) でなければならない(添字付き変数は使用できない).
シンボル @1,@2,… は,atvalue の表示における,変数
var1,var2,… を表す.
● printprops([f_1,…,f_k),atvalue)
atvalue で設定された現時点での内容を表示する.all を指定できる.
/home/inoue/bin/go tmp_lang/chunk-67.mx > tmp_lang/chunk-67.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-67.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-67.mx
atvalue(f(x,y),[x = 0,y = 1],a^2)
2
a
atvalue('diff(f(x,y),x),x = 0,1+y)
@2 + 1
printprops(all,atvalue)
!
d !
--- (f(@1, @2))! = @2 + 1
d@1 !
!@1 = 0
2
f(0, 1) = a
done
/var/www/html/LANG/tmp_lang/chunk-67.mx
● at(exp, list_of_equations)
exp (任意の式が指定できる) の変数を list_of_equations で
指定される値,または関数 atvalue に与えるのと同様の形式で置換する.
/home/inoue/bin/go tmp_lang/chunk-68.mx > tmp_lang/chunk-68.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-68.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-68.mx
diff(4*f(x,y)^2-u(x,y)^2,x)
d d
8 f(x, y) (-- (f(x, y))) - 2 u(x, y) (-- (u(x, y)))
dx dx
at(%,[x = 0,y = 1])
! !
d ! d !
8 f(0, 1) (-- (f(x, 1))! ) - 2 u(0, 1) (-- (u(x, 1))! )
dx ! dx !
!x = 0 !x = 0
/var/www/html/LANG/tmp_lang/chunk-68.mx
◆ 実行例
batchload("/home/inoue/.maxima/max-init.mac")$
on3lib()$ /* on3ライブライリーの呼び出し */
f2l();
f2l(a+b*(c+d));
f2l(f1*log(x)*on3(x,1,2,co)+f0);
l2f();
L : ["+",["*",f1,[on3,x,3,4,co]],[on3,x,1,2,co]];
l2f(L);
if false then (l2f('ex), grind(l2f));
/home/inoue/bin/go tmp_lang/chunk-69.mx > tmp_lang/chunk-69.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-69.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-69.mx
batchload("/home/inoue/.maxima/max-init.mac")
file_search1: /home/inoue/.maxima/max-init.mac not found in file_search_maxima.
-- an error. To debug this try: debugmode(true);
/var/www/html/LANG/tmp_lang/chunk-69.mx
パターン照合コマンドは,特定のパターンと式の中にある部分がマッチするかをテストする方法を提供し, それからマッチした部分を特定の置換式で入れ換える.パターン照合プログラムには,ユーザ定義または システム定義の関数あるいは演算子に用いる簡約化のルールを追加することができる. ルール(規則)は次の手順で記述される.
パターン変数の定義: matchdeclare() を用いて,パターン照合に適合したパターンを以後のルール適用の 対象とする.
規則の定義:置換規則を定義する.定義方法としては, defrule() , tellsimp() , tellsimpafter と let() がある.
規則の適用:規則の適用は, defrule() による規則は apply() によって実行され, tellsimp() と tellsimpafter() による規則は自動実行される.また, let() による規則は letsimp() によって実行される.
また,定義できる規則に関して,以下の制限がある.
defrule で指定できるパターンは, matchdeclare で宣言した変数の可換積「*」や和「+」 は指定できない.複数個の規則は, defrule(rule_1,prod,repl) , defrule(rule_2,prod,repl) のように定義され, apply(exp,rule_1,rule_2) のように適用される.
tellsimp で指定できるパターンは,「和」,「積」, 単変数」や「数値」は指定できない.なお,規則の適用は Maxima の内部簡約化の前に実行される. 一方, tellsimpafter で指定できるパターンは,「単変数」や「数」を除く,任意の式が指 定できる.規則の適用は Maxima の内部簡約化の後に実行される.
let で指定できるパターンは,アトム, sin(x) や f(x,y) のような関数の可換積「*」や 商「/」や巾「 ^ 」を含む「項」 ( 単項式であって多項式は許さない ) を指定できる.ただ し,負の巾を用いる場合には,環境変数 letrat:false を true に設定する必要がある. 複数個の規則は, let([prod,repl],rule_1) , let([prod,repl],rule_2) のように定 義され, letsimp(exp,rule_1,rule_2) のように適用される.
規則の表示は, rules; で規則名を表示する.また, disprule(rule_1,rule_2) , disprule(all) ,または, letrules(rule_1) を用いる. 規則の削除は, remrule(prod,name) , remrule(all) または, remlet(prod,name) , remlet(all) を用いる. 規則の例としては, /usr/share/maxima/5.11.0/share/trigonometry 内の trgsimp.mac , atrig1.mac 等が参考になる.
/home/inoue/bin/go tmp_lang/chunk-70.mx > tmp_lang/chunk-70.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-70.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-70.mx
kill(all)
load(trgsmp)
rules
[trigrule1, trigrule2, trigrule3, trigrule4, htrigrule1, htrigrule2,
htrigrule3, htrigrule4]
disprule(all)
sin(a)
(%t3) trigrule1 : tan(a) -> ------
cos(a)
1
(%t4) trigrule2 : sec(a) -> ------
cos(a)
1
(%t5) trigrule3 : csc(a) -> ------
sin(a)
cos(a)
(%t6) trigrule4 : cot(a) -> ------
sin(a)
sinh(a)
(%t7) htrigrule1 : tanh(a) -> -------
cosh(a)
1
(%t8) htrigrule2 : sech(a) -> -------
cosh(a)
1
(%t9) htrigrule3 : csch(a) -> -------
sinh(a)
cosh(a)
(%t10) htrigrule4 : coth(a) -> -------
sinh(a)
[%t3, %t4, %t5, %t6, %t7, %t8, %t9, %t10]
/var/www/html/LANG/tmp_lang/chunk-70.mx
このセクションは4つのパートに分かれている. 第1パートは,matchdeclare を用いてパターン変数を定義する方法を説明する. 第2パートは,tellsimp, tellsimpafter, defmatch, defrule を用いてルールを定義する方法を説明する. 第3パートは,ルールの表示について説明する. 第4パートは,apply1, apply2, applyb1 を使ってルールを適用する方法について説明する. 有理式の部分の照合に関しては,let を用いること.
● matchdeclare(pattern_var, predicate,…)
述語 predicate が true である式のみを照合するために patternvar
を定義する. 例えば,matchdeclare(q,freeof(x,%e)); が実行された後には q
は x あるいは %e を含まない式と照合する.
この照合に成功すると,その後変数は照合された式に設定される.述語(この例では
freeof)
は,パターン変数がテストされる最後の引数がない状態で記述される.freeof
の構文は freeof(x,%e,exp) である.
patternvar および predicate
の引数は,照合が実行されるときに評価される.matchdeclare(var,true);
は var がどんな式とも照合する.printprop([var1,…,vark],matchdeclare);
は変数 var1,…,vark の matchdeclare プロパティを表示する.
パターン変数によって記述される検出すべきパターンと置換規則(ルール)を定義する方法について説明する. ルールの定義の方法は,第1の方法として,telsimp,telsimpafter による方法で, 第2の方法は, defrule による方法である.第1の方法によって定義されたルールはそれが定義された後, 内部簡約化の機能によって適用される.(正確には,telsimp は内部簡約化の前に処理され,telsimpafter では 内部簡約化の後に処理される). 一方,第2の方法では,ユーザによって陽に適用されたときのみ処理される.
● tellsimp(pattern, replacement,[condition]) 検出パターン pattern と置換規則 replacement および追加的な引数として条件 condition を与える. この変換規則は内部簡約化の前に適用される. 追加引数 condition は is(condition); がtrueと評価される場合のみ適用される.
/home/inoue/bin/go tmp_lang/chunk-71.mx > tmp_lang/chunk-71.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-71.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-71.mx
display2d:false
kill(all)
"/* 注1: 下では,展開後の項 sin(x)^2 に置換規則を作用する */"
matchdeclare(x,true)
tellsimp(sin(x)^2,1-cos(x)^2)
[\^rule1,simpexpt]
(1+sin(x))^2
(sin(x)+1)^2
expand((1+sin(x))^2)
2*sin(x)-cos(x)^2+2
"/* 注2: 下では,関数 f に対して巾等性を与える */"
matchdeclare(x,true,k,integerp)
tellsimp(f(x)^k,f(x),k > 0)
[\^rule2,\^rule1,simpexpt]
f(x)^3
f(x)
f(x)^-3
f(x)
expand((1+f(y))^2)
3*f(y)+1
"/var/www/html/LANG/tmp_lang/chunk-71.mx"
● tellsimpafter(pattern, replacement,[condition]) tellsimp と異なる点は,適用時点が内部簡約化の後である点である.
/home/inoue/bin/go tmp_lang/chunk-72.mx > tmp_lang/chunk-72.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-72.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-72.mx
display2d:false
kill(all)
"/* 注1: 下では,関数 f に対して規則 1/f -> f を与える(失敗例?) */"
f(x)/f(x)
1
matchdeclare(x,true,k,integerp)
tellsimpafter(f(x)^k,f(x))
[\^rule1,simpexpt]
f(x)/f(x)
f(x)
expand((1+f(y))/f(y))
2*f(y)
kill(all)
"/* 注2: 下では,関数 f に対して規則 1/f -> f を与える(成功例) */"
matchdeclare(x,true,k,integerp)
tellsimp(f(x)^k,f(x))
[\^rule2,simpexpt]
f(x)/f(x)
f(x)
expand((1+f(y))/f(y))
2*f(y)
"/var/www/html/LANG/tmp_lang/chunk-72.mx"
● defmatch(’progname,’pattern, ’parm_1,…,’parm_k) 関数名が progname で,引数 ’parm_1,…,’parm_k をもつ関数 progname(’parm_1,…,’parm_k) を, パターン ’pattern を照合する照合関数として宣言する.照合関数として宣言された関数は,パターンと照合し, false または 照合結果リストを返す.以下に実行例を示す.
◆ 実行例1:照合関数の定義
/home/inoue/bin/go tmp_lang/chunk-73.mx > tmp_lang/chunk-73.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-73.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-73.mx
display2d:false
kill(all)
"/* 注1: パターン変数 a, b を定義する */"
matchdeclare(a,freeof(x),b,freeof(x))
"/* 注2: パターン a*x+b を照合する照合関数 linearp(exp,x) を定義する */"
defmatch(linearp,a*x+b,x)
"/* 注3: 照合関数 linearp(exp,x) の使用例 */"
linearp(3*z+(y+1)*z+y^2,z)
[b = y^2,a = y+4,x = z]
linearp(3*z+(y+1)*z+z^2,z)
false
"/var/www/html/LANG/tmp_lang/chunk-73.mx"
パターン変数 a, b を変数 x と独立である属性をもつとする.
(freeof(x,a) : 「 a が x に依存しない」 が true を返す属性 ) ここで,関数
freeof() の構文は freeof(x1,x2,…,exp) であることに注意する.
関数 linearp(exp,x) を, exp が x に関してバターン a*x+b
に一致するかを照合する照合関数として 定義する.
照合関数 linearp(exp,x) を用いて, exp=3z + (y+1)z + y^2 が変数 z に関して上記の照合 パターンを照合する.
◆ 実行例2:照合関数の定義
/home/inoue/bin/go tmp_lang/chunk-74.mx > tmp_lang/chunk-74.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-74.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-74.mx
display2d:false
kill(all)
"/* 注0: 関数 integrate の属性を表示する */"
properties(integrate)
[transfun,outative,"limit function",noun,rule]
"/* 注1: パターン変数 a, f を定義する */"
matchdeclare([a,f],true)
"/* 注2: 以下で用いる述語関数constinterval()を事前定義する */"
constinterval(l,h):=constantp(h-l)
"/* 注3: パターン変数 b を「b-a:定数である」変数として定義する*/"
matchdeclare(b,constinterval(a))
matchdeclare(x,atom)
"/* 注4:関数integrate からoutative属性を一端削除する */"
"/* 注5:'integrate(f,x,a,b)を照合する照合関数checklimit()を定義する */"
(remove(integrate,outative),defmatch(checklimits,'integrate(f,x,a,b)),
declare(integrate,outative))
"/* 注6:照合関数checklimit()の使用例 */"
ex1:'integrate(sin(t),t,%pi+x,2*%pi+x)
'integrate(sin(t),t,x+%pi,x+2*%pi)
checklimits(ex1)
[b = x+2*%pi,a = x+%pi,x = t,f = sin(t)]
ex2:'integrate(sin(t),t,0,x)
'integrate(sin(t),t,0,t)
checklimits(ex2)
false
"/var/www/html/LANG/tmp_lang/chunk-74.mx"
● defrule(’rulename,’pattern, replacement)
与えられたパターン pattern に対し,replacement
のルールを定義し,ルール名 rulename を付ける. 例えば,ルール
atan2_to_atan を定義し,atan2 フォームを atan フォームに置換する.
/home/inoue/bin/go tmp_lang/chunk-75.mx > tmp_lang/chunk-75.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-75.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-75.mx
display2d:false
matchdeclare([y,x],true)
defrule(atan2_to_atan,atan2(y,x),atan(y/x))
apply1(2*atan2(v,u),atan2_to_atan)
2*atan(v/u)
"/var/www/html/LANG/tmp_lang/chunk-75.mx"
● remrule(operator,rulename)
operator からルール rulename を削除する.
/home/inoue/bin/go tmp_lang/chunk-76.mx > tmp_lang/chunk-76.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-76.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-76.mx
tellsimp(foo(aa,bb),bb-aa)
[foorule1, false]
foo(aa,bb)
bb - aa
tellsimpafter(aa+bb,special_add(aa,bb))
[+rule1, simplus]
aa+bb
special_add(aa, bb)
a+b
b + a
remrule(foo,foorule1)
foo
remrule("+","+rule1")
remrule: no such rule: "+rule1"
-- an error. To debug this try: debugmode(true);
/var/www/html/LANG/tmp_lang/chunk-76.mx
● rules:[] システム変数
● apply1(exp,rule_1,…,rule_k)
式 exp に規則 rule_1 を適用する.その結果に対して規則 rule_2
を適用する. 以下同様の処理を規則 rule_k まで続け,結果を返す.
● apply2(exp,rule_1,…,rule_k)
式 exp に規則 rule_1 を適用し,この処理に失敗すると,規則 rule_2
を適用する.現在は機能しない.
● applyb1(exp,rule_1,…,rule_k)
apply1 が式の上から下(全体から部分)に作用するのに対して,applyb1
は下から上(部分から全体)へ作用する.
● maxapplydepth:10000 環境変数
● maxapplyheight:10000 環境変数
/home/inoue/bin/go tmp_lang/chunk-77.mx > tmp_lang/chunk-77.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-77.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-77.mx
display2d:false
kill(all)
matchdeclare(x,true,k,integerp)
defrule(drule1,f(x)*g(x),f(x)^2)
defrule(drule2,f(x)^k,f(x))
apply1(f(x)*g(x),drule1,drule2)
f(x)
apply1(f(x)*g(x),drule2,drule1)
f(x)^2
apply1(f(x)*h(x)*f(x),drule1,drule2)
f(x)*h(x)
"/var/www/html/LANG/tmp_lang/chunk-77.mx"
● let(prod,repl,predname,arg_1,…,arg_k)
prod が repl によって置き換えられるような letsimp
に対する置換のルールを定義する. 引数 prod はタイプ(シンボル,sin(x),
n!, f(x,y) といったカーネル)の項の正数あるいは負数の
累乗の積となる.
● let([prod,repl,predname,arg_1,…,arg_k], name)
スペシャルフォーム
ルールパッケージ名にルールを挿入する。ルールパッケージ名でルールを適用するには,
letsimp(exp,name_1,…,name_k) のようにする.
● letrat:false 環境変数
false のとき,letsimp は exp
の分子と分母を個別に簡約化し,結果を返す.n! を (n-1)! にする
ような置換では失敗する.そのような場合に true
にすると,分子,分母,商がこの順序で簡約化される.
● remlet(prod,name)
関数 let によって最も最近に定義された置換ルール prod -> repl
を削除する. 引数 name
が指定された場合は,ルールパッケージ名から削除される.remlet(); および
remlet(all); は現在のルールパッケージから全置換ルールを削除する.
● current_let_rule_package: default_let_rule_package 環境変数
● let_rule_package: [default_let_rule_package] システム変数
● letrules(name)
ルールパッケージ名を表示する.letrules(); は現在のルールパッケー
ジ名の中のルールを表示する.
● letsimp(exp) スペシャルフォーム
関数 let により事前定義されている置換規則をくり返し適用する.
letsimp(exp, rule_pkg_name) はルールパッケージ rule_pkg_name
内で定義されたルールにのみ適用される.
/home/inoue/bin/go tmp_lang/chunk-78.mx > tmp_lang/chunk-78.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-78.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-78.mx
matchdeclare([a,a1,a2],true)
oneless(x,y):=is(x = y-1)
let(a1*a2!,a1!,oneless,a2,a1)
a1 a2! --> a1! where oneless(a2, a1)
letrat:true
let(a1!/a1,(a1-1)!)
a1!
--- --> (a1 - 1)!
a1
letsimp((n*m!*(n-1)!)/m)
(m - 1)! n!
let(sin(a)^2,1-cos(a)^2)
2 2
sin (a) --> 1 - cos (a)
letsimp(sin(x)^4)
4 2
cos (x) - 2 cos (x) + 1
/var/www/html/LANG/tmp_lang/chunk-78.mx
パターン照合の最も単純なフォームは式に適用される述語がtrueかfalseを返 すかをテストをすることである.以下の述語関数は特定の属性に対する引数を テストするためのリストである.
● numberp(exp) 整数,有理数,浮動小数点数を判定
● intergerp(exp) 整数を判定
● floatp(exp) 浮動小数点数を判定
● bfloatp(exp) 倍精度浮動小数点数を判定
● primep(exp) 素数を判定
● ratnump(exp) 有理数を判定
● even(exp) 偶数を判定
● odd(exp) 奇数を判定
● zeroequiv(exp,var) ゼロを判定
/home/inoue/bin/go tmp_lang/chunk-79.mx > tmp_lang/chunk-79.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-79.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-79.mx
map(numberp,[3,-3,3.14,%e,%pi,%i,%phi,inf,minf])
[true, true, true, false, false, false, false, false, false]
map(symbolp,[3,-3,3.14,%e,%pi,%i,%phi,inf,minf])
[false, false, false, true, true, true, true, true, true]
map(integerp,[0,1,-3,1.0,inf,minf])
[true, true, true, false, false, false]
map(nonnegintegerp,[minf,-3,0,3,inf])
[false, false, true, true, false]
map(floatp,[0,1,-3,1.0,%e,inf,minf])
[floatp(0), floatp(1), floatp(- 3), floatp(1.0), floatp(%e), floatp(inf),
floatp(minf)]
map(primep,[0,1,2,3,4,5])
[false, false, true, true, false, true]
map(ratnump,[1,1/3,4.5,5])
[true, true, false, true]
map(evenp,[1,2,4,5])
[false, true, true, false]
map(oddp,[1,2,4,5])
[true, false, false, true]
zeroequiv(sin(2*x)-2*sin(x)*cos(x),x)
true
zeroequiv(%e^x+x,x)
false
zeroequiv(log(a*b)-log(a)-log(b),a)
dontknow
/var/www/html/LANG/tmp_lang/chunk-79.mx
● algebraicp(exp) 有理関数との比較で相対的に代数学的と見なせるとき
true を返す
● constantp(exp) 定数を判定
● equationp(exp) 方程式を判定
● freeof(x_1,…,x_k,exp) 独立性を判定
● scalarp(exp) スカラーを判定
● nonscalarp(exp) 非スカラーを判定
● simple_vectr_p(exp) 単純なベクトルを判定
● matrixp(exp) 行列を判定
● square_matrixp(exp) 正方行列を判定
● operatorp(exp,one_or_more_ops) スカラーを判定
● taylorp(exp) Taylor級数を判定
● equalp(exp) 数学的等号を判定
/home/inoue/bin/go tmp_lang/chunk-80.mx > tmp_lang/chunk-80.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-80.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-80.mx
map(constantp,[1,2,sqrt(2),%e])
[true, true, true, true]
freeof(x,y,x+y^2)
false
freeof(s,t,x+y^2)
true
map(scalarp,[1,2,sqrt(2),%e,a[1],[e1,e2]])
[true, true, true, true, false, false]
map(nonscalarp,[1,2,sqrt(2),%e,a[1],[e1,e2]])
[false, false, false, false, false, true]
map(matrixp,[matrix([a11,a12],[a21,a22]),a11])
[true, false]
operatorp(c*x+b*y,"+")
true
operatorp(c*x+b*y,"*")
false
operatorp(c*x+b*y,["+","*"])
true
out:taylor(sin(x),x,0,5)
3 5
x x
/T/ x - -- + --- + . . .
6 120
taylorp(out)
true
/var/www/html/LANG/tmp_lang/chunk-80.mx
● stringp(exp) 文字列を判定
● substringp(substring,string) 部分文字列を判定
/home/inoue/bin/go tmp_lang/chunk-81.mx > tmp_lang/chunk-81.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-81.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-81.mx
str:"substring"
stringp(str)
true
substring(str,4)
string
substring(str,4,6)
st
/var/www/html/LANG/tmp_lang/chunk-81.mx
● string_equal(string_1,string_2) 文字列一致を判定
/home/inoue/bin/go tmp_lang/chunk-82.mx > tmp_lang/chunk-82.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-82.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-82.mx
exp:c1*f(x,y,z)+c2*g(x,y)
str:string(exp)
c1*f(x,y,z)+c2*g(x,y)
ssearch("f(",str)
4
integerp(ssearch("f(",str))
true
on2ftrue(funcs)::=buildq([u:funcs],integerp(ssearch("on2(",string(u))))
on2ftrue(c1*on2(x,x,1,3,co)+c2*on2(x,3,7,co))
true
on2ftrue(exp)
false
/var/www/html/LANG/tmp_lang/chunk-82.mx
● atom(exp) アトム(シンボル,文字列,数字)を判定
● array(exp) 配列を判定
● subvarp(exp) 添字つき変数を判定
● listp(exp) リストを判定
● ratp(exp) CREフォームを判定
● symbolp(exp) シンボル(アトムであって数ではない)を判定
/home/inoue/bin/go tmp_lang/chunk-83.mx > tmp_lang/chunk-83.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-83.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-83.mx
atom(x)
true
map(atom,[x,sin(x),3])
[true, false, true]
map(listp,[[e1,e2,e3],e1])
[true, false]
map(symbolp,[3,x])
[false, true]
/var/www/html/LANG/tmp_lang/chunk-83.mx
item{代入 a <- b <- c <- 3 item{関数 ev(x, infeval) は結果が変化しなくなるまで引数 x を評価する. item{関数 ev(a, b=x) は一時的環境 b=x の下で a を評価する.
評価はシンボリック言語と数値処理言語を区別する基本的なプロセスである. 評価の時点,順序,連鎖、等に留意すること.
◆ 実行例1. シンボルへの代入と評価の連鎖
/home/inoue/bin/go tmp_lang/chunk-84.mx > tmp_lang/chunk-84.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-84.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-84.mx
a:b
b:c
c:3
"/* 注1: 上より,a <- b <- c <-3 の代入がなされている */"
a
b
b
c
c
3
ev(a)
c
"/* 注2:上は a <- b <- c まで評価される */"
ev(ev(a))
3
"/* 注3:上は a <- b <- c <- 3 まで評価される */"
ev(a,b = x)
x
"/* 注4:上は 一時的環境 b <- x の下で x が評価される */"
b
c
ev(a,infeval)
3
"/* 注5:上は,a の評価を,その結果が変化しなくなるまで評価する */"
/var/www/html/LANG/tmp_lang/chunk-84.mx
コマンドラインから投入された「式」(数,変数,関数呼び出し,演算子から構成される表現) の受ける処理
1.構文解析 -> Lisp翻訳 -> 入力ラインへ表示
2.式の評価,簡約化 (評価,簡約化を総じて評価と呼ぶ)
(1) 名前の評価:代入値があれば代入値を返し,なければ名前を返す
(2) 関数の評価:関数の引数を評価し,次に関数値を評価する.
名詞型関数では関数定義式を返す.(再考)
◆ 実行例2.関数の型(動詞型関数と名詞型関数)
/home/inoue/bin/go tmp_lang/chunk-85.mx > tmp_lang/chunk-85.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-85.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-85.mx
exp:diff(x*f(x),x)
f(x):=sin(x)
ev(exp,diff)
sin(x) + x cos(x)
"/* 注1: 下は,式 exp を名詞型で返す */"
ev(exp,noun)
d
x (-- (sin(x))) + sin(x)
dx
"/* 注2: 下は,式 exp を動詞型で返す */"
ev(exp,nouns)
sin(x) + x cos(x)
/var/www/html/LANG/tmp_lang/chunk-85.mx
◆ 実行例3.関数の型(動詞型関数と名詞型関数)
/home/inoue/bin/go tmp_lang/chunk-86.mx > tmp_lang/chunk-86.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-86.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-86.mx
x
x
x:3
3
"/* 注1:下は x を名詞型で返す */"
'x
x
f(x):=x^2
2
f(x) := x
"/* 注2:下は 'f(2) の結果 */"
'f(2)
f(2)
"/* 注3:下は ev('f(2),f) の結果 */"
ev('f(2),f)
4
"/* 注4:下は '(f(2)) の結果 */"
'(f(2))
f(2)
"/* 注5:下は ''(f(2)) の結果 */"
4
4
/var/www/html/LANG/tmp_lang/chunk-86.mx
◆ 実行例4.関数の型(動詞型関数と名詞型関数)
/home/inoue/bin/go tmp_lang/chunk-87.mx > tmp_lang/chunk-87.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-87.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-87.mx
display2d:false
declare(integrate,noun)
"/* 注:上で,関数 integrate() を名詞型関数として宣言した */"
integrate(y^2,y)
integrate(y^2,y)
''integrate(y^2,y)
y^3/3
"/var/www/html/LANG/tmp_lang/chunk-87.mx"
◆ 実行例5.define の利用
/home/inoue/bin/go tmp_lang/chunk-88.mx > tmp_lang/chunk-88.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-88.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-88.mx
"/* 注1:ブロック内の関数定義に := を用いた場合 */"
g(i):=block(f(y):='diff(y*log(y),y,i),ldisplay(f(y)),return(f(y)))
g(1)
d
(%t4) f(y) = -- (y log(y))
dy
d
-- (y log(y))
dy
g(2)
2
d
(%t5) f(y) = --- (y log(y))
2
dy
2
d
--- (y log(y))
2
dy
"/* 注1:ブロック内の関数定義に define() を用いた場合 */"
h(i):=block(define(f(y),diff(y*log(y),y,i)),ldisplay(f(y)),return(f(y)))
h(1)
(%t8) f(y) = log(y) + 1
log(y) + 1
h(2)
1
(%t9) f(y) = -
y
1
-
y
/var/www/html/LANG/tmp_lang/chunk-88.mx
● ev(exp,arg_1,…,arg_k) スペシャルフォーム
関数 ev は,Maxima にとって最も強力で多機能な関数のひと
つである.この関数は,exp を引数 arg_1,…,arg_k によって
指定される環境の下で評価を行う.評価は以下の手順で行われる.
スペシャルフォーム ev は以下の任意のアイテムを引数として受け付ける.
関数 ev の arg_i は通常,任意の順序で指定できるが,それらは左から右にピックアップされ るので,その順序が結果に影響する場合がある.このことは,左から右へ順に操作する代数方程 式や, evfun に当てはまる.例えば, ev(exp,ratsimp,rectform) は recform(ratsimp(exp)) の順で扱われる.環境変数 simp, numer, float, pred, infeval は block においてローカルに 設定できるものの,それらがリセットされるまで長く使用できるようグローバルにも設定できる. ローカルに infeval:true を設定すると, ev への明示的呼び出しによって発生するすべての評 価は無限に実行される. exp が CRE フォームである場合, ev は結果を CRE フォームで返す.た だし,その場合, numer と float 環境変数はどちらも false でなければならない. 以下に, ev が認識するキーワードとキーワードフォームを示す.
● noeval (ev 用キーワード)
手順 (4) における, ev
の評価局面を禁止する.これは,他のオプション変数と競合しないよう
にする場合や, exp
を再度簡約化する際に評価を繰り返したくない場合に役立つ.
● eval (ev 用キーワード)
手順(5)における exp の追加的な事後評価を行う.
● infeval (ev 用キーワード)
無限評価モードを発生させる.これにより,ev
は式がそれ以上変化しなくなるまで反復して式の評価を行う. ある変数(例えば
x)をこのモードでの評価から外したい場合は,x=’x を ev
の引数として含めるだけで良い. もちろん,ev(x, x=x+1, infeval);
のような式は無限ループする.
● pred (ev 用キーワード)
このキーワードは,述語(評価結果がtrueまたはfalseとなる式)の評価を行わせる.
● nouns (ev 用キーワード)
このキーワードは exp に出てくるすべての名詞を動詞に変換する.
● expand(m,n) (ev 用キーワード)
このキーワードは,maxposex, maxnegex の値をそれぞれ m, n
に設定した上で展開を行うようにする.
● derivlist(var_1,…,var_k) (ev 用キーワード)
指定された変数に付いてのみ微分が実行されるようにする.
● var:expression (ev 用キーワード)
コマンド exp:expression または var=expression を実行すると,exp
の評価の間,expression の値を var に一時的に結びつけるようになる.
● var=expression (ev 用キーワード)
同上
● f(args) := body (ev 用キーワード)
f(args) := body を ev の引数として指定することによって, exp
に出てくる関数(例えば,f(args)
を評価の便宜からローカルに定義できる.
◆ 実行例:ev()の使用例
/home/inoue/bin/go tmp_lang/chunk-89.mx > tmp_lang/chunk-89.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-89.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-89.mx
exp:sin(x)+cos(y)+(w+1)^2+'diff(sin(w),w)
d 2
cos(y) + sin(x) + -- (sin(w)) + (w + 1)
dw
ev(exp,diff,x = a,y = 1)
2
cos(w) + (w + 1) + sin(a) + cos(1)
/var/www/html/LANG/tmp_lang/chunk-89.mx
◆ 実行例:ev()の使用例(programmode: false$)
/home/inoue/bin/go tmp_lang/chunk-90.mx > tmp_lang/chunk-90.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-90.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-90.mx
display2d:false
programmode:false
"/* 注1: x+y, x: a+y, y: 2; が以下のように評価される */"
ev(x+y,x:a+y,y:2)
y+a+2
"/* 注1:上の評価では x + y <- (a+y)+2 = y+a+2 が返されている */"
eq1:2*x-3*y = 3
eq2:(-3)*x+2*y = -4
solve([eq1,eq2])
Solution:
y = -1/5
x = 6/5
[[%t9,%t10]]
"/* 注2:以下では,不等式の評価を行う */"
exp1:x+1/x > gamma(1/2)
x+1/x > sqrt(%pi)
"/* 注3:下は,exp2: exp1, numer, x=1/2; の結果 */"
ev(exp2:exp1,numer,x = 1/2)
2.5 > 1.772453850905516
"/* 注4:下は,exp2: pred; の結果 */"
ev(exp2,pred)
true
"/var/www/html/LANG/tmp_lang/chunk-90.mx"
◆ 実行例:ev()の使用例
/home/inoue/bin/go tmp_lang/chunk-91.mx > tmp_lang/chunk-91.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-91.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-91.mx
batchload("/home/inoue/.maxima/max-init.mac")
file_search1: /home/inoue/.maxima/max-init.mac not found in file_search_maxima.
-- an error. To debug this try: debugmode(true);
/var/www/html/LANG/tmp_lang/chunk-91.mx
● eval(exp)
関数 eval によって,exp についての追加的な事後評価を発生させる.
● ev(exp, infeval)
関数 infeval は exp を無限評価モードで評価させる.
● eval_string(string)
これは,文字列のシンボリックな構成要素の部分を評価する.例えば, b:2$
に続けて,eval_string(“abc”); とすると,結果は 2ac
となる.
/home/inoue/bin/go tmp_lang/chunk-92.mx > tmp_lang/chunk-92.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-92.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-92.mx
b:2
2
eval_string("a*b*c")
2 a c
/var/www/html/LANG/tmp_lang/chunk-92.mx
関数の定義と利用について考察する.
関数の定義方法
* 定義 1 : f(x) := body body の評価は関数の適用時に行う. * 定義 2 :
define(f(x), body) body の評価は define の評価時に行う.
関数の評価の流れ ( 引数の評価,関数値の評価 )
関数とマクロ
*
マクロでは適用時に引数の評価を行わないで結果をフォームで返し,その評価はインタプリターに任せる.
◆ 実行例1. 関数が関数を呼び出す例.
/home/inoue/bin/go tmp_lang/chunk-93.mx > tmp_lang/chunk-93.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-93.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-93.mx
"/* 注1:関数 f(x) を定義する */"
f(x):=x^2+y
f(2)
y + 4
y:7
f(2)
11
"/* 注2:関数 g(y,z) を事前定義関数 f(z) を用いて定義する */"
g(y,z):=f(z)+3*y
"/* 注3:関数 g(2*y+z, -0.5) の評価順序を下にまとめる */"
g(2*y+z,-0.5)
3 (z + 14) + z + 14.25
kill(f)
done
f(x)
f(x)
/var/www/html/LANG/tmp_lang/chunk-93.mx
関数 g の評価順序を示す.
◆ 実行例2.不定個の引数をもつ関数の作成
/home/inoue/bin/go tmp_lang/chunk-94.mx > tmp_lang/chunk-94.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-94.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-94.mx
av([L]):=apply("+",L)/length(L)
av(1,2,3,4,5)
3
/var/www/html/LANG/tmp_lang/chunk-94.mx
また,実行例2の応用例としては以下の例が挙げられる.
◆ 実行例2a.不定個の引数をもつ関数の作成
/home/inoue/bin/go tmp_lang/chunk-95.mx > tmp_lang/chunk-95.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-95.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-95.mx
linel:75
exargs(x,y,[args]):=block([ans,debugmode:false],
for i thru length(args) do if args[i] = debug then debugmode:true,
ans:x+y,if debugmode = true then ldisplay(ans),return(ans))
exargs(a,b)
b + a
exargs(a,b,debug)
(%t5) ans = b + a
b + a
/var/www/html/LANG/tmp_lang/chunk-95.mx
◆ 実行例3.Lambda Noation
名前の付かない関数を定義する.
/home/inoue/bin/go tmp_lang/chunk-96.mx > tmp_lang/chunk-96.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-96.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-96.mx
f:lambda([x,y,z],x^2+y^2+z^2)
2 2 2
lambda([x, y, z], x + y + z )
f(1,2,a)
2
a + 5
lambda([x],x+1)(3)
4
1+2+a
a + 3
/var/www/html/LANG/tmp_lang/chunk-96.mx
◆ 実行例4.関数配列 fk の作成と利用例
fk の評価は f[k] を評価した後に fk
を評価する点に留意する.
/home/inoue/bin/go tmp_lang/chunk-97.mx > tmp_lang/chunk-97.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-97.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-97.mx
display2d:false
f[k](x):=x^k+1
f[1](3)
4
g[2](3)
g[2](3)
g[k](exp):=coeff(exp,x,k)
g[2](x^2+1)
0
h(k,exp):=coeff(exp,x,k)
h(2,x^2+1)
1
"/var/www/html/LANG/tmp_lang/chunk-97.mx"
gk では先に g[k] が評価され coeff(exp,x,k) -> 0 (exp は未評価)となる.
◆ 実行例5.関数配列の利用例
/home/inoue/bin/go tmp_lang/chunk-98.mx > tmp_lang/chunk-98.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-98.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-98.mx
display2d:false
g[n](x):=sum(ev(x),i,n,n+2)
h(n,x):=sum(ev(x),i,n,n+2)
g[2](i^2)
3*i^2
h(2,i^2)
29
p[n](x):=diff((x^2-1)^n,x,n)
q(n,x):=diff((x^2-1)^n,x,n)
p[2]
lambda([x],8*x^2+4*(x^2-1))
p[2](3)
104
q(2,x)
8*x^2+4*(x^2-1)
q(2,3)
diff: second argument must be a variable; found 3
#0: q(n=2,x=3)
-- an error. To debug this try: debugmode(true);
"/var/www/html/LANG/tmp_lang/chunk-98.mx"
g2 対 h(2,i^2) では h(2,i^2) が有効. p2 対 q(2,3) では p2 が有効であることに留意せよ.
◆ 実行例6.引数を評価しない関数
関数定義の引数をシングルクォート前置することで,引数未評価で関数を評価
することができる.
/home/inoue/bin/go tmp_lang/chunk-99.mx > tmp_lang/chunk-99.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-99.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-99.mx
a:2
2
f('x):=print(x,"has value",ev(x))
f(a)
a has value 2
2
g('x,y):=x+y
g('x, y) := x + y
g(a,a)
a + 2
h('x):=block([simp:false],print(ev(x)))
h(a+a)
2 + 2
4
/var/www/html/LANG/tmp_lang/chunk-99.mx
◆ 実行例7.関数の引数としての利用
/home/inoue/bin/go tmp_lang/chunk-100.mx > tmp_lang/chunk-100.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-100.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-100.mx
display2d:false
f(x):=x::2
f('a)
2
a
2
g[i,j](x,y):=x^i+y^j
h(fun,arg1,arg2):=print(fun,"applied to",arg1,"and",arg2,"is",fun(arg1,arg2))
h(g[2,1],cos(%pi),2*c)
lambda([x,y],y+x^2) applied to -1 and 2*c is 2*c+1
2*c+1
"/var/www/html/LANG/tmp_lang/chunk-100.mx"
◆ 実行例8.apply を用いた関数利用
/home/inoue/bin/go tmp_lang/chunk-101.mx > tmp_lang/chunk-101.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-101.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-101.mx
L:[1,2,3,4,5]
max(L)
max([1, 2, 3, 4, 5])
apply('max,L)
5
av([L]):=apply("+",L)/length(L)
av(1,2,3,4,5)
3
/var/www/html/LANG/tmp_lang/chunk-101.mx
◆ 実行例9.関数を評価せず,定義式を返す関数(funmake)
/home/inoue/bin/go tmp_lang/chunk-102.mx > tmp_lang/chunk-102.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-102.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-102.mx
f(x,y):=x+y
f(a+1,b+1)
b + a + 2
ex:funmake(f,[a+1,b+1])
f(a + 1, b + 1)
ev(ex)
b + a + 2
/var/www/html/LANG/tmp_lang/chunk-102.mx
構文 funmake(function,[arg1,…,argk])
◆ 実行例10.関数についての引数の写像(map)
/home/inoue/bin/go tmp_lang/chunk-103.mx > tmp_lang/chunk-103.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-103.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-103.mx
map(f,x+a*y+b*z)
f(b z) + f(a y) + f(x)
map(lambda([u],partfrac(u,x)),x+1/(x^3+4*x^2+5*x+2))
1 1 1
----- - ----- + -------- + x
x + 2 x + 1 2
(x + 1)
map(ratsimp,x/(x^2+x)+(y^2+y)/y)
1
y + ----- + 1
x + 1
map("=",[a,b],[-0.5,3])
[a = - 0.5, b = 3]
ex1:a+b*c
map(f,ex1)
f(b c) + f(a)
fullmap(f,ex1)
f(b) f(c) + f(a)
exp:(a^2+2*a+1)*x+y^2
2 2
y + (a + 2 a + 1) x
scanmap(factor,exp)
2 2
y + (a + 1) x
scanmap(factor,expand(exp))
2 2
y + a x + 2 a x + x
scanmap(f,a*x+b)
f(f(f(a) f(x)) + f(b))
scanmap(f,a*x+b,bottomup)
f(f(f(a) f(x)) + f(b))
/var/www/html/LANG/tmp_lang/chunk-103.mx
メモ: scanmap(f, expr) <- expr に関数 f を上から再帰的に適応する
scanmap(f, expr, bottomp) <- expr に関数 f を下から再帰的に適応する
mode_declare([function(f1,f2,...),x],fixnum, completearray(q), float);
この章では,Maxima に用意されているいくつかのプログラミング構造について説明する.
条件文は,「if (条件) then (式1) else (式2)」 で記述される.条件の記述は以下の関係付け演算子や論理演算子で表される.
● exp_1 > exp_2 より大きい
● exp_1 < exp_2 より小さい
● exp_1 >= exp_2 より以上
● exp_1 <= exp_2 より以下
● exp_1 # exp_2 等しくない
● exp_1 = exp_2 等しい(構文的に),数学的な等号はequal(exp_1,exp_2)
を用いる.
● exp_1 or exp_2 論理和
● exp_1 and exp_2 論理積
● not exp 否定
関係付け演算子は算術演算子より計算優先度が低く,また論理演算子より高い演算子である. ただし,関係付け演算子どうしは同じである.また,論理演算子 and の優先度は not より高く,or より低い.
★ 実行例 関係付け演算子や論理演算子, 条件文
is(3 > 2);
is(3 < 2);
is(3 >= 2);
is(3 <= 3);
is(2 # 3);
is(2 =3);
is((2 < 3) or (2 > 3));
is((2 < 3) and (2 > 3));
is(2 < 3); not is(2 < 3);
"/* if 文 */"$
(x : 5, y : 6);
if x = y then (x : x+1, y : y -1)
else (x : x-1, y : y+1);
x;
y;
/home/inoue/bin/go tmp_lang/chunk-104.mx > tmp_lang/chunk-104.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-104.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-104.mx
is(3 > 2)
true
is(3 < 2)
false
is(3 >= 2)
true
is(3 <= 3)
true
is(2 # 3)
true
is(2 = 3)
false
is(2 < 3 or 2 > 3)
true
is(2 < 3 and 2 > 3)
false
is(2 < 3)
true
not is(2 < 3)
false
"/* if 文 */"
(x:5,y:6)
6
if x = y then (x:x+1,y:y-1) else (x:x-1,y:y+1)
7
x
4
y
7
/var/www/html/LANG/tmp_lang/chunk-104.mx
1つのステートメントしか使用できないコンテクストにおいて,一連の文をまとめて実行するには,文ごとに カンマで区切り,全体を括弧で囲むことにより行う.複合文の結果は複合文の最後の文の結果を返す.
★ 実行例 複合文, 条件文
/home/inoue/bin/go tmp_lang/chunk-105.mx > tmp_lang/chunk-105.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-105.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-105.mx
(a:3,b:4,a+b)
7
(x:5,y:6)
6
if x = y then (x:x+1,y:y-1) else (x:x-1,y:y+1)
7
/var/www/html/LANG/tmp_lang/chunk-105.mx
多数の文をグループ化し,1つの文にするものに block がある.ブロックは return, go の参照ポイントにも なる.
● block([var_1,…,var_k],statement_1,…,statement_k)
var_i はアトミックなローカル変数で,var_i:initial_value
と指定することでブロック内でのローカルな
初期値を与えることができる.ローカル変数の使用により,ブロック外の同名の変数(グローバル変数)との競合を
回避できる.また,ローカル変数の記憶メモリはブロックの外に制御が移った時点で自動的に強制開放される.
ブロックのローカル変数のリストに指定されていない変数がブロック内で使われた場合には,その変数は
グローバルな変数として扱われる.従って,ブロック内でもグローバルな変数値を使うことができる.
★ 実行例 ブロック
/home/inoue/bin/go tmp_lang/chunk-106.mx > tmp_lang/chunk-106.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-106.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-106.mx
x:a
a
block([x:b,y:x+1],x*y)
(a + 1) b
x
a
/var/www/html/LANG/tmp_lang/chunk-106.mx
ローカル変数として添字つき変数を利用する際はブロック内で local(array_var) を宣言することが必要である.
★ 実行例 ローカル変数として添字つき変数を利用
/home/inoue/bin/go tmp_lang/chunk-107.mx > tmp_lang/chunk-107.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-107.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-107.mx
display2d:false
f(x):=block([y:4],local(a),a[y]:x,display(a[y]))
y:2
2
a[y+2]
a[4]
f(9)
a[4] = 9
done
a[y+2]
a[4]
"/var/www/html/LANG/tmp_lang/chunk-107.mx"
block の値は,ブロック内の最後の文の値,または,明示的にブロックから抜けるために使われた return 関数の引数値である.
● go(tag) スペシャルフォーム block([x:1], loop,x:x+1,…, go(loop),…);
● return(exp)
この関数は,block または do
の本体の内部で用い,そこから抜け出るのに用いる.この関数を用いると,
block または do の非標準的なポイントから抜け出ることができる.(block
内で使用される do の中での
return の使用は do から抜け出るのであって,block
から抜け出るのではない.同じ操作は go では行う ことができない.)
return(exp) が実行されたとき,それを含んでいる do または block
によって返される 値は,exp が複合文のときも,その 1
番最初の評価結果である.exp を省略した場合にはデフォルトでfalse
を返す.
★ 実行例 return & go (意図していない結果?)
/home/inoue/bin/go tmp_lang/chunk-108.mx > tmp_lang/chunk-108.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-108.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-108.mx
alleven(L):=block(top,ldisplay(L),if L = [] then return(true),
if oddp(first[L]) then return(false),L:rest(L),go(top))
alleven([2,6,8])
(%t3) L = [2, 6, 8]
(%t4) L = [6, 8]
(%t5) L = [8]
(%t6) L = []
true
alleven([2,6,7])
(%t7) L = [2, 6, 7]
(%t8) L = [6, 7]
(%t9) L = [7]
(%t10) L = []
true
/var/www/html/LANG/tmp_lang/chunk-108.mx
● catch(exp_1,…,exp_k)
● throw(exp)
★ 実行例 catch & throw
/home/inoue/bin/go tmp_lang/chunk-109.mx > tmp_lang/chunk-109.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-109.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-109.mx
g(L):=catch(map(lambda([x],if x < 0 then throw(x) else f(x)),L))
g([1,2,3,7])
[f(1), f(2), f(3), f(7)]
g([1,2,-3,7])
- 3
/var/www/html/LANG/tmp_lang/chunk-109.mx
● for (変数:初期値) step (増分) thru (制限) do (命令)
● for (変数:初期値) step (増分) while (条件) do (命令)
● for (変数:初期値) step (増分) unless (条件) do (命令)
● for (変数:初期値) next (増分記述) thru (制限) do (命令)
● for (変数:初期値) next (増分記述) while (制限) do (命令)
● for (変数:初期値) next (増分記述) unless (制限) do (命令)
「(変数:初期値)」の部分は「変数 from 初期値」とも記述できる.
● for (変数) in (リスト) do (命令)
◆ 実行例
/home/inoue/bin/go tmp_lang/chunk-110.mx > tmp_lang/chunk-110.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-110.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-110.mx
for i from 0 thru 4 do ldisplay(sin((%pi*i)/4))
(%t2) sin(0) = 0
%pi 1
(%t3) sin(---) = -------
4 sqrt(2)
%pi
(%t4) sin(---) = 1
2
3 %pi 1
(%t5) sin(-----) = -------
4 sqrt(2)
(%t6) sin(%pi) = 0
/var/www/html/LANG/tmp_lang/chunk-110.mx
◆ 実行例
/home/inoue/bin/go tmp_lang/chunk-111.mx > tmp_lang/chunk-111.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-111.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-111.mx
for ex in [sin(x),cos(x),tan(x)] do ldisplay(diff(ex,x))
(%t2) diff(sin(x), x) = cos(x)
(%t3) diff(cos(x), x) = - sin(x)
2
(%t4) diff(tan(x), x) = sec (x)
/var/www/html/LANG/tmp_lang/chunk-111.mx
Maxima で記述された関数やパッケージを Lisp にトランスレー トし,その Lisp プログラムをコンパイルすると,実行速度が速いコー ドになる.Maxima プログラムをトランスレート,コンパイルする前に, 高速化およびメモリ管理上の改善のためにデータタイプに関する宣言を行う必 要がある.以下の2つのスペシャルフォーム(関数のようなもの)がこれを行う.
● mode_declare(’y_1, ’mode_1,…, ’y_k, ’mode_k) スペシャルフォーム
関数のトランスレート,コンパイルに先立ち実行する. 関数(名)およびその変数(名)のモードの宣言を行う. スペシャルフォームであるため引数の評価は行われない.モードに指定できるものは, boolean, fixnum, float, list, number, rational, any である. y_i には変数のリストも指定できる.mode_declare は関数定義の内部でも,グローバル変数として トップレベルでも使用できる.
次の宣言
mode_declare([function(f1,f2,...), x], fixnum, completearray(q), float);
は,関数名 f1,f2,… と変数名 x (によって返される値)は単一文字の整数(fixnum)であり, q は浮動小数点数(float)の配列であることを宣言している. 環境変数 tr_warn_undclare:compile は宣言されていない変数について警告を発するのに用いる. 設定可能な値を以下に示す.
false 警告メッセージを抑止する.
compile compile について警告を出す.
translate translate:true ならば,translate について警告を出す.
all compile および translate について警告を出す.
ある変数を,float や fixnum に限定しない通常の Maxima 変数として宣言するには mode_declare(var, any); のようにする. コンパイルするコードの中で用いるすべての変数をモード宣言する手間はかけておいて損はない.
● mode_identity(arg_1, arg_2) スペシャルフォーム
第1引数 arg_1 には,mode_declare のモード名(すなわち,boolean, fixnum,
float, list, number, rational, any) を指定する. 第2引数 arg_2
には,この関数により評価され,その値として返される式を指定する.ただし,
第1引数で宣言されるモードが返り値を認めない場合は,エラーまたは警告が表示される.重要な点は,
Maxima-Lisp
トランスレータが調べる式のモードが第1引数として指定される点である.
第2引数はこれに影響を与えない.
◆ 実行例
/home/inoue/bin/go tmp_lang/chunk-112.mx > tmp_lang/chunk-112.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-112.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-112.mx
x:3.3
mode_identity(fixnum,x)
translator: x was declared with mode fixnum, but it has value: 3.3
3.3
mode_identity(flonum,x)
3.3
/var/www/html/LANG/tmp_lang/chunk-112.mx
◆ 実行例
/home/inoue/bin/go tmp_lang/chunk-113.mx > tmp_lang/chunk-113.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-113.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-113.mx
L:[3,a,b]
[3, a, b]
first(L)
3
mode_identity(number,first(L))
3
firstnumb(x)::=buildq([x],mode_identity(number,first(x)))
firstnumb(L)
3
/var/www/html/LANG/tmp_lang/chunk-113.mx
● optimize(exp)
exp
と同じ値となり,同じ副次的効果を持つ式でありながら,共通するサブ式の計算の繰り返しを
回避させた式を返す.
この関数は,その引数を壊すことにより,すべての共通するサブ式を共用するように変化させる
副次的効果がある.
◆ 実行例 optimize-1
/home/inoue/bin/go tmp_lang/chunk-114.mx > tmp_lang/chunk-114.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-114.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-114.mx
ex1:(a-b)/(a+b)+1/(a+b)
optimize(ex1)
1
block([%1], %1 : -----, (a - b) %1 + %1)
b + a
/var/www/html/LANG/tmp_lang/chunk-114.mx
◆ 実行例 optimize-2
/home/inoue/bin/go tmp_lang/chunk-115.mx > tmp_lang/chunk-115.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-115.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-115.mx
ex2:diff(exp(y+x^2)/(y+x),x,1)
optimize(ex2)
2
y + x 2 x %2 %2
block([%1, %2], %1 : y + x, %2 : %e , ------ - ---)
%1 2
%1
/var/www/html/LANG/tmp_lang/chunk-115.mx
◆ 実行例 optimize-3
/home/inoue/bin/go tmp_lang/chunk-116.mx > tmp_lang/chunk-116.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-116.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-116.mx
ex3:integrate((x+y)*f(x+y),x)
optimize(ex3)
/
[
block([%1], %1 : y + x, I %1 f(%1) dx)
]
/
/var/www/html/LANG/tmp_lang/chunk-116.mx
● optimprefix:% (環境変数)
optimize により生成されるシンボルに使用されるプレフィックスを設定する.
トランスレートとは,1つの言語で記述された式を意味を変えずに別の言語に変換することを指す. Maxima インタープリタは,Maximaコードを何のトランスレートもせずに直接処理する. Maxima の式については, Lisp にトランスレートされ,Maximaインタープリタではなく Lisp インタープリタにより処理されるものもある. これにより実効速度が改善する.これをコンパイルすると,トランスレータが内部的に起動する.
● translate_file(file,[output_file])
ファイル名 file 内の Maxima コード(バッチファイル)を Lisp
コードにトランスレートする. 引数 output_file はトランスレート後の Lisp
コードの保存先ファイル名を指定する. 無指定の場合は,file.lisp となる.
この拡張子は,環境変数 translate_file_default:lisp
で設定できる.例えば, translate_file(“test.mx”); は,入力ファイル
“test.mx” を トランスレートし,結果を出力ファイル “test.LISP”
に保存する. このとき,様々なトランスレータ警告メッセージをファイル
“test.UNLISP”
に出力する.具体的な実行手順を後述の「コンパイル」の節で示す.
なお,入力ファイルには,関数定義に加えて declare, mode_declare,
matchdeclare が関係する宣言文を含めることが出来る.
● translate(f_1,…,f_k)
ユーザ定義関数 f_1,…,f_k を Maxima 言語から Lisp へトランスレートする.効率的なコード生成のためには,出来れば引数の先頭 に mode_declare の呼び出しを含める必要がある.次の例を参照.
f(x1,x2,...) := block([v1,v2,...],
mode_declare(v1,mode1, v2,mode2,...),
...
)$
この例において, x1,x2,… はこの関数のパラメータであり, v1,v2,… はローカル変数である, トランスレートされた関数の名前は prop リストに追加される.テストし,実行結果が満足出来るも であることが確認できるまで,関数をトランスレートしてはいけない. translate(functions); または translate(all); はいずれも,すべてのユーザ定義関数をトランスレートする.
● translate:false (環境変数)
trueである場合,関数を Lisp へ自動的にトランスレートする.
● trancompile:true (環境変数)
trueである場合,translate
がコンパイルに必要な宣言を生成するようになる.関数 compile は
transcompile:true; を使用する.
● savedef:true (環境変数)
trueである場合,トランスレートされた後も,Lispバージョンではなく,Maxima
バージョンのユーザ定義関数が
保存される.また,トランスレートされた定義が dispfun
により表示できる.このオプション変数が false の
場合は,ユーザ定義関数の名前は,functions リストから削除される.
● transrun:true (環境変数)
falseである場合,トランスレートされた Lisp
バージョンでなく,インタプリートされた Maxima
バージョンが用いられる.(もし,それが存在するならば)
● compfile([filename],f_1,…,f_k)
Maxima関数f_1,…,f_kをトランスレートした Lisp コードを引数 filename
で指定したファイルに書き出す.
● eval_when(keywords,form_1,…,form_k) (スペシャルフォームxx)
これは,パッケージライタにとって非常に有用であるトップレベルのスペシャルフォームである.
引数 keywords には,batch, loadfile, translate
からなる1個のキーワードまたはそのリストである.
● tr_array_as_ref:true (環境変数)
trueである場合,ランタイムコードが変数の値を配列として使う.
● tr_bound_function_applyp:true (環境変数)
付値された変数が関数として用いられたとき警告を出す.
● tr_file_tty_messagesp:false (環境変数)
translate_file
コマンドの実行時に生成されるメッセージをターミナルにも表示するかを指定する.
● tr_float_can_branch_complex:true (環境変数)
弧関数が複素数の結果を返すかどうかを指定する.
● tr_function_call_default:general (環境変数)
この変数には,false, exp, general のいずれかを指定できる.false
はギブアップして meavl を
呼び出す(すなわち,トランスレートにおける問題の発生を意味する).exp は
Lisp の固定長引数を取る関数を 想定することを意味する.general
は,関数としては正しく,マクロとしては正しくないコードであることを
承認する.general
の場合は,コンパイルされたコードにおいて変数への付値が正しいかを検証する.
このモードでは,f が付値された変数であるとき,f(x)
をトランスレートすると,それは, apply(f,[x])
と解釈し,警告は出すものの,そのようなものとしてトランスレートされる.
● tr_numer:false (環境変数)
trueである場合,%e, %pi, %phi, %gamma を含むアトムのプロバティとして
numer プロバティが使用される.
● tr_optimize_max_loop:100 (環境変数)
マクロ展開と最適化の過程で,トランスレータがフォームを考慮する際にたどるループの回数の上限を指定する.
マクロ展開および終了しない最適化プロバティをキャッチするためのものである.
● tr_output_file_default:trlisp (環境変数)
トランスレートされたLispコードの出力ファイルのファイル拡張子を指定する.
● tr_semicompile:false (環境変数)
trueである場合,関数 translate_file, compfile
が,マクロ展開されているものの, Lisp
コンパイラによる機械コードへのコンパイルは受け付けていないフォームを返す.
これにより,すべてのマクロが展開されたオブジェクトファイルが生成でき,トランスレートされたコードをインタープリートしながら実行できる.
● tr_true_name_of_file_being_translated:false (環境変数)
translate_file
により前回トランスレートされたファイルの正式名をクォート付き文字列フォームにしたものが付値される.
● tr_version:false (環境変数xx)
トランスレータのバージョン.
● tr_warn_bad_function_calls:true (環境変数)
トランスレート時に作成された不適切な宣言に起因する不正な関数呼び出しが行われたときに警告を出す.
● tr_warn_fexpr:compfile (環境変数)
識別できないスペシャルフォームが検出されたとき警告を出す.そうしたスペシャルフォームは,
通常トランスレートされたコードには出力されない.すべての識別できるスペシャルフォームのみが
トランスレートされる.
● tr_warn_meval:compfile (環境変数)
関数 meval が呼び出しを受けると警告を出す.meval
呼び出しはトランスレートにおける問題の発生を 意味する.
● tr_warn_mode:all (環境変数)
変数にそのモードとして不適切な値が付値されている場合に警告を出す.
● tr_warn_undeclared:compile (環境変数)
宣言されていない変数に関する警告をターミナルに送信するタイミングを指定する.
● tr_warn_undefined_variable:all (環境変数)
未定義のグローバル変数が検知された場合に警告を出す.この環境変数に指定できる設定は,
all, compile, compfile, translate, false
であり,それぞれ警告を出すタイミングを 指定する.false
はこの機能を無効にする.
● tr_warnings_get()
現在行っているトランスレートの際にトランスレートが出した警告のリストを返す.
● tr_windy:true (環境変数)
助けになるコメントとプログラミングをする上のヒント(verbose)を生成する.
● mode_chekp:true (環境変数)
trueである場合,mode_declare
は付値された変数のモードをチェックする.
● mode_check_wqrnp:true (環境変数)
trueである場合,モードエラーが記述される.
● mode_check_errorp:false (環境変数)
trueである場合,mode_decalre は error を呼び出す.
コンパイルは主に,高水準言語から低水準言語へのトランスレート(変換)を意味する.Maxima における 2ステップからコンパイルプロセスは,まずMaxima コードから Lisp コードにトランスレートし,次に, Lisp コードから機械コードにトランスレートする.
● compile(fc_1,…,fc_k) (スペシャルフォーム)
fcni をファイル名としてもつ関数をコンパイルし,Lisp ファイルを出力する.
スペシャルフォーム compile を呼び出すことにより,Maxima コードを
Lispコードに トランスレートし,次に,Lisp
コンパイラを実行しオブジェクトコードと呼ばれるコンパイル出力を Maxima
へロードする.
また,この過程のエラーに付いて検査を行い,結果をリスト出力ファイルに出力する.
これらの一連の作業は手作業でも可能であるが,compile
使用の場合は,便利なデフォルト機能を 利用することが出来る.特に,plot,
plot2, 数値積分 (numerical integration) は,compile
のこの利点を活用している.compile(all); または compile(functions);
とすると,すべてのユーザ定義関数がコンパイルされる.
本コマンドは,compile(“ex-translate.mx”); のように用い,load(“ex-translate.fas”); の ようにして用いる.
● compile_file(file,output_file)
file で指定される Maxima コードファイル(バッチファイル) または Lisp
コードファイルを オブジェクトコードにコンパイルし,output_file
に出力する.file に Maxima コードが 含まれている場合,まず
translate_file を用いて Lisp コードにトランスレートし,その後に Lisp
コードファイルをオブジェクトコードにコンパイルする.output_file
が省略された場合,Maxima はコンパイルしたオブジェクトファイルを
“file.fas” とする. 例えば,compile_file(“test.mx”); の場合,Lisp
ファイル “test.LISP” と オブジェクトファイル “test.fas” を生成する.
コンパイルを最大限有効に活用するには,関数タイプおよび変数の宣言を行う必要がある.この宣言により Maxima はマシンによる浮動小数点演算の必要性を判断する処理を短縮できる. 一般に,新しい変数を利用する場合,必ず mode_declare をその最初の「関数呼び出し」と記述する必要がある. 変数は,新しく使用開始したらすぐに mode_declare を行わねばならない.それより前でも後でもいけない. 以下の演算子は新しい字句の輪郭(lexical construct)を作成する.モード宣言の式は,関連する 一連の式の先頭もしくは Maxima のトップレベル使用する必要がある.sum などの特定の構造体では, 添字変数をユーザがモード宣言する必要はない.以下に,mode_declare によるモード宣言の宣言位置となる「輪郭」の開始点をまとめる.
:= すべての正規のパラメータおよび関数内で使用されるすべての独立変数について輪郭を使用開始する.
block すべての「ブロック」変数について輪郭を使用開始する.
do コントロール変数について輪郭を使用開始する.コントロール変数は,それを含んでいる輪郭内で
宣言する必要がある.以下の例を参照.
for x:x1 thru xn step dx do(mode_declare(x, float), sum:sum+f(x)*dx)
lambdalambda 変数について輪郭を使用開始する.
以下に 1) モード宣言のプログラム上の位置, 2) トランスレートの利用, 3) コンパイルの利用 を 実行例を示す.まず,以下の Maxima コードをファイル ex-translate.mx として作成する.
ff(x,y) := (mode_declare([x,y],float),
block([ans],
mode_declare(ans,float),
ans : x + y,
return(ans)
))$
fa(x,y) := (mode_declare([x,y],any),
block([ans],
mode_declare(ans,any),
ans : x + y,
return(ans)
))$
以下に 1)モード宣言のプログラム上の位置,2)トランスレートの利用,3)コンパイルの利用 を実行例を示す. まず,以下の Maxima コードをファイル ex-translate.mx として作成する.
(%i1) translate_file("ex-translate.mx");
Translation begun on ex-translate.mx.
(%o1) [ex-translate.mx, ex-translate.LISP, ex-translate.UNLISP]
(%i2) load("ex-translate.LISP");
(%o2) ex-translate.LISP
(%i3) ff(1.0,2.0);
(%o3) 3.0
(%i4) fa(1,2);
(%o4) 3
(%i5) fa(a,b);
(%o5) b + a
mode_declare によるモード宣言の位置が上述の輪郭開始位置であることを確認する.次に,上記 Maxima コードで記述された(2個の関数を含む)ファイルを,translate_file および compile_file コマンドを 用いてトランスレート,コンパイルする実行例を示す.
◆ 実行例:translate_file による
(%i1) compile_file("ex-translate.mx");
Translation begun on ex-translate.mx.
;; Compiling file /home/inoue/Max-ex/ex-translate.LISP ...
;; Wrote file /home/inoue/Max-ex/ex-translate.fas
0 errors, 0 warnings
(%o1) [ex-translate.mx, ex-translate.LISP, ex-translate.UNLISP,
/home/inoue/Max-ex/ex-translate.fas]
(%i2) load("ex-translate.fas");
(%o2) ex-translate.fas
(%i3) ff(1.0,2.0);
(%o3) 3.0
(%i4) fa(a,b);
(%o4) b + a
上記以外に ex-translate.lib が作られている.これを呼び出し実行できる.
(%i1) load("ex-translate.lib");
(%o1) ex-translate.lib
(%i2) fa(a,b);
(%o2) b + a
作成されたファイルとそのファイルサイズを示す.
ex-translate.LISP 1195
ex-translate.UNLISP 78
ex-translate.fas 4486 <--- compile
ex-translate.lib 2320 <--- compile
ex-translate.mx 446
<<ex-translate.LISP>>****************************************************
;;; -*- Mode: Lisp; package:maxima; syntax:common-lisp ;Base: 10 -*- ;;;
;;; Translated on: 2007-07-03 12:23:26+09:00
;;; Maxima System version: 5.11.0
;;; Lisp type: CLISP
;;; Lisp version: 2.39 (2006-07-16)
(built on x86-linux2.cf.sourceforge.net [10.8.2.2])
(in-package :maxima)
;;** Variable settings were **
;; transcompile: true;
;; tr_semicompile: false;
;; translate_fast_arrays: true;
;; tr_warn_undeclared: compile;
;; tr_warn_meval: compfile;
;; tr_warn_fexpr: compfile;
;; tr_warn_mode: all;
;; tr_warn_undefined_variable: all;
;; tr_function_call_default: general;
;; tr_array_as_ref: true;
;; tr_numer: false;
;; define_variable: false;
(progn (defprop $ff t translated) (add2lnc '$ff $props)
(defmtrfun ($ff $any mdefine nil nil) ($x $y)
(declare (special $y $x) (flonum $y $x))
(progn nil
((lambda ($ans) (declare (special $ans) (flonum $ans))
(prog nil (setq $ans (+$ $x $y)) (return $ans)))
0.0))))
(progn (defprop $fa t translated) (add2lnc '$fa $props)
(defmtrfun ($fa $any mdefine nil nil) ($x $y) (declare (special $y $x))
(progn nil
((lambda ($ans) (declare (special $ans))
(prog nil (setq $ans (add* $x $y)) (return $ans)))
'$ans))))
<<ex-translate.UNLISP>>*************************************************
This is the unlisp file for ex-translate.mx
Translating: ff
Translating: fa
define_variable(foo, true, boolenan);
● define_variable(’name,’default_binding,’mode,option_doc)
(スペシャルフォーム )
グローバル変数を環境内で使用開始する.これは,頻繁にトランスレート,コンパイルするユー
ザ記述パッケージ用.例えば, define_variable(foo, true, boolenan);
は以下の動作を行う.
● setup_autoload(’filename, ’fcn_1,…,’fcn_k) (スペシャルフォーム
)
● packagefile:false 環境変数
マクロ機能により,一見関数と似ているものの,評価および簡約化のコントロー ルをより注意深く行えるフォームを定義することが可能となる.高度なコント ロールが可能になることにより,多くの強力な機能を利用可能にする.例えば, 拡張コントロール構造体として機能し,内部的に特定の引数を取ったり,引数 の評価のための特殊環境を確立したりする演算子を記述する機能を有する.さ らに,コンパイルされたときに非常に良好なコードを生成することにもつなが る.
● マクロ名 ::= (定義) (インフィックス演算子)
“:=” の変わりに “::=” が使用され,以下の定義が関数定義で
はなくマクロ定義であることを示す.マクロ名は macros リストに追
加される.また, macros プロパティを受け取る.マクロ定義は,そ
のフォームを評価したとき,値として返ってくるものでなければならない.
showme の場合,その実行により以下のフォームを返す.
for i thru length(L) do print(L[i]=L[i]);
この返されたフォームの評価は,インタープリタが引き継ぐ.
マクロの適用に先だって引数の評価は行われない.この点が関数と異なる.
● buildq(variable_list,expression)
引数の variable_list は block の変数リストに似たものであ
る.アトミックな変数,代入フォームのいずれも指定できる.代入フォームの
場合,その右辺側はどのような式についても左から右に評価され,変数に付値
された結果は expression の中にひとまとめにして代入される.実際
のプロセスは,以下で理解できるように,substのプロセスよりも複雑
な記述を可能にする.expression には,ネストされた buildq
を含めてあらゆる有効な式を指定できる.新しい式は評価されないでそのまま
返される.
/home/inoue/bin/go tmp_lang/chunk-117.mx > tmp_lang/chunk-117.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-117.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-117.mx
display2d:false
s:a+b
buildq([s,a:a+b*c,fun:bar],s^2+g(a,'a)+fun(s))
g(b*c+a,'(b*c+a))+bar(b+a)+(b+a)^2
"/var/www/html/LANG/tmp_lang/chunk-117.mx"
代入の同時性は以下の例で確認できる.
/home/inoue/bin/go tmp_lang/chunk-118.mx > tmp_lang/chunk-118.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-118.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-118.mx
buildq([a:'b,b:'a],sin(a)+cos(b))
sin(b) + cos(a)
/var/www/html/LANG/tmp_lang/chunk-118.mx
● splice(form_1,…,form_k) (buildq 用キーワードフォーム)
スペシャルフォーム buildq は,式に指定できるキーワードフォーム splice
を識別できる.指定された splice が引数を1つもち,
それが代入を受ける変数の1つである場合,その変数の値は代入されないで式
にスプライス(接ぎ木)される.スプライスされた変数は,評価されるとリスト
になる.
/home/inoue/bin/go tmp_lang/chunk-119.mx > tmp_lang/chunk-119.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-119.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-119.mx
L:[a,b,c]
buildq([L],f(L,splice(L)))
f([a, b, c], a, b, c)
/var/www/html/LANG/tmp_lang/chunk-119.mx
以下に,前述の例に挙げたユーザ作成マクロ showme を示す.
/home/inoue/bin/go tmp_lang/chunk-120.mx > tmp_lang/chunk-120.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-120.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-120.mx
display2d:false
showme(L)::=buildq([L],for i thru length(L) do print('L[i] = L[i]))
x:['a,'b]
showme(x)
'x[1] = a
'x[2] = b
done
"/var/www/html/LANG/tmp_lang/chunk-120.mx"
シンボルは macro プロバティ,function プロバティのいずれ かを持つことが出来るが,両方を持つことは出来ない.アトムを ::= を使って定義すると,そのアトムの関数プロバティは削除される.逆もまた同じで ある.
● macros:[] システム変数
このシステム変数は,現在の環境内で定義されているすべてのマクロのリストを保持している.
変数 macros は infolists の1つである.
マクロの定義内容は,dispfun(name); または grind(name);
で表示できる.
コマンド sringout(functions);
は現在の環境にあるすべての関数とマクロの名前を表示するのに 利用できる.
スペシャルフォーム remfunction(func) は関数/マクロ func
の関数プロバティ/マクロプロバティを削除する. remove(name,function); は
name から関数ブロパティがあれば削除するがマクロプロバティは削除しない.
remove(name,macro); は name
からマクロブロパティがあれば削除するが関数プロバティは削除しない.
● macrosexpansion:false 環境変数
マクロの効率性に影響を与える高水準機能をコントロールする.以下の設定が可能.
以下は,マクロのデバッキングに有用である.
● macrosexpand1(form)
form がマクロ呼び出してある場合,それを自己評価することなく,厳
密に1回だけ展開する.form がマクロ呼び出してない場合は, form
は評価されず,そのまま返ってくる.
● macrosexpand(form)
form をマクロ呼び出しでなくなるまで,繰り返し展開する.最後の展
開部分については自動評価なして返ってくる.
/home/inoue/bin/go tmp_lang/chunk-121.mx > tmp_lang/chunk-121.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-121.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-121.mx
display2d:false
g(x)::=x/99
h(x)::=buildq([x],g(x-a))
h(x)::=buildq([x],g(x-a))
a:1234
1234
macroexpand(h(y))
(y-a)/99
h(y)
(y-1234)/99
"/var/www/html/LANG/tmp_lang/chunk-121.mx"
● error(arg_1,…,arg_k)
引数を評価し、エラーを出す。これにより、トップレベルもしくは最寄りの
errcatch の括弧の中に結果を返す.処理を抜ける前に, errorp が
arg_1,…,arg_k の値を表示する.エラーの条件が満
たされた場合に,ネストされた関数を抜けるのに役立つ.最新のエラーメッセー
ジを再度表示するには,errormsg(); を用いる.
◆ 実行例 error
/home/inoue/bin/go tmp_lang/chunk-123.mx > tmp_lang/chunk-123.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-123.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-123.mx
f(x):=if x < 0 then error("引数",x,"が負の値である") else sqrt(x)
f(4)
2
f(-4)
引数 - 4 が負の値である
#0: f(x=-4)
-- an error. To debug this try: debugmode(true);
/var/www/html/LANG/tmp_lang/chunk-123.mx
● errorfun:false 環境変数
この変数に引数を取らない関数名をセットしておくと,その関数になんらかの
エラーが発生した場合に強制終了する.暴走したbatchファイルに対し ては
quit を用いる.
● errormsg()
出力されたエラーメッセージのうち最新のものを再表示する.エラーが発生し
た場合,変数 error_list にそのエラーを記述したリストをセットする.そ
のリストの第1要素はテキストで,残りの要素はエラー状況に関するオブジェ
クトになっている.
● errcatch(exp_1,…,exp_k) スペシャルフォーム
引数を順に評価し,エラーが発生しなければ最後の引数 expk の値を
リストの形で返す.いずれかの引数の評価時点でエラーが発生した場合,
errcatch がそのエラーを受け取り,即座にを返
す.このスペシャルフォームは,batch ファイルの実行時に役立つ.
◆ 実行例 comment
/home/inoue/bin/go tmp_lang/chunk-124.mx > tmp_lang/chunk-124.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-124.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-124.mx
errcatch(romberg(log(x),x,0,1))
log: encountered log(0).
/var/www/html/LANG/tmp_lang/chunk-124.mx
次の例のように,関数内でのエラー発生時に実行を停止することを避けられる.
◆ 実行例 errcatch
/home/inoue/bin/go tmp_lang/chunk-125.mx > tmp_lang/chunk-125.out 2>&1
batch("/var/www/html/LANG/tmp_lang/chunk-125.mx")
read and interpret /var/www/html/LANG/tmp_lang/chunk-125.mx
f(x):=block([ans],ans:log(x),return(ans))
g(x):=block([ans],
if errcatch(log(x),return) = []
then ans:"エラー:真数条件を満たさない" else ans:log(x),
return(ans))
f(%e^3)
3
g(0)
log: encountered log(0).
エラー:真数条件を満たさない
print("--- pass to g(0) ---")
--- pass to g(0) ---
/var/www/html/LANG/tmp_lang/chunk-125.mx
f(0) ではエラーになり,その時点で実行停止になる.
● errormsg:true 環境変数
trueである場合,errcatch
の中にエラーが発生した場合,そのエラーメッセージを表示する.
● prederror:true 環境変数
trueである場合,if 文の述語または is フォームが true と false
のいずれにも評価されないとその度にエラーを 表示する.falseである場合は
UNKNOWN を返す.prederror:false のモードはトランスレートされたコードでは
サポートされない.
● parsewindow:10 環境変数
● error_size:10 環境変数
● error_syms:[errexp_1,errexp_2,errexp_3] 環境変数