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

File: [local] / OpenXM / doc / Attic / genkou19991125.tex (download)

Revision 1.96, Sun Dec 26 06:33:32 1999 UTC (24 years, 4 months ago) by ohara
Branch: MAIN
Changes since 1.95: +17 -14 lines

I add some sentences to Section 3 and 8.

\documentclass{jarticle}

%% $OpenXM: OpenXM/doc/genkou19991125.tex,v 1.96 1999/12/26 06:33:32 ohara Exp $

\usepackage{jssac}

\title{OpenXM プロジェクトの現状について}
\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}
\maketitle


\section{OpenXMとは}

OpenXM は数学プロセス間でメッセージを交換するための規約である.  数学プロ
セス間でメッセージをやりとりすることにより, ある数学プロセスから他の数学
プロセスを呼び出して計算を行なったり, 他のマシンで計算を行なわせたりする
ことが目的である.  なお, OpenXM とは Open message eXchange protocol for
Mathematics の略である.  OpenXM の開発の発端は野呂と高山により, asir と 
kan/sm1 を相互に呼び出す機能を実装したことである.

初期の実装では, 相手側のローカル言語の文法に従った文字列を送っていた. 
この方法では相手側のソフトが asir なのか kan/sm1 なのかを判別するなどし
て, 相手側のローカル言語の文法に合わせた文字列を作成しなければならない. 
このローカル言語の文法に従った文字列を送る方法は, 効率的であるとはいい難
いが, 使いやすいとも言える.

現在の OpenXM 規約では共通表現形式によるメッセージを用いている.  上記の
文字列を送る方法の利点を生かすため, OpenXM 規約では共通表現形式の中の文
字列として, ローカル言語の文法に従った文字列を用いたメッセージの交換も可
能となっている.

OpenXM 規約では通信の方法に幾らかの自由度があるが, 現在のところは TCP/IP 
を用いた通信しか実装されていない.  \footnote{asir には MPI を用いた実装
もある.}  そこで, この論文では具体的な実装は TCP/IP を用いていると仮定す
る.

\section{OpenXM のメッセージの構造}

通信の方法によってメッセージの構造は変わる.  この論文では TCP/IP の場合
についてのみ説明を行なう.

OpenXM 規約で規定されているメッセージはバイトストリームとなっており, 次
のような構造になっている.
\begin{center}
\begin{tabular}{|c|c|}
\hline
ヘッダ	& \hspace{10mm} ボディ \hspace{10mm} \\ 
\hline
\end{tabular}
\end{center}
ヘッダの長さは 8 バイトであると定められている.  ボディの長さはメッセージ
ごとに異なっているが, 長さは $0$ でもよい.

ヘッダは次の二つの情報を持っている.
\begin{enumerate}
\item
前半の 4 バイト. メッセージの種類を表す識別子であり, タグと呼ばれる.
\item
後半の 4 バイト. メッセージにつけられた通し番号である.
\end{enumerate}
それぞれの 4 バイトは 32 ビット整数とみなされて扱われる.

この場合に用いられる 32 ビット整数の表現方法について説明しておこう.  問
題になるのは負数の表現とバイトオーダーの問題である.  まず, 負数を表す必
要があるときには2の補数表現を使うことになっている.  次にバイトオーダーで
あるが, OpenXM 規約は複数のバイトオーダーを許容する.  ただし一つの通信路
ではひとつのバイトオーダーのみが許され, 通信路の確立時に一度だけ選ばれる.  

現在のOpenXM 規約では, タグ(整数値)として以下のものが定義されている.

\begin{verbatim}
#define	OX_COMMAND              513
#define	OX_DATA	                514
#define OX_SYNC_BALL            515
#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}

ボディの構造はメッセージの種類によって異なる.  OX\_COMMAND で識別される
メッセージはスタックマシンへの命令であり, それ以外のメッセージは何らかの
オブジェクトを表している.  この論文では OX\_DATA と OX\_COMMAND で識別さ
れるメッセージについてのみ, 説明する.

既存のメッセージでは対応できない場合は, 新しい識別子を定義することで新し
い種類のメッセージを作成することができる. この方法は各数学ソフトウェアの
固有の表現を含むメッセージを作成したい場合などに有効である. 新しい識別子
の定義方法については, \cite{OpenXM-1999} を参照すること.


\section{OpenXM の計算モデル}

