%% $OpenXM: OpenXM/doc/OpenXM-specs/implementation.tex,v 1.3 2000/10/12 00:14:51 ohara Exp $ //&jp \section{ 実装, デバッグ, 検証 } //&jp \subsection{ 実装の手順 } /*&jp ソフト xxx を, open XM 対応にするのには以下のような 手順をふむと開発が容易であろう. \begin{enumerate} \item[Step 1.] {\tt executeStringByLocalParser} および {\tt popString} の機能を実現して, xxx をライブラリとしてまとめ, 他のソフトとリンクして 使用できるかテストする. C での実現の場合 割り込みの取扱に注意を要する. これだけの実現でも, サンプルサーバ ({\tt nullserver00.c}) とリンクすれば, open XM 対応のクライアントと通信できる. クライアント側では, このシステムに対応した機能呼び出し プログラムを書く. \item[Step 2.] 次に, CMO を可能な限り実装する. open sm1 や open asir で, CMO 形式のデータを 作成して, 読み込めるかテストする. \item[Step 2'.] {\tt kan/sm1} の plugin として組み込むとサーバの開発が楽かもしれない. {\tt kan/sm1} のソースファイルのディレクトリ {\tt plugin} を見よ. \item[Step 3.] CMO の stream への転送, stream よりの転送は, 巨大データの送信受信にきわめて大切である. これを実装しサンプルサーバとリンクする. \end{enumerate} \subsection{歴史} kan -- asir 間でも以上のように開発がすすんだ. Risa/Asir の開発が沼津の富士フォーラムでおこなわれていた ころ, 私が沼津を, 1996年, 1月19日に訪問し, {\tt Asir\_executeString()} の機能を野呂さんに書いてもらって, kan より asir を文字列で呼び出す 機能およびその逆を実現したのがことの発端である. たとえば, asir より kan/sm1 の機能を呼び出すには, \begin{verbatim} F = x; G = y; Ans = kan("(%p). (%p). mul toString",F,G) \end{verbatim} と入力すればよい. {\tt x} と {\tt y} の積が kan で解釈実行されて, 結果を もどす. このレベルの結合では kan/sm1 は, 内蔵インタプリタ付の ライブラリとして利用できてずいぶん便利である. この関数 {\tt kan} は {\tt builtin/parif.c} に組み込んだ. {\tt asir} は {\tt pari} の関数を組み込んでいるが, この組み込みの メカニズムを利用すると容易にリンクできた. 参照: {\tt noro/src/Old1/parif.c}. 次に, CMO Primitive の機能を 1997, 5 月, 6 月に実現した. その後, 1997年 7 月に, SMObject/Basic の実装, 1997年 7 月には, 野呂がイタリアの CoCoA のワークショップにおいて, 大阿久の b-function を stratification 込みで計算する計算プログラムを asir, kan を連係してデモした. このときは, {\tt Sm1\_executeStringByLocalParser} 関数を用いて, ライブラリとしてリンクしてつかった. 1997 年 11 月に TCP/IP による, サーバスタックマシン間の通信の 実装をおこなっている. 通信の実装テストのために, Java および C で null server , null client を作成した. 以下, これにつき述べる. \subsection{ サンプルサーバ, クライアント } Open XM では, 現在のところ, サンプルサーバとして {\tt oxserver00.c} を提供している. このサーバをもとにして, {\tt asir} および {\tt kan/sm1} の open XM サーバを試験中である ({\tt ox\_asir}, {\tt ox\_sm1}). {\tt ox\_sm1} では, {\tt sm1stackmachine.c} が open XM スタックマシンを実現している. サンプルクライアントは, ネットワークにデータを送出および 受信する機能のみをもつ, {\tt testclient.c} を提供 している. {\tt asir} および {\tt kan/sm1} には本格的な クライアント機能(open XM サーバを呼び出す 機能)を組み込んである. サーバを起動するプログラムは, {\tt kan/sm1} グループでは, {\tt ox} なる名前で, {\tt asir} グループでは, {\tt ox\_lauch} なる名前であるが, 機能は同じである. {\tt ox} のソースは {\tt oxmain.c} である. \subsubsection{OpenXM/src/ox\_toolkit にあるサンプル実装} このディレクトリの解説文書を見よ. \subsubsection{ ox\_null } Primitive のスタックマシンのソケットによる実装. スタックマシンは {\tt nullstackmachine.c} に実装されており, {\tt oxserver00.c} にリンクしてサーバとなる. サンプルサーバであり, これに CMO Primitive 仕様の関数を結合すれば, 一応 サーバが動作するはずである. スタックには,CMO の Primitive の object へのポインタがそのまま push される. コントロール機能なし. 1997/11/29 版よりコントロール機能追加. @Old/nullserver00.c.19971122c, @Old/mytcpip.c.19971122c 現在はこのサーバはメンテナンスされていない (object 関係の関数を追加しないとコンパイルできない.) \subsubsection{ testclient } Java による実装: @Old/client.java.19971122c これも現在はふるい. OX パケットのシリアル番号に対応していない. ちかいうちに改訂する予定. {\tt executeString} および {\tt popString} を要請する能力しか持たない. 受信は スレッド {\tt listner} がおこなっている. 受信は byte データを表示するのみである. スレッドの優先度をうまくバランスとらないと, 受信データがあるのに 表示しなかったりする. C による {\tt testclient} 同じような機能をもつプログラムの実装もある. {\footnotesize \begin{verbatim} ./ox -ox ox_sm1 -host localhost -data 1300 -control 1200 (サーバの立ち上げ) ./testclient (testclient の立ち上げ) \end{verbatim}} これも現在はふるい. 田村 ({\tt tamura@math.kobe-u.ac.jp}) による Java への新しい実装がある (1999, 3月, 神戸大学修士論文). \subsubsection{ {\tt ox} } {\tt ox} は ox サーバをたちあげるためのプログラムである. クライアントよりサーバへ接続するには二つの方法がある. 一つは {\tt ox} で データとコントロール用の二つの ポート番号を明示的に起動し, クライアントがこのポートへつなぎに いく方法である. もう一つは, クライアント側でまず, 空いているポートを二つ さがし, それから {\tt ox} を {\tt -reverse} で起動して サーバ側がクライアントにつなぎにくる方法である. この場合, {\tt ox} はたとえば次のように起動される. {\footnotesize \begin{verbatim} /home/nobuki/kxx/ox -reverse -ox /home/nobuki/kxx/ox_sm1 -data 1172 -control 1169 -pass 1045223078 \end{verbatim} } {\tt ox} は, 子どもプロセスとして, {\tt ox\_asir}, {\tt ox\_sm1} などを起動するのであるが, これらのプロセスは 3 よりOX データ, コマンドを読み込み, 4 へ OX データを書き出す. 現在の実装では 3 と 4 は dup して同一視してしまっている. {\tt ox} はTCP/IP のデータ転送のポートを, 3, 4 へわりあてて, 子どもプロセスを起動する. {\footnotesize \begin{verbatim} close(fdControl); /* close(0); dup(fdStream); */ dup2(fdStream,3); dup2(fdStream,4); \end{verbatim}} \subsubsection{ {\tt ox\_asir} phrase book} [ この節の記述は古い] CMObject と asir の object は次の規則にしたがって変換される. なお asir の object のタグをみるには関数 {\tt type} を用いる. \begin{enumerate} \item Null : 0 として使用される. \item Integer32 : 内部的にのみ使用される. 送出は, ZZ に変換される. -1 は (unsigned int) -1 に変換されてから, ZZ に変換されるので, 正の数となる. \item Cstring : 文字列 (type = 7) に変換される. \item ZZ : 数 (type = 1 ) に変換される. \item QQ : 数 (type = 1 ) に変換される. \item List : リスト (type = 4) に変換される. \item Dpolynomial : 分散表現多項式 (type = 9) に変換される. order はうけとったモノミアルのリストと同じ order である. \item RecursivePolynomial : 再帰表現多項式に変換される. 内部順序に自動変換される. \item Indeterminate : 不定元に変換される. \end{enumerate} 記述のない CMObject に関しては, 利用できない (cf. mathcap ). \noindent 問題点: 0 の扱いの仕様がまださだまっていない. Null が数 (type = 1) の 0 に変換される版もある. \medbreak \noindent 例: 分散表現多項式の $x^2-1$ の因数分解を asir にやってもらう OXexpression の列をあげる. {\footnotesize \begin{verbatim} (OX_DATA, (CMO_LIST, 4, CMO_DMS,CMO_DMS_GENERIC, (CMO_MONOMIAL32,1,2,(CMO_ZZ,1)), (CMO_MONOMIAL32,1,0,(CMO_ZZ,-1)))), (OX_DATA, (CMO_INT32,1)) (OX_DATA, (CMO_STRING,"ox_dtop")) (OX_COMMAND,(SM_executeString)) (OX_DATA, (CMO_INT32,1)) (OX_DATA, (CMO_STRING,"fctr")) (OX_COMMAND,(SM_executeString)) (OX_DATA, (CMO_INT32,1)) (OX_DATA, (CMO_STRING,"ox_ptod")) (OX_COMMAND,(SM_executeString)) (OX_COMMAND,(SM_popCMO)) \end{verbatim}} ここで, ZZ の元を普通の整数表記であらわした. {\tt dtop1} および {\tt ptod1} はそれぞれ, 分散表現多項式を, Asir の再帰表現 多項式に, 逆に, Asir の再帰表現多項式を, 分散表現多項式に変換する, ユーザ定義の 1 引数関数である. %% kxx/oxasir.sm1 これらの関数は Asir の リストにも作用させることが可能であり, その場合は 要素としてでてくる, 分散表現多項式 または Asir の再帰表現多項式 を必要な形に変換する. {\tt fctr} は因数分解をする組み込み関数である. {\tt kxx/oxasir.asir} のソース. {\footnotesize \begin{verbatim} OxVlist = [x,y,z]$ def ox_ptod(F) { extern OxVlist; if (type(F) == 4) return(map(ox_ptod,F)); else if (type(F) == 2) return(dp_ptod(F,OxVlist)); else return(F); } def ox_dtop(F) { extern OxVlist; if (type(F) == 4) return(map(ox_dtop,F)); else if (type(F) == 9) return(dp_dtop(F,OxVlist)); else return(F); } end$ \end{verbatim}} \subsubsection{ {\tt ox\_sm1} phrase book } [ この節の記述は古い] CMObject と kan/sm1 の object は次の規則にしたがい変換される. なお, kan/sm1 の object のタグをみるには, {\tt tag} または {\tt etag} を用いる. \begin{enumerate} %% \item Error : Error (etag = 257) に変換される. \item Error2 : Error (etag = 257) に変換される. \item Null : null (tag = 0) に変換される. \item Integer32 : integer (tag = 1) に変換される. \item Cstring : 文字列 (type = 5) に変換される. \item ZZ : universalNumber (type = 15 ) に変換される. \item QQ : rational (tag = 16 ) に変換される. \item List : array (tag = 6) に変換される. \item Dpolynomial : 多項式 (tag = 9) に変換される. \end{enumerate} \noroa{ {\tt SS475/memo1.txt} も見よ.} 注意: {\tt ReverseOutputOrder = 1} (標準) のとき, {\tt xn, ..., x0, dn, ..., d0} の順番で ({\tt show\_ring} の形式) Dpolynomial に変換される (印刷形式だと, {\tt xn} は {\tt e}, {\tt d0} は {\tt h}, {\tt x0} は {\tt E}, {\tt dn} は {\tt H}). たとえば, {\tt ox\_send\_cmo(id,<<1,0,0,0,0,0>>)} は, {\tt x2} に変換される. {\tt ox\_send\_cmo(id,<<0,0,1,0,0,0>>)} は, {\tt x0} に変換される. {\tt OxVersion} 変数で openXM のプロトコルの version を表す. \subsubsection{ {\tt ox\_sm1} を用いたクライアントのテスト方法 } まだかいてない. \subsubsection{ {\tt Asir} を用いたサーバのテスト方法 } \subsection{ 最小の TCP/IP クライアントの例 } Java または M2 によるソースコードを掲載の予定. \subsection{ クライアント asir, sm1 } sm1 については, ox.sm1 , oxasir.sm1 がクライアントパッケージ. {\tt ox}, {\tt ox\_asir}, {\tt ox\_sm1} の存在するパス, および sm1 より呼び出すための asir の関数定義である {\tt oxasir.asir} のあるパスを これらのパッケージに書き込んでおく必要がある. {\tt ox\_asir} は, {\tt asir} なる名前でよばれると asir として動作し, {\tt ox\_asir} なる名前でよばれると, open XM サーバとして動作する. {\tt /usr/local/lib/asir} または {\tt ASIR\_LIBDIR} へ {\tt ox\_asir} 実体をおき, {\tt ox\_launch} をおなじディレクトリへ {\tt ox\_asir} へのシンボリックリンク として作成する. コマンドサーチパスにあるディレクトリへ {\tt asir} を {\tt ox\_asir} へのシンボリックリンクとして作成する. {\footnotesize \begin{verbatim} This is Asir, Version 990413. Copyright (C) FUJITSU LABORATORIES LIMITED. 3 March 1994. All rights reserved. 0 [324] ox_launch(0,"/usr/local/lib/asir/ox_asir"); 1 <=== これがサーバの番号. [326] ox_execute_string(1,"fctr(x^10-1);"); 0 [327] ox_pop_local(1); [[1,1],[x-1,1],[x+1,1],[x^4+x^3+x^2+x+1,1],[x^4-x^3+x^2-x+1,1]] [328] ox_execute_string(1,"dp_ptod((x+y)^5,[x,y]);"); 0 [329] ox_pop_cmo(1); (1)*<<5,0>>+(5)*<<4,1>>+(10)*<<3,2>>+(10)*<<2,3>>+(5)*<<1,4>>+(1)*<<0,5>> [330] ox_rpc(1,"fctr",x^10-y^10); 0 [331] ox_pop_local(1); [[1,1],[x^4-y*x^3+y^2*x^2-y^3*x+y^4,1],[x^4+y*x^3+y^2*x^2+y^3*x+y^4,1],[x+y,1],[x-y,1]] [332] ox_rpc(1,"fctr",x^1000-y^1000); ox_cmo_rpc もあり. 0 [333] ox_flush(1); 1 [334] ox_pop_local(1); 0 ox_sync(1); --- sync ball を送る. \end{verbatim}} \subsection{開発中のサーバ, クランアント} Mathematica サーバ, クライアント : 小原. Java クライアント, Open Math proxy : 田村. Gnuplot サーバ, Macaulay 2 クライアント, サーバ, その他小さいソフト (Toric GB, Grobner fan)のサーバ, Algebraic equation solver by numerical method: 高山. Open Asir マニュアル, サンプル: 小原, 高山. 数学的におもしろい問題を実際にあつかってみないと わからない問題点もおおくあると思う. 現在, ${\cal A}$-超幾何関数の解のグラフ表示, パラメータ付積分のグラフ表示のソフトをかくことで さらに問題点をさぐることを 計画している. グレブナdeformation による多項式解, 有理解の導出(線形および非線形方程式, 非線形微分方程式から出発すると代数方程式を解く問題になる) は OpenXM 的なプログラムのおもしろい練習問題. Java の並列計算記述能力をつかって ox サーバを使うのもおもしろい. 世界中の人につかってもらえる規格にするには まだまだ実験と経験をかさねないといけない. Free Mathematical Software Initiative を作るべきだろう. \subsection{ Change log } \begin{enumerate} \item 1997/11/20 : この document の最初の version が生まれた. kxx/openxxx.tex なる名前であった. \item 1999/07 : {\tt CMO\_ZZ} の形式を変えた. \item 1999/09/7, 9/8 : 分散表現多項式, Mathcap, RecursivePolynomial, の形式を変えた. asir, sm1 に実装した. エラー処理のために, dupErrors, getsp を SM コマンドに加えた. \end{enumerate} \subsection{ } Java で sm1 サーバをすべて書いてみるか? */