• 検索結果がありません。

LISP に関係する関数

ドキュメント内 Maxima c (2007),,,,,. (ページ 78-81)

1.9.1 MaximaLISP

MaximaはCommon Lispと呼ばれるLISPの一方言で記述されています. LISPは函数型と呼

ばれるプログラム言語で,プログラムは様々な函数を定義し,それらを組合せて行く作業とも言え ます.因みに,CやFORTRANは手続型と呼ばれます.

MaximaはこのLISPの上で動作する環境ですが,Maxima自体はPASCAL風の処理言語を持っ

ており,構文的にもLISPを意識する事は単純な利用では殆どありません.

但し,Maximaで酷いエラーを出すとLISPのデバッガに落ちる事があります. LISPのデバッガ からの抜け方は,Maximaを実装したLISPによって微妙に異なりますが,CLISPの場合は:qと入 力してみて下さい.するとMaximaに戻ります.

LISPの特徴は言語仕様が非常に柔軟な点です.LISPにはアトムと呼ばれる変数があり,それらを 空行で区切って小括弧()で括ったリストと呼ばれるデータが,最も基本的なデータとなります.こ のリストはリストのリストといったものも許容します.このアトムとリスト等で構成されたデータ をS式と呼びます.因に,LISPのプログラム自体もS式です.その為,LISPの函数でプログラムを操 作する事も容易に行えます.

その為,Maximaのプログラムでは足りない所をLISPで代用する事も多くあります. 又,Maxima からLISPを直接利用する事も可能です.この場合はMaximaのto lisp函数を利用します.Maxima で to lisp(); と入力すると, 裏方のLISPが表に出ます.これでLISPを使って遊べます.この状態 からMaximaに戻りたければ, (to-maxima)と入力します.すると通常のMaximaに戻ります.

(%i1) to_lisp();

type (to-maxima) to restart, ($quit) to quit Maxima.

Maxima> (setq $a ’1) 1

Maxima> (to-Maxima) returning to Maxima

(%o1) true

(%i2) a;

(%o2) 1

この例ではto lisp();でLISPに入って,アトム$aに1を割当てています. それから(to-maxima) でMaximaに戻っています.to lisp函数の返却値はtrueです.最後にa;を入力すると,LISPで$aに 割当てた値1が返却されます.これはMaximaでのアトムの内部表現では$aの様に先頭に$が付く からです.

この例で注目して頂きたい事は,Maximaで表示されているものとLISP側で見たものと様子が 違う事です.即ち,Maximaで扱うデータ,更には函数それ自体もLISP側では別の表記方法があり ます.このLISP側での表現を単純に内部表現と呼んでいます.この内部表現を通常の処理で気にす る事は殆どありませんが, 細かな処理を行う必要が出た時点で初めて意識する事になります.

尚,Maximaの函数名で先頭に?が付いているものが幾つか存在します.この様な函数は?を外した 部分はLISPの函数で,Maximaから裏のLISPで処理させて,その結果をMaxima側に持って来る 函数です.?は通常のLISP の函数にも適応可能で?を頭に付けた函数は,Maxima内部では?を外し て,LISPの函数として処理されます.この様にMaximaが介在する為,?を用いてLISPの函数を利 用する場合には,引数はMaximaで見えているものを設定します.

尚,?と函数の間に空行を入れるとMaximaのオンラインマニュアルを呼出そうとするので,注意 が必要です.

?と似た函数に:lisp函数があります. こちらは,直接LISPのS式をMaxima側から入力し,LISP に評価させた値を得る為の函数です.?演算子との違いは,?演算子では引数がLISPの函数で,その引

数はMaxima に準じたものとなりますが,:lispの場合はより一般的なLISPのS式となります. そ

の為,引数もMaximaの内部表現そのものとなります.

(%i26) a:x+y+z;

(%o26) z + y + x

(%i27) :lisp $a;

((MPLUS SIMP) $X $Y $Z) (%i27) :lisp (car $a) (MPLUS SIMP)

(%i27) ?car(a);

(%o27) ("+", simp)

上記の例では変数aにx+y+zを割当てていますが,$aが変数aの内部変数名となります. :lisp $a;

でこの変数に割当てた値を参照していますが, 返却値は内部表現そのものです.この様な変数の参 照は?では出来ません.

更に, :lisp (car $a);の値は内部表現そのものですが, ?car(a); の値はそれをMaximaで解釈し

た(”+”, simp)となっており,引数に$が付いていない事と:lispの結果に%oラベルが無い事に注目

して下さい.

この様に,?は入力と出力にMaximaが介在する為に,入出力をする度にMaximaの評価を受ける 事になりますが,:lispの場合は直接操作となります. :lispはMaximaで内部表現を確認する必要が ある場合に特に便利な函数です.

尚,MaximaはLISPで記述されている為,そのデータだけではなく,全てがLISPのS式で,LISP の函数で処理が可能となります.この事を利用してMaximaの機能を拡張する事が容易に行えます.

Maximaの函数をLISPから利用する場合,mfuncall函数を用います. この場合,引数はMaxima の函数名の頭に’$を付け,その後に引数を並べます.

MAXIMA> (mfuncall ’$diff ’$x ’$x 1) 1

この例では,変数xをdiff函数を使ってxで微分するものです.この様に,引数は全て内部表現に 対応したものでなければなりません. 従って,Maxima上で引数を割当ててある状態でなければ,使 い難いものです. 現実的には,Maxima函数の虫取りや動作の確認で用いる程度でしょう.

ドキュメント内 Maxima c (2007),,,,,. (ページ 78-81)