OpenXM 規約での計算とはメッセージを交換することである. また, OpenXM 規
約ではクライアント・サーバモデルを採用しているので, メッセージの交換はサー
バとクライアントの間で行なわれる.\footnote{これの拡張は, いま主に野呂
が考えてる.  サーバ同士通信できないと効率的並列計算の実験には使えない.}
クライアントからサーバへメッセージを送
り, クライアントがサーバからメッセージを受け取ることによって計算の結果が
得られる. このメッセージのやりとりはクライアントの主導で行われる. つまり,
クライアントは自由にメッセージをサーバに送付してもよいが, サーバからは自
発的にメッセージが送付されることはない. この原理はサーバはスタックマシン
であることで実現される. スタックマシンの構造については \ref{sec:oxsm} 節
で述べる.

サーバがクライアントから受け取ったオブジェクト(つまり OX\_COMMAND でない
メッセージのボディ)はすべてスタックに積まれる. スタックマシンへの命令
(OX\_COMMAND で識別されるメッセージのボディ)を受け取ったサーバは命令に対
応する動作を行なう. このとき, 命令によってはスタックからオブジェクトを取
り出すことがあり, また(各数学システムでの)計算結果をスタックに積むことが
ある. もし, 与えられたデータが正しくないなどの理由でエラーが生じた場合に
はサーバはエラーオブジェクトをスタックに積む. 計算結果をクライアントが得
る場合にはスタックマシンの命令 SM\_popCMO または SM\_popString をサーバ
に送らなければならない. これらの命令を受け取ってはじめて, サーバからクラ
イアントへメッセージが送られる.

まとめると, クライアントがサーバへメッセージを送り, 計算の結果を得るとい
う手順は以下のようになる.

\begin{enumerate}
\item
まず, クライアントがサーバへオブジェクトを送る.  サーバは送られてきたオ
ブジェクトをスタックに積む.
\item
クライアントがサーバに計算の命令を送ると, サーバはあらかじめ定めれらた動
作を行う.  一部の命令はスタックの状態を変更する.  例えば 
SM\_executeFunction, \\ SM\_executeStringByLocalParser などの命令は, ス
タック上のオブジェクトから計算を行う.  SM\_popCMO もしくは SM\_popString 
は, スタックの最上位のオブジェクトを取りだし, クライアントに送り返す.
\end{enumerate}


\section{OpenXM スタックマシン}\label{sec:oxsm}

OpenXM 規約ではサーバはスタックマシンであると定義している. 以下, OpenXM 
スタックマシンと呼ぶ. この節ではOpenXM スタックマシンの構造について説明
しよう.

まず, OpenXM 規約は通信時にやりとりされる共通のデータ形式については規定
するが, OpenXM スタックマシンがスタックに積む, オブジェクトの構造までは
規定しない. つまり, オブジェクトの構造は各数学システムごとに異なっている
ということである. このことは通信路からデータを受け取った際に, 各数学シス
テムが固有のデータ構造に変換してからスタックに積むことを意味する. この変
換は1対1対応である必要はない.

次に OpenXM スタックマシンの命令コードについて説明する. OpenXM スタック
マシンにおけるすべての命令は4バイトの長さを持つ. OpenXM 規約の他の規定と
同様に, 4バイトのデータは32ビット整数と見なされるので, この論文でもその
表記にしたがう. OpenXM スタックマシンに対する命令はスタックに積まれるこ
とはない. 現在のところ, OpenXM 規約では以下の命令が定義されている.

\begin{verbatim}
#define SM_popSerializedLocalObject               258
#define SM_popCMO                                 262
#define SM_popString                              263

#define SM_mathcap                                264
#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

#define SM_DUMMY_sendcmo                          280
#define SM_sync_ball                              281

#define SM_control_kill                          1024
#define SM_control_to_debug_mode                 1025
#define SM_control_exit_debug_mode               1026
#define SM_control_ping                          1027
#define SM_control_start_watch_thread            1028
#define SM_control_stop_watch_thread             1029
#define SM_control_reset_connection              1030
\end{verbatim}

スタックマシンに対する命令の中には実行によって結果が返ってくるものがある. 
結果が返ってくる命令を実行した場合, サーバはその結果をスタックに積む. 
たとえば, 命令 SM\_executeStringByLocalParser はスタックに積まれているオ
ブジェクトをサーバ側のローカル言語の文法に従った文字列とみなして計算を行
なうが, 行なった計算の結果はスタックに積まれる.

なお, 命令の実行中にエラーが起こり, 結果が得られなかった場合には,
エラーオブジェクトがスタックに積まれる.

\section{CMO のデータ構造}\label{sec:cmo}

