version 1.11, 1999/12/18 20:02:19 |
version 1.63, 1999/12/23 21:04:10 |
|
|
\documentclass{jarticle} |
\documentclass{jarticle} |
|
|
\title{\bf Open XM($B%?%$%H%kL$Dj(B)} |
%% $OpenXM: OpenXM/doc/genkou19991125.tex,v 1.62 1999/12/23 19:59:51 tam Exp $ |
\author{ |
|
Maekawa \\ |
|
Noro \\ |
|
: \\ |
|
: \\ |
|
} |
|
\date{ 1999$BG/(B, 11$B7n(B25$BF|(B} |
|
|
|
%\pagestyle{empty} |
\usepackage{jssac} |
|
\title{タイのトル} |
|
\title{意味もない修飾過剰な語句は排除しましょう。} |
|
|
|
\author{前 川 将 秀\affil{神戸大学理学部} |
|
\mail{maekawa@math.sci.kobe-u.ac.jp} |
|
\and 野 呂 正 行\affil{富士通研究所} |
|
\mail{noro@para.flab.fujitsu.co.jp} |
|
\and 小 原 功 任\affil{金沢大学理学部} |
|
\mail{ohara@kappa.s.kanazawa-u.ac.jp} |
|
\and 奥 谷 行 央\affil{神戸大学大学院自然科学研究科} |
|
\mail{okutani@math.sci.kobe-u.ac.jp} |
|
\and 高 山 信 毅\affil{神戸大学理学部} |
|
\mail{takayama@math.sci.kobe-u.ac.jp} |
|
\and 田 村 恭 士\affil{神戸大学大学院自然科学研究科} |
|
\mail{tamura@math.sci.kobe-u.ac.jp} |
|
} |
|
\art{} |
|
|
\begin{document} |
\begin{document} |
\maketitle |
\maketitle |
|
|
\section{OpenXM $B$N7W;;%b%G%k(B} |
\section{OpenXMとは} |
|
|
OpenXM $B$O?t3X%=%U%H4V$G%a%C%;!<%8$r8r49$9$k$?$a$N5,Ls$G$"$k!#(B |
OpenXM は数学プロセス間でメッセージを交換するための規約である。 |
OpenXM $B$H$O(B Open message eXchange protocol for Mathematics $B$NN,$G$"$k!#(B |
数学プロセス間でメッセージをやりとりすることにより、 |
$B?t3X%=%U%H4V$G%a%C%;!<%8$r$d$j$H$j$5$;$k$3$H$K$h$j!"(B |
ある数学プロセスから他の数学プロセスを呼び出して計算を行なったり、 |
$B$"$k?t3X%=%U%H$+$iB>$N?t3X%=%U%H$r8F$S=P$7$F7W;;$r9T$J$C$?$j!"(B |
他のマシンで計算を行なわせたりすることが目的である。 |
$BB>$N%^%7%s$G7W;;$r9T$J$o$;$?$j$G$-$k$h$&$K$9$k!#(B |
なお、 OpenXM とは Open message eXchange protocol for Mathematics の略である。 |
$BH/C<$OLnO$@59T$H9b;3?.5#$K$h$j!"(B asir $B$H(B kan/sm1 $B$r(B |
OpenXM の開発の発端は野呂と高山により、 |
$BAj8_$K8F$S=P$95!G=$r<BAu$7$?$3$H$G$"$k!#(B |
asir と kan/sm1 を相互に呼び出す機能を実装したことである。 |
$B8=:_$NL\I8$O!"%U%j!<$N?t3X%=%U%H$rAj8_$K@\B3$7$F(B |
|
$B9%$-$J8@8l$+$i4JC1$KB>$N?t3X%=%U%H$r;H$($k$h$&$K$9$k$3$H$G$"$k!#(B |
|
|
|
$BH/C<$H$J$C$?(B asir $B$H(B kan/sm1 $B$G$N<BAu;~$K$O!"(B |
{\bf\large 以下の説明がなぜ必要なのかは全然分からないけれど、} |
$B$*8_$$$KAj<jB&$N%3%^%s%IJ8;zNs$rAw$C$F$$$?!#(B |
初期の実装では、相手側のローカル言語の文法に従った文字列を送っていた。こ |
$B$3$NJ}K!$O8=:_$N(B OpenXM $B5,Ls$G$b2DG=$G$"$j!"(B |
の方法では相手側のソフトが asir なのか kan/sm1 なのかを判別するなどして、 |
$B;H$$$d$9$/$O$"$k$,!"8zN(E*$G$"$k$H$O$$$$Fq$$!#(B |
相手側のローカル言語の文法に合わせた文字列を作成しなければならない。この |
$B$5$i$K!"$3$NJ}K!$G$OAj<jB&$N%=%U%H$,(B asir $B$J$N$+(B kan/sm1 $B$J$N$+$r(B |
ローカル言語の文法に従った文字列を送る方法は、効率的であるとはいい難いが、 |
$BH=JL$7$F!"Aj<jB&$K9g$o$;$F%3%^%s%IJ8;zNs$r:n@.$9$kI,MW$,$"$k!#(B |
使いやすいとも言える。 |
|
|
$B$3$l0J30$NJ}K!$H$7$F!"(B OpenXM $B5,Ls$G$O6&DLI=8=7A<0$K$h$k(B |
現在の OpenXM 規約では共通表現形式によるメッセージを用いている。上記の文 |
$B%a%C%;!<%8$rMQ0U$7$F$$$k!#(B |
字列を送る方法の利点を生かすため、OpenXM 規約では共通表現形式の中の文字 |
OpenXM $B5,LsFH<+$N%G!<%?7A<0$G$"$k(B CMO $B7A<0(B(Common Mathematical Object format) |
列として、ローカル言語の文法に従った文字列を用いたメッセージの交換も可能 |
$B0J30$K$b!"(B MP $B$d(B OpenMath $B$N(B XML, binary $BI=8=7A<0$H$$$C$?B>$N7A<0$r$b(B |
となっている。 |
$B07$($k$h$&$K$7$F$"$k!#(B |
{\large\bf しかし、こんな細かいことをここで説明しなければ |
|
ならない理由がやっぱり分からないなぁ。構成的におかしいと思うけどなぁ。意 |
|
味不明。} |
|
|
|
OpenXM 規約では通信の方法に幾らかの自由度があるが、 |
|
現在のところは TCP/IP を用いた通信しか実装されていない。 |
|
そこで、ここでは具体的な実装は TCP/IP を用いていると仮定する。 |
|
|
\section{OpenXM $B$N%a%C%;!<%8$N9=B$(B} |
\section{OpenXM のメッセージの構造} |
|
|
OpenXM $B$G5,Dj$7$F$$$k%a%C%;!<%8$OO@M}E*$K(B |
通信の方法によってメッセージの構造は変わる。 |
OX $BAX!"(B SM $BAX!"(B CMO $BAX$KJ,$1$k$3$H$,$G$-$k!#(B |
ここでは、 TCP/IP の場合について説明を行なう。 |
$B$3$NCf$G!"%a%C%;!<%8$H$7$FAw$k$3$H$,2DG=$J$N$O(B |
|
OX $BAX$GDj5A$5$l$?$b$N$@$1$G$"$j!"(B |
|
SM $BAX!"(B CMO $BAX$GDj5A$5$l$F$$$k%G!<%?$O(B |
|
OX $BAX$GDj5A$5$l$F$$$k%G!<%?$N0lIt$KKd$a9~$^$l$F(B |
|
$BAw$i$l$k!#(B |
|
SM $BAX!"(B CMO $BAX$GDj5A$5$l$F$$$k%G!<%?0J30$K$b(B |
|
$BA0=R$N(B MP $B$d(B OpenMath $B$N(B XML, binary $BI=8=$b(B |
|
OX $BAX$KKd$a9~$^$l$FAw$i$l$k$o$1$G$"$k$,!"(B |
|
$B$I$N$h$&$J%G!<%?$,Kd$a9~$^$l$F$$$k$+$O!"(B |
|
OX $BAX$N@hF,$K$"$k(B tag $B$r8+$l$PH=JL$G$-$k$h$&$K$J$C$F$$$k!#(B |
|
|
|
|
OpenXM 規約で規定されているメッセージはバイトストリームとなっており、 |
|
次のような構造になっている。 |
|
|
\section{OpenXM $B$N7W;;$N?J9TJ}K!(B} |
\begin{tabular}{|c|c|} |
|
\hline |
|
ヘッダ & \hspace{10mm} ボディ \hspace{10mm} \\ |
|
\hline |
|
\end{tabular} |
|
|
OpenXM $B5,Ls$G$N%a%C%;!<%8$N8r49$O%5!<%P$H%/%i%$%"%s%H$N4V$G(B |
ヘッダの長さは 8 バイトであると定められている。 |
$B9T$J$o$l$k!#%/%i%$%"%s%H$+$i%5!<%P$X7W;;$5$;$?$$%G!<%?$r(B |
ボディの長さはメッセージごとに異なっているが、 |
$B%a%C%;!<%8$H$7$FAw$j!"<!$$$G%5!<%P$K9T$J$o$;$?$$F0:n$K(B |
長さは $0$ でもよい。 |
$BBP1~$7$?%G!<%?$rAw$k$3$H$K$h$C$F!"7W;;$J$I$N!"$J$s$i$+$NF0:n$r(B |
|
$B%5!<%P$K9T$J$o$;$k!#%5!<%P$O7k2L$NAw?.$bL?Na$5$l$J$1$l$P(B |
|
$B9T$J$&$3$H$O$J$/!"%/%i%$%"%s%H$O7k2L$r<u$1<h$i$:$K%5!<%P$K<!!9$H(B |
|
$B7W;;$r9T$J$o$;$k$3$H$b2DG=$G$"$k!#$J$*!"%5!<%P$KBP$9$kF0:n$KBP1~$7$?(B |
|
$B%G!<%?$O(B SM $BAX$GDj5A$5$l$F$*$j!"(B SM $BAX0J30$N%G!<%?$G$O%5!<%P$O(B |
|
$B%G!<%?$r<u$1<h$k0J30$NF0:n$r$7$J$$$3$H$K$J$C$F$$$k!#(B |
|
|
|
$B%5!<%P$O%9%?%C%/$r;}$C$F$$$k$H2>Dj$5$l$F$*$j!"<u$1<h$C$?(B |
ヘッダは次の二つの情報を持っている。 |
$B%a%C%;!<%8$O$9$Y$F%9%?%C%/$K@Q$^$l$k!#$3$3$G!"(B SM $BAX$GDj5A$5$l$?(B |
\begin{enumerate} |
$B%G!<%?$r<u$1<h$C$?>l9g$K$O!"$=$l$KBP1~$9$kF0:n$r9T$J$&!#(B |
\item 前半の 4 バイト。メッセージの種類を表わす識別子であり、 |
$B$3$N$H$-!"I,MW$,$"$l$P%5!<%P$O%9%?%C%/$+$i%G!<%?$r<h$j=P$9!#(B |
タグと呼ばれる。 |
$B%/%i%$%"%s%H$+$i$NL?Na$K$h$kF0:nCf$K%(%i!<$,H/@8$7$?$H$7$F$b!"(B |
\item 後半の 4 バイト。メッセージにつけられた通し番号である。 |
$B%5!<%P$O%(%i!<%*%V%8%'%/%H$r%9%?%C%/$K@Q$`$@$1$G!"(B |
\end{enumerate} |
$BL@<($5$l$J$$8B$j%(%i!<$rJV$5$J$$$3$H$KCm0U$7$J$1$l$P$J$i$J$$!#(B |
それぞれの 4 バイトは 32 ビット整数とみなされて扱われる。 |
|
この場合に用いられる整数の表現方法については後述するが、 |
|
基本的に表現方法はいくつかの選択肢から選ぶことが可能となっており、 |
|
またその選択は通信路の確立時に一度だけなされることに注意しなければならない。 |
|
現在のOpenXM 規約では、タグ(整数値)として |
|
以下のものが定義されている。 |
|
|
$B7k2L$,@8$8$kF0:n$r%5!<%P$,9T$J$C$?>l9g!"(B |
\begin{verbatim} |
$B%5!<%P$OF0:n$N7k2L$r%9%?%C%/$K@Q$s$G$$$k!#(B |
#define OX_COMMAND 513 |
$B%5!<%P$K9T$J$o$;$?F0:n$N7k2L$r%/%i%$%"%s%H$,CN$j$?$$>l9g!"(B |
#define OX_DATA 514 |
$B%9%?%C%/$+$i%G!<%?$r<h$j=P$7Aw?.$r9T$J$&L?Na$KBP1~$7$?(B SM $BAX$N%G!<%?$r(B |
#define OX_SYNC_BALL 515 |
$B%5!<%PB&$XAw$l$P$h$$!#(B |
#define OX_DATA_WITH_LENGTH 521 |
|
#define OX_DATA_OPENMATH_XML 523 |
|
#define OX_DATA_OPENMATH_BINARY 524 |
|
#define OX_DATA_MP 525 |
|
\end{verbatim} |
|
|
$B%/%i%$%"%s%H$,%5!<%P$X7W;;$r9T$J$o$;!"7k2L$rF@$k$H$$$&<j=g$rDI$C$F$$$/$H!"(B |
ボディの構造はメッセージの種類によって異なる。 |
$B<!$N$h$&$K$J$k!#(B |
ここでは、 OX\_DATA と OX\_COMMAND で識別されるメッセージについてのみ、 |
|
説明する。 |
|
|
|
既存のメッセージでは対応できない場合は、新しい識別子を定義することで新し |
|
い種類のメッセージを作成することができる。この方法は各数学ソフトウェアの |
|
固有の表現を含むメッセージを作成したい場合などに有効である。新しい識別子 |
|
の定義方法については、\cite{OpenXM-1999} を参照すること。 |
|
|
|
\section{OpenXM の計算モデル} |
|
|
|
OpenXM 規約での計算とはメッセージを交換することである。また、 OpenXM 規 |
|
約ではクライアント・サーバモデルを採用しているので、メッセージの交換はサー |
|
バとクライアントの間で行なわれる。クライアントからサーバへメッセージを送 |
|
り、クライアントがサーバからメッセージを受け取ることによって計算の結果が |
|
得られる。 |
|
|
|
サーバはスタックマシンである。サーバがクライアントから受け取ったメッセー |
|
ジは、タグが OX\_COMMAND でなければすべてスタックに積まれる。タグが |
|
OX\_COMMAND となっているメッセージはスタックマシンへの命令であり、このメッ |
|
セージを受け取ったサーバはそれに対応する動作を行なうことが期待されている。 |
|
サーバはメッセージを受け取らない限り、自ら何か動作をおこなわない。 |
|
|
|
{\large\bf 意味不明な書き方だけど、} |
|
|
|
これは毎回サーバへメッセージを送る |
|
たびに、いつもサーバからのメッセージをクライアントが待つ必要がないことを |
|
意味する。このため、クライアントはサーバの状態を気にせずにメッセージを送 |
|
り、一旦メッセージを送付し終えた後、サーバへ送ったメッセージの結果をサー |
|
バから待つことなしに次の動作に移ることができる。 |
|
|
|
\section{OpenXM の計算の進行方法} |
|
|
|
前の節と重複しているのでもう少しちゃんと考えて欲しいのだけれど、 |
|
|
|
サーバが行うのは基本的に次の事柄だけである。 |
|
クライアントからメッセージを受け取ると、 |
|
サーバはまずメッセージの識別子を調べ、 |
|
タグが OX\_COMMAND のメッセージでなければスタックに積む。 |
|
タグが OX\_COMMAND のメッセージであればメッセージのボディから |
|
スタックマシンの命令コードを取りだし、 |
|
あらかじめ規約で定められた動作を行なう。 |
|
|
|
上の説明でわかるように、 |
|
サーバはクライアントからの指示なしに、 |
|
自らメッセージを送らないことに注意する必要がある。 |
|
%(例外? ox\_asir の mathcap)。 |
|
|
|
サーバがクライアントから受け取ったメッセージはすべてスタックに積まれている。 |
|
次いでサーバにスタックマシンへの命令を送ると、 |
|
初めてサーバはデータをスタックに積む以外のなんらかの動作を行なう。 |
|
このとき、必要があればサーバはスタックから必要なだけデータを取り出す。 |
|
ここで、クライアントからの命令による動作中にたとえエラーが発生したとしても |
|
サーバはエラーオブジェクトをスタックに積むだけで、 |
|
明示されない限りエラーをクライアントへ返さないことに注意しなければならない。 |
|
|
|
結果が生じる動作をサーバが行なった場合、 |
|
サーバは動作の結果をスタックに積む。 |
|
サーバに行なわせた動作の結果をクライアントが知りたい場合、 |
|
スタックからデータを取り出し送信を行なう命令をサーバ側へ送ればよい。 |
|
|
|
%{\Huge 以下、書き直し} |
|
|
|
クライアントがサーバへメッセージを送り、 |
|
計算の結果を得るという手順を追っていくと次のようになる。 |
|
|
\begin{enumerate} |
\begin{enumerate} |
\item $B$^$:!"%/%i%$%"%s%H$,%5!<%P$X7W;;$5$;$?$$%G!<%?$rAw$k!#(B |
\item まず、クライアントがサーバへメッセージを送る。 |
$B%5!<%P$OAw$i$l$F$-$?%G!<%?$r%9%?%C%/$K@Q$`!#(B |
サーバは送られてきたメッセージをスタックに積む。 |
\item $B%/%i%$%"%s%H$,%5!<%P$K7W;;$r9T$J$&F0:n$KBP1~$7$?%G!<%?$r(B |
\item クライアントがサーバにスタックマシンへの命令を送ると、 |
$BAw$k$H!"%5!<%P$OI,MW$J$@$1%9%?%C%/$+$i%G!<%?$r<h$j=P$7!"(B |
サーバは必要なだけスタックからデータを取り出し、 |
$B<B9T$7$?7W;;$N7k2L$r%9%?%C%/$K@Q$`!#(B |
実行した結果をスタックに積む。 |
\item $B:G8e$K!V%G!<%?$r<h$j=P$7Aw?.$r9T$J$&L?Na$KBP1~$7$?%G!<%?!W$r(B |
\item 最後に「スタックからデータを取り出し送信を行なう命令」を |
$B%5!<%P$XAw$k$H!"%5!<%P$O%9%?%C%/$+$i7W;;7k2L$NF~$C$F$$$k(B |
サーバへ送ると、サーバはスタックから計算結果の入っている |
$B%G!<%?$r<h$j=P$7!"%/%i%$%"%s%H$XAw=P$9$k!#(B |
データを取り出し、クライアントへ送出する。 |
\end{enumerate} |
\end{enumerate} |
|
|
|
|
\section{CMO $B$N%G!<%?9=B$(B} |
\section{CMO のデータ構造} |
|
|
OpenXM $B4V$G$d$j$H$j$5$l$k%a%C%;!<%8$r<B:]$K:n@.$9$k>l9g!"(B |
OpenXM 規約では、数学的オブジェクトを表現する方法として |
CMO $BAX$GDj5A$5$l$F$$$kB?G\D9@0?t$rM}2r$7$F$*$/$H!"(B |
CMO 形式(Common Mathematical Object format)を定義している。 |
CMO $BAX$NB>$N%G!<%?9=B$$@$1$G$J$/!"(B OX $BAX!"(B SM $BAX$N%G!<%?$r(B |
この CMO 形式を使ってメッセージを送るには、 |
$BM}2r$9$k=u$1$K$J$k$H;W$($k$N$G!"(B CMO $BAX$NB?G\D9@0?t$N(B |
タグを OX\_DATA にすればよい。 |
$B%G!<%?9=B$$K$D$$$F@bL@$9$k!#(B |
CMO 形式におけるデータ構造について以下で説明するが、 |
|
%OpenXM 規約で定義されているメッセージを実際に作成する場合、 |
|
CMO 形式で定義されている多倍長整数を理解しておくと、 |
|
CMO 形式の他のデータ構造だけでなく、 |
|
OpenXM 規約で定義されている様々なデータ構造を理解する助けになると思えるので、 |
|
ここでは CMO 形式の多倍長整数のデータ構造についてのみ説明する。 |
|
|
CMO $BAX$GDj5A$5$l$F$$$k%G!<%?$OB?G\D9@0?t0J30$K$b(B |
CMO 形式で定義されているデータは多倍長整数以外にも |
$BJ8;zNs$d%j%9%H$J$I$,$"$k!#$I$N$h$&$J%G!<%?$G$"$k$+$O(B |
文字列やリスト構造などがある。どのようなデータであるかは |
$B%G!<%?$N@hF,$K$"$k(B tag $B$r8+$l$PH=JL$G$-$k$h$&$K$J$C$F$$$k!#(B |
データの先頭にある(メッセージの識別子とは別にある)タグを見れば |
$B$3$l$O(B OX $BAX$G$N%G!<%?$NH=JL$N;EJ}$H$*$J$8$G$"$k!#(B |
判別できるようになっている。 |
$B$J$*!"(B tag $B$O3F%G!<%?Kh$K(B 32 bit $B$N@0?t$GI=$5$l$F$*$j!"(B |
これはメッセージの種類の判別の仕方とおなじである。 |
$BB?G\D9@0?t$O(B 20 $B$H$J$C$F$$$k!#(B |
なお、タグは各データ毎に 32 bit の整数で表されており、 |
$B$3$3$G(B 32 bit $B$N@0?t$NI=8=J}K!$K$D$$$F@bL@$9$kI,MW$,$"$k!#(B |
多倍長整数は 20 となっている。 |
%$B:r:#$N%3%s%T%e!<%?;v>p$+$i!"(B |
よく使われると思われる CMO 形式のタグをあげておく。 |
%32 bit $B@0?t$b(B 8 bit $BC10L$G07$&$[$&$,ET9g$,$h$$!#(B |
\begin{verbatim} |
OpenXM $B$G$O(B 8 bit $BC10L$G(B $( \mbox{\tt 00 00 00 14})_{2^8}$ $B$HI=$9J}K!$H(B |
#define CMO_INT32 2 /* 32 ビット整数 */ |
$( \mbox{\tt 14 00 00 00})_{2^8}$ $B$HI=$9J}K!$,$"$k!#(B |
#define CMO_STRING 4 /* 文字列 */ |
$B$3$NI=8=J}K!$N0c$$$O%/%i%$%"%s%H$H%5!<%P$N:G=i$N@\B3;~$K(B |
#define CMO_MATHCAP 5 /* mathcap(後述) */ |
$BAPJ}$N9g0U$G7hDj$9$k$3$H$K$J$C$F$$$k!#$J$*!"9g0U$,$J$$>l9g$K$O(B |
#define CMO_LIST 17 /* リスト構造 */ |
$BA0<T$NI=8=J}K!(B($B0J8e!"$3$NI=8=J}K!$r(B network byte order $B$H8F$V(B)$B$r(B |
#define CMO_ZZ 20 /* 多倍長整数 */ |
$B;H$&$3$H$K$J$C$F$$$k!#(B |
\end{verbatim} |
$B$^$?!"Ii$N?t$rI=8=$9$kI,MW$,$"$k$H$-$K$O!"(B |
|
2 $B$NJd?tI=8=$r;H$&$3$H$K$J$C$F$$$k!#(B |
|
|
|
$BI=8=$7$?$$B?G\D9@0?t$N@dBPCM$r(B 2 $B?J?t$GI=$7$?>l9g$N7e?t$r(B $n$ $B$H(B |
ここで 32 bit の整数の表現方法について説明する必要がある。 |
$B$7$?$H$-!"<!$K$/$k%G!<%?$O(B $[(n+31)/32]$ $B$r(B 32 bit $B$N@0?t$H$J$k!#(B |
OpenXM 規約ではバイトストリームで 32 bit の整数 20 を |
$B$3$l$OB?G\D9@0?t$N@dBPCM$r(B $2^{32}$ $B?J?t$GI=$7$?>l9g$N7e?t$H$H$C$F$b$h$$!#(B |
{\tt 00 00 00 14} と表す方法と {\tt 14 00 00 00} と表す方法がある。 |
$B$?$@$7!"I=8=$7$?$$?t$,Ii$N>l9g$O$3$N(B 32 bit $B$N@0?tCM$O(B 2 $B$NJd?tI=8=$GIi$K$J$k!#(B |
この表現方法の違いはクライアントとサーバの最初の接続時に |
|
双方の合意で決定することになっている。 |
|
なお、合意がない場合には前者の表現方法 |
|
(以後、この表現方法をネットワークバイトオーダーと呼ぶ)を |
|
使うことになっている。 |
|
また、負の数を表現する必要があるときには、 |
|
2 の補数表現を使うことになっている。 |
|
|
%$BI=8=$7$?$$B?G\D9@0?t$,Ii$G$"$C$F$b$3$l0J9_$N@bL@$O@5$N>l9g$H(B |
CMO 形式の多倍長整数は、 Gnu MPライブラリ等を参考にしており、 |
%$BJQ$o$i$J$$$N$G!"0J8eB?G\D9@0?t$O@5$H$_$J$9!#(B |
符合付き絶対値表現を用いている。 |
|
タグ以降の形式は次のようになる。 |
|
|
$BI=8=$7$?$$B?G\D9@0?t$N@dBPCM$,(B $2^{32}$ $B?J?t$G(B $(b_0 b_1 ...)_{2^{32}}$ |
\begin{tabular}{|c|c|c|c|c|} \hline |
$B$HI=$;$k$H$-!"<!$K$/$k%G!<%?$O(B $b_0$, $b_1$, $\cdots$ $B$r(B |
$f$ & $b_0$ & $b_1$ & $\cdots$ & $b_{n-1}$ \\ \hline |
32 bit $B$N@0?t$GI=8=$7$?CM$H$J$k!#(B |
\end{tabular} |
|
|
$B$3$3$G6qBNNc$r$@$=$&!#(B |
ここで、 1 つの枠は 4 バイトを表し、 |
$4294967298 = 1 \times 2^{32} + 2$ $B$r(B network byte order $B$NB?G\D9@0?t$G(B |
$f$ は符合付き 32 ビット整数を、 |
$BI=8=$9$k$H!"(B |
$b_0$, $b_1$, $\cdots$, $b_{n-1}$ は符合なし 32 ビット整数を表している。 |
|
さらに、 $|f| = n$ が成り立たなければならない。 |
|
このオブジェクトは |
|
\[ \mbox{sgn}(f) \times \{ b_0 (2^{32})^0 + b_1 (2^{32})^1 + \cdots |
|
+ b_{n-1} (2^{32})^{n-1} \} \] |
|
という整数であると定義されている。 |
|
ただし、 |
|
\[ \mbox{sgn}(f) = \left\{ \begin{array}{ll} |
|
1 & f>0 \\ |
|
0 & f=0 \\ |
|
-1 & f<0 \\ \end{array} \right. \] |
|
である。 |
|
|
|
ここで具体例をだそう。 |
|
$4294967298 = 1 \times 2^{32} + 2$ を CMO 形式の |
|
ネットワークバイトオーダー、多倍長整数で表現すると、 |
\begin{center} |
\begin{center} |
{\tt 00 00 00 14 00 00 00 02 00 00 00 02 00 00 00 01} |
{\tt 00 00 00 14 00 00 00 02 00 00 00 02 00 00 00 01} |
\end{center} |
\end{center} |
$B$H$J$k!#$^$?!"F1$8I=8=J}K!$G(B $-1$ $B$rI=8=$9$k$H!"(B |
となる。また、同じ表現方法で $-1$ を表現すると、 |
\begin{center} |
\begin{center} |
{\tt 00 00 00 14 ff ff ff ff 00 00 00 01} |
{\tt 00 00 00 14 ff ff ff ff 00 00 00 01} |
\end{center} |
\end{center} |
$B$H$J$k!#(B |
となる。 |
|
|
|
|
\section{MathCap $B$K$D$$$F(B} |
\section{mathcap について} |
|
|
%$BA0@a$G8+$?$h$&$K!"(B 1 $B$D$N%a%C%;!<%8$ND9$5$O7h$^$C$F$$$J$$!#(B |
OpenXM 規約では、通信時に用いられるメッセージの種類を |
$B%5!<%P$*$h$S%/%i%$%"%s%HAPJ}$H$b$K(B OpenXM $B$G5,Dj$5$l$F$$$k(B |
各ソフトウェアが制限する方法を用意している。 |
$B$9$Y$F$N%a%C%;!<%8$rM}2r$G$-$k$o$1$G$O$J$$!#(B |
これは各ソフトウェアの実装によってはすべてのメッセージを |
$B$=$3$G!"(B OpenXM $B$G$OAj<j$NM}2r2DG=$J%a%C%;!<%8$r(B |
サポートするのが困難な場合があるからである。 |
$B<}F@$9$kJ}K!$rMQ0U$7$F$$$k!#(B |
また、各ソフトウェアでメッセージの種類を拡張したい場合にも有効である。 |
CMO $BAX$GDj5A$5$l$F$$$k(B MathCap $B%G!<%?$O(B |
この制限(あるいは拡張)は CMO 形式で定義されている mathcap と |
$BM}2r2DG=$J%a%C%;!<%8$rI=$9%G!<%?$G$"$j!"(B |
呼ばれるデータ構造によって行われる。 |
$BMW5a$5$l$l$P%5!<%P$O(B MathCap $B$r%9%?%C%/$K@Q$`!#(B |
この節では mathcap のデータ構造と、 |
$B$^$?!"%/%i%$%"%s%H$+$i(B MathCap $B$r%5!<%P$XAw$k$3$H$b$G$-!"(B |
具体的なメッセージの制限の手続きについて説明する。 |
MathCap $B$r%5!<%P$H%/%i%$%"%s%H$G8r49$9$k$3$H$K$h$C$F!"(B |
|
$B$*8_$$$KAj<j$NM}2rIT2DG=$J%a%C%;!<%8$rAw$C$F$7$^$&$3$H$r(B |
|
$BKI$0$3$H$,$G$-$k!#(B |
|
$B$J$*!"(B MathCap $B$N%G!<%?$NCf$G$O(B CMO $BAX$GDj5A$5$l$F$$$k(B |
|
32 bit $B@0?t!"J8;zNs!"%j%9%H9=B$$r;H$C$F$*$j!"(B |
|
MathCap $B$rM}2r$G$-$k$?$a$K$OI,A3E*$K$3$l$i$bM}2r$G$-$k(B |
|
$BI,MW$,$"$k!#(B |
|
|
|
OpenXM $BBP1~HG$N(B asir $B$G$"$k(B ox\_asir $B$,JV$9(B MathCap $B$r(B |
まず、手続きについて説明しよう。 |
$B0J2<$K<($9!#$J$*!"(B $a_0$, $a_1$, $\cdots$, $a_n$ $B$rMWAG$K(B |
クライアント側の mathcap をサーバへ送ると、 |
$B;}$D%j%9%H9=B$$r(B {\tt [$a_0$, $a_1$, $\cdots$, $a_n$]} $B!"(B |
すでに説明したように、サーバは受け取った mathcap をスタックに積み上げる。 |
$BJ8;zNs(B ``string'' $B$r(B {\tt "string"} $B!"(B 32 bit $B@0?t$r(B |
次にクライアントはスタックマシンへの命令をサーバへ送ることにより、 |
$B$=$l$KBP1~$9$k(B 10 $B?J?t$N@0?t$G<($9!#(B |
サーバはスタックに積まれている mathcap を取り出し、 |
|
mathcap で設定されていないメッセージをクライアント側へ |
|
送らないように設定する。 |
|
サーバ側の mathcap が欲しい場合には以下のようにする。 |
|
クライアントがサーバに mathcap を要求すると、 |
|
サーバはサーバ自身の mathcap をスタックに積む。 |
|
さらにサーバにスタックからデータを取り出し送信を行なう命令を送れば、 |
|
サーバはスタックにある mathcap をクライアントへ送出する。 |
|
このようにしてクライアントはサーバ側の mathcap を受け取るわけである。 |
|
|
%$B"-<j$G:n$C$?$N$G4V0c$($F$$$k2DG=@-$"$j!#(B |
次に mathcap のデータ構造について説明する。 |
%%$B8E$$%P!<%8%g%s!#:9$7BX$($NI,MW$"$j!#(B |
mathcap は CMO 形式で定義されており、 |
\begin{verbatim} |
1 つの CMO 形式のオブジェクトを持つ。 |
[ [199901160,"ox_asir"], |
そのオブジェクトは以下で説明する、 3 つの要素からなるリストでなければならない。 |
[276,275,258,262,263,266,267,268,274 |
|
,269,272,265,264,273,300,270,271], |
|
[ [514,[1,2,3,4,5,2130706433,2130706434 |
|
,17,19,20,21,22,24,25,26,31,27,33,60]], |
|
[2144202544,[0,1]] |
|
] |
|
] |
|
\end{verbatim} |
|
|
|
$B$3$N(B MathCap $B%G!<%?$N%j%9%H9=B$$N:G=i$NMWAG$O%5!<%P$N>pJs$,F~$C$F$$$k!#(B |
\[ \begin{tabular}{|c|c|c|} \hline |
$B$3$N:G=i$NMWAG$,$^$?%j%9%H9=B$$H$J$C$F$*$j!"(B |
$A$ & $B$ & $C$ \\ \hline |
$B:G=i$NMWAG$O%P!<%8%g%s%J%s%P!<$r!"<!$NMWAG$O%5!<%P$NL>A0$rI=$7$F$$$k!#(B |
\end{tabular} \] |
|
|
$B<!$NMWAG$O(B SM $BAX$GDj5A$5$l$F$$$kM}2r2DG=$J%G!<%?$rI=$7$F$$$k!#(B |
最初の要素 $A$ の部分は以下のようなリスト構造をしており、 |
$B%5!<%P$NF0:n$KBP$9$k%G!<%?$O(B SM $BAX$G$O$9$Y$F(B 32 bit $B$N@0?t$G(B |
$a_1$ は 32 ビット整数でバージョンナンバーを、 |
$BI=$5$l$F$*$j!"$3$N(B 2 $BHV$a$NMWAG$OM}2r2DG=$J(B SM $BAX$N%G!<%?$K(B |
$a_2$ は文字列でシステムの名前を表すことになっている。 |
$BBP$9$k(B 32 bit $B@0?t$N%j%9%H$H$J$C$F$$$k!#(B |
|
|
|
$B:G8e$NMWAG$OM}2r2DG=$J%G!<%?$rI=$7$F$$$k!#(B |
\[ \begin{tabular}{|c|c|} \hline |
%$B$3$N%j%9%H$NMWAG$O$^$?%j%9%H$H$J$C$F$*$j!"(B |
$a_1$ & $a_2$ \\ \hline |
$B$3$N:G8e$NItJ,$b$^$?%j%9%H$H$J$C$F$*$j!"(B |
\end{tabular} \] |
$B$"$k%G!<%?7A<0$GM}2r2DG=$J$b$N$rI=8=$7$?%j%9%H$rMWAG$H$7$F$$$k!#(B |
|
{\tt [514,[1, 2, $\cdots$]]} $B$N:G=i$N(B 514 $B$O$3$N%j%9%H$,(B CMO $B7A<0(B |
|
$B$G$NM}2r2DG=$J%G!<%?$rI=$7$F$$$k$3$H$r<($7$F$*$j!"(B |
|
$B$=$N8e$N%j%9%H$G$O(B CMO $BAX$GDj5A$5$l$F$$$k%G!<%?$N$&$A!"(B |
|
$BM}2r2DG=$J%G!<%?$N(B tag $B$,JB$s$G$$$k!#(B |
|
$BA0@a$G(B CMO $B7A<0$G$OB?G\D9@0?t$rI=$9(B tag $B$,(B 20 $B$G$"$k$3$H$r=R$Y$?$,!"(B |
|
$B$3$N%j%9%H$K(B 20 $B$,4^$^$l$F$$$k$N$G!"(B ox\_asir $B$O(B CMO $B7A<0$N(B |
|
$BB?G\D9@0?t$,M}2r$G$-$k$3$H$,$o$+$k!#(B |
|
|
|
$B:G=i$N%j%9%H$,%5!<%P$N>pJs$rI=$7$F$$$k$H$$$C$?$3$H$,M}2r$G$-$k$3$H$H!"(B |
2 番目の要素 $B$ の部分は次のようなリスト構造をしている。 |
$B%G!<%?$,<u$1<h$l$k$3$H$H$O$^$C$?$/JLJ*$G$"$k$N$G(B |
この $b_1$, $b_2$, $\cdots$, $b_n$ はすべて 32 ビットの整数である。 |
$BCm0U$9$kI,MW$,$"$k!#(B |
スタックマシンへの命令はすべて 32 ビットの整数で表しており、 |
|
各 $b_i$ は利用可能な命令に対応する 32 ビットの整数となっている。 |
|
|
|
\[ \begin{tabular}{|c|c|c|c|} \hline |
|
$b_1$ & $b_2$ & $\cdots$ & $b_n$ \\ \hline |
|
\end{tabular} \] |
|
|
\section{security $BBP:v(B} |
3 番目の要素 $C$ は以下のようなリスト構造をしている。 |
|
\[ \overbrace{ |
|
\begin{tabular}{|c|c|c|c|} \hline |
|
$c_1$ & $c_2$ & $\cdots$ & $c_n$ \\ \hline |
|
\end{tabular} |
|
}^{C} \] |
|
%$n$ は OX\_COMMAND 以外の受け取れるメッセージのタグの種類の数に等しい。 |
|
%要素数は 1 でももちろん構わない。 |
|
各 $c_i$ もまた以下のようなリスト構造となっており、 |
|
どの $c_i$ も最初の要素が 32 ビットの整数となっている。 |
|
\[ \overbrace{ |
|
\begin{tabular}{|c|c|c|c|c|} \hline |
|
$c_{i1}$ (32 ビットの整数) & $c_{i2}$ & $c_{i3}$ & |
|
$\cdots$ & $c_{im}$ \\ \hline |
|
\end{tabular} |
|
}^{c_i} \] |
|
このリストの最初の整数値は受け取れるメッセージのタグが入っている。 |
|
$c_{i2}$ 以降については最初の $c_{i1}$ の値によってそれぞれ異なる。 |
|
ここでは、最初の要素が OX\_DATA の場合についてのみ説明する。 |
|
この $c_{i1}$ が OX\_DATA の場合、 |
|
リスト $c_i$ は CMO 形式についての情報を表しており、 |
|
$m=2$ である。 |
|
$c_{i1}$ にはもちろんのこと、 OX\_DATA が入っており、 |
|
$c_{i2}$ は以下のようなリスト構造になっている。 |
|
各要素は 32 ビットの整数であり、 |
|
受け取ることが可能な CMO 形式のタグが入る。 |
|
\[ \overbrace{ |
|
\begin{tabular}{|c|c|c|c|c|} \hline |
|
$c_{i21}$ & $c_{i22}$ & $\cdots$ & $c_{i2l}$ \\ \hline |
|
\end{tabular} |
|
}^{c_{i2}} \] |
|
|
OpenXM $B$G$O4v$i$+$N%;%-%e%j%F%#BP:v$r9T$J$C$F$$$k!#(B |
%なお、 mathcap データの中では CMO 形式で定義されている |
|
%32 bit 整数、文字列、リスト構造が使われており、 |
|
%mathcap データに含まれている内容を理解できるためには |
|
%必然的にこれらも理解できる必要がある |
|
%(ってことは CMO 形式のところでこれらを |
|
%説明しなければならないってことです)。 |
|
|
$B$^$:!"@\B3$,I,MW$K$J$C$?;~$K!"%/%i%$%"%s%H$,%5!<%PB&$+$i$N(B |
具体的な mathcap の例をあげる。 |
$B@\B3$rBT$D$h$&$K$J$C$F$$$k!#$3$l$O>o$K@\B3$rBT$D$3$H$K$h$C$F!"(B |
%なお、 $a_1$, $a_2$, $\cdots$, $a_n$ を要素に |
$B?/F~<T$K@\B3$N5!2q$rM?$($F$7$^$&$3$H$r8:$i$9$?$a$G$"$k!#(B |
%持つリスト構造を {\tt [$a_1$, $a_2$, $\cdots$, $a_n$]} 、 |
|
%文字列 ``string'' を {\tt "string"} 、 32 bit 整数を |
|
%それに対応する 10 進数の整数で示す。 |
|
名前が ``ox\_test'' 、バージョンナンバーが 199911250 のサーバであれば、 |
|
$A$ の部分は |
|
\begin{tabular}{|c|c|} \hline |
|
199911250 & "ox\_test" \\ \hline |
|
\end{tabular} |
|
となる。 |
|
さらに、このサーバのスタックマシンが |
|
命令コード 2, 3, 5, 7, 11 番(実際にはこのような命令コードは存在しない)を |
|
実行可能であれば、 $B$ の部分は |
|
\begin{tabular}{|c|c|c|c|c|} \hline |
|
2 & 3 & 5 & 7 & 11 \\ \hline |
|
\end{tabular} 、 |
|
CMO 形式の 32 ビット整数、文字列、 mathcap 、リスト構造のみが |
|
受け取れるときには、 $C$ の部分は |
|
|
$B<!$K!"%/%i%$%"%s%H$,@\B3Kh$K@\B3$rBT$D(B port $BHV9f$r%i%s%@%`$K7hDj$9$k(B |
\begin{tabular}{|c|c|} \hline |
$B$3$H$K$J$C$F$$$k!#$3$l$K$h$j!"?/F~<T$,$I$3$K@\B3$r9T$J$($P$h$$$N$+(B |
OX\_DATA & \vspace{1mm} |
$B$o$+$j$K$/$/$7$F$$$k!#(B |
\begin{tabular}{|c|c|c|c|} \hline |
|
CMO\_INT32 & CMO\_STRING & CMO\_MATHCAP & CMO\_LIST \\ \hline |
|
\end{tabular} \\ \hline |
|
\end{tabular} |
|
|
$B:G8e$K!"@\B3;~$K%/%i%$%"%s%H$,(B 1 $B2s$N$_M-8z$J%Q%9%o!<%I$rH/9T$7!"(B |
|
$BG'>Z$r9T$J$&$h$&$K$J$C$F$$$k!#$3$N%Q%9%o!<%I$O0lC6;HMQ$5$l$k$H(B |
|
$BL58z$K$J$k$N$G!"$b$72>$K$J$s$i$+$N<jCJ$G%Q%9%o!<%I$,1L$l$?$H$7$F$b(B |
|
$B0BA4$G$"$k!#$J$*!"$3$N%Q%9%o!<%I$O0BA4$J<jCJ$GAw$i$l$F$$$J$$$H(B |
|
$B$$$1$J$$!#$^$?!"8=:_$N<BAu$G$O%5!<%P!"$*$h$S%/%i%$%"%s%H$NF0:n$7$F$$$k(B |
|
$B%3%s%T%e!<%?>e$G$O$3$N%Q%9%o!<%I$,$o$+$C$F$7$^$&$?$a!"(B |
|
$BF10l$N%3%s%T%e!<%?>e$K0-0U$N$"$k%f!<%6$O$$$J$$$H2>Dj$7$F$$$k(B |
|
$B$3$H$KCm0U$7$J$1$l$P$J$i$J$$!#(B |
|
|
|
$B$J$*!"@\B3$,3NN)$7$?8e$N%a%C%;!<%8$NAw<u?.$K4X$7$F$O!"(B |
なお、データが受け取れることと、 |
$BFC$K0E9f2=$J$I$N=hCV$,9T$J$o$l$F$$$k$o$1$G$O$J$$!#(B |
データの論理構造が理解できることとはまったく別物であるので |
$B$b$7I,MW$,$"$l$P!"DL?.O)$N0E9f2=$r9T$J$&5!G=$,$"$k(B |
注意する必要がある。 |
$B%=%U%H%&%'%"$r;H$&$3$H$r9M$($F$$$k!#(B |
|
|
|
|
|
\section{$BB>$N%W%m%8%'%/%H(B} |
\section{セキュリティ対策} |
|
|
$BB>$N%W%m%8%'%/%H$K$D$$$F4v$D$+>R2p$9$k!#(B |
OpenXM 規約は TCP/IP を用いて通信を行うことを考慮している規約である。 |
|
ネットワークによって接続される現代の多くのソフトウェアと同様、 |
|
OpenXM 規約もまた通信時のセキュリティについて注意している。 |
|
以下、このことについて説明しよう。 |
|
|
OpenMath $B%W%m%8%'%/%H$O?t3XE*$J%*%V%8%'%/%H$r(B |
{\large\bf 意味不明なことを書いているが、} |
$B%3%s%T%e!<%?>e$GI=8=$9$kJ}K!$r7hDj$7$F$$$k!#(B |
|
$BI=8=J}K!$O(B |
|
|
|
%NetSolve |
侵入者に攻撃の機会をできるだけ与えないようするた |
|
めに、接続が必要になった時のみ接続を待つようにし、 |
|
常に接続に関与するといったことは避けている(やっぱり意味不明である)。 |
|
|
%MP |
また、侵入者が接続を行なう一瞬のすきを狙ってくる可能性もあるので、 |
|
接続を行なう時に接続を待つポート番号をランダムに決めている(誰が決めてい |
|
るのかはやっぱり不明であるが)。 |
|
さらにもう一段安全性を高めるために、 |
|
接続時に 1 回だけ使用可能なパスワードを作成し、 |
|
そのパスワードを使って認証を行なう(誰がパスワードを決めて誰が認証を行っ |
|
ているのかが不明だけど)。 |
|
このパスワードは一旦使用されれば無効にするので、 |
|
もし仮になんらかの手段でパスワードが洩れたとしても安全だと考えている。 |
|
|
%MCP |
%なお、上記のポート番号とパスワードは安全な手段で送られて |
|
%いると仮定している。 |
|
%また、同一のコンピュータ上に悪意のあるユーザはいないと仮定している |
|
%ことに注意しなければならない。 |
|
%なぜなら、現在の実装ではサーバ、およびクライアントの動作している |
|
%コンピュータ上ではこのポート番号とパスワードがわかってしまうためである。 |
|
|
\section{$B8=:_Ds6!$5$l$F$$$k%=%U%H%&%'%"(B} |
なお、接続が確立した後のメッセージの送受信に関しては、 |
|
特に暗号化などの処置を行っているわけではない。 |
|
もし必要があれば、通信路の暗号化を行なう機能がある |
|
ソフトウェア ssh を使うことを考えている。 |
|
|
$B8=:_(B OpenXM $B5,3J$KBP1~$7$F$$$k%/%i%$%"%s%H%=%U%H%&%'%"$K$O(B |
\section{他のプロジェクト} |
asir, sm1, Mathematica $B$,$"$k!#(B |
|
$B$3$l$i$N%/%i%$%"%s%H%=%U%H%&%'%"$+$i(B |
他のプロジェクトについても触れておこう。 |
OpenXM $B5,3J$KBP1~$7$?%5!<%P$r8F$S=P$9$3$H$,$G$-$k!#(B |
|
$B8=:_(B OpenXM $B5,Ls$KBP1~$7$F$$$k%5!<%P%=%U%H%&%'%"$K$O!"(B |
OpenMath プロジェクトは数学的なオブジェクトを |
asir, sm1, gnuplot, Mathematica $B$J$I$,$"$j!"(B |
コンピュータ上で表現する方法を決定している。 |
$B$=$l$>$l(B ox\_asir, ox\_sm1, ox\_math $B$H$$$&L>A0$GDs6!$5$l$F$$$k!#(B |
各ソフトウェア間でオブジェクトを交換する際の |
$B$^$?!"(B OpenMath $B5,3J$N(B XML $BI=8=$GI=8=$5$l$?%G!<%?$H(B CMO $B7A<0$N(B |
オブジェクトの変換手順についても述べられている。 |
$B%G!<%?$rJQ49$9$k%=%U%H%&%'%"$,(B JAVA $B$K$h$C$F<BAu$5$l$F$*$j!"(B |
表現方法は一つだけでなく、 XML 表現や binary 表現などが |
OMproxy $B$H$$$&L>A0$GDs6!$5$l$F$$$k!#(B |
用意されている。 |
|
詳細は |
|
|
|
http://www.openmath.org/omsoc/index.html A.M.Cohen |
|
|
|
|
|
以下は書いてる途中。 |
|
|
|
NetSolve |
|
|
|
http://www.cs.utk.edu/netsolve/ |
|
|
|
|
|
MP |
|
|
|
http://symbolicNet.mcs.kent.edu/SN/areas/protocols/mp.html |
|
|
|
|
|
MCP |
|
|
|
http://horse.mcs.kent.edu/~pwang/ |
|
|
|
|
|
\section{現在提供されているソフトウェア} |
|
|
|
現在 OpenXM 規格に対応しているクライアントには |
|
asir, sm1, Mathematica がある。 |
|
これらのクライアントから |
|
OpenXM 規格に対応したサーバを呼び出すことができる。 |
|
現在 OpenXM 規約に対応しているサーバソフトウェアには、 |
|
asir, sm1, gnuplot, Mathematica などがあり、 |
|
それぞれ ox\_asir, ox\_sm1, ox\_math という名前で提供されている。 |
|
また、 OpenMath 規格の XML 表現で表現されたデータと CMO 形式の |
|
データを変換するソフトウェアが JAVA によって実装されており、 |
|
OMproxy という名前で提供されている。 |
|
|
|
\begin{thebibliography}{99} |
|
\bibitem{OpenXM-1999} |
|
野呂正行, 高山信毅: |
|
{Open XM の設計と実装 --- Open message eXchange protocol for Mathematics}, |
|
1999/11/22 |
|
\bibitem{Ohara-Takayama-Noro-1999} |
|
小原功任, 高山信毅, 野呂正行: |
|
{Open asir 入門}, 1999, 数式処理, Vol 7, No 2, 2--17. (ISBN4-87243-086-7, SEG 出版, Tokyo). |
|
\end{thebibliography} |
|
|
\end{document} |
\end{document} |