[BACK]Return to genkou19991125.tex CVS log [TXT][DIR] Up to [local] / OpenXM / doc

Diff for /OpenXM/doc/Attic/genkou19991125.tex between version 1.9 and 1.76

version 1.9, 1999/12/18 18:02:03 version 1.76, 1999/12/24 19:01:00
Line 1 
Line 1 
 \documentclass{jarticle}  \documentclass{jarticle}
   
 \title{\bf Open XM($B%?%$%H%kL$Dj(B)}  %% $OpenXM: OpenXM/doc/genkou19991125.tex,v 1.75 1999/12/24 17:59:42 tam Exp $
 \author{  
         Maekawa \\  \usepackage{jssac}
         Noro \\  \title{
         : \\  1. 意味もない修飾過剰な語句は排除しましょう。\\
         : \\  2. せっかく fill しているのをいじらないでくれ。\\
   3. 田村が遊んでばかりでおればかり仕事をしているのはどう考えても不公平だ。
   なんで仕事をしないのか、いい加減仕事をしろ、田村。
   %↑すみません、家で御飯食べてました。
 }  }
 \date{ 1999$BG/(B, 11$B7n(B25$BF|(B}  
   
 %\pagestyle{empty}  \author{奥 谷   行 央\affil{神戸大学大学院自然科学研究科}
                   \mail{okutani@math.sci.kobe-u.ac.jp}
     \and  小 原   功 任\affil{金沢大学理学部}
                   \mail{ohara@kappa.s.kanazawa-u.ac.jp}
     \and  高 山   信 毅\affil{神戸大学理学部}
                   \mail{takayama@math.sci.kobe-u.ac.jp}
     \and  田 村   恭 士\affil{神戸大学大学院自然科学研究科}
                   \mail{tamura@math.sci.kobe-u.ac.jp}
     \and  野 呂   正 行\affil{富士通研究所}
                   \mail{noro@para.flab.fujitsu.co.jp}
     \and  前 川   将 秀\affil{神戸大学理学部}
                   \mail{maekawa@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  初期の実装では、相手側のローカル言語の文法に従った文字列を送っていた。
 $B$*8_$$$KAj<jB&$N%3%^%s%IJ8;zNs$rAw$C$F$$$?!#(B  この方法では相手側のソフトが asir なのか kan/sm1 なのかを判別するなどして、
 $B$3$NJ}K!$O8=:_$N(B OpenXM $B5,Ls$G$b2DG=$G$"$j!"(B  相手側のローカル言語の文法に合わせた文字列を作成しなければならない。
 $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 $B5,LsFH<+$N%G!<%?7A<0$G$"$k(B CMO $B7A<0(B(Common Mathematical Object format)  OpenXM 規約では共通表現形式の中の文字列として、
 $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  
   
   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\_COMMAND となっているメッセージはスタックマシンへの命令であり、
   それ以外のメッセージは何らかのオブジェクトを表している。
   この論文では OX\_DATA と OX\_COMMAND で識別される
   メッセージについてのみ、説明する。
   
   既存のメッセージでは対応できない場合は、新しい識別子を定義することで新し
   い種類のメッセージを作成することができる。この方法は各数学ソフトウェアの
   固有の表現を含むメッセージを作成したい場合などに有効である。新しい識別子
   の定義方法については、\cite{OpenXM-1999} を参照すること。
   
   \section{OpenXM の計算モデル}
   
   OpenXM 規約での計算とはメッセージを交換することである。また、 OpenXM 規
   約ではクライアント・サーバモデルを採用しているので、メッセージの交換はサー
   バとクライアントの間で行なわれる。クライアントからサーバへメッセージを送
   り、クライアントがサーバからメッセージを受け取ることによって計算の結果が
   得られる。このメッセージのやりとりはクライアントの主導で行われる。つまり、
   クライアントは自由にメッセージをサーバに送付してもよいが、サーバからは自
   発的にメッセージが送付されることはない。この原理はサーバはスタックマシン
   であることで実現される。スタックマシンの構造については \ref{sec:oxsm} 節
   で述べる。
   
   サーバがクライアントから受け取ったオブジェクト(つまり OX\_COMMAND でない
   メッセージのボディ)はすべてスタックに積まれる。スタックマシンへの命令
   (OX\_COMMAND で識別されるメッセージのボディ)を受け取ったサーバは命令に対
   応する動作を行なう。このとき、命令によってはスタックからオブジェクトを取
   り出すことがあり、また(各数学システムでの)計算結果をスタックに積むことが
   ある。もし、与えられたデータが正しくないなどの理由でエラーが生じた場合に
   はサーバはエラーオブジェクトをスタックに積む。計算結果をクライアントが得
   る場合にはスタックマシンの命令 SM\_popCMO または SM\_popString をサーバ
   に送らなければならない。これらの命令を受け取ってはじめて、サーバからクラ
   イアントへメッセージが送られる。
   
   {\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  ジェクトをスタックに積む。
         $BAw$k$H!"%5!<%P$OI,MW$J$@$1%9%?%C%/$+$i%G!<%?$r<h$j=P$7!"(B  \item
         $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  を取り出し、実行した結果をスタックに積む。
         $B%5!<%P$XAw$k$H!"%5!<%P$O%9%?%C%/$+$i7W;;7k2L$NF~$C$F$$$k(B  %って書いてるけど、命令がSM\_popCMO とか SM\_shutdown の場合は?
         $B%G!<%?$r<h$j=P$7!"%/%i%$%"%s%H$XAw=P$9$k!#(B  \item
   最後に SM\_popCMO もしくは SM\_popString をサーバへ送ると、
   サーバはスタックから計算結果の入っているデータを取り出し、
   クライアントへ送出する。
 \end{enumerate}  \end{enumerate}
   
   \section{OpenXM スタックマシン}\label{sec:oxsm}
   
 \section{CMO $B$N%G!<%?9=B$(B}  OpenXM 規約ではサーバはスタックマシンであると定義している。以下、OpenXM
   スタックマシンと呼ぶ。この節ではOpenXM スタックマシンの構造について説明
   しよう。
   
 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  するが、OpenXM スタックマシンがスタックに積む、オブジェクトの構造までは
 CMO $BAX$NB>$N%G!<%?9=B$$@$1$G$J$/!"(B OX $BAX!"(B SM $BAX$N%G!<%?$r(B  規定しない。つまり、オブジェクトの構造は各数学システムごとに異なっている
 $BM}2r$9$k=u$1$K$J$k$H;W$($k$N$G!"(B CMO $BAX$NB?G\D9@0?t$N(B  ということである。このことは通信路からデータを受け取った際に、各数学シス
 $B%G!<%?9=B$$K$D$$$F@bL@$9$k!#(B  テムが固有のデータ構造に変換してからスタックに積むことを意味する。この変
   換は1対1対応である必要はない。
   
 CMO $BAX$GDj5A$5$l$F$$$k%G!<%?$OB?G\D9@0?t0J30$K$b(B  次に OpenXM スタックマシンの命令コードについて説明する。OpenXM スタック
 $BJ8;zNs$d%j%9%H$J$I$,$"$k!#$I$N$h$&$J%G!<%?$G$"$k$+$O(B  マシンにおけるすべての命令は4バイトの長さを持つ。OpenXM 規約の他の規定と
 $B%G!<%?$N@hF,$K$"$k(B tag $B$r8+$l$PH=JL$G$-$k$h$&$K$J$C$F$$$k!#(B  同様に、4バイトのデータは32ビット整数と見なされるので、この論文でもその
 $B$3$l$O(B OX $BAX$G$N%G!<%?$NH=JL$N;EJ}$H$*$J$8$G$"$k!#(B  表記にしたがう。OpenXM スタックマシンに対する命令はスタックに積まれるこ
 $B$J$*!"(B tag $B$O3F%G!<%?Kh$K(B 32 bit $B$N@0?t$GI=$5$l$F$*$j!"(B  とはない。現在のところ、OpenXM 規約では以下の命令が定義されている。
 $BB?G\D9@0?t$O(B 20 $B$H$J$C$F$$$k!#(B  
 $B$3$3$G(B 32 bit $B$N@0?t$NI=8=J}K!$K$D$$$F@bL@$9$kI,MW$,$"$k!#(B  
 %$B:r:#$N%3%s%T%e!<%?;v>p$+$i!"(B  
 %32 bit $B@0?t$b(B 8 bit $BC10L$G07$&$[$&$,ET9g$,$h$$!#(B  
 OpenXM $B$G$O(B 8 bit $BC10L$G(B $( \mbox{\tt 00 00 00 14})_{2^8}$ $B$HI=$9J}K!$H(B  
 $( \mbox{\tt 14 00 00 00})_{2^8}$ $B$HI=$9J}K!$,$"$k!#(B  
 $B$3$NI=8=J}K!$N0c$$$O%/%i%$%"%s%H$H%5!<%P$N:G=i$N@\B3;~$K(B  
 $BAPJ}$N9g0U$G7hDj$9$k$3$H$K$J$C$F$$$k!#$J$*!"9g0U$,$J$$>l9g$K$O(B  
 $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  
 $B;H$&$3$H$K$J$C$F$$$k!#(B  
 $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  \begin{verbatim}
 $B$7$?$H$-!"<!$K$/$k%G!<%?$O(B $[(n+31)/32]$ $B$r(B 32 bit $B$N@0?t$H$J$k!#(B  #define SM_popSerializedLocalObject               258
 $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  #define SM_popCMO                                 262
 $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  #define SM_popString                              263
   
 %$BI=8=$7$?$$B?G\D9@0?t$,Ii$G$"$C$F$b$3$l0J9_$N@bL@$O@5$N>l9g$H(B  #define SM_mathcap                                264
 %$BJQ$o$i$J$$$N$G!"0J8eB?G\D9@0?t$O@5$H$_$J$9!#(B  #define SM_pops                                   265
   #define SM_setName                                266
   #define SM_evalName                               267
   #define SM_executeStringByLocalParser             268
   #define SM_executeFunction                        269
   #define SM_beginBlock                             270
   #define SM_endBlock                               271
   #define SM_shutdown                               272
   #define SM_setMathCap                             273
   #define SM_executeStringByLocalParserInBatchMode  274
   #define SM_getsp                                  275
   #define SM_dupErrors                              276
   
 $BI=8=$7$?$$B?G\D9@0?t$N@dBPCM$,(B $2^{32}$ $B?J?t$G(B $(b_0 b_1 ...)_{2^{32}}$  #define SM_DUMMY_sendcmo                          280
 $B$HI=$;$k$H$-!"<!$K$/$k%G!<%?$O(B $b_0$, $b_1$, $\cdots$ $B$r(B  #define SM_sync_ball                              281
 32 bit $B$N@0?t$GI=8=$7$?CM$H$J$k!#(B  
   
 $B$3$3$G6qBNNc$r$@$=$&!#(B  #define SM_control_kill                          1024
 $4294967298 = 1 \times 2^{32} + 2$ $B$r(B network byte order $B$NB?G\D9@0?t$G(B  #define SM_control_to_debug_mode                 1025
 $BI=8=$9$k$H!"(B  #define SM_control_exit_debug_mode               1026
 \begin{center}  #define SM_control_ping                          1027
         {\tt 00 00 00 14 00 00 00 02 00 00 00 02 00 00 00 01}  #define SM_control_start_watch_thread            1028
 \end{center}  #define SM_control_stop_watch_thread             1029
 $B$H$J$k!#$^$?!"F1$8I=8=J}K!$G(B $-1$ $B$rI=8=$9$k$H!"(B  #define SM_control_reset_connection              1030
 \begin{center}  \end{verbatim}
         {\tt 00 00 00 14 ff ff ff ff 00 00 00 01}  
 \end{center}  
 $B$H$J$k!#(B  
   
   %以下、どういうときに結果をスタックに積むかエラーの場合どうするかの説明が
   %必要であろう。
   
 \section{MathCap $B$K$D$$$F(B}  スタックマシンに対する命令の中には実行の結果が存在するものがある。
   結果が存在する命令を実行した場合、サーバはその結果をスタックに積む。
   たとえば、 SM\_executeStringByLocalParser は
   スタックに積まれているオブジェクトを
   サーバ側のローカル言語の文法に従った文字列とみなして計算を行なうが、
   行なった結果はローカル言語で記述した文字列でスタックに積まれる。
   なお、命令の実行中にエラーが起こり、結果が得られなかった場合には、
   エラーオブジェクトがスタックに積まれる。
   
 %$BA0@a$G8+$?$h$&$K!"(B 1 $B$D$N%a%C%;!<%8$ND9$5$O7h$^$C$F$$$J$$!#(B  
 $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  
 $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  
 $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  \section{CMO のデータ構造}\label{sec:cmo}
 $B0J2<$K<($9!#$J$*!"(B $a_0$, $a_1$, $\cdots$, $a_n$ $B$rMWAG$K(B  
 $B;}$D%j%9%H9=B$$r(B {\tt [$a_0$, $a_1$, $\cdots$, $a_n$]} $B!"(B  
 $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  
   
 %$B"-<j$G:n$C$?$N$G4V0c$($F$$$k2DG=@-$"$j!#(B  OpenXM 規約では、数学的オブジェクトを表現する方法として CMO 形式(Common
 %%$B8E$$%P!<%8%g%s!#:9$7BX$($NI,MW$"$j!#(B  Mathematical Object format)を定義している。この CMO 形式にしたがったデー
   タは、識別子が OX\_DATA であるようなメッセージのボディになることを想定し
   ている。
   
   CMO 形式におけるデータ構造は次のような構造をもつ。
   
   \begin{tabular}{|c|c|} \hline
   ヘッダ        & \hspace{10mm} ボディ \hspace{10mm} \\ \hline
   \end{tabular}
   
   ヘッダは4バイトである。ボディの長さはそれぞれのデータによって異なるが、
   0でもよい。
   
   メッセージと同様にヘッダは4バイト単位に管理される。すなわち、CMO ではヘッ
   ダは一つだけの情報を含む。この4バイトのヘッダのことをタグともいう。さて、
   CMO では、タグによってボディの論理的構造が決定する。すなわち、タグはそれ
   ぞれのデータ構造と1対1に対応する識別子である。それぞれの論理的構造は
   \cite{OpenXM-1999} に詳述されている。現在の OpenXM 規約では以下の CMO が
   定義されている。
   
 \begin{verbatim}  \begin{verbatim}
 [ [199901160,"ox_asir"],  #define CMO_ERROR2  0x7f000002
   [276,275,258,262,263,266,267,268,274  #define CMO_NULL    1
     ,269,272,265,264,273,300,270,271],  #define CMO_INT32   2
   [ [514,[1,2,3,4,5,2130706433,2130706434  #define CMO_DATUM   3
           ,17,19,20,21,22,24,25,26,31,27,33,60]],  #define CMO_STRING  4
     [2144202544,[0,1]]  #define CMO_MATHCAP 5
   ]  
 ]  #define CMO_START_SIGNATURE      0x7fabcd03
   #define CMO_ARRAY                16
   #define CMO_LIST                 17
   #define CMO_ATOM                 18
   #define CMO_MONOMIAL32           19
   #define CMO_ZZ                   20
   #define CMO_QQ                   21
   #define CMO_ZERO                 22
   #define CMO_DMS_GENERIC          24
   #define CMO_DMS_OF_N_VARIABLES   25
   #define CMO_RING_BY_NAME         26
   #define CMO_RECURSIVE_POLYNOMIAL 27
   #define CMO_LIST_R               28
   
   #define CMO_INT32COEFF                 30
   #define CMO_DISTRIBUTED_POLYNOMIAL     31
   #define CMO_POLYNOMIAL_IN_ONE_VARIABLE 33
   #define CMO_RATIONAL                   34
   
   #define CMO_64BIT_MACHINE_DOUBLE           40
   #define CMO_ARRAY_OF_64BIT_MACHINE_DOUBLE  41
   #define CMO_128BIT_MACHINE_DOUBLE          42
   #define CMO_ARRAY_OF_128BIT_MACHINE_DOUBLE 43
   
   #define CMO_BIGFLOAT          50
   #define CMO_IEEE_DOUBLE_FLOAT 51
   
   #define CMO_INDETERMINATE 60
   #define CMO_TREE          61
   #define CMO_LAMBDA        62
 \end{verbatim}  \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  この中で CMO\_ERROR2, CMO\_NULL, CMO\_INT32, CMO\_DATUM, CMO\_STRING,
 $B$3$N:G=i$NMWAG$,$^$?%j%9%H9=B$$H$J$C$F$*$j!"(B  CMO\_MATHCAP, CMO\_LIST で識別されるオブジェクトは最も基本的なオブジェ
 $B:G=i$NMWAG$O%P!<%8%g%s%J%s%P!<$r!"<!$NMWAG$O%5!<%P$NL>A0$rI=$7$F$$$k!#(B  クトであって、すべての OpenXM 対応システムに実装されていなければならない。
   
 $B<!$NMWAG$O(B SM $BAX$GDj5A$5$l$F$$$kM}2r2DG=$J%G!<%?$rI=$7$F$$$k!#(B  これらについての解説を行う前に記法について、少し説明しておく。
 $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  この論文では、大文字で CMO\_INT32 と書いた場合には、上記で定義した識別子
 $BI=$5$l$F$*$j!"$3$N(B 2 $BHV$a$NMWAG$OM}2r2DG=$J(B SM $BAX$N%G!<%?$K(B  を表わす。また CMO\_INT32 で識別されるオブジェクトのクラス(あるいはデー
 $BBP$9$k(B 32 bit $B@0?t$N%j%9%H$H$J$C$F$$$k!#(B  タ構造)を cmo\_int32 と小文字で表わすことにする。
   
 $B:G8e$NMWAG$OM}2r2DG=$J%G!<%?$rI=$7$F$$$k!#(B  さて cmo を表現するための一つの記法を導入する。この記法は CMO expression
 %$B$3$N%j%9%H$NMWAG$O$^$?%j%9%H$H$J$C$F$*$j!"(B  と呼ばれている。その正確な形式的定義は \cite{OpenXM-1999} を参照すること。
 $B$3$N:G8e$NItJ,$b$^$?%j%9%H$H$J$C$F$*$j!"(B  
 $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  まず CMO expssion は Lisp 風表現の一種で、 cmo を括弧で囲んだリストとし
 $B%G!<%?$,<u$1<h$l$k$3$H$H$O$^$C$?$/JLJ*$G$"$k$N$G(B  て表現する。それぞれの要素はカンマで区切る。
 $BCm0U$9$kI,MW$,$"$k!#(B  例えば、
   \begin{quote}
   (17, {\sl int32}, (CMO\_NULL), (2, {\sl int32} $n$))
   \end{quote}
   は CMO expression である。ここで、小文字の斜体で表された``{\sl int32}''
   は 4バイトの任意のデータを表す記号であり、``{\sl int32} $n$'' は同じく 4
   バイトのデータであるが以下の説明で $n$ と表すことを示す。また数字 17, 2
   などは 4バイトのデータで整数値としてみたときの値を意味する。CMO\_NULL は
   識別子(すなわち数字 1 と等価)である。この記法から上記のデータは 20 バイ
   トの大きさのデータであることが分かる。
   なお、このデータは cmo ではないことに注意してほしい。
   %なお、 CMO expression で表現できていても、
   %それが CMO であることとは無関係である。
   
   さて、この記法のもとで cmo\_int32 を次のデータ構造を持つと定義する。
   \begin{quote}
   cmo\_int32 := (CMO\_INT32,  {\sl int32} $a$)
   \end{quote}
   
 \section{security $BBP:v(B}  これは 32 ビット整数 $a$ の cmo を表す。
   他のオブジェクトを定義するために、
   以後 ``{\sl string} $s$'' を文字列 $s$ 、
   ``{\sl cmo} $ob$'' を cmo のオブジェクト $ob$ とする。
   これを用いて、 cmo\_string, cmo\_list を定義する。
   
 OpenXM $B$G$O(B  
   
   {\Huge 同様に cmo\_string, cmo\_list などを定義}
   
   cmo\_string := (CMO\_STRING, {\sl int32}, string)
   
 \section{$BB>$N%W%m%8%'%/%H(B}  cmo\_list := (CMO\_LIST, {\sl int32},...
   
 \section{$B8=:_Ds6!$5$l$F$$$k%=%U%H%&%'%"(B}  % ここで 32 bit の整数の表現方法について触れておく。
   % OpenXM 規約ではバイトストリームで 32 bit の整数 20 を
   % {\tt 00 00 00 14} と表す方法と {\tt 14 00 00 00} と表す方法がある。
   % この表現方法の違いはクライアントとサーバの最初の接続時に
   % 双方の合意で決定することになっている。
   % なお、合意がない場合には前者の表現方法
   % (以後、この表現方法をネットワークバイトオーダーと呼ぶ)を
   % 使うことになっている。
   % また、負の数を表現する必要があるときには、
   % 2 の補数表現を使うことになっている。
   
   % 先ほどの、 (CMO\_INT32, 123456789) をネットワークバイトオーダーで
   % バイト列に直すと、
   % \begin{center}
   %       {\tt 00 00 00 02 07 5b cd 15}
   % \end{center}
   % となり、
   % (CMO\_STRING, 6, ``OpenXM'') は
   % \begin{center}
   %       {\tt 00 00 00 04 00 00 00 06 4f 70 65 6e 58 4d}
   % \end{center}
   % となる。
   
   % CMO 形式の多倍長整数は、 Gnu MPライブラリ等を参考にしており、
   % 符号付き絶対値表現を用いている。
   % タグ以降の形式は次のようになる。
   
   % \begin{tabular}{|c|c|c|c|c|} \hline
   % $f$ & $b_0$ & $b_1$ & $\cdots$ & $b_{n-1}$ \\ \hline
   % \end{tabular}
   
   % ここで、 1 つの枠は 4 バイトを表し、
   % $f$ は符号付き 32 ビット整数を、
   % $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}
   %       {\tt 00 00 00 14 00 00 00 02 00 00 00 02 00 00 00 01}
   % \end{center}
   % となる。また、同じ表現方法で $-1$ を表現すると、
   % \begin{center}
   %       {\tt 00 00 00 14 ff ff ff ff 00 00 00 01}
   % \end{center}
   % となる。
   
   
   \section{mathcap について}
   
   OpenXM 規約では、通信時に用いられるメッセージの種類を各ソフトウェアが制
   限する方法を用意している。これは各ソフトウェアの実装によってはすべてのメッ
   セージをサポートするのが困難な場合があるからである。また、各ソフトウェア
   でメッセージの種類を拡張したい場合にも有効である。この制限(あるいは拡張)
   は mathcap と呼ばれるデータ構造によって行われる。この節では mathcap のデー
   タ構造と、具体的なメッセージの制限の手続きについて説明する。
   
   では、手続きについて説明しよう。
   
   第一にサーバの機能を制限するには次のようにする。クライアントが mathcap
   オブジェクトをサーバへ送ると、サーバは受け取ったmathcap をスタックに積む。
   次にクライアントが命令 SM\_setMathCap を送ると、サーバはスタックの最上位
   に積まれている mathcap オブジェクトを取り出し、mathcap で設定されていな
   いメッセージをクライアントへ送らないように制限を行う。
   
   第二にクライアントを制限するには次のようにする。クライアントがサーバに命
   令 SM\_mathcap を送ると、サーバは mathcap オブジェクトをスタックに積む。
   さらに命令 SM\_popCMO を送ると、サーバはスタックの最上位のオブジェクト
   (すなわち mathcap オブジェクト)をボディとするメッセージをクライアントに
   送付する。クライアントはそのオブジェクトを解析して、制限をかける。
   
   次に mathcap のデータ構造について説明する。
   mathcap は CMO の一種であるので、すでに説明したように
   \begin{verbatim}
   ヘッダ     ボディ
   \end{verbatim}
   の構造を持ちヘッダの値は 5 である(\ref{sec:cmo} 節を参照のこと)。
   ボディは cmo\_list オブジェクトでなければならない。
   
   さて、mathcap オブジェクトのボディの cmo\_list オブジェクトは以下の条件を
   満たすことを要求される。
   
   まず、その cmo\_list オブジェクトは少なくともリスト長が 3 以上でなければ
   ならない。
   
   \[      \begin{tabular}{|c|c|c|} \hline
           $A$ & $B$ & $C$ \\ \hline
           \end{tabular}   \]
   
   第一要素 $A$ はまた cmo\_list であり、リスト長は 4 以上、
   $a_1$ は 32 ビット整数でバージョンナンバーを、
   $a_2$ は文字列でシステムの名前を表すことになっている。
   
   \[      \begin{tabular}{|c|c|} \hline
           $a_1$ & $a_2$   \\ \hline
           \end{tabular}   \]
   
   2 番目の要素 $B$ の部分は次のようなリスト構造をしている。
   この $b_1$, $b_2$, $\cdots$, $b_n$ はすべて 32 ビットの整数である。
   スタックマシンへの命令はすべて 32 ビットの整数で表しており、
   各 $b_i$ は利用可能な命令に対応する 32 ビットの整数となっている。
   
   \[      \begin{tabular}{|c|c|c|c|} \hline
           $b_1$ & $b_2$ & $\cdots$ & $b_n$        \\ \hline
           \end{tabular}   \]
   
   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}}   \]
   
   %なお、 mathcap データの中では CMO 形式で定義されている
   %32 bit 整数、文字列、リスト構造が使われており、
   %mathcap データに含まれている内容を理解できるためには
   %必然的にこれらも理解できる必要がある
   %(ってことは CMO 形式のところでこれらを
   %説明しなければならないってことです)。
   
   具体的な mathcap の例をあげよう。
   %なお、 $a_1$, $a_2$, $\cdots$, $a_n$ を要素に
   %持つリスト構造を {\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$ の部分は
   \begin{tabular}{|c|} \hline
           \\[-5mm]
           \begin{tabular}{|c|c|} \hline
                   & \\[-5mm]
                   OX\_DATA &
                   \begin{tabular}{|c|c|c|c|} \hline
                   CMO\_INT32 & CMO\_STRING & CMO\_MATHCAP & CMO\_LIST \\ \hline
                   \end{tabular} \\[0.8mm] \hline
           \end{tabular} \\[1.4mm] \hline
   \end{tabular} \\
   となる。
   CMO\_ZZ がないので、このサーバは多倍長整数が送られてこないことを期待して
   いる。
   
   なお、データが受け取れることと、データの論理構造が理解できることとはまっ
   たく別物であるので注意する必要がある。
   
   {\Huge ってなんででしょうか? データの論理構造を知らないと受け取れないと
   思うんですが$\ldots$}
   
   
   \section{セキュリティ対策}
   
   OpenXM 規約は TCP/IP を用いて通信を行うことを考慮している。ネットワーク
   によって接続される現代の多くのソフトウェアと同様、OpenXM 規約もまた通信
   時のセキュリティについて注意している。以下、このことについて説明しよう。
   
   {\large\bf 意味不明なことを書いているが、}
   
   侵入者に攻撃の機会をできるだけ与えないようするた
   めに、接続が必要になった時のみ接続を待つようにし、
   常に接続に関与するといったことは避けている(やっぱり意味不明である)。
   
   また、侵入者が接続を行なう一瞬のすきを狙ってくる可能性もあるので、
   接続を行なう時に接続を待つポート番号をランダムに決めている(誰が決めてい
   るのかはやっぱり不明であるが)。
   さらにもう一段安全性を高めるために、
   接続時に 1 回だけ使用可能なパスワードを作成し、
   そのパスワードを使って認証を行なう(誰がパスワードを決めて誰が認証を行っ
   ているのかが不明だけど)。
   このパスワードは一旦使用されれば無効にするので、
   もし仮になんらかの手段でパスワードが洩れたとしても安全だと考えている。
   
   なお、接続が確立した後のメッセージの送受信に関しては、
   特に暗号化などの処置を行っているわけではない。
   もし必要があれば、通信路の暗号化を行なう機能がある
   ソフトウェア ssh を使うことを考えている。
   
   \section{他のプロジェクト}
   
   他のプロジェクトについても触れておこう。
   
   \begin{itemize}
   \item OpenMath\\
   OpenMath プロジェクトは数学的なオブジェクトをコンピュータ上で表現する方
   法を規定している。各ソフトウェア間でオブジェクトを交換する際のオブジェク
   トの変換手順につても定められている。表現方法は幾つかの段階で定められて
   いて、XML 表現やバイナリ表現などが用意されている。詳細は
   
   http://www.openmath.org/omsoc/   A.M.Cohen
   
   \item NetSolve
   
   http://www.cs.utk.edu/netsolve/
   
   \item MP
   
   http://symbolicNet.mcs.kent.edu/SN/areas/protocols/mp.html
   
   \item MCP
   
   http://horse.mcs.kent.edu/~pwang/
   \end{itemize}
   
   
   \section{現在提供されているソフトウェア}
   
   現在 OpenXM 規約に対応しているクライアントにはasir, sm1, Mathematica が
   ある。これらのクライアントから OpenXM 規約に対応したサーバを呼び出すこと
   ができる。現在 OpenXM 規約に対応しているサーバソフトウェアには、asir,
   sm1, gnuplot, Mathematica などがあり、それぞれ ox\_asir, ox\_sm1,
   ox\_sm1\_gnuplot, ox\_math という名前で提供されている。また、 OpenMath
   規約の XML 表現で表現されたオブジェクトと CMO 形式のオブジェクトを変換す
   るソフトウェアが JAVA によって実装されており、OMproxy という名前で提供さ
   れている。
   
   \begin{thebibliography}{99}
   \bibitem{Ohara-Takayama-Noro-1999}
   小原功任, 高山信毅, 野呂正行:
   {Open asir 入門}, 1999, 数式処理, Vol 7, No 2, 2--17. (ISBN4-87243-086-7, SEG 出版, Tokyo).
   \bibitem{OpenXM-1999}
   野呂正行, 高山信毅:
   {Open XM の設計と実装 --- Open message eXchange protocol for Mathematics},
   1999/11/22
   \end{thebibliography}
   
 \end{document}  \end{document}

Legend:
Removed from v.1.9  
changed lines
  Added in v.1.76

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>