OpenXM 規約では, 数学的オブジェクトを表現する方法として CMO 形式(Common
Mathematical Object format)を定義している. この CMO 形式にしたがったデー
タは, 識別子が OX\_DATA であるようなメッセージのボディになることを想定し
ている.

CMO 形式におけるデータ構造は次のような構造をもつ.
\begin{center}
\begin{tabular}{|c|c|}
\hline
ヘッダ        & \hspace{10mm} ボディ \hspace{10mm} \\
\hline
\end{tabular}
\end{center}
ヘッダは4バイトである. ボディの長さはそれぞれのデータによって異なるが,
0でもよい.

メッセージと同様にヘッダは4バイト単位に管理される. すなわち, CMO ではヘッ
ダは一つだけの情報を含む. この4バイトのヘッダのことをタグともいう. さて,
CMO では, タグによってボディの論理的構造が決定する. すなわち, タグはそれ
ぞれのデータ構造と1対1に対応する識別子である. それぞれの論理的構造は 
\cite{OpenXM-1999} に詳述されている. 現在の OpenXM 規約では以下の CMO が
定義されている.

\begin{verbatim}
#define CMO_ERROR2                         0x7f000002
#define CMO_NULL                           1
#define CMO_INT32                          2
#define CMO_DATUM                          3
#define CMO_STRING                         4
#define CMO_MATHCAP                        5
#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}

この中で CMO\_ERROR2, CMO\_NULL, CMO\_INT32, CMO\_DATUM, CMO\_STRING,
CMO\_MATHCAP, CMO\_LIST で識別されるオブジェクトは最も基本的なオブジェ
クトであって, すべての OpenXM 対応システムに実装されていなければならない.

これらについての解説を行う前に記法について, 少し説明しておく.  この論文
では, 大文字で CMO\_INT32 と書いた場合には, 上記で定義した識別子を表す. 
また CMO\_INT32 で識別されるオブジェクトのクラス(あるいはデータ構造) を 
cmo\_int32 と小文字で表すことにする.

さて cmo を表現するための一つの記法を導入する. この記法は CMO expression
と呼ばれている. その正確な形式的定義は \cite{OpenXM-1999} を参照すること.

CMO expssion は Lisp 風表現の一種で, cmo を括弧で囲んだリストとして表現
する. それぞれの要素はカンマで区切る.  例えば,
\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 expression は単なる表
記法であることに特に注意してほしい.

さて, この記法のもとで cmo\_int32 を次のデータ構造であると定義する.
\begin{quote}
cmo\_int32 := (CMO\_INT32,  {\sl int32})
\end{quote}
同様に, cmo\_null, cmo\_string, cmo\_list, cmo\_mathcap のシンタッ
クスは次のように定義される.
\begin{quote}
cmo\_null := (CMO\_NULL) \\
cmo\_string := (CMO\_STRING, {\sl int32} $n$, {\sl string} $s$) \\
cmo\_list := (CMO\_LIST, {\sl int32} $m$, {\sl cmo} $c_1$, $\ldots$,
{\sl cmo} $c_m$) \\
cmo\_mathcap := (CMO\_MATHCAP, {\sl cmo\_list})
\end{quote}
ただし, {\sl string}は適当な長さのバイト列を表す. $s$ のバイト長は $n$
と一致することが要求される.

\section{mathcap について}

OpenXM 規約では, 通信時に用いられるメッセージの種類を各ソフトウェアが制
限する方法を用意している. これは各ソフトウェアの実装によってはすべてのメッ
セージをサポートするのが困難な場合があるからである. また, 各ソフトウェア
でメッセージの種類を拡張したい場合にも有効である. この制限(あるいは拡張) 
は mathcap と呼ばれるデータ構造によって行われる. この節では mathcap のデー
タ構造と, 具体的なメッセージの制限の手続きについて説明する.

まず, 手続きについて説明しよう.

第一にサーバの機能を制限するには次のようにする. クライアントが mathcap 
オブジェクトをサーバへ送ると, サーバは受け取ったmathcap をスタックに積む.
次にクライアントが命令 SM\_setMathCap を送ると, サーバはスタックの最上位
に積まれている mathcap オブジェクトを取り出し, mathcap で設定されていな
いメッセージをクライアントへ送らないように制限を行う.

第二にクライアントを制限するには次のようにする. クライアントがサーバに命令 \\
SM\_mathcap を送ると, サーバは mathcap オブジェクトをスタックに積む.
さらに命令 SM\_popCMO を送ると, サーバはスタックの最上位のオブジェクト
(すなわち mathcap オブジェクト)をボディとするメッセージをクライアントに
送付する. クライアントはそのオブジェクトを解析して, 制限をかける.

次に mathcap のデータ構造について説明する.
mathcap は cmo の一種であるので, すでに説明したように
\begin{quote}
cmo\_mathcap := (CMO\_MATHCAP, {\sl cmo\_list})
\end{quote}
の構造をもつ(\ref{sec:cmo} 節を参照のこと).
ボディは cmo\_list オブジェクトでなければならない.

さて, mathcap オブジェクトのボディの cmo\_list オブジェクトは以下の条件
を満たすことを要求される.  まず, その cmo\_list オブジェクトは少なくとも
リスト長が 3 以上でなければならない.
\begin{quote}
(CMO\_LIST, {\sl int32}, {\sl cmo} $a$, {\sl cmo} $b$, {\sl cmo} $c$, $\ldots$)
\end{quote}

第一要素 $a$ はまた cmo\_list であり, リスト長は 4 以上, $a_1$ は 
cmo\_int32 でバージョンを表す. $a_2$, $a_3$, $a_4$ は cmo\_string であり, 
それぞれ数学システムの名前, バージョン, HOSTTYPE を表すことになっている.
\begin{quote}
(CMO\_LIST, {\sl int32},
{\sl cmo\_int32} $a_1$, {\sl cmo\_string} $a_2$, {\sl cmo\_string}
$a_3$, {\sl cmo\_string} $a_4$, $\ldots$)
\end{quote}

第二要素 $b$ も cmo\_list であり, OpenXM スタックマシンを制御するために
用いられる.  各 $b_i$ は cmo\_int32 であり, ボディはスタックマシンの命令
コードである.  \ref{sec:oxsm} 節で説明したが, スタックマシンへの命令はす
べて {\sl int32} で表されていたことに注意しよう.
\begin{quote}
(CMO\_LIST, {\sl int32} $n$,
{\sl cmo\_int32} $b_1$, $\ldots$, {\sl cmo\_int32} $b_n$)
\end{quote}

第三要素 $c$ は以下のような cmo\_list であり, オブジェクトの送受信を制御
するために用いられる.  送受信の制御はメッセージの種類ごとに行われる.  
\begin{quote}
(CMO\_LIST, {\sl int32} $m$, {\sl cmo\_list} $\ell_1$, $\ldots$, 
{\sl cmo\_list} $\ell_m$)
\end{quote}
各 $\ell_i$ が制御のための情報を表す.  どの $\ell_i$ も一つ以上の要素を
持っており, 第一要素は必ず cmo\_int32 となっていなければならない.  これ
は制御すべきメッセージの識別子を入れるためである.

各 $\ell_i$ の構造はメッセージの種類によって異なる.  ここでは, OX\_DATA 
の場合についてのみ説明する.  第一要素が OX\_DATA の場合, リスト $\ell_i$ 
は以下のような構造となっている.  各 $c_i$ は cmo\_int32 であり, そのボディ
は CMO の識別子である.  $c_i$ で指示された CMO のみが送受信することを許
される.
\begin{quote}
(CMO\_LIST, 2, (CMO\_INT32, OX\_DATA), \\
\ \ (CMO\_LIST, {\sl int32} $k$, {\sl cmo\_int32} $c_1$, 
$\ldots$, {\sl cmo\_int32} $c_k$))
\end{quote}

具体的な mathcap の例をあげよう.  名前が ``ox\_test'', バージョンナンバー
が 199911250 のサーバで, Linux 上で動いており, このサーバのスタックマシ
ンが命令 SM\_popCMO, SM\_popString, SM\_mathcap,
SM\_executeStringByLocalParser を利用可能で, かつ オブジェクトを 
cmo\_int32, cmo\_string, cmo\_mathcap, cmo\_list のみに制限したいときの 
mathcap は
\begin{quote}
(CMO\_MATHCAP, (CMO\_LIST, 3, \\
$\quad$ (CMO\_LIST, 4, (CMO\_INT32, $199911250$), (CMO\_STRING, 7, ``ox\_test''), \\
$\qquad$ (CMO\_STRING, 9, ``199911250''), (CMO\_STRING, 4, ``i386'')) \\
$\quad$ (CMO\_LIST, $5$, (CMO\_INT32, SM\_popCMO), \\
$\qquad$ (CMO\_INT32, SM\_popString), (CMO\_INT32, SM\_mathcap), \\
$\qquad$ (CMO\_INT32, SM\_executeStringByLocalParser)) \\
$\quad$ (CMO\_LIST, $1$, (CMO\_LIST, $2$, (CMO\_INT32, OX\_DATA), \\
$\qquad$ (CMO\_LIST, $4$, (CMO\_INT32, CMO\_INT32), \\
$\qquad\quad$ (CMO\_INT32, CMO\_STRING), (CMO\_INT32, CMO\_MATHCAP), \\
$\qquad\quad$ (CMO\_INT32, CMO\_LIST))))))
\end{quote}
になる.


\section{セキュリティ対策}

OpenXM 規約は TCP/IP を用いて通信を行うことを考慮している. ネットワーク
によって接続される現代の多くのソフトウェアと同様, OpenXM 規約もまた通信
時のセキュリティについて注意している. 以下, このことについて説明しよう.

第一に OpenXM では侵入者に攻撃の機会をできるだけ与えないようにするため, 
サーバは接続が必要になった時のみ起動している.  しかし, これだけでは接続
を行なう一瞬のすきを狙われる可能性もある.  そこで接続を行なう時に, 接続
を行なうポート番号を毎回変えている.  こうすることで, 特定のポート番号を
狙って接続を行なう手口を防ぐことができる.

さらにもう一段安全性を高めるために, 接続時に一時パスワードをクライアント
が作成し, そのパスワードを使って認証を行なう.  このパスワードは一旦使用
されれば無効になるので, もし仮になんらかの手段でパスワードが洩れたとして
も安全である.

なお, メッセージ自体には特に暗号化などの処置を行っていないので, そのまま
ではパケット盗聴などを受ける可能性がある.  現在の実装では, 必要ならば 
ssh を利用して対応している.


\section{OpenXM 以外のプロジェクト}

OpenXM 以外にも数式処理システム間の通信を目指したプロジェクトは存在する. 
ここでは他のプロジェクトについても触れておこう.

\begin{itemize}
\item ESPRIT OpenMath Project

http://www.openmath.org/omsoc/

数学的対象の SGML 的表記の標準化を目指した大規模なプロジェクト. 異なる種
類の数式処理システムの間で情報を交換するときに, OpenMath で定義された表
現を利用することができる.  実際の情報交換の手続きにはいろいろなものが考
えられるが, 例えば MCP を用いた実装があり, GAP と Axiom の間で通信が行わ
れている.  OpenXM は OpenMath 規約の phrasedictionary と同じアイデアを用
いている.

\item NetSolve

http://www.cs.utk.edu/netsolve/

NetSolve はクライアント・サーバ型の分散システムであり, 単なる計算システ
ム以上のものを目指している.  クライアントは必要に応じて, サーバを呼び出
して計算をさせる.  NetSolve の特徴は, サーバの呼び出しに Agent というソ
フトウェアを介在させることである.  Agent は呼び出し先などを決定するデー
タベース的役割を果たす.  また Agent によって負荷分散が可能になる.  現在
の NetSolve は RPC を基礎にして実装されている.

\item MP

http://symbolicnet.mcs.kent.edu/SN/areas/protocols/mp.html

科学技術計算を行なうソフトウェア間で数学的なデータを効率的に交換させるこ
とを目的としたプロトコルを作成している. 木構造を用いて, 簡単かつ柔軟なも
のを目指しており, データの表現方法や交換方法によらずにソフトウェアを作る
ことができるようにするのが目標である.  現在すでに, C 言語で利用可能なラ
イブラリが提供されている.

\item MCP (Mathematical Computation Protocol)

http://horse.mcs.kent.edu/\~{}pwang/

数学的な計算を行なうための HTTP に似たプロトコル.  クライアント・サー
バモデルを採用しており, ピアツーピアのストリームコネクションを行なう. 
数学的なオブジェクトを MP や MathML で定められた方法で表現することが考え
られている.  すでに OpenMath を用いた実装が存在する.
この場合 MCP によって送信されるデータは, 本文に OpenMath 形式で数式を記
述したテキストである.

\end{itemize}


\section{現在提供されているソフトウェア}

現在 OpenXM 規約に対応しているクライアントにはasir, sm1, Mathematica が
ある.  これらのクライアントから OpenXM 規約に対応したサーバを呼び出すこ
とができる.  また OpenXM 規約に対応しているサーバには, asir, sm1,
Mathematica, gnuplot, PHC pack などがあり, それぞれ ox\_asir, ox\_sm1,
ox\_math, ox\_sm1\_gnuplot, ox\_sm1\_phc という名前で提供されている. 
さらに 